From 53222ce9a1a5e56b07286ab317392f41b9c792f1 Mon Sep 17 00:00:00 2001 From: Boulder Sprinters Date: Mon, 6 Nov 2006 07:38:57 +0000 Subject: [PATCH] [boulder-oracle-sprint] Oracle passes most of runtests.py now. git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@4022 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/oracle/query.py | 48 +++++++++++++++++++++++++----- django/db/models/query.py | 28 +++++++---------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/django/db/backends/oracle/query.py b/django/db/backends/oracle/query.py index ed72540632..5ffbb29857 100644 --- a/django/db/backends/oracle/query.py +++ b/django/db/backends/oracle/query.py @@ -1,15 +1,50 @@ from django.db import backend, connection -from django.db.models.query import handle_legacy_orderlist +# TODO: Why the frack can't I just import get_cached_row? +#from django.db.models.query import get_cached_row +from django.db.models.query import handle_legacy_orderlist, orderfield2column from django.utils.datastructures import SortedDict import cx_Oracle as Database +def get_cached_row(klass, row, index_start): + "Helper function that recursively returns an object with cache filled" + index_end = index_start + len(klass._meta.fields) + obj = klass(*row[index_start:index_end]) + for f in klass._meta.fields: + if f.rel and not f.null: + rel_obj, index_end = get_cached_row(f.rel.to, row, index_end) + setattr(obj, f.get_cache_name(), rel_obj) + return obj, index_end + + +def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen): + """ + Helper function that recursively populates the select, tables and where (in + place) for select_related queries. + """ + from django.db.models.fields import AutoField + qn = backend.quote_name + for f in opts.fields: + if f.rel and not f.null: + db_table = f.rel.to._meta.db_table + if db_table not in cache_tables_seen: + tables.append(qn(db_table)) + else: # The table was already seen, so give it a table alias. + new_prefix = '%s%s' % (db_table, len(cache_tables_seen)) + tables.append('%s %s' % (qn(db_table), qn(new_prefix))) + db_table = new_prefix + cache_tables_seen.append(db_table) + where.append('%s.%s = %s.%s' % \ + (qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column))) + select.extend(['%s.%s' % (backend.quote_name(db_table), backend.quote_name(f2.column)) for f2 in f.rel.to._meta.fields if not isinstance(f2, AutoField)]) + fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen) + + def get_query_set_class(DefaultQuerySet): - """ - Create a custom QuerySet class for Oracle. - """ + "Create a custom QuerySet class for Oracle." class OracleQuerySet(DefaultQuerySet): + def iterator(self): "Performs the SELECT database lookup of this QuerySet." @@ -60,7 +95,7 @@ def get_query_set_class(DefaultQuerySet): joins = SortedDict() where = self._where[:] params = self._params[:] - + # Convert self._filters into SQL. joins2, where2, params2 = self._filters.get_sql(opts) joins.update(joins2) @@ -156,6 +191,5 @@ def get_query_set_class(DefaultQuerySet): full_query = None return select, " ".join(sql), params, full_query - - + return OracleQuerySet diff --git a/django/db/models/query.py b/django/db/models/query.py index d49438c525..af5340eaf3 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -5,8 +5,7 @@ from django.db.models import signals from django.dispatch import dispatcher from django.utils.datastructures import SortedDict from django.conf import settings -import operator -import re +import datetime, operator, re # For Python 2.3 if not hasattr(__builtins__, 'set'): @@ -197,10 +196,7 @@ class _QuerySet(object): counter._offset = None counter._limit = None counter._select_related = False - if settings.DATABASE_ENGINE == 'oracle': - select, sql, params, full_query = counter._get_sql_clause() - else: - select, sql, params = counter._get_sql_clause() + select, sql, params = counter._get_sql_clause()[:3] cursor = connection.cursor() if self._distinct: id_col = "%s.%s" % (backend.quote_name(self.model._meta.db_table), @@ -539,10 +535,7 @@ class ValuesQuerySet(QuerySet): field_names = [f.attname for f in self.model._meta.fields] cursor = connection.cursor() - if settings.DATABASE_ENGINE == 'oracle': - select, sql, params, full_query = self._get_sql_clause() - else: - select, sql, params = self._get_sql_clause() + select, sql, params = self._get_sql_clause()[:3] select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) while 1: @@ -655,9 +648,13 @@ def get_where_clause(lookup_type, table_prefix, field_name, value): if table_prefix.endswith('.'): table_prefix = backend.quote_name(table_prefix[:-1])+'.' field_name = backend.quote_name(field_name) - # Put some oracle exceptions here - if lookup_type == "icontains" and settings.DATABASE_ENGINE == 'oracle': - return 'lower(%s%s) %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) + # TODO: move this into django.db.backends.oracle somehow + if settings.DATABASE_ENGINE == 'oracle': + if lookup_type == 'icontains': + return 'lower(%s%s) %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) + elif type(value) == datetime.datetime: + return "%s%s %s" % (table_prefix, field_name, + (backend.OPERATOR_MAPPING[lookup_type] % "TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS')")) try: return '%s%s %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) except KeyError: @@ -703,10 +700,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen) cache_tables_seen.append(db_table) where.append('%s.%s = %s.%s' % \ (qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column))) - if settings.DATABASE_ENGINE == 'oracle': - select.extend(['%s.%s' % (backend.quote_name(db_table), backend.quote_name(f2.column)) for f2 in f.rel.to._meta.fields if not isinstance(f2, AutoField)]) - else: - select.extend(['%s.%s' % (backend.quote_name(db_table), backend.quote_name(f2.column)) for f2 in f.rel.to._meta.fields]) + select.extend(['%s.%s' % (backend.quote_name(db_table), backend.quote_name(f2.column)) for f2 in f.rel.to._meta.fields]) fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen) def parse_lookup(kwarg_items, opts):