Modular backend progress V.
authorAntony Chazapis <chazapis@gmail.com>
Mon, 8 Aug 2011 14:59:25 +0000 (17:59 +0300)
committerAntony Chazapis <chazapis@gmail.com>
Mon, 8 Aug 2011 14:59:25 +0000 (17:59 +0300)
pithos/backends/lib/node.py
pithos/backends/lib/permissions.py
pithos/backends/modular.py

index 6879b70..e0d3fc1 100644 (file)
@@ -190,6 +190,24 @@ class Node(DBWorker):
         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."""
         
@@ -360,6 +378,9 @@ class Node(DBWorker):
            do not belong to the cluster.
         """
         
+        execute = self.execute
+        fetchone = self.fetchone
+        
         # The node.
         props = self.node_get_properties(node)
         if props is None:
@@ -373,8 +394,8 @@ class Node(DBWorker):
                              "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]
@@ -389,7 +410,7 @@ class Node(DBWorker):
              "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
@@ -408,7 +429,7 @@ class Node(DBWorker):
              "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
@@ -713,18 +734,33 @@ class Node(DBWorker):
             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()]
index c89698a..02cefe5 100644 (file)
@@ -89,7 +89,7 @@ class Permissions(XFeatures, Groups, Public):
         for owner, group in self.group_parents(member):
             if owner + ':' + group in members:
                 return True
-        return True
+        return False
     
     def access_inherit(self, path):
         """Return the inherited or assigned (path, permissions) pair for path."""
index 9b5a9d6..5cec584 100644 (file)
@@ -112,6 +112,7 @@ class ModularBackend(BaseBackend):
     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]
@@ -378,8 +379,8 @@ class ModularBackend(BaseBackend):
             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):
@@ -554,8 +555,7 @@ class ModularBackend(BaseBackend):
         
         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):