''' Members: class base indexable using a tuple of the DB-API v2.0 module and the single argument to be passed to the connect call the index call will return a class dbdict Example: dbwrap.base()[(pgdb, ":dbname")] clase dbdict(dbmod = None, dsn = None) can initalize w/o having to call the following two routines by hand setmod -> sets the DB-API v2.0 module to use setdsn -> sets the dsn string and connect to the db This is not normally called directly. Use the base class to get an instance. To use, index using the table name. It will return a tbdict instance. Example: dbdict['table'] class tbdict(db, cursor, table) db is the DB-API v2.0 module to use cursor is a cursor to use for all queries table is the name of the table we will work with append(dict) -> adds dict to table getfields() -> returns a list (that can change) containing all the columns of the table keys() -> returns a list of the data from the first column of the table (this may not be primary key of the table) values() -> returns a list of all rows has_key((column, value)) -> check to see if column has a row with value in it __getitem__(key) -> key can be a tuple, a dict, or an object representable as a string. If it is a tuple or a dict, it will return a rwdict using key. If it is a string, then we will return all values from the column that matches the string. __setitem__(key, value) -> calls rwdict's setdict w/ value. class rwdict(db, cursor, table, fields, key) All data is passed down through previous class. key can be a tuple (two or three elemnts) or a dict. If a tuple, it is (column, value [, ordered by]) If a dict: { 'field': column, 'key': value, ['orderby': orderedby,] } keys() -> returns a list of column minus the column the table is key'd on values() -> returns the first value that matches the passed in key getdict() -> returns a dict of the row getall() -> get all that match key ''' import string class rwdict: def __init__(self, db, cur, table, fields, key): self.db = db self.cursor = cur self.table = table self.fields = fields self.obd = '' if type(key) == type(()): self.keyf = key[0] self.key = key[1] if len(key) > 2: self.obd = key[2] elif type(key) == type({}): self.keyf = key['field'] self.key = key['key'] self.obd = key['orderby'] if self.obd: self.ob = ' order by %s' % self.obd else: self.ob = '' def keys(self): if not self.__dict__.has_key('keydict'): self.keydict = map(lambda x: x[0], self.fields) try: self.keydict.remove(self.keyf) except ValueError: pass return self.keydict def values(self): self.cursor.execute('select %s from %s where %s = %s%s' % (string.join(self.keys(), ','), self.table, self.keyf, repr(self.key), self.ob), ()) return self.cursor.fetchone() def getdict(self): a = self.keys() b = self.values() ret = {} for i in xrange(len(a)): ret[a[i]] = b[i] return ret def setfields(self, fields): self.fields = fields def getall(self): #self.cursor.execute('select %s from %s where %s = %s%s', (string.join(self.keys(), ','), self.table, self.keyf, repr(self.key), self.ob)) self.cursor.execute('select * from %s where %s = %s%s', (self.table, self.keyf, repr(self.key), self.ob)) t = self.cursor.fetchall() f = [] for i in self.keys(): f.append(i) return (f, t) def __getitem__(self, key): #print self.keyf #print self.key self.cursor.execute('select %s from %s where %s = %s%s', (key, self.table, self.keyf, repr(self.key), self.ob)) return self.cursor.fetchone()[0] def __setitem__(self, key, value): self.setdict({key: value}) def setdict(self, value): import string vl = string.join(map(lambda x, y: x + '=' + repr(y), value.keys(), value.values()), ',') self.cursor.execute('update %s set %s where %s = %s', (self.table, vl, self.keyf, repr(self.key))) if not self.cursor.rowcount: self.cursor.execute('insert into %s (%s, %s) values (%s, %s)', (self.table, self.keyf, string.join(value.keys(), ','), '\'' + self.key + '\'', string.join(map(lambda x: '\'' + x + '\'', value.values()), ','))) self.db.commit() class tbdict: def getall(self): self.cursor.execute('select * from %s', (self.table,)) return self.cursor.fetchall() def append(self, value): import string import sys self.cursor.execute('insert into %s (%s) values (%s)', (self.table, string.join(value.keys(), ','), string.join(map(lambda x: repr(x), value.values()), ','))) self.db.commit() def getfields(self): # grab all the current column names self.cursor.execute('select * from %s limit 1', self.table) self.fields[0:len(self.fields)] = self.cursor.description return self.fields def keys(self): # XXX - should I return all possible key combinations? self.cursor.execute('select %s from %%s' % self.fields[0][0], self.table) ret = [] for i in self.cursor.fetchall(): ret.append((self.fields[0][0], i[0])) #ret = map(lambda x, y: (self.fields[0][0], x[0]), b, a) return ret def values(self): self.cursor.execute('select * from %s', self.table) return self.cursor.fetchall() def has_key(self, key): self.cursor.execute('select %s from %s where %s = \'%%s\'' % (self.fields[0][0], self.table, key[0]), key[1]) t = self.cursor.fetchone() return [1, 0][t == None] def __init__(self, db, cursor, table): self.cursor = cursor self.table = table self.db = db self.fields = [] self.getfields() self.keydict = {} def __getitem__(self, key): #print 'creating rowitem' #print 'table: %s\nfields: %s\nkey: %s\n' % (self.table, self.fields, key) if type(key) == type(()) or type(key) == type({}): return rwdict(self.db, self.db.cursor(), self.table, self.fields, key) else: cur = self.db.cursor() cur.execute('select %s from %s', (key, self.table)) return cur.fetchall() raise KeyError, 'invalid key %s' % key def __setitem__(self, key, value): import types import string self[key].setdict(value) return if len(value) != len(self.fields): raise TypeError, 'num of data not equal to columns' s = string.join(map(lambda x: x[0], self.fields), ',') t = string.join(map(lambda x: "'" + x + "'", value), ',') self.cursor.execute('insert into %s (%s) values (%%s)' % (self.table, s), t) self.db.commit() class dbdict: def setdbmod(self, mod): if self.__dict__.has_key('dbmod'): raise AttributeError, 'Already set' self.dbmod = mod def setdsn(self, dsn): if self.__dict__.has_key('dsn'): raise AttributeError, 'Already set' self.dsn = dsn self.con = self.dbmod.connect(self.dsn) def __init__(self, dbmod = None, dsn = None): self.tables = {} if not dbmod: return self.setdbmod(dbmod) if not dsn: return self.setdsn(dsn) def __getitem__(self, key): if not self.tables.has_key(key): self.tables[key] = tbdict(self.con, self.con.cursor(), key) return self.tables[key] class base: def __getitem__(self, key): return dbdict(key[0], key[1])