Index: trac/db/sqlite_backend.py
===================================================================
--- trac/db/sqlite_backend.py	(revision 8555)
+++ trac/db/sqlite_backend.py	(working copy)
@@ -19,8 +19,7 @@
 import weakref
 
 from trac.core import *
-from trac.db.api import IDatabaseConnector
-from trac.db.util import ConnectionWrapper
+from trac.db.api import IDatabaseConnector, DatabaseConnection
 from trac.util import get_pkginfo, getuser
 
 _like_escape_re = re.compile(r'([/_%])')
@@ -157,7 +156,7 @@
             raise TracError("Backup attempt failed")
         return dest_file
 
-class SQLiteConnection(ConnectionWrapper):
+class SQLiteConnection(DatabaseConnection):
     """Connection wrapper for SQLite."""
 
     __slots__ = ['_active_cursors']
@@ -165,7 +164,7 @@
 
     def __init__(self, path, log=None, params={}):
         assert have_pysqlite > 0
-        self.cnx = None
+        super(SQLiteConnection,self).__init__(log=log)
         if path != ':memory:':
             if not os.access(path, os.F_OK):
                 raise TracError('Database "%s" not found.' % path)
@@ -183,15 +182,13 @@
             timeout = int(params.get('timeout', 10.0))
             if isinstance(path, unicode): # needed with 2.4.0
                 path = path.encode('utf-8')
-            cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES,
+            self.cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES,
                                  check_same_thread=sqlite_version < 30301,
                                  timeout=timeout)
         else:
             timeout = int(params.get('timeout', 10000))
-            cnx = sqlite.connect(path, timeout=timeout, encoding='utf-8')
+            self.cnx = sqlite.connect(path, timeout=timeout, encoding='utf-8')
             
-        ConnectionWrapper.__init__(self, cnx, log)
-
     if have_pysqlite == 2:
         def cursor(self):
             cursor = self.cnx.cursor(PyFormatCursor)
Index: trac/db/api.py
===================================================================
--- trac/db/api.py	(revision 8555)
+++ trac/db/api.py	(working copy)
@@ -142,6 +142,47 @@
         return connector, args
 
 
+class DatabaseConnection(object):
+    """Minimal set of methods necessary to implement Database backend for Trac
+    """
+
+    def __init__(self, path=None, log=None, params={}):
+        """Initialize connection and save connection reference in self.cnx
+        """
+        self.cnx = None
+        self.log = log
+
+    # {{{ standard DB API 2.0 connection methods
+    def close(self):
+        return self.cnx.close();
+
+    def commit(self):
+        return self.cnx.commit();
+
+    def rollback(self):
+        return self.cnx.rollback();
+
+    def cursor(self):
+        return self.cnx.cursor();
+    # }}}
+
+    def get_last_id(self, cursor, table, column='id'):
+        raise TracError('Not implemented.')
+
+    def cast(self, column, type):
+        raise TracError('Not implemented.')
+
+    def concat(self, *args):
+        raise TracError('Not implemented.')
+
+    def like(self):
+        raise TracError('Not implemented.')
+
+    def like_escape(self, text):
+        raise TracError('Not implemented.')
+
+
+
 def _parse_db_str(db_str):
     scheme, rest = db_str.split(':', 1)
 
Index: trac/db/mysql_backend.py
===================================================================
--- trac/db/mysql_backend.py	(revision 8555)
+++ trac/db/mysql_backend.py	(working copy)
@@ -18,8 +18,7 @@
 
 from trac.core import *
 from trac.config import Option
-from trac.db.api import IDatabaseConnector, _parse_db_str
-from trac.db.util import ConnectionWrapper
+from trac.db.api import IDatabaseConnector, DatabaseConnection, _parse_db_str
 from trac.util import get_pkginfo
 from trac.util.compat import close_fds
 from trac.util.text import to_unicode
@@ -179,22 +178,22 @@
         return dest_file
 
 
-class MySQLConnection(ConnectionWrapper):
+class MySQLConnection(DatabaseConnection):
     """Connection wrapper for MySQL."""
 
     poolable = True
 
     def __init__(self, path, log, user=None, password=None, host=None,
                  port=None, params={}):
+        super(MySQLConnection,self).__init__(log=log)
         if path.startswith('/'):
             path = path[1:]
         if password == None:
             password = ''
         if port == None:
             port = 3306
-        cnx = MySQLdb.connect(db=path, user=user, passwd=password,
+        self.cnx = MySQLdb.connect(db=path, user=user, passwd=password,
                               host=host, port=port, charset='utf8')
-        ConnectionWrapper.__init__(self, cnx, log)
         self._is_closed = False
 
     def cast(self, column, type):
Index: trac/db/postgres_backend.py
===================================================================
--- trac/db/postgres_backend.py	(revision 8555)
+++ trac/db/postgres_backend.py	(working copy)
@@ -18,8 +18,7 @@
 
 from trac.core import *
 from trac.config import Option
-from trac.db.api import IDatabaseConnector, _parse_db_str
-from trac.db.util import ConnectionWrapper
+from trac.db.api import IDatabaseConnector, DatabaseConnection, _parse_db_str
 from trac.util import get_pkginfo
 from trac.util.compat import close_fds
 from trac.util.text import to_unicode
@@ -143,13 +142,14 @@
         return dest_file
 
 
-class PostgreSQLConnection(ConnectionWrapper):
+class PostgreSQLConnection(DatabaseConnection):
     """Connection wrapper for PostgreSQL."""
 
     poolable = True
 
     def __init__(self, path, log=None, user=None, password=None, host=None,
                  port=None, params={}):
+        super(PostgreSQLConnection,self).__init__(log=log)
         if path.startswith('/'):
             path = path[1:]
         # We support both psycopg and PgSQL but prefer psycopg
@@ -180,24 +180,23 @@
                 dsn.append('host=' + host)
             if port:
                 dsn.append('port=' + str(port))
-            cnx = psycopg.connect(' '.join(dsn))
-            cnx.set_client_encoding('UNICODE')
+            self.cnx = psycopg.connect(' '.join(dsn))
+            self.cnx.set_client_encoding('UNICODE')
         else:
             # Don't use chatty, inefficient server-side cursors.
             # http://pypgsql.sourceforge.net/pypgsql-faq.html#id2787367
             PgSQL.fetchReturnsList = 1
             PgSQL.noPostgresCursor = 1
-            cnx = PgSQL.connect('', user, password, host, path, port, 
+            self.cnx = PgSQL.connect('', user, password, host, path, port, 
                                 client_encoding='utf-8', unicode_results=True)
         try:
             self.schema = None
             if 'schema' in params:
                 self.schema = params['schema']
-                cnx.cursor().execute('SET search_path TO %s', (self.schema,))
-                cnx.commit()
+                self.cnx.cursor().execute('SET search_path TO %s', (self.schema,))
+                self.cnx.commit()
         except PGSchemaError:
-            cnx.rollback()
-        ConnectionWrapper.__init__(self, cnx, log)
+            self.cnx.rollback()
 
     def cast(self, column, type):
         # Temporary hack needed for the union of selects in the search module
