iter_OBJECTS can take an order_by field list
This commit is contained in:
@@ -1892,6 +1892,7 @@ class DbWriteBase(DbReadBase):
|
|||||||
["AND", [filter, filter, ...]] |
|
["AND", [filter, filter, ...]] |
|
||||||
["OR", [filter, filter, ...]] |
|
["OR", [filter, filter, ...]] |
|
||||||
["NOT", filter]
|
["NOT", filter]
|
||||||
|
order_by - [[fieldname, "ASC" | "DESC"], ...]
|
||||||
"""
|
"""
|
||||||
class Result(list):
|
class Result(list):
|
||||||
"""
|
"""
|
||||||
@@ -1993,9 +1994,7 @@ class DbWriteBase(DbReadBase):
|
|||||||
if "*" in fields:
|
if "*" in fields:
|
||||||
fields.remove("*")
|
fields.remove("*")
|
||||||
fields.extend(self._tables[table]["class_func"].get_schema().keys())
|
fields.extend(self._tables[table]["class_func"].get_schema().keys())
|
||||||
#FIXME: add order_by to iter_funcs
|
data = self._tables[table]["iter_func"](order_by=order_by)
|
||||||
#data = self._tables[table]["iter_func"](order_by=order_by)
|
|
||||||
data = self._tables[table]["iter_func"]()
|
|
||||||
position = 0
|
position = 0
|
||||||
selected = 0
|
selected = 0
|
||||||
result = Result()
|
result = Result()
|
||||||
@@ -2041,3 +2040,14 @@ class DbWriteBase(DbReadBase):
|
|||||||
"""
|
"""
|
||||||
name = self._tables[table]["class_func"].get_field_alias(name)
|
name = self._tables[table]["class_func"].get_field_alias(name)
|
||||||
return name.replace(".", "__")
|
return name.replace(".", "__")
|
||||||
|
|
||||||
|
def eval_order_by(self, order_by, obj):
|
||||||
|
"""
|
||||||
|
Given a list of [[field, DIRECTION], ...]
|
||||||
|
return the list of values of the fields
|
||||||
|
"""
|
||||||
|
values = []
|
||||||
|
for (field, direction) in order_by:
|
||||||
|
values.append(obj.get_field(field))
|
||||||
|
return values
|
||||||
|
|
||||||
|
@@ -33,6 +33,7 @@ import logging
|
|||||||
import shutil
|
import shutil
|
||||||
import bisect
|
import bisect
|
||||||
import ast
|
import ast
|
||||||
|
from operator import itemgetter
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@@ -1143,11 +1144,36 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def iter_people(self):
|
def iter_items(self, order_by, class_):
|
||||||
return (Person.create(data[1]) for data in self.get_person_cursor())
|
"""
|
||||||
|
Iterate over items in a class, possibly ordered by
|
||||||
|
a list of field names and direction ("ASC" or "DESC").
|
||||||
|
"""
|
||||||
|
cursor = self._tables[class_.__name__]["cursor_func"]
|
||||||
|
if order_by is None:
|
||||||
|
for data in cursor():
|
||||||
|
yield class_.create(data[1])
|
||||||
|
else:
|
||||||
|
# first build sort order:
|
||||||
|
sorted_items = []
|
||||||
|
for data in cursor():
|
||||||
|
obj = class_.create(data[1])
|
||||||
|
# just use values and handle to keep small:
|
||||||
|
sorted_items.append((self.eval_order_by(order_by, obj), obj.handle))
|
||||||
|
# next we sort by fields and direction
|
||||||
|
pos = len(order_by) - 1
|
||||||
|
for (field, order) in reversed(order_by): # sort the lasts parts first
|
||||||
|
sorted_items.sort(key=itemgetter(pos), reverse=(order=="DESC"))
|
||||||
|
pos -= 1
|
||||||
|
# now we will look them up again:
|
||||||
|
for (order_by_values, handle) in sorted_items:
|
||||||
|
yield self._tables[class_.__name__]["handle_func"](handle)
|
||||||
|
|
||||||
def iter_families(self):
|
def iter_people(self, order_by=None):
|
||||||
return (Family.create(data[1]) for data in self.get_family_cursor())
|
return self.iter_items(order_by, Person)
|
||||||
|
|
||||||
|
def iter_families(self, order_by=None):
|
||||||
|
return self.iter_items(order_by, Family)
|
||||||
|
|
||||||
def get_person_from_gramps_id(self, gramps_id):
|
def get_person_from_gramps_id(self, gramps_id):
|
||||||
return Person.create(self.person_id_map[gramps_id])
|
return Person.create(self.person_id_map[gramps_id])
|
||||||
@@ -1817,26 +1843,26 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
|||||||
def is_open(self):
|
def is_open(self):
|
||||||
return self.db_is_open
|
return self.db_is_open
|
||||||
|
|
||||||
def iter_citations(self):
|
def iter_citations(self, order_by=None):
|
||||||
return (Citation.create(data[1]) for data in self.get_citation_cursor())
|
return self.iter_items(order_by, Citation)
|
||||||
|
|
||||||
def iter_events(self):
|
def iter_events(self, order_by=None):
|
||||||
return (Event.create(data[1]) for data in self.get_event_cursor())
|
return self.iter_items(order_by, Event)
|
||||||
|
|
||||||
def iter_media(self):
|
def iter_media(self, order_by=None):
|
||||||
return (Media.create(data[1]) for data in self.get_media_cursor())
|
return self.iter_items(order_by, Media)
|
||||||
|
|
||||||
def iter_notes(self):
|
def iter_notes(self, order_by=None):
|
||||||
return (Note.create(data[1]) for data in self.get_note_cursor())
|
return self.iter_items(order_by, Note)
|
||||||
|
|
||||||
def iter_places(self):
|
def iter_places(self, order_by=None):
|
||||||
return (Place.create(data[1]) for data in self.get_place_cursor())
|
return self.iter_items(order_by, Place)
|
||||||
|
|
||||||
def iter_repositories(self):
|
def iter_repositories(self, order_by=None):
|
||||||
return (Repository.create(data[1]) for data in self.get_repository_cursor())
|
return self.iter_items(order_by, Repository)
|
||||||
|
|
||||||
def iter_sources(self):
|
def iter_sources(self, order_by=None):
|
||||||
return (Source.create(data[1]) for data in self.get_source_cursor())
|
return self.iter_items(order_by, Source)
|
||||||
|
|
||||||
def iter_tags(self):
|
def iter_tags(self):
|
||||||
return (Tag.create(data[1]) for data in self.get_tag_cursor())
|
return (Tag.create(data[1]) for data in self.get_tag_cursor())
|
||||||
|
@@ -34,6 +34,7 @@ import time
|
|||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
from sys import maxsize
|
from sys import maxsize
|
||||||
|
from operator import itemgetter
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from bsddb3 import db
|
from bsddb3 import db
|
||||||
@@ -1203,12 +1204,34 @@ class DbBsddbRead(DbReadBase, Callback):
|
|||||||
"""
|
"""
|
||||||
Closure that returns an iterator over objects in the database.
|
Closure that returns an iterator over objects in the database.
|
||||||
"""
|
"""
|
||||||
def g(self):
|
def g(self, order_by=None):
|
||||||
with curs_(self) as cursor:
|
"""
|
||||||
for key, data in cursor:
|
order_by - [[field, DIRECTION], ...]
|
||||||
obj = obj_()
|
DIRECTION is "ASC" or "DESC"
|
||||||
obj.unserialize(data)
|
"""
|
||||||
yield obj
|
if order_by is None:
|
||||||
|
with curs_(self) as cursor:
|
||||||
|
for key, data in cursor:
|
||||||
|
obj = obj_()
|
||||||
|
obj.unserialize(data)
|
||||||
|
yield obj
|
||||||
|
else:
|
||||||
|
# first build sort order:
|
||||||
|
sorted_items = []
|
||||||
|
with curs_(self) as cursor:
|
||||||
|
for key, data in cursor:
|
||||||
|
obj = obj_()
|
||||||
|
obj.unserialize(data)
|
||||||
|
# just use values and handle to keep small:
|
||||||
|
sorted_items.append((self.eval_order_by(order_by, obj), obj.handle))
|
||||||
|
# next we sort by fields and direction
|
||||||
|
pos = len(order_by) - 1
|
||||||
|
for (field, order) in reversed(order_by): # sort the lasts parts first
|
||||||
|
sorted_items.sort(key=itemgetter(pos), reverse=(order=="DESC"))
|
||||||
|
pos -= 1
|
||||||
|
# now we will look them up again:
|
||||||
|
for (order_by_values, handle) in sorted_items:
|
||||||
|
yield self._tables[obj_.__class__.__name__]["handle_func"](handle)
|
||||||
return g
|
return g
|
||||||
|
|
||||||
# Use closure to define iterators for each primary object type
|
# Use closure to define iterators for each primary object type
|
||||||
|
Reference in New Issue
Block a user