Django

Code

Show
Ignore:
Timestamp:
06/25/07 07:47:19 (2 years ago)
Author:
mtredinnick
Message:

unicode: Merged from trunk up to [5530]. Oracle backend has not been ported to
support unicode yet.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/unicode

    • Property svnmerge-integrated changed from /django/trunk:1-5460 to /django/trunk:1-5530
  • django/branches/unicode/django/db/models/base.py

    r5400 r5531  
    100100    def __init__(self, *args, **kwargs): 
    101101        dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs) 
    102          
     102 
    103103        # There is a rather weird disparity here; if kwargs, it's set, then args 
    104         # overrides it. It should be one or the other; don't duplicate the work  
     104        # overrides it. It should be one or the other; don't duplicate the work 
    105105        # The reason for the kwargs check is that standard iterator passes in by 
    106106        # args, and nstantiation for iteration is 33% faster. 
     
    126126                if isinstance(field.rel, ManyToOneRel): 
    127127                    kwargs.pop(field.attname, None) 
    128          
     128 
    129129        # Now we're left with the unprocessed fields that *must* come from 
    130130        # keywords, or default. 
    131          
     131 
    132132        for field in fields_iter: 
    133133            if kwargs: 
     
    151151                                val = getattr(rel_obj, field.rel.get_related_field().attname) 
    152152                            except AttributeError: 
    153                                 raise TypeError("Invalid value: %r should be a %s instance, not a %s" %  
     153                                raise TypeError("Invalid value: %r should be a %s instance, not a %s" % 
    154154                                    (field.name, field.rel.to, type(rel_obj))) 
    155155                else: 
     
    214214        if pk_set: 
    215215            # Determine whether a record with the primary key already exists. 
    216             cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % \ 
    217                 (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), [pk_val]) 
     216            cursor.execute("SELECT COUNT(*) FROM %s WHERE %s=%%s" % \ 
     217                (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), 
     218                self._meta.pk.get_db_prep_lookup('exact', pk_val)) 
    218219            # If it does already exist, do an UPDATE. 
    219             if cursor.fetchone()
     220            if cursor.fetchone()[0] > 0
    220221                db_values = [f.get_db_prep_save(f.pre_save(self, False)) for f in non_pks] 
    221222                if db_values: 
     
    224225                        ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]), 
    225226                        backend.quote_name(self._meta.pk.column)), 
    226                         db_values + [pk_val]
     227                        db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val)
    227228            else: 
    228229                record_exists = False 
  • django/branches/unicode/django/db/models/fields/__init__.py

    r5314 r5531  
    7676        prepopulate_from=None, unique_for_date=None, unique_for_month=None, 
    7777        unique_for_year=None, validator_list=None, choices=None, radio_admin=None, 
    78         help_text='', db_column=None): 
     78        help_text='', db_column=None, db_tablespace=None): 
    7979        self.name = name 
    8080        self.verbose_name = verbose_name 
     
    8282        self.maxlength, self.unique = maxlength, unique 
    8383        self.blank, self.null = blank, null 
     84        # Oracle treats the empty string ('') as null, so coerce the null 
     85        # option whenever '' is a possible value. 
     86        if self.empty_strings_allowed and settings.DATABASE_ENGINE == 'oracle': 
     87            self.null = True 
    8488        self.core, self.rel, self.default = core, rel, default 
    8589        self.editable = editable 
     
    9397        self.help_text = help_text 
    9498        self.db_column = db_column 
     99        self.db_tablespace = db_tablespace 
    95100 
    96101        # Set db_index to True if the field has a relationship and doesn't explicitly set db_index. 
     
    203208                return self.default() 
    204209            return self.default 
    205         if not self.empty_strings_allowed or self.null
     210        if not self.empty_strings_allowed or (self.null and settings.DATABASE_ENGINE != 'oracle')
    206211            return None 
    207212        return "" 
     
    808813 
    809814class NullBooleanField(Field): 
     815    empty_strings_allowed = False 
    810816    def __init__(self, *args, **kwargs): 
    811817        kwargs['null'] = True 
     
    877883 
    878884    def get_db_prep_lookup(self, lookup_type, value): 
     885        if settings.DATABASE_ENGINE == 'oracle': 
     886            # Oracle requires a date in order to parse. 
     887            def prep(value): 
     888                if isinstance(value, datetime.time): 
     889                    value = datetime.datetime.combine(datetime.date(1900, 1, 1), value) 
     890                return smart_unicode(value) 
     891        else: 
     892            prep = smart_unicode 
    879893        if lookup_type == 'range': 
    880             value = [smart_unicode(v) for v in value] 
    881         else: 
    882             value = smart_unicode(value) 
     894            value = [prep(v) for v in value] 
     895        else: 
     896            value = prep(value) 
    883897        return Field.get_db_prep_lookup(self, lookup_type, value) 
    884898 
     
    898912            if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'): 
    899913                value = value.replace(microsecond=0) 
    900             value = smart_unicode(value) 
     914            if settings.DATABASE_ENGINE == 'oracle': 
     915                # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field. 
     916                if isinstance(value, datetime.time): 
     917                    value = datetime.datetime(1900, 1, 1, value.hour, value.minute, 
     918                                              value.second, value.microsecond) 
     919                elif isinstance(value, basestring): 
     920                    value = datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6])) 
     921            else: 
     922                value = smart_unicode(value) 
    901923        return Field.get_db_prep_save(self, value) 
    902924 
  • django/branches/unicode/django/db/models/fields/related.py

    r5230 r5531  
    1212from django.dispatch import dispatcher 
    1313 
    14 # For Python 2.3 
    15 if not hasattr(__builtins__, 'set'): 
    16     from sets import Set as set 
     14try: 
     15    set 
     16except NameError: 
     17    from sets import Set as set   # Python 2.3 fallback 
    1718 
    1819# Values for Relation.edit_inline. 
     
    337338                    target_col_name, ",".join(['%s'] * len(new_ids))), 
    338339                    [self._pk_val] + list(new_ids)) 
    339                 if cursor.rowcount is not None and cursor.rowcount != 0: 
    340                     existing_ids = set([row[0] for row in cursor.fetchmany(cursor.rowcount)]) 
    341                 else: 
    342                     existing_ids = set() 
     340                existing_ids = set([row[0] for row in cursor.fetchall()]) 
    343341 
    344342                # Add the ones that aren't there already 
  • django/branches/unicode/django/db/models/options.py

    r5372 r5531  
    1616DEFAULT_NAMES = ('verbose_name', 'db_table', 'ordering', 
    1717                 'unique_together', 'permissions', 'get_latest_by', 
    18                  'order_with_respect_to', 'app_label'
     18                 'order_with_respect_to', 'app_label', 'db_tablespace'
    1919 
    2020class Options(object): 
     
    3030        self.get_latest_by = None 
    3131        self.order_with_respect_to = None 
     32        self.db_tablespace = None 
    3233        self.admin = None 
    3334        self.meta = meta 
     
    6364 
    6465    def _prepare(self, model): 
     66        from django.db import backend 
     67        from django.db.backends.util import truncate_name 
    6568        if self.order_with_respect_to: 
    6669            self.order_with_respect_to = self.get_field(self.order_with_respect_to) 
     
    7780        if not self.db_table: 
    7881            self.db_table = "%s_%s" % (self.app_label, self.module_name) 
     82            self.db_table = truncate_name(self.db_table, 
     83                                          backend.get_max_name_length()) 
    7984 
    8085    def add_field(self, field): 
  • django/branches/unicode/django/db/models/query.py

    r5399 r5531  
    66from django.utils.encoding import smart_unicode 
    77from django.contrib.contenttypes import generic 
     8import datetime 
    89import operator 
    910import re 
    1011 
    11 # For Python 2.3 
    12 if not hasattr(__builtins__, 'set'): 
    13     from sets import Set as set 
     12try: 
     13    set 
     14except NameError: 
     15    from sets import Set as set   # Python 2.3 fallback 
    1416 
    1517# The string constant used to separate query parts 
     
    7981        return backend.quote_name(word) 
    8082 
    81 class QuerySet(object): 
     83class _QuerySet(object): 
    8284    "Represents a lazy database lookup for a set of objects" 
    8385    def __init__(self, model=None): 
     
    183185        cursor = connection.cursor() 
    184186        cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 
     187 
    185188        fill_cache = self._select_related 
    186         index_end = len(self.model._meta.fields) 
     189        fields = self.model._meta.fields 
     190        index_end = len(fields) 
     191        has_resolve_columns = hasattr(self, 'resolve_columns') 
    187192        while 1: 
    188193            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     
    190195                raise StopIteration 
    191196            for row in rows: 
     197                if has_resolve_columns: 
     198                    row = self.resolve_columns(row, fields) 
    192199                if fill_cache: 
    193200                    obj, index_end = get_cached_row(klass=self.model, row=row, 
     
    553560        return select, " ".join(sql), params 
    554561 
     562# Use the backend's QuerySet class if it defines one, otherwise use _QuerySet. 
     563if hasattr(backend, 'get_query_set_class'): 
     564    QuerySet = backend.get_query_set_class(_QuerySet) 
     565else: 
     566    QuerySet = _QuerySet 
     567 
    555568class ValuesQuerySet(QuerySet): 
    556569    def __init__(self, *args, **kwargs): 
     
    567580        # self._fields is a list of field names to fetch. 
    568581        if self._fields: 
    569             #columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 
    570582            if not self._select: 
    571                 columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 
     583                fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] 
    572584            else: 
    573                 columns = [] 
     585                fields = [] 
    574586                for f in self._fields: 
    575587                    if f in [field.name for field in self.model._meta.fields]: 
    576                         columns.append( self.model._meta.get_field(f, many_to_many=False).column
     588                        fields.append(self.model._meta.get_field(f, many_to_many=False)
    577589                    elif not self._select.has_key( f ): 
    578590                        raise FieldDoesNotExist, '%s has no field named %r' % ( self.model._meta.object_name, f ) 
     
    580592            field_names = self._fields 
    581593        else: # Default to all fields. 
    582             columns = [f.column for f in self.model._meta.fields] 
    583             field_names = [f.attname for f in self.model._meta.fields] 
    584  
     594            fields = self.model._meta.fields 
     595            field_names = [f.attname for f in fields] 
     596 
     597        columns = [f.column for f in fields] 
    585598        select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] 
    586  
    587599        # Add any additional SELECTs. 
    588600        if self._select: 
     
    591603        cursor = connection.cursor() 
    592604        cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 
     605 
     606        has_resolve_columns = hasattr(self, 'resolve_columns') 
    593607        while 1: 
    594608            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     
    596610                raise StopIteration 
    597611            for row in rows: 
     612                if has_resolve_columns: 
     613                    row = self.resolve_columns(row, fields) 
    598614                yield dict(zip(field_names, row)) 
    599615 
     
    606622    def iterator(self): 
    607623        from django.db.backends.util import typecast_timestamp 
     624        from django.db.models.fields import DateTimeField 
    608625        self._order_by = () # Clear this because it'll mess things up otherwise. 
    609626        if self._field.null: 
    610627            self._where.append('%s.%s IS NOT NULL' % \ 
    611628                (backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column))) 
    612  
    613629        try: 
    614630            select, sql, params = self._get_sql_clause() 
     
    616632            raise StopIteration 
    617633 
    618         sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1 %s' % \ 
     634        table_name = backend.quote_name(self.model._meta.db_table) 
     635        field_name = backend.quote_name(self._field.column) 
     636 
     637        if backend.allows_group_by_ordinal: 
     638            group_by = '1' 
     639        else: 
     640            group_by = backend.get_date_trunc_sql(self._kind, 
     641                                                  '%s.%s' % (table_name, field_name)) 
     642 
     643        sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ 
    619644            (backend.get_date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table), 
    620             backend.quote_name(self._field.column))), sql, self._order) 
     645            backend.quote_name(self._field.column))), sql, group_by, self._order) 
    621646        cursor = connection.cursor() 
    622647        cursor.execute(sql, params) 
    623         # We have to manually run typecast_timestamp(str()) on the results, because 
    624         # MySQL doesn't automatically cast the result of date functions as datetime 
    625         # objects -- MySQL returns the values as strings, instead. 
    626         return [typecast_timestamp(str(row[0])) for row in cursor.fetchall()] 
     648 
     649        has_resolve_columns = hasattr(self, 'resolve_columns') 
     650        needs_datetime_string_cast = backend.needs_datetime_string_cast 
     651        dates = [] 
     652        # It would be better to use self._field here instead of DateTimeField(), 
     653        # but in Oracle that will result in a list of datetime.date instead of 
     654        # datetime.datetime. 
     655        fields = [DateTimeField()] 
     656        while 1: 
     657            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     658            if not rows: 
     659                return dates 
     660            for row in rows: 
     661                date = row[0] 
     662                if has_resolve_columns: 
     663                    date = self.resolve_columns([date], fields)[0] 
     664                elif needs_datetime_string_cast: 
     665                    date = typecast_timestamp(str(date)) 
     666                dates.append(date) 
    627667 
    628668    def _clone(self, klass=None, **kwargs): 
     
    732772        table_prefix = backend.quote_name(table_prefix[:-1])+'.' 
    733773    field_name = backend.quote_name(field_name) 
     774    if type(value) == datetime.datetime and backend.get_datetime_cast_sql(): 
     775        cast_sql = backend.get_datetime_cast_sql() 
     776    else: 
     777        cast_sql = '%s' 
     778    if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops: 
     779        format = 'UPPER(%s%s) %s' 
     780    else: 
     781        format = '%s%s %s' 
    734782    try: 
    735         return '%s%s %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) 
     783        return format % (table_prefix, field_name, 
     784                         backend.OPERATOR_MAPPING[lookup_type] % cast_sql) 
    736785    except KeyError: 
    737786        pass