Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/boto/sdb/db/model.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
comparison
equal
deleted
inserted
replaced
| 4:79f47841a781 | 5:9b1c78e6ba9c |
|---|---|
| 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.sdb.db.property import Property | |
| 23 from boto.sdb.db.key import Key | |
| 24 from boto.sdb.db.query import Query | |
| 25 import boto | |
| 26 from boto.compat import filter | |
| 27 | |
| 28 class ModelMeta(type): | |
| 29 "Metaclass for all Models" | |
| 30 | |
| 31 def __init__(cls, name, bases, dict): | |
| 32 super(ModelMeta, cls).__init__(name, bases, dict) | |
| 33 # Make sure this is a subclass of Model - mainly copied from django ModelBase (thanks!) | |
| 34 cls.__sub_classes__ = [] | |
| 35 | |
| 36 # Do a delayed import to prevent possible circular import errors. | |
| 37 from boto.sdb.db.manager import get_manager | |
| 38 | |
| 39 try: | |
| 40 if filter(lambda b: issubclass(b, Model), bases): | |
| 41 for base in bases: | |
| 42 base.__sub_classes__.append(cls) | |
| 43 cls._manager = get_manager(cls) | |
| 44 # look for all of the Properties and set their names | |
| 45 for key in dict.keys(): | |
| 46 if isinstance(dict[key], Property): | |
| 47 property = dict[key] | |
| 48 property.__property_config__(cls, key) | |
| 49 prop_names = [] | |
| 50 props = cls.properties() | |
| 51 for prop in props: | |
| 52 if not prop.__class__.__name__.startswith('_'): | |
| 53 prop_names.append(prop.name) | |
| 54 setattr(cls, '_prop_names', prop_names) | |
| 55 except NameError: | |
| 56 # 'Model' isn't defined yet, meaning we're looking at our own | |
| 57 # Model class, defined below. | |
| 58 pass | |
| 59 | |
| 60 class Model(object): | |
| 61 __metaclass__ = ModelMeta | |
| 62 __consistent__ = False # Consistent is set off by default | |
| 63 id = None | |
| 64 | |
| 65 @classmethod | |
| 66 def get_lineage(cls): | |
| 67 l = [c.__name__ for c in cls.mro()] | |
| 68 l.reverse() | |
| 69 return '.'.join(l) | |
| 70 | |
| 71 @classmethod | |
| 72 def kind(cls): | |
| 73 return cls.__name__ | |
| 74 | |
| 75 @classmethod | |
| 76 def _get_by_id(cls, id, manager=None): | |
| 77 if not manager: | |
| 78 manager = cls._manager | |
| 79 return manager.get_object(cls, id) | |
| 80 | |
| 81 @classmethod | |
| 82 def get_by_id(cls, ids=None, parent=None): | |
| 83 if isinstance(ids, list): | |
| 84 objs = [cls._get_by_id(id) for id in ids] | |
| 85 return objs | |
| 86 else: | |
| 87 return cls._get_by_id(ids) | |
| 88 | |
| 89 get_by_ids = get_by_id | |
| 90 | |
| 91 @classmethod | |
| 92 def get_by_key_name(cls, key_names, parent=None): | |
| 93 raise NotImplementedError("Key Names are not currently supported") | |
| 94 | |
| 95 @classmethod | |
| 96 def find(cls, limit=None, next_token=None, **params): | |
| 97 q = Query(cls, limit=limit, next_token=next_token) | |
| 98 for key, value in params.items(): | |
| 99 q.filter('%s =' % key, value) | |
| 100 return q | |
| 101 | |
| 102 @classmethod | |
| 103 def all(cls, limit=None, next_token=None): | |
| 104 return cls.find(limit=limit, next_token=next_token) | |
| 105 | |
| 106 @classmethod | |
| 107 def get_or_insert(key_name, **kw): | |
| 108 raise NotImplementedError("get_or_insert not currently supported") | |
| 109 | |
| 110 @classmethod | |
| 111 def properties(cls, hidden=True): | |
| 112 properties = [] | |
| 113 while cls: | |
| 114 for key in cls.__dict__.keys(): | |
| 115 prop = cls.__dict__[key] | |
| 116 if isinstance(prop, Property): | |
| 117 if hidden or not prop.__class__.__name__.startswith('_'): | |
| 118 properties.append(prop) | |
| 119 if len(cls.__bases__) > 0: | |
| 120 cls = cls.__bases__[0] | |
| 121 else: | |
| 122 cls = None | |
| 123 return properties | |
| 124 | |
| 125 @classmethod | |
| 126 def find_property(cls, prop_name): | |
| 127 property = None | |
| 128 while cls: | |
| 129 for key in cls.__dict__.keys(): | |
| 130 prop = cls.__dict__[key] | |
| 131 if isinstance(prop, Property): | |
| 132 if not prop.__class__.__name__.startswith('_') and prop_name == prop.name: | |
| 133 property = prop | |
| 134 if len(cls.__bases__) > 0: | |
| 135 cls = cls.__bases__[0] | |
| 136 else: | |
| 137 cls = None | |
| 138 return property | |
| 139 | |
| 140 @classmethod | |
| 141 def get_xmlmanager(cls): | |
| 142 if not hasattr(cls, '_xmlmanager'): | |
| 143 from boto.sdb.db.manager.xmlmanager import XMLManager | |
| 144 cls._xmlmanager = XMLManager(cls, None, None, None, | |
| 145 None, None, None, None, False) | |
| 146 return cls._xmlmanager | |
| 147 | |
| 148 @classmethod | |
| 149 def from_xml(cls, fp): | |
| 150 xmlmanager = cls.get_xmlmanager() | |
| 151 return xmlmanager.unmarshal_object(fp) | |
| 152 | |
| 153 def __init__(self, id=None, **kw): | |
| 154 self._loaded = False | |
| 155 # first try to initialize all properties to their default values | |
| 156 for prop in self.properties(hidden=False): | |
| 157 try: | |
| 158 setattr(self, prop.name, prop.default_value()) | |
| 159 except ValueError: | |
| 160 pass | |
| 161 if 'manager' in kw: | |
| 162 self._manager = kw['manager'] | |
| 163 self.id = id | |
| 164 for key in kw: | |
| 165 if key != 'manager': | |
| 166 # We don't want any errors populating up when loading an object, | |
| 167 # so if it fails we just revert to it's default value | |
| 168 try: | |
| 169 setattr(self, key, kw[key]) | |
| 170 except Exception as e: | |
| 171 boto.log.exception(e) | |
| 172 | |
| 173 def __repr__(self): | |
| 174 return '%s<%s>' % (self.__class__.__name__, self.id) | |
| 175 | |
| 176 def __str__(self): | |
| 177 return str(self.id) | |
| 178 | |
| 179 def __eq__(self, other): | |
| 180 return other and isinstance(other, Model) and self.id == other.id | |
| 181 | |
| 182 def _get_raw_item(self): | |
| 183 return self._manager.get_raw_item(self) | |
| 184 | |
| 185 def load(self): | |
| 186 if self.id and not self._loaded: | |
| 187 self._manager.load_object(self) | |
| 188 | |
| 189 def reload(self): | |
| 190 if self.id: | |
| 191 self._loaded = False | |
| 192 self._manager.load_object(self) | |
| 193 | |
| 194 def put(self, expected_value=None): | |
| 195 """ | |
| 196 Save this object as it is, with an optional expected value | |
| 197 | |
| 198 :param expected_value: Optional tuple of Attribute, and Value that | |
| 199 must be the same in order to save this object. If this | |
| 200 condition is not met, an SDBResponseError will be raised with a | |
| 201 Confict status code. | |
| 202 :type expected_value: tuple or list | |
| 203 :return: This object | |
| 204 :rtype: :class:`boto.sdb.db.model.Model` | |
| 205 """ | |
| 206 self._manager.save_object(self, expected_value) | |
| 207 return self | |
| 208 | |
| 209 save = put | |
| 210 | |
| 211 def put_attributes(self, attrs): | |
| 212 """ | |
| 213 Save just these few attributes, not the whole object | |
| 214 | |
| 215 :param attrs: Attributes to save, key->value dict | |
| 216 :type attrs: dict | |
| 217 :return: self | |
| 218 :rtype: :class:`boto.sdb.db.model.Model` | |
| 219 """ | |
| 220 assert(isinstance(attrs, dict)), "Argument must be a dict of key->values to save" | |
| 221 for prop_name in attrs: | |
| 222 value = attrs[prop_name] | |
| 223 prop = self.find_property(prop_name) | |
| 224 assert(prop), "Property not found: %s" % prop_name | |
| 225 self._manager.set_property(prop, self, prop_name, value) | |
| 226 self.reload() | |
| 227 return self | |
| 228 | |
| 229 def delete_attributes(self, attrs): | |
| 230 """ | |
| 231 Delete just these attributes, not the whole object. | |
| 232 | |
| 233 :param attrs: Attributes to save, as a list of string names | |
| 234 :type attrs: list | |
| 235 :return: self | |
| 236 :rtype: :class:`boto.sdb.db.model.Model` | |
| 237 """ | |
| 238 assert(isinstance(attrs, list)), "Argument must be a list of names of keys to delete." | |
| 239 self._manager.domain.delete_attributes(self.id, attrs) | |
| 240 self.reload() | |
| 241 return self | |
| 242 | |
| 243 save_attributes = put_attributes | |
| 244 | |
| 245 def delete(self): | |
| 246 self._manager.delete_object(self) | |
| 247 | |
| 248 def key(self): | |
| 249 return Key(obj=self) | |
| 250 | |
| 251 def set_manager(self, manager): | |
| 252 self._manager = manager | |
| 253 | |
| 254 def to_dict(self): | |
| 255 props = {} | |
| 256 for prop in self.properties(hidden=False): | |
| 257 props[prop.name] = getattr(self, prop.name) | |
| 258 obj = {'properties': props, | |
| 259 'id': self.id} | |
| 260 return {self.__class__.__name__: obj} | |
| 261 | |
| 262 def to_xml(self, doc=None): | |
| 263 xmlmanager = self.get_xmlmanager() | |
| 264 doc = xmlmanager.marshal_object(self, doc) | |
| 265 return doc | |
| 266 | |
| 267 @classmethod | |
| 268 def find_subclass(cls, name): | |
| 269 """Find a subclass with a given name""" | |
| 270 if name == cls.__name__: | |
| 271 return cls | |
| 272 for sc in cls.__sub_classes__: | |
| 273 r = sc.find_subclass(name) | |
| 274 if r is not None: | |
| 275 return r | |
| 276 | |
| 277 class Expando(Model): | |
| 278 | |
| 279 def __setattr__(self, name, value): | |
| 280 if name in self._prop_names: | |
| 281 object.__setattr__(self, name, value) | |
| 282 elif name.startswith('_'): | |
| 283 object.__setattr__(self, name, value) | |
| 284 elif name == 'id': | |
| 285 object.__setattr__(self, name, value) | |
| 286 else: | |
| 287 self._manager.set_key_value(self, name, value) | |
| 288 object.__setattr__(self, name, value) | |
| 289 | |
| 290 def __getattr__(self, name): | |
| 291 if not name.startswith('_'): | |
| 292 value = self._manager.get_key_value(self, name) | |
| 293 if value: | |
| 294 object.__setattr__(self, name, value) | |
| 295 return value | |
| 296 raise AttributeError |
