# portage_db_mysql.db by oneofone{-a-t-}limitlessfx.com import MySQLdb,cPickle import portage_db_template class database(portage_db_template.database): #ought to do ref counting on the number of open connections. course that's worthless till portage calls database.close(). connections = {} cursor = None path_map = {} categories = {} defaultOptions = {'host':'localhost', 'port': 3306, 'user': 'portage', 'password': "", 'db': 'portage'} options = {} lastkey = lastval = None def __init__(self,path,category,dbkeys,uid,gid,config_path="/etc/portage/module_configs/"): try: portage_db_template.database.__init__(self, path,category,dbkeys,uid,gid,config_path) except: self.path = path self.category = category self.dbkeys = dbkeys self.uid = uid self.gid = gid self.module_init() def module_init(self): options = database.defaultOptions.copy(); options.update(self.options) self.options = options; del options from re import sub path = sub('/{2,}', '/', self.path) self.constr = self.options['host'] + ':' + str(self.options['port']) + '/' + self.options['db'] if not database.connections.has_key(self.constr): try: database.connections[self.constr] = MySQLdb.connect(host=self.options['host'], port=self.options['port'], user=self.options['user'], passwd=self.options['password'], db=self.options['db']) database.connections[self.constr+":cursor"] = database.connections[self.constr].cursor() except Exception, e: raise Exception, "Error connecting to Database using self.options=('%s'): exception=(%s)" % (str(self.options), str(e)) self.con = database.connections[self.constr] if not database.connections.has_key(self.constr+":cursor"): database.connections[self.constr+":cursor"] = self.con.cursor() self.db = database.connections[self.constr+":cursor"] try: if len(database.categories.keys()) == 0: self.db.execute('select * from `category_table`') for y, x in self.db.fetchall(): database.categories[y] = x except: raise Exception, "Database Error: failed pulling tables from %s" % self.options['db'] if not database.categories.has_key(self.category) : #create the category table try: self.db.execute('INSERT INTO `category_table` (`name`) VALUES("%s")' % self.category) database.categories.clear() self.db.execute('select * from `category_table`') for y, x in self.db.fetchall(): database.categories[y] = x except Exception, e: raise Exception, "Database error: failed creation table for path('%s'), category('%s'), Exception=(%s)" % (path, category, str(e)) self.cat_id = database.categories[self.category] if not database.path_map.has_key(self.path): try: if len( database.path_map.keys()) == 0: if self.db.execute('SELECT name, p_id FROM `path_table` ') > 0: for x,y in self.db.fetchall(): database.path_map[x] = y except Exception, e: raise Exception, "database error: %s" % str(e) if not database.path_map.has_key(path): try: self.db.execute('INSERT INTO `path_table`(`name`) VALUES("%s")' % MySQLdb.escape_string(path)) #flush the table, and load it anew database.path_map.clear() self.db.execute('SELECT * FROM `path_table`') for path,id in self.db.fetchall(): database.path_map[path] = id except Exception, e: raise Exception, "Database error, failed loading path map: exc=%s" % str(e) self.p_id = database.path_map[path] def has_key(self,key): self.check_key(key) try : return self.db.execute("SELECT data FROM `package_name` WHERE `name` = '%s' AND `cat_id` = '%d' AND `path_id` = '%d'" % (key, self.cat_id, self.p_id )) > 0 except Exception, e: print "exception in has_key for Key (%s), Error (%s) " % (key, str(e)) return False def keys(self): ks = {} try: self.db.execute('SELECT name, data from `package_name` WHERE `cat_id` = "%d" AND `path_id` = "%d"' % (self.cat_id, self.p_id )) for x,y in self.db.fetchall(): ks[x] = cPickle.loads(y) return ks except Exception, e: raise KeyError, "Keys are dead :( (%s)" % str(e) def get_values(self,key): self.check_key(key) if self.lastkey == key: return self.lastval if self.db.execute("SELECT data FROM `package_name` WHERE `name` = '%s' AND `cat_id` = '%d' AND `path_id` = '%d'" % (key, self.cat_id, self.p_id )) > 0: try: one = self.db.fetchone() if len(one) > 0 and one[0] != None: self.lastkey = key; self.lastval = cPickle.loads(one[0]) return self.lastval return None except Exception, e: raise ValueError, "Value error (%s)" % str(e) return None def set_values(self,key,val): self.check_key(key) try: if self.lastkey == key: self.lastkey = self.lastval = None self.db.execute("""REPLACE INTO `package_name` (`name`,`cat_id`, `data`, `path_id`) VALUES ("%s","%d", "%s","%d") """ % (key, self.cat_id, MySQLdb.escape_string(cPickle.dumps(val)),self.p_id ) ) except Exception, e: raise Exception, "Error inserting/updating the database (%s)." % str(e) def del_key(self,key): try: if self.lastkey == key: self.lastkey = self.lastval = None return (self.db.execute('DELETE FROM `package_name` WHERE `cat_id` = "%d" AND `name`= "%s" AND `path_id` = "%d"' % (self.cat_id, key, self.p_id)) > 0) except Exception, e: raise Exception, "Error deleting key (%s)" % str(e) def sync(self): self.con.commit() def close(self): self.db.close()