Revision 5576e6dd

b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/node.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
from time import time
35
from operator import itemgetter
36
from itertools import groupby
37

  
35 38
from sqlalchemy import Table, Integer, BigInteger, DECIMAL, Column, String, MetaData, ForeignKey
36 39
from sqlalchemy.types import Text
37 40
from sqlalchemy.schema import Index, Sequence
......
178 181
    columns.append(Column('key', String(128), primary_key=True))
179 182
    columns.append(Column('value', String(256)))
180 183
    attributes = Table('attributes', metadata, *columns, mysql_engine='InnoDB')
184
    Index('idx_attributes_domain', attributes.c.domain)
181 185

  
182 186
    metadata.create_all(engine)
183 187
    return metadata.sorted_tables
......
1104 1108
        l = r.fetchone()
1105 1109
        r.close()
1106 1110
        return l
1111

  
1112
    def domain_object_list(self, domain, cluster=None):
1113
        """Return a list of (path, property list, attribute dictionary)
1114
           for the objects in the specific domain and cluster.
1115
        """
1116

  
1117
        v = self.versions.alias('v')
1118
        n = self.nodes.alias('n')
1119
        a = self.attributes.alias('a')
1120

  
1121
        s = select([n.c.path, v.c.serial, v.c.node, v.c.hash, v.c.size,
1122
                    v.c.type, v.c.source, v.c.mtime, v.c.muser, v.c.uuid,
1123
                    v.c.checksum, v.c.cluster, a.c.key, a.c.value])
1124
        s = s.where(n.c.node == v.c.node)
1125
        s = s.where(n.c.latest_version == v.c.serial)
1126
        if cluster:
1127
            s = s.where(v.c.cluster == cluster)
1128
        s = s.where(v.c.serial == a.c.serial)
1129
        s = s.where(a.c.domain == domain)
1130

  
1131
        r = self.conn.execute(s)
1132
        rows = r.fetchall()
1133
        r.close()
1134

  
1135
        group_by = itemgetter(slice(12))
1136
        rows.sort(key = group_by)
1137
        groups = groupby(rows, group_by)
1138
        return [(k[0], k[1:], dict([i[12:] for i in data])) \
1139
            for (k, data) in groups]
b/snf-pithos-backend/pithos/backends/lib/sqlite/node.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
from time import time
35
from operator import itemgetter
36
from itertools import groupby
35 37

  
36 38
from dbworker import DBWorker
37 39

  
......
180 182
                            references versions(serial)
181 183
                            on update cascade
182 184
                            on delete cascade ) """)
185
        execute(""" create index if not exists idx_attributes_domain
186
                    on attributes(domain) """)
183 187

  
184 188
        wrapper = self.wrapper
185 189
        wrapper.execute()
......
284 288
        self.statistics_update(parent, -nr, -size, mtime, cluster)
285 289
        self.statistics_update_ancestors(parent, -nr, -size, mtime, cluster)
286 290

  
287
        q = ("select hash from versions "
291
        q = ("select hash, serial from versions "
288 292
             "where node in (select node "
289 293
             "from nodes "
290 294
             "where parent = ?) "
......
333 337
        mtime = time()
334 338
        self.statistics_update_ancestors(node, -nr, -size, mtime, cluster)
335 339

  
336
        q = ("select hash from versions "
340
        q = ("select hash, serial from versions "
337 341
             "where node = ? "
338 342
             "and cluster = ? "
339 343
             "and mtime <= ?")
......
343 347
        for r in self.fetchall():
344 348
            hashes += [r[0]]
345 349
            serials += [r[1]]
346
        
350

  
347 351
        q = ("delete from versions "
348 352
             "where node = ? "
349 353
             "and cluster = ? "
......
1001 1005
             "and n.node = v.node") % cluster_where
1002 1006
        self.execute(q, args)
1003 1007
        return self.fetchone()
1008

  
1009
    def domain_object_list(self, domain, cluster=None):
1010
        """Return a list of (path, property list, attribute dictionary)
1011
           for the objects in the specific domain and cluster.
1012
        """
1013

  
1014
        q = ("select n.path, v.serial, v.node, v.hash, "
1015
             "v.size, v.type, v.source, v.mtime, v.muser, "
1016
             "v.uuid, v.checksum, v.cluster, a.key, a.value "
1017
             "from nodes n, versions v, attributes a "
1018
             "where n.node = v.node and "
1019
             "n.latest_version = v.serial and "
1020
             "v.serial = a.serial and "
1021
             "a.domain = ? ")
1022
        args = [domain]
1023
        if cluster != None:
1024
            q += "and v.cluster = ?"
1025
            args += [cluster]
1026

  
1027
        self.execute(q, args)
1028
        rows = self.fetchall()
1029

  
1030
        group_by = itemgetter(slice(12))
1031
        rows.sort(key = group_by)
1032
        groups = groupby(rows, group_by)
1033
        return [(k[0], k[1:], dict([i[12:] for i in data])) \
1034
            for (k, data) in groups]
b/snf-pithos-backend/pithos/backends/modular.py
614 614
            raise NotAllowedError
615 615
        if shared and public:
616 616
            # get shared first
617
            shared = self._list_object_permissions(
617
            shared_paths = self._list_object_permissions(
618 618
                user, account, container, prefix, shared=True, public=False)
619 619
            objects = set()
620
            if shared:
620
            if shared_paths:
621 621
                path, node = self._lookup_container(account, container)
622
                shared = self._get_formatted_paths(shared)
623
                objects |= set(self._list_object_properties(node, path, prefix, delimiter, marker, limit, virtual, domain, keys, until, size_range, shared, all_props))
622
                shared_paths = self._get_formatted_paths(shared_paths)
623
                objects |= set(self._list_object_properties(node, path, prefix, delimiter, marker, limit, virtual, domain, keys, until, size_range, shared_paths, all_props))
624 624

  
625 625
            # get public
626 626
            objects |= set(self._list_public_object_properties(
......
1516 1516
        for path in self.permissions.access_list_paths(user, account):
1517 1517
            allow.add(path.split('/', 2)[1])
1518 1518
        return sorted(allow)
1519

  
1520
    # Domain functions
1521

  
1522
    def _get_domain_objects(self, domain, user=None):
1523
        obj_list = self.node.domain_object_list(domain, CLUSTER_NORMAL)
1524
        if user != None:
1525
            obj_list = [t for t in obj_list \
1526
                if self._has_read_access(user, t[0])]
1527
        return [(path,
1528
                 self._build_metadata(props, user_defined_meta),
1529
                 self.permissions.access_get(path)) \
1530
            for path, props, user_defined_meta in obj_list]
1531

  
1532
    # util functions
1533

  
1534
    def _build_metadata(self, props, user_defined=None,
1535
                        include_user_defined=True):
1536
        meta = {'bytes': props[self.SIZE],
1537
                'type': props[self.TYPE],
1538
                'hash': props[self.HASH],
1539
                'version': props[self.SERIAL],
1540
                'version_timestamp': props[self.MTIME],
1541
                'modified_by': props[self.MUSER],
1542
                'uuid': props[self.UUID],
1543
                'checksum': props[self.CHECKSUM]}
1544
        if include_user_defined and user_defined != None:
1545
            meta.update(user_defined)
1546
        return meta
1547

  
1548
    def _has_read_access(self, user, path):
1549
        try:
1550
            account, container, object = path.split('/', 2)
1551
        except ValueError:
1552
            raise ValueError('Invalid object path')
1553

  
1554
        assert isinstance(user, basestring), "Invalid user"
1555

  
1556
        try:
1557
            self._can_read(user, account, container, object)
1558
        except NotAllowedError:
1559
            return False
1560
        else:
1561
            return True

Also available in: Unified diff