Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: boto/sdb/db/property.py

Issue 8386013: Merging in latest boto. (Closed) Base URL: svn://svn.chromium.org/boto
Patch Set: Redoing vendor drop by deleting and then merging. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « boto/sdb/db/model.py ('k') | boto/sdb/db/sequence.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/ 1 # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
2 # 2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a 3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the 4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including 5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis- 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 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- 8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions: 9 # lowing conditions:
10 # 10 #
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 boto.log.exception("Exception running on_set_%s" % self.name) 68 boto.log.exception("Exception running on_set_%s" % self.name)
69 69
70 setattr(obj, self.slot_name, value) 70 setattr(obj, self.slot_name, value)
71 71
72 def __property_config__(self, model_class, property_name): 72 def __property_config__(self, model_class, property_name):
73 self.model_class = model_class 73 self.model_class = model_class
74 self.name = property_name 74 self.name = property_name
75 self.slot_name = '_' + self.name 75 self.slot_name = '_' + self.name
76 76
77 def default_validator(self, value): 77 def default_validator(self, value):
78 if value == self.default_value(): 78 if isinstance(value, basestring) or value == self.default_value():
79 return 79 return
80 if not isinstance(value, self.data_type): 80 if not isinstance(value, self.data_type):
81 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value)) 81 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value))
82 82
83 def default_value(self): 83 def default_value(self):
84 return self.default 84 return self.default
85 85
86 def validate(self, value): 86 def validate(self, value):
87 if self.required and value==None: 87 if self.required and value==None:
88 raise ValueError, '%s is a required property' % self.name 88 raise ValueError, '%s is a required property' % self.name
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 class TextProperty(Property): 128 class TextProperty(Property):
129 129
130 type_name = 'Text' 130 type_name = 'Text'
131 131
132 def __init__(self, verbose_name=None, name=None, default='', required=False, 132 def __init__(self, verbose_name=None, name=None, default='', required=False,
133 validator=None, choices=None, unique=False, max_length=None): 133 validator=None, choices=None, unique=False, max_length=None):
134 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique) 134 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique)
135 self.max_length = max_length 135 self.max_length = max_length
136 136
137 def validate(self, value): 137 def validate(self, value):
138 value = super(TextProperty, self).validate(value)
138 if not isinstance(value, str) and not isinstance(value, unicode): 139 if not isinstance(value, str) and not isinstance(value, unicode):
139 raise TypeError, 'Expecting Text, got %s' % type(value) 140 raise TypeError, 'Expecting Text, got %s' % type(value)
140 if self.max_length and len(value) > self.max_length: 141 if self.max_length and len(value) > self.max_length:
141 raise ValueError, 'Length of value greater than maxlength %s' % self .max_length 142 raise ValueError, 'Length of value greater than maxlength %s' % self .max_length
142 143
143 class PasswordProperty(StringProperty): 144 class PasswordProperty(StringProperty):
144 """ 145 """
145 Hashed property who's original value can not be 146
146 retrieved, but still can be compaired. 147 Hashed property whose original value can not be
148 retrieved, but still can be compared.
149
150 Works by storing a hash of the original value instead
151 of the original value. Once that's done all that
152 can be retrieved is the hash.
153
154 The comparison
155
156 obj.password == 'foo'
157
158 generates a hash of 'foo' and compares it to the
159 stored hash.
160
161 Underlying data type for hashing, storing, and comparing
162 is boto.utils.Password. The default hash function is
163 defined there ( currently sha512 in most cases, md5
164 where sha512 is not available )
165
166 It's unlikely you'll ever need to use a different hash
167 function, but if you do, you can control the behavior
168 in one of two ways:
169
170 1) Specifying hashfunc in PasswordProperty constructor
171
172 import hashlib
173
174 class MyModel(model):
175 password = PasswordProperty(hashfunc=hashlib.sha224)
176
177 2) Subclassing Password and PasswordProperty
178
179 class SHA224Password(Password):
180 hashfunc=hashlib.sha224
181
182 class SHA224PasswordProperty(PasswordProperty):
183 data_type=MyPassword
184 type_name="MyPassword"
185
186 class MyModel(Model):
187 password = SHA224PasswordProperty()
188
147 """ 189 """
148 data_type = Password 190 data_type = Password
149 type_name = 'Password' 191 type_name = 'Password'
150 192
151 def __init__(self, verbose_name=None, name=None, default='', required=False, 193 def __init__(self, verbose_name=None, name=None, default='', required=False,
152 validator=None, choices=None, unique=False): 194 validator=None, choices=None, unique=False, hashfunc=None):
195
196 """
197 The hashfunc parameter overrides the default hashfunc in boto.utils.P assword.
198
199 The remaining parameters are passed through to StringProperty.__init_ _"""
200
201
153 StringProperty.__init__(self, verbose_name, name, default, required, val idator, choices, unique) 202 StringProperty.__init__(self, verbose_name, name, default, required, val idator, choices, unique)
203 self.hashfunc=hashfunc
154 204
155 def make_value_from_datastore(self, value): 205 def make_value_from_datastore(self, value):
156 p = Password(value) 206 p = self.data_type(value, hashfunc=self.hashfunc)
157 return p 207 return p
158 208
159 def get_value_for_datastore(self, model_instance): 209 def get_value_for_datastore(self, model_instance):
160 value = StringProperty.get_value_for_datastore(self, model_instance) 210 value = StringProperty.get_value_for_datastore(self, model_instance)
161 if value and len(value): 211 if value and len(value):
162 return str(value) 212 return str(value)
163 else: 213 else:
164 return None 214 return None
165 215
166 def __set__(self, obj, value): 216 def __set__(self, obj, value):
167 if not isinstance(value, Password): 217 if not isinstance(value, self.data_type):
168 p = Password() 218 p = self.data_type(hashfunc=self.hashfunc)
169 p.set(value) 219 p.set(value)
170 value = p 220 value = p
171 Property.__set__(self, obj, value) 221 Property.__set__(self, obj, value)
172 222
173 def __get__(self, obj, objtype): 223 def __get__(self, obj, objtype):
174 return Password(StringProperty.__get__(self, obj, objtype)) 224 return self.data_type(StringProperty.__get__(self, obj, objtype), hashfu nc=self.hashfunc)
175 225
176 def validate(self, value): 226 def validate(self, value):
177 value = Property.validate(self, value) 227 value = Property.validate(self, value)
178 if isinstance(value, Password): 228 if isinstance(value, self.data_type):
179 if len(value) > 1024: 229 if len(value) > 1024:
180 raise ValueError, 'Length of value greater than maxlength' 230 raise ValueError, 'Length of value greater than maxlength'
181 else: 231 else:
182 raise TypeError, 'Expecting Password, got %s' % type(value) 232 raise TypeError, 'Expecting %s, got %s' % (type(self.data_type), typ e(value))
183 233
184 class BlobProperty(Property): 234 class BlobProperty(Property):
185 data_type = Blob 235 data_type = Blob
186 type_name = "blob" 236 type_name = "blob"
187 237
188 def __set__(self, obj, value): 238 def __set__(self, obj, value):
189 if value != self.default_value(): 239 if value != self.default_value():
190 if not isinstance(value, Blob): 240 if not isinstance(value, Blob):
191 oldb = self.__get__(obj, type(obj)) 241 oldb = self.__get__(obj, type(obj))
192 id = None 242 id = None
193 if oldb: 243 if oldb:
194 id = oldb.id 244 id = oldb.id
195 b = Blob(value=value, id=id) 245 b = Blob(value=value, id=id)
196 value = b 246 value = b
197 Property.__set__(self, obj, value) 247 Property.__set__(self, obj, value)
198 248
199 class S3KeyProperty(Property): 249 class S3KeyProperty(Property):
200 250
201 data_type = boto.s3.key.Key 251 data_type = boto.s3.key.Key
202 type_name = 'S3Key' 252 type_name = 'S3Key'
203 validate_regex = "^s3:\/\/([^\/]*)\/(.*)$" 253 validate_regex = "^s3:\/\/([^\/]*)\/(.*)$"
204 254
205 def __init__(self, verbose_name=None, name=None, default=None, 255 def __init__(self, verbose_name=None, name=None, default=None,
206 required=False, validator=None, choices=None, unique=False): 256 required=False, validator=None, choices=None, unique=False):
207 Property.__init__(self, verbose_name, name, default, required, 257 Property.__init__(self, verbose_name, name, default, required,
208 validator, choices, unique) 258 validator, choices, unique)
209 259
210 def validate(self, value): 260 def validate(self, value):
261 value = super(S3KeyProperty, self).validate(value)
211 if value == self.default_value() or value == str(self.default_value()): 262 if value == self.default_value() or value == str(self.default_value()):
212 return self.default_value() 263 return self.default_value()
213 if isinstance(value, self.data_type): 264 if isinstance(value, self.data_type):
214 return 265 return
215 match = re.match(self.validate_regex, value) 266 match = re.match(self.validate_regex, value)
216 if match: 267 if match:
217 return 268 return
218 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.data_t ype, type(value)) 269 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.data_t ype, type(value))
219 270
220 def __get__(self, obj, objtype): 271 def __get__(self, obj, objtype):
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique) 384 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique)
334 self.auto_now = auto_now 385 self.auto_now = auto_now
335 self.auto_now_add = auto_now_add 386 self.auto_now_add = auto_now_add
336 387
337 def default_value(self): 388 def default_value(self):
338 if self.auto_now or self.auto_now_add: 389 if self.auto_now or self.auto_now_add:
339 return self.now() 390 return self.now()
340 return Property.default_value(self) 391 return Property.default_value(self)
341 392
342 def validate(self, value): 393 def validate(self, value):
394 value = super(DateTimeProperty, self).validate(value)
343 if value == None: 395 if value == None:
344 return 396 return
345 if not isinstance(value, self.data_type): 397 if not isinstance(value, self.data_type):
346 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value)) 398 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value))
347 399
348 def get_value_for_datastore(self, model_instance): 400 def get_value_for_datastore(self, model_instance):
349 if self.auto_now: 401 if self.auto_now:
350 setattr(model_instance, self.name, self.now()) 402 setattr(model_instance, self.name, self.now())
351 return Property.get_value_for_datastore(self, model_instance) 403 return Property.get_value_for_datastore(self, model_instance)
352 404
(...skipping 10 matching lines...) Expand all
363 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique) 415 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique)
364 self.auto_now = auto_now 416 self.auto_now = auto_now
365 self.auto_now_add = auto_now_add 417 self.auto_now_add = auto_now_add
366 418
367 def default_value(self): 419 def default_value(self):
368 if self.auto_now or self.auto_now_add: 420 if self.auto_now or self.auto_now_add:
369 return self.now() 421 return self.now()
370 return Property.default_value(self) 422 return Property.default_value(self)
371 423
372 def validate(self, value): 424 def validate(self, value):
425 value = super(DateProperty, self).validate(value)
373 if value == None: 426 if value == None:
374 return 427 return
375 if not isinstance(value, self.data_type): 428 if not isinstance(value, self.data_type):
376 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value)) 429 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value))
377 430
378 def get_value_for_datastore(self, model_instance): 431 def get_value_for_datastore(self, model_instance):
379 if self.auto_now: 432 if self.auto_now:
380 setattr(model_instance, self.name, self.now()) 433 setattr(model_instance, self.name, self.now())
381 val = Property.get_value_for_datastore(self, model_instance) 434 val = Property.get_value_for_datastore(self, model_instance)
382 if isinstance(val, datetime.datetime): 435 if isinstance(val, datetime.datetime):
383 val = val.date() 436 val = val.date()
384 return val 437 return val
385 438
386 def now(self): 439 def now(self):
387 return datetime.date.today() 440 return datetime.date.today()
388 441
442
443 class TimeProperty(Property):
444 data_type = datetime.time
445 type_name = 'Time'
446
447 def __init__(self, verbose_name=None, name=None,
448 default=None, required=False, validator=None, choices=None, uni que=False):
449 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique)
450
451 def validate(self, value):
452 value = super(TimeProperty, self).validate(value)
453 if value is None:
454 return
455 if not isinstance(value, self.data_type):
456 raise TypeError, 'Validation Error, expecting %s, got %s' % (self.da ta_type, type(value))
457
458
389 class ReferenceProperty(Property): 459 class ReferenceProperty(Property):
390 460
391 data_type = Key 461 data_type = Key
392 type_name = 'Reference' 462 type_name = 'Reference'
393 463
394 def __init__(self, reference_class=None, collection_name=None, 464 def __init__(self, reference_class=None, collection_name=None,
395 verbose_name=None, name=None, default=None, required=False, val idator=None, choices=None, unique=False): 465 verbose_name=None, name=None, default=None, required=False, val idator=None, choices=None, unique=False):
396 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique) 466 Property.__init__(self, verbose_name, name, default, required, validator , choices, unique)
397 self.reference_class = reference_class 467 self.reference_class = reference_class
398 self.collection_name = collection_name 468 self.collection_name = collection_name
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 try: 506 try:
437 obj_lineage = value.get_lineage() 507 obj_lineage = value.get_lineage()
438 cls_lineage = self.reference_class.get_lineage() 508 cls_lineage = self.reference_class.get_lineage()
439 if obj_lineage.startswith(cls_lineage): 509 if obj_lineage.startswith(cls_lineage):
440 return 510 return
441 raise TypeError, '%s not instance of %s' % (obj_lineage, cls_lineage ) 511 raise TypeError, '%s not instance of %s' % (obj_lineage, cls_lineage )
442 except: 512 except:
443 raise ValueError, '%s is not a Model' % value 513 raise ValueError, '%s is not a Model' % value
444 514
445 def validate(self, value): 515 def validate(self, value):
516 if self.validator:
517 self.validator(value)
446 if self.required and value==None: 518 if self.required and value==None:
447 raise ValueError, '%s is a required property' % self.name 519 raise ValueError, '%s is a required property' % self.name
448 if value == self.default_value(): 520 if value == self.default_value():
449 return 521 return
450 if not isinstance(value, str) and not isinstance(value, unicode): 522 if not isinstance(value, str) and not isinstance(value, unicode):
451 self.check_instance(value) 523 self.check_instance(value)
452 524
453 class _ReverseReferenceProperty(Property): 525 class _ReverseReferenceProperty(Property):
454 data_type = Query 526 data_type = Query
455 type_name = 'query' 527 type_name = 'query'
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 data_type = list 593 data_type = list
522 type_name = 'List' 594 type_name = 'List'
523 595
524 def __init__(self, item_type, verbose_name=None, name=None, default=None, ** kwds): 596 def __init__(self, item_type, verbose_name=None, name=None, default=None, ** kwds):
525 if default is None: 597 if default is None:
526 default = [] 598 default = []
527 self.item_type = item_type 599 self.item_type = item_type
528 Property.__init__(self, verbose_name, name, default=default, required=Tr ue, **kwds) 600 Property.__init__(self, verbose_name, name, default=default, required=Tr ue, **kwds)
529 601
530 def validate(self, value): 602 def validate(self, value):
603 if self.validator:
604 self.validator(value)
531 if value is not None: 605 if value is not None:
532 if not isinstance(value, list): 606 if not isinstance(value, list):
533 value = [value] 607 value = [value]
534 608
535 if self.item_type in (int, long): 609 if self.item_type in (int, long):
536 item_type = (int, long) 610 item_type = (int, long)
537 elif self.item_type in (str, unicode): 611 elif self.item_type in (str, unicode):
538 item_type = (str, unicode) 612 item_type = (str, unicode)
539 else: 613 else:
540 item_type = self.item_type 614 item_type = self.item_type
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 data_type = dict 648 data_type = dict
575 type_name = 'Map' 649 type_name = 'Map'
576 650
577 def __init__(self, item_type=str, verbose_name=None, name=None, default=None , **kwds): 651 def __init__(self, item_type=str, verbose_name=None, name=None, default=None , **kwds):
578 if default is None: 652 if default is None:
579 default = {} 653 default = {}
580 self.item_type = item_type 654 self.item_type = item_type
581 Property.__init__(self, verbose_name, name, default=default, required=Tr ue, **kwds) 655 Property.__init__(self, verbose_name, name, default=default, required=Tr ue, **kwds)
582 656
583 def validate(self, value): 657 def validate(self, value):
658 value = super(MapProperty, self).validate(value)
584 if value is not None: 659 if value is not None:
585 if not isinstance(value, dict): 660 if not isinstance(value, dict):
586 raise ValueError, 'Value must of type dict' 661 raise ValueError, 'Value must of type dict'
587 662
588 if self.item_type in (int, long): 663 if self.item_type in (int, long):
589 item_type = (int, long) 664 item_type = (int, long)
590 elif self.item_type in (str, unicode): 665 elif self.item_type in (str, unicode):
591 item_type = (str, unicode) 666 item_type = (str, unicode)
592 else: 667 else:
593 item_type = self.item_type 668 item_type = self.item_type
594 669
595 for key in value: 670 for key in value:
596 if not isinstance(value[key], item_type): 671 if not isinstance(value[key], item_type):
597 if item_type == (int, long): 672 if item_type == (int, long):
598 raise ValueError, 'Values in the %s Map must all be integers .' % self.name 673 raise ValueError, 'Values in the %s Map must all be integers .' % self.name
599 else: 674 else:
600 raise ValueError('Values in the %s Map must all be %s instan ces' % 675 raise ValueError('Values in the %s Map must all be %s instan ces' %
601 (self.name, self.item_type.__name__)) 676 (self.name, self.item_type.__name__))
602 return value 677 return value
603 678
604 def empty(self, value): 679 def empty(self, value):
605 return value is None 680 return value is None
606 681
607 def default_value(self): 682 def default_value(self):
608 return {} 683 return {}
OLDNEW
« no previous file with comments | « boto/sdb/db/model.py ('k') | boto/sdb/db/sequence.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698