DictionaryDb: adding missing functions, bringing up to date

This commit is contained in:
Doug Blank 2015-05-13 19:26:14 -04:00
parent 6bff90419e
commit fbbd9d9c6e
3 changed files with 395 additions and 71 deletions

View File

@ -29,6 +29,8 @@ import base64
import time
import re
from gramps.gen.db import DbReadBase, DbWriteBase, DbTxn
from gramps.gen.utils.callback import Callback
from gramps.gen.updatecallback import UpdateCallback
from gramps.gen.db import (PERSON_KEY,
FAMILY_KEY,
CITATION_KEY,
@ -53,33 +55,101 @@ from gramps.gen.lib.repo import Repository
from gramps.gen.lib.note import Note
from gramps.gen.lib.tag import Tag
class Environment(object):
"""
Implements the Environment API.
"""
def __init__(self, db):
self.db = db
def txn_begin(self):
return DictionaryTxn("DictionaryDb Transaction", self.db)
class Table(object):
"""
Implements Table interface.
"""
def __init__(self, funcs):
self.funcs = funcs
def cursor(self):
"""
Returns a Cursor for this Table.
"""
return self.funcs["cursor_func"]()
def put(key, data, txn=None):
self[key] = data
class Map(dict):
"""
Implements the map API for person_map, etc.
Takes a Table() as argument.
"""
def __init__(self, tbl, *args, **kwargs):
super().__init__(*args, **kwargs)
self.db = tbl
class MetaCursor(object):
def __init__(self):
pass
def __enter__(self):
return self
def __iter__(self):
return self.__next__()
def __next__(self):
yield None
def __exit__(self, *args, **kwargs):
pass
def iter(self):
yield None
def first(self):
self._iter = self.__iter__()
return self.next()
def next(self):
try:
return next(self._iter)
except:
return None
def close(self):
pass
class Cursor(object):
"""
Iterates through model returning (handle, raw_data)...
"""
def __init__(self, model, func):
self.model = model
def __init__(self, map, func):
self.map = map
self.func = func
def __enter__(self):
return self
def __iter__(self):
return self
return self.__next__()
def __next__(self):
for handle in self.model.keys():
return (handle, self.func(handle))
def next(self):
for handle in self.model.keys():
return (handle, self.func(handle))
for item in self.map.keys():
yield (bytes(item, "utf-8"), self.func(item))
def __exit__(self, *args, **kwargs):
pass
def iter(self):
for item in self.map.keys():
yield (bytes(item, "utf-8"), self.func(item))
yield None
def first(self):
self._iter = self.__iter__()
return self.next()
def next(self):
try:
return next(self._iter)
except:
return None
def close(self):
pass
class Bookmarks:
class Bookmarks(object):
def __init__(self):
self.handles = []
def get(self):
return [] # handles
return self.handles
def append(self, handle):
pass
self.handles.append(handle)
class DictionaryTxn(DbTxn):
def __init__(self, message, db, batch=False):
@ -99,13 +169,38 @@ class DictionaryTxn(DbTxn):
"""
txn[handle] = new_data
class DictionaryDb(DbWriteBase, DbReadBase):
class DictionaryDb(DbWriteBase, DbReadBase, UpdateCallback, Callback):
"""
A Gramps Database Backend. This replicates the grampsdb functions.
"""
__signals__ = dict((obj+'-'+op, signal)
for obj in
['person', 'family', 'event', 'place',
'source', 'citation', 'media', 'note', 'repository', 'tag']
for op, signal in zip(
['add', 'update', 'delete', 'rebuild'],
[(list,), (list,), (list,), None]
)
)
# 2. Signals for long operations
__signals__.update(('long-op-'+op, signal) for op, signal in zip(
['start', 'heartbeat', 'end'],
[(object,), None, None]
))
# 3. Special signal for change in home person
__signals__['home-person-changed'] = None
# 4. Signal for change in person group name, parameters are
__signals__['person-groupname-rebuild'] = (str, str)
__callback_map = {}
def __init__(self, *args, **kwargs):
DbReadBase.__init__(self)
DbWriteBase.__init__(self)
Callback.__init__(self)
self._tables['Person'].update(
{
"handle_func": self.get_person_from_handle,
@ -115,6 +210,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_person_handles,
"add_func": self.add_person,
"commit_func": self.commit_person,
"iter_func": self.iter_people,
})
self._tables['Family'].update(
{
@ -125,6 +221,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_family_handles,
"add_func": self.add_family,
"commit_func": self.commit_family,
"iter_func": self.iter_families,
})
self._tables['Source'].update(
{
@ -135,6 +232,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_source_handles,
"add_func": self.add_source,
"commit_func": self.commit_source,
"iter_func": self.iter_sources,
})
self._tables['Citation'].update(
{
@ -145,6 +243,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_citation_handles,
"add_func": self.add_citation,
"commit_func": self.commit_citation,
"iter_func": self.iter_citations,
})
self._tables['Event'].update(
{
@ -155,6 +254,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_event_handles,
"add_func": self.add_event,
"commit_func": self.commit_event,
"iter_func": self.iter_events,
})
self._tables['Media'].update(
{
@ -165,6 +265,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_media_object_handles,
"add_func": self.add_object,
"commit_func": self.commit_media_object,
"iter_func": self.iter_media_objects,
})
self._tables['Place'].update(
{
@ -175,6 +276,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_place_handles,
"add_func": self.add_place,
"commit_func": self.commit_place,
"iter_func": self.iter_places,
})
self._tables['Repository'].update(
{
@ -185,6 +287,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_repository_handles,
"add_func": self.add_repository,
"commit_func": self.commit_repository,
"iter_func": self.iter_repositories,
})
self._tables['Note'].update(
{
@ -195,6 +298,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_note_handles,
"add_func": self.add_note,
"commit_func": self.commit_note,
"iter_func": self.iter_notes,
})
self._tables['Tag'].update(
{
@ -205,6 +309,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
"handles_func": self.get_tag_handles,
"add_func": self.add_tag,
"commit_func": self.commit_tag,
"iter_func": self.iter_tags,
})
# skip GEDCOM cross-ref check for now:
self.set_feature("skip-check-xref", True)
@ -218,7 +323,7 @@ class DictionaryDb(DbWriteBase, DbReadBase):
self.place_bookmarks = Bookmarks()
self.citation_bookmarks = Bookmarks()
self.source_bookmarks = Bookmarks()
self.repo_bookmarks = Bookmarks()
self.repository_bookmarks = Bookmarks()
self.media_bookmarks = Bookmarks()
self.note_bookmarks = Bookmarks()
self.set_person_id_prefix('I%04d')
@ -249,18 +354,18 @@ class DictionaryDb(DbWriteBase, DbReadBase):
self.omap_index = 0
self.rmap_index = 0
self.nmap_index = 0
self.env = None
self.person_map = {}
self.family_map = {}
self.place_map = {}
self.citation_map = {}
self.source_map = {}
self.repository_map = {}
self.note_map = {}
self.media_map = {}
self.event_map = {}
self.tag_map = {}
self.metadata = {}
self.env = Environment(self)
self.person_map = Map(Table(self._tables["Person"]))
self.family_map = Map(Table(self._tables["Family"]))
self.place_map = Map(Table(self._tables["Place"]))
self.citation_map = Map(Table(self._tables["Citation"]))
self.source_map = Map(Table(self._tables["Source"]))
self.repository_map = Map(Table(self._tables["Repository"]))
self.note_map = Map(Table(self._tables["Note"]))
self.media_map = Map(Table(self._tables["Media"]))
self.event_map = Map(Table(self._tables["Event"]))
self.tag_map = Map(Table(self._tables["Tag"]))
self.metadata = Map(Table({"cursor_func": lambda: MetaCursor()}))
self.name_group = {}
self.undo_callback = None
self.redo_callback = None
@ -286,9 +391,6 @@ class DictionaryDb(DbWriteBase, DbReadBase):
def transaction_commit(self, txn):
pass
def enable_signals(self):
pass
def get_undodb(self):
return None
@ -546,90 +648,106 @@ class DictionaryDb(DbWriteBase, DbReadBase):
return obj
def get_person_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
## Fixme: implement sort
return self.person_map.keys()
def get_family_handles(self):
return self.family_map.keys()
def get_event_handles(self):
def get_event_handles(self, sort_handles=False):
return self.event_map.keys()
def get_citation_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
## Fixme: implement sort
return self.citation_map.keys()
def get_source_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
## Fixme: implement sort
return self.source_map.keys()
def get_place_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
## Fixme: implement sort
return self.place_map.keys()
def get_repository_handles(self):
return self.repository_map.keys()
def get_media_object_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
## Fixme: implement sort
return self.media_map.keys()
def get_note_handles(self):
return self.note_map.keys()
def get_tag_handles(self, sort_handles=False):
if sort_handles:
raise Exception("Implement!")
else:
# FIXME: sort
return self.tag_map.keys()
def get_event_from_handle(self, handle):
return self.event_map[handle]
event = None
if handle in self.event_map:
event = self.event_map[handle]
return event
def get_family_from_handle(self, handle):
return self.family_map[handle]
family = None
if handle in self.family_map:
family = self.family_map[handle]
return family
def get_repository_from_handle(self, handle):
return self.repository_map[handle]
repository = None
if handle in self.repository_map:
repository = self.repository_map[handle]
return repository
def get_person_from_handle(self, handle):
return self.person_map[handle]
person = None
if handle in self.person_map:
person = self.person_map[handle]
return person
def get_place_from_handle(self, handle):
place = None
if handle in self.place_map:
place = self.place_map[handle]
return place
def get_citation_from_handle(self, handle):
citation = None
if handle in self.citation_map:
citation = self.citation_map[handle]
return citation
def get_source_from_handle(self, handle):
source = None
if handle in self.source_map:
source = self.source_map[handle]
return source
def get_note_from_handle(self, handle):
note = None
if handle in self.note_map:
note = self.note_map[handle]
return note
def get_object_from_handle(self, handle):
media = None
if handle in self.media_map:
media = self.media_map[handle]
return media
def get_tag_from_handle(self, handle):
tag = None
if handle in self.tag_map:
tag = self.tag_map[handle]
return tag
def get_default_person(self):
handle = self.get_default_handle()
if handle:
return self.get_person_from_handle(handle)
else:
return None
def iter_people(self):
@ -1203,3 +1321,205 @@ class DictionaryDb(DbWriteBase, DbReadBase):
transaction.add(REFERENCE_KEY, TXNDEL, key, old_data, None)
#transaction.reference_del.append(str(key))
self.reference_map.delete(key, txn=txn)
## Missing:
def backup(self):
pass
def close(self):
pass
def find_backlink_handles(self, handle, include_classes=None):
return []
def find_initial_person(self):
items = self.person_map.keys()
if len(items) > 0:
return self.get_person_from_handle(list(items)[0])
return None
def find_place_child_handles(self, handle):
return []
def get_bookmarks(self):
return self.bookmarks
def get_child_reference_types(self):
return []
def get_citation_bookmarks(self):
return self.citation_bookmarks
def get_cursor(self, table, txn=None, update=False, commit=False):
pass
def get_dbname(self):
return "DictionaryDb"
def get_default_handle(self):
items = self.person_map.keys()
if len(items) > 0:
return list(items)[0]
return None
def get_event_attribute_types(self):
return []
def get_event_bookmarks(self):
return self.event_bookmarks
def get_event_roles(self):
return []
def get_event_types(self):
return []
def get_family_attribute_types(self):
return []
def get_family_bookmarks(self):
return self.family_bookmarks
def get_family_event_types(self):
return []
def get_family_relation_types(self):
return []
def get_media_attribute_types(self):
return []
def get_media_bookmarks(self):
return self.media_bookmarks
def get_name_types(self):
return []
def get_note_bookmarks(self):
return self.note_bookmarks
def get_note_types(self):
return []
def get_number_of_records(self, table):
return 0
def get_origin_types(self):
return []
def get_person_attribute_types(self):
return []
def get_person_event_types(self):
return []
def get_place_bookmarks(self):
return self.place_bookmarks
def get_place_tree_cursor(self):
return []
def get_place_types(self):
return []
def get_repo_bookmarks(self):
return self.repository_bookmarks
def get_repository_types(self):
return []
def get_save_path(self):
return self._directory
def get_source_attribute_types(self):
return []
def get_source_bookmarks(self):
return self.source_bookmarks
def get_source_media_types(self):
return []
def get_surname_list(self):
return []
def get_url_types(self):
return []
def has_changed(self):
return True
def is_open(self):
return True
def iter_citation_handles(self):
return (key for key in self.citation_map.keys())
def iter_citations(self):
return (key for key in self.citation_map.values())
def iter_event_handles(self):
return (key for key in self.event_map.keys())
def iter_events(self):
return (key for key in self.event_map.values())
def iter_media_objects(self):
return (key for key in self.media_map.values())
def iter_note_handles(self):
return (key for key in self.note_map.keys())
def iter_notes(self):
return (key for key in self.note_map.values())
def iter_place_handles(self):
return (key for key in self.place_map.keys())
def iter_places(self):
return (key for key in self.place_map.values())
def iter_repositories(self):
return (key for key in self.repositories_map.values())
def iter_repository_handles(self):
return (key for key in self.repositories_map.keys())
def iter_source_handles(self):
return (key for key in self.source_map.keys())
def iter_sources(self):
return (key for key in self.source_map.values())
def iter_tag_handles(self):
return (key for key in self.tag_map.keys())
def iter_tags(self):
return (key for key in self.tag_map.values())
def load(self, directory, pulse_progress, mode,
force_schema_upgrade,
force_bsddb_upgrade,
force_bsddb_downgrade,
force_python_upgrade):
self._directory = directory
def prepare_import(self):
pass
def redo(self, update_history=True):
pass
def restore(self):
pass
def set_prefixes(self, person, media, family, source, citation,
place, event, repository, note):
pass
def set_save_path(self, directory):
self._directory = directory
def undo(self, update_history=True):
pass

View File

@ -68,7 +68,7 @@ class Environment(object):
self.db = db
def txn_begin(self):
return DjangoTxn("DbDjango Transaction", self.db)
return DjangoTxn("DjangoDb Transaction", self.db)
class Table(object):
"""
@ -210,6 +210,8 @@ class DbDjango(DbWriteBase, DbReadBase, UpdateCallback, Callback):
# 4. Signal for change in person group name, parameters are
__signals__['person-groupname-rebuild'] = (str, str)
__callback_map = {}
def __init__(self, directory=None):
DbReadBase.__init__(self)
DbWriteBase.__init__(self)
@ -1745,8 +1747,6 @@ class DbDjango(DbWriteBase, DbReadBase, UpdateCallback, Callback):
self.get_number_of_media_objects() == 0 and
self.get_number_of_repositories() == 0)
__callback_map = {}
def set_prefixes(self, person, media, family, source, citation,
place, event, repository, note):
self.set_person_id_prefix(person)

View File

@ -143,8 +143,12 @@ def get_person_from_handle(db, handle):
return None
def probably_alive(handle):
## FIXME: need to call after save?
person = db.get_person_from_handle(handle)
if person:
return alive(person, db)
else:
return True
def format_number(number, with_grouping=True):
if number != "":