9744: Tidy up iterators
Remove order_by parameter. Add unit tests.
This commit is contained in:
parent
1905d417be
commit
9fc316abdf
@ -50,35 +50,6 @@ from .exceptions import DbTransactionCancel
|
||||
|
||||
_LOG = logging.getLogger(DBLOGNAME)
|
||||
|
||||
def eval_order_by(order_by, obj, db):
|
||||
"""
|
||||
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, db, ignore_errors=True))
|
||||
return values
|
||||
|
||||
def sort_objects(objects, order_by, db):
|
||||
"""
|
||||
Python-based sorting.
|
||||
"""
|
||||
# first build sort order:
|
||||
sorted_items = []
|
||||
map_items = {}
|
||||
for obj in objects:
|
||||
# just use values and handle to keep small:
|
||||
sorted_items.append((eval_order_by(order_by, obj, db), obj.handle))
|
||||
map_items[obj.handle] = obj
|
||||
# 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
|
||||
for (order_by_values, handle) in sorted_items:
|
||||
yield map_items[handle]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps libraries
|
||||
@ -953,7 +924,7 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_citations(self, order_by=None):
|
||||
def iter_citations(self):
|
||||
"""
|
||||
Return an iterator over objects for Citations in the database
|
||||
"""
|
||||
@ -965,13 +936,13 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_events(self, order_by=None):
|
||||
def iter_events(self):
|
||||
"""
|
||||
Return an iterator over objects for Events in the database
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_families(self, order_by=None):
|
||||
def iter_families(self):
|
||||
"""
|
||||
Return an iterator over objects for Families in the database
|
||||
"""
|
||||
@ -989,7 +960,7 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_media(self, order_by=None):
|
||||
def iter_media(self):
|
||||
"""
|
||||
Return an iterator over objects for Medias in the database
|
||||
"""
|
||||
@ -1001,13 +972,13 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_notes(self, order_by=None):
|
||||
def iter_notes(self):
|
||||
"""
|
||||
Return an iterator over objects for Notes in the database
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
def iter_people(self):
|
||||
"""
|
||||
Return an iterator over objects for Persons in the database
|
||||
"""
|
||||
@ -1025,13 +996,13 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_places(self, order_by=None):
|
||||
def iter_places(self):
|
||||
"""
|
||||
Return an iterator over objects for Places in the database
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_repositories(self, order_by=None):
|
||||
def iter_repositories(self):
|
||||
"""
|
||||
Return an iterator over objects for Repositories in the database
|
||||
"""
|
||||
@ -1049,7 +1020,7 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_sources(self, order_by=None):
|
||||
def iter_sources(self):
|
||||
"""
|
||||
Return an iterator over objects for Sources in the database
|
||||
"""
|
||||
@ -1061,7 +1032,7 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def iter_tags(self, order_by=None):
|
||||
def iter_tags(self):
|
||||
"""
|
||||
Return an iterator over objects for Tags in the database
|
||||
"""
|
||||
|
@ -51,8 +51,7 @@ from gramps.gen.db import (DbReadBase, DbWriteBase, DbTxn, DbUndo,
|
||||
CLASS_TO_KEY_MAP, TXNADD, TXNUPD, TXNDEL,
|
||||
PERSON_KEY, FAMILY_KEY, CITATION_KEY,
|
||||
SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
|
||||
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY,
|
||||
TAG_KEY, eval_order_by)
|
||||
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY)
|
||||
from gramps.gen.errors import HandleError
|
||||
from gramps.gen.utils.callback import Callback
|
||||
from gramps.gen.updatecallback import UpdateCallback
|
||||
@ -1217,47 +1216,43 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
else:
|
||||
return None
|
||||
|
||||
def iter_items(self, order_by, class_):
|
||||
def _iter_objects(self, class_):
|
||||
"""
|
||||
Iterate over items in a class, possibly ordered by
|
||||
a list of field names and direction ("ASC" or "DESC").
|
||||
Iterate over items in a class.
|
||||
"""
|
||||
cursor = self.get_table_func(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((eval_order_by(order_by, obj, self), obj.handle))
|
||||
# next we sort by fields and direction
|
||||
def getitem(item, pos):
|
||||
sort_items = item[0]
|
||||
if isinstance(sort_items[pos], str):
|
||||
return sort_items[pos]
|
||||
elif sort_items[pos] is None:
|
||||
return ""
|
||||
else:
|
||||
# FIXME: should do something clever/recurive to
|
||||
# sort these meaningfully, and return a string:
|
||||
return str(sort_items[pos])
|
||||
pos = len(order_by) - 1
|
||||
for (field, order) in reversed(order_by): # sort the lasts parts first
|
||||
sorted_items.sort(key=lambda item: getitem(item, pos),
|
||||
reverse=(order=="DESC"))
|
||||
pos -= 1
|
||||
# now we will look them up again:
|
||||
for (order_by_values, handle) in sorted_items:
|
||||
yield self.get_table_func(class_.__name__,"handle_func")(handle)
|
||||
for data in cursor():
|
||||
yield class_.create(data[1])
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
return self.iter_items(order_by, Person)
|
||||
def iter_people(self):
|
||||
return self._iter_objects(Person)
|
||||
|
||||
def iter_families(self, order_by=None):
|
||||
return self.iter_items(order_by, Family)
|
||||
def iter_families(self):
|
||||
return self._iter_objects(Family)
|
||||
|
||||
def iter_citations(self):
|
||||
return self._iter_objects(Citation)
|
||||
|
||||
def iter_events(self):
|
||||
return self._iter_objects(Event)
|
||||
|
||||
def iter_media(self):
|
||||
return self._iter_objects(Media)
|
||||
|
||||
def iter_notes(self):
|
||||
return self._iter_objects(Note)
|
||||
|
||||
def iter_places(self):
|
||||
return self._iter_objects(Place)
|
||||
|
||||
def iter_repositories(self):
|
||||
return self._iter_objects(Repository)
|
||||
|
||||
def iter_sources(self):
|
||||
return self._iter_objects(Source)
|
||||
|
||||
def iter_tags(self):
|
||||
return self._iter_objects(Tag)
|
||||
|
||||
def get_person_from_gramps_id(self, gramps_id):
|
||||
data = self._get_raw_person_from_id_data(gramps_id)
|
||||
@ -1838,30 +1833,6 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
def is_open(self):
|
||||
return self.db_is_open
|
||||
|
||||
def iter_citations(self, order_by=None):
|
||||
return self.iter_items(order_by, Citation)
|
||||
|
||||
def iter_events(self, order_by=None):
|
||||
return self.iter_items(order_by, Event)
|
||||
|
||||
def iter_media(self, order_by=None):
|
||||
return self.iter_items(order_by, Media)
|
||||
|
||||
def iter_notes(self, order_by=None):
|
||||
return self.iter_items(order_by, Note)
|
||||
|
||||
def iter_places(self, order_by=None):
|
||||
return self.iter_items(order_by, Place)
|
||||
|
||||
def iter_repositories(self, order_by=None):
|
||||
return self.iter_items(order_by, Repository)
|
||||
|
||||
def iter_sources(self, order_by=None):
|
||||
return self.iter_items(order_by, Source)
|
||||
|
||||
def iter_tags(self, order_by=None):
|
||||
return self.iter_items(order_by, Tag)
|
||||
|
||||
def set_prefixes(self, person, media, family, source, citation,
|
||||
place, event, repository, note):
|
||||
self.set_person_id_prefix(person)
|
||||
|
@ -30,7 +30,6 @@ Proxy class for the Gramps databases. Apply filter
|
||||
# Gramps libraries
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.db.base import sort_objects
|
||||
from .proxybase import ProxyDbBase
|
||||
from ..lib import (Date, Person, Name, Surname, NameOriginType, Family, Source,
|
||||
Citation, Event, Media, Place, Repository, Note, Tag)
|
||||
@ -516,14 +515,11 @@ class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
return self.plist
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
def iter_people(self):
|
||||
"""
|
||||
Return an iterator over objects for Persons in the database
|
||||
"""
|
||||
if order_by:
|
||||
return sort_objects(map(self.get_person_from_handle, self.plist), order_by, self)
|
||||
else:
|
||||
return map(self.get_person_from_handle, self.plist)
|
||||
return map(self.get_person_from_handle, self.plist)
|
||||
|
||||
def get_event_handles(self):
|
||||
"""
|
||||
@ -539,14 +535,11 @@ class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
return self.elist
|
||||
|
||||
def iter_events(self, order_by=None):
|
||||
def iter_events(self):
|
||||
"""
|
||||
Return an iterator over objects for Events in the database
|
||||
"""
|
||||
if order_by:
|
||||
return sort_objects(map(self.get_event_from_handle, self.elist), order_by, self)
|
||||
else:
|
||||
return map(self.get_event_from_handle, self.elist)
|
||||
return map(self.get_event_from_handle, self.elist)
|
||||
|
||||
def get_family_handles(self, sort_handles=False):
|
||||
"""
|
||||
@ -563,14 +556,11 @@ class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
return self.flist
|
||||
|
||||
def iter_families(self, order_by=None):
|
||||
def iter_families(self):
|
||||
"""
|
||||
Return an iterator over objects for Families in the database
|
||||
"""
|
||||
if order_by:
|
||||
return sort_objects(map(self.get_family_from_handle, self.flist), order_by, self)
|
||||
else:
|
||||
return map(self.get_family_from_handle, self.flist)
|
||||
return map(self.get_family_from_handle, self.flist)
|
||||
|
||||
def get_note_handles(self):
|
||||
"""
|
||||
@ -586,14 +576,11 @@ class FilterProxyDb(ProxyDbBase):
|
||||
"""
|
||||
return self.nlist
|
||||
|
||||
def iter_notes(self, order_by=None):
|
||||
def iter_notes(self):
|
||||
"""
|
||||
Return an iterator over objects for Notes in the database
|
||||
"""
|
||||
if order_by:
|
||||
return sort_objects(map(self.get_note_from_handle, self.nlist), order_by, self)
|
||||
else:
|
||||
return map(self.get_note_from_handle, self.nlist)
|
||||
return map(self.get_note_from_handle, self.nlist)
|
||||
|
||||
def get_default_person(self):
|
||||
"""returns the default Person of the database"""
|
||||
|
@ -33,7 +33,6 @@ from ..lib import (Date, Person, Name, Surname, NameOriginType, Family, Source,
|
||||
Citation, Event, Media, Place, Repository, Note, Tag)
|
||||
from ..utils.alive import probably_alive
|
||||
from ..config import config
|
||||
from gramps.gen.db.base import sort_objects
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -234,32 +233,18 @@ class LivingProxyDb(ProxyDbBase):
|
||||
family = self.__remove_living_from_family(family)
|
||||
return family
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
def iter_people(self):
|
||||
"""
|
||||
Protected version of iter_people
|
||||
"""
|
||||
if order_by:
|
||||
retval = []
|
||||
for person in filter(None, self.db.iter_people()):
|
||||
if self.__is_living(person):
|
||||
if self.mode == self.MODE_EXCLUDE_ALL:
|
||||
continue
|
||||
else:
|
||||
retval.append(self.__restrict_person(person))
|
||||
for person in filter(None, self.db.iter_people()):
|
||||
if self.__is_living(person):
|
||||
if self.mode == self.MODE_EXCLUDE_ALL:
|
||||
continue
|
||||
else:
|
||||
retval.append(person)
|
||||
retval = sort_objects(retval, order_by, self)
|
||||
for item in retval:
|
||||
yield item
|
||||
else:
|
||||
for person in filter(None, self.db.iter_people()):
|
||||
if self.__is_living(person):
|
||||
if self.mode == self.MODE_EXCLUDE_ALL:
|
||||
continue
|
||||
else:
|
||||
yield self.__restrict_person(person)
|
||||
else:
|
||||
yield person
|
||||
yield self.__restrict_person(person)
|
||||
else:
|
||||
yield person
|
||||
|
||||
def get_person_from_gramps_id(self, val):
|
||||
"""
|
||||
|
@ -35,7 +35,7 @@ import types
|
||||
# Gramps libraries
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..db.base import DbReadBase, DbWriteBase, sort_objects
|
||||
from ..db.base import DbReadBase, DbWriteBase
|
||||
from ..lib import (Citation, Event, Family, Media, Note, Person, Place,
|
||||
Repository, Source, Tag)
|
||||
|
||||
@ -498,85 +498,82 @@ class ProxyDbBase(DbReadBase):
|
||||
"""
|
||||
return filter(self.include_tag, self.db.iter_tag_handles())
|
||||
|
||||
def __iter_object(self, selector, method, order_by=None):
|
||||
def __iter_object(self, selector, method):
|
||||
""" Helper function to return an iterator over an object class """
|
||||
retval = filter(lambda obj:
|
||||
((selector is None) or selector(obj.handle)),
|
||||
method())
|
||||
if order_by:
|
||||
return sort_objects([item for item in retval], order_by, self)
|
||||
else:
|
||||
return retval
|
||||
return retval
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
def iter_people(self):
|
||||
"""
|
||||
Return an iterator over Person objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_person,
|
||||
self.db.iter_people, order_by)
|
||||
self.db.iter_people)
|
||||
|
||||
def iter_families(self, order_by=None):
|
||||
def iter_families(self):
|
||||
"""
|
||||
Return an iterator over Family objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_family,
|
||||
self.db.iter_families, order_by)
|
||||
self.db.iter_families)
|
||||
|
||||
def iter_events(self, order_by=None):
|
||||
def iter_events(self):
|
||||
"""
|
||||
Return an iterator over Event objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_event,
|
||||
self.db.iter_events, order_by)
|
||||
self.db.iter_events)
|
||||
|
||||
def iter_places(self, order_by=None):
|
||||
def iter_places(self):
|
||||
"""
|
||||
Return an iterator over Place objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_place,
|
||||
self.db.iter_places, order_by)
|
||||
self.db.iter_places)
|
||||
|
||||
def iter_sources(self, order_by=None):
|
||||
def iter_sources(self):
|
||||
"""
|
||||
Return an iterator over Source objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_source,
|
||||
self.db.iter_sources, order_by)
|
||||
self.db.iter_sources)
|
||||
|
||||
def iter_citations(self, order_by=None):
|
||||
def iter_citations(self):
|
||||
"""
|
||||
Return an iterator over Citation objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_citation,
|
||||
self.db.iter_citations, order_by)
|
||||
self.db.iter_citations)
|
||||
|
||||
def iter_media(self, order_by=None):
|
||||
def iter_media(self):
|
||||
"""
|
||||
Return an iterator over Media objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_media,
|
||||
self.db.iter_media, order_by)
|
||||
self.db.iter_media)
|
||||
|
||||
def iter_repositories(self, order_by=None):
|
||||
def iter_repositories(self):
|
||||
"""
|
||||
Return an iterator over Repositories objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_repository,
|
||||
self.db.iter_repositories, order_by)
|
||||
self.db.iter_repositories)
|
||||
|
||||
def iter_notes(self, order_by=None):
|
||||
def iter_notes(self):
|
||||
"""
|
||||
Return an iterator over Note objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_note,
|
||||
self.db.iter_notes, order_by)
|
||||
self.db.iter_notes)
|
||||
|
||||
def iter_tags(self, order_by=None):
|
||||
def iter_tags(self):
|
||||
"""
|
||||
Return an iterator over Tag objects in the database
|
||||
"""
|
||||
return self.__iter_object(self.include_tag,
|
||||
self.db.iter_tags, order_by)
|
||||
self.db.iter_tags)
|
||||
|
||||
@staticmethod
|
||||
def gfilter(predicate, obj):
|
||||
|
@ -71,7 +71,7 @@ from gramps.gen.lib.nameorigintype import NameOriginType
|
||||
|
||||
from gramps.gen.utils.callback import Callback
|
||||
from . import BsddbBaseCursor
|
||||
from gramps.gen.db.base import DbReadBase, eval_order_by
|
||||
from gramps.gen.db.base import DbReadBase
|
||||
from gramps.gen.utils.id import create_id
|
||||
from gramps.gen.errors import DbError, HandleError
|
||||
from gramps.gen.constfunc import get_env_var
|
||||
@ -1260,34 +1260,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
Closure that returns an iterator over objects in the database.
|
||||
"""
|
||||
def g(self, order_by=None):
|
||||
"""
|
||||
order_by - [[field, DIRECTION], ...]
|
||||
DIRECTION is "ASC" or "DESC"
|
||||
"""
|
||||
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((eval_order_by(order_by, obj, self), 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.get_table_func(obj_.__name__,"handle_func")(handle)
|
||||
def g(self):
|
||||
with curs_(self) as cursor:
|
||||
for key, data in cursor:
|
||||
obj = obj_()
|
||||
obj.unserialize(data)
|
||||
yield obj
|
||||
return g
|
||||
|
||||
# Use closure to define iterators for each primary object type
|
||||
|
@ -37,7 +37,6 @@ import logging
|
||||
# Gramps Modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.db.base import eval_order_by
|
||||
from gramps.gen.db.dbconst import (DBLOGNAME, DBBACKEND, KEY_TO_NAME_MAP,
|
||||
TXNADD, TXNUPD, TXNDEL,
|
||||
PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
|
||||
@ -1014,152 +1013,77 @@ class DBAPI(DbGeneric):
|
||||
if row:
|
||||
return self.get_person_from_handle(row[0])
|
||||
|
||||
def iter_items_order_by_python(self, order_by, class_):
|
||||
def _iter_handles(self, obj_key):
|
||||
"""
|
||||
This method is for those iter_items with a order_by, but
|
||||
can't be done with secondary fields.
|
||||
Return an iterator over handles in the database
|
||||
"""
|
||||
# first build sort order:
|
||||
sorted_items = []
|
||||
query = "SELECT blob_data FROM %s;" % class_.__name__.lower()
|
||||
self.dbapi.execute(query)
|
||||
table = KEY_TO_NAME_MAP[obj_key]
|
||||
sql = "SELECT handle FROM %s" % table
|
||||
self.dbapi.execute(sql)
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
obj = self.get_table_func(class_.__name__,
|
||||
"class_func").create(pickle.loads(row[0]))
|
||||
# just use values and handle to keep small:
|
||||
sorted_items.append((eval_order_by(order_by, obj, self),
|
||||
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.get_table_func(class_.__name__, "handle_func")(handle)
|
||||
|
||||
def iter_items(self, order_by, class_):
|
||||
"""
|
||||
Iterate over items in a class, possibly ordered by
|
||||
a list of field names and direction ("ASC" or "DESC").
|
||||
"""
|
||||
# check if order_by fields are secondary
|
||||
# if so, fine
|
||||
# else, use Python sorts
|
||||
if order_by:
|
||||
secondary_fields = class_.get_secondary_fields()
|
||||
if not self._check_order_by_fields(class_.__name__,
|
||||
order_by, secondary_fields):
|
||||
for item in self.iter_items_order_by_python(order_by, class_):
|
||||
yield item
|
||||
return
|
||||
## Continue with dbapi select
|
||||
if order_by is None:
|
||||
query = "SELECT blob_data FROM %s;" % class_.__name__.lower()
|
||||
else:
|
||||
order_phrases = [
|
||||
"%s %s" % (self._hash_name(class_.__name__,
|
||||
class_.get_field_alias(field)),
|
||||
direction)
|
||||
for (field, direction) in order_by]
|
||||
query = "SELECT blob_data FROM %s ORDER BY %s;" % (
|
||||
class_.__name__.lower(), ", ".join(order_phrases))
|
||||
self.dbapi.execute(query)
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield class_.create(pickle.loads(row[0]))
|
||||
yield row[0]
|
||||
|
||||
def iter_person_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Persons in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM person;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(PERSON_KEY)
|
||||
|
||||
def iter_family_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Families in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM family;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(FAMILY_KEY)
|
||||
|
||||
def iter_citation_handles(self):
|
||||
"""
|
||||
Return an iterator over database handles, one handle for each Citation
|
||||
in the database.
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM citation;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(CITATION_KEY)
|
||||
|
||||
def iter_event_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Events in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM event;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(EVENT_KEY)
|
||||
|
||||
def iter_media_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Media in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM media;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(MEDIA_KEY)
|
||||
|
||||
def iter_note_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Notes in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM note;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(NOTE_KEY)
|
||||
|
||||
def iter_place_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Places in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM place;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(PLACE_KEY)
|
||||
|
||||
def iter_repository_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Repositories in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM repository;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(REPOSITORY_KEY)
|
||||
|
||||
def iter_source_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Sources in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM source;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(SOURCE_KEY)
|
||||
|
||||
def iter_tag_handles(self):
|
||||
"""
|
||||
Return an iterator over handles for Tags in the database
|
||||
"""
|
||||
self.dbapi.execute("SELECT handle FROM tag;")
|
||||
rows = self.dbapi.fetchall()
|
||||
for row in rows:
|
||||
yield row[0]
|
||||
return self._iter_handles(TAG_KEY)
|
||||
|
||||
def _iter_raw_data(self, obj_key):
|
||||
"""
|
||||
@ -1725,19 +1649,6 @@ class DBAPI(DbGeneric):
|
||||
else:
|
||||
return repr(value)
|
||||
|
||||
def _check_order_by_fields(self, table, order_by, secondary_fields):
|
||||
"""
|
||||
Check to make sure all order_by fields are defined. If not, then
|
||||
we need to do the Python-based order.
|
||||
|
||||
secondary_fields are hashed.
|
||||
"""
|
||||
if order_by:
|
||||
for (field, directory) in order_by:
|
||||
if self._hash_name(table, field) not in secondary_fields:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_summary(self):
|
||||
"""
|
||||
Returns dictionary of summary item.
|
||||
|
@ -506,6 +506,106 @@ class DbTest(unittest.TestCase):
|
||||
self.__get_cursor_test(self.db.get_tag_cursor,
|
||||
self.db.get_raw_tag_data)
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Test iter_*_handles methods
|
||||
#
|
||||
################################################################
|
||||
|
||||
def __iter_handles_test(self, obj_type, iter_func):
|
||||
for handle in iter_func():
|
||||
self.assertIn(handle, self.handles[obj_type])
|
||||
|
||||
def test_iter_person_handles(self):
|
||||
self.__iter_handles_test('Person',
|
||||
self.db.iter_person_handles)
|
||||
|
||||
def test_iter_family_handles(self):
|
||||
self.__iter_handles_test('Family',
|
||||
self.db.iter_family_handles)
|
||||
|
||||
def test_iter_event_handles(self):
|
||||
self.__iter_handles_test('Event',
|
||||
self.db.iter_event_handles)
|
||||
|
||||
def test_iter_place_handles(self):
|
||||
self.__iter_handles_test('Place',
|
||||
self.db.iter_place_handles)
|
||||
|
||||
def test_iter_repository_handles(self):
|
||||
self.__iter_handles_test('Repository',
|
||||
self.db.iter_repository_handles)
|
||||
|
||||
def test_iter_source_handles(self):
|
||||
self.__iter_handles_test('Source',
|
||||
self.db.iter_source_handles)
|
||||
|
||||
def test_iter_citation_handles(self):
|
||||
self.__iter_handles_test('Citation',
|
||||
self.db.iter_citation_handles)
|
||||
|
||||
def test_iter_media_handles(self):
|
||||
self.__iter_handles_test('Media',
|
||||
self.db.iter_media_handles)
|
||||
|
||||
def test_iter_note_handles(self):
|
||||
self.__iter_handles_test('Note',
|
||||
self.db.iter_note_handles)
|
||||
|
||||
def test_iter_tag_handles(self):
|
||||
self.__iter_handles_test('Tag',
|
||||
self.db.iter_tag_handles)
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Test iter_* methods
|
||||
#
|
||||
################################################################
|
||||
|
||||
def __iter_objects_test(self, obj_class, iter_func):
|
||||
for obj in iter_func():
|
||||
self.assertIsInstance(obj, obj_class)
|
||||
|
||||
def test_iter_people(self):
|
||||
self.__iter_objects_test(Person,
|
||||
self.db.iter_people)
|
||||
|
||||
def test_iter_families(self):
|
||||
self.__iter_objects_test(Family,
|
||||
self.db.iter_families)
|
||||
|
||||
def test_iter_events(self):
|
||||
self.__iter_objects_test(Event,
|
||||
self.db.iter_events)
|
||||
|
||||
def test_iter_places(self):
|
||||
self.__iter_objects_test(Place,
|
||||
self.db.iter_places)
|
||||
|
||||
def test_iter_repositories(self):
|
||||
self.__iter_objects_test(Repository,
|
||||
self.db.iter_repositories)
|
||||
|
||||
def test_iter_sources(self):
|
||||
self.__iter_objects_test(Source,
|
||||
self.db.iter_sources)
|
||||
|
||||
def test_iter_citations(self):
|
||||
self.__iter_objects_test(Citation,
|
||||
self.db.iter_citations)
|
||||
|
||||
def test_iter_media(self):
|
||||
self.__iter_objects_test(Media,
|
||||
self.db.iter_media)
|
||||
|
||||
def test_iter_notes(self):
|
||||
self.__iter_objects_test(Note,
|
||||
self.db.iter_notes)
|
||||
|
||||
def test_iter_tags(self):
|
||||
self.__iter_objects_test(Tag,
|
||||
self.db.iter_tags)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -1341,7 +1341,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
"""
|
||||
return self.db_is_open
|
||||
|
||||
def iter_citations(self, order_by=None):
|
||||
def iter_citations(self):
|
||||
"""
|
||||
Return an iterator over objects for Citations in the database
|
||||
"""
|
||||
@ -1357,7 +1357,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_events(self, order_by=None):
|
||||
def iter_events(self):
|
||||
"""
|
||||
Return an iterator over objects for Events in the database
|
||||
"""
|
||||
@ -1365,7 +1365,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_families(self, order_by=None):
|
||||
def iter_families(self):
|
||||
"""
|
||||
Return an iterator over objects for Families in the database
|
||||
"""
|
||||
@ -1389,7 +1389,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_media(self, order_by=None):
|
||||
def iter_media(self):
|
||||
"""
|
||||
Return an iterator over objects for Medias in the database
|
||||
"""
|
||||
@ -1405,7 +1405,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_notes(self, order_by=None):
|
||||
def iter_notes(self):
|
||||
"""
|
||||
Return an iterator over objects for Notes in the database
|
||||
"""
|
||||
@ -1413,7 +1413,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_people(self, order_by=None):
|
||||
def iter_people(self):
|
||||
"""
|
||||
Return an iterator over objects for Persons in the database
|
||||
"""
|
||||
@ -1437,7 +1437,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_places(self, order_by=None):
|
||||
def iter_places(self):
|
||||
"""
|
||||
Return an iterator over objects for Places in the database
|
||||
"""
|
||||
@ -1445,7 +1445,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_repositories(self, order_by=None):
|
||||
def iter_repositories(self):
|
||||
"""
|
||||
Return an iterator over objects for Repositories in the database
|
||||
"""
|
||||
@ -1469,7 +1469,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_sources(self, order_by=None):
|
||||
def iter_sources(self):
|
||||
"""
|
||||
Return an iterator over objects for Sources in the database
|
||||
"""
|
||||
@ -1485,7 +1485,7 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return []
|
||||
|
||||
def iter_tags(self, order_by=None):
|
||||
def iter_tags(self):
|
||||
"""
|
||||
Return an iterator over objects for Tags in the database
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user