db.select() can now use filter; returns total count, and selection

This commit is contained in:
Doug Blank 2016-01-08 14:07:43 -05:00
parent cc00442e0b
commit 1654757c22

View File

@ -1880,7 +1880,7 @@ class DbWriteBase(DbReadBase):
filter=None): filter=None):
""" """
Default implementation of a select for those databases Default implementation of a select for those databases
that don't support SQL. Yields data row by row. that don't support SQL. Returns a list of dicts, and total.
table - Person, Family, etc. table - Person, Family, etc.
fields - used by object.get_field() fields - used by object.get_field()
@ -1890,6 +1890,11 @@ class DbWriteBase(DbReadBase):
filter - {field: (SQL string_operator, value), } filter - {field: (SQL string_operator, value), }
handles all SQL except for NOT expression, eg NOT x = y handles all SQL except for NOT expression, eg NOT x = y
""" """
class Result(list):
"""
A list rows of just matching for this page, with total = all.
"""
total = 0
def hash_name(name): def hash_name(name):
""" """
Used in filter to eval expressions involving selected Used in filter to eval expressions involving selected
@ -1914,19 +1919,17 @@ class DbWriteBase(DbReadBase):
data = self._tables[table]["handles_func"]() data = self._tables[table]["handles_func"]()
position = 0 position = 0
selected = 0 selected = 0
result = Result()
if filter:
for handle in data: for handle in data:
if position < start: # have to evaluate all, because there is a filter
pass # skip it
else:
item = self._tables[table]["handle_func"](handle) item = self._tables[table]["handle_func"](handle)
row = {} row = {}
env = {} env = {}
for field in fields: for field in filter.keys():
# just the ones we need for filter
value = item.get_field(field) value = item.get_field(field)
row[field] = value
if filter:
env[hash_name(field)] = value env[hash_name(field)] = value
if filter:
matched = True matched = True
for name, (op, value) in filter.items(): for name, (op, value) in filter.items():
v = eval(hash_name(name), env) v = eval(hash_name(name), env)
@ -1962,13 +1965,27 @@ class DbWriteBase(DbReadBase):
if not matched: if not matched:
break break
if matched: if matched:
if selected < limit and start <= position:
# now, we get all of the fields
for field in fields:
value = item.get_field(field)
row[field] = value
selected += 1 selected += 1
yield row result.append(row)
else:
continue
else:
selected += 1
yield row
position += 1 position += 1
if selected == limit: result.total = position
else: # no filter
for handle in data:
if position >= start:
if selected >= limit:
break break
item = self._tables[table]["handle_func"](handle)
row = {}
for field in fields:
value = item.get_field(field)
row[field] = value
result.append(row)
selected += 1
position += 1
result.total = self._tables[table]["count_func"]()
return result