aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2007-10-13 00:51:57 +0000
committerRobin H. Johnson <robbat2@gentoo.org>2007-10-13 00:51:57 +0000
commitc8dd33a8630241a2c8648cd97af4b2fd253e5695 (patch)
tree4608687690302b3913963f18aa3cb2cfb17fec61
parentEnable tracebacks and ignore some signals. (diff)
downloadpackages-3-c8dd33a8630241a2c8648cd97af4b2fd253e5695.tar.gz
packages-3-c8dd33a8630241a2c8648cd97af4b2fd253e5695.tar.bz2
packages-3-c8dd33a8630241a2c8648cd97af4b2fd253e5695.zip
Fix code to support a proper external config and have proper MySQL support.
-rw-r--r--dbgenerator/core.py19
-rw-r--r--dbgenerator/database.py112
-rw-r--r--web/controller.py18
-rw-r--r--web/model.py80
4 files changed, 129 insertions, 100 deletions
diff --git a/dbgenerator/core.py b/dbgenerator/core.py
index 7fb8fb4..ffd47c8 100644
--- a/dbgenerator/core.py
+++ b/dbgenerator/core.py
@@ -14,14 +14,17 @@ def main():
backend.set_domain_by_name("livefs domain")
backend.set_work_repo_by_id("gentoo")
- # where we push it to
- #from database import SQLitePackageDB
- #database = SQLitePackageDB("./pgo.db")
-
- #from database import MySQLPackageDB
- #database = MySQLPackageDB("localhost","user","pass","db")
- print "choose database in core.py first"
- sys.exit(1)
+ from etc.database_config import DatabaseConfig
+ database = None
+ if DatabaseConfig.mode == 'sqlite':
+ from database import SQLitePackageDB
+ database = SQLitePackageDB(DatabaseConfig.settings['sqlite'])
+ if DatabaseConfig.mode == 'mysql':
+ from database import MySQLPackageDB
+ database = MySQLPackageDB(DatabaseConfig.settings['mysql_rw'])
+ if database is None:
+ print "choose database in core.py first"
+ sys.exit(1)
#iter over all packages
for package in backend.all_packages_list:
diff --git a/dbgenerator/database.py b/dbgenerator/database.py
index 5ee2e5b..ad6b275 100644
--- a/dbgenerator/database.py
+++ b/dbgenerator/database.py
@@ -15,7 +15,7 @@ class SQLPackageDatabase(object):
# This should match /usr/portage/profiles/arch.list
arches = frozenset(['alpha', 'amd64', 'arm', 'hppa', 'ia64', 'm68k', 'mips', 'ppc', 'ppc64', 's390', 'sh', 'sparc', 'sparc-fbsd', 'x86', 'x86-fbsd'])
# If you change the database structure below, you should increment this number
- schema_version = 57
+ schema_version = 59
# These are used to cache the various relations
# and avoid more SELECT queries just to find the relations
@@ -29,59 +29,59 @@ class SQLPackageDatabase(object):
def __init__(self):
raise NotImplementedError("don't use base class")
- def create_structure(self):
- """create database structure"""
+ tables = {}
- self.cursor.execute("""CREATE TABLE categories (
- c INTEGER PRIMARY KEY AUTOINCREMENT,
+ tables['categories'] = """CREATE TABLE categories (
+ c INTEGER PRIMARY KEY __AI__,
category VARCHAR(64) UNIQUE
- )""")
-
- self.cursor.execute("""CREATE TABLE packages (
- cp INTEGER PRIMARY KEY AUTOINCREMENT,
+ )"""
+ tables['packages'] = """CREATE TABLE packages (
+ cp INTEGER PRIMARY KEY __AI__,
c INTEGER,
pn VARCHAR(64),
UNIQUE (c, pn)
- )""")
-
- self.cursor.execute("""CREATE TABLE metadata (
+ )"""
+ # All of these get longer than 256 chars sometimes
+ tables['metadata'] = """CREATE TABLE metadata (
cp INTEGER,
- license VARCHAR(255),
- homepage VARCHAR(255),
+ license TEXT,
+ homepage TEXT,
description TEXT,
changelog TEXT,
PRIMARY KEY (cp)
- )""")
-
- self.cursor.execute("""CREATE TABLE versions (
- cpv INTEGER PRIMARY KEY AUTOINCREMENT,
+ )"""
+ tables['versions'] = """CREATE TABLE versions (
+ cpv INTEGER PRIMARY KEY __AI__,
cp INTEGER,
pv VARCHAR(32),
mtime INT,
UNIQUE (cp, pv)
- )""")
-
- self.cursor.execute("""CREATE TABLE keywords (
+ )"""
+ tables['keywords'] = """CREATE TABLE keywords (
cpv INTEGER,
a INTEGER,
mode CHAR(2),
PRIMARY KEY (cpv, a)
- )""")
-
- self.cursor.execute("""CREATE TABLE arches (
- a INTEGER PRIMARY KEY AUTOINCREMENT,
+ )"""
+ tables['arches'] = """CREATE TABLE arches (
+ a INTEGER PRIMARY KEY __AI__,
arch VARCHAR(16),
UNIQUE(arch)
- )""")
-
- self.cursor.execute("""CREATE TABLE schema_info (
+ )"""
+ tables['schema_info'] = """CREATE TABLE schema_info (
version INTEGER PRIMARY KEY
- )""")
+ )"""
+
+ def create_structure(self):
+ """create database structure"""
+
+ for k in self.tables.keys():
+ self.cursor.execute(self.tables[k].replace('__AI__',self.syntax_autoincrement))
for arch in self.arches:
self.find_or_create_arch(arch)
- self.cursor.execute('INSERT INTO schema_info (version) VALUES (?)'.replace('?',self.placeholder), (self.schema_version,))
+ self.cursor.execute('INSERT INTO schema_info (version) VALUES (?)'.replace('?',self.syntax_placeholder), (self.schema_version,))
self.db.commit()
def drop_structure(self):
@@ -94,8 +94,8 @@ class SQLPackageDatabase(object):
def add_keywords(self, category, pn, pv, keyword_dict):
cpv = self.find_cpv(category, pn, pv)
#print "c=%s pn=%s pv=%s cpv=%s kw=%s" % (category, pn, pv, repr(cpv), keyword_dict)
- self.cursor.execute('DELETE FROM keywords WHERE cpv = ?'.replace('?',self.placeholder), (cpv,))
- sql = 'INSERT INTO keywords (cpv, a, mode) VALUES (?, ?, ?)'.replace('?',self.placeholder)
+ self.cursor.execute('DELETE FROM keywords WHERE cpv = ?'.replace('?',self.syntax_placeholder), (cpv,))
+ sql = 'INSERT INTO keywords (cpv, a, mode) VALUES (?, ?, ?)'.replace('?',self.syntax_placeholder)
for arch in keyword_dict.keys():
a = self.find_or_create_arch(arch)
self.cursor.execute(sql, (cpv, a, keyword_dict[arch]))
@@ -103,22 +103,22 @@ class SQLPackageDatabase(object):
def add_metadata(self, category, pn, description, homepage, license, changelog):
cp = self.find_or_create_cp(category, pn)
- self.cursor.execute('DELETE FROM metadata WHERE cp = ?'.replace('?',self.placeholder), (cp,))
- self.cursor.execute('INSERT INTO metadata (cp, homepage, description, license, changelog) VALUES (?, ?, ?, ?, ?)'.replace('?',self.placeholder),
+ self.cursor.execute('DELETE FROM metadata WHERE cp = ?'.replace('?',self.syntax_placeholder), (cp,))
+ self.cursor.execute('INSERT INTO metadata (cp, homepage, description, license, changelog) VALUES (?, ?, ?, ?, ?)'.replace('?',self.syntax_placeholder),
(cp, homepage, description, str(license), changelog))
self.commit()
def add_version(self, category, pn, pv, mtime):
cp = self.find_or_create_cp(category, pn)
- self.cursor.execute('DELETE FROM versions WHERE cp = ? AND pv = ?'.replace('?',self.placeholder), (cp, pv))
- self.cursor.execute('INSERT INTO versions (cp, pv, mtime) VALUES (?, ?, ?)'.replace('?',self.placeholder), (cp, pv, mtime))
+ self.cursor.execute('DELETE FROM versions WHERE cp = ? AND pv = ?'.replace('?',self.syntax_placeholder), (cp, pv))
+ self.cursor.execute('INSERT INTO versions (cp, pv, mtime) VALUES (?, ?, ?)'.replace('?',self.syntax_placeholder), (cp, pv, mtime))
self.commit()
def commit(self):
return
def find_cpv_mtime(self, category, pn, pv):
- self.cursor.execute('SELECT mtime FROM versions JOIN packages USING (cp) JOIN categories USING (c) WHERE category = ? AND pn = ? AND pv = ?'.replace('?',self.placeholder), (category, pn, pv))
+ self.cursor.execute('SELECT mtime FROM versions JOIN packages USING (cp) JOIN categories USING (c) WHERE category = ? AND pn = ? AND pv = ?'.replace('?',self.syntax_placeholder), (category, pn, pv))
entries = self.cursor.fetchall()
try:
return entries[0][0]
@@ -129,7 +129,7 @@ class SQLPackageDatabase(object):
cachekey = category+pn+pv
if cachekey in self.cache_cpv:
return self.cache_cpv[cachekey]
- self.cursor.execute('SELECT cpv FROM versions JOIN packages USING (cp) JOIN categories USING (c) WHERE categories.category = ? AND packages.pn = ? AND versions.pv = ?'.replace('?',self.placeholder), (category, pn, pv))
+ self.cursor.execute('SELECT cpv FROM versions JOIN packages USING (cp) JOIN categories USING (c) WHERE categories.category = ? AND packages.pn = ? AND versions.pv = ?'.replace('?',self.syntax_placeholder), (category, pn, pv))
entries = self.cursor.fetchall()
try:
cpv = entries[0][0]
@@ -142,14 +142,14 @@ class SQLPackageDatabase(object):
cachekey = category
if cachekey in self.cache_category:
return self.cache_category[cachekey]
- self.cursor.execute('SELECT c FROM categories WHERE category = ?'.replace('?',self.placeholder), (category,))
+ self.cursor.execute('SELECT c FROM categories WHERE category = ?'.replace('?',self.syntax_placeholder), (category,))
entries = self.cursor.fetchall()
try:
c = entries[0][0]
self.cache_category[cachekey] = c
return c
except IndexError:
- self.cursor.execute('INSERT INTO categories (category) VALUES (?)'.replace('?',self.placeholder), (category,))
+ self.cursor.execute('INSERT INTO categories (category) VALUES (?)'.replace('?',self.syntax_placeholder), (category,))
self.commit()
c = self.cursor.lastrowid
self.cache_category[cachekey] = c
@@ -159,14 +159,14 @@ class SQLPackageDatabase(object):
cachekey = arch
if cachekey in self.cache_arch:
return self.cache_arch[cachekey]
- self.cursor.execute('SELECT a FROM arches WHERE arch = ?'.replace('?',self.placeholder), (arch,))
+ self.cursor.execute('SELECT a FROM arches WHERE arch = ?'.replace('?',self.syntax_placeholder), (arch,))
entries = self.cursor.fetchall()
try:
a = entries[0][0]
self.cache_arch[cachekey] = a
return a
except IndexError:
- self.cursor.execute('INSERT INTO arches (arch) VALUES (?)'.replace('?',self.placeholder), (arch,))
+ self.cursor.execute('INSERT INTO arches (arch) VALUES (?)'.replace('?',self.syntax_placeholder), (arch,))
self.commit()
a = self.cursor.lastrowid
self.cache_arch[cachekey] = a
@@ -177,14 +177,14 @@ class SQLPackageDatabase(object):
if cachekey in self.cache_cp:
return self.cache_cp[cachekey]
c = self.find_or_create_category(category)
- self.cursor.execute('SELECT cp FROM packages WHERE c = ? AND pn = ?'.replace('?',self.placeholder), (c, pn))
+ self.cursor.execute('SELECT cp FROM packages WHERE c = ? AND pn = ?'.replace('?',self.syntax_placeholder), (c, pn))
entries = self.cursor.fetchall()
try:
cp = entries[0][0]
self.cache_cp[cachekey] = cp
return cp
except IndexError:
- self.cursor.execute('INSERT INTO packages (c,pn) VALUES (?,?)'.replace('?',self.placeholder), (c,pn))
+ self.cursor.execute('INSERT INTO packages (c,pn) VALUES (?,?)'.replace('?',self.syntax_placeholder), (c,pn))
self.commit()
cp = self.cursor.lastrowid
self.cache_cp[cachekey] = cp
@@ -200,11 +200,15 @@ class SQLPackageDatabase(object):
return False
except self.db.OperationalError:
return False
+ except self.db.ProgrammingError:
+ return False
class SQLitePackageDB(SQLPackageDatabase):
"""override for sqlite backend"""
- def __init__(self, filename):
+ def __init__(self, config={}):
+ self.syntax_placeholder = '?'
+ self.syntax_autoincrement = 'AUTOINCREMENT'
try:
import sqlite3 as sqlite
except ImportError:
@@ -213,11 +217,13 @@ class SQLitePackageDB(SQLPackageDatabase):
except ImportError:
print "Please install PySQLite or use Python 2.5 with sqlite"
sys.exit(1)
- self.placeholder = '?'
+
initdb = True
- if os.path.exists(filename):
+ if os.path.exists(config['database']):
initdb = False
- self.db = sqlite.connect(filename)
+ #self.db = sqlite.connect(database=config['database'])
+ self.db = sqlite.connect(**config)
+ print self.db
self.db.isolation_level = 'DEFERRED'
self.cursor = self.db.cursor()
if not self.schema_is_current():
@@ -233,15 +239,19 @@ class SQLitePackageDB(SQLPackageDatabase):
class MySQLPackageDB(SQLPackageDatabase):
"""override for MySQL backend"""
- def __init__(self, host, username, password, database):
- self.placeholder = "%s"
+ def __init__(self, config={}):
+ self.syntax_placeholder = "%s"
+ self.syntax_autoincrement = 'AUTO_INCREMENT'
+
try:
import MySQLdb
except ImportError:
print "Please install a recent version of MySQLdb for Python"
sys.exit(1)
- self.db = MySQLdb.connect(host=host, user=username, passwd=password, db=database, charset='utf8')
+ #self.db = MySQLdb.connect(host=config['host'], user=config['user'], passwd=config['passwd'], db=config['db'], charset=config['charset'])
+ self.db = MySQLdb.connect(**config)
self.cursor = self.db.cursor()
+ initdb = False
if not self.schema_is_current():
print 'Schema is outdated, flushing!'
initdb = True
diff --git a/web/controller.py b/web/controller.py
index cb93f88..0664d78 100644
--- a/web/controller.py
+++ b/web/controller.py
@@ -173,12 +173,18 @@ class Root(object):
def database_connect(thread_index):
"""Create a DB connection and store it in the current thread"""
- from web.model import SQLitePackageDB
- cherrypy.thread_data.db = SQLitePackageDB("pgo.db")
-
- #from web.model import MySQLPackageDB
- #cherrypy.thread_data.db = MySQLPackageDB("localhost", "user", "pass", "db")
- #cherrypy.thread.data.db.ping(True)
+ from etc.database_config import DatabaseConfig
+ database = None
+ if DatabaseConfig.mode == 'sqlite':
+ from web.model import SQLitePackageDB
+ database = SQLitePackageDB(DatabaseConfig.settings['sqlite'])
+ if DatabaseConfig.mode == 'mysql':
+ from web.model import MySQLPackageDB
+ database = MySQLPackageDB(DatabaseConfig.settings['mysql_ro'])
+ if database is None:
+ print "choose database in core.py first"
+ sys.exit(1)
+ cherrypy.thread_data.db = database
def main():
"""Use this when we run standalone"""
diff --git a/web/model.py b/web/model.py
index 02850b0..eea8cfb 100644
--- a/web/model.py
+++ b/web/model.py
@@ -33,6 +33,7 @@ def build_centerpkg_list(latest_entries, get_package_details_cpv, count, **kwds)
center_pkgs = []
shown_cp = []
for cpv, change in latest_entries:
+ #print 'cpv=%s' % (cpv)
atom = CPV(str(cpv))
if 'use_fullver' in kwds and kwds['use_fullver']:
version_check = atom.cpvstr
@@ -59,17 +60,17 @@ class PackageDB(object):
"""return modified cpvs"""
params = ()
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM versions JOIN packages USING (cp) JOIN categories USING (c)
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
if limit is not None:
try:
sql += " LIMIT 0, ?"
params = (int(limit),)
except ValueError:
return []
-
- self.cursor.execute(sql, params)
+ #print 'sql=%s' % (sql)
+ self.cursor.execute(sql.replace('?',self.syntax_placeholder), params)
entries = self.cursor.fetchall()
#print 'get_latest_cpvs=%s' % (entries,)
return entries
@@ -77,10 +78,10 @@ class PackageDB(object):
def get_latest_cpvs_by_pkgname(self, pkgname, limit=None):
"""return modified cpvs"""
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM versions JOIN packages USING (cp) JOIN categories USING (c)
WHERE pn = ?
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
params = (pkgname,)
if limit is not None:
try:
@@ -89,7 +90,7 @@ class PackageDB(object):
except ValueError:
return []
- self.cursor.execute(sql, params)
+ self.cursor.execute(sql.replace('?',self.syntax_placeholder), params)
entries = self.cursor.fetchall()
#print 'get_latest_cpvs_by_pkgname=%s' % (entries,)
return entries
@@ -97,10 +98,10 @@ class PackageDB(object):
def get_latest_cpvs_by_category(self, category, limit=None):
"""return modified cpvs"""
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM versions JOIN packages USING (cp) JOIN categories USING (c)
WHERE category = ?
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
params = (category,)
if limit is not None:
try:
@@ -116,10 +117,10 @@ class PackageDB(object):
def get_latest_cpvs_by_category_pkgname(self, category, pkgname, limit=None):
"""return modified cpvs"""
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM versions JOIN packages USING (cp) JOIN categories USING (c)
WHERE category = ? AND pn = ?
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
params = (category,pkgname,)
if limit is not None:
try:
@@ -142,16 +143,16 @@ class PackageDB(object):
return []
if mode != '':
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM arches JOIN keywords USING (a) JOIN versions USING (cpv) JOIN packages USING (cp) JOIN categories USING (c)
WHERE arches.arch=? AND keywords.mode=?
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
params = (arch, mode)
else:
- sql = """SELECT category || '/' || pn || '-' || pv, versions.mtime
+ sql = """SELECT %s, versions.mtime
FROM arches JOIN keywords USING (a) JOIN versions USING (cpv) JOIN packages USING (cp) JOIN categories USING (c)
WHERE arches.arch=?
- ORDER by versions.mtime DESC"""
+ ORDER by versions.mtime DESC""" % (self.columns_category_pn_pv)
params = (arch,)
if limit is not None:
try:
@@ -160,12 +161,11 @@ class PackageDB(object):
return []
sql += " LIMIT 0, ?"
params += (limit,)
-
- else:
- print 'limit was %s' % (repr(limit),)
+ #else:
+ # print 'limit was %s' % (repr(limit),)
#print "arch=%s mode=%s limit=%s sql=%s params=%s" % (repr(arch),repr(mode),repr(limit),repr(sql),repr(params))
- self.cursor.execute(sql.replace('?',self.placeholder),params)
+ self.cursor.execute(sql.replace('?',self.syntax_placeholder),params)
entries = self.cursor.fetchall()
#print 'get_latest_cpvs_by_arch=%s' % (entries,)
#print 'get_latest_cpvs_by_arch params=%s sql=%s' % (params,sql,)
@@ -198,7 +198,7 @@ class PackageDB(object):
sql = """SELECT license, homepage, description, changelog
FROM metadata JOIN packages USING (cp) JOIN categories USING (c)
WHERE category=? AND pn=?"""
- self.cursor.execute(sql.replace('?', self.placeholder), (category,pn))
+ self.cursor.execute(sql.replace('?', self.syntax_placeholder), (category,pn))
row = self.cursor.fetchone()
if not row:
return
@@ -214,11 +214,11 @@ class PackageDB(object):
if len(split_test) == 2:
date = split_test[1]
- sql = """SELECT category || '/' || pn AS cp, mtime
+ sql = """SELECT %s AS cp, mtime
FROM versions JOIN packages USING (cp) JOIN categories USING (c)
WHERE category = ? AND pn = ?
- ORDER BY pv"""
- self.cursor.execute(sql.replace('?', self.placeholder), (category,pn))
+ ORDER BY pv""" % (self.columns_category_pn)
+ self.cursor.execute(sql.replace('?', self.syntax_placeholder), (category,pn))
for changerow in self.cursor:
if CPV(str(changerow[0])).key == cp:
@@ -238,16 +238,16 @@ class PackageDB(object):
"""return cpv keywords"""
atom = CPV(str(query))
- sql = """SELECT category || '/' || pn || '-' || pv, arches.arch, mode
+ sql = """SELECT %s, arches.arch, mode
FROM arches JOIN keywords USING (a) JOIN versions USING (cpv) JOIN packages USING (cp) JOIN categories USING (c)
- WHERE category = ? AND pn = ?"""
+ WHERE category = ? AND pn = ?""" % (self.columns_category_pn_pv)
params = (atom.category,atom.package)
if atom.fullver is not None and len(atom.fullver) >= 1:
sql += ' AND pv = ?'
params += (atom.fullver,)
sql += ' ORDER BY pv ASC'
#print 'get_package_keywords sql=%s' % (sql,)
- self.cursor.execute(sql.replace('?',self.placeholder),params)
+ self.cursor.execute(sql.replace('?',self.syntax_placeholder),params)
#print 'get_package_keywords(atom)=%s' % (atom,)
pkgs = {}
@@ -291,18 +291,24 @@ class PackageDB(object):
def get_category_packages(self, category):
"""get a list of all packages for a category"""
- sql = """SELECT category || '/' || pn, 0
+ sql = """SELECT %s, 0
FROM packages JOIN categories USING (c)
WHERE category = ?
- ORDER BY pn"""
+ ORDER BY pn""" % (self.columns_category_pn)
- self.cursor.execute(sql.replace('?', self.placeholder), (category,))
+ self.cursor.execute(sql.replace('?', self.syntax_placeholder), (category,))
return self.cursor.fetchall()
+ columns_category_pn = None
+ columns_category_pn_pv = None
+
class SQLitePackageDB(PackageDB):
"""override for sqlite backend"""
+
+ columns_category_pn = "category || '/' || pn"
+ columns_category_pn_pv = "category || '/' || pn || '-' || pv"
- def __init__(self, filename):
+ def __init__(self, config={}):
try:
import sqlite3 as sqlite
except ImportError:
@@ -311,19 +317,23 @@ class SQLitePackageDB(PackageDB):
except ImportError:
print "Please install PySQLite or use Python 2.5 with sqlite"
sys.exit(1)
- self.placeholder = '?'
- self.db = sqlite.connect(filename)
+ self.syntax_placeholder = '?'
+ self.db = sqlite.connect(config)
self.cursor = self.db.cursor()
class MySQLPackageDB(PackageDB):
"""override for MySQL backend"""
+
+ columns_category_pn = "CONCAT(category, '/', pn)"
+ columns_category_pn_pv = "CONCAT(category, '/', pn, '-', pv)"
- def __init__(self, host, username, password, database):
- self.placeholder = '%s'
+ def __init__(self, config={}):
+ self.syntax_placeholder = '%s'
try:
import MySQLdb
except ImportError:
print "Please install a recent version of MySQLdb for Python"
sys.exit(1)
- self.db = MySQLdb.connect(host=host, user=username, passwd=password, db=database, charset='utf8')
+ #self.db = MySQLdb.connect(host=host, user=username, passwd=password, db=database, charset='utf8')
+ self.db = MySQLdb.connect(**config)
self.cursor = self.db.cursor()