~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/boto/boto/sdb/persist/property.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
 
2
#
 
3
# Permission is hereby granted, free of charge, to any person obtaining a
 
4
# copy of this software and associated documentation files (the
 
5
# "Software"), to deal in the Software without restriction, including
 
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
 
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
 
8
# persons to whom the Software is furnished to do so, subject to the fol-
 
9
# lowing conditions:
 
10
#
 
11
# The above copyright notice and this permission notice shall be included
 
12
# in all copies or substantial portions of the Software.
 
13
#
 
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
20
# IN THE SOFTWARE.
 
21
 
 
22
from boto.exception import SDBPersistenceError
 
23
from boto.sdb.persist.checker import StringChecker, PasswordChecker, IntegerChecker, BooleanChecker
 
24
from boto.sdb.persist.checker import DateTimeChecker, ObjectChecker, S3KeyChecker, S3BucketChecker
 
25
from boto.utils import Password
 
26
 
 
27
class Property(object):
 
28
 
 
29
    def __init__(self, checker_class, **params):
 
30
        self.name = ''
 
31
        self.checker = checker_class(**params)
 
32
        self.slot_name = '__'
 
33
        
 
34
    def set_name(self, name):
 
35
        self.name = name
 
36
        self.slot_name = '__' + self.name
 
37
 
 
38
class ScalarProperty(Property):
 
39
 
 
40
    def save(self, obj):
 
41
        domain = obj._manager.domain
 
42
        domain.put_attributes(obj.id, {self.name : self.to_string(obj)}, replace=True)
 
43
 
 
44
    def to_string(self, obj):
 
45
        return self.checker.to_string(getattr(obj, self.name))
 
46
 
 
47
    def load(self, obj):
 
48
        domain = obj._manager.domain
 
49
        a = domain.get_attributes(obj.id, self.name)
 
50
        # try to get the attribute value from SDB
 
51
        if self.name in a:
 
52
            value = self.checker.from_string(a[self.name], obj)
 
53
            setattr(obj, self.slot_name, value)
 
54
        # if it's not there, set the value to the default value
 
55
        else:
 
56
            self.__set__(obj, self.checker.default)
 
57
 
 
58
    def __get__(self, obj, objtype):
 
59
        if obj:
 
60
            try:
 
61
                value = getattr(obj, self.slot_name)
 
62
            except AttributeError:
 
63
                if obj._auto_update:
 
64
                    self.load(obj)
 
65
                    value = getattr(obj, self.slot_name)
 
66
                else:
 
67
                    value = self.checker.default
 
68
                    setattr(obj, self.slot_name, self.checker.default)
 
69
        return value
 
70
 
 
71
    def __set__(self, obj, value):
 
72
        self.checker.check(value)
 
73
        try:
 
74
            old_value = getattr(obj, self.slot_name)
 
75
        except:
 
76
            old_value = self.checker.default
 
77
        setattr(obj, self.slot_name, value)
 
78
        if obj._auto_update:
 
79
            try:
 
80
                self.save(obj)
 
81
            except:
 
82
                setattr(obj, self.slot_name, old_value)
 
83
                raise
 
84
                                      
 
85
class StringProperty(ScalarProperty):
 
86
 
 
87
    def __init__(self, **params):
 
88
        ScalarProperty.__init__(self, StringChecker, **params)
 
89
 
 
90
class PasswordProperty(ScalarProperty):
 
91
    """
 
92
    Hashed password
 
93
    """
 
94
 
 
95
    def __init__(self, **params):
 
96
        ScalarProperty.__init__(self, PasswordChecker, **params)
 
97
 
 
98
    def __set__(self, obj, value):
 
99
        p = Password()
 
100
        p.set(value)
 
101
        ScalarProperty.__set__(self, obj, p)
 
102
 
 
103
    def __get__(self, obj, objtype):
 
104
        return Password(ScalarProperty.__get__(self, obj, objtype))
 
105
 
 
106
class SmallPositiveIntegerProperty(ScalarProperty):
 
107
 
 
108
    def __init__(self, **params):
 
109
        params['size'] = 'small'
 
110
        params['signed'] = False
 
111
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
112
 
 
113
class SmallIntegerProperty(ScalarProperty):
 
114
 
 
115
    def __init__(self, **params):
 
116
        params['size'] = 'small'
 
117
        params['signed'] = True
 
118
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
119
 
 
120
class PositiveIntegerProperty(ScalarProperty):
 
121
 
 
122
    def __init__(self, **params):
 
123
        params['size'] = 'medium'
 
124
        params['signed'] = False
 
125
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
126
 
 
127
class IntegerProperty(ScalarProperty):
 
128
 
 
129
    def __init__(self, **params):
 
130
        params['size'] = 'medium'
 
131
        params['signed'] = True
 
132
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
133
 
 
134
class LargePositiveIntegerProperty(ScalarProperty):
 
135
 
 
136
    def __init__(self, **params):
 
137
        params['size'] = 'large'
 
138
        params['signed'] = False
 
139
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
140
 
 
141
class LargeIntegerProperty(ScalarProperty):
 
142
 
 
143
    def __init__(self, **params):
 
144
        params['size'] = 'large'
 
145
        params['signed'] = True
 
146
        ScalarProperty.__init__(self, IntegerChecker, **params)
 
147
 
 
148
class BooleanProperty(ScalarProperty):
 
149
 
 
150
    def __init__(self, **params):
 
151
        ScalarProperty.__init__(self, BooleanChecker, **params)
 
152
 
 
153
class DateTimeProperty(ScalarProperty):
 
154
 
 
155
    def __init__(self, **params):
 
156
        ScalarProperty.__init__(self, DateTimeChecker, **params)
 
157
 
 
158
class ObjectProperty(ScalarProperty):
 
159
 
 
160
    def __init__(self, **params):
 
161
        ScalarProperty.__init__(self, ObjectChecker, **params)
 
162
 
 
163
class S3KeyProperty(ScalarProperty):
 
164
 
 
165
    def __init__(self, **params):
 
166
        ScalarProperty.__init__(self, S3KeyChecker, **params)
 
167
        
 
168
    def __set__(self, obj, value):
 
169
        self.checker.check(value)
 
170
        try:
 
171
            old_value = getattr(obj, self.slot_name)
 
172
        except:
 
173
            old_value = self.checker.default
 
174
        if isinstance(value, str):
 
175
            value = self.checker.from_string(value, obj)
 
176
        setattr(obj, self.slot_name, value)
 
177
        if obj._auto_update:
 
178
            try:
 
179
                self.save(obj)
 
180
            except:
 
181
                setattr(obj, self.slot_name, old_value)
 
182
                raise
 
183
                                      
 
184
class S3BucketProperty(ScalarProperty):
 
185
 
 
186
    def __init__(self, **params):
 
187
        ScalarProperty.__init__(self, S3BucketChecker, **params)
 
188
        
 
189
    def __set__(self, obj, value):
 
190
        self.checker.check(value)
 
191
        try:
 
192
            old_value = getattr(obj, self.slot_name)
 
193
        except:
 
194
            old_value = self.checker.default
 
195
        if isinstance(value, str):
 
196
            value = self.checker.from_string(value, obj)
 
197
        setattr(obj, self.slot_name, value)
 
198
        if obj._auto_update:
 
199
            try:
 
200
                self.save(obj)
 
201
            except:
 
202
                setattr(obj, self.slot_name, old_value)
 
203
                raise
 
204
 
 
205
class MultiValueProperty(Property):
 
206
 
 
207
    def __init__(self, checker_class, **params):
 
208
        Property.__init__(self, checker_class, **params)
 
209
 
 
210
    def __get__(self, obj, objtype):
 
211
        if obj:
 
212
            try:
 
213
                value = getattr(obj, self.slot_name)
 
214
            except AttributeError:
 
215
                if obj._auto_update:
 
216
                    self.load(obj)
 
217
                    value = getattr(obj, self.slot_name)
 
218
                else:
 
219
                    value = MultiValue(self, obj, [])
 
220
                    setattr(obj, self.slot_name, value)
 
221
        return value
 
222
 
 
223
    def load(self, obj):
 
224
        if obj != None:
 
225
            _list = []
 
226
            domain = obj._manager.domain
 
227
            a = domain.get_attributes(obj.id, self.name)
 
228
            if self.name in a:
 
229
                lst = a[self.name]
 
230
                if not isinstance(lst, list):
 
231
                    lst = [lst]
 
232
                for value in lst:
 
233
                    value = self.checker.from_string(value, obj)
 
234
                    _list.append(value)
 
235
        setattr(obj, self.slot_name, MultiValue(self, obj, _list))
 
236
 
 
237
    def __set__(self, obj, value):
 
238
        if not isinstance(value, list):
 
239
            raise SDBPersistenceError('Value must be a list')
 
240
        setattr(obj, self.slot_name, MultiValue(self, obj, value))
 
241
        str_list = self.to_string(obj)
 
242
        domain = obj._manager.domain
 
243
        if obj._auto_update:
 
244
            if len(str_list) == 1:
 
245
                domain.put_attributes(obj.id, {self.name : str_list[0]}, replace=True)
 
246
            else:
 
247
                try:
 
248
                    self.__delete__(obj)
 
249
                except:
 
250
                    pass
 
251
                domain.put_attributes(obj.id, {self.name : str_list}, replace=True)
 
252
                setattr(obj, self.slot_name, MultiValue(self, obj, value))
 
253
 
 
254
    def __delete__(self, obj):
 
255
        if obj._auto_update:
 
256
            domain = obj._manager.domain
 
257
            domain.delete_attributes(obj.id, [self.name])
 
258
        setattr(obj, self.slot_name, MultiValue(self, obj, []))
 
259
 
 
260
    def to_string(self, obj):
 
261
        str_list = []
 
262
        for value in self.__get__(obj, type(obj)):
 
263
            str_list.append(self.checker.to_string(value))
 
264
        return str_list
 
265
 
 
266
class StringListProperty(MultiValueProperty):
 
267
 
 
268
    def __init__(self, **params):
 
269
        MultiValueProperty.__init__(self, StringChecker, **params)
 
270
 
 
271
class SmallIntegerListProperty(MultiValueProperty):
 
272
 
 
273
    def __init__(self, **params):
 
274
        params['size'] = 'small'
 
275
        params['signed'] = True
 
276
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
277
 
 
278
class SmallPositiveIntegerListProperty(MultiValueProperty):
 
279
 
 
280
    def __init__(self, **params):
 
281
        params['size'] = 'small'
 
282
        params['signed'] = False
 
283
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
284
 
 
285
class IntegerListProperty(MultiValueProperty):
 
286
 
 
287
    def __init__(self, **params):
 
288
        params['size'] = 'medium'
 
289
        params['signed'] = True
 
290
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
291
 
 
292
class PositiveIntegerListProperty(MultiValueProperty):
 
293
 
 
294
    def __init__(self, **params):
 
295
        params['size'] = 'medium'
 
296
        params['signed'] = False
 
297
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
298
 
 
299
class LargeIntegerListProperty(MultiValueProperty):
 
300
 
 
301
    def __init__(self, **params):
 
302
        params['size'] = 'large'
 
303
        params['signed'] = True
 
304
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
305
 
 
306
class LargePositiveIntegerListProperty(MultiValueProperty):
 
307
 
 
308
    def __init__(self, **params):
 
309
        params['size'] = 'large'
 
310
        params['signed'] = False
 
311
        MultiValueProperty.__init__(self, IntegerChecker, **params)
 
312
 
 
313
class BooleanListProperty(MultiValueProperty):
 
314
 
 
315
    def __init__(self, **params):
 
316
        MultiValueProperty.__init__(self, BooleanChecker, **params)
 
317
 
 
318
class ObjectListProperty(MultiValueProperty):
 
319
 
 
320
    def __init__(self, **params):
 
321
        MultiValueProperty.__init__(self, ObjectChecker, **params)
 
322
        
 
323
class HasManyProperty(Property):
 
324
 
 
325
    def set_name(self, name):
 
326
        self.name = name
 
327
        self.slot_name = '__' + self.name
 
328
 
 
329
    def __get__(self, obj, objtype):
 
330
        return self
 
331
 
 
332
 
 
333
class MultiValue:
 
334
    """
 
335
    Special Multi Value for boto persistence layer to allow us to do 
 
336
    obj.list.append(foo)
 
337
    """
 
338
    def __init__(self, property, obj, _list):
 
339
        self.checker = property.checker
 
340
        self.name = property.name
 
341
        self.object = obj
 
342
        self._list = _list
 
343
 
 
344
    def __repr__(self):
 
345
        return repr(self._list)
 
346
 
 
347
    def __getitem__(self, key):
 
348
        return self._list.__getitem__(key)
 
349
 
 
350
    def __delitem__(self, key):
 
351
        item = self[key]
 
352
        self._list.__delitem__(key)
 
353
        domain = self.object._manager.domain
 
354
        domain.delete_attributes(self.object.id, {self.name: [self.checker.to_string(item)]})
 
355
 
 
356
    def __len__(self):
 
357
        return len(self._list)
 
358
 
 
359
    def append(self, value):
 
360
        self.checker.check(value)
 
361
        self._list.append(value)
 
362
        domain = self.object._manager.domain
 
363
        domain.put_attributes(self.object.id, {self.name: self.checker.to_string(value)}, replace=False)
 
364
 
 
365
    def index(self, value):
 
366
        for x in self._list:
 
367
            if x.id == value.id:
 
368
                return self._list.index(x)
 
369
 
 
370
    def remove(self, value):
 
371
        del(self[self.index(value)])