summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-03-17 15:30:49 +0000
committermichele.simionato <devnull@localhost>2009-03-17 15:30:49 +0000
commit5ac87f1d80f861f1ecffac2fcb60701434cbf3d0 (patch)
treee49355e282f4881457aab01382f4e2de356b3b8b
parentdbc590151f3865301f7e8ba1b7176bb76d4513cc (diff)
downloadmicheles-5ac87f1d80f861f1ecffac2fcb60701434cbf3d0.tar.gz
Various improvements to sqlplain
-rw-r--r--sqlplain/__init__.py11
-rw-r--r--sqlplain/connection.py24
-rw-r--r--sqlplain/doc/sql_repl.py7
-rw-r--r--sqlplain/mssql_support.py27
-rw-r--r--sqlplain/postgres_support.py2
-rw-r--r--sqlplain/sql_support.py4
-rw-r--r--sqlplain/sqlite_support.py2
-rw-r--r--sqlplain/uri.py11
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