web/lib/django/db/backends/sqlite3/base.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
--- a/web/lib/django/db/backends/sqlite3/base.py	Wed May 19 17:43:59 2010 +0200
+++ b/web/lib/django/db/backends/sqlite3/base.py	Tue May 25 02:43:45 2010 +0200
@@ -1,12 +1,16 @@
 """
 SQLite3 backend for django.
 
-Python 2.3 and 2.4 require pysqlite2 (http://pysqlite.org/).
+Python 2.4 requires pysqlite2 (http://pysqlite.org/).
 
 Python 2.5 and later can use a pysqlite2 module or the sqlite3 module in the
 standard library.
 """
 
+import re
+import sys
+
+from django.db import utils
 from django.db.backends import *
 from django.db.backends.signals import connection_created
 from django.db.backends.sqlite3.client import DatabaseClient
@@ -27,12 +31,8 @@
         exc = e1
     else:
         module = 'either pysqlite2 or sqlite3 modules (tried in that order)'
-    raise ImproperlyConfigured, "Error loading %s: %s" % (module, exc)
+    raise ImproperlyConfigured("Error loading %s: %s" % (module, exc))
 
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal # for Python 2.3
 
 DatabaseError = Database.DatabaseError
 IntegrityError = Database.IntegrityError
@@ -64,13 +64,17 @@
 class DatabaseOperations(BaseDatabaseOperations):
     def date_extract_sql(self, lookup_type, field_name):
         # sqlite doesn't support extract, so we fake it with the user-defined
-        # function django_extract that's registered in connect().
-        return 'django_extract("%s", %s)' % (lookup_type.lower(), field_name)
+        # function django_extract that's registered in connect(). Note that
+        # single quotes are used because this is a string (and could otherwise
+        # cause a collision with a field name).
+        return "django_extract('%s', %s)" % (lookup_type.lower(), field_name)
 
     def date_trunc_sql(self, lookup_type, field_name):
         # sqlite doesn't support DATE_TRUNC, so we fake it with a user-defined
-        # function django_date_trunc that's registered in connect().
-        return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name)
+        # function django_date_trunc that's registered in connect(). Note that
+        # single quotes are used because this is a string (and could otherwise
+        # cause a collision with a field name).
+        return "django_date_trunc('%s', %s)" % (lookup_type.lower(), field_name)
 
     def drop_foreignkey_sql(self):
         return ""
@@ -154,19 +158,19 @@
         self.client = DatabaseClient(self)
         self.creation = DatabaseCreation(self)
         self.introspection = DatabaseIntrospection(self)
-        self.validation = BaseDatabaseValidation()
+        self.validation = BaseDatabaseValidation(self)
 
     def _cursor(self):
         if self.connection is None:
             settings_dict = self.settings_dict
-            if not settings_dict['DATABASE_NAME']:
+            if not settings_dict['NAME']:
                 from django.core.exceptions import ImproperlyConfigured
-                raise ImproperlyConfigured, "Please fill out DATABASE_NAME in the settings module before using the database."
+                raise ImproperlyConfigured("Please fill out the database NAME in the settings module before using the database.")
             kwargs = {
-                'database': settings_dict['DATABASE_NAME'],
+                'database': settings_dict['NAME'],
                 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
             }
-            kwargs.update(settings_dict['DATABASE_OPTIONS'])
+            kwargs.update(settings_dict['OPTIONS'])
             self.connection = Database.connect(**kwargs)
             # Register extract, date_trunc, and regexp functions.
             self.connection.create_function("django_extract", 2, _sqlite_extract)
@@ -179,9 +183,11 @@
         # If database is in memory, closing the connection destroys the
         # database. To prevent accidental data loss, ignore close requests on
         # an in-memory db.
-        if self.settings_dict['DATABASE_NAME'] != ":memory:":
+        if self.settings_dict['NAME'] != ":memory:":
             BaseDatabaseWrapper.close(self)
 
+FORMAT_QMARK_REGEX = re.compile(r'(?![^%])%s')
+
 class SQLiteCursorWrapper(Database.Cursor):
     """
     Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
@@ -189,19 +195,25 @@
     you'll need to use "%%s".
     """
     def execute(self, query, params=()):
-        query = self.convert_query(query, len(params))
-        return Database.Cursor.execute(self, query, params)
+        query = self.convert_query(query)
+        try:
+            return Database.Cursor.execute(self, query, params)
+        except Database.IntegrityError, e:
+            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
+        except Database.DatabaseError, e:
+            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
 
     def executemany(self, query, param_list):
+        query = self.convert_query(query)
         try:
-          query = self.convert_query(query, len(param_list[0]))
-          return Database.Cursor.executemany(self, query, param_list)
-        except (IndexError,TypeError):
-          # No parameter list provided
-          return None
+            return Database.Cursor.executemany(self, query, param_list)
+        except Database.IntegrityError, e:
+            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
+        except Database.DatabaseError, e:
+            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
 
-    def convert_query(self, query, num_params):
-        return query % tuple("?" * num_params)
+    def convert_query(self, query):
+        return FORMAT_QMARK_REGEX.sub('?', query).replace('%%','%')
 
 def _sqlite_extract(lookup_type, dt):
     if dt is None: