self.execute(q, (node,))
return self.fetchone()
+ def node_get_versions(self, node, keys=(), propnames=_propnames):
+ """Return the properties of all versions at node.
+ If keys is empty, return all properties in the order
+ (serial, node, size, source, mtime, muser, cluster).
+ """
+
+ q = ("select serial, node, size, source, mtime, muser, cluster "
+ "from versions "
+ "where node = ?")
+ self.execute(q, (serial,))
+ r = self.fetchall()
+ if r is None:
+ return r
+
+ if not keys:
+ return r
+ return [[p[propnames[k]] for k in keys if k in propnames] for p in r]
+
def node_count_children(self, node):
"""Return node's child count."""
do not belong to the cluster.
"""
+ execute = self.execute
+ fetchone = self.fetchone
+
# The node.
props = self.node_get_properties(node)
if props is None:
"from versions "
"where node = ? and mtime < ?) "
"and cluster != ?")
- self.execute(q, (node, before, except_cluster))
- props = self.fetchone()
+ execute(q, (node, before, except_cluster))
+ props = fetchone()
if props is None:
return None
mtime = props[MTIME]
"and node in (select node "
"from nodes "
"where parent = ?)")
- self.execute(q, (before, except_cluster, parent))
+ execute(q, (before, except_cluster, node))
r = fetchone()
if r is None:
return None
"and node in (select node "
"from nodes "
"where path like ?)")
- self.execute(q, (before, except_cluster, path + '%'))
+ execute(q, (before, except_cluster, path + '%'))
r = fetchone()
if r is None:
return None
q = "delete from attributes where serial = ?"
self.execute(q, (serial,))
-# def node_get_attribute_keys(self, parent):
-# """Return a list with all keys pairs defined
-# for the namespace of the node specified.
-# """
-#
-# q = ("select distinct key from attributes a, versions v, nodes n "
-# "where a.serial = v.serial and v.node = n.node and n.parent = ?")
-# self.execute(q, (parent,))
-# return [r[0] for r in self.fetchall()]
-
def attribute_copy(self, source, dest):
q = ("insert or replace into attributes "
"select ?, key, value from attributes "
"where serial = ?")
self.execute(q, (dest, source))
+
+ def latest_attribute_keys(self, parent, before=inf, except_cluster=0, allowed_paths=[]):
+ """Return a list with all keys pairs defined
+ for all latest versions under parent that
+ do not belong to the cluster.
+ """
+
+ # TODO: Use another table to store before=inf results.
+ q = ("select a.key "
+ "from attributes a, versions v, nodes n "
+ "where v.serial = (select max(serial) "
+ "from versions "
+ "where node = v.node and mtime < ?) "
+ "and v.cluster != ? "
+ "and v.node in (select node "
+ "from nodes "
+ "where parent = ?) "
+ "and a.serial = v.serial "
+ "and n.node = v.node")
+ args = (before, except_cluster, parent)
+ for path in allowed_paths:
+ q += ' and n.path like ?'
+ args += (path + '%',)
+ self.execute(q, args)
+ return [r[0] for r in self.fetchall()]
def list_accounts(self, user, marker=None, limit=10000):
"""Return a list of accounts the user can access."""
+ logger.debug("list_accounts: %s %s", user, marker, limit)
allowed = self._allowed_accounts(user)
start, limit = self._list_limits(allowed, marker, limit)
return allowed[start:start + limit]
if not allowed:
raise NotAllowedError
path, node = self._lookup_container(account, container)
- # TODO: Implement.
- return []
+ before = until if until is not None else inf
+ return self.node.latest_attribute_keys(node, before, CLUSTER_DELETED, allowed)
@backend_method
def get_object_meta(self, user, account, container, name, version=None):
logger.debug("list_versions: %s %s %s", account, container, name)
self._can_read(user, account, container, name)
- # TODO: Implement.
- return []
+ return self.node.node_get_versions(node, ['serial', 'mtime'])
@backend_method(autocommit=0)
def get_block(self, hash):