Revision 2715ade4 snf-pithos-backend/pithos/backends/lib/sqlalchemy/xfeatures.py

b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/xfeatures.py
1 1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
# 
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
40 40

  
41 41
from dbworker import DBWorker
42 42

  
43

  
43 44
def create_tables(engine):
44 45
    metadata = MetaData()
45
    columns=[]
46
    columns = []
46 47
    columns.append(Column('feature_id', Integer, primary_key=True))
47 48
    columns.append(Column('path', String(2048)))
48 49
    xfeatures = Table('xfeatures', metadata, *columns, mysql_engine='InnoDB')
49 50
    # place an index on path
50 51
    Index('idx_features_path', xfeatures.c.path, unique=True)
51
    
52
    columns=[]
52

  
53
    columns = []
53 54
    columns.append(Column('feature_id', Integer,
54 55
                          ForeignKey('xfeatures.feature_id',
55 56
                                     ondelete='CASCADE'),
......
57 58
    columns.append(Column('key', Integer, primary_key=True,
58 59
                          autoincrement=False))
59 60
    columns.append(Column('value', String(256), primary_key=True))
60
    xfeaturevals = Table('xfeaturevals', metadata, *columns, mysql_engine='InnoDB')
61
    
61
    xfeaturevals = Table(
62
        'xfeaturevals', metadata, *columns, mysql_engine='InnoDB')
63

  
62 64
    metadata.create_all(engine)
63 65
    return metadata.sorted_tables
64 66

  
67

  
65 68
class XFeatures(DBWorker):
66 69
    """XFeatures are path properties that allow non-nested
67 70
       inheritance patterns. Currently used for storing permissions.
68 71
    """
69
    
72

  
70 73
    def __init__(self, **params):
71 74
        DBWorker.__init__(self, **params)
72 75
        try:
......
76 79
        except NoSuchTableError:
77 80
            tables = create_tables(self.engine)
78 81
            map(lambda t: self.__setattr__(t.name, t), tables)
79
    
82

  
80 83
#     def xfeature_inherit(self, path):
81 84
#         """Return the (path, feature) inherited by the path, or None."""
82
#         
85
#
83 86
#         s = select([self.xfeatures.c.path, self.xfeatures.c.feature_id])
84 87
#         s = s.where(self.xfeatures.c.path <= path)
85 88
#         #s = s.where(self.xfeatures.c.path.like(self.escape_like(path) + '%', escape='\\')) # XXX: Implement reverse and escape like...
......
88 91
#         l = r.fetchall()
89 92
#         r.close()
90 93
#         return l
91
    
94

  
92 95
    def xfeature_get(self, path):
93 96
        """Return feature for path."""
94
        
97

  
95 98
        s = select([self.xfeatures.c.feature_id])
96 99
        s = s.where(self.xfeatures.c.path == path)
97 100
        s = s.order_by(self.xfeatures.c.path)
......
101 104
        if row:
102 105
            return row[0]
103 106
        return None
104
    
107

  
105 108
    def xfeature_create(self, path):
106 109
        """Create and return a feature for path.
107 110
           If the path has a feature, return it.
108 111
        """
109
        
112

  
110 113
        feature = self.xfeature_get(path)
111 114
        if feature is not None:
112 115
            return feature
......
115 118
        inserted_primary_key = r.inserted_primary_key[0]
116 119
        r.close()
117 120
        return inserted_primary_key
118
    
121

  
119 122
    def xfeature_destroy(self, path):
120 123
        """Destroy a feature and all its key, value pairs."""
121
        
124

  
122 125
        s = self.xfeatures.delete().where(self.xfeatures.c.path == path)
123 126
        r = self.conn.execute(s)
124 127
        r.close()
125
    
128

  
126 129
    def xfeature_destroy_bulk(self, paths):
127 130
        """Destroy features and all their key, value pairs."""
128
        
131

  
129 132
        s = self.xfeatures.delete().where(self.xfeatures.c.path.in_(paths))
130 133
        r = self.conn.execute(s)
131 134
        r.close()
132
    
135

  
133 136
    def feature_dict(self, feature):
134 137
        """Return a dict mapping keys to list of values for feature."""
135
        
138

  
136 139
        s = select([self.xfeaturevals.c.key, self.xfeaturevals.c.value])
137 140
        s = s.where(self.xfeaturevals.c.feature_id == feature)
138 141
        r = self.conn.execute(s)
......
141 144
            d[key].append(value)
142 145
        r.close()
143 146
        return d
144
    
147

  
145 148
    def feature_set(self, feature, key, value):
146 149
        """Associate a key, value pair with a feature."""
147
        
150

  
148 151
        s = self.xfeaturevals.select()
149 152
        s = s.where(self.xfeaturevals.c.feature_id == feature)
150 153
        s = s.where(self.xfeaturevals.c.key == key)
......
156 159
            s = self.xfeaturevals.insert()
157 160
            r = self.conn.execute(s, feature_id=feature, key=key, value=value)
158 161
            r.close()
159
    
162

  
160 163
    def feature_setmany(self, feature, key, values):
161 164
        """Associate the given key, and values with a feature."""
162
        
165

  
163 166
        #TODO: more efficient way to do it
164 167
        for v in values:
165 168
            self.feature_set(feature, key, v)
166
    
169

  
167 170
    def feature_unset(self, feature, key, value):
168 171
        """Disassociate a key, value pair from a feature."""
169
        
172

  
170 173
        s = self.xfeaturevals.delete()
171 174
        s = s.where(and_(self.xfeaturevals.c.feature_id == feature,
172
                     self.xfeaturevals.c.key == key,
173
                     self.xfeaturevals.c.value == value))
175
                         self.xfeaturevals.c.key == key,
176
                         self.xfeaturevals.c.value == value))
174 177
        r = self.conn.execute(s)
175 178
        r.close()
176
    
179

  
177 180
    def feature_unsetmany(self, feature, key, values):
178 181
        """Disassociate the key for the values given, from a feature."""
179
        
182

  
180 183
        for v in values:
181 184
            conditional = and_(self.xfeaturevals.c.feature_id == feature,
182 185
                               self.xfeaturevals.c.key == key,
......
184 187
            s = self.xfeaturevals.delete().where(conditional)
185 188
            r = self.conn.execute(s)
186 189
            r.close()
187
        
190

  
188 191
    def feature_get(self, feature, key):
189 192
        """Return the list of values for a key of a feature."""
190
        
193

  
191 194
        s = select([self.xfeaturevals.c.value])
192 195
        s = s.where(and_(self.xfeaturevals.c.feature_id == feature,
193
                     self.xfeaturevals.c.key == key))
196
                         self.xfeaturevals.c.key == key))
194 197
        r = self.conn.execute(s)
195 198
        l = [row[0] for row in r.fetchall()]
196 199
        r.close()
197 200
        return l
198
    
201

  
199 202
    def feature_clear(self, feature, key):
200 203
        """Delete all key, value pairs for a key of a feature."""
201
        
204

  
202 205
        s = self.xfeaturevals.delete()
203 206
        s = s.where(and_(self.xfeaturevals.c.feature_id == feature,
204
                     self.xfeaturevals.c.key == key))
207
                         self.xfeaturevals.c.key == key))
205 208
        r = self.conn.execute(s)
206 209
        r.close()

Also available in: Unified diff