class MsgGetList(MsgpackMsg): """ Sent by client, requests a list of children of the given node matching the given filters. Children can be filtered by tags (the set of tags in the query must be a subset of the node's tags for it to match) and by a position filter. If sub is False, server will reply with a single MsgGetListReply with gone=[], or with a single MsgQueryError. If sub is True, the first reply will be like for sub=False, but subsequent replies will only mention changed nodes - nodes that are new on the list, along with changed nodes remaining on the list are sent in the objs field of the reply, while the IDs of nodes no longer on the list are sent in the gone field of the reply. The list may fail with ObjectGoneError if the parent node is gone. If it reappears in the future, a MsgGetListReply will be sent with a complete list of children. """ object_type = 'get_list' qid = fields.SmallUnsignedInteger() parent = fields.NodeID(default=NodeID.root_id) tags = fields.Set(fields.String()) pos_filter = fields.Object(PosFilter, default=PosFilter()) sub = fields.Boolean(default=False)
def get_list(self, parent, tags=frozenset(), pos_filter=PosFilter()): """ Fetches a list of children of a given node, containing given tags, and with pos_start/pos_end in the given ranges. Returns an awaitable of list of Nodes. """ raise NotImplementedError
def __init__(self, tracker, parent, tags=frozenset(), pos_filter=PosFilter()): self.parent = parent self.tags = tags self.pos_filter = pos_filter super().__init__(tracker)
def get_list(self, tags=frozenset(), pos_filter=PosFilter()): """ Fetches a list of children of this node, containing given tags, and with pos_start/pos_end in the given ranges. Returns an awaitable of list of AsyncNodes. """ anodes = self.conn.get_list(self.id, tags, pos_filter) async def inner(): nodes = await anodes res = [] for node in nodes: anode = self.conn.get_node_norefresh(node.id) anode.node = node res.append(anode) return res loop = asyncio.get_event_loop() return loop.create_task(inner())
def list(self, parent, tags=frozenset(), pos_filter=PosFilter()): if not isinstance(parent, NodeID): raise TypeError('parent must be a NodeID') if not isinstance(tags, (set, frozenset)): raise TypeError('tags must be a set') if not isinstance(pos_filter, PosFilter): raise TypeError('pos_filter must be a PosFilter') if parent == NodeID.root_id: stmt = """ SELECT id FROM node WHERE parent IS NULL """ args = () else: stmt = """ SELECT id FROM node WHERE parent = ? """ args = (buffer(parent.bytes), ) for tag in tags: if not isinstance(tag, six.text_type): raise TypeError('tag is not a string') stmt += """ AND EXISTS ( SELECT 1 FROM node_tag WHERE node_tag.id = node.id AND name = ? )""" args += (tag,) if pos_filter.start_from is not None: stmt += " AND pos_start >= ?" args += (db_bigint_encode(pos_filter.start_from),) if pos_filter.start_to is not None: stmt += " AND (pos_start <= ? OR pos_start IS NULL)" args += (db_bigint_encode(pos_filter.start_to),) if pos_filter.end_from is not None: stmt += " AND (pos_end >= ? OR pos_end is NULL)" args += (db_bigint_encode(pos_filter.end_from),) if pos_filter.end_to is not None: stmt += " AND pos_end <= ?" args += (db_bigint_encode(pos_filter.end_to),) c = self.db.cursor() c.execute(stmt, args) return {NodeID(bytes(x)) for x, in c.fetchall()}
def get_list(self, parent, tags=set(), pos_filter=PosFilter()): ares = self.conn.get_list(parent, tags, pos_filter) loop = asyncio.get_event_loop() return loop.create_task(self._get_list(parent, tags, pos_filter, ares))
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 get_list(self, parent, tags=frozenset(), pos_filter=PosFilter()): return [ self.get_cached_node(nid).node for nid in self.get_list_raw(parent, tags, pos_filter) ]
def get_list(self, parent, tags=frozenset(), pos_filter=PosFilter()): try: return done_future(self.tracker.get_list(parent, tags, pos_filter)) except VelesException as e: return bad_future(e)
from veles.proto.node import Node, PosFilter NODES = [ Node(id=NodeID()), Node(id=NodeID(), pos_start=17), Node(id=NodeID(), pos_end=17), Node(id=NodeID(), pos_start=0x123456789abcdef123456789), Node(id=NodeID(), pos_start=10, pos_end=20), Node(id=NodeID(), pos_start=20, pos_end=30), Node(id=NodeID(), pos_start=30, pos_end=40), Node(id=NodeID(), pos_start=10, pos_end=40), Node(id=NodeID(), pos_start=20), Node(id=NodeID(), pos_start=20, pos_end=20), ] CASES = [ (PosFilter(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), (PosFilter(start_from=9), [1, 3, 4, 5, 6, 7, 8, 9]), (PosFilter(start_from=10), [1, 3, 4, 5, 6, 7, 8, 9]), (PosFilter(start_from=11), [1, 3, 5, 6, 8, 9]), (PosFilter(start_from=20), [3, 5, 6, 8, 9]), (PosFilter(start_to=29), [0, 1, 2, 4, 5, 7, 8, 9]), (PosFilter(start_to=30), [0, 1, 2, 4, 5, 6, 7, 8, 9]), (PosFilter(start_from=15, start_to=25), [1, 5, 8, 9]), (PosFilter(end_from=19), [0, 1, 3, 4, 5, 6, 7, 8, 9]), (PosFilter(end_from=20), [0, 1, 3, 4, 5, 6, 7, 8, 9]), (PosFilter(end_from=21), [0, 1, 3, 5, 6, 7, 8]), (PosFilter(end_from=31), [0, 1, 3, 6, 7, 8]), (PosFilter(end_to=29), [2, 4, 9]), (PosFilter(end_to=30), [2, 5, 4, 9]), (PosFilter(end_from=15, end_to=25), [2, 4, 9]), (PosFilter.intersecting_with(20, 30), [0, 1, 5, 7, 8]),
def get_list(self, parent, tags=frozenset(), pos_filter=PosFilter()): return ListGetter(self.proto, parent, set(tags), pos_filter).future