shep

Multi-state key stores using bit masks for python3
git clone git://git.defalsify.org/shep.git
Log | Files | Refs | LICENSE

commit 1e077be1211335d26058f742dfbccb2e48acf3a8
parent 60dee4167e5b968306882784fb00acf0ee2725c5
Author: lash <dev@holbrook.no>
Date:   Tue,  1 Feb 2022 13:54:27 +0000

Implement move, set, unset on persistedstore

Diffstat:
MCHANGELOG | 2++
Msetup.cfg | 2+-
Mshep/persist.py | 42+++++++++++++++++++++++++++++++++++++-----
Mshep/state.py | 10+++++++---
Mshep/store/file.py | 6+++++-
Mtests/test_file.py | 51++++++++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -1,3 +1,5 @@ +- 0.0.10 + * Implement move, set, unset on persisted store - 0.0.9 * Add optional overwrite of contents * Add list all keys by state diff --git a/setup.cfg b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = shep -version = 0.0.9 +version = 0.0.10 description = Multi-state key stores using bit masks author = Louis Holbrook author_email = dev@holbrook.no diff --git a/shep/persist.py b/shep/persist.py @@ -16,27 +16,59 @@ class PersistedState(State): def put(self, key, contents=None, state=None, force=False): - k = self.name(state) + to_state = super(PersistedState, self).put(key, state=state, contents=contents, force=force) + + k = self.name(to_state) + self.__ensure_store(k) self.__stores[k].add(key, contents, force=force) - super(PersistedState, self).put(key, state=state, contents=contents, force=force) + def set(self, key, or_state): + from_state = self.state(key) + k_from = self.name(from_state) - def move(self, key, to_state): + to_state = super(PersistedState, self).set(key, or_state) k_to = self.name(to_state) + self.__ensure_store(k_to) + contents = self.__stores[k_from].get(key) + self.__stores[k_to].add(key, contents) + self.__stores[k_from].remove(key) + + return to_state + + + def unset(self, key, not_state): from_state = self.state(key) k_from = self.name(from_state) + to_state = super(PersistedState, self).unset(key, not_state) + + k_to = self.name(to_state) + self.__ensure_store(k_to) + + contents = self.__stores[k_from].get(key) + self.__stores[k_to].add(key, contents) + self.__stores[k_from].remove(key) + + return to_state + + + def move(self, key, to_state): + from_state = self.state(key) + k_from = self.name(from_state) + + to_state = super(PersistedState, self).move(key, to_state) + + k_to = self.name(to_state) self.__ensure_store(k_to) - self.__ensure_store(k_from) contents = self.__stores[k_from].get(key) self.__stores[k_to].add(key, contents) self.__stores[k_from].remove(key) - super(PersistedState, self).move(key, to_state) + return to_state def purge(self, key): diff --git a/shep/state.py b/shep/state.py @@ -166,6 +166,8 @@ class State: self.__add_state_list(state, key) if contents != None: self.__contents[key] = contents + + return state def move(self, key, to_state): @@ -177,7 +179,7 @@ class State: if new_state == None: raise StateInvalid(to_state) - self.__move(key, current_state, to_state) + return self.__move(key, current_state, to_state) def __move(self, key, from_state, to_state): @@ -194,6 +196,8 @@ class State: self.__add_state_list(to_state, key) current_state_list.pop(idx) + return to_state + def set(self, key, or_state): if not self.__is_pure(or_state): @@ -208,7 +212,7 @@ class State: if new_state == None: raise StateInvalid('resulting to state is unknown: {}'.format(to_state)) - self.__move(key, current_state, to_state) + return self.__move(key, current_state, to_state) def unset(self, key, not_state): @@ -227,7 +231,7 @@ class State: if new_state == None: raise StateInvalid('resulting to state is unknown: {}'.format(to_state)) - self.__move(key, current_state, to_state) + return self.__move(key, current_state, to_state) def purge(self, key): diff --git a/shep/store/file.py b/shep/store/file.py @@ -26,12 +26,16 @@ class SimpleFileStore: elif contents == None: contents = '' - print('wriging {}'.format(fp)) f = open(fp, 'w') f.write(contents) f.close() + def remove(self, k): + fp = os.path.join(self.path, k) + os.unlink(fp) + + def get(self, k): fp = os.path.join(self.path, k) f = open(fp, 'r') diff --git a/tests/test_file.py b/tests/test_file.py @@ -9,6 +9,7 @@ from shep.store.file import SimpleFileStoreFactory from shep.error import ( StateExists, StateInvalid, + StateItemExists, ) @@ -34,7 +35,7 @@ class TestStateReport(unittest.TestCase): def test_dup(self): self.states.put('abcd', state=self.states.FOO) - with self.assertRaises(FileExistsError): + with self.assertRaises(StateItemExists): self.states.put('abcd', state=self.states.FOO) with self.assertRaises(FileExistsError): @@ -66,7 +67,55 @@ class TestStateReport(unittest.TestCase): self.assertIn('yyy', keys) self.assertNotIn('1234', keys) self.assertNotIn('xx!', keys) + + + def test_move(self): + self.states.put('abcd', state=self.states.FOO, contents='foo') + self.states.move('abcd', self.states.BAR) + fp = os.path.join(self.d, 'BAR', 'abcd') + f = open(fp, 'r') + v = f.read() + f.close() + + fp = os.path.join(self.d, 'FOO', 'abcd') + with self.assertRaises(FileNotFoundError): + os.stat(fp) + + + def test_set(self): + self.states.alias('xyzzy', self.states.FOO | self.states.BAR) + self.states.put('abcd', state=self.states.FOO, contents='foo') + self.states.set('abcd', self.states.BAR) + + fp = os.path.join(self.d, 'XYZZY', 'abcd') + f = open(fp, 'r') + v = f.read() + f.close() + + fp = os.path.join(self.d, 'FOO', 'abcd') + with self.assertRaises(FileNotFoundError): + os.stat(fp) + + fp = os.path.join(self.d, 'BAR', 'abcd') + with self.assertRaises(FileNotFoundError): + os.stat(fp) + + self.states.unset('abcd', self.states.FOO) + + fp = os.path.join(self.d, 'BAR', 'abcd') + f = open(fp, 'r') + v = f.read() + f.close() + + fp = os.path.join(self.d, 'FOO', 'abcd') + with self.assertRaises(FileNotFoundError): + os.stat(fp) + + fp = os.path.join(self.d, 'XYZZY', 'abcd') + with self.assertRaises(FileNotFoundError): + os.stat(fp) + if __name__ == '__main__': unittest.main()