Skip to content

Commit

Permalink
Use class instead of type; use casefold
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidMStraub committed Apr 22, 2024
1 parent 6bfcce1 commit edc4954
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 25 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ python -m pip install gramps-ql
## Usage

```python
from gramps_ql import iter_objects
import gramps_ql as gql

db = ... # A Gramps DbReadBase instance

# iterate over private people
query = 'type=person AND private'

for obj in iter_objects(query, db):
for obj in gql.iter_objects(query, db):
f(obj) # do something with the Gramps object obj
```

Expand Down
12 changes: 10 additions & 2 deletions src/gramps_ql/gql.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def match(query: str, obj: Union[PrimaryObject, dict[str, Any]]) -> bool:
gq = GQLQuery(query=query)
if isinstance(obj, PrimaryObject):
obj_dict = json.loads(to_json(obj))
obj_dict["type"] = obj_dict["_class"].lower()
obj_dict["class"] = obj_dict["_class"].lower()
return gq.match(obj_dict)
return gq.match(obj)

Expand Down Expand Up @@ -176,16 +176,24 @@ def _match_values(self, result, operator: str = "", rhs: str = "") -> bool:
else:
rhs = rhs.strip("\"'")
if operator == "=":
if isinstance(result, str):
rhs = str(rhs)
return result.casefold() == rhs.casefold()
return result == rhs
if operator == "!=":
if isinstance(result, str):
rhs = str(rhs)
return result.casefold() != rhs.casefold()
return result != rhs
if operator == "~":
if isinstance(result, str):
rhs = str(rhs)
return rhs.casefold() in result.casefold()
return rhs in result
if operator == "!~":
if isinstance(result, str):
rhs = str(rhs)
return rhs.casefold() in result.casefold()
return rhs not in result
try:
if operator == "<":
Expand All @@ -205,6 +213,6 @@ def iter_objects(self, db: DbReadBase) -> Generator[PrimaryObject, None, None]:
iter_method = getattr(db, f"iter_{objects_name}")
for obj in iter_method():
obj_dict = json.loads(to_json(obj))
obj_dict["type"] = obj_dict["_class"].lower()
obj_dict["class"] = obj_dict["_class"].lower()
if self.match(obj_dict):
yield obj
16 changes: 8 additions & 8 deletions tests/gramps_ql/test_iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ def test_fixture(db):


def test_person_gramps_id(db):
q = GQLQuery("type=person")
q = GQLQuery("class=person")
assert len(list(q.iter_objects(db))) == 1
for obj in q.iter_objects(db):
assert isinstance(obj, Person)
q = GQLQuery("""type=person and gramps_id="person001" """)
q = GQLQuery("""class=person and gramps_id="person001" """)
assert len(list(q.iter_objects(db))) == 1
q = GQLQuery("""type=person and gramps_id!="person001" """)
q = GQLQuery("""class=person and gramps_id!="person001" """)
assert len(list(q.iter_objects(db))) == 0
q = GQLQuery("""type=person and gramps_id="person002" """)
q = GQLQuery("""class=person and gramps_id="person002" """)
assert len(list(q.iter_objects(db))) == 0
q = GQLQuery("""type=person and gramps_id>"person002" """)
q = GQLQuery("""class=person and gramps_id>"person002" """)
assert len(list(q.iter_objects(db))) == 0
q = GQLQuery("""type=person and gramps_id<"person002" """)
q = GQLQuery("""class=person and gramps_id<"person002" """)
assert len(list(q.iter_objects(db))) == 1
q = GQLQuery("type=person and gramps_id < 'person002'")
q = GQLQuery("class=person and gramps_id < 'person002'")
assert len(list(q.iter_objects(db))) == 1
q = GQLQuery("type=person and gramps_id < 'person002'")
q = GQLQuery("class=person and gramps_id < 'person002'")
assert len(list(q.iter_objects(db))) == 1
6 changes: 6 additions & 0 deletions tests/gramps_ql/test_match.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def test_string_contains():
assert q.match({"string": "co2"})


def test_string_contains_case():
q = GQLQuery("string ~ a")
assert q.match({"string": "abc"})
assert q.match({"string": "Abc"})


def test_any():
q = GQLQuery("array.any = 2")
assert not q.match({"array": []})
Expand Down
28 changes: 15 additions & 13 deletions tests/gramps_ql/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@


def test_single():
assert parse("type=person").as_list() == ["type", "=", "person"]
assert parse("class=person").as_list() == ["class", "=", "person"]


def test_two():
assert parse("type=person or date.year > 2021").as_list() == [
assert parse("class=person or date.year > 2021").as_list() == [
[
"type",
"class",
"=",
"person",
"or",
Expand All @@ -20,48 +20,50 @@ def test_two():


def test_three():
assert parse("type=person or name='John Doe' and date.year > 2021").as_list() == [
assert parse("class=person or name='John Doe' and date.year > 2021").as_list() == [
[
"type",
"class",
"=",
"person",
"or",
["name", "=", "'John Doe'", "and", "date.year", ">", "2021"],
]
]
assert parse("type=person and name='John Doe' or date.year > 2021").as_list() == [
assert parse("class=person and name='John Doe' or date.year > 2021").as_list() == [
[
["type", "=", "person", "and", "name", "=", "'John Doe'"],
["class", "=", "person", "and", "name", "=", "'John Doe'"],
"or",
"date.year",
">",
"2021",
]
]
assert parse("type=person and name='John Doe' or only_id").as_list() == [
assert parse("class=person and name='John Doe' or only_id").as_list() == [
[
["type", "=", "person", "and", "name", "=", "'John Doe'"],
["class", "=", "person", "and", "name", "=", "'John Doe'"],
"or",
"only_id",
]
]


def test_brackets():
assert parse("(type=person or name='John Doe') and date.year > 2021").as_list() == [
assert parse(
"(class=person or name='John Doe') and date.year > 2021"
).as_list() == [
[
["type", "=", "person", "or", "name", "=", "'John Doe'"],
["class", "=", "person", "or", "name", "=", "'John Doe'"],
"and",
"date.year",
">",
"2021",
]
]
assert parse(
"(((((((((((type=person or name='John Doe')))) and date.year > 2021)))))))"
"(((((((((((class=person or name='John Doe')))) and date.year > 2021)))))))"
).as_list() == [
[
["type", "=", "person", "or", "name", "=", "'John Doe'"],
["class", "=", "person", "or", "name", "=", "'John Doe'"],
"and",
"date.year",
">",
Expand Down

0 comments on commit edc4954

Please sign in to comment.