diff options
| author | Christophe Simonis <chs@odoo.com> | 2016-02-17 17:48:03 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2016-02-17 17:48:03 +0100 |
| commit | 5be43b8d9ae4485ac28e9afb7dd7cdecefb58abc (patch) | |
| tree | 483b65cfc65fb4f57a32f841424812575ebdbc84 /openerp/sql_db.py | |
| parent | 6999a862fdff34ea7d05ba90c2977f2c386cb506 (diff) | |
| parent | 27058c4763b40c5ef9b2b81c9f8a2de8d68469af (diff) | |
[MERGE] forward port of branch 9.0 up to 27058c4
Diffstat (limited to 'openerp/sql_db.py')
| -rw-r--r-- | openerp/sql_db.py | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 4aef9549ff4..fe0502a4fa9 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -13,6 +13,8 @@ from functools import wraps import logging import urlparse import uuid + +import psycopg2 import psycopg2.extras import psycopg2.extensions from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_REPEATABLE_READ @@ -527,7 +529,11 @@ class ConnectionPool(object): _logger.debug(('%r ' + msg), self, *args) @locked - def borrow(self, dsn): + def borrow(self, connection_info): + """ + :param dict connection_info: dict of psql connection keywords + :rtype: PsycoConnection + """ # free dead and leaked connections for i, (cnx, _) in tools.reverse_enumerate(self._connections): if cnx.closed: @@ -541,7 +547,7 @@ class ConnectionPool(object): _logger.info('%r: Free leaked connection to %r', self, cnx.dsn) for i, (cnx, used) in enumerate(self._connections): - if not used and cnx._original_dsn == dsn: + if not used and cnx._original_dsn == connection_info: try: cnx.reset() except psycopg2.OperationalError: @@ -570,11 +576,13 @@ class ConnectionPool(object): raise PoolError('The Connection Pool Is Full') try: - result = psycopg2.connect(dsn=dsn, connection_factory=PsycoConnection) + result = psycopg2.connect( + connection_factory=PsycoConnection, + **connection_info) except psycopg2.Error: _logger.info('Connection to the database failed') raise - result._original_dsn = dsn + result._original_dsn = connection_info self._connections.append((result, True)) self._debug('Create new connection') return result @@ -639,8 +647,17 @@ class Connection(object): except Exception: return False -def dsn(db_or_uri): - """parse the given `db_or_uri` and return a 2-tuple (dbname, uri)""" +def connection_info_for(db_or_uri): + """ parse the given `db_or_uri` and return a 2-tuple (dbname, connection_params) + + Connection params are either a dictionary with a single key ``dsn`` + containing a connection URI, or a dictionary containing connection + parameter keywords which psycopg2 can build a key/value connection string + (dsn) from + + :param str db_or_uri: database name or postgres dsn + :rtype: (str, dict) + """ if db_or_uri.startswith(('postgresql://', 'postgres://')): # extract db from uri us = urlparse.urlsplit(db_or_uri) @@ -650,15 +667,15 @@ def dsn(db_or_uri): db_name = us.username else: db_name = us.hostname - return db_name, db_or_uri + return db_name, {'dsn': db_or_uri} - _dsn = '' + connection_info = {'database': db_or_uri} for p in ('host', 'port', 'user', 'password'): cfg = tools.config['db_' + p] if cfg: - _dsn += '%s=%s ' % (p, cfg) + connection_info[p] = cfg - return db_or_uri, '%sdbname=%s' % (_dsn, db_or_uri) + return db_or_uri, connection_info _Pool = None @@ -667,16 +684,16 @@ def db_connect(to, allow_uri=False): if _Pool is None: _Pool = ConnectionPool(int(tools.config['db_maxconn'])) - db, uri = dsn(to) + db, info = connection_info_for(to) if not allow_uri and db != to: raise ValueError('URI connections not allowed') - return Connection(_Pool, db, uri) + return Connection(_Pool, db, info) def close_db(db_name): """ You might want to call openerp.modules.registry.RegistryManager.delete(db_name) along this function.""" global _Pool if _Pool: - _Pool.close_all(dsn(db_name)[1]) + _Pool.close_all(connection_info_for(db_name)[1]) def close_all(): global _Pool |
