summaryrefslogtreecommitdiff
path: root/ick2/apibase.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@exolobe1>2018-05-13 15:30:23 +0300
committerLars Wirzenius <liw@liw.fi>2018-05-17 21:44:59 +0300
commitb11d31ef23c5dfee6bfa54afbec47fc8b8bab7b1 (patch)
tree2e6b085f8fb023d53c8ac20a97aef2c7d1c11d4b /ick2/apibase.py
parent531dd2c50bfdfcf50bb37f57cf9fc2b69787adcf (diff)
downloadick2-b11d31ef23c5dfee6bfa54afbec47fc8b8bab7b1.tar.gz
Change: how controller stores persistent data
Replace old State class with new FilePersistentState and TransactionalState classes. Use new Resource class instead of raw dicts. Use context managers for creating, updating resources, to avoid mistakes from accidentally not saving changes. Overall persistence should now be rather simpler. This should open up a possibility for changing the controller to insert more actions into the build graph, to trigger notifcations via the workers.
Diffstat (limited to 'ick2/apibase.py')
-rw-r--r--ick2/apibase.py59
1 files changed, 30 insertions, 29 deletions
diff --git a/ick2/apibase.py b/ick2/apibase.py
index cb0d9f9..aeda00b 100644
--- a/ick2/apibase.py
+++ b/ick2/apibase.py
@@ -19,10 +19,8 @@ import ick2
class APIbase:
def __init__(self, state):
- self._state = state
-
- def get_state(self):
- return self._state
+ assert state is None or isinstance(state, ick2.FilePersistentState)
+ self._trans = ick2.TransactionalState(state)
def get_routes(self, path):
return [
@@ -100,12 +98,6 @@ class APIbase:
ick2.log.log(
'warning', msg_text='PUT Not found', kwargs=kwargs)
return ick2.not_found(e)
- except ick2.WrongProjectStatus as e:
- ick2.log.log(
- 'error',
- msg_text='Wrong state for project',
- exception=str(e))
- return ick2.bad_request(e)
ick2.log.log('trace', msg_text='returned body', body=repr(body))
return ick2.OK(body)
return wrapper
@@ -149,22 +141,28 @@ class ResourceApiBase(APIbase):
self._type_name = type_name
def list(self, **kwargs):
+ resources = self._trans.get_resources(self._type_name)
return {
- self._type_name: self._state.get_resources(self._type_name),
+ self._type_name: [r.as_dict() for r in resources]
}
def show(self, name, **kwargs):
- return self._state.get_resource(self._type_name, name)
+ return self._trans.get_resource(self._type_name, name).as_dict()
def create(self, body, **kwargs):
- resource = self.mangle_new_resource(body)
- name = self.get_resource_name(resource)
- try:
- self._state.get_resource(self._type_name, name)
- except ick2.NotFound:
- return self._state.add_resource(self._type_name, name, resource)
- else:
- raise ick2.ExistsAlready(name)
+ ick2.log.log(
+ 'trace', msg_text='create resource',
+ resource_type=self._type_name, body=body, kwargs=kwargs)
+
+ as_dict = self.mangle_new_resource(body)
+ rid = self.get_resource_name(as_dict)
+ if self._trans.has_resource(self._type_name, rid):
+ raise ick2.ExistsAlready(rid)
+
+ with self._trans.new(self._type_name, rid) as resource:
+ resource.from_dict(as_dict)
+
+ return as_dict
def mangle_new_resource(self, resource): # pragma: no cover
return resource
@@ -173,17 +171,20 @@ class ResourceApiBase(APIbase):
raise NotImplementedError()
def update(self, body, name, **kwargs):
- name = self.get_resource_name(body)
- try:
- old = self._state.get_resource(self._type_name, name)
- except ick2.NotFound:
- raise
- else:
- resource = self.mangle_updated_resource(old, body)
- return self._state.update_resource(self._type_name, name, resource)
+ rid = self.get_resource_name(body)
+ if not self._trans.has_resource(self._type_name, rid):
+ raise ick2.NotFound()
+
+ with self._trans.modify(self._type_name, rid) as resource:
+ as_dict = self.mangle_updated_resource(resource.as_dict(), body)
+ resource.from_dict(as_dict)
+
+ return as_dict
def mangle_updated_resource(self, old, new): # pragma: no cover
return new
def delete(self, name, **kwargs):
- self._state.remove_resource(self._type_name, name)
+ if not self._trans.has_resource(self._type_name, name):
+ raise ick2.NotFound()
+ self._trans.remove_resource(self._type_name, name)