Added events history
This commit is contained in:
@@ -96,7 +96,7 @@ class Sheerka(Concept):
|
||||
if self.sdp.first_time:
|
||||
self.sdp.set_key(self.USER_CONCEPTS_KEYS, 1000)
|
||||
|
||||
event = Event("Initializing Sheerka.")
|
||||
event = Event("Initializing Sheerka.", user=self.name)
|
||||
self.sdp.save_event(event)
|
||||
exec_context = ExecutionContext(self.key, event, self)
|
||||
|
||||
@@ -547,6 +547,11 @@ class Sheerka(Concept):
|
||||
|
||||
return sorted(res, key=lambda i: int(i.id))
|
||||
|
||||
def history(self, page=10, start=0):
|
||||
"""Gets the history of all commands"""
|
||||
return self.sdp.load_events(page, start)
|
||||
|
||||
|
||||
def test(self):
|
||||
return f"I have access to Sheerka !"
|
||||
|
||||
|
||||
@@ -42,3 +42,26 @@ class SheerkaDump:
|
||||
self.sheerka.log.info(f"body : {c.body}")
|
||||
self.sheerka.log.info(f"digest : {c.get_digest()}")
|
||||
first = False
|
||||
|
||||
def dump_history(self, page=20, start=0):
|
||||
count = 0
|
||||
resolved_page = page if page > 0 else 50
|
||||
page_count = 0
|
||||
|
||||
while count < page if page > 0 else True:
|
||||
history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
|
||||
try:
|
||||
h = next(history)
|
||||
except StopIteration:
|
||||
break
|
||||
|
||||
while True:
|
||||
try:
|
||||
if h.user != self.sheerka.name:
|
||||
self.sheerka.log.info(h)
|
||||
count += 1
|
||||
h = next(history)
|
||||
except StopIteration:
|
||||
break
|
||||
|
||||
page_count += 1
|
||||
|
||||
@@ -64,6 +64,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
"desc": context.sheerka.dump_handler.dump_desc,
|
||||
"concepts": context.sheerka.dump_handler.dump_concepts,
|
||||
"definitions": context.sheerka.dump_handler.dump_definitions,
|
||||
"history": context.sheerka.dump_handler.dump_history,
|
||||
}
|
||||
if context.obj:
|
||||
context.log(self.verbose_log,
|
||||
|
||||
@@ -25,13 +25,17 @@ class Event(object):
|
||||
Class that represents something that modifies the state of the system
|
||||
"""
|
||||
|
||||
def __init__(self, message="", user="", date=datetime.now()):
|
||||
def __init__(self, message="", user="", date=datetime.now(), parents=None):
|
||||
self.version = 1
|
||||
self.user = user
|
||||
self.date = date
|
||||
self.message = message
|
||||
self.parents = parents
|
||||
self._digest = None
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.date.strftime('%d/%m/%Y %H:%M:%S')} {self.message}"
|
||||
|
||||
def get_digest(self):
|
||||
"""
|
||||
Returns the digest of the event
|
||||
@@ -48,7 +52,8 @@ class Event(object):
|
||||
if not isinstance(self.message, str):
|
||||
raise NotImplementedError
|
||||
|
||||
self._digest = hashlib.sha256(f"Event:{self.user}{self.date}{self.message}".encode("utf-8")).hexdigest()
|
||||
to_hash = f"Event:{self.user}{self.date}{self.message}{self.parents}".encode("utf-8")
|
||||
self._digest = hashlib.sha256(to_hash).hexdigest()
|
||||
return self._digest
|
||||
|
||||
def to_dict(self):
|
||||
@@ -58,6 +63,7 @@ class Event(object):
|
||||
self.user = as_dict["user"]
|
||||
self.date = datetime.fromisoformat(as_dict["date"])
|
||||
self.message = as_dict["message"]
|
||||
self.parents = as_dict["parents"]
|
||||
|
||||
|
||||
class ObjToUpdate:
|
||||
@@ -280,6 +286,7 @@ class SheerkaDataProvider:
|
||||
ObjectsFolder = "objects"
|
||||
CacheFolder = "cache"
|
||||
HeadFile = "HEAD"
|
||||
LastEventFile = "LAST_EVENT"
|
||||
KeysFile = "keys"
|
||||
REF_PREFIX = "##REF##:"
|
||||
|
||||
@@ -365,7 +372,7 @@ class SheerkaDataProvider:
|
||||
if is_ref and not isinstance(obj, dict):
|
||||
raise SheerkaDataProviderError("is_ref can only be used with dictionaries", obj)
|
||||
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
self.log.debug(f"Adding obj '{obj}' in entry '{entry}' (allow_multiple={allow_multiple}, use_ref={use_ref})")
|
||||
@@ -400,7 +407,7 @@ class SheerkaDataProvider:
|
||||
state.update(entry, obj)
|
||||
|
||||
new_snapshot = self.save_state(state)
|
||||
self.set_snapshot(new_snapshot)
|
||||
self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot)
|
||||
return entry, key
|
||||
|
||||
def add_with_auto_key(self, event_digest: str, entry, obj):
|
||||
@@ -419,7 +426,7 @@ class SheerkaDataProvider:
|
||||
|
||||
def add_unique(self, event_digest: str, entry, obj):
|
||||
"""Add an entry and make sure it's unique"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
state.parents = [] if snapshot is None else [snapshot]
|
||||
@@ -434,7 +441,7 @@ class SheerkaDataProvider:
|
||||
state.data[entry].add(obj)
|
||||
|
||||
new_snapshot = self.save_state(state)
|
||||
self.set_snapshot(new_snapshot)
|
||||
self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot)
|
||||
return (None if already_exist else entry), None
|
||||
|
||||
def set(self, event_digest, entry, obj, use_ref=False, is_ref=False):
|
||||
@@ -455,7 +462,7 @@ class SheerkaDataProvider:
|
||||
if is_ref and not isinstance(obj, dict):
|
||||
raise SheerkaDataProviderError("is_ref can only be used with dictionaries", obj)
|
||||
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
state.parents = [] if snapshot is None else [snapshot]
|
||||
@@ -472,7 +479,7 @@ class SheerkaDataProvider:
|
||||
state.data[entry] = obj if key is None else {key: obj}
|
||||
|
||||
new_snapshot = self.save_state(state)
|
||||
self.set_snapshot(new_snapshot)
|
||||
self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot)
|
||||
return entry, key
|
||||
|
||||
def modify(self, event_digest, entry, key, obj):
|
||||
@@ -489,7 +496,7 @@ class SheerkaDataProvider:
|
||||
if key is None:
|
||||
raise SheerkaDataProviderError("Key is mandatory.", None)
|
||||
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
if entry not in state.data:
|
||||
@@ -517,7 +524,7 @@ class SheerkaDataProvider:
|
||||
state.modify(entry, key, obj, obj_key)
|
||||
|
||||
new_snapshot = self.save_state(state)
|
||||
self.set_snapshot(new_snapshot)
|
||||
self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot)
|
||||
return entry, obj_key
|
||||
|
||||
def list(self, entry, filter=None):
|
||||
@@ -527,7 +534,7 @@ class SheerkaDataProvider:
|
||||
:param filter: filter to use
|
||||
:return: list of elements
|
||||
"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
if entry not in state.data:
|
||||
return []
|
||||
@@ -562,7 +569,7 @@ class SheerkaDataProvider:
|
||||
:return: new sha256 of the state
|
||||
TODO: Remove by key
|
||||
"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
if entry not in state.data:
|
||||
@@ -574,7 +581,7 @@ class SheerkaDataProvider:
|
||||
state.remove(entry, filter)
|
||||
|
||||
new_snapshot = self.save_state(state)
|
||||
self.set_snapshot(new_snapshot)
|
||||
self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot)
|
||||
return new_snapshot
|
||||
|
||||
def get(self, entry, key=None, load_origin=True):
|
||||
@@ -582,9 +589,10 @@ class SheerkaDataProvider:
|
||||
Retrieve an element by its key
|
||||
:param entry:
|
||||
:param key:
|
||||
:param load_origin: if True, adds the origin (parent digest) to the object
|
||||
:return:
|
||||
"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
if entry not in state.data:
|
||||
@@ -604,9 +612,10 @@ class SheerkaDataProvider:
|
||||
Retrieve an element by its key. Return None if the element does not exist
|
||||
:param entry:
|
||||
:param key:
|
||||
:param load_origin: if True, adds the origin (parent digest) to the object
|
||||
:return:
|
||||
"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
|
||||
if entry not in state.data:
|
||||
@@ -629,7 +638,7 @@ class SheerkaDataProvider:
|
||||
:param digest: digest of the object, when several entries share the same key
|
||||
:return:
|
||||
"""
|
||||
snapshot = self.get_snapshot()
|
||||
snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.load_state(snapshot)
|
||||
exist = entry in state.data
|
||||
|
||||
@@ -659,25 +668,63 @@ class SheerkaDataProvider:
|
||||
:return: digest of the event
|
||||
"""
|
||||
digest = event.get_digest()
|
||||
parent = self.get_snapshot(SheerkaDataProvider.LastEventFile)
|
||||
event.parents = [parent] if parent else None
|
||||
|
||||
target_path = self.io.get_obj_path(SheerkaDataProvider.EventFolder, digest)
|
||||
if self.io.exists(target_path):
|
||||
return digest
|
||||
|
||||
self.io.write_binary(target_path, self.serializer.serialize(event, None).read())
|
||||
self.set_snapshot(SheerkaDataProvider.LastEventFile, digest)
|
||||
|
||||
return digest
|
||||
|
||||
def load_event(self, digest):
|
||||
def load_event(self, digest=None):
|
||||
"""
|
||||
return an event, given its digest
|
||||
:param digest:
|
||||
:return:
|
||||
"""
|
||||
digest = digest or self.get_snapshot(SheerkaDataProvider.LastEventFile)
|
||||
if digest is None:
|
||||
return None
|
||||
|
||||
target_path = self.io.get_obj_path(SheerkaDataProvider.EventFolder, digest)
|
||||
|
||||
with self.io.open(target_path, "rb") as f:
|
||||
return self.serializer.deserialize(f, None)
|
||||
|
||||
def load_events(self, page_size, start=0):
|
||||
"""
|
||||
Load multiple events in the same command
|
||||
:param start:
|
||||
:param page_size:
|
||||
:return:
|
||||
"""
|
||||
|
||||
digest = None
|
||||
if start:
|
||||
for i in range(start):
|
||||
event = self.load_event(digest)
|
||||
if event is None or event.parents is None:
|
||||
return
|
||||
digest = event.parents[0]
|
||||
|
||||
count = 0
|
||||
while count < page_size:
|
||||
event = self.load_event(digest)
|
||||
if event is None:
|
||||
return
|
||||
|
||||
yield event
|
||||
|
||||
if event.parents is None:
|
||||
return
|
||||
|
||||
digest = event.parents[0]
|
||||
count += 1
|
||||
|
||||
def save_result(self, execution_context):
|
||||
"""
|
||||
Save the execution context associated with an event
|
||||
@@ -833,16 +880,16 @@ class SheerkaDataProvider:
|
||||
digest, cache_path = self.get_cache_params(category, key)
|
||||
return self.io.exists(cache_path)
|
||||
|
||||
def get_snapshot(self):
|
||||
head_file = self.io.path_join(SheerkaDataProvider.HeadFile)
|
||||
def get_snapshot(self, file):
|
||||
head_file = self.io.path_join(file)
|
||||
if not self.io.exists(head_file):
|
||||
return None
|
||||
return self.io.read_text(head_file)
|
||||
# with open(head_file, "r") as f:
|
||||
# return f.read()
|
||||
|
||||
def set_snapshot(self, digest):
|
||||
head_file = self.io.path_join(SheerkaDataProvider.HeadFile)
|
||||
def set_snapshot(self, file, digest):
|
||||
head_file = self.io.path_join(file)
|
||||
return self.io.write_text(head_file, digest)
|
||||
# with open(head_file, "w") as f:
|
||||
# return f.write(digest)
|
||||
|
||||
@@ -29,13 +29,13 @@ def json_default_converter(o):
|
||||
if isinstance(o, Enum):
|
||||
return o.name
|
||||
|
||||
raise Exception("Cannot serialize " + o.__class__.__name__)
|
||||
raise Exception(f"Cannot serialize object '{o}', class='{o.__class__.__name__}'")
|
||||
# In debug mode, just
|
||||
#
|
||||
# with open("json_encoding_error.txt", "a") as f:
|
||||
# f.write(o.__class__.__name__ + "\n")
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass()
|
||||
class SerializerContext:
|
||||
user_name: str = None
|
||||
|
||||
@@ -219,8 +219,76 @@ def test_i_can_save_and_load_an_event(root):
|
||||
assert evt.date == datetime(year=2007, month=9, day=10)
|
||||
assert evt.user == "kodjo"
|
||||
assert evt.message == "hello world"
|
||||
assert evt.parents is None
|
||||
assert sdp.io.exists(path.join(sdp.io.root, SheerkaDataProvider.EventFolder, evt_digest[0:24], evt_digest))
|
||||
|
||||
# I can get the last event
|
||||
evt = sdp.load_event()
|
||||
assert evt.message == "hello world"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("root", [
|
||||
".sheerka",
|
||||
"mem://"
|
||||
])
|
||||
def test_i_can_get_event_history(root):
|
||||
sdp = SheerkaDataProvider(root)
|
||||
event = Event("hello world", date=date(year=2007, month=9, day=10), user="kodjo")
|
||||
event2 = Event("hello world 2", date=date(year=2007, month=9, day=10), user="kodjo")
|
||||
|
||||
evt_digest1 = sdp.save_event(event)
|
||||
evt_digest2 = sdp.save_event(event2)
|
||||
|
||||
evt = sdp.load_event(evt_digest2)
|
||||
assert evt.version == 1
|
||||
assert evt.date == datetime(year=2007, month=9, day=10)
|
||||
assert evt.user == "kodjo"
|
||||
assert evt.message == "hello world 2"
|
||||
assert evt.parents == [evt_digest1]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("root", [
|
||||
".sheerka",
|
||||
"mem://"
|
||||
])
|
||||
def test_i_can_load_events(root):
|
||||
sdp = SheerkaDataProvider(root)
|
||||
|
||||
for i in range(15):
|
||||
sdp.save_event(Event(f"Hello {i}"))
|
||||
|
||||
events = list(sdp.load_events(10))
|
||||
assert len(events) == 10
|
||||
assert events[0].message == "Hello 14"
|
||||
assert events[9].message == "Hello 5"
|
||||
|
||||
events = list(sdp.load_events(10, 5))
|
||||
assert len(events) == 10
|
||||
assert events[0].message == "Hello 9"
|
||||
assert events[9].message == "Hello 0"
|
||||
|
||||
events = list(sdp.load_events(20, 10))
|
||||
assert len(events) == 5
|
||||
assert events[0].message == "Hello 4"
|
||||
assert events[4].message == "Hello 0"
|
||||
|
||||
events = list(sdp.load_events(1, 20))
|
||||
assert len(events) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("root", [
|
||||
".sheerka",
|
||||
"mem://"
|
||||
])
|
||||
def test_i_can_load_events_when_no_event(root):
|
||||
sdp = SheerkaDataProvider(root)
|
||||
|
||||
events = list(sdp.load_events(1))
|
||||
assert len(events) == 0
|
||||
|
||||
events = list(sdp.load_events(1, 5))
|
||||
assert len(events) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("root", [
|
||||
".sheerka",
|
||||
@@ -231,7 +299,7 @@ def test_i_can_add_an_string(root):
|
||||
obj = "foo => bar"
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj)
|
||||
last_commit = sdp.get_snapshot()
|
||||
last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = sdp.load_state(last_commit)
|
||||
loaded = sdp.get(entry, key)
|
||||
|
||||
@@ -289,7 +357,7 @@ def test_i_can_add_an_object_with_no_key(root):
|
||||
obj = ObjNoKey("a", "b")
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj)
|
||||
last_commit = sdp.get_snapshot()
|
||||
last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = sdp.load_state(last_commit)
|
||||
loaded = sdp.get(entry, key)
|
||||
|
||||
@@ -359,7 +427,7 @@ def test_i_can_add_a_dict(root):
|
||||
obj = {"my_key": "my_value"}
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj)
|
||||
last_commit = sdp.get_snapshot()
|
||||
last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = sdp.load_state(last_commit)
|
||||
loaded = sdp.get(entry, key)
|
||||
|
||||
@@ -456,7 +524,7 @@ def test_i_can_add_obj_with_key(root):
|
||||
|
||||
entry1, key1 = sdp.add(evt_digest, "entry", obj1) # test when key is taken from obj.get_key()
|
||||
entry2, key2 = sdp.add(evt_digest, "entry2", obj2) # test when key is taken from obj.key
|
||||
last_commit = sdp.get_snapshot()
|
||||
last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = sdp.load_state(last_commit)
|
||||
|
||||
loaded1 = sdp.get(entry1, key1)
|
||||
@@ -545,7 +613,7 @@ def test_i_can_add_a_reference(root):
|
||||
sdp.add(evt_digest, "entry", obj2, use_ref=True)
|
||||
sdp.add(evt_digest, "entry_by_value", {obj2.b: obj2.get_digest()}, is_ref=True)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {
|
||||
"entry": {
|
||||
"1": '##REF##:' + obj1.get_digest(),
|
||||
@@ -593,7 +661,7 @@ def test_i_can_add_string_using_auto_generated_key(root):
|
||||
entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", "bar")
|
||||
entry3, key3 = sdp.add_with_auto_key(evt_digest, "entry2", "baz")
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
|
||||
assert sdp.io.exists(key_file)
|
||||
assert read_json_file(sdp, key_file) == {"entry1": 2, "entry2": 1}
|
||||
@@ -732,7 +800,7 @@ def test_i_can_add_object_using_auto_generated_key(root):
|
||||
entry1, key1 = sdp.add_with_auto_key(evt_digest, "entry1", ObjNoKey("a", "b"))
|
||||
entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", ObjNoKey("a", "b"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
|
||||
assert sdp.io.exists(key_file)
|
||||
assert read_json_file(sdp, key_file) == {"entry1": 2}
|
||||
@@ -754,7 +822,7 @@ def test_object_key_is_updated_when_possible_using_auto_generated_key(root):
|
||||
entry1, key1 = sdp.add_with_auto_key(evt_digest, "entry1", ObjSetKey("foo"))
|
||||
entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", ObjSetKey("foo"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
|
||||
assert sdp.io.exists(key_file)
|
||||
assert read_json_file(sdp, key_file) == {"entry1": 2}
|
||||
@@ -774,7 +842,7 @@ def test_i_can_set_objects_with_key(root):
|
||||
sdp.add(evt_digest, "entry", ObjWithKey(1, "foo"))
|
||||
entry, key = sdp.set(evt_digest, "entry", ObjWithKey(2, "foo"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"2": ObjWithKey(2, "foo")}}
|
||||
assert entry == "entry"
|
||||
assert key == "2"
|
||||
@@ -789,7 +857,7 @@ def test_i_can_set_objects_with_no_key(root):
|
||||
sdp.add(evt_digest, "entry", ObjNoKey(1, "foo"))
|
||||
entry, key = sdp.set(evt_digest, "entry", ObjNoKey(2, "foo"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": ObjNoKey(2, "foo")}
|
||||
assert entry == "entry"
|
||||
assert key is None
|
||||
@@ -804,7 +872,7 @@ def test_i_can_set_from_list_to_dict(root):
|
||||
sdp.set(evt_digest, "entry", [ObjNoKey(1, "foo"), ObjNoKey(2, "foo")])
|
||||
entry, key = sdp.set(evt_digest, "entry", {"1": ObjNoKey(1, "foo"), "2": ObjNoKey(2, "foo")})
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"1": ObjNoKey(1, "foo"), "2": ObjNoKey(2, "foo")}}
|
||||
assert entry == "entry"
|
||||
assert key is None
|
||||
@@ -820,7 +888,7 @@ def test_i_can_set_using_reference(root):
|
||||
sdp.add(evt_digest, "entry", ObjWithKey(1, "foo"))
|
||||
entry, key = sdp.set(evt_digest, "entry", ObjWithKey(2, "foo"), use_ref=True)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"2": '##REF##:43f07065c7bad051cdd726bdfa4de7f8d754c31486c65ddb31d6b6548dec3db9'}}
|
||||
assert entry == "entry"
|
||||
assert key == "2"
|
||||
@@ -845,7 +913,7 @@ def test_i_can_set_a_reference(root):
|
||||
sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
sdp.set(evt_digest, "entry_by_value", {obj.b: obj.get_digest()}, is_ref=True)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {
|
||||
"entry": {"1": '##REF##:' + obj.get_digest()},
|
||||
"entry_by_value": {"foo": '##REF##:' + obj.get_digest()},
|
||||
@@ -882,7 +950,7 @@ def test_i_can_add_an_object_with_a_key_as_a_reference(root):
|
||||
sdp.serializer.register(obj_serializer)
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
digest = state.data["entry"]["my_key"][len(SheerkaDataProvider.REF_PREFIX):]
|
||||
|
||||
assert key == obj.key
|
||||
@@ -906,7 +974,7 @@ def test_i_can_add_a_dictionary_as_a_reference(root):
|
||||
sdp.serializer.register(obj_serializer)
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
digest = state.data["entry"][len(SheerkaDataProvider.REF_PREFIX):]
|
||||
|
||||
assert key is None
|
||||
@@ -937,7 +1005,7 @@ def test_i_can_add_unique(root):
|
||||
entry, key = sdp.add_unique(evt_digest, "entry", ObjNoKey(2, "bar"))
|
||||
assert (entry, key) == (None, None)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {ObjNoKey(1, "foo"), ObjNoKey(2, "bar")}}
|
||||
|
||||
|
||||
@@ -952,13 +1020,13 @@ def test_i_can_keep_state_history(root):
|
||||
event_digest1 = sdp.save_event(event1)
|
||||
obj1 = "foo => bar"
|
||||
sdp.add(event_digest1, "entry1", obj1)
|
||||
state_digest1 = sdp.get_snapshot()
|
||||
state_digest1 = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
|
||||
event2 = Event("cmd add 'foo => baz'")
|
||||
event_digest2 = sdp.save_event(event2)
|
||||
obj2 = "foo => baz"
|
||||
sdp.add(event_digest2, "entry2", obj2)
|
||||
state_digest2 = sdp.get_snapshot()
|
||||
state_digest2 = sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
|
||||
state2 = sdp.load_state(state_digest2)
|
||||
|
||||
@@ -1269,7 +1337,7 @@ def test_i_can_modify_dict_with_a_key(root):
|
||||
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key1", "baz")
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key1": "baz", "key2": "bar"}}
|
||||
assert entry == "entry"
|
||||
assert key == "key1"
|
||||
@@ -1286,7 +1354,7 @@ def test_i_can_modify_an_object_with_a_key(root):
|
||||
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key1", ObjWithKey("key1", "baz"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key1": ObjWithKey("key1", "baz"), "key2": ObjWithKey("key2", "bar")}}
|
||||
assert entry == "entry"
|
||||
assert key == "key1"
|
||||
@@ -1303,7 +1371,7 @@ def test_i_can_modify_an_object_while_changing_the_key(root):
|
||||
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key1", ObjWithKey("key3", "baz"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key2": ObjWithKey("key2", "bar"), "key3": ObjWithKey("key3", "baz")}}
|
||||
assert entry == "entry"
|
||||
assert key == "key3"
|
||||
@@ -1320,7 +1388,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_key(root):
|
||||
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key2", ObjWithKey("key1", "bar"))
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key1": [ObjWithKey("key1", "foo"), ObjWithKey("key1", "bar")]}}
|
||||
assert entry == "entry"
|
||||
assert key == "key1"
|
||||
@@ -1348,7 +1416,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_list(
|
||||
setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest())
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key2", new_value)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {
|
||||
"key1": [ObjDumpJson("key1", "value11"), ObjDumpJson("key1", "value12"), ObjDumpJson("key1", "value13")],
|
||||
"key2": [ObjDumpJson("key2", "value22")]
|
||||
@@ -1377,7 +1445,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_nothi
|
||||
setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest())
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key2", new_value)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {
|
||||
"key1": ObjDumpJson("key1", "value13"),
|
||||
"key2": [ObjDumpJson("key2", "value22")]
|
||||
@@ -1407,7 +1475,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_one_i
|
||||
setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest())
|
||||
entry, key = sdp.modify(evt_digest, "entry", "key2", new_value)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {
|
||||
"key1": [ObjDumpJson("key1", "value11"), ObjDumpJson("key1", "value13")],
|
||||
"key2": [ObjDumpJson("key2", "value22")]
|
||||
@@ -1427,7 +1495,7 @@ def test_i_can_modify_a_ref(root):
|
||||
entry, key = sdp.add(evt_digest, "entry", ObjWithKey("key2", "bar"), use_ref=True)
|
||||
|
||||
sdp.modify(evt_digest, "entry", "key2", ObjWithKey("key2", "baz"))
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {
|
||||
"key1": ObjWithKey("key1", "foo"),
|
||||
"key2": "##REF##:041d3cca905b51bc2c66251e73e56b836aae7b9435ee3d7eb05d44bb67ff575e"}}
|
||||
@@ -1471,7 +1539,7 @@ def test_i_cannot_modify_a_list_when_origin_is_unknown(root):
|
||||
sdp.add(evt_digest, "entry", ObjWithKey("key", "value1"))
|
||||
sdp.add(evt_digest, "entry", ObjWithKey("key", "value2")) # same they
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
|
||||
with pytest.raises(SheerkaDataProviderError) as error:
|
||||
sdp.modify(evt_digest, "entry", "key", ObjWithKey("key", "value2"))
|
||||
@@ -1495,7 +1563,7 @@ def test_i_can_modify_a_list_when_the_origin_is_known(root):
|
||||
|
||||
sdp.modify(evt_digest, "entry", "key", new_value)
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key": [ObjDumpJson("key", "value3"), ObjDumpJson("key", "value2")]}}
|
||||
|
||||
|
||||
@@ -1520,7 +1588,7 @@ def test_i_can_modify_a_list_when_the_origin_is_known_2(root):
|
||||
|
||||
sdp.modify(evt_digest, "entry", "key", objs[0])
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {"key": [
|
||||
"##REF##:621771a3af6a331e9abb3a63fb25e0cac4b13df0b292dfa30db6bd89031bfad0",
|
||||
"##REF##:5fe085e8366d35c5f04a18b2d3dada376128b246e07c66de5872830b00f5f517"]}}
|
||||
@@ -1846,7 +1914,7 @@ def test_i_can_save_and_load_object_ref_with_history(root):
|
||||
assert history2[Serializer.MODIFICATION_DATE] != ""
|
||||
assert history2[Serializer.PARENTS] == [previous_digest]
|
||||
|
||||
state = sdp.load_state(sdp.get_snapshot())
|
||||
state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile))
|
||||
assert state.data == {"entry": {
|
||||
"my_key": '##REF##:e6bf5b56428cfce0f08c94f2c3625dc3b3a8180d7229eaa9f8aa967fb16e5256'}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user