def test_exceptions(self): a = VelesException('zlew', 'Something went wrong.') self.assertEqual(type(a), VelesException) self.assertIsInstance(a, VelesException) self.assertNotIsInstance(a, ObjectGoneError) self.assertEqual(a.code, 'zlew') self.assertEqual(a.msg, 'Something went wrong.') self.assertEqual(a.args, (a.code, a.msg)) a = VelesException('object_gone', 'Object gone.') self.assertEqual(type(a), ObjectGoneError) self.assertIsInstance(a, VelesException) self.assertIsInstance(a, ObjectGoneError) self.assertEqual(a.code, 'object_gone') self.assertEqual(a.msg, 'Object gone.') self.assertEqual(a.args, (a.msg, )) a = ObjectGoneError('Whoops.') self.assertEqual(type(a), ObjectGoneError) self.assertIsInstance(a, VelesException) self.assertIsInstance(a, ObjectGoneError) self.assertEqual(a.code, 'object_gone') self.assertEqual(a.msg, 'Whoops.') self.assertEqual(a.args, (a.msg, )) a = ObjectGoneError() self.assertEqual(type(a), ObjectGoneError) self.assertIsInstance(a, VelesException) self.assertIsInstance(a, ObjectGoneError) self.assertEqual(a.code, 'object_gone') self.assertEqual(a.msg, ObjectGoneError.msg) self.assertEqual(a.args, ())
def _op_set_bindata(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() self.db.set_bindata(dbnode.id, op.key, op.start, op.data, op.truncate, commit=False) old_len = dbnode.node.bindata.get(op.key, 0) if op.truncate: new_len = op.start + len(op.data) change_end = max(old_len, new_len) else: new_len = max(op.start + len(op.data), old_len) change_end = op.start + len(op.data) for sub in dbnode.bindata_subs.get(op.key, ()): if sub.end is not None and sub.end <= op.start: continue if change_end <= sub.start: continue xact.bindata_changed(sub) if old_len != new_len: if new_len: dbnode.node.bindata[op.key] = new_len else: del dbnode.node.bindata[op.key]
def _op_add_tag(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() if op.tag in dbnode.node.tags: return self.db.add_tag(dbnode.id, op.tag, commit=False) dbnode.node.tags.add(op.tag)
def _op_set_parent(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() parent = self.get_cached_node(op.parent) if parent.node is None and parent.id != NodeID.root_id: raise ObjectGoneError() if parent.id == dbnode.parent.id: return cur = parent while cur.id != NodeID.root_id: if cur.id == dbnode.id: raise ParentCycleError() cur = cur.parent self.db.set_parent(dbnode.id, parent.id, commit=False) dbnode.node.parent = parent.id dbnode.parent = parent
def _op_del_tag(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() if op.tag not in dbnode.node.tags: return self.db.del_tag(dbnode.id, op.tag, commit=False) dbnode.node.tags.remove(op.tag)
def _add_sub_data(self, sub): if sub.key not in self.data_subs: self.data_subs[sub.key] = set() self.data_subs[sub.key].add(sub) if self.node is None: sub.error(ObjectGoneError()) else: sub.data_changed(self.tracker.get_data(self.id, sub.key))
def _op_set_data(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() self.db.set_data(dbnode.id, op.key, op.data, commit=False) xact.set_data(dbnode, op.key, op.data) if op.data is None and op.key in dbnode.node.data: dbnode.node.data.remove(op.key) elif op.data is not None and op.key not in dbnode.node.data: dbnode.node.data.add(op.key)
def _op_set_pos(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() if (op.pos_start == dbnode.node.pos_start and op.pos_end == dbnode.node.pos_end): return self.db.set_pos(dbnode.id, op.pos_start, op.pos_end, commit=False) dbnode.node.pos_start = op.pos_start dbnode.node.pos_end = op.pos_end
def _op_set_attr(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() if dbnode.node.attr.get(op.key) == op.data: return self.db.set_attr(dbnode.id, op.key, op.data, commit=False) if op.data is None: del dbnode.node.attr[op.key] else: dbnode.node.attr[op.key] = op.data
def _op_create(self, xact, op, dbnode): if dbnode.node is not None: raise ObjectExistsError() parent = self.get_cached_node(op.parent) if parent.node is None and parent.id != NodeID.root_id: raise ObjectGoneError() dbnode.node = Node(id=dbnode.id, parent=op.parent, pos_start=op.pos_start, pos_end=op.pos_end, tags=op.tags, attr=op.attr, data=set(op.data), bindata={x: len(y) for x, y in op.bindata.items()}) self.db.create(dbnode.node, commit=False) dbnode.parent = parent for key, val in op.data.items(): self.db.set_data(dbnode.id, key, val) xact.set_data(dbnode, key, val) for key, val in op.bindata.items(): self.db.set_bindata(dbnode.id, key, 0, val) for sub in dbnode.bindata_subs.get(key, set()): xact.bindata_changed(sub)
def __exit__(self, exc, val, tb): if exc is None: # Everything alright, let's commit. self.tracker.db.commit() for dbnode, (node, parent) in self.undo.items(): if dbnode.node != node: self.handle_changed_node(dbnode, node, parent) # Send out all gone subs. for sub in self.gone_subs: sub.error(ObjectGoneError()) # Send out all node subs. for sub, node in self.node_subs.items(): sub.node_changed(node) # Now send out all buffered list changes. for sub, (changed, gone) in self.list_changes.items(): if sub in self.gone_subs: continue sub.list_changed(list(changed.values()), list(gone)) # Send out data subs. for sub, data in self.data_subs.items(): if sub in self.gone_subs: continue sub.data_changed(data) # Send out bindata subs. for sub in self.bindata_subs: if sub in self.gone_subs: continue data = self.tracker.get_bindata(sub.node, sub.key, sub.start, sub.end) sub.bindata_changed(data) else: # Whoops. Undo changes. self.tracker.db.rollback() for dbnode, (node, parent) in self.undo.items(): dbnode.node = node dbnode.parent = parent
def get_data(self, nid, key): dbnode = self.get_cached_node(nid) if dbnode.node is None: raise ObjectGoneError() return self.db.get_data(nid, key)
def get(self, nid): dbnode = self.get_cached_node(nid) if dbnode.node is None: raise ObjectGoneError() return dbnode.node
def _op_del_trigger(self, xact, op, dbnode): if dbnode.node is None: raise ObjectGoneError() # XXX raise NotImplementedError
def get_bindata(self, nid, key, start=0, end=None): dbnode = self.get_cached_node(nid) if dbnode.node is None: raise ObjectGoneError() return self.db.get_bindata(nid, key, start, end)
def get_list_raw(self, parent, tags=frozenset(), pos_filter=PosFilter()): if parent != NodeID.root_id: dbnode = self.get_cached_node(parent) if dbnode.node is None: raise ObjectGoneError() return self.db.list(parent, tags, pos_filter)
def _add_sub(self, sub): self.subs.add(sub) if self.node is not None: sub.node_changed(self.node) else: sub.error(ObjectGoneError())