Code

Ticket #225: ado_mssql.py

File ado_mssql.py, 5.0 KB (added by anonymous, 9 years ago)
Line 
1"""
2ADO MSSQL database backend for Django.
3requires adodbapi 2.0.1 from http://adodbapi.sourceforge.net/
4"""
5
6from django.core.db import base
7from django.core.db.dicthelpers import *
8import adodbapi
9try:
10    import mx
11except:
12    mx = None
13import datetime
14DatabaseError = adodbapi.DatabaseError
15
16CSTR = "PROVIDER=SQLOLEDB;DATA SOURCE=%s;UID=%s;PWD=%s;DATABASE=%s"
17
18class Connection(adodbapi.Connection):
19    def cursor(self):
20        return Cursor(self)
21#the connect function in adodbapi must call this Connection
22adodbapi.Connection = Connection 
23
24class Cursor(adodbapi.Cursor):
25    def executeHelper(self, operation, isStoredProcedureCall, parameters=None):
26        if parameters != None and "%s" in operation:
27            operation = operation.replace("%s", "?")
28        adodbapi.Cursor.executeHelper(self, operation, isStoredProcedureCall, parameters)
29       
30origCVtoP = adodbapi.convertVariantToPython
31def variantToPython(variant, adType):
32    if type(variant)==type(True) and adType==11: 
33        return variant  #bool not 1/0
34    res = origCVtoP(variant, adType)
35    if not mx is None and type(res) == mx.DateTime.mxDateTime.DateTimeType:
36        tv = list(res.tuple()[:7])  #if mxdate then datetime
37        tv[-2] = int(tv[-2])    #DepreciationWarning -> int instead of float
38        return datetime.datetime(*tuple(tv))
39
40    if type(res) == type(1.0) and str(res)[-2:]==".0":
41        return int(res)     #if float but int then int
42    return res
43adodbapi.convertVariantToPython = variantToPython
44
45class DatabaseWrapper:
46    def __init__(self):
47        self.connection = None
48        self.queries = []
49
50    def cursor(self):
51        from django.conf.settings import DATABASE_USER, DATABASE_NAME, DATABASE_HOST, DATABASE_PASSWORD, DEBUG
52        if self.connection is None:
53            if DATABASE_NAME == '' or DATABASE_USER == '':
54                from django.core.exceptions import ImproperlyConfigured
55                raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file."
56            if not DATABASE_HOST:
57                DATABASE_HOST = "127.0.0.1"
58            conn_string = CSTR % (DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME)
59           
60            self.connection = adodbapi.connect(conn_string)
61        cursor = self.connection.cursor()
62        if DEBUG:
63            return base.CursorDebugWrapper(cursor, self)
64        return cursor
65
66    def commit(self):
67        return self.connection.commit()
68
69    def rollback(self):
70        if self.connection:
71            return self.connection.rollback()
72
73    def close(self):
74        if self.connection is not None:
75            self.connection.close()
76            self.connection = None
77
78def get_last_insert_id(cursor, table_name, pk_name):
79    cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name))
80    return cursor.fetchone()[0]
81
82# lookup_type is 'year', 'month', 'day'
83def get_date_extract_sql(lookup_type, table_name):
84    return "DATEPART(%s, %s)" % (lookup_type, table_name)
85
86def get_date_trunc_sql(lookup_type, field_name):
87    if lookup_type=='year':
88        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name
89    if lookup_type=='month':
90        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name)
91    if lookup_type=='day':
92        return "Convert(datetime, Convert(varchar(12), %s))" % field_name
93       
94
95OPERATOR_MAPPING = {
96    'exact': '=',
97    'iexact': 'LIKE',
98    'contains': 'LIKE',
99    'icontains': 'LIKE',
100    'ne': '!=',
101    'gt': '>',
102    'gte': '>=',
103    'lt': '<',
104    'lte': '<=',
105    'startswith': 'LIKE',
106    'endswith': 'LIKE',
107    'istartswith': 'LIKE',
108    'iendswith': 'LIKE',
109}
110
111DATA_TYPES = {
112    'AutoField':         'int IDENTITY (1, 1)',
113    'BooleanField':      'bit', 
114    'CharField':         'varchar(%(maxlength)s)',
115    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
116    'DateField':         'smalldatetime',
117    'DateTimeField':     'smalldatetime',
118    'EmailField':        'varchar(75)',
119    'FileField':         'varchar(100)',
120    'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
121    'ImageField':        'varchar(100)',
122    'IntegerField':      'int',
123    'IPAddressField':    'char(15)',
124    'ManyToManyField':   None,
125    'NullBooleanField':  'bit',
126    'OneToOneField':     'int',
127    'PhoneNumberField':  'varchar(20)',
128    'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(name)s] CHECK ([%(name)s] > 0)',
129    'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(name)s] CHECK ([%(name)s] > 0)',
130    'SlugField':         'varchar(50)',
131    'SmallIntegerField': 'smallint',
132    'TextField':         'text',
133    'TimeField':         'time',
134    'URLField':          'varchar(200)',
135    'USStateField':      'varchar(2)',
136    'XMLField':          'text',
137}