Selection method added to database
This commit is contained in:
parent
41f9e3cccc
commit
0bfee44e9b
@ -30,19 +30,26 @@ from this class.
|
|||||||
# Python libraries
|
# Python libraries
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
from ..const import GRAMPS_LOCALE as glocale
|
import re
|
||||||
_ = glocale.translation.gettext
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Gramps libraries
|
# Gramps libraries
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
from ..const import GRAMPS_LOCALE as glocale
|
||||||
|
_ = glocale.translation.gettext
|
||||||
from ..lib.childreftype import ChildRefType
|
from ..lib.childreftype import ChildRefType
|
||||||
from ..lib.childref import ChildRef
|
from ..lib.childref import ChildRef
|
||||||
from .txn import DbTxn
|
from .txn import DbTxn
|
||||||
from .exceptions import DbTransactionCancel
|
from .exceptions import DbTransactionCancel
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Gramps libraries
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
class DbReadBase(object):
|
class DbReadBase(object):
|
||||||
"""
|
"""
|
||||||
Gramps database object. This object is a base class for all
|
Gramps database object. This object is a base class for all
|
||||||
@ -1868,3 +1875,100 @@ class DbWriteBase(DbReadBase):
|
|||||||
self.remove_family(instance.handle, transaction)
|
self.remove_family(instance.handle, transaction)
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid instance type: %s" % instance.__class__.__name__)
|
raise ValueError("invalid instance type: %s" % instance.__class__.__name__)
|
||||||
|
|
||||||
|
def select(self, table, fields=None, sort=False, start=0, limit=50,
|
||||||
|
filter=None):
|
||||||
|
"""
|
||||||
|
Default implementation of a select for those databases
|
||||||
|
that don't support SQL. Yields data row by row.
|
||||||
|
|
||||||
|
table - Person, Family, etc.
|
||||||
|
fields - used by object.get_field()
|
||||||
|
sort - use sort order (argument to DB.get_X_handles)
|
||||||
|
start - position to start
|
||||||
|
limit - count to get; -1 for all
|
||||||
|
filter - {field: (SQL string_operator, value), }
|
||||||
|
handles all SQL except for NOT expression, eg NOT x = y
|
||||||
|
"""
|
||||||
|
def hash_name(name):
|
||||||
|
"""
|
||||||
|
Used in filter to eval expressions involving selected
|
||||||
|
data.
|
||||||
|
"""
|
||||||
|
return (name
|
||||||
|
.replace(".", "_D_")
|
||||||
|
.replace("(", "_P_")
|
||||||
|
.replace(")", "_P_"))
|
||||||
|
# Fields is None or list, maybe containing "*":
|
||||||
|
if fields is None:
|
||||||
|
fields = ["*"]
|
||||||
|
elif not isinstance(fields, (list, tuple)):
|
||||||
|
raise Exception("fields must be a list/tuple of field names")
|
||||||
|
if "*" in fields:
|
||||||
|
fields.remove("*")
|
||||||
|
fields.extend(self._tables[table]["class_func"].get_schema().keys())
|
||||||
|
# Get iterator of handles, possibly sorted by name, etc.:
|
||||||
|
if sort:
|
||||||
|
data = self._tables[table]["handles_func"](sort_handles=True)
|
||||||
|
else:
|
||||||
|
data = self._tables[table]["handles_func"]()
|
||||||
|
position = 0
|
||||||
|
selected = 0
|
||||||
|
for handle in data:
|
||||||
|
if position < start:
|
||||||
|
pass # skip it
|
||||||
|
else:
|
||||||
|
item = self._tables[table]["handle_func"](handle)
|
||||||
|
row = []
|
||||||
|
env = {}
|
||||||
|
for field in fields:
|
||||||
|
value = item.get_field(field)
|
||||||
|
row.append(value)
|
||||||
|
if filter:
|
||||||
|
env[hash_name(field)] = value
|
||||||
|
if filter:
|
||||||
|
matched = True
|
||||||
|
for name, (op, value) in filter.items():
|
||||||
|
v = eval(hash_name(name), env)
|
||||||
|
if op == "=":
|
||||||
|
matched = v == value
|
||||||
|
elif op == ">":
|
||||||
|
matched = v > value
|
||||||
|
elif op == ">=":
|
||||||
|
matched = v >= value
|
||||||
|
elif op == "<":
|
||||||
|
matched = v < value
|
||||||
|
elif op == "<=":
|
||||||
|
matched = v <= value
|
||||||
|
elif op == "IN":
|
||||||
|
matched = v in value
|
||||||
|
elif op == "IS":
|
||||||
|
matched = v is value
|
||||||
|
elif op == "IS NOT":
|
||||||
|
matched = v is not value
|
||||||
|
elif op == "IS NULL":
|
||||||
|
matched = v is None
|
||||||
|
elif op == "IS NOT NULL":
|
||||||
|
matched = v is not None
|
||||||
|
elif op == "BETWEEN":
|
||||||
|
matched = value[0] <= v <= value[1]
|
||||||
|
elif op in ["<>", "!="]:
|
||||||
|
matched = v != value
|
||||||
|
elif op == "LIKE":
|
||||||
|
value = value.replace("%", "(.*)").replace("_", ".")
|
||||||
|
matched = re.match(value, v)
|
||||||
|
else:
|
||||||
|
raise Exception("invalid select operator: '%s'" % op)
|
||||||
|
if not matched:
|
||||||
|
break
|
||||||
|
if matched:
|
||||||
|
selected += 1
|
||||||
|
yield row
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
selected += 1
|
||||||
|
yield row
|
||||||
|
position += 1
|
||||||
|
if selected == limit:
|
||||||
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user