34 if settings.DEBUG: |
57 if settings.DEBUG: |
35 return self.make_debug_cursor(cursor) |
58 return self.make_debug_cursor(cursor) |
36 return cursor |
59 return cursor |
37 |
60 |
38 def make_debug_cursor(self, cursor): |
61 def make_debug_cursor(self, cursor): |
39 from django.db.backends import util |
|
40 return util.CursorDebugWrapper(cursor, self) |
62 return util.CursorDebugWrapper(cursor, self) |
41 |
63 |
42 class BaseDatabaseFeatures(object): |
64 class BaseDatabaseFeatures(object): |
43 allows_group_by_ordinal = True |
65 # True if django.db.backend.utils.typecast_timestamp is used on values |
44 allows_unique_and_pk = True |
66 # returned from dates() calls. |
45 autoindexes_primary_keys = True |
|
46 inline_fk_references = True |
|
47 needs_datetime_string_cast = True |
67 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 |
68 uses_custom_query_class = False |
53 empty_fetchmany_value = [] |
69 empty_fetchmany_value = [] |
54 update_can_self_select = True |
70 update_can_self_select = True |
|
71 interprets_empty_strings_as_nulls = False |
|
72 can_use_chunked_reads = True |
|
73 uses_savepoints = False |
|
74 # If True, don't use integer foreign keys referring to, e.g., positive |
|
75 # integer primary keys. |
|
76 related_fields_match_type = False |
55 |
77 |
56 class BaseDatabaseOperations(object): |
78 class BaseDatabaseOperations(object): |
57 """ |
79 """ |
58 This class encapsulates all backend-specific differences, such as the way |
80 This class encapsulates all backend-specific differences, such as the way |
59 a backend performs ordering or calculates the ID of a recently-inserted |
81 a backend performs ordering or calculates the ID of a recently-inserted |
231 If the feature is not supported (or part of it is not supported), a |
243 If the feature is not supported (or part of it is not supported), a |
232 NotImplementedError exception can be raised. |
244 NotImplementedError exception can be raised. |
233 """ |
245 """ |
234 raise NotImplementedError |
246 raise NotImplementedError |
235 |
247 |
|
248 def savepoint_create_sql(self, sid): |
|
249 """ |
|
250 Returns the SQL for starting a new savepoint. Only required if the |
|
251 "uses_savepoints" feature is True. The "sid" parameter is a string |
|
252 for the savepoint id. |
|
253 """ |
|
254 raise NotImplementedError |
|
255 |
|
256 def savepoint_commit_sql(self, sid): |
|
257 """ |
|
258 Returns the SQL for committing the given savepoint. |
|
259 """ |
|
260 raise NotImplementedError |
|
261 |
|
262 def savepoint_rollback_sql(self, sid): |
|
263 """ |
|
264 Returns the SQL for rolling back the given savepoint. |
|
265 """ |
|
266 raise NotImplementedError |
|
267 |
236 def sql_flush(self, style, tables, sequences): |
268 def sql_flush(self, style, tables, sequences): |
237 """ |
269 """ |
238 Returns a list of SQL statements required to remove all data from |
270 Returns a list of SQL statements required to remove all data from |
239 the given database tables (without actually removing the tables |
271 the given database tables (without actually removing the tables |
240 themselves). |
272 themselves). |
260 """ |
292 """ |
261 return "BEGIN;" |
293 return "BEGIN;" |
262 |
294 |
263 def tablespace_sql(self, tablespace, inline=False): |
295 def tablespace_sql(self, tablespace, inline=False): |
264 """ |
296 """ |
265 Returns the tablespace SQL, or None if the backend doesn't use |
297 Returns the SQL that will be appended to tables or rows to define |
266 tablespaces. |
298 a tablespace. Returns '' if the backend doesn't use tablespaces. |
267 """ |
299 """ |
268 return None |
300 return '' |
|
301 |
|
302 def prep_for_like_query(self, x): |
|
303 """Prepares a value for use in a LIKE query.""" |
|
304 from django.utils.encoding import smart_unicode |
|
305 return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_") |
|
306 |
|
307 # Same as prep_for_like_query(), but called for "iexact" matches, which |
|
308 # need not necessarily be implemented using "LIKE" in the backend. |
|
309 prep_for_iexact_query = prep_for_like_query |
|
310 |
|
311 def value_to_db_date(self, value): |
|
312 """ |
|
313 Transform a date value to an object compatible with what is expected |
|
314 by the backend driver for date columns. |
|
315 """ |
|
316 if value is None: |
|
317 return None |
|
318 return datetime_safe.new_date(value).strftime('%Y-%m-%d') |
|
319 |
|
320 def value_to_db_datetime(self, value): |
|
321 """ |
|
322 Transform a datetime value to an object compatible with what is expected |
|
323 by the backend driver for datetime columns. |
|
324 """ |
|
325 if value is None: |
|
326 return None |
|
327 return unicode(value) |
|
328 |
|
329 def value_to_db_time(self, value): |
|
330 """ |
|
331 Transform a datetime value to an object compatible with what is expected |
|
332 by the backend driver for time columns. |
|
333 """ |
|
334 if value is None: |
|
335 return None |
|
336 return unicode(value) |
|
337 |
|
338 def value_to_db_decimal(self, value, max_digits, decimal_places): |
|
339 """ |
|
340 Transform a decimal.Decimal value to an object compatible with what is |
|
341 expected by the backend driver for decimal (numeric) columns. |
|
342 """ |
|
343 if value is None: |
|
344 return None |
|
345 return util.format_number(value, max_digits, decimal_places) |
|
346 |
|
347 def year_lookup_bounds(self, value): |
|
348 """ |
|
349 Returns a two-elements list with the lower and upper bound to be used |
|
350 with a BETWEEN operator to query a field value using a year lookup |
|
351 |
|
352 `value` is an int, containing the looked-up year. |
|
353 """ |
|
354 first = '%s-01-01 00:00:00' |
|
355 second = '%s-12-31 23:59:59.999999' |
|
356 return [first % value, second % value] |
|
357 |
|
358 def year_lookup_bounds_for_date_field(self, value): |
|
359 """ |
|
360 Returns a two-elements list with the lower and upper bound to be used |
|
361 with a BETWEEN operator to query a DateField value using a year lookup |
|
362 |
|
363 `value` is an int, containing the looked-up year. |
|
364 |
|
365 By default, it just calls `self.year_lookup_bounds`. Some backends need |
|
366 this hook because on their DB date fields can't be compared to values |
|
367 which include a time part. |
|
368 """ |
|
369 return self.year_lookup_bounds(value) |
|
370 |
|
371 class BaseDatabaseIntrospection(object): |
|
372 """ |
|
373 This class encapsulates all backend-specific introspection utilities |
|
374 """ |
|
375 data_types_reverse = {} |
|
376 |
|
377 def __init__(self, connection): |
|
378 self.connection = connection |
|
379 |
|
380 def table_name_converter(self, name): |
|
381 """Apply a conversion to the name for the purposes of comparison. |
|
382 |
|
383 The default table name converter is for case sensitive comparison. |
|
384 """ |
|
385 return name |
|
386 |
|
387 def table_names(self): |
|
388 "Returns a list of names of all tables that exist in the database." |
|
389 cursor = self.connection.cursor() |
|
390 return self.get_table_list(cursor) |
|
391 |
|
392 def django_table_names(self, only_existing=False): |
|
393 """ |
|
394 Returns a list of all table names that have associated Django models and |
|
395 are in INSTALLED_APPS. |
|
396 |
|
397 If only_existing is True, the resulting list will only include the tables |
|
398 that actually exist in the database. |
|
399 """ |
|
400 from django.db import models |
|
401 tables = set() |
|
402 for app in models.get_apps(): |
|
403 for model in models.get_models(app): |
|
404 tables.add(model._meta.db_table) |
|
405 tables.update([f.m2m_db_table() for f in model._meta.local_many_to_many]) |
|
406 if only_existing: |
|
407 tables = [t for t in tables if t in self.table_names()] |
|
408 return tables |
|
409 |
|
410 def installed_models(self, tables): |
|
411 "Returns a set of all models represented by the provided list of table names." |
|
412 from django.db import models |
|
413 all_models = [] |
|
414 for app in models.get_apps(): |
|
415 for model in models.get_models(app): |
|
416 all_models.append(model) |
|
417 return set([m for m in all_models |
|
418 if self.table_name_converter(m._meta.db_table) in map(self.table_name_converter, tables) |
|
419 ]) |
|
420 |
|
421 def sequence_list(self): |
|
422 "Returns a list of information about all DB sequences for all models in all apps." |
|
423 from django.db import models |
|
424 |
|
425 apps = models.get_apps() |
|
426 sequence_list = [] |
|
427 |
|
428 for app in apps: |
|
429 for model in models.get_models(app): |
|
430 for f in model._meta.local_fields: |
|
431 if isinstance(f, models.AutoField): |
|
432 sequence_list.append({'table': model._meta.db_table, 'column': f.column}) |
|
433 break # Only one AutoField is allowed per model, so don't bother continuing. |
|
434 |
|
435 for f in model._meta.local_many_to_many: |
|
436 sequence_list.append({'table': f.m2m_db_table(), 'column': None}) |
|
437 |
|
438 return sequence_list |
|
439 |
|
440 class BaseDatabaseClient(object): |
|
441 """ |
|
442 This class encapsulates all backend-specific methods for opening a |
|
443 client shell. |
|
444 """ |
|
445 # This should be a string representing the name of the executable |
|
446 # (e.g., "psql"). Subclasses must override this. |
|
447 executable_name = None |
|
448 |
|
449 def runshell(self): |
|
450 raise NotImplementedError() |
|
451 |
|
452 class BaseDatabaseValidation(object): |
|
453 """ |
|
454 This class encapsualtes all backend-specific model validation. |
|
455 """ |
|
456 def validate_field(self, errors, opts, f): |
|
457 "By default, there is no backend-specific validation" |
|
458 pass |
|
459 |