mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
magic-removal: Moved the rest of django/core/db to django/db/backends
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1636 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
295f00d099
commit
394ad9aa7f
@ -1,32 +0,0 @@
|
|||||||
from time import time
|
|
||||||
|
|
||||||
class CursorDebugWrapper:
|
|
||||||
def __init__(self, cursor, db):
|
|
||||||
self.cursor = cursor
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
def execute(self, sql, params=[]):
|
|
||||||
start = time()
|
|
||||||
result = self.cursor.execute(sql, params)
|
|
||||||
stop = time()
|
|
||||||
self.db.queries.append({
|
|
||||||
'sql': sql % tuple(params),
|
|
||||||
'time': "%.3f" % (stop - start),
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
|
|
||||||
def executemany(self, sql, param_list):
|
|
||||||
start = time()
|
|
||||||
result = self.cursor.executemany(sql, param_list)
|
|
||||||
stop = time()
|
|
||||||
self.db.queries.append({
|
|
||||||
'sql': 'MANY: ' + sql + ' ' + str(tuple(param_list)),
|
|
||||||
'time': "%.3f" % (stop - start),
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
if self.__dict__.has_key(attr):
|
|
||||||
return self.__dict__[attr]
|
|
||||||
else:
|
|
||||||
return getattr(self.cursor, attr)
|
|
@ -1,24 +0,0 @@
|
|||||||
"""
|
|
||||||
Helper functions for dictfetch* for databases that don't natively support them.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _dict_helper(desc, row):
|
|
||||||
"Returns a dictionary for the given cursor.description and result row."
|
|
||||||
return dict([(desc[col[0]][0], col[1]) for col in enumerate(row)])
|
|
||||||
|
|
||||||
def dictfetchone(cursor):
|
|
||||||
"Returns a row from the cursor as a dict"
|
|
||||||
row = cursor.fetchone()
|
|
||||||
if not row:
|
|
||||||
return None
|
|
||||||
return _dict_helper(cursor.description, row)
|
|
||||||
|
|
||||||
def dictfetchmany(cursor, number):
|
|
||||||
"Returns a certain number of rows from a cursor as a dict"
|
|
||||||
desc = cursor.description
|
|
||||||
return [_dict_helper(desc, row) for row in cursor.fetchmany(number)]
|
|
||||||
|
|
||||||
def dictfetchall(cursor):
|
|
||||||
"Returns all rows from a cursor as a dict"
|
|
||||||
desc = cursor.description
|
|
||||||
return [_dict_helper(desc, row) for row in cursor.fetchall()]
|
|
@ -1,54 +0,0 @@
|
|||||||
import datetime
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
# Converters from database (string) to Python #
|
|
||||||
###############################################
|
|
||||||
|
|
||||||
def typecast_date(s):
|
|
||||||
return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null
|
|
||||||
|
|
||||||
def typecast_time(s): # does NOT store time zone information
|
|
||||||
if not s: return None
|
|
||||||
hour, minutes, seconds = s.split(':')
|
|
||||||
if '.' in seconds: # check whether seconds have a fractional part
|
|
||||||
seconds, microseconds = seconds.split('.')
|
|
||||||
else:
|
|
||||||
microseconds = '0'
|
|
||||||
return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))
|
|
||||||
|
|
||||||
def typecast_timestamp(s): # does NOT store time zone information
|
|
||||||
# "2005-07-29 15:48:00.590358-05"
|
|
||||||
# "2005-07-29 09:56:00-05"
|
|
||||||
if not s: return None
|
|
||||||
d, t = s.split()
|
|
||||||
# Extract timezone information, if it exists. Currently we just throw
|
|
||||||
# it away, but in the future we may make use of it.
|
|
||||||
if '-' in t:
|
|
||||||
t, tz = t.split('-', 1)
|
|
||||||
tz = '-' + tz
|
|
||||||
elif '+' in t:
|
|
||||||
t, tz = t.split('+', 1)
|
|
||||||
tz = '+' + tz
|
|
||||||
else:
|
|
||||||
tz = ''
|
|
||||||
dates = d.split('-')
|
|
||||||
times = t.split(':')
|
|
||||||
seconds = times[2]
|
|
||||||
if '.' in seconds: # check whether seconds have a fractional part
|
|
||||||
seconds, microseconds = seconds.split('.')
|
|
||||||
else:
|
|
||||||
microseconds = '0'
|
|
||||||
return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
|
|
||||||
int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000))
|
|
||||||
|
|
||||||
def typecast_boolean(s):
|
|
||||||
if s is None: return None
|
|
||||||
if not s: return False
|
|
||||||
return str(s)[0].lower() == 't'
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
# Converters from Python to database (string) #
|
|
||||||
###############################################
|
|
||||||
|
|
||||||
def rev_typecast_boolean(obj, d):
|
|
||||||
return obj and '1' or '0'
|
|
@ -10,7 +10,7 @@ except ImportError, e:
|
|||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
import os
|
import os
|
||||||
backend_dir = os.path.join(__path__[0], 'backends')
|
backend_dir = os.path.join(__path__[0], 'backends')
|
||||||
available_backends = [f[:-3] for f in os.listdir(backend_dir) if not f.startswith('_')]
|
available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.')]
|
||||||
available_backends.sort()
|
available_backends.sort()
|
||||||
raise ImproperlyConfigured, "Could not load database backend: %s. Is your DATABASE_ENGINE setting (currently, %r) spelled correctly? Available options are: %s" % \
|
raise ImproperlyConfigured, "Could not load database backend: %s. Is your DATABASE_ENGINE setting (currently, %r) spelled correctly? Available options are: %s" % \
|
||||||
(e, DATABASE_ENGINE, ", ".join(map(repr, available_backends)))
|
(e, DATABASE_ENGINE, ", ".join(map(repr, available_backends)))
|
||||||
|
@ -4,8 +4,7 @@ ADO MSSQL database backend for Django.
|
|||||||
Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
|
Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.db import base
|
from django.db.backends import util
|
||||||
from django.core.db.dicthelpers import *
|
|
||||||
import adodbapi as Database
|
import adodbapi as Database
|
||||||
import datetime
|
import datetime
|
||||||
try:
|
try:
|
||||||
@ -82,6 +81,10 @@ class DatabaseWrapper:
|
|||||||
return name # Quoting once is enough.
|
return name # Quoting once is enough.
|
||||||
return '[%s]' % name
|
return '[%s]' % name
|
||||||
|
|
||||||
|
dictfetchone = util.dictfetchone
|
||||||
|
dictfetchmany = util.dictfetchmany
|
||||||
|
dictfetchall = util.dictfetchall
|
||||||
|
|
||||||
def get_last_insert_id(cursor, table_name, pk_name):
|
def get_last_insert_id(cursor, table_name, pk_name):
|
||||||
cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name))
|
cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name))
|
||||||
return cursor.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
@ -151,4 +154,3 @@ DATA_TYPES = {
|
|||||||
'URLField': 'varchar(200)',
|
'URLField': 'varchar(200)',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,7 @@ MySQL database backend for Django.
|
|||||||
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.db import base, typecasts
|
from django.db.backends import util
|
||||||
from django.core.db.dicthelpers import *
|
|
||||||
import MySQLdb as Database
|
import MySQLdb as Database
|
||||||
from MySQLdb.converters import conversions
|
from MySQLdb.converters import conversions
|
||||||
from MySQLdb.constants import FIELD_TYPE
|
from MySQLdb.constants import FIELD_TYPE
|
||||||
@ -15,10 +14,10 @@ DatabaseError = Database.DatabaseError
|
|||||||
|
|
||||||
django_conversions = conversions.copy()
|
django_conversions = conversions.copy()
|
||||||
django_conversions.update({
|
django_conversions.update({
|
||||||
types.BooleanType: typecasts.rev_typecast_boolean,
|
types.BooleanType: util.rev_typecast_boolean,
|
||||||
FIELD_TYPE.DATETIME: typecasts.typecast_timestamp,
|
FIELD_TYPE.DATETIME: util.typecast_timestamp,
|
||||||
FIELD_TYPE.DATE: typecasts.typecast_date,
|
FIELD_TYPE.DATE: util.typecast_date,
|
||||||
FIELD_TYPE.TIME: typecasts.typecast_time,
|
FIELD_TYPE.TIME: util.typecast_time,
|
||||||
})
|
})
|
||||||
|
|
||||||
# This is an extra debug layer over MySQL queries, to display warnings.
|
# This is an extra debug layer over MySQL queries, to display warnings.
|
||||||
@ -66,7 +65,7 @@ class DatabaseWrapper:
|
|||||||
kwargs['port'] = DATABASE_PORT
|
kwargs['port'] = DATABASE_PORT
|
||||||
self.connection = Database.connect(**kwargs)
|
self.connection = Database.connect(**kwargs)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
return base.CursorDebugWrapper(MysqlDebugWrapper(self.connection.cursor()), self)
|
return util.CursorDebugWrapper(MysqlDebugWrapper(self.connection.cursor()), self)
|
||||||
return self.connection.cursor()
|
return self.connection.cursor()
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
@ -89,6 +88,10 @@ class DatabaseWrapper:
|
|||||||
return name # Quoting once is enough.
|
return name # Quoting once is enough.
|
||||||
return "`%s`" % name
|
return "`%s`" % name
|
||||||
|
|
||||||
|
dictfetchone = util.dictfetchone
|
||||||
|
dictfetchmany = util.dictfetchmany
|
||||||
|
dictfetchall = util.dictfetchall
|
||||||
|
|
||||||
def get_last_insert_id(cursor, table_name, pk_name):
|
def get_last_insert_id(cursor, table_name, pk_name):
|
||||||
cursor.execute("SELECT LAST_INSERT_ID()")
|
cursor.execute("SELECT LAST_INSERT_ID()")
|
||||||
return cursor.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
|
@ -4,7 +4,7 @@ PostgreSQL database backend for Django.
|
|||||||
Requires psycopg 1: http://initd.org/projects/psycopg1
|
Requires psycopg 1: http://initd.org/projects/psycopg1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.db import base, typecasts
|
from django.db.backends import util
|
||||||
import psycopg as Database
|
import psycopg as Database
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
@ -34,7 +34,7 @@ class DatabaseWrapper:
|
|||||||
cursor = self.connection.cursor()
|
cursor = self.connection.cursor()
|
||||||
cursor.execute("SET TIME ZONE %s", [TIME_ZONE])
|
cursor.execute("SET TIME ZONE %s", [TIME_ZONE])
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
return base.CursorDebugWrapper(cursor, self)
|
return util.CursorDebugWrapper(cursor, self)
|
||||||
return cursor
|
return cursor
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
@ -93,12 +93,12 @@ def get_random_function_sql():
|
|||||||
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
||||||
# use mx.DateTime by default.
|
# use mx.DateTime by default.
|
||||||
try:
|
try:
|
||||||
Database.register_type(Database.new_type((1082,), "DATE", typecasts.typecast_date))
|
Database.register_type(Database.new_type((1082,), "DATE", util.typecast_date))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise Exception, "You appear to be using psycopg version 2, which isn't supported yet, because it's still in beta. Use psycopg version 1 instead: http://initd.org/projects/psycopg1"
|
raise Exception, "You appear to be using psycopg version 2, which isn't supported yet, because it's still in beta. Use psycopg version 1 instead: http://initd.org/projects/psycopg1"
|
||||||
Database.register_type(Database.new_type((1083,1266), "TIME", typecasts.typecast_time))
|
Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time))
|
||||||
Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", typecasts.typecast_timestamp))
|
Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp))
|
||||||
Database.register_type(Database.new_type((16,), "BOOLEAN", typecasts.typecast_boolean))
|
Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean))
|
||||||
|
|
||||||
OPERATOR_MAPPING = {
|
OPERATOR_MAPPING = {
|
||||||
'exact': '= %s',
|
'exact': '= %s',
|
||||||
|
@ -2,17 +2,16 @@
|
|||||||
SQLite3 backend for django. Requires pysqlite2 (http://pysqlite.org/).
|
SQLite3 backend for django. Requires pysqlite2 (http://pysqlite.org/).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.db import base, typecasts
|
from django.db.backends import util
|
||||||
from django.core.db.dicthelpers import *
|
|
||||||
from pysqlite2 import dbapi2 as Database
|
from pysqlite2 import dbapi2 as Database
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
|
||||||
# Register adaptors ###########################################################
|
# Register adaptors ###########################################################
|
||||||
|
|
||||||
Database.register_converter("bool", lambda s: str(s) == '1')
|
Database.register_converter("bool", lambda s: str(s) == '1')
|
||||||
Database.register_converter("time", typecasts.typecast_time)
|
Database.register_converter("time", util.typecast_time)
|
||||||
Database.register_converter("date", typecasts.typecast_date)
|
Database.register_converter("date", util.typecast_date)
|
||||||
Database.register_converter("datetime", typecasts.typecast_timestamp)
|
Database.register_converter("datetime", util.typecast_timestamp)
|
||||||
|
|
||||||
# Database wrapper ############################################################
|
# Database wrapper ############################################################
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ class DatabaseWrapper:
|
|||||||
cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
|
cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
|
||||||
cursor.row_factory = utf8rowFactory
|
cursor.row_factory = utf8rowFactory
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
return base.CursorDebugWrapper(cursor, self)
|
return util.CursorDebugWrapper(cursor, self)
|
||||||
else:
|
else:
|
||||||
return cursor
|
return cursor
|
||||||
|
|
||||||
@ -60,6 +59,10 @@ class DatabaseWrapper:
|
|||||||
return name # Quoting once is enough.
|
return name # Quoting once is enough.
|
||||||
return '"%s"' % name
|
return '"%s"' % name
|
||||||
|
|
||||||
|
dictfetchone = util.dictfetchone
|
||||||
|
dictfetchmany = util.dictfetchmany
|
||||||
|
dictfetchall = util.dictfetchall
|
||||||
|
|
||||||
class SQLiteCursorWrapper(Database.Cursor):
|
class SQLiteCursorWrapper(Database.Cursor):
|
||||||
"""
|
"""
|
||||||
Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
|
Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
|
||||||
@ -92,7 +95,7 @@ def get_date_extract_sql(lookup_type, table_name):
|
|||||||
|
|
||||||
def _sqlite_extract(lookup_type, dt):
|
def _sqlite_extract(lookup_type, dt):
|
||||||
try:
|
try:
|
||||||
dt = typecasts.typecast_timestamp(dt)
|
dt = util.typecast_timestamp(dt)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return None
|
return None
|
||||||
return str(getattr(dt, lookup_type))
|
return str(getattr(dt, lookup_type))
|
||||||
@ -113,7 +116,7 @@ def get_random_function_sql():
|
|||||||
|
|
||||||
def _sqlite_date_trunc(lookup_type, dt):
|
def _sqlite_date_trunc(lookup_type, dt):
|
||||||
try:
|
try:
|
||||||
dt = typecasts.typecast_timestamp(dt)
|
dt = util.typecast_timestamp(dt)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return None
|
return None
|
||||||
if lookup_type == 'year':
|
if lookup_type == 'year':
|
||||||
|
111
django/db/backends/util.py
Normal file
111
django/db/backends/util.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import datetime
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
class CursorDebugWrapper:
|
||||||
|
def __init__(self, cursor, db):
|
||||||
|
self.cursor = cursor
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
def execute(self, sql, params=[]):
|
||||||
|
start = time()
|
||||||
|
result = self.cursor.execute(sql, params)
|
||||||
|
stop = time()
|
||||||
|
self.db.queries.append({
|
||||||
|
'sql': sql % tuple(params),
|
||||||
|
'time': "%.3f" % (stop - start),
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
def executemany(self, sql, param_list):
|
||||||
|
start = time()
|
||||||
|
result = self.cursor.executemany(sql, param_list)
|
||||||
|
stop = time()
|
||||||
|
self.db.queries.append({
|
||||||
|
'sql': 'MANY: ' + sql + ' ' + str(tuple(param_list)),
|
||||||
|
'time': "%.3f" % (stop - start),
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
if self.__dict__.has_key(attr):
|
||||||
|
return self.__dict__[attr]
|
||||||
|
else:
|
||||||
|
return getattr(self.cursor, attr)
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
# Converters from database (string) to Python #
|
||||||
|
###############################################
|
||||||
|
|
||||||
|
def typecast_date(s):
|
||||||
|
return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null
|
||||||
|
|
||||||
|
def typecast_time(s): # does NOT store time zone information
|
||||||
|
if not s: return None
|
||||||
|
hour, minutes, seconds = s.split(':')
|
||||||
|
if '.' in seconds: # check whether seconds have a fractional part
|
||||||
|
seconds, microseconds = seconds.split('.')
|
||||||
|
else:
|
||||||
|
microseconds = '0'
|
||||||
|
return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))
|
||||||
|
|
||||||
|
def typecast_timestamp(s): # does NOT store time zone information
|
||||||
|
# "2005-07-29 15:48:00.590358-05"
|
||||||
|
# "2005-07-29 09:56:00-05"
|
||||||
|
if not s: return None
|
||||||
|
d, t = s.split()
|
||||||
|
# Extract timezone information, if it exists. Currently we just throw
|
||||||
|
# it away, but in the future we may make use of it.
|
||||||
|
if '-' in t:
|
||||||
|
t, tz = t.split('-', 1)
|
||||||
|
tz = '-' + tz
|
||||||
|
elif '+' in t:
|
||||||
|
t, tz = t.split('+', 1)
|
||||||
|
tz = '+' + tz
|
||||||
|
else:
|
||||||
|
tz = ''
|
||||||
|
dates = d.split('-')
|
||||||
|
times = t.split(':')
|
||||||
|
seconds = times[2]
|
||||||
|
if '.' in seconds: # check whether seconds have a fractional part
|
||||||
|
seconds, microseconds = seconds.split('.')
|
||||||
|
else:
|
||||||
|
microseconds = '0'
|
||||||
|
return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
|
||||||
|
int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000))
|
||||||
|
|
||||||
|
def typecast_boolean(s):
|
||||||
|
if s is None: return None
|
||||||
|
if not s: return False
|
||||||
|
return str(s)[0].lower() == 't'
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
# Converters from Python to database (string) #
|
||||||
|
###############################################
|
||||||
|
|
||||||
|
def rev_typecast_boolean(obj, d):
|
||||||
|
return obj and '1' or '0'
|
||||||
|
|
||||||
|
##################################################################################
|
||||||
|
# Helper functions for dictfetch* for databases that don't natively support them #
|
||||||
|
##################################################################################
|
||||||
|
|
||||||
|
def _dict_helper(desc, row):
|
||||||
|
"Returns a dictionary for the given cursor.description and result row."
|
||||||
|
return dict([(desc[col[0]][0], col[1]) for col in enumerate(row)])
|
||||||
|
|
||||||
|
def dictfetchone(cursor):
|
||||||
|
"Returns a row from the cursor as a dict"
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if not row:
|
||||||
|
return None
|
||||||
|
return _dict_helper(cursor.description, row)
|
||||||
|
|
||||||
|
def dictfetchmany(cursor, number):
|
||||||
|
"Returns a certain number of rows from a cursor as a dict"
|
||||||
|
desc = cursor.description
|
||||||
|
return [_dict_helper(desc, row) for row in cursor.fetchmany(number)]
|
||||||
|
|
||||||
|
def dictfetchall(cursor):
|
||||||
|
"Returns all rows from a cursor as a dict"
|
||||||
|
desc = cursor.description
|
||||||
|
return [_dict_helper(desc, row) for row in cursor.fetchall()]
|
Loading…
x
Reference in New Issue
Block a user