Revision ad9ada51

b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/alembic/versions/3b62b3f1bf6c_add_attributes_node_.py
1
"""add attributes node column
2

  
3
Revision ID: 3b62b3f1bf6c
4
Revises: 4c8ccdc58192
5
Create Date: 2013-07-04 13:11:01.842706
6

  
7
"""
8

  
9
# revision identifiers, used by Alembic.
10
revision = '3b62b3f1bf6c'
11
down_revision = '4c8ccdc58192'
12

  
13
from alembic import op
14
import sqlalchemy as sa
15
from sqlalchemy.sql import table, column, and_
16

  
17

  
18
def upgrade():
19
    op.add_column('attributes',
20
                  sa.Column('node', sa.Integer, default=0))
21
    op.add_column('attributes',
22
                  sa.Column('is_latest', sa.Boolean, default=True))
23

  
24
    n = table('nodes',
25
              column('node', sa.Integer),
26
              column('latest_version', sa.Integer))
27
    v = table('versions',
28
              column('node', sa.Integer),
29
              column('serial', sa.Integer))
30
    a = table('attributes',
31
              column('serial', sa.Integer),
32
              column('node', sa.Integer),
33
              column('is_latest', sa.Boolean))
34

  
35
    s = sa.select([v.c.node]).where(v.c.serial == a.c.serial)
36
    u = a.update().values({'node': s})
37
    op.execute(u)
38

  
39
    s = sa.select([v.c.serial == n.c.latest_version],
40
                  and_(a.c.node == n.c.node, a.c.serial == v.c.serial))
41
    u = a.update().values({'is_latest': s})
42
    op.execute(u)
43

  
44
    op.alter_column('attributes', 'node', nullable=False)
45
    op.alter_column('attributes', 'is_latest', nullable=False)
46

  
47
    op.create_index('idx_attributes_serial_node', 'attributes',
48
                    ['serial', 'node'])
49

  
50

  
51
def downgrade():
52
    op.drop_index('idx_attributes_serial_node')
53

  
54
    op.drop_column('attributes', 'is_latest')
55
    op.drop_column('attributes', 'node')
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/node.py
35 35
from operator import itemgetter
36 36
from itertools import groupby
37 37

  
38
from sqlalchemy import Table, Integer, BigInteger, DECIMAL, Column, String, MetaData, ForeignKey
38
from sqlalchemy import (Table, Integer, BigInteger, DECIMAL, Boolean,
39
                        Column, String, MetaData, ForeignKey)
39 40
from sqlalchemy.types import Text
40 41
from sqlalchemy.schema import Index, Sequence
41 42
from sqlalchemy.sql import func, and_, or_, not_, null, select, bindparam, text, exists
......
180 181
    columns.append(Column('domain', String(256), primary_key=True))
181 182
    columns.append(Column('key', String(128), primary_key=True))
182 183
    columns.append(Column('value', String(256)))
184
    columns.append(Column('node', Integer, nullable=False, default=0))
185
    columns.append(Column('is_latest', Boolean, nullable=False, default=True))
183 186
    attributes = Table('attributes', metadata, *columns, mysql_engine='InnoDB')
184 187
    Index('idx_attributes_domain', attributes.c.domain)
188
    Index('idx_attributes_serial_node', attributes.c.serial, attributes.c.node)
185 189

  
186 190
    metadata.create_all(engine)
187 191
    return metadata.sorted_tables
......
865 869
        r.close()
866 870
        return l
867 871

  
868
    def attribute_set(self, serial, domain, items):
872
    def attribute_set(self, serial, domain, node, items, is_latest=True):
869 873
        """Set the attributes of the version specified by serial.
870 874
           Receive attributes as an iterable of (key, value) pairs.
871 875
        """
......
881 885
            rp.close()
882 886
            if rp.rowcount == 0:
883 887
                s = self.attributes.insert()
884
                s = s.values(serial=serial, domain=domain, key=k, value=v)
888
                s = s.values(serial=serial, domain=domain, node=node,
889
                             is_latest=is_latest, key=k, value=v)
885 890
                self.conn.execute(s).close()
886 891

  
887 892
    def attribute_del(self, serial, domain, keys=()):
......
906 911

  
907 912
    def attribute_copy(self, source, dest):
908 913
        s = select(
909
            [dest, self.attributes.c.domain,
910
                self.attributes.c.key, self.attributes.c.value],
914
            [dest, self.attributes.c.domain, self.attributes.c.node,
915
             self.attributes.c.key, self.attributes.c.value],
911 916
            self.attributes.c.serial == source)
912 917
        rp = self.conn.execute(s)
913 918
        attributes = rp.fetchall()
914 919
        rp.close()
915
        for dest, domain, k, v in attributes:
916
            #insert or replace
920
        for dest, domain, node, k, v in attributes:
921
            # insert or replace
917 922
            s = self.attributes.update().where(and_(
918 923
                self.attributes.c.serial == dest,
919 924
                self.attributes.c.domain == domain,
920 925
                self.attributes.c.key == k))
921
            rp = self.conn.execute(s, value=v)
926
            s = s.values(value=v)
927
            rp = self.conn.execute(s)
922 928
            rp.close()
923 929
            if rp.rowcount == 0:
924 930
                s = self.attributes.insert()
925
                values = {'serial': dest, 'domain': domain,
926
                          'key': k, 'value': v}
927
                self.conn.execute(s, values).close()
931
                s = s.values(serial=dest, domain=domain, node=node,
932
                             is_latest=True, key=k, value=v)
933
            self.conn.execute(s).close()
934

  
935
    def attribute_unset_is_latest(self, node, exclude):
936
        u = self.attributes.update().where(and_(
937
            self.attributes.c.node == node,
938
                     self.attributes.c.serial != exclude)).values(
939
                             {'is_latest': False})
940
        self.conn.execute(u)
928 941

  
929 942
    def latest_attribute_keys(self, parent, domain, before=inf, except_cluster=0, pathq=None):
930 943
        """Return a list with all keys pairs defined
......
1178 1191
        s = select([n.c.path, v.c.serial, v.c.node, v.c.hash, v.c.size,
1179 1192
                    v.c.type, v.c.source, v.c.mtime, v.c.muser, v.c.uuid,
1180 1193
                    v.c.checksum, v.c.cluster, a.c.key, a.c.value])
1181
        s = s.where(n.c.node == v.c.node)
1182
        s = s.where(n.c.latest_version == v.c.serial)
1183 1194
        if cluster:
1184 1195
            s = s.where(v.c.cluster == cluster)
1185 1196
        s = s.where(v.c.serial == a.c.serial)
1186 1197
        s = s.where(a.c.domain == domain)
1198
        s = s.where(a.c.node == n.c.node)
1199
        s = s.where(a.c.is_latest == True)
1187 1200
        if paths:
1188 1201
            s = s.where(n.c.path.in_(paths))
1189 1202

  
b/snf-pithos-backend/pithos/backends/modular.py
863 863
        if src_version_id is None:
864 864
            src_version_id = pre_version_id
865 865
        self._put_metadata_duplicate(
866
            src_version_id, dest_version_id, domain, meta, replace_meta)
866
            src_version_id, dest_version_id, domain, node, meta, replace_meta)
867 867

  
868 868
        del_size = self._apply_versioning(account, container, pre_version_id,
869 869
                                          update_statistics_ancestors_depth=1)
......
1277 1277
        dest_version_id, mtime = self.node.version_create(
1278 1278
            node, hash, size, type, src_version_id, user, uuid, checksum,
1279 1279
            cluster, update_statistics_ancestors_depth)
1280

  
1281
        self.node.attribute_unset_is_latest(node, dest_version_id)
1282

  
1280 1283
        return pre_version_id, dest_version_id
1281 1284

  
1282
    def _put_metadata_duplicate(self, src_version_id, dest_version_id, domain, meta, replace=False):
1285
    def _put_metadata_duplicate(self, src_version_id, dest_version_id, domain,
1286
                                node, meta, replace=False):
1283 1287
        if src_version_id is not None:
1284 1288
            self.node.attribute_copy(src_version_id, dest_version_id)
1285 1289
        if not replace:
1286 1290
            self.node.attribute_del(dest_version_id, domain, (
1287 1291
                k for k, v in meta.iteritems() if v == ''))
1288
            self.node.attribute_set(dest_version_id, domain, (
1292
            self.node.attribute_set(dest_version_id, domain, node, (
1289 1293
                (k, v) for k, v in meta.iteritems() if v != ''))
1290 1294
        else:
1291 1295
            self.node.attribute_del(dest_version_id, domain)
1292
            self.node.attribute_set(dest_version_id, domain, ((
1296
            self.node.attribute_set(dest_version_id, domain, node, ((
1293 1297
                k, v) for k, v in meta.iteritems()))
1294 1298

  
1295 1299
    def _put_metadata(self, user, node, domain, meta, replace=False,
......
1300 1304
            user, node,
1301 1305
            update_statistics_ancestors_depth=update_statistics_ancestors_depth)
1302 1306
        self._put_metadata_duplicate(
1303
            src_version_id, dest_version_id, domain, meta, replace)
1307
            src_version_id, dest_version_id, domain, node, meta, replace)
1304 1308
        return src_version_id, dest_version_id
1305 1309

  
1306 1310
    def _list_limits(self, listing, marker, limit):

Also available in: Unified diff