Ticket #1261: firebird-svn6654.diff
File firebird-svn6654.diff, 54.3 KB (added by , 17 years ago) |
---|
-
django/db/models/base.py
241 241 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)] 242 242 # If the PK has been manually set, respect that. 243 243 if pk_set: 244 field_names += [f.column for f in self._meta.fields if isinstance(f, AutoField)] 244 if connection.features.quote_autofields: 245 field_names += [qn(f.column) for f in self._meta.fields if isinstance(f, AutoField)] 246 else: 247 field_names += [f.column for f in self._meta.fields if isinstance(f, AutoField)] 245 248 db_values += [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)] 246 249 placeholders = ['%s'] * len(field_names) 247 250 if self._meta.order_with_respect_to: -
django/db/models/fields/__init__.py
148 148 data_types = get_creation_module().DATA_TYPES 149 149 internal_type = self.get_internal_type() 150 150 if internal_type not in data_types: 151 return None 151 return None 152 152 return data_types[internal_type] % self.__dict__ 153 153 154 def db_type_check(self): 155 creation_module = get_creation_module() 156 if hasattr(creation_module, 'DATA_TYPE_CHECKS'): 157 internal_type = self.get_internal_type() 158 data_checks = creation_module.DATA_TYPE_CHECKS 159 if internal_type in data_checks: 160 return data_checks[internal_type] % self.__dict__ 161 return None 162 154 163 def validate_full(self, field_data, all_data): 155 164 """ 156 165 Returns a list of errors for this field. This is the main interface, … … 208 217 return value 209 218 210 219 def get_db_prep_lookup(self, lookup_type, value): 220 from django.db import connection 211 221 "Returns field's value prepared for database lookup." 212 222 if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'): 213 223 return [value] 214 224 elif lookup_type in ('range', 'in'): 215 225 return value 216 226 elif lookup_type in ('contains', 'icontains'): 227 if connection.features.uses_custom_icontains and lookup_type == 'icontains': 228 return [value] 217 229 return ["%%%s%%" % prep_for_like_query(value)] 218 230 elif lookup_type == 'iexact': 219 231 return [prep_for_like_query(value)] 220 232 elif lookup_type in ('startswith', 'istartswith'): 233 if connection.features.uses_custom_startswith: 234 return [value] 221 235 return ["%s%%" % prep_for_like_query(value)] 222 236 elif lookup_type in ('endswith', 'iendswith'): 223 237 return ["%%%s" % prep_for_like_query(value)] … … 589 603 # doesn't support microseconds. 590 604 if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'): 591 605 value = value.replace(microsecond=0) 592 value = smart_unicode(value) 606 #Firebird supports native datetime 607 if settings.DATABASE_ENGINE != 'firebird': 608 value = smart_unicode(value) 593 609 return Field.get_db_prep_save(self, value) 594 610 595 611 def get_db_prep_lookup(self, lookup_type, value): … … 997 1013 # doesn't support microseconds. 998 1014 if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'): 999 1015 value = value.replace(microsecond=0) 1000 if settings.DATABASE_ENGINE == 'oracle':1001 # cx_Oracle expectsa datetime.datetime to persist into TIMESTAMP field.1016 if settings.DATABASE_ENGINE in ('oracle', 'firebird'): 1017 # cx_Oracle and kinterbasdb expect a datetime.datetime to persist into TIMESTAMP field. 1002 1018 if isinstance(value, datetime.time): 1003 1019 value = datetime.datetime(1900, 1, 1, value.hour, value.minute, 1004 1020 value.second, value.microsecond) -
django/db/models/fields/related.py
331 331 new_ids.add(obj) 332 332 # Add the newly created or already existing objects to the join table. 333 333 # First find out which items are already added, to avoid adding them twice 334 qn = connection.ops.quote_name 334 335 cursor = connection.cursor() 335 336 cursor.execute("SELECT %s FROM %s WHERE %s = %%s AND %s IN (%s)" % \ 336 ( target_col_name, self.join_table, source_col_name,337 target_col_name, ",".join(['%s'] * len(new_ids))),337 (qn(target_col_name), qn(self.join_table), qn(source_col_name), 338 qn(target_col_name), ",".join(['%s'] * len(new_ids))), 338 339 [self._pk_val] + list(new_ids)) 339 340 existing_ids = set([row[0] for row in cursor.fetchall()]) 340 341 341 342 # Add the ones that aren't there already 342 343 for obj_id in (new_ids - existing_ids): 343 344 cursor.execute("INSERT INTO %s (%s, %s) VALUES (%%s, %%s)" % \ 344 ( self.join_table, source_col_name, target_col_name),345 (qn(self.join_table), qn(source_col_name), qn(target_col_name)), 345 346 [self._pk_val, obj_id]) 346 347 transaction.commit_unless_managed() 347 348 -
django/db/models/query.py
1111 1111 # Last query term was a normal field. 1112 1112 column = field.column 1113 1113 db_type = field.db_type() 1114 1114 if settings.DATABASE_ENGINE == 'firebird': 1115 current_table = qn(current_table) 1116 column = qn(column) 1115 1117 where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type)) 1116 1118 params.extend(field.get_db_prep_lookup(lookup_type, value)) 1117 1119 … … 1146 1148 if isinstance(f, generic.GenericRelation): 1147 1149 from django.contrib.contenttypes.models import ContentType 1148 1150 query_extra = 'AND %s=%%s' % f.rel.to._meta.get_field(f.content_type_field_name).column 1151 if settings.DATABASE_ENGINE == 'firebird': 1152 query_extra = 'AND %s=%%s' % qn(f.rel.to._meta.get_field(f.content_type_field_name).column) 1149 1153 args_extra = [ContentType.objects.get_for_model(cls).id] 1150 1154 else: 1151 1155 query_extra = '' -
django/db/backends/__init__.py
45 45 autoindexes_primary_keys = True 46 46 inline_fk_references = True 47 47 needs_datetime_string_cast = True 48 needs_default_null = False 48 49 needs_upper_for_iops = False 49 50 supports_constraints = True 50 51 supports_tablespaces = False 52 quote_autofields = False 51 53 uses_case_insensitive_names = False 54 uses_custom_icontains = False 55 uses_custom_startswith = False 52 56 uses_custom_queryset = False 53 57 54 58 class BaseDatabaseOperations(object): … … 65 69 This SQL is executed when a table is created. 66 70 """ 67 71 return None 68 72 73 def cascade_delete_update_sql(self): 74 """ 75 Returns the SQL necessary to make a cascading deletes and updates 76 of foreign key references during a CREATE TABLE statement. 77 """ 78 return '' 79 69 80 def date_extract_sql(self, lookup_type, field_name): 70 81 """ 71 82 Given a lookup_type of 'year', 'month' or 'day', returns the SQL that -
django/db/backends/firebird/base.py
1 """ 2 Firebird database backend for Django. 3 4 Requires KInterbasDB 3.2: http://kinterbasdb.sourceforge.net/ 5 The egenix mx (mx.DateTime) is NOT required 6 7 Database charset should be UNICODE_FSS or UTF8 (FireBird 2.0+) 8 To use UTF8 encoding add FIREBIRD_CHARSET = 'UTF8' to your settings.py 9 UNICODE_FSS works with all versions and uses less memory 10 """ 11 12 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util 13 14 try: 15 import kinterbasdb as Database 16 except ImportError, e: 17 from django.core.exceptions import ImproperlyConfigured 18 raise ImproperlyConfigured, "Error loading KInterbasDB module: %s" % e 19 20 DatabaseError = Database.DatabaseError 21 IntegrityError = Database.IntegrityError 22 23 class DatabaseFeatures(BaseDatabaseFeatures): 24 needs_datetime_string_cast = False 25 needs_default_null = True 26 needs_upper_for_iops = True 27 quote_autofields = True 28 supports_constraints = False #some tests went strange without it 29 uses_custom_icontains = True #CONTAINING <value> op instead of LIKE %<value>% 30 uses_custom_startswith = True #STARTING WITH op. Faster than LIKE 31 uses_custom_queryset = True 32 33 class DatabaseOperations(BaseDatabaseOperations): 34 _max_name_length = 27 35 def __init__(self): 36 self._firebird_version = None 37 self._page_size = None 38 39 def get_generator_name(self, name): 40 return '%s_G' % util.truncate_name(name, self._max_name_length-2).upper() 41 42 def get_trigger_name(self, name): 43 return '%s_T' % util.truncate_name(name, self._max_name_length-2).upper() 44 45 def _get_firebird_version(self): 46 if self._firebird_version is None: 47 from django.db import connection 48 self._firebird_version = [int(val) for val in connection.server_version.split()[-1].split('.')] 49 return self._firebird_version 50 firebird_version = property(_get_firebird_version) 51 52 def _get_page_size(self): 53 if self._page_size is None: 54 from django.db import connection 55 self._page_size = connection.database_info(Database.isc_info_page_size, 'i') 56 return self._page_size 57 page_size = property(_get_page_size) 58 59 def _get_index_limit(self): 60 if self.firebird_version[0] < 2: 61 self._index_limit = 252 62 else: 63 page_size = self.page_size 64 self._index_limit = page_size/4 65 return self._index_limit 66 index_limit = property(_get_index_limit) 67 68 def _autoinc_sql_with_style(self, style, table_name, column_name): 69 """ 70 To simulate auto-incrementing primary keys in Firebird, we have to 71 create a generator and a trigger. 72 73 Create the generators and triggers names based only on table name 74 since django only support one auto field per model 75 """ 76 77 KWD = style.SQL_KEYWORD 78 TBL = style.SQL_TABLE 79 FLD = style.SQL_FIELD 80 81 generator_name = self.get_generator_name(table_name) 82 trigger_name = self.get_trigger_name(table_name) 83 column_name = self.quote_name(column_name) 84 table_name = self.quote_name(table_name) 85 86 generator_sql = "%s %s;" % ( KWD('CREATE GENERATOR'), 87 TBL(generator_name)) 88 trigger_sql = "\n".join([ 89 "%s %s %s %s" % ( \ 90 KWD('CREATE TRIGGER'), TBL(trigger_name), KWD('FOR'), 91 TBL(table_name)), 92 "%s 0 %s" % (KWD('ACTIVE BEFORE INSERT POSITION'), KWD('AS')), 93 KWD('BEGIN'), 94 " %s ((%s.%s %s) %s (%s.%s = 0)) %s" % ( \ 95 KWD('IF'), 96 KWD('NEW'), FLD(column_name), KWD('IS NULL'), 97 KWD('OR'), KWD('NEW'), FLD(column_name), 98 KWD('THEN') 99 ), 100 " %s" % KWD('BEGIN'), 101 " %s.%s = %s(%s, 1);" % ( \ 102 KWD('NEW'), FLD(column_name), 103 KWD('GEN_ID'), TBL(generator_name) 104 ), 105 " %s" % KWD('END'), 106 KWD('END') 107 ]) 108 return (generator_sql, trigger_sql) 109 110 def autoinc_sql(self, table_name, column_name): 111 # style argument disappeared, so we'll just import django's dummy 112 from django.core.management.color import no_style, color_style 113 return self._autoinc_sql_with_style(no_style(), table_name, column_name) 114 115 def max_name_length(self): 116 return self._max_name_length 117 118 def query_set_class(this, DefaultQuerySet): 119 from django.db import connection 120 from django.db.models.query import EmptyResultSet, GET_ITERATOR_CHUNK_SIZE, quote_only_if_word 121 122 class FirebirdQuerySet(DefaultQuerySet): 123 def _get_sql_clause(self): 124 from django.db.models.query import SortedDict, handle_legacy_orderlist, orderfield2column, fill_table_cache 125 qn = connection.ops.quote_name 126 opts = self.model._meta 127 128 # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. 129 select = ["%s.%s" % (qn(opts.db_table), qn(f.column)) for f in opts.fields] 130 tables = [qn(t) for t in self._tables] 131 joins = SortedDict() 132 where = self._where[:] 133 params = self._params[:] 134 135 # Convert self._filters into SQL. 136 joins2, where2, params2 = self._filters.get_sql(opts) 137 joins.update(joins2) 138 where.extend(where2) 139 params.extend(params2) 140 141 # Add additional tables and WHERE clauses based on select_related. 142 if self._select_related: 143 fill_table_cache(opts, select, tables, where, 144 old_prefix=opts.db_table, 145 cache_tables_seen=[opts.db_table], 146 max_depth=self._max_related_depth) 147 148 # Add any additional SELECTs. 149 if self._select: 150 select.extend([('(%s AS %s') % (qn(s[1]), qn(s[0])) for s in self._select.items()]) 151 152 # Start composing the body of the SQL statement. 153 sql = [" FROM", qn(opts.db_table)] 154 155 # Compose the join dictionary into SQL describing the joins. 156 if joins: 157 sql.append(" ".join(["%s %s %s ON %s" % (join_type, table, alias, condition) 158 for (alias, (table, join_type, condition)) in joins.items()])) 159 160 # Compose the tables clause into SQL. 161 if tables: 162 sql.append(", " + ", ".join(tables)) 163 164 # Compose the where clause into SQL. 165 if where: 166 sql.append(where and "WHERE " + " AND ".join(where)) 167 168 # ORDER BY clause 169 order_by = [] 170 if self._order_by is not None: 171 ordering_to_use = self._order_by 172 else: 173 ordering_to_use = opts.ordering 174 for f in handle_legacy_orderlist(ordering_to_use): 175 if f == '?': # Special case. 176 order_by.append(connection.ops.random_function_sql()) 177 else: 178 if f.startswith('-'): 179 col_name = f[1:] 180 order = "DESC" 181 else: 182 col_name = f 183 order = "ASC" 184 if "." in col_name: 185 table_prefix, col_name = col_name.split('.', 1) 186 table_prefix = qn(table_prefix) + '.' 187 else: 188 # Use the database table as a column prefix if it wasn't given, 189 # and if the requested column isn't a custom SELECT. 190 if "." not in col_name and col_name not in (self._select or ()): 191 table_prefix = qn(opts.db_table) + '.' 192 else: 193 table_prefix = '' 194 order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order)) 195 if order_by: 196 sql.append("ORDER BY " + ", ".join(order_by)) 197 198 return select, " ".join(sql), params 199 200 def iterator(self): 201 "Performs the SELECT database lookup of this QuerySet." 202 from django.db.models.query import get_cached_row 203 204 try: 205 select, sql, params = self._get_sql_clause() 206 except EmptyResultSet: 207 raise StopIteration 208 209 # self._select is a dictionary, and dictionaries' key order is 210 # undefined, so we convert it to a list of tuples. 211 extra_select = self._select.items() 212 213 cursor = connection.cursor() 214 limit_offset_before = "" 215 if self._limit is not None: 216 limit_offset_before += "FIRST %s " % self._limit 217 if self._offset: 218 limit_offset_before += "SKIP %s " % self._offset 219 else: 220 assert self._offset is None, "'offset' is not allowed without 'limit'" 221 cursor.execute("SELECT " + limit_offset_before + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 222 fill_cache = self._select_related 223 fields = self.model._meta.fields 224 index_end = len(fields) 225 while 1: 226 rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 227 if not rows: 228 raise StopIteration 229 for row in rows: 230 row = self.resolve_columns(row, fields) 231 if fill_cache: 232 obj, index_end = get_cached_row(klass=self.model, row=row, 233 index_start=0, max_depth=self._max_related_depth) 234 else: 235 obj = self.model(*row[:index_end]) 236 for i, k in enumerate(extra_select): 237 setattr(obj, k[0], row[index_end+i]) 238 yield obj 239 240 def resolve_columns(self, row, fields=()): 241 from django.db.models.fields import DateField, DateTimeField, \ 242 TimeField, BooleanField, NullBooleanField, DecimalField, Field 243 values = [] 244 for value, field in map(None, row, fields): 245 #if value is None and isinstance(field, Field) and field.empty_strings_allowed: 246 # value = u'' 247 # Convert 1 or 0 to True or False 248 if value in (1, 0) and isinstance(field, (BooleanField, NullBooleanField)): 249 value = bool(value) 250 251 values.append(value) 252 return values 253 254 return FirebirdQuerySet 255 256 def quote_name(self, name): 257 # Trancate and quote once. No need for uppercase since 258 # we quote autofields too 259 if not name.startswith('"') and not name.endswith('"'): 260 name = '"%s"' % util.truncate_name(name, self._max_name_length) 261 return name 262 263 def field_cast_sql(self, db_type): 264 return '%s' 265 266 def last_insert_id(self, cursor, table_name, pk_name): 267 generator_name = self.get_generator_name(table_name) 268 cursor.execute('SELECT GEN_ID(%s, 0) from RDB$DATABASE' % generator_name) 269 return cursor.fetchone()[0] 270 271 def date_extract_sql(self, lookup_type, column_name): 272 # lookup_type is 'year', 'month', 'day' 273 return "EXTRACT(%s FROM %s)" % (lookup_type, column_name) 274 275 def date_trunc_sql(self, lookup_type, column_name): 276 if lookup_type == 'year': 277 sql = "EXTRACT(year FROM %s)||'-01-01 00:00:00'" % column_name 278 elif lookup_type == 'month': 279 sql = "EXTRACT(year FROM %s)||'-'||EXTRACT(month FROM %s)||'-01 00:00:00'" % (column_name, column_name) 280 elif lookup_type == 'day': 281 sql = "EXTRACT(year FROM %s)||'-'||EXTRACT(month FROM %s)||'-'||EXTRACT(day FROM %s)||' 00:00:00'" % (column_name, column_name, column_name) 282 return "CAST(%s AS TIMESTAMP)" % sql 283 284 def cascade_delete_update_sql(self): 285 # Solves FK problems with sql_flush 286 return " ON DELETE CASCADE ON UPDATE CASCADE" 287 288 def datetime_cast_sql(self): 289 return None 290 291 def limit_offset_sql(self, limit, offset=None): 292 # limits are handled in custom FirebirdQuerySet 293 assert False, 'Limits are handled in a different way in Firebird' 294 return "" 295 296 def random_function_sql(self): 297 return "rand()" 298 299 def pk_default_value(self): 300 return "NULL" 301 302 def start_transaction_sql(self): 303 return "START TRANSACTION;" 304 305 def sequence_reset_sql(self, style, model_list): 306 from django.db import models 307 output = [] 308 sql = """\ 309 CREATE OR ALTER PROCEDURE "GENERATOR_RESET" AS 310 DECLARE VARIABLE start_val integer; 311 DECLARE VARIABLE gen_val integer; 312 BEGIN 313 SELECT MAX(%(col)s) FROM %(table)s INTO :start_val; 314 IF (start_val IS NULL) THEN 315 gen_val = GEN_ID(%(gen)s, 1 - GEN_ID(%(gen)s, 0)); 316 ELSE 317 gen_val = GEN_ID(%(gen)s, start_val - GEN_ID(%(gen)s, 0)); 318 EXIT; 319 END;""" 320 for model in model_list: 321 for f in model._meta.fields: 322 if isinstance(f, models.AutoField): 323 generator_name = self.get_generator_name(model._meta.db_table) 324 column_name = self.quote_name(f.db_column or f.name) 325 table_name = self.quote_name(model._meta.db_table) 326 output.append(sql % {'col' : column_name, 'table' : table_name, 'gen' : generator_name}) 327 output.append('EXECUTE PROCEDURE "GENERATOR_RESET";') 328 break # Only one AutoField is allowed per model, so don't bother continuing. 329 for f in model._meta.many_to_many: 330 generator_name = self.get_generator_name(f.m2m_db_table()) 331 table_name = self.quote_name(f.m2m_db_table()) 332 column_name = '"id"' 333 output.append(sql % {'col' : column_name, 'table' : table_name, 'gen' : generator_name}) 334 output.append('EXECUTE PROCEDURE "GENERATOR_RESET";') 335 return output 336 337 def sql_flush(self, style, tables, sequences): 338 if tables: 339 # FK constraints gave us a lot of trouble with default values 340 # that was a reason behind very ugly and dangerous code here 341 # Solved with "ON DELETE CASCADE" with all FK references 342 sql = ['%s %s %s;' % \ 343 (style.SQL_KEYWORD('DELETE'), 344 style.SQL_KEYWORD('FROM'), 345 style.SQL_FIELD(self.quote_name(table)) 346 ) for table in tables] 347 for generator_info in sequences: 348 table_name = generator_info['table'] 349 query = "SET GENERATOR %s TO 0;" % self.get_generator_name(table_name) 350 sql.append(query) 351 return sql 352 else: 353 return [] 354 355 # def fulltext_search_sql(self, field_name): 356 # return field_name + ' CONTAINING %s' 357 358 def drop_sequence_sql(self, table): 359 return "DROP GENERATOR %s;" % self.get_generator_name(table) 360 361 def last_executed_query(self, cursor, sql, params): 362 """ 363 Returns a string of the query last executed by the given cursor, with 364 placeholders replaced with actual values. 365 366 `sql` is the raw query containing placeholders, and `params` is the 367 sequence of parameters. These are used by default, but this method 368 exists for database backends to provide a better implementation 369 according to their own quoting schemes. 370 """ 371 from django.utils.encoding import smart_unicode, force_unicode 372 373 # Convert params to contain Unicode values. 374 to_unicode = lambda s: force_unicode(s, strings_only=True) 375 if isinstance(params, (list, tuple)): 376 u_params = tuple([to_unicode(val) for val in params]) 377 else: 378 u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()]) 379 try: 380 #Extracts sql right from KInterbasDB's prepared statement 381 return smart_unicode(cursor.query) % u_params 382 except TypeError: 383 return smart_unicode(sql) % u_params 384 385 class FirebirdCursorWrapper(object): 386 """ 387 Django uses "format" ('%s') style placeholders, but firebird uses "qmark" ('?') style. 388 This fixes it -- but note that if you want to use a literal "%s" in a query, 389 you'll need to use "%%s". 390 391 We also do all automatic type conversions here. 392 """ 393 import kinterbasdb.typeconv_datetime_stdlib as tc_dt 394 import kinterbasdb.typeconv_fixed_decimal as tc_fd 395 import kinterbasdb.typeconv_text_unicode as tc_tu 396 import django.utils.encoding as dj_ue 397 398 def timestamp_conv_in(self, timestamp): 399 if isinstance(timestamp, basestring): 400 #Replaces 6 digits microseconds to 4 digits allowed in Firebird 401 timestamp = timestamp[:24] 402 return self.tc_dt.timestamp_conv_in(timestamp) 403 404 def time_conv_in(self, value): 405 import datetime 406 if isinstance(value, datetime.datetime): 407 value = datetime.time(value.hour, value.minute, value.second, value.microsecond) 408 return self.tc_dt.time_conv_in(value) 409 410 def ascii_conv_in(self, text): 411 return self.dj_ue.smart_str(text, 'ascii') 412 413 def unicode_conv_in(self, text): 414 return self.tc_tu.unicode_conv_in((self.dj_ue.force_unicode(text[0]), self.FB_CHARSET_CODE)) 415 416 def blob_conv_in(self, text): 417 return self.tc_tu.unicode_conv_in((self.dj_ue.force_unicode(text), self.FB_CHARSET_CODE)) 418 419 def blob_conv_out(self, text): 420 return self.tc_tu.unicode_conv_out((text, self.FB_CHARSET_CODE)) 421 422 def __init__(self, cursor): 423 from django.conf import settings 424 self.FB_CHARSET_CODE = 3 #UNICODE_FSS 425 if hasattr(settings, 'FIREBIRD_CHARSET'): 426 if settings.FIREBIRD_CHARSET == 'UTF8': 427 self.FB_CHARSET_CODE = 4 # UTF-8 with Firebird 2.0+ 428 self.cursor = cursor 429 430 # Prepared Statement 431 # http://kinterbasdb.sourceforge.net/dist_docs/usage.html#adv_prepared_statements 432 # Need to decide wether they are useful or not 433 # Maybe add prepare, execute_prep and executemany_pep methods here 434 # and rewrite QuerySet to take advantage of them? 435 # Could speed the things up 436 self._statement = None 437 self.cursor.set_type_trans_in({ 438 'DATE': self.tc_dt.date_conv_in, 439 'TIME': self.time_conv_in, 440 'TIMESTAMP': self.timestamp_conv_in, 441 'FIXED': self.tc_fd.fixed_conv_in_imprecise, 442 'TEXT': self.ascii_conv_in, 443 'TEXT_UNICODE': self.unicode_conv_in, 444 'BLOB': self.blob_conv_in 445 }) 446 self.cursor.set_type_trans_out({ 447 'DATE': self.tc_dt.date_conv_out, 448 'TIME': self.tc_dt.time_conv_out, 449 'TIMESTAMP': self.tc_dt.timestamp_conv_out, 450 'FIXED': self.tc_fd.fixed_conv_out_imprecise, 451 'TEXT': self.dj_ue.force_unicode, 452 'TEXT_UNICODE': self.tc_tu.unicode_conv_out, 453 'BLOB': self.blob_conv_out 454 }) 455 456 def _get_query(self): 457 if self._statement: 458 return self._statement.sql 459 def _get_statement(self): 460 if self._statement: 461 return self._statement 462 query = property(_get_query) 463 statement = property(_get_statement) 464 465 def execute(self, query, params=()): 466 cquery = self.convert_query(query, len(params)) 467 if self._get_query() != cquery: 468 try: 469 self._statement = self.cursor.prep(cquery) 470 except Database.ProgrammingError, e: 471 output = ["Error preparing query."] 472 output.extend(str(e).split(', ')[1].strip("'").split('\\n')) 473 output.append("\nThe problem query was:") 474 output.append(query % params) 475 raise DatabaseError, "\n".join(output) 476 try: 477 return self.cursor.execute(self._statement, params) 478 except Database.ProgrammingError, e: 479 err_no = int(str(e).split()[0].strip(',()')) 480 output = ["Error executing query. FB error No. %i" % err_no] 481 output.extend(str(e).split(', ')[1].strip("'").split('\\n')) 482 #e.append(err_no) 483 output.append("\nThe problem query was:") 484 output.append(query % params) 485 raise DatabaseError, "\n".join(output) 486 487 def executemany(self, query, param_list): 488 try: 489 cquery = self.convert_query(query, len(param_list[0])) 490 except IndexError: 491 return None 492 if self._get_query() != cquery: 493 self._statement = self.cursor.prep(cquery) 494 return self.cursor.executemany(self._statement, param_list) 495 496 def convert_query(self, query, num_params): 497 try: 498 return query % tuple("?" * num_params) 499 except TypeError, e: 500 print query, num_params 501 raise TypeError, e 502 503 def __getattr__(self, attr): 504 if attr in self.__dict__: 505 return self.__dict__[attr] 506 else: 507 return getattr(self.cursor, attr) 508 509 class DatabaseWrapper(BaseDatabaseWrapper): 510 features = DatabaseFeatures() 511 ops = DatabaseOperations() 512 operators = { 513 'exact': '= %s', 514 'iexact': '= UPPER(%s)', 515 'contains': "LIKE %s ESCAPE'\\'", 516 'icontains': 'CONTAINING %s', #case is ignored 517 'gt': '> %s', 518 'gte': '>= %s', 519 'lt': '< %s', 520 'lte': '<= %s', 521 'startswith': 'STARTING WITH %s', #looks to be faster then LIKE 522 'endswith': "LIKE %s ESCAPE'\\'", 523 'istartswith': 'STARTING WITH UPPER(%s)', 524 'iendswith': "LIKE UPPER(%s) ESCAPE'\\'", 525 } 526 _current_cursor = None 527 def _connect(self, settings): 528 if settings.DATABASE_NAME == '': 529 from django.core.exceptions import ImproperlyConfigured 530 raise ImproperlyConfigured, "You need to specify DATABASE_NAME in your Django settings file." 531 charset = 'UNICODE_FSS' 532 if hasattr(settings, 'FIREBIRD_CHARSET'): 533 if settings.FIREBIRD_CHARSET == 'UTF8': 534 charset = 'UTF8' 535 kwargs = {'charset' : charset } 536 if settings.DATABASE_HOST: 537 kwargs['dsn'] = "%s:%s" % (settings.DATABASE_HOST, settings.DATABASE_NAME) 538 else: 539 kwargs['dsn'] = "localhost:%s" % settings.DATABASE_NAME 540 if settings.DATABASE_USER: 541 kwargs['user'] = settings.DATABASE_USER 542 if settings.DATABASE_PASSWORD: 543 kwargs['password'] = settings.DATABASE_PASSWORD 544 self.connection = Database.connect(**kwargs) 545 assert self.charset == charset 546 try: 547 self.connection.execute_immediate(""" 548 DECLARE EXTERNAL FUNCTION rand 549 RETURNS DOUBLE PRECISION 550 BY VALUE ENTRY_POINT 'IB_UDF_rand' MODULE_NAME 'ib_udf'; 551 """) 552 except Database.ProgrammingError: 553 pass #Already defined 554 555 556 557 def cursor(self, name=None): 558 #Cursors can be named 559 #http://kinterbasdb.sourceforge.net/dist_docs/usage.html#adv_named_cursors 560 #and maybe useful for scrolling updates and deletes 561 from django.conf import settings 562 cursor = self._cursor(settings, name) 563 if settings.DEBUG: 564 return self.make_debug_cursor(cursor) 565 return cursor 566 567 def _cursor(self, settings, name): 568 if self.connection is None: 569 self._connect(settings) 570 cursor = self.connection.cursor() 571 if name: 572 cursor.name = name 573 cursor = FirebirdCursorWrapper(cursor) 574 self._current_cursor = cursor 575 return cursor 576 577 #Returns query from prepared statement 578 def _get_query(self): 579 if self._current_cursor: 580 return self._current_cursor.query 581 query = property(_get_query) 582 #Returns prepared statement itself 583 def _get_statement(self): 584 if self._current_cursor: 585 return self._current_cursor.statement 586 statement = property(_get_statement) 587 588 589 def __getattr__(self, attr): 590 if attr in self.__dict__: 591 return self.__dict__[attr] 592 else: 593 return getattr(self.connection, attr) 594 595 -
django/db/backends/firebird/client.py
1 from django.conf import settings 2 import os 3 4 def runshell(): 5 args = [settings.DATABASE_NAME] 6 args += ["-u %s" % settings.DATABASE_USER] 7 if settings.DATABASE_PASSWORD: 8 args += ["-p %s" % settings.DATABASE_PASSWORD] 9 if 'FIREBIRD' not in os.environ: 10 path = '/opt/firebird/bin/' 11 os.system(path + 'isql ' + ' '.join(args)) -
django/db/backends/firebird/introspection.py
1 from django.db import transaction 2 from django.db.backends.firebird.base import DatabaseOperations 3 4 quote_name = DatabaseOperations().quote_name 5 6 def get_table_list(cursor): 7 "Returns a list of table names in the current database." 8 cursor.execute(""" 9 SELECT rdb$relation_name FROM rdb$relations 10 WHERE rdb$system_flag = 0 AND rdb$view_blr IS NULL ORDER BY rdb$relation_name""") 11 return [str(row[0].strip().lower()) for row in cursor.fetchall()] 12 13 def get_table_description(cursor, table_name): 14 "Returns a description of the table, with the DB-API cursor.description interface." 15 #cursor.execute("SELECT FIRST 1 * FROM %s" % quote_name(table_name)) 16 #return cursor.description 17 # (name, type_code, display_size, internal_size, precision, scale, null_ok) 18 cursor.execute(""" 19 SELECT DISTINCT R.RDB$FIELD_NAME AS FNAME, 20 F.RDB$FIELD_TYPE AS FTYPE, 21 F.RDB$FIELD_LENGTH AS FLENGTH, 22 F.RDB$FIELD_PRECISION AS FPRECISION, 23 F.RDB$FIELD_SCALE AS FSCALE, 24 R.RDB$NULL_FLAG AS NULL_FLAG, 25 R.RDB$FIELD_POSITION 26 FROM RDB$RELATION_FIELDS R 27 JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME 28 WHERE F.RDB$SYSTEM_FLAG=0 and R.RDB$RELATION_NAME= %s 29 ORDER BY R.RDB$FIELD_POSITION 30 """, (table_name,)) 31 return [(row[0].lower().rstrip(), row[1], row[2], row[2] or 0, row[3], row[4], row[5] and True or False) for row in cursor.fetchall()] 32 33 34 def get_relations(cursor, table_name): 35 """ 36 Returns a dictionary of {field_index: (field_index_other_table, other_table)} 37 representing all relationships to the given table. Indexes are 0-based. 38 """ 39 cursor.execute(""" 40 SELECT seg.rdb$field_name, seg_ref.rdb$field_name, idx_ref.rdb$relation_name 41 FROM rdb$indices idx 42 INNER JOIN rdb$index_segments seg 43 ON seg.rdb$index_name = idx.rdb$index_name 44 INNER JOIN rdb$indices idx_ref 45 ON idx_ref.rdb$index_name = idx.rdb$foreign_key 46 INNER JOIN rdb$index_segments seg_ref 47 ON seg_ref.rdb$index_name = idx_ref.rdb$index_name 48 WHERE idx.rdb$relation_name = %s 49 AND idx.rdb$foreign_key IS NOT NULL""", [table_name]) 50 51 relations = {} 52 for row in cursor.fetchall(): 53 relations[row[0].rstrip()] = (row[1].strip(), row[2].strip()) 54 return relations 55 56 def get_indexes(cursor, table_name): 57 """ 58 Returns a dictionary of fieldname -> infodict for the given table, 59 where each infodict is in the format: 60 {'primary_key': boolean representing whether it's the primary key, 61 'unique': boolean representing whether it's a unique index} 62 """ 63 64 # This query retrieves each field name and index type on the given table. 65 cursor.execute(""" 66 SELECT seg.rdb$field_name, const.rdb$constraint_type 67 FROM rdb$relation_constraints const 68 LEFT JOIN rdb$index_segments seg 69 ON seg.rdb$index_name = const.rdb$index_name 70 WHERE const.rdb$relation_name = %s 71 AND (const.rdb$constraint_type = 'PRIMARY KEY' 72 OR const.rdb$constraint_type = 'UNIQUE')""", [table_name]) 73 indexes = {} 74 for row in cursor.fetchall(): 75 indexes[row[0].strip()] = { 76 'primary_key': ('PRIMARY KEY' == row[1].strip()), 77 'unique': ('UNIQUE' == row[1].strip())} 78 return indexes 79 80 # Maps type codes to Django Field types. 81 # !todo 82 DATA_TYPES_REVERSE = { 83 7: 'BooleanField', 84 7: 'SmallIntegerField', 85 8: 'IntegerField', 86 261: 'TextField', 87 37: 'IPAddressField', 88 37: 'CharField', 89 12: 'DateField', 90 13: 'TimeField', 91 35: 'DateTimeField', 92 10: 'FloatField', 93 } -
django/db/backends/firebird/creation.py
1 # This dictionary maps Field objects to their associated Firebird column 2 # types, as strings. Column-type strings can contain format strings; they'll 3 # be interpolated against the values of Field.__dict__ before being output. 4 # If a column type is set to None, it won't be included in the output. 5 6 import sys, os.path 7 from kinterbasdb import connect, create_database 8 from django.core.management import call_command 9 10 DATA_TYPES = { 11 'AutoField': 'integer', 12 'BooleanField': 'smallint', 13 'CharField': 'varchar(%(max_length)s)', 14 'CommaSeparatedIntegerField': 'varchar(%(max_length)s) CHARACTER SET ASCII', 15 'DateField': 'date', 16 'DateTimeField': 'timestamp', 17 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 18 'FileField': 'varchar(%(max_length)s)', 19 'FilePathField': 'varchar(%(max_length)s)', 20 'FloatField': 'double precision', 21 'ImageField': 'varchar(%(max_length)s)', 22 'IntegerField': 'integer', 23 'IPAddressField': 'varchar(15) CHARACTER SET ASCII', 24 'NullBooleanField': 'smallint', 25 'OneToOneField': 'integer', 26 'PhoneNumberField': 'varchar(20)', 27 'PositiveIntegerField': 'integer', 28 'PositiveSmallIntegerField': 'smallint', 29 'SlugField': 'varchar(%(max_length)s)', 30 'SmallIntegerField': 'smallint', 31 'TextField': 'blob sub_type text', 32 'TimeField': 'time', 33 'URLField': 'varchar(%(max_length)s) CHARACTER SET ASCII', 34 'USStateField': 'char(2) CHARACTER SET ASCII', 35 } 36 37 DATA_TYPE_CHECKS = { 38 'BooleanField': '("%(column)s" IN (0,1))', 39 'NullBooleanField': '(("%(column)s" IN (0,1)) OR ("%(column)s" IS NULL))', 40 'PositiveIntegerField': '("%(column)s" >= 0)', 41 'PositiveSmallIntegerField': '("%(column)s" >= 0)' 42 } 43 44 TEST_DATABASE_PREFIX = 'test_' 45 46 def create_test_db(settings, connection, verbosity, autoclobber): 47 # KInterbasDB supports dynamic database creation and deletion 48 # via the module-level function create_database and the method Connection.drop_database. 49 50 if settings.TEST_DATABASE_NAME: 51 TEST_DATABASE_NAME = settings.TEST_DATABASE_NAME 52 else: 53 dbnametuple = os.path.split(settings.DATABASE_NAME) 54 TEST_DATABASE_NAME = os.path.join(dbnametuple[0], TEST_DATABASE_PREFIX + dbnametuple[1]) 55 56 dsn = "localhost:%s" % TEST_DATABASE_NAME 57 if settings.DATABASE_HOST: 58 dsn = "%s:%s" % (settings.DATABASE_HOST, TEST_DATABASE_NAME) 59 60 if os.path.isfile(TEST_DATABASE_NAME): 61 sys.stderr.write("Database %s already exists\n" % TEST_DATABASE_NAME) 62 if not autoclobber: 63 confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % TEST_DATABASE_NAME) 64 if autoclobber or confirm == 'yes': 65 if verbosity >= 1: 66 print "Destroying old test database..." 67 old_connection = connect(dsn=dsn, user=settings.DATABASE_USER, password=settings.DATABASE_PASSWORD) 68 old_connection.drop_database() 69 else: 70 print "Tests cancelled." 71 sys.exit(1) 72 73 if verbosity >= 1: 74 print "Creating test database..." 75 try: 76 charset = 'UNICODE_FSS' 77 if hasattr(settings, 'FIREBIRD_CHARSET'): 78 if settings.FIREBIRD_CHARSET == 'UTF8': 79 charset='UTF8' 80 create_database("create database '%s' user '%s' password '%s' default character set %s" % \ 81 (dsn, settings.DATABASE_USER, settings.DATABASE_PASSWORD, charset)) 82 except Exception, e: 83 sys.stderr.write("Got an error creating the test database: %s\n" % e) 84 sys.exit(2) 85 86 87 connection.close() 88 settings.DATABASE_NAME = TEST_DATABASE_NAME 89 90 call_command('syncdb', verbosity=verbosity, interactive=False) 91 92 if settings.CACHE_BACKEND.startswith('db://'): 93 cache_name = settings.CACHE_BACKEND[len('db://'):] 94 call_command('createcachetable', cache_name) 95 96 # Get a cursor (even though we don't need one yet). This has 97 # the side effect of initializing the test database. 98 cursor = connection.cursor() 99 100 return TEST_DATABASE_NAME 101 102 def destroy_test_db(settings, connection, old_database_name, verbosity): 103 # KInterbasDB supports dynamic database deletion via the method Connection.drop_database. 104 if verbosity >= 1: 105 print "Destroying test database..." 106 connection.drop_database() 107 108 -
django/core/cache/backends/db.py
47 47 if timeout is None: 48 48 timeout = self.default_timeout 49 49 cursor = connection.cursor() 50 cursor.execute("SELECT COUNT(*) FROM %s" % self._table) 50 qn = connection.ops.quote_name 51 cursor.execute("SELECT COUNT(*) FROM %s" % qn(self._table)) 51 52 num = cursor.fetchone()[0] 52 53 now = datetime.now().replace(microsecond=0) 53 54 exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0) 54 55 if num > self._max_entries: 55 56 self._cull(cursor, now) 56 57 encoded = base64.encodestring(pickle.dumps(value, 2)).strip() 57 cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s" % self._table, [key])58 cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s" % qn(self._table), [key]) 58 59 try: 59 60 if mode == 'set' and cursor.fetchone(): 60 cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % self._table, [encoded, str(exp), key])61 cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % qn(self._table), [encoded, str(exp), key]) 61 62 else: 62 cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)])63 cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % qn(self._table), [key, encoded, str(exp)]) 63 64 except DatabaseError: 64 65 # To be threadsafe, updates/inserts are allowed to fail silently 65 66 pass -
django/core/management/sql.py
1 1 from django.core.management.base import CommandError 2 from django.conf import settings 2 3 import os 3 4 import re 4 5 … … 253 254 pending_references = {} 254 255 qn = connection.ops.quote_name 255 256 inline_references = connection.features.inline_fk_references 257 is_firebird = hasattr(connection.ops, "firebird_version") 256 258 for f in opts.fields: 257 col_type = f.db_type() 259 col_type, col_type_check = f.db_type(), f.db_type_check() 260 if is_firebird: 261 fb_version = "%s.%s" % (connection.ops.firebird_version[0], connection.ops.firebird_version[1]) 262 page_size = connection.ops.page_size 263 #look at: http://www.volny.cz/iprenosil/interbase/ip_ib_indexcalculator.htm 264 if connection.ops.index_limit < 1000: 265 strip2ascii = False 266 if (f.unique or f.primary_key or f.db_index): 267 strip2ascii = True 268 if len(opts.unique_together) > 0: 269 if f.column in opts.unique_together[0]: 270 strip2ascii = True 271 if strip2ascii: 272 if col_type.startswith('varchar'): 273 if not col_type.endswith('ASCII'): 274 col_type += " CHARACTER SET ASCII" 275 msg = "WARNING: Character encoding of the column '%s' has changed to ASCII\n" 276 msg += " due to restriction of %s bytes in Firebird %s" 277 if not page_size: 278 print msg % (f.column, connection.ops.index_limit, fb_version) 279 else: 280 msg += " with page size %s" 281 print msg % (f.column, connection.ops.index_limit, fb_version, page_size) 282 if opts.unique_together: 283 num_ufields = len(opts.unique_together[0]) 284 limit = connection.ops.index_limit - ((num_ufields - 1)*64) 285 max_length = int(limit/float(num_ufields)) 286 old_length = int(f.__dict__["max_length"]) 287 if old_length > max_length: 288 col_type = "varchar(%i) CHARACTER SET ASCII" % max_length 289 print " The maximum length of '%s' is now %s instead of %s"\ 290 % (f.column, max_length, old_length) 291 258 292 tablespace = f.db_tablespace or opts.db_tablespace 259 293 if col_type is None: 260 294 # Skip ManyToManyFields, because they're not represented as … … 263 297 # Make the definition (e.g. 'foo VARCHAR(30)') for this field. 264 298 field_output = [style.SQL_FIELD(qn(f.column)), 265 299 style.SQL_COLTYPE(col_type)] 266 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) 300 nullstring = "" 301 if connection.features.needs_default_null: 302 nullstring = "DEFAULT " 303 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or nullstring))) 267 304 if f.unique and (not f.primary_key or connection.features.allows_unique_and_pk): 268 305 field_output.append(style.SQL_KEYWORD('UNIQUE')) 269 306 if f.primary_key: … … 276 313 if inline_references and f.rel.to in known_models: 277 314 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 278 315 style.SQL_TABLE(qn(f.rel.to._meta.db_table)) + ' (' + \ 279 style.SQL_FIELD(qn(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + 280 connection.ops. deferrable_sql()316 style.SQL_FIELD(qn(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + \ 317 connection.ops.cascade_delete_update_sql() + connection.ops.deferrable_sql() 281 318 ) 282 319 else: 283 320 # We haven't yet created the table to which this field 284 321 # is related, so save it for later. 285 322 pr = pending_references.setdefault(f.rel.to, []).append((model, f)) 323 if col_type_check: 324 field_output.extend([ style.SQL_KEYWORD('CHECK'), style.SQL_COLTYPE(col_type_check) ]) 286 325 table_output.append(' '.join(field_output)) 287 326 if opts.order_with_respect_to: 288 327 table_output.append(style.SQL_FIELD(qn('_order')) + ' ' + \ … … 335 374 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ 336 375 (qn(r_table), truncate_name(r_name, connection.ops.max_name_length()), 337 376 qn(r_col), qn(table), qn(col), 377 connection.ops.cascade_delete_update_sql(), 338 378 connection.ops.deferrable_sql())) 339 379 del pending_references[model] 340 380 return final_output … … 364 404 tablespace_sql)) 365 405 if inline_references: 366 406 deferred = [] 367 table_output.append(' %s %s %s %s (%s)%s ,' %407 table_output.append(' %s %s %s %s (%s)%s%s,' % 368 408 (style.SQL_FIELD(qn(f.m2m_column_name())), 369 409 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 370 410 style.SQL_KEYWORD('NOT NULL REFERENCES'), 371 411 style.SQL_TABLE(qn(opts.db_table)), 372 412 style.SQL_FIELD(qn(opts.pk.column)), 413 connection.ops.cascade_delete_update_sql(), 373 414 connection.ops.deferrable_sql())) 374 table_output.append(' %s %s %s %s (%s)%s ,' %415 table_output.append(' %s %s %s %s (%s)%s%s,' % 375 416 (style.SQL_FIELD(qn(f.m2m_reverse_name())), 376 417 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 377 418 style.SQL_KEYWORD('NOT NULL REFERENCES'), 378 419 style.SQL_TABLE(qn(f.rel.to._meta.db_table)), 379 420 style.SQL_FIELD(qn(f.rel.to._meta.pk.column)), 421 connection.ops.cascade_delete_update_sql(), 380 422 connection.ops.deferrable_sql())) 381 423 else: 382 424 table_output.append(' %s %s %s,' % … … 412 454 (qn(r_table), 413 455 truncate_name(r_name, connection.ops.max_name_length()), 414 456 qn(r_col), qn(table), qn(col), 457 connection.ops.cascade_delete_update_sql(), 415 458 connection.ops.deferrable_sql())) 416 459 417 460 # Add any extra SQL needed to support auto-incrementing PKs -
tests/regressiontests/initial_sql_regress/sql/simple.sql
1 INSERT INTO initial_sql_regress_simple (name) VALUES ('John');2 INSERT INTO initial_sql_regress_simple (name) VALUES ('Paul');3 INSERT INTO initial_sql_regress_simple (name) VALUES ('Ringo');4 INSERT INTO initial_sql_regress_simple (name) VALUES ('George');5 INSERT INTO initial_sql_regress_simple (name) VALUES ('Miles O''Brien');6 INSERT INTO initial_sql_regress_simple (name) VALUES ('Semicolon;Man');7 INSERT INTO initial_sql_regress_simple (name) VALUES ('This line has a Windows line ending');1 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('John'); 2 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('Paul'); 3 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('Ringo'); 4 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('George'); 5 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('Miles O''Brien'); 6 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('Semicolon;Man'); 7 INSERT INTO "initial_sql_regress_simple" ("name") VALUES ('This line has a Windows line ending'); 8 8 -
tests/regressiontests/backends/models.py
22 22 >>> opts = Square._meta 23 23 >>> f1, f2 = opts.get_field('root'), opts.get_field('square') 24 24 >>> query = ('INSERT INTO %s (%s, %s) VALUES (%%s, %%s)' 25 ... % (t_convert(opts.db_table), qn(f1.column), qn(f2.column)))25 ... % qn((t_convert(opts.db_table)), qn(f1.column), qn(f2.column))) 26 26 >>> cursor.executemany(query, [(i, i**2) for i in range(-5, 6)]) and None or None 27 27 >>> Square.objects.order_by('root') 28 28 [<Square: -5 ** 2 == 25>, <Square: -4 ** 2 == 16>, <Square: -3 ** 2 == 9>, <Square: -2 ** 2 == 4>, <Square: -1 ** 2 == 1>, <Square: 0 ** 2 == 0>, <Square: 1 ** 2 == 1>, <Square: 2 ** 2 == 4>, <Square: 3 ** 2 == 9>, <Square: 4 ** 2 == 16>, <Square: 5 ** 2 == 25>]