from xivo import anysql from xivo import urisup from xivo.urisup import SCHEME, AUTHORITY, PATH, QUERY, FRAGMENT, uri_help_split, uri_help_unsplit def __dict_from_query(query): if not query: return {} return dict(query) def connect_by_uri(uri): puri = urisup.uri_help_split(uri) opts = __dict_from_query(puri[QUERY]) con = None if "timeout_ms" in opts: con = sqlite3.connect(puri[PATH],float(opts["timeout_ms"])) else: con = sqlite3.connect(puri[PATH]) return con def c14n_uri(uri): puri = list(urisup.uri_help_split(uri)) puri[PATH] = os.path.abspath(puri[PATH]) return uri_help_unsplit(tuple(puri)) def escape(s): return '.'.join([('"%s"' % comp.replace('"', '""')) for comp in s.split('.')]) anysql.register_uri_backend('sqlite3', connect_by_uri, sqlite3, c14n_uri, escape)
#params = __dict_from_query(puri[QUERY]) params = {} if puri[AUTHORITY]: user, passwd, host, port = puri[AUTHORITY] if user: params['user'] = user if passwd: params['password'] = passwd if host: params['host'] = host if port: params['port'] = port if puri[PATH]: params['database'] = puri[PATH] if params['database'] and params['database'][0] == '/': params['database'] = params['database'][1:] #__apply_types(params, __typemap) return psycopg2.connect(**params) def escape(s): return '.'.join(['"%s"' % comp for comp in s.split('.')]) def cast(fieldname, type): return "%s::%s" % (fieldname, type) anysql.register_uri_backend('postgresql', connect_by_uri, psycopg2, None, escape, cast)
# The next affectation work around a bug in python-mysqldb which # happens when using an unicode charset: the conv parameter is # defaulted to the common dictionary MySQLdb.converters.conversions # when not explicitly given to the __init__() of # MySQLdb.connections.Connection, the _mysql module just store it in # the .converter member in the __init__() method of the base class # _mysql.connection, and later, back in the __init__() of # MySQLdb.connections.Connection, some children of .converter, which # are lists, are prepended by dynamically generated functions. The net # result is that every times a new Mysql connection is asked for with # no individualised conversion dictionary passed to the conv parameter, # a bunch of new functions and tuples are created, on which the process # will keep references forever, effectively leaking some memory as some # won't be used anymore after the termination of any connection. # This work around is believed to be effective because the only # references to the dynamically created conversion functions generated # by MySQLdb.connections will be in this instance-specific copy of # MySQLdb.converters.conversions. A unique reference to this copy will # be held by the connection instance, so when the latter is garbage # collected, the copied conversion dictionary is freed, and eventually # the now orphan tuples and generated functions are too. params['conv'] = CST_CONVERSIONS.copy() params['cursorclass'] = SSCursor return MySQLdb.connect(**params) def escape(s): return '.'.join([('`%s`' % comp.replace('`', '``')) for comp in s.split('.')]) anysql.register_uri_backend('mysql', connect_by_uri, MySQLdb, None, escape)
if puri[AUTHORITY]: user, passwd, host, port = puri[AUTHORITY] if user: params['user'] = user if passwd: params['password'] = passwd if host: params['host'] = host if port: params['port'] = port if puri[PATH]: params['database'] = puri[PATH] if params['database'] and params['database'][0] == '/': params['database'] = params['database'][1:] #__apply_types(params, __typemap) return psycopg2.connect(**params) def escape(s): return '.'.join(['"%s"' % comp for comp in s.split('.')]) def cast(fieldname, type): return "%s::%s" % (fieldname, type) anysql.register_uri_backend('postgresql', connect_by_uri, psycopg2, None, escape, cast)
NOTE: the authority and the path parts of the URI have precedence over the query part, if an argument is given in both. Descriptions of options: file:///usr/lib/python?.?/site-packages/pyPgSQL/PgSQL.py """ puri = urisup.uri_help_split(uri) params = __dict_from_query(puri[QUERY]) if puri[AUTHORITY]: user, password, host, port = puri[AUTHORITY] if user: params['user'] = user if password: params['password'] = password if host: params['host'] = host if port: params['port'] = port if puri[PATH]: params['database'] = puri[PATH] if params['database'] and params['database'][0] == '/': params['database'] = params['database'][1:] __apply_types(params, __typemap) return PgSQL.connect(**params) def escape(s): return '.'.join([('"%s"' % comp.replace('"', '""')) for comp in s.split('.')]) anysql.register_uri_backend('postgres', connect_by_uri, PgSQL, None, escape)