Skip to content

Commit

Permalink
Have a storage PoC
Browse files Browse the repository at this point in the history
  • Loading branch information
matejak committed Sep 23, 2024
1 parent fd218ac commit 729a2f4
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 132 deletions.
2 changes: 2 additions & 0 deletions estimage/inidata.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def _unpack_list(string_list: str):
@classmethod
def _load_existing_config(cls, filename):
config = configparser.ConfigParser(interpolation=None)
# Have keys case-sensitive: https://docs.python.org/3/library/configparser.html#id1
config.optionxform = lambda option: option
try:
config.read(filename)
except configparser.MissingSectionHeaderError:
Expand Down
11 changes: 9 additions & 2 deletions estimage/local_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
class Storage:
def __init__(self):
self.storage = dict()
self.ns_to_set = dict()

self.requests = set()
self.ns_requests = set()

Expand All @@ -17,8 +19,12 @@ def get_key(self, key):
return self.storage[tuple()][key]

def get_namespace(self, namespace):
ns = namespace
return self.storage[ns]
ret = dict()
ret.update(self.storage[namespace])
return ret

def set_namespace(self, namespace, with_what):
self.ns_to_set[namespace] = with_what

def request_key(self, key):
return self.requests.add(key)
Expand All @@ -29,6 +35,7 @@ def request_namespace(self, namespace):

def save(self, io):
io.save_dict(self.storage)
io.set_ns(self.ns_to_set)

def load(self, io):
data = dict()
Expand Down
57 changes: 1 addition & 56 deletions estimage/persistence/card/__init__.py
Original file line number Diff line number Diff line change
@@ -1,56 +1 @@
import contextlib
import typing

from ... import data


class Saver:
@classmethod
def bulk_save_metadata(cls, cards: typing.Iterable[data.BaseCard]):
saver = cls()
for t in cards:
t.pass_data_to_saver(saver)

@classmethod
def forget_all(cls):
raise NotImplementedError()

@classmethod
@contextlib.contextmanager
def get_saver(cls):
yield cls()


class Loader:
def __init__(self, ** kwargs):
self.card_class = kwargs.get("loaded_card_type", data.BaseCard)

@classmethod
def get_all_card_names(cls):
raise NotImplementedError()

@classmethod
def get_loaded_cards_by_id(cls, card_class=typing.Type[data.BaseCard]):
raise NotImplementedError()

@classmethod
def denormalize(cls, t: data.BaseCard):
for child in t.children:
child.parent = t
cls.denormalize(child)

@classmethod
def load_all_cards(cls, card_class=typing.Type[data.BaseCard]):
raise NotImplementedError()

@classmethod
@contextlib.contextmanager
def get_loader_of(cls, loaded_card_type):
with cls.get_loader() as ret:
ret.card_class = loaded_card_type
yield ret

@classmethod
@contextlib.contextmanager
def get_loader(cls):
yield cls()
from . import ini, memory
56 changes: 56 additions & 0 deletions estimage/persistence/card/abstract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import contextlib
import typing

from ... import data


class Saver:
@classmethod
def bulk_save_metadata(cls, cards: typing.Iterable[data.BaseCard]):
saver = cls()
for t in cards:
t.pass_data_to_saver(saver)

@classmethod
def forget_all(cls):
raise NotImplementedError()

@classmethod
@contextlib.contextmanager
def get_saver(cls):
yield cls()


class Loader:
def __init__(self, ** kwargs):
self.card_class = kwargs.get("loaded_card_type", data.BaseCard)

@classmethod
def get_all_card_names(cls):
raise NotImplementedError()

@classmethod
def get_loaded_cards_by_id(cls, card_class=typing.Type[data.BaseCard]):
raise NotImplementedError()

@classmethod
def denormalize(cls, t: data.BaseCard):
for child in t.children:
child.parent = t
cls.denormalize(child)

@classmethod
def load_all_cards(cls, card_class=typing.Type[data.BaseCard]):
raise NotImplementedError()

@classmethod
@contextlib.contextmanager
def get_loader_of(cls, loaded_card_type):
with cls.get_loader() as ret:
ret.card_class = loaded_card_type
yield ret

@classmethod
@contextlib.contextmanager
def get_loader(cls):
yield cls()
5 changes: 3 additions & 2 deletions estimage/persistence/card/ini.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
import datetime

from ... import data, inidata, persistence
from . import abstract


class IniCardSaverBase(inidata.IniSaverBase, persistence.card.Saver):
class IniCardSaverBase(inidata.IniSaverBase, abstract.Saver):
def _store_our(self, t, attribute, value=None):
if value is None and hasattr(t, attribute):
value = getattr(t, attribute)
return self._write_items_attribute(t.name, attribute, value)


class IniCardLoaderBase(inidata.IniLoaderBase, persistence.card.Loader):
class IniCardLoaderBase(inidata.IniLoaderBase, abstract.Loader):
def _get_our(self, t, attribute, fallback=None):
if fallback is None and hasattr(t, attribute):
fallback = getattr(t, attribute)
Expand Down
5 changes: 3 additions & 2 deletions estimage/persistence/card/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import typing

from ... import data, persistence
from . import abstract


GLOBAL_STORAGE = collections.defaultdict(dict)


@persistence.saver_of(data.BaseCard, "memory")
class MemoryCardSaver(persistence.card.Saver):
class MemoryCardSaver(abstract.Saver):
def _save(self, t, attribute):
GLOBAL_STORAGE[t.name][attribute] = getattr(t, attribute)

Expand Down Expand Up @@ -51,7 +52,7 @@ def forget_all(cls):


@persistence.loader_of(data.BaseCard, "memory")
class MemoryCardLoader(persistence.card.Loader):
class MemoryCardLoader(abstract.Loader):
def _load(self, t, attribute):
setattr(t, attribute, GLOBAL_STORAGE[t.name][attribute])

Expand Down
1 change: 1 addition & 0 deletions estimage/persistence/storage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import ini, memory
38 changes: 33 additions & 5 deletions estimage/persistence/storage/ini.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,40 @@

class IniStorageBase:
BASE_NS_STR = "-NONS-"
NS_SEP = "*-*-*"
BASE_NS = tuple()
WHAT_IS_THIS = "Storage Item"


class IniStorageSaver(inidata.IniSaverBase, IniStorageBase):
def _update_ns(self, ns_str, tosave):
for key, val in tosave.items():
self._write_items_attribute(ns_str, key, str(val))

def save_dict(self, data):
if self.BASE_NS not in data:
return
for key, val in data[self.BASE_NS].items():
self._write_items_attribute(self.BASE_NS_STR, key, str(val))
for ns, tosave in data.items():
ns_str = self.NS_SEP.join(ns)
if ns == self.BASE_NS:
ns_str = self.BASE_NS_STR
self._update_ns(ns_str, tosave)
self.save()

def set_ns(self, data):
self._remove_namespaces(data.keys())
for ns, tosave in data.items():
ns_str = self.NS_SEP.join(ns)
self._update_ns(ns_str, tosave)
self.save()

def _remove_namespaces(self, namespaces):
with self._manipulate_existing_config(self.CONFIG_FILENAME) as config:
for ns in namespaces:
ns_str = self.NS_SEP.join(ns)
if ns_str in config:
del config[ns_str]
if ns_str in self._data_to_save:
del self._data_to_save[ns_str]


class IniStorageLoader(inidata.IniLoaderBase, IniStorageBase):
def load_keys_to_dict(self, keys):
Expand All @@ -33,7 +55,13 @@ def load_key_to_dict(self, key):
raise KeyError(msg)

def load_ns_to_dict(self, ns):
return {ns: dict()}
ns_str = self.NS_SEP.join(ns)
if ns_str not in self._loaded_data:
msg = f"Failed to load '{ns}'"
raise KeyError(msg)
ret = dict()
ret[ns] = self._loaded_data[ns_str]
return ret


class IniStorageIO(IniStorageLoader, IniStorageSaver):
Expand Down
36 changes: 36 additions & 0 deletions estimage/persistence/storage/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
GLOBAL_STORAGE = dict()
GLOBAL_STORAGE[tuple()] = dict()


class GlobalMemoryIO:
def save_dict(self, data):
GLOBAL_STORAGE.update(data)

def set_ns(self, data):
for key, contents in data.items():
GLOBAL_STORAGE[key] = contents

def load_keys_to_dict(self, keys):
return {key: GLOBAL_STORAGE[tuple()][key] for key in keys}

def load_ns_to_dict(self, nsname):
return {nsname: GLOBAL_STORAGE[nsname]}


class LocalMemoryIO:
def __init__(self):
self.storage = dict()
self.storage[tuple()] = dict()

def save_dict(self, data):
self.storage.update(data)

def set_ns(self, data):
for key, contents in data.items():
self.storage[key] = contents

def load_keys_to_dict(self, keys):
return {key: self.storage[tuple()][key] for key in keys}

def load_ns_to_dict(self, nsname):
return {nsname: self.storage[nsname]}
Loading

0 comments on commit 729a2f4

Please sign in to comment.