Index: tracdownloads/api.py
===================================================================
--- tracdownloads/api.py	(revision 14870)
+++ tracdownloads/api.py	(working copy)
@@ -87,12 +87,13 @@
         sql = 'SELECT ' + ', '.join(columns) + ' FROM ' + table + (where
           and (' WHERE ' + where) or '') + (order_by and (' ORDER BY ' +
           order_by + (' ASC', ' DESC')[bool(desc)]) or '')
-        self.log.debug(sql % values)
-        context.cursor.execute(sql, values)
         items = []
-        for row in context.cursor:
-            row = dict(zip(columns, row))
-            items.append(row)
+        with self.env.db_query as db:
+            cursor = db.cursor()
+            cursor.execute(sql, values)
+            for row in cursor:
+                row = dict(zip(columns, row))
+                items.append(row)
         return items
 
     def get_versions(self, context, order_by = 'name', desc = False):
@@ -159,11 +160,12 @@
     def _get_item(self, context, table, columns, where = '', values = ()):
         sql = 'SELECT ' + ', '.join(columns) + ' FROM ' + table + (where
           and (' WHERE ' + where) or '')
-        self.log.debug(sql % values)
-        context.cursor.execute(sql, values)
-        for row in context.cursor:
-            row = dict(zip(columns, row))
-            return row
+        with self.env.db_query as db:
+            cursor = db.cursor()
+            cursor.execute(sql, values)
+            for row in cursor:
+                row = dict(zip(columns, row))
+                return row
         return None
 
     def get_download(self, context, id):
@@ -225,10 +227,11 @@
 
     def get_description(self, context):
         sql = "SELECT value FROM system WHERE name = 'downloads_description'"
-        self.log.debug(sql)
-        context.cursor.execute(sql)
-        for row in context.cursor:
-            return row[0]
+        with self.env.db_query as db:
+            cursor = db.cursor()
+            cursor.execute(sql)
+            for row in cursor:
+                return row[0]
 
     # Add item functions.
 
@@ -237,8 +240,9 @@
         values = item.values()
         sql = "INSERT INTO %s (" % (table,) + ", ".join(fields) + ") VALUES (" \
           + ", ".join(["%s" for I in xrange(len(fields))]) + ")"
-        self.log.debug(sql % tuple(values))
-        context.cursor.execute(sql, tuple(values))
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(sql, tuple(values))
 
     def add_download(self, context, download):
         self._add_item(context, 'download', download)
@@ -259,8 +263,9 @@
         values = item.values()
         sql = "UPDATE %s SET " % (table,) + ", ".join([("%s = %%s" % (field))
           for field in fields]) + " WHERE id = %s"
-        self.log.debug(sql % tuple(values + [id]))
-        context.cursor.execute(sql, tuple(values + [id]))
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(sql, tuple(values + [id]))
 
     def edit_download(self, context, id, download):
         self._edit_item(context, 'download', id, download)
@@ -276,20 +281,23 @@
 
     def edit_description(self, context, description):
         sql = "UPDATE system SET value = %s WHERE name = 'downloads_description'"
-        self.log.debug(sql % (description,))
-        context.cursor.execute(sql, (description,))
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(sql, (description,))
 
     # Delete item functions.
 
     def _delete_item(self, context, table, id):
         sql = "DELETE FROM " + table + " WHERE id = %s"
-        self.log.debug(sql % (id,))
-        context.cursor.execute(sql, (id,))
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(sql, (id,))
 
     def _delete_item_ref(self, context, table, column, id):
         sql = "UPDATE " + table + " SET " + column + " = NULL WHERE " + column + " = %s"
-        self.log.debug(sql % (id,))
-        context.cursor.execute(sql, (id,))
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(sql, (id,))
 
     def delete_download(self, context, id):
         self._delete_item(context, 'download', id)
@@ -311,10 +319,11 @@
     def _get_attribute(self, context, table, column, where = '', values = ()):
         sql = 'SELECT ' + column + ' FROM ' + table + (where and (' WHERE ' +
           where) or '')
-        self.log.debug(sql % values)
-        context.cursor.execute(sql, values)
-        for row in context.cursor:
-            return row[0]
+        with self.env.db_query as db:
+            cursor = db.cursor()
+            cursor.execute(sql, values)
+            for row in cursor:
+                return row[0]
         return None
 
     def get_download_id_from_file(self, context, file):
@@ -325,10 +334,11 @@
         sql = 'SELECT SUM(count) FROM download' + (download_ids and
           (' WHERE id in (' + ', '.join([to_unicode(download_id) for download_id
           in download_ids]) + ')') or '')
-        self.log.debug(sql)
-        context.cursor.execute(sql)
-        for row in context.cursor:
-            return row[0]
+        with self.env.db_query as db:
+            cursor = db.cursor()
+            cursor.execute(sql)
+            for row in cursor:
+                return row[0]
         return None
 
     # Proces request functions.
@@ -337,10 +347,6 @@
         # Clear data for next request.
         self.data = {}
 
-        # Get database access.
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
-
         # Get request mode
         modes = self._get_modes(context)
         self.log.debug('modes: %s' % modes)
@@ -362,8 +368,7 @@
         add_script(context.req, 'common/js/trac.js')
         add_script(context.req, 'common/js/wikitoolbar.js')
 
-        # Commit database changes and return template and data.
-        db.commit()
+        # Return template and data.
         self.env.log.debug('data: %s' % (self.data,))
         return modes[-1] + '.html', {'downloads' : self.data}
 
@@ -424,6 +429,8 @@
                 return ['description-edit', 'downloads-list']
             elif action == 'post-edit':
                 return ['description-post-edit', 'downloads-list']
+            elif action == 'get-file':
+                return ['get-file']
             else:
                 return ['downloads-list']
         else:
@@ -468,10 +475,6 @@
                     listener.download_changed(context, new_download,
                       download)
 
-                # Commit DB before file send.
-                db = self.env.get_db_cnx()
-                db.commit()
-
                 # Guess mime type.
                 file = open(path.encode('utf-8'), "r")
                 file_data = file.read(1000)
Index: tracdownloads/consoleadmin.py
===================================================================
--- tracdownloads/consoleadmin.py	(revision 14870)
+++ tracdownloads/consoleadmin.py	(working copy)
@@ -57,8 +57,6 @@
 
         # Create context.
         context = Context('downloads-consoleadmin')
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
 
         # Print uploded download
         downloads = api.get_downloads(context)
@@ -76,8 +74,6 @@
 
         # Create context.
         context = Context('downloads-consoleadmin')
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
         context.req = FakeRequest(self.env, self.consoleadmin_user)
 
         # Convert relative path to absolute.
@@ -124,9 +120,8 @@
         # Upload file to DB and file storage.
         api._add_download(context, download, file)
 
-        # Close input file and commit changes in DB.
+        # Close input file
         file.close()
-        db.commit()
 
     def _do_remove(self, identifier):
         # Get downloads API component.
@@ -134,8 +129,6 @@
 
         # Create context.
         context = Context('downloads-consoleadmin')
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
         context.req = FakeRequest(self.env, self.consoleadmin_user)
 
         # Get download by ID or filename.
@@ -153,9 +146,6 @@
         # Delete download by ID.
         api.delete_download(context, download_id)
 
-        # Commit changes in DB.
-        db.commit()
-
     def _get_file(self, filename):
         # Open file and get its size
         file = open(filename, 'rb')
Index: tracdownloads/core.py
===================================================================
--- tracdownloads/core.py	(revision 14870)
+++ tracdownloads/core.py	(working copy)
@@ -29,7 +29,9 @@
         The core module implements plugin's ability to download files, provides
         permissions and templates.
     """
-    implements(IRequestHandler, ITemplateProvider, IPermissionRequestor,
+    #implements(IRequestHandler, ITemplateProvider, IPermissionRequestor,
+    #  IResourceManager)
+    implements(ITemplateProvider, IPermissionRequestor,
       IResourceManager)
 
     # IPermissionRequestor methods.
@@ -52,27 +54,27 @@
 
     # IRequestHandler methods.
 
-    def match_request(self, req):
-        match = re.match(r'''^/downloads/(\d+)($|/$)''', req.path_info)
-        if match:
-            req.args['action'] = 'get-file'
-            req.args['id'] = match.group(1)
-            return True
-        match = re.match(r'''^/downloads/([^/]+)($|/$)''', req.path_info)
-        if match:
-            req.args['action'] = 'get-file'
-            req.args['file'] = match.group(1)
-            return True
-        return False
+#    def match_request(self, req):
+#        match = re.match(r'''^/downloads/(\d+)($|/$)''', req.path_info)
+#        if match:
+#            req.args['action'] = 'get-file'
+#            req.args['id'] = match.group(1)
+#            return True
+#        match = re.match(r'''^/downloads/([^/]+)($|/$)''', req.path_info)
+#        if match:
+#            req.args['action'] = 'get-file'
+#            req.args['file'] = match.group(1)
+#            return True
+#        return False
 
-    def process_request(self, req):
-        # Create request context.
-        context = Context.from_request(req)('downloads-core')
+#    def process_request(self, req):
+#        # Create request context.
+#        context = Context.from_request(req)('downloads-core')
+#
+#        # Process request and return content.
+#        api = self.env[DownloadsApi]
+#        return api.process_downloads(context) + (None,)
 
-        # Process request and return content.
-        api = self.env[DownloadsApi]
-        return api.process_downloads(context) + (None,)
-
     # IResourceManager methods.
 
     def get_resource_realms(self):
@@ -85,8 +87,6 @@
       context = None, **kwargs):
         # Create context.
         context = Context('downloads-core')
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
 
         # Get download from ID.
         api = self.env[DownloadsApi]
@@ -124,6 +124,11 @@
         match = re.match(r'''^/downloads($|/$)''', req.path_info)
         if match:
             return True
+        match = re.match(r'''^/downloads/(\d+)($|/$)''', req.path_info)
+        if match:
+            req.args['action'] = 'get-file'
+            req.args['id'] = match.group(1)
+            return True
         match = re.match(r'''^/downloads/([^/]+)($|/$)''', req.path_info)
         if match:
             req.args['action'] = 'get-file'
Index: tracdownloads/init.py
===================================================================
--- tracdownloads/init.py	(revision 14870)
+++ tracdownloads/init.py	(working copy)
@@ -40,7 +40,6 @@
     def _get_db_version(self, cursor):
         try:
             sql = "SELECT value FROM system WHERE name='downloads_version'"
-            self.log.debug(sql)
             cursor.execute(sql)
             for row in cursor:
                 return int(row[0])
Index: tracdownloads/tags.py
===================================================================
--- tracdownloads/tags.py	(revision 14870)
+++ tracdownloads/tags.py	(working copy)
@@ -139,8 +139,6 @@
     def _resolve_ids(self, download):
         # Create context.
         context = Context('downloads-core')
-        db = self.env.get_db_cnx()
-        context.cursor = db.cursor()
 
         # Resolve architecture platform and type names.
         api = self.env[DownloadsApi]
Index: tracdownloads/timeline.py
===================================================================
--- tracdownloads/timeline.py	(revision 14870)
+++ tracdownloads/timeline.py	(working copy)
@@ -33,8 +33,6 @@
         if ('downloads' in filters) and ('DOWNLOADS_VIEW' in req.perm):
             # Create context.
             context = Context.from_request(req)('downloads-timeline')
-            db = self.env.get_db_cnx()
-            context.cursor = db.cursor()
 
             # Get API component.
             api = self.env[DownloadsApi]
Index: tracdownloads/wiki.py
===================================================================
--- tracdownloads/wiki.py	(revision 14870)
+++ tracdownloads/wiki.py	(working copy)
@@ -50,10 +50,6 @@
             # Create request context.
             context = Context.from_request(formatter.req)('downloads-wiki')
 
-            # Get database access.
-            db = self.env.get_db_cnx()
-            context.cursor = db.cursor()
-
             # Get API component.
             api = self.env[DownloadsApi]
 
@@ -104,10 +100,6 @@
             # Create request context.
             context = Context.from_request(formatter.req)('downloads-wiki')
 
-            # Get database access.
-            db = self.env.get_db_cnx()
-            context.cursor = db.cursor()
-
             # Get API object.
             api = self.env[DownloadsApi]
 
@@ -138,8 +130,6 @@
             if formatter.req.perm.has_permission('DOWNLOADS_VIEW'):
                 # Create context.
                 context = Context.from_request(formatter.req)('downloads-wiki')
-                db = self.env.get_db_cnx()
-                context.cursor = db.cursor()
 
                 # Get API component.
                 api = self.env[DownloadsApi]
