class PersistentOrderedDict(Persistent): ''' This class implements the same interface as the `collections.OrderedDict` class from the standard library, but uses `persistent` data types for Durus support. ''' def __init__(self, items=None): self.key_index = PersistentList() self.data = PersistentDict() if items: for k, v in items: self[k] = v def keys(self): return self.key_index[:] def __setitem__(self, k, v): if k not in self.data: self.key_index.append(k) self.data[k] = v def items(self): return [(k, v) for k, v in self.iteritems()] def iteritems(self): for k in self.key_index: yield k, self.data[k] def values(self): return [v for k, v in self.iteritems()] def get(self, key): return self.data.get(key) def __delitem__(self, key): del self.data[key] i = self.key_index.index(key) del self.key_index[i] def __getitem__(self, key): return self.data[key] def move_to_end(self, key, last=True): assert(key in self) items = [] for k, v in self.items(): if k != key: items.append((k, v)) del self[k] if last: items.append((key, self[key])) del self[key] for k, v in items: self[k] = v def __contains__(self, key): return key in self.data def __len__(self): return len(self.key_index)
class Document(Persistent): @property def handler(self): return _handler_index[id(self)] def __init__(self): self.notes = BTree() self.subscribers = PersistentList() self.notes[0] = Note(self, 0, {'desc': 'ROOT'}) def create_note(self, props={}, cls=Note, parent_id=0, id=None): if id is None: if self.notes: id = max(self.list_note_ids()) + 1 else: id = 0 if id in self.notes: raise ValueError('Note id "%s" already in use' % id) note = cls(self, id, props) self.notes[id] = note self.notes[parent_id]._children.append(note.id) return note def get_note(self, note_id): return self.notes[note_id] def list_note_ids(self): return self.notes.iterkeys() def list_notes(self): return self.notes.itervalues() def del_note(self, note_id): for child_note_id in self.get_note(note_id)._children: self.del_note(child_note_id) self._cleanup_child_links(note_id) del self.notes[note_id] def subscribe(self, subscriber): self.subscribers.append(subscriber) def _cleanup_child_links(self, note_id): for note in self.list_notes(): if note_id in note._children: note._children.remove(note_id) def dump_notes(self): def generate(): for note in self.list_notes(): note_data = { 'props': dict(note._props), 'children': list(note._children), } yield note.id, note_data return json.dumps(dict(generate())) # TODO: deprecate these methods def abort(self): self.handler.abort() def commit(self): self.handler.commit() def close(self): self.handler.close()
def test_nonzero(self): p = PersistentList() assert not p self.root['a'] = p self.connection.commit() p.append(1) assert p assert p._p_is_unsaved()
def nonzero(self): p = PersistentList() assert not p self.root['a'] = p self.connection.commit() p.append(1) assert p assert p._p_is_unsaved()
def __init__(self, subnet=None, subnetname=None): super(Network, self).__init__() self.name = None self.mask = None self._subnets = PersistentList() self.nodes = PersistentDict() # actually, Interface objects self._gatways = PersistentList() if subnet: self.add_subnet(subnet, subnetname)
def cmp(self): p = PersistentList(interval(10)) p2 = PersistentList(interval(10)) assert p == p2 assert p == list(p2) assert p <= p2 assert p >= p2 assert not p < p2 assert not p > p2 p.append(3) assert p != p2
def slice(self): p = PersistentList(x for x in interval(10)) p[:] = [2, 3] assert len(p) == 2 assert p[-1:] == [3] p[1:] = PersistentList(interval(2)) assert p == [2, 0, 1], p.data p[:] = (3, 4) assert p == [3, 4] del p[:1] assert p == [4]
def test_cmp(self): p = PersistentList(interval(10)) p2 = PersistentList(interval(10)) assert p == p2 assert p == list(p2) assert p <= p2 assert p >= p2 assert not p < p2 assert not p > p2 p.append(3) assert p != p2
def test_other(self): p = PersistentList() p.insert(0, 2) assert p == [2] assert p.count(0) == 0 assert p.count(2) == 1 assert p.index(2) == 0 p.remove(2) p.extend(PersistentList(interval(3))) assert p == interval(3)
def arith(self): p = PersistentList(interval(3)) p2 = PersistentList(interval(3)) assert p + p2 == interval(3) + interval(3) assert interval(3) + p2 == interval(3) + interval(3) assert tuple(interval(3)) + p2 == interval(3) + interval(3) assert p + interval(3) == interval(3) + interval(3) assert p + tuple(interval(3)) == interval(3) + interval(3) assert p * 2 == interval(3) + interval(3) p += p2 assert p == interval(3) + interval(3) p2 += interval(3) assert p == interval(3) + interval(3) p = PersistentList(interval(3)) p *= 2 assert p == interval(3) + interval(3)
def index_pagename(self, pagename): pm = self.getpage(pagename) ol, ul = pm.outlinks, pm.unlinks # set-ify to eliminate dups for metakey in set(pm.outlinks.keys() + pm.unlinks.keys()): pl = self.pagename_by_metakey.setdefault(metakey, PersistentList()) # add page name to metakey index if pagename not in pl: pl.append(pagename) # add page to metaval index for val in set(ol.get(metakey, []) + ul.get(metakey, [])): self.pagename_by_metaval.setdefault( val, PersistentList()).append(pagename)
def __init__(self, name): super(NetworkDevice, self).__init__() self.name = self.hostname = str(name) self.INTERFACEMAP = PersistentDict() self._interfaces = PersistentDict() self.data_interfaces = PersistentList() self.admin_interface = None self.initialize() # subclass interface
def check_touch_every_reference(self): connection = Connection(self._get_storage()) root = connection.get_root() root['a'] = Persistent() root['b'] = Persistent() from durus.persistent_list import PersistentList root['b'].c = PersistentList() connection.commit() touch_every_reference(connection, 'PersistentList') assert root['b']._p_is_unsaved() assert root['b'].c._p_is_unsaved() assert not root._p_is_unsaved() assert len(list(connection.get_cache())) == 4
def test_iter(self): p = PersistentList() assert list(p) == [] p.extend([2,3,4]) assert list(p) == [2,3,4]
def set_single(self, typ, val): self[typ] = PersistentList([val])
def __init__(self, urlfeed): self.url = urlfeed self.title = '' self.link = '' self.last_items = PersistentList() # last 50, for example, only hash self.users = PersistentSet() # CUser set
def sort(self): p = PersistentList(x for x in interval(10)) p.reverse() assert p == list(reversed(interval(10))) p = sorted(p) assert p == interval(10)
class Network(OwnedPersistent): _netnode_template = """| +---------------------------------------------+ |--| %-20.20s (%-20.20s) | | +---------------------------------------------+""" # don't touch this def __init__(self, subnet=None, subnetname=None): super(Network, self).__init__() self.name = None self.mask = None self._subnets = PersistentList() self.nodes = PersistentDict() # actually, Interface objects self._gatways = PersistentList() if subnet: self.add_subnet(subnet, subnetname) def __str__(self): s = ["-"*70] sbl = [] sn = [] for subnet, name in self._subnets: sbl.append("%20s" % (subnet,)) sn.append("%20s" % (name,)) s.append(" | ".join(sbl)) s.append(" | ".join(sn)) s.append("-"*70) for node in self.nodes.values(): s.append(self._netnode_template % (node.owner.name, node.owner.__class__.__name__)) return "\n".join(s) def __repr__(self): try: addr, name = self._subnets[0] return "%s(%r, %r)" % (self.__class__.__name__, addr, name) except IndexError: return "%s()" % (self.__class__.__name__) def __getitem__(self, idx): return self._subnets[idx] def __iter__(self): return iter(self._subnets) def add_interface(self, interface): self.nodes[interface.hostname] = interface interface.network = self def del_interface(self, interface): del self.nodes[interface.hostname] interface.network = None def get_interfaces(self): return self.nodes.copy() def get_node(self, hostname): intf = self.nodes[str(hostname)] return intf.owner def add_node(self, netdev): for intf in netdev.interfaces.values(): for subnet, name in self._subnets: if intf.address in subnet: self.nodes[intf.name] = intf intf.network = self return def add_subnet(self, addr, name=None): sn = ipv4.IPv4(addr) sn.host = 0 name = name or sn.cidr() if not self._subnets: # first subnet sets the name and mask self.name = name self.mask = sn.mask self._subnets.append((sn, name)) self._p_note_change() return sn def remove_subnet(self, name): for i, (sn, netname) in enumerate(self._subnets[:]): if netname == name: del self._subnets[i] def get_subnets(self): return list(self._subnets) subnets = property(get_subnets) def __contains__(self, address): if isinstance(address, str): address = ipv4.IPv4(address) for subnet, name in self._subnets: if address in subnet: return True return False
def other(self): p = PersistentList() p.insert(0, 2) assert p == [2] assert p.count(0) == 0 assert p.count(2) == 1 assert p.index(2) == 0 p.remove(2) p.extend(PersistentList(interval(3))) assert p == interval(3)
def delete(self): p = PersistentList(x for x in interval(10)) self.root['x'] = p self.connection.commit() del p[1] assert p._p_is_unsaved()
def __init__(self, *args, **kwargs): PersistentList.__init__(self, *args, **kwargs)
class Network(OwnedPersistent): _netnode_template = """| +---------------------------------------------+ |--| %-20.20s (%-20.20s) | | +---------------------------------------------+""" # don't touch this def __init__(self, subnet=None, subnetname=None): super(Network, self).__init__() self.name = None self.mask = None self._subnets = PersistentList() self.nodes = PersistentDict() # actually, Interface objects self._gatways = PersistentList() if subnet: self.add_subnet(subnet, subnetname) def __str__(self): s = ["-" * 70] sbl = [] sn = [] for subnet, name in self._subnets: sbl.append("%20s" % (subnet, )) sn.append("%20s" % (name, )) s.append(" | ".join(sbl)) s.append(" | ".join(sn)) s.append("-" * 70) for node in self.nodes.values(): s.append(self._netnode_template % (node.owner.name, node.owner.__class__.__name__)) return "\n".join(s) def __repr__(self): try: addr, name = self._subnets[0] return "%s(%r, %r)" % (self.__class__.__name__, addr, name) except IndexError: return "%s()" % (self.__class__.__name__) def __getitem__(self, idx): return self._subnets[idx] def __iter__(self): return iter(self._subnets) def add_interface(self, interface): self.nodes[interface.hostname] = interface interface.network = self def del_interface(self, interface): del self.nodes[interface.hostname] interface.network = None def get_interfaces(self): return self.nodes.copy() def get_node(self, hostname): intf = self.nodes[str(hostname)] return intf.owner def add_node(self, netdev): for intf in netdev.interfaces.values(): for subnet, name in self._subnets: if intf.address in subnet: self.nodes[intf.name] = intf intf.network = self return def add_subnet(self, addr, name=None): sn = ipv4.IPv4(addr) sn.host = 0 name = name or sn.cidr() if not self._subnets: # first subnet sets the name and mask self.name = name self.mask = sn.mask self._subnets.append((sn, name)) self._p_note_change() return sn def remove_subnet(self, name): for i, (sn, netname) in enumerate(self._subnets[:]): if netname == name: del self._subnets[i] def get_subnets(self): return list(self._subnets) subnets = property(get_subnets) def __contains__(self, address): if isinstance(address, str): address = ipv4.IPv4(address) for subnet, name in self._subnets: if address in subnet: return True return False
def __init__(self, jid): self.jid = jid self.items_pending = PersistentList() # [CItem, ...] self.config = PersistentDict() self.feeds = PersistentDict() # {CFeed: send first notification?}
def test_pop(self): p = PersistentList(x for x in interval(10)) p.pop() assert 9 not in p
def no_arbitrary_attributes(self): p = PersistentList() raises(AttributeError, setattr, p, 'bogus', 1)
def add(self, typ, val): try: l = self[typ] except KeyError: l = self[typ] = PersistentList() l.append(val)
def pop(self): p = PersistentList(x for x in interval(10)) p.pop() assert 9 not in p
def test_delete(self): p = PersistentList(x for x in interval(10)) self.root['x'] = p self.connection.commit() del p[1] assert p._p_is_unsaved()
def __init__(self, items=None): self.key_index = PersistentList() self.data = PersistentDict() if items: for k, v in items: self[k] = v
def test_sort(self): p = PersistentList(x for x in interval(10)) p.reverse() assert p == list(reversed(interval(10))) p = sorted(p) assert p == interval(10)
def iter(self): p = PersistentList() assert list(p) == [] p.extend([2, 3, 4]) assert list(p) == [2, 3, 4]
def clear_items(self): self.items_pending = PersistentList()
def insert_again(self): p = PersistentList([5, 6, 7]) p[1] = 2 p[1] = 3 assert p[1] == 3
def __init__(self): self.notes = BTree() self.subscribers = PersistentList() self.notes[0] = Note(self, 0, {'desc': 'ROOT'})
def contains(self): p = PersistentList(x for x in interval(5)) assert 2 in p assert -1 not in p