From 49b7c09cea35407acc00365b997162f4f181e9bf Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 10 Nov 2013 15:17:47 -0500 Subject: [PATCH] Revised Handle class; added get_dependencies; revised Struct class to allow changes --- gramps/gen/lib/handle.py | 38 +++++++++++++----------------------- gramps/gen/merge/diff.py | 42 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/gramps/gen/lib/handle.py b/gramps/gen/lib/handle.py index c9e519c7b..353ffaa82 100644 --- a/gramps/gen/lib/handle.py +++ b/gramps/gen/lib/handle.py @@ -22,29 +22,17 @@ from gramps.gen.constfunc import UNITYPE -class Handle: - def __init__(self, classname, handle): - """ Class to hold type and handle of referenced item """ - self.classname = classname - if handle and not isinstance(handle, UNITYPE): - handle = handle.decode('utf-8') - self.handle = handle +class HandleClass(str): + def __init__(self, handle): + super(HandleClass, self).__init__() + +def Handle(classname, handle): + if handle is None: + return None + h = HandleClass(handle) + h.classname = classname + return h - def __repr__(self): - return str({"_class": "Handle", - "handle": self.handle}) - - def __str__(self): - if self.handle: - return self.handle - else: - return "None" - - @classmethod - def from_struct(cls, struct): - if isinstance(struct, Handle): - return struct.handle - elif isinstance(struct, dict): - return struct["handle"] - else: - return struct +def __from_struct(struct): + return struct +Handle.from_struct = __from_struct diff --git a/gramps/gen/merge/diff.py b/gramps/gen/merge/diff.py index 4dd30661d..ebce791df 100644 --- a/gramps/gen/merge/diff.py +++ b/gramps/gen/merge/diff.py @@ -31,7 +31,7 @@ from ..dbstate import DbState from gramps.cli.grampscli import CLIManager from ..plug import BasePluginManager from ..db.dictionary import DictionaryDb -from gramps.gen.lib.handle import Handle +from gramps.gen.lib.handle import HandleClass from ..const import GRAMPS_LOCALE as glocale from ..constfunc import handle2internal _ = glocale.translation.gettext @@ -87,9 +87,6 @@ def diff_items(path, json1, json2): """ if json1 == json2: return False - elif isinstance(json1, Handle) and isinstance(json2, Handle): - return not (json1.classname == json2.classname and - json1.handle == json2.handle) elif isinstance(json1, list) and isinstance(json2, list): if len(json1) != len(json2): return True @@ -214,6 +211,26 @@ def from_struct(struct): return Tag.create(Tag.from_struct(struct)) raise AttributeError("invalid struct") +def get_dependencies(struct): + """ + Walk the struct recursively, getting all dependencies on other + objects. + """ + if isinstance(struct, HandleClass): + return [(struct.classname, str(struct))] + elif isinstance(struct, (tuple, list)): + retval = [] + for item in struct: + retval.extend(get_dependencies(item)) + return retval + elif isinstance(struct, dict): + retval = [] + for key in struct.keys(): + retval.extend(get_dependencies(struct[key])) + return retval + else: + return [] + class Struct(object): """ Class for getting and setting parts of a struct by dotted path. @@ -228,6 +245,7 @@ class Struct(object): def __init__(self, struct, db=None): self.struct = struct self.db = db + self.transaction = db.get_transaction_class() def __getitem__(self, path): """ @@ -283,6 +301,22 @@ class Struct(object): else: return # update the database + if self.db: + self.update_db() + + def update_db(self): + name = self.struct["_class"] + handle = self.struct["handle"] + obj = self.db.get_from_name_and_handle(name, handle) + new_obj = from_struct(self.struct) + with self.transaction("Struct Update", self.db) as trans: + if obj: + commit_func = self.db._tables[name]["commit_func"] + commit_func(new_obj, trans) + else: + add_func = self.db._tables[name]["add_func"] + add_func(new_obj, trans) def __str__(self): return str(self.struct) +