def _find(self, **kv): """ Find keys that meet search critieria """ db = self.db all_keys = [] for field_name in kv.keys(): value = kv[field_name] if value != None: if not isinstance(value, (list, tuple)): wc = 'value=%s' v = (value,) else: wc = 'value in ('+','.join(['%s']*len(value))+')' v = value cmd = 'select distinct row_id from attributes where kind=%s and attribute=%s and '+wc rs = db(cmd, self.kind, field_name.lower(), *v) all_keys.append([rec.ROW_ID for rec in rs]) answer = set(all_keys[0]) for keys in all_keys[1:]: answer = set(keys) & answer if answer: return list(answer) else: return []
def create_storage(db): db(""" create table if not exists entities ( id int not null auto_increment, kind varchar(100), PRIMARY KEY (id) ) """) db(""" create table if not exists attributes ( id int not null auto_increment, kind varchar(100), row_id int not null, attribute varchar(100), datatype varchar(30), value text, PRIMARY KEY (id) ) """)
def delete_storage(db): db('drop table if exists attributes') db('drop table if exists entities')
def put(self, entity): """ stores an entity >>> db = setup_test() >>> class Person(Entity): pass >>> class People(EntityStore): pass >>> people = People(db, Person) >>> sally = Person(name='Sally', age=25) >>> sally <Person {'name': 'Sally', 'age': 25}> >>> id = people.put(Person(name='Sally', age=25)) >>> id 1L >>> sally <Person {'name': 'Sally', 'age': 25}> >>> sally = people.get(id) >>> sally <Person {'name': 'Sally', 'age': 25}> >>> sally.age = 35 >>> people.put(sally) 1L >>> person = people.get(id) >>> person <Person {'name': 'Sally', 'age': 35}> >>> id = people.put({'name':'James', 'age':15}) >>> id 2L >>> people.get(id) <Person {'name': 'James', 'age': 15}> >>> db.close() """ def fixval(d): if type(d) == datetime.datetime: # avoids mysqldb reliance on strftime that lacks support for dates before 1900 return "%02d-%02d-%02d %02d:%02d:%02d" % (d.year,d.month,d.day,d.hour,d.minute,d.second) if type(d) == decimal.Decimal: return str(d) else: return d def get_type_str(v): t = repr(type(v)) if 'type' in t: return t.strip('<type >').strip("'") elif 'class' in t: return t.strip('<class >').strip("'") else: return t db = self.db keys = [k for k in entity.keys() if k <> '_id'] values = [entity[k] for k in keys] datatypes = [get_type_str(v) for v in values] values = [fixval(i) for i in values] # same fix as above valid_types = ['str','unicode','long','int','float','decimal.Decimal','datetime.date','datetime.datetime','bool','NoneType'] for atype in datatypes: if atype not in valid_types: raise TypeException,'unsupported type <type %s>' % atype if '_id' in entity: id = entity['_id'] db('delete from attributes where row_id=%s', id) else: db('insert into entities (kind) values (%s)', self.kind) id = entity['_id'] = db.lastrowid n = len(keys) lkeys = [k.lower() for k in keys] param_list = zip([self.kind]*n, [id]*n, lkeys, datatypes, values) cmd = 'insert into attributes (kind, row_id, attribute, datatype, value) values (%s,%s,%s,%s,%s)' db.cursor().executemany(cmd, param_list) return id