diff options
author | michele.simionato <devnull@localhost> | 2009-03-17 15:30:49 +0000 |
---|---|---|
committer | michele.simionato <devnull@localhost> | 2009-03-17 15:30:49 +0000 |
commit | 5ac87f1d80f861f1ecffac2fcb60701434cbf3d0 (patch) | |
tree | e49355e282f4881457aab01382f4e2de356b3b8b | |
parent | dbc590151f3865301f7e8ba1b7176bb76d4513cc (diff) | |
download | micheles-5ac87f1d80f861f1ecffac2fcb60701434cbf3d0.tar.gz |
Various improvements to sqlplain
-rw-r--r-- | sqlplain/__init__.py | 11 | ||||
-rw-r--r-- | sqlplain/connection.py | 24 | ||||
-rw-r--r-- | sqlplain/doc/sql_repl.py | 7 | ||||
-rw-r--r-- | sqlplain/mssql_support.py | 27 | ||||
-rw-r--r-- | sqlplain/postgres_support.py | 2 | ||||
-rw-r--r-- | sqlplain/sql_support.py | 4 | ||||
-rw-r--r-- | sqlplain/sqlite_support.py | 2 | ||||
-rw-r--r-- | sqlplain/uri.py | 11 |
8 files changed, 31 insertions, 57 deletions
diff --git a/sqlplain/__init__.py b/sqlplain/__init__.py index 196f3e2..e73bf8c 100644 --- a/sqlplain/__init__.py +++ b/sqlplain/__init__.py @@ -1,11 +1,2 @@ -from sqlplain.connection import LazyConnection, TransactionalConnection, \ - qmark2pyformat +from sqlplain.connection import LazyConnection as lazyconnect from sqlplain.sql_support import do - -def lazyconnect(uri, isolation_level=None, threadlocal=False, retry=False, - conn_class=None): - if conn_class is None and isolation_level is None: - conn_class = LazyConnection - elif conn_class is None and isolation_level is not None: - conn_class = TransactionalConnection - return conn_class(uri, isolation_level, threadlocal, retry) diff --git a/sqlplain/connection.py b/sqlplain/connection.py index ccfa116..82e1f50 100644 --- a/sqlplain/connection.py +++ b/sqlplain/connection.py @@ -122,7 +122,8 @@ class LazyConnection(object): self.uri = URI(uri) self.name = self.uri['database'] self.dbtype = self.uri['dbtype'] - self.driver, connect, params = self.uri.get_driver_connect_params() + self.driver, params = self.uri.get_driver_params() + connect = self.driver.connect args = params, isolation_level self.chatty = False self.isolation_level = isolation_level @@ -165,14 +166,12 @@ class LazyConnection(object): else: lst.append(a) args = tuple(lst) - if self.driver.placeholder: # the template has to be interpolated - argnames, templ = get_args_templ(templ, self.placeholder) # cached + argnames, templ = get_args_templ(templ, self.driver.placeholder) if len(argnames) != len(args): # especially useful for mssql raise TypeError( "Expected %d arguments (%s), got %d (%s)" % (len(argnames), ', '.join(argnames), len(args), args)) - descr, res = self._raw_execute(templ, args) if scalar: # you expect a scalar result if not res: @@ -220,19 +219,6 @@ class LazyConnection(object): """The next time you will call an active method, a fresh new connection will be instantiated""" self._storage.close() - - def __repr__(self): - return "<%s %s>" % (self.__class__.__name__, self.uri) - - @property - def rowcount(self): - return self._storage.curs.rowcount - -class TransactionalConnection(LazyConnection): - """ - Add commit and rollback methods to a LazyConnection, as well - as a with statement interface. - """ def rollback(self): return self._storage.conn.rollback() @@ -253,6 +239,10 @@ class TransactionalConnection(LazyConnection): def __repr__(self): return "<%s %s, isolation_level=%s>" % ( self.__class__.__name__, self.uri, self.isolation_level) + + @property + def rowcount(self): + return self._storage.curs.rowcount class NullObject(object): '''Implements the NullObject pattern. diff --git a/sqlplain/doc/sql_repl.py b/sqlplain/doc/sql_repl.py index aa3642f..47344ca 100644 --- a/sqlplain/doc/sql_repl.py +++ b/sqlplain/doc/sql_repl.py @@ -28,8 +28,11 @@ class Console(object): def sql_eval(self, code): rows = self.db.execute(code) - if not isinstance(rows, list): # a scalar was returned - return '%s rows were affected' % rows + if isinstance(rows, int): + if rows != -1: + return '%s rows were affected' % rows + else: + return '' out = ['%d rows were returned' % len(rows), '\t'.join(rows.header)] for row in rows: out.append('\t'.join(map(str, row))) diff --git a/sqlplain/mssql_support.py b/sqlplain/mssql_support.py index adb324f..2183087 100644 --- a/sqlplain/mssql_support.py +++ b/sqlplain/mssql_support.py @@ -7,15 +7,22 @@ ISOLATION_LEVELS = ( None, 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE') +placeholder = '%s' + class Connection(object): def __init__(self, cnx, isolation_level=None): + assert isolation_level in ISOLATION_LEVELS, isolation_level self._cnx = cnx self.isolation_level = isolation_level - assert isolation_level in ISOLATION_LEVELS if isolation_level: cnx.query("set transaction isolation level " + isolation_level) - + try: + self._cnx.query("begin tran") + self._cnx.fetch_array() + except Exception, e: + raise OperationalError(e) + def cursor(self): if self._cnx is None: raise OperationalError("Closed connection") @@ -29,16 +36,6 @@ class Connection(object): return # the connection was already closed self._cnx.close() self._cnx = None - -class TransactionalConnection(Connection): - - def __init__(self, cnx, isolation_level): - super(TransactionalConnection, self).__init__(cnx, isolation_level) - try: - self._cnx.query("begin tran") - self._cnx.fetch_array() - except Exception, e: - raise OperationalError(e) def commit(self): if self._cnx is None: @@ -71,8 +68,4 @@ def connect(params, isolation_level=None): host = '%s:%s' % (host, port) # add the port _conn = _mssql.connect(host, user, pwd) _conn.select_db(db) - if isolation_level is None: - conn = Connection(_conn) - else: - conn = TransactionalConnection(_conn, isolation_level) - return conn + return Connection(_conn, isolation_level) diff --git a/sqlplain/postgres_support.py b/sqlplain/postgres_support.py index c29a22e..507fc29 100644 --- a/sqlplain/postgres_support.py +++ b/sqlplain/postgres_support.py @@ -2,6 +2,8 @@ import psycopg2 as dbapi2 ISOLATION_LEVELS = None, 0, 1, 2 +placeholder = '%s' + # AUTOCOMMIT = None, 0 # READ_COMMITTED = READ_UNCOMMITTED = 1 # REPEATABLE_READ = SERIALIZABLE = 2 diff --git a/sqlplain/sql_support.py b/sqlplain/sql_support.py index 1f5cf04..62eaf0a 100644 --- a/sqlplain/sql_support.py +++ b/sqlplain/sql_support.py @@ -7,8 +7,8 @@ class _SymbolReplacer(object): Returns the names of the arguments and the template interpolated with a placeholder. Used by get_args_templ. """ - STRING_OR_COMMENT = re.compile(r"'[^']*'|--.*\n") - SYMBOL = re.compile(r":([a-zA-Z]\w*)") + STRING_OR_COMMENT = re.compile(r"('[^']*'|--.*\n)") + SYMBOL = re.compile(r":(\w+)") def __init__(self, placeholder): self.placeholder = placeholder diff --git a/sqlplain/sqlite_support.py b/sqlplain/sqlite_support.py index 1cd87fc..d556456 100644 --- a/sqlplain/sqlite_support.py +++ b/sqlplain/sqlite_support.py @@ -5,6 +5,8 @@ except ImportError: # Python < 2.5 ISOLATION_LEVELS = (None, "", "DEFERRED", "IMMEDIATE", "EXCLUSIVE") +placeholder = '?' + def connect(fname, isolation_level=None, **kw): dbapi2.register_converter('datetime', dbapi2.converters['TIMESTAMP']) return dbapi2.connect( diff --git a/sqlplain/uri.py b/sqlplain/uri.py index 46a6337..e1e7578 100644 --- a/sqlplain/uri.py +++ b/sqlplain/uri.py @@ -91,16 +91,9 @@ class URI(object): for name, value in vars(driver_util).iteritems(): if name.endswith(dbtype): setattr(util, name, value) - # set the placeholder according to the paramstyle - if driver.paramstyle == 'qmark': - driver.placeholder = '?' - elif driver.paramstyle in ('format', 'pyformat'): - driver.placeholder = '%s' - else: - driver.placeholder = None return driver - def get_driver_connect_params(self): + def get_driver_params(self): """ Determine the database type (and therefore the driver to use) from the URI and returns the right connection factory, as well as its @@ -112,7 +105,7 @@ class URI(object): else: params = (self.user, self.password, self.host, self.port, self.database) - return driver.dbapi2, driver.connect, params + return driver, params def __getitem__(self, name): # make the interpolation syntax (string-templ % self) possible |