From 8344a860d226d8a5172bcb2e9de5946717a950ca Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 20 Jul 2019 16:52:01 +0300 Subject: Drop: use of old persistent state classes --- ick2/__init__.py | 1 - ick2/apibase.py | 2 +- ick2/persistent.py | 61 +----------------------------- ick2/persistent_tests.py | 9 ----- ick2/projectapi_tests.py | 9 +---- ick2/trans.py | 98 ++++++++++++++++++++++++++++++++++++------------ ick2/workapi_tests.py | 9 +---- 7 files changed, 79 insertions(+), 110 deletions(-) diff --git a/ick2/__init__.py b/ick2/__init__.py index e21f666..7229a5f 100644 --- a/ick2/__init__.py +++ b/ick2/__init__.py @@ -20,7 +20,6 @@ from .store import ( Conflict, ) from .persistent import ( - MemoryPersistentState, NotFound, Resource, resource_from_dict, diff --git a/ick2/apibase.py b/ick2/apibase.py index 19f70e4..3827f6e 100644 --- a/ick2/apibase.py +++ b/ick2/apibase.py @@ -23,7 +23,7 @@ class APIbase: def __init__(self, state): assert (state is None or - isinstance(state, ick2.MemoryPersistentState)) + isinstance(state, ick2.MemoryStore)) self._trans = ick2.TransactionalState(state) def get_routes(self, path): diff --git a/ick2/persistent.py b/ick2/persistent.py index e225b88..33903fe 100644 --- a/ick2/persistent.py +++ b/ick2/persistent.py @@ -25,66 +25,7 @@ import yaml import ick2 -class PersistentStateInterface: # pragma: no cover - - def get_resource_names(self, token, kind): - raise NotImplementedError() - - def has_resource(self, token, kind, name): - raise NotImplementedError() - - def get_resource(self, token, kind, name): - raise NotImplementedError() - - def get_resources(self, token, kind): - return [ - self.get_resource(token, kind, name) - for name in self.get_resource_names(token, kind) - ] - - def write_resource(self, token, kind, name, resource): - raise NotImplementedError() - - def update_resource(self, token, kind, name, resource): - raise NotImplementedError() - - def remove_resource(self, token, kind, name): - raise NotImplementedError() - - -class MemoryPersistentState(PersistentStateInterface): - - def __init__(self): - self._res = {} - - def get_resource_names(self, token, kind): - if kind not in self._res: - return [] - return list(self._res[kind].keys()) - - def has_resource(self, token, kind, name): - return kind in self._res and name in self._res[kind] - - def get_resource(self, token, kind, name): - if kind not in self._res or name not in self._res[kind]: - raise ick2.NotFound(kind=kind, name=name) - return self._res[kind][name] - - def write_resource(self, token, kind, name, resource): - if kind not in self._res: - self._res[kind] = {} - self._res[kind][name] = resource - - def update_resource(self, token, kind, name, resource): - self.write_resource(token, kind, name, resource) - - def remove_resource(self, token, kind, name): - if kind not in self._res or name not in self._res[kind]: - raise ick2.NotFound(kind=kind, name=name) - del self._res[kind][name] - - -class NotFound(Exception): +class NotFound(Exception): # pragma: no cover def __init__(self, kind, name): super().__init__( diff --git a/ick2/persistent_tests.py b/ick2/persistent_tests.py index 18b5c5c..961742f 100644 --- a/ick2/persistent_tests.py +++ b/ick2/persistent_tests.py @@ -90,12 +90,3 @@ class PersistentStateTestsMixIn: self.state.write_resource(token, 'silly', '#1', r) with self.assertRaises(ick2.NotFound): self.state.remove_resource(token, 'silly', '#2') - - -class MemoryPersistentStateTests(unittest.TestCase, PersistentStateTestsMixIn): - - def get_token(self): - return 'DUMMY-TOKEN' - - def setUp(self): - self.state = ick2.MemoryPersistentState() diff --git a/ick2/projectapi_tests.py b/ick2/projectapi_tests.py index 5be2a58..f8b3c2a 100644 --- a/ick2/projectapi_tests.py +++ b/ick2/projectapi_tests.py @@ -14,8 +14,6 @@ import os -import shutil -import tempfile import unittest @@ -25,12 +23,7 @@ import ick2 class ProjectAPITests(unittest.TestCase): def setUp(self): - self.tempdir = tempfile.mkdtemp() - self.statedir = os.path.join(self.tempdir, 'state/dir') - self.state = ick2.MemoryPersistentState() - - def tearDown(self): - shutil.rmtree(self.tempdir) + self.state = ick2.MemoryStore() def create_api(self): return ick2.ProjectAPI(self.state) diff --git a/ick2/trans.py b/ick2/trans.py index 119f277..da2f80d 100644 --- a/ick2/trans.py +++ b/ick2/trans.py @@ -14,22 +14,75 @@ # along with this program. If not, see . +import copy + + import ick2 +def wrap(kind, name, as_dict): + return { + 'kind': kind, + 'name': name, + 'res': copy.deepcopy(as_dict), + } + + +def unwrap(obj): + return obj['kind'], obj['name'], copy.deepcopy(obj['res']) + + +def find_by_name(store, token, kind, name): + rids = store.search(token, None) # FIXME for real searches + for rid in rids: + obj, rev = store.show(token, rid) + if obj is not None: + okind, oname, as_dict = unwrap(obj) + if okind == kind and oname == name: + return as_dict, rid, rev + + raise ick2.NotFound(kind=kind, name=name) + + +def find_names_by_kind(store, token, kind): + rids = store.search(token, None) # FIXME for real searches + for rid in rids: + obj, rev = store.show(token, rid) + if obj is not None: + okind, oname, as_dict = unwrap(obj) + if okind == kind: + yield oname + + class TransactionalResource: - def __init__(self, token, state, kind, name): + def __init__(self, new, token, store, kind, name): self.token = token - self.state = state + self.store = store self.kind = kind self.name = name - if state.has_resource(self.token, kind, name): - self.new = False - self.resource = state.get_resource(self.token, kind, name) + + self.rid = None + self.rev = None + self.resource = None + + if new: + try: + find_by_name(self.store, token, kind, name) + except ick2.NotFound: + as_dict = {} + else: + raise ick2.ExistsAlready(name) else: - self.new = True - self.resource = ick2.resource_from_dict({}) + try: + as_dict, self.rid, self.rev = find_by_name( + self.store, token, kind, name) + except ick2.NotFound: + raise + + self.resource = ick2.resource_from_dict(as_dict) + assert ((new and self.rid is None) or + (not new and self.rid is not None)) methods = [ 'as_dict', @@ -46,12 +99,12 @@ class TransactionalResource: def __exit__(self, exc_type, value, traceback): if exc_type is None: - if self.new: - self.state.write_resource( - self.token, self.kind, self.name, self.resource) + as_dict = self.resource.as_dict() + obj = wrap(self.kind, self.name, as_dict) + if self.rid is None: + self.store.create(self.token, obj) else: - self.state.update_resource( - self.token, self.kind, self.name, self.resource) + self.store.update(self.token, self.rid, obj, self.rev) class TransactionalState: @@ -60,22 +113,21 @@ class TransactionalState: self.state = state def new(self, token, kind, name): - if self.state.has_resource(token, kind, name): - raise ick2.ExistsAlaready(name) - return TransactionalResource(token, self.state, kind, name) + return TransactionalResource(True, token, self.state, kind, name) def modify(self, token, kind, name): - if not self.state.has_resource(token, kind, name): - raise ick2.NotFound(kind=kind, name=name) - return TransactionalResource(token, self.state, kind, name) + return TransactionalResource(False, token, self.state, kind, name) def get_resource(self, token, kind, name): - return self.state.get_resource(token, kind, name) + as_dict, rid, rev = find_by_name(self.state, token, kind, name) + return ick2.resource_from_dict(as_dict) def get_resources(self, token, kind): - return self.state.get_resources(token, kind) + return [ + self.get_resource(token, kind, name) + for name in find_names_by_kind(self.state, token, kind) + ] def remove_resource(self, token, kind, name): - if not self.state.has_resource(token, kind, name): - raise ick2.NotFound(kind=kind, name=name) - self.state.remove_resource(token, kind, name) + as_dict, rid, rev = find_by_name(self.state, token, kind, name) + self.state.delete(token, rid) diff --git a/ick2/workapi_tests.py b/ick2/workapi_tests.py index 8652110..72bcaf1 100644 --- a/ick2/workapi_tests.py +++ b/ick2/workapi_tests.py @@ -15,8 +15,6 @@ import copy import os -import shutil -import tempfile import unittest @@ -26,14 +24,9 @@ import ick2 class WorkAPITests(unittest.TestCase): def setUp(self): - self.tempdir = tempfile.mkdtemp() - self.statedir = os.path.join(self.tempdir, 'state/dir') - self.state = ick2.MemoryPersistentState() + self.state = ick2.MemoryStore() self.claims = None - def tearDown(self): - shutil.rmtree(self.tempdir) - def create_project_api(self): pipeline = { 'pipeline': 'build', -- cgit v1.2.1