|
1 try: |
|
2 # Only exists in Python 2.4+ |
|
3 from threading import local |
|
4 except ImportError: |
|
5 # Import copy of _thread_local.py from Python 2.4 |
|
6 from django.utils._threading_local import local |
|
7 |
|
8 class BaseDatabaseWrapper(local): |
|
9 """ |
|
10 Represents a database connection. |
|
11 """ |
|
12 ops = None |
|
13 def __init__(self, **kwargs): |
|
14 self.connection = None |
|
15 self.queries = [] |
|
16 self.options = kwargs |
|
17 |
|
18 def _commit(self): |
|
19 if self.connection is not None: |
|
20 return self.connection.commit() |
|
21 |
|
22 def _rollback(self): |
|
23 if self.connection is not None: |
|
24 return self.connection.rollback() |
|
25 |
|
26 def close(self): |
|
27 if self.connection is not None: |
|
28 self.connection.close() |
|
29 self.connection = None |
|
30 |
|
31 def cursor(self): |
|
32 from django.conf import settings |
|
33 cursor = self._cursor(settings) |
|
34 if settings.DEBUG: |
|
35 return self.make_debug_cursor(cursor) |
|
36 return cursor |
|
37 |
|
38 def make_debug_cursor(self, cursor): |
|
39 from django.db.backends import util |
|
40 return util.CursorDebugWrapper(cursor, self) |
|
41 |
|
42 class BaseDatabaseFeatures(object): |
|
43 allows_group_by_ordinal = True |
|
44 allows_unique_and_pk = True |
|
45 autoindexes_primary_keys = True |
|
46 inline_fk_references = True |
|
47 needs_datetime_string_cast = True |
|
48 needs_upper_for_iops = False |
|
49 supports_constraints = True |
|
50 supports_tablespaces = False |
|
51 uses_case_insensitive_names = False |
|
52 uses_custom_query_class = False |
|
53 empty_fetchmany_value = [] |
|
54 update_can_self_select = True |
|
55 |
|
56 class BaseDatabaseOperations(object): |
|
57 """ |
|
58 This class encapsulates all backend-specific differences, such as the way |
|
59 a backend performs ordering or calculates the ID of a recently-inserted |
|
60 row. |
|
61 """ |
|
62 def autoinc_sql(self, table, column): |
|
63 """ |
|
64 Returns any SQL needed to support auto-incrementing primary keys, or |
|
65 None if no SQL is necessary. |
|
66 |
|
67 This SQL is executed when a table is created. |
|
68 """ |
|
69 return None |
|
70 |
|
71 def date_extract_sql(self, lookup_type, field_name): |
|
72 """ |
|
73 Given a lookup_type of 'year', 'month' or 'day', returns the SQL that |
|
74 extracts a value from the given date field field_name. |
|
75 """ |
|
76 raise NotImplementedError() |
|
77 |
|
78 def date_trunc_sql(self, lookup_type, field_name): |
|
79 """ |
|
80 Given a lookup_type of 'year', 'month' or 'day', returns the SQL that |
|
81 truncates the given date field field_name to a DATE object with only |
|
82 the given specificity. |
|
83 """ |
|
84 raise NotImplementedError() |
|
85 |
|
86 def datetime_cast_sql(self): |
|
87 """ |
|
88 Returns the SQL necessary to cast a datetime value so that it will be |
|
89 retrieved as a Python datetime object instead of a string. |
|
90 |
|
91 This SQL should include a '%s' in place of the field's name. |
|
92 """ |
|
93 return "%s" |
|
94 |
|
95 def deferrable_sql(self): |
|
96 """ |
|
97 Returns the SQL necessary to make a constraint "initially deferred" |
|
98 during a CREATE TABLE statement. |
|
99 """ |
|
100 return '' |
|
101 |
|
102 def drop_foreignkey_sql(self): |
|
103 """ |
|
104 Returns the SQL command that drops a foreign key. |
|
105 """ |
|
106 return "DROP CONSTRAINT" |
|
107 |
|
108 def drop_sequence_sql(self, table): |
|
109 """ |
|
110 Returns any SQL necessary to drop the sequence for the given table. |
|
111 Returns None if no SQL is necessary. |
|
112 """ |
|
113 return None |
|
114 |
|
115 def field_cast_sql(self, db_type): |
|
116 """ |
|
117 Given a column type (e.g. 'BLOB', 'VARCHAR'), returns the SQL necessary |
|
118 to cast it before using it in a WHERE statement. Note that the |
|
119 resulting string should contain a '%s' placeholder for the column being |
|
120 searched against. |
|
121 """ |
|
122 return '%s' |
|
123 |
|
124 def fulltext_search_sql(self, field_name): |
|
125 """ |
|
126 Returns the SQL WHERE clause to use in order to perform a full-text |
|
127 search of the given field_name. Note that the resulting string should |
|
128 contain a '%s' placeholder for the value being searched against. |
|
129 """ |
|
130 raise NotImplementedError('Full-text search is not implemented for this database backend') |
|
131 |
|
132 def last_executed_query(self, cursor, sql, params): |
|
133 """ |
|
134 Returns a string of the query last executed by the given cursor, with |
|
135 placeholders replaced with actual values. |
|
136 |
|
137 `sql` is the raw query containing placeholders, and `params` is the |
|
138 sequence of parameters. These are used by default, but this method |
|
139 exists for database backends to provide a better implementation |
|
140 according to their own quoting schemes. |
|
141 """ |
|
142 from django.utils.encoding import smart_unicode, force_unicode |
|
143 |
|
144 # Convert params to contain Unicode values. |
|
145 to_unicode = lambda s: force_unicode(s, strings_only=True) |
|
146 if isinstance(params, (list, tuple)): |
|
147 u_params = tuple([to_unicode(val) for val in params]) |
|
148 else: |
|
149 u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()]) |
|
150 |
|
151 return smart_unicode(sql) % u_params |
|
152 |
|
153 def last_insert_id(self, cursor, table_name, pk_name): |
|
154 """ |
|
155 Given a cursor object that has just performed an INSERT statement into |
|
156 a table that has an auto-incrementing ID, returns the newly created ID. |
|
157 |
|
158 This method also receives the table name and the name of the primary-key |
|
159 column. |
|
160 """ |
|
161 return cursor.lastrowid |
|
162 |
|
163 def limit_offset_sql(self, limit, offset=None): |
|
164 """ |
|
165 Returns a LIMIT/OFFSET SQL clause, given a limit and optional offset. |
|
166 """ |
|
167 # 'LIMIT 40 OFFSET 20' |
|
168 sql = "LIMIT %s" % limit |
|
169 if offset and offset != 0: |
|
170 sql += " OFFSET %s" % offset |
|
171 return sql |
|
172 |
|
173 def lookup_cast(self, lookup_type): |
|
174 """ |
|
175 Returns the string to use in a query when performing lookups |
|
176 ("contains", "like", etc). The resulting string should contain a '%s' |
|
177 placeholder for the column being searched against. |
|
178 """ |
|
179 return "%s" |
|
180 |
|
181 def max_name_length(self): |
|
182 """ |
|
183 Returns the maximum length of table and column names, or None if there |
|
184 is no limit. |
|
185 """ |
|
186 return None |
|
187 |
|
188 def no_limit_value(self): |
|
189 """ |
|
190 Returns the value to use for the LIMIT when we are wanting "LIMIT |
|
191 infinity". Returns None if the limit clause can be omitted in this case. |
|
192 """ |
|
193 # FIXME: API may need to change once Oracle backend is repaired. |
|
194 raise NotImplementedError() |
|
195 |
|
196 def pk_default_value(self): |
|
197 """ |
|
198 Returns the value to use during an INSERT statement to specify that |
|
199 the field should use its default value. |
|
200 """ |
|
201 return 'DEFAULT' |
|
202 |
|
203 def query_class(self, DefaultQueryClass): |
|
204 """ |
|
205 Given the default QuerySet class, returns a custom QuerySet class |
|
206 to use for this backend. Returns None if a custom QuerySet isn't used. |
|
207 See also BaseDatabaseFeatures.uses_custom_query_class, which regulates |
|
208 whether this method is called at all. |
|
209 """ |
|
210 return None |
|
211 |
|
212 def quote_name(self, name): |
|
213 """ |
|
214 Returns a quoted version of the given table, index or column name. Does |
|
215 not quote the given name if it's already been quoted. |
|
216 """ |
|
217 raise NotImplementedError() |
|
218 |
|
219 def random_function_sql(self): |
|
220 """ |
|
221 Returns a SQL expression that returns a random value. |
|
222 """ |
|
223 return 'RANDOM()' |
|
224 |
|
225 def regex_lookup(self, lookup_type): |
|
226 """ |
|
227 Returns the string to use in a query when performing regular expression |
|
228 lookups (using "regex" or "iregex"). The resulting string should |
|
229 contain a '%s' placeholder for the column being searched against. |
|
230 |
|
231 If the feature is not supported (or part of it is not supported), a |
|
232 NotImplementedError exception can be raised. |
|
233 """ |
|
234 raise NotImplementedError |
|
235 |
|
236 def sql_flush(self, style, tables, sequences): |
|
237 """ |
|
238 Returns a list of SQL statements required to remove all data from |
|
239 the given database tables (without actually removing the tables |
|
240 themselves). |
|
241 |
|
242 The `style` argument is a Style object as returned by either |
|
243 color_style() or no_style() in django.core.management.color. |
|
244 """ |
|
245 raise NotImplementedError() |
|
246 |
|
247 def sequence_reset_sql(self, style, model_list): |
|
248 """ |
|
249 Returns a list of the SQL statements required to reset sequences for |
|
250 the given models. |
|
251 |
|
252 The `style` argument is a Style object as returned by either |
|
253 color_style() or no_style() in django.core.management.color. |
|
254 """ |
|
255 return [] # No sequence reset required by default. |
|
256 |
|
257 def start_transaction_sql(self): |
|
258 """ |
|
259 Returns the SQL statement required to start a transaction. |
|
260 """ |
|
261 return "BEGIN;" |
|
262 |
|
263 def tablespace_sql(self, tablespace, inline=False): |
|
264 """ |
|
265 Returns the tablespace SQL, or None if the backend doesn't use |
|
266 tablespaces. |
|
267 """ |
|
268 return None |