def find(cls, **params): if params.has_key('manager'): manager = params['manager'] del params['manager'] else: manager = cls._manager keys = params.keys() if len(keys) > 4: raise SDBPersistenceError('Too many fields, max is 4') parts = ["['__type__'='%s'] union ['__lineage__'starts-with'%s']" % (cls.__name__, cls.get_lineage())] properties = cls.properties() for key in keys: found = False for property in properties: if property.name == key: found = True if isinstance(property, ScalarProperty): checker = property.checker parts.append("['%s' = '%s']" % (key, checker.to_string(params[key]))) else: raise SDBPersistenceError('%s is not a searchable field' % key) if not found: raise SDBPersistenceError('%s is not a valid field' % key) query = ' intersection '.join(parts) if manager.domain: rs = manager.domain.query(query) else: rs = [] return object_lister(None, rs, manager)
def save_object(self, obj): if not obj.id: obj.id = str(uuid.uuid4()) attrs = {'__type__' : obj.__class__.__name__, '__module__' : obj.__class__.__module__, '__lineage__' : obj.get_lineage()} del_attrs = [] for property in obj.properties(hidden=False): value = property.get_value_for_datastore(obj) if value is not None: value = self.encode_value(property, value) if value == []: value = None if value == None: del_attrs.append(property.name) continue attrs[property.name] = value if property.unique: try: args = {property.name: value} obj2 = obj.find(**args).next() if obj2.id != obj.id: raise SDBPersistenceError("Error: %s must be unique!" % property.name) except(StopIteration): pass self.domain.put_attributes(obj.id, attrs, replace=True) if len(del_attrs) > 0: self.domain.delete_attributes(obj.id, del_attrs) return obj
def get_object(self, cls, id): qs = """SELECT * FROM "%s" WHERE id='%s';""" % (self.db_table, id) self.cursor.execute(qs, None) if self.cursor.rowcount == 1: row = self.cursor.fetchone() return self._object_from_row(row, self.cursor.description) else: raise SDBPersistenceError('%s object with id=%s does not exist' % (cls.__name__, id))
def set_property(self, prop, obj, name, value): value = prop.get_value_for_datastore(obj) value = self.encode_value(prop, value) if prop.unique: try: args = {prop.name: value} obj2 = obj.find(**args).next() if obj2.id != obj.id: raise SDBPersistenceError("Error: %s must be unique!" % prop.name) except(StopIteration): pass self.domain.put_attributes(obj.id, {name : value}, replace=True)
def query(self, cls, filters, limit=None, order_by=None): import types if len(filters) > 4: raise SDBPersistenceError('Too many filters, max is 4') s = "['__type__'='%s'" % cls.__name__ for subclass in cls.__sub_classes__: s += " OR '__type__'='%s'" % subclass.__name__ s += "]" parts = [s] properties = cls.properties(hidden=False) for filter, value in filters: name, op = filter.strip().split() found = False for property in properties: if property.name == name: found = True if types.TypeType(value) == types.ListType: filter_parts = [] for val in value: val = self.encode_value(property, val) filter_parts.append("'%s' %s '%s'" % (name, op, val)) parts.append("[%s]" % " OR ".join(filter_parts)) else: value = self.encode_value(property, value) parts.append("['%s' %s '%s']" % (name, op, value)) if not found: raise SDBPersistenceError('%s is not a valid field' % name) if order_by: if order_by.startswith("-"): key = order_by[1:] type = "desc" else: key = order_by type = "asc" parts.append("['%s' starts-with ''] sort '%s' %s" % (key, key, type)) query = ' intersection '.join(parts) rs = self.domain.query(query, max_items=limit) return self._object_lister(cls, rs)
def get(cls, id=None, **params): if params.has_key('manager'): manager = params['manager'] else: manager = cls._manager if manager.domain and id: a = cls._manager.domain.get_attributes(id, '__type__') if a.has_key('__type__'): return cls(id, manager) else: raise SDBPersistenceError('%s object with id=%s does not exist' % (cls.__name__, id)) else: rs = cls.find(**params) try: obj = rs.next() except StopIteration: raise SDBPersistenceError('%s object matching query does not exist' % cls.__name__) try: rs.next() except StopIteration: return obj raise SDBPersistenceError('Query matched more than 1 item')
def __init__(self, id=None, manager=None): if manager: self._manager = manager self.id = id if self.id: self._auto_update = True if self._manager.domain: attrs = self._manager.domain.get_attributes(self.id, '__type__') if len(attrs.keys()) == 0: raise SDBPersistenceError('Object %s: not found' % self.id) else: self.id = str(uuid.uuid4()) self._auto_update = False
def get_object(self, cls, id, a=None): if not a: a = self.domain.get_attributes(id) if not a.has_key('__type__'): raise SDBPersistenceError('object %s does not exist' % id) if not cls: cls = find_class(a['__module__'], a['__type__']) obj = cls(id) obj._auto_update = False for prop in obj.properties(hidden=False): if prop.data_type != Key: if a.has_key(prop.name): value = self.decode_value(prop, a[prop.name]) value = prop.make_value_from_datastore(value) setattr(obj, prop.name, value) obj._auto_update = True return obj
def save_object(self, obj, expected_value=None): if not obj.id: obj.id = str(uuid.uuid4()) attrs = { '__type__': obj.__class__.__name__, '__module__': obj.__class__.__module__, '__lineage__': obj.get_lineage() } del_attrs = [] for property in obj.properties(hidden=False): if property.is_calculated: del_attrs.append(property.name) continue value = property.get_value_for_datastore(obj) if value is not None: value = self.encode_value(property, value) if value == []: value = None if value == None: del_attrs.append(property.name) continue attrs[property.name] = value if property.unique: try: args = {property.name: value} obj2 = obj.find(**args).next() if obj2.id != obj.id: raise SDBPersistenceError("Error: %s must be unique!" % property.name) except (StopIteration): pass # Convert the Expected value to SDB format if expected_value: prop = obj.find_property(expected_value[0]) v = expected_value[1] if v is not None and not type(v) == bool: v = self.encode_value(prop, v) expected_value[1] = v self.domain.put_attributes(obj.id, attrs, replace=True, expected_value=expected_value) if len(del_attrs) > 0: self.domain.delete_attributes(obj.id, del_attrs) return obj
def __set__(self, obj, value): if not isinstance(value, list): raise SDBPersistenceError('Value must be a list') setattr(obj, self.slot_name, MultiValue(self, obj, value)) str_list = self.to_string(obj) domain = obj._manager.domain if obj._auto_update: if len(str_list) == 1: domain.put_attributes(obj.id, {self.name: str_list[0]}, replace=True) else: try: self.__delete__(obj) except: pass domain.put_attributes(obj.id, {self.name: str_list}, replace=True) setattr(obj, self.slot_name, MultiValue(self, obj, value))
def encode_blob(self, value): if not value: return None if not value.id: bucket = self.manager.get_blob_bucket() key = bucket.new_key(str(uuid.uuid4())) value.id = "s3://%s/%s" % (key.bucket.name, key.name) else: match = re.match("^s3:\/\/([^\/]*)\/(.*)$", value.id) if match: s3 = self.manager.get_s3_connection() bucket = s3.get_bucket(match.group(1), validate=False) key = bucket.get_key(match.group(2)) else: raise SDBPersistenceError("Invalid Blob ID: %s" % value.id) key.set_contents_from_string(value.value) return value.id
def query(self, cls, filters, limit=None, order_by=None): parts = [] qs = 'SELECT * FROM "%s"' % self.db_table if filters: qs += ' WHERE ' properties = cls.properties(hidden=False) for filter, value in filters: name, op = filter.strip().split() found = False for property in properties: if property.name == name: found = True value = self.encode_value(property, value) parts.append(""""%s"%s'%s'""" % (name, op, value)) if not found: raise SDBPersistenceError('%s is not a valid field' % name) qs += ','.join(parts) qs += ';' print qs cursor = self.connection.cursor() cursor.execute(qs) return self._object_lister(cursor)
def lookup(self, cls, name, value): values = [] qs = 'SELECT * FROM "%s" WHERE ' % self.db_table found = False for property in cls.properties(hidden=False): if property.name == name: found = True value = self.encode_value(property, value) values.append(value) qs += "%s=" % name qs += "%s" if not found: raise SDBPersistenceError('%s is not a valid field' % name) qs += ';' print qs self.cursor.execute(qs, values) if self.cursor.rowcount == 1: row = self.cursor.fetchone() return self._object_from_row(row, self.cursor.description) elif self.cursor.rowcount == 0: raise KeyError, 'Object not found' else: raise LookupError, 'Multiple Objects Found'
def __init__(self, **params): self.default = None self.ref_class = params.get('ref_class', None) if self.ref_class == None: raise SDBPersistenceError('ref_class parameter is required')