summaryrefslogtreecommitdiff
path: root/ick2/trans.py
diff options
context:
space:
mode:
Diffstat (limited to 'ick2/trans.py')
-rw-r--r--ick2/trans.py98
1 files changed, 75 insertions, 23 deletions
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 <http://www.gnu.org/licenses/>.
+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)