json_db: move json to python conversion logic from
StoredDict to json_db. convert_key, convert_value are used to convert json objects to python classes, do not call them in StoredDict.__setitem__ This makes StoredDict agnostic about the type of database we use.
This commit is contained in:
@@ -163,16 +163,9 @@ class StoredDict(dict):
|
|||||||
for k, vv in v.items():
|
for k, vv in v.items():
|
||||||
v.__setitem__(k, vv, patch=False)
|
v.__setitem__(k, vv, patch=False)
|
||||||
# recursively convert dict to StoredDict.
|
# recursively convert dict to StoredDict.
|
||||||
# _convert_dict is called breadth-first
|
|
||||||
elif isinstance(v, dict):
|
elif isinstance(v, dict):
|
||||||
if self.db:
|
|
||||||
v = self.db._convert_dict(self.path, key, v)
|
|
||||||
if not self.db or self.db._should_convert_to_stored_dict(key):
|
if not self.db or self.db._should_convert_to_stored_dict(key):
|
||||||
v = StoredDict(v, self.db, self.path + [key])
|
v = StoredDict(v, self.db, self.path + [key])
|
||||||
# convert_value is called depth-first
|
|
||||||
if isinstance(v, dict) or isinstance(v, str) or isinstance(v, int):
|
|
||||||
if self.db:
|
|
||||||
v = self.db._convert_value(self.path, key, v)
|
|
||||||
# set parent of StoredObject
|
# set parent of StoredObject
|
||||||
if isinstance(v, StoredObject):
|
if isinstance(v, StoredObject):
|
||||||
v.set_db(self.db, self.path + [key])
|
v.set_db(self.db, self.path + [key])
|
||||||
@@ -263,7 +256,9 @@ class JsonDB(Logger):
|
|||||||
if upgrader:
|
if upgrader:
|
||||||
data, was_upgraded = upgrader(data)
|
data, was_upgraded = upgrader(data)
|
||||||
self._modified |= was_upgraded
|
self._modified |= was_upgraded
|
||||||
# convert to StoredDict
|
# convert json to python objects
|
||||||
|
data = self._convert_dict([], data)
|
||||||
|
# convert dict to StoredDict
|
||||||
self.data = StoredDict(data, self, [])
|
self.data = StoredDict(data, self, [])
|
||||||
# write file in case there was a db upgrade
|
# write file in case there was a db upgrade
|
||||||
if self.storage and self.storage.file_exists():
|
if self.storage and self.storage.file_exists():
|
||||||
@@ -391,7 +386,22 @@ class JsonDB(Logger):
|
|||||||
def _should_convert_to_stored_dict(self, key) -> bool:
|
def _should_convert_to_stored_dict(self, key) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _convert_dict(self, path, key, v):
|
def _convert_dict_key(self, path):
|
||||||
|
key = path[-1]
|
||||||
|
parent_key = path[-2] if len(path) > 1 else None
|
||||||
|
gp_key = path[-3] if len(path) > 2 else None
|
||||||
|
if parent_key and parent_key in registered_dict_keys:
|
||||||
|
convert_key = registered_dict_keys[parent_key]
|
||||||
|
elif gp_key and gp_key in registered_parent_keys:
|
||||||
|
convert_key = registered_parent_keys.get(gp_key)
|
||||||
|
else:
|
||||||
|
convert_key = None
|
||||||
|
if convert_key:
|
||||||
|
key = convert_key(key)
|
||||||
|
return key
|
||||||
|
|
||||||
|
def _convert_dict_value(self, path, v):
|
||||||
|
key = path[-1]
|
||||||
if key in registered_dicts:
|
if key in registered_dicts:
|
||||||
constructor, _type = registered_dicts[key]
|
constructor, _type = registered_dicts[key]
|
||||||
if _type == dict:
|
if _type == dict:
|
||||||
@@ -400,25 +410,26 @@ class JsonDB(Logger):
|
|||||||
v = dict((k, constructor(*x)) for k, x in v.items())
|
v = dict((k, constructor(*x)) for k, x in v.items())
|
||||||
else:
|
else:
|
||||||
v = dict((k, constructor(x)) for k, x in v.items())
|
v = dict((k, constructor(x)) for k, x in v.items())
|
||||||
if key in registered_dict_keys:
|
elif key in registered_names:
|
||||||
convert_key = registered_dict_keys[key]
|
|
||||||
elif path and path[-1] in registered_parent_keys:
|
|
||||||
convert_key = registered_parent_keys.get(path[-1])
|
|
||||||
else:
|
|
||||||
convert_key = None
|
|
||||||
if convert_key:
|
|
||||||
v = dict((convert_key(k), x) for k, x in v.items())
|
|
||||||
return v
|
|
||||||
|
|
||||||
def _convert_value(self, path, key, v):
|
|
||||||
if key in registered_names:
|
|
||||||
constructor, _type = registered_names[key]
|
constructor, _type = registered_names[key]
|
||||||
if _type == dict:
|
if _type == dict:
|
||||||
v = constructor(**v)
|
v = constructor(**v)
|
||||||
else:
|
else:
|
||||||
v = constructor(v)
|
v = constructor(v)
|
||||||
|
if isinstance(v, dict):
|
||||||
|
v = self._convert_dict(path, v)
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
def _convert_dict(self, path, data: dict):
|
||||||
|
# recursively convert dict to StoredDict
|
||||||
|
d = {}
|
||||||
|
for k, v in list(data.items()):
|
||||||
|
child_path = path + [k]
|
||||||
|
k = self._convert_dict_key(child_path)
|
||||||
|
v = self._convert_dict_value(child_path, v)
|
||||||
|
d[k] = v
|
||||||
|
return d
|
||||||
|
|
||||||
@locked
|
@locked
|
||||||
def write(self):
|
def write(self):
|
||||||
if self.storage.should_do_full_write_next():
|
if self.storage.should_do_full_write_next():
|
||||||
|
|||||||
@@ -1279,7 +1279,7 @@ def upgrade_wallet_db(data: dict, do_upgrade: bool) -> Tuple[dict, bool]:
|
|||||||
first_electrum_version_used=ELECTRUM_VERSION,
|
first_electrum_version_used=ELECTRUM_VERSION,
|
||||||
)
|
)
|
||||||
assert data.get("db_metadata", None) is None
|
assert data.get("db_metadata", None) is None
|
||||||
data["db_metadata"] = v
|
data["db_metadata"] = v.to_json()
|
||||||
was_upgraded = True
|
was_upgraded = True
|
||||||
|
|
||||||
dbu = WalletDBUpgrader(data)
|
dbu = WalletDBUpgrader(data)
|
||||||
|
|||||||
Reference in New Issue
Block a user