Ticket #1261: release-0.96-firebird.diff
File release-0.96-firebird.diff, 31.8 KB (added by , 18 years ago) |
---|
-
django/test/utils.py
1 1 import sys, time 2 2 from django.conf import settings 3 from django.db import connection, transaction, backend 3 from django.db import connection, transaction, backend, get_creation_module 4 4 from django.core import management 5 5 from django.dispatch import dispatcher 6 6 from django.test import signals … … 44 44 connection.connection.set_isolation_level(0) 45 45 46 46 def create_test_db(verbosity=1, autoclobber=False): 47 # If the database backend wants to create the test DB itself, let it 48 creation_module = get_creation_module() 49 if hasattr(creation_module, "create_test_db"): 50 creation_module.create_test_db(settings, connection, backend, verbosity, autoclobber) 51 return 52 47 53 if verbosity >= 1: 48 54 print "Creating test database..." 49 55 # If we're using SQLite, it's more convenient to test against an … … 92 98 cursor = connection.cursor() 93 99 94 100 def destroy_test_db(old_database_name, verbosity=1): 101 # If the database wants to drop the test DB itself, let it 102 creation_module = get_creation_module() 103 if hasattr(creation_module, "destroy_test_db"): 104 creation_module.destroy_test_db(settings, connection, backend, old_database_name, verbosity) 105 return 106 95 107 # Unless we're using SQLite, remove the test database to clean up after 96 108 # ourselves. Connect to the previous database (not the test database) 97 109 # to do so, because it's not allowed to delete a database while being -
django/db/models/base.py
205 205 record_exists = True 206 206 if pk_set: 207 207 # Determine whether a record with the primary key already exists. 208 cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % \ 208 check_sql = 'SELECT 1 FROM %s WHERE %s=%%s LIMIT 1' 209 if settings.DATABASE_ENGINE == 'firebird': 210 check_sql = 'SELECT FIRST 1 1 FROM %s WHERE %s=%%s' 211 cursor.execute(check_sql % \ 209 212 (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), [pk_val]) 210 213 # If it does already exist, do an UPDATE. 211 214 if cursor.fetchone(): -
django/db/models/fields/related.py
335 335 (target_col_name, self.join_table, source_col_name, 336 336 target_col_name, ",".join(['%s'] * len(new_ids))), 337 337 [self._pk_val] + list(new_ids)) 338 if cursor.rowcount is not None and cursor.rowcount != 0: 339 existing_ids = set([row[0] for row in cursor.fetchmany(cursor.rowcount)]) 338 rows = cursor.fetchall() 339 if rows: 340 existing_ids = set([row[0] for row in rows]) 340 341 else: 341 342 existing_ids = set() 342 343 -
django/db/models/query.py
2 2 from django.db.models.fields import DateField, FieldDoesNotExist 3 3 from django.db.models.fields.generic import GenericRelation 4 4 from django.db.models import signals 5 from django.conf import settings 5 6 from django.dispatch import dispatcher 6 7 from django.utils.datastructures import SortedDict 7 8 import operator … … 179 180 # undefined, so we convert it to a list of tuples. 180 181 extra_select = self._select.items() 181 182 183 pre_columns = "" 184 if settings.DATABASE_ENGINE == 'firebird' and self._limit is not None: 185 pre_columns += "FIRST %s " % self._limit 186 if self._offset: 187 pre_columns += "SKIP %s " % self._offset 188 if self._distinct: 189 pre_columns += "DISTINCT " 182 190 cursor = connection.cursor() 183 cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "")+ ",".join(select) + sql, params)191 cursor.execute("SELECT " + pre_columns + ",".join(select) + sql, params) 184 192 fill_cache = self._select_related 185 193 index_end = len(self.model._meta.fields) 186 194 while 1: … … 502 510 503 511 # Compose the join dictionary into SQL describing the joins. 504 512 if joins: 505 sql.append(" ".join(["%s %s AS%s ON %s" % (join_type, table, alias, condition)513 sql.append(" ".join(["%s %s %s ON %s" % (join_type, table, alias, condition) 506 514 for (alias, (table, join_type, condition)) in joins.items()])) 507 515 508 516 # Compose the tables clause into SQL. … … 717 725 table_prefix = backend.quote_name(table_prefix[:-1])+'.' 718 726 field_name = backend.quote_name(field_name) 719 727 try: 720 return '%s%s %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) 728 lookup_sql = '%s%s %s' 729 if settings.DATABASE_ENGINE == 'firebird' and lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'): 730 lookup_sql = 'UPPER(%s%s) %s' 731 return lookup_sql % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) 721 732 except KeyError: 722 733 pass 723 734 if lookup_type == 'in': -
django/db/backends/util.py
1 import datetime 1 import datetime, md5 2 2 from time import time 3 3 4 4 class CursorDebugWrapper(object): … … 38 38 else: 39 39 return getattr(self.cursor, attr) 40 40 41 def truncate_name(name, length=None): 42 """Shortens a string to a repeatable mangled version with the given length. 43 """ 44 if length is None or len(name) <= length: 45 return name 46 hash = md5.md5(name).hexdigest()[:4] 47 return '%s%s' % (name[:length-4], hash) 48 41 49 ############################################### 42 50 # Converters from database (string) to Python # 43 51 ############################################### -
django/db/backends/firebird/base.py
1 """ 2 Firebird database backend for Django. 3 4 Requires kinterbasdb: http://kinterbasdb.sourceforge.net/ 5 """ 6 7 from django.conf import settings 8 from django.db.backends import util 9 import re 10 try: 11 import kinterbasdb as Database 12 import kinterbasdb.typeconv_datetime_stdlib as typeconv_datetime 13 except ImportError, e: 14 from django.core.exceptions import ImproperlyConfigured 15 raise ImproperlyConfigured, "Error loading kinterbasdb module: %s" % e 16 17 DatabaseError = Database.DatabaseError 18 Database.init(type_conv=199) 19 20 try: 21 # Only exists in Python 2.4+ 22 from threading import local 23 except ImportError: 24 # Import copy of _thread_local.py from Python 2.4 25 from django.utils._threading_local import local 26 27 server_version = None 28 29 def unicode_conv_in(text): 30 #Type converter for columns with charsets NONE, OCTETS, or ASCII 31 if isinstance(text, unicode): 32 return text.encode(settings.DEFAULT_CHARSET) 33 return text 34 35 def timestamp_conv_in(datetime): 36 #Type converter for datetime casted strings. 37 #Replaces 6 digits microseconds to 4 digits allowed in Firebird 38 if isinstance(datetime, basestring) and datetime.find('.') > 0 and len(datetime) == 26: 39 datetime = datetime[0:-2] 40 return typeconv_datetime.timestamp_conv_in(datetime) 41 42 class DatabaseWrapper(local): 43 def __init__(self, **kwargs): 44 self.connection = None 45 self.queries = [] 46 self.options = kwargs 47 48 def cursor(self): 49 if self.connection is None: 50 if settings.DATABASE_NAME == '': 51 from django.core.exceptions import ImproperlyConfigured 52 raise ImproperlyConfigured, "You need to specify DATABASE_NAME in your Django settings file." 53 kwargs = {'database': settings.DATABASE_NAME} 54 if settings.DATABASE_HOST: 55 kwargs['host'] = settings.DATABASE_HOST 56 if settings.DATABASE_USER: 57 kwargs['user'] = settings.DATABASE_USER 58 if settings.DATABASE_PASSWORD: 59 kwargs['password'] = settings.DATABASE_PASSWORD 60 self.connection = Database.connect(**kwargs) 61 self.connection.set_type_trans_in({ 62 'TEXT': unicode_conv_in, 63 'BLOB': unicode_conv_in, 64 'TIMESTAMP': timestamp_conv_in 65 }) 66 global server_version 67 if not server_version: 68 import re 69 version_re = re.compile('.*Firebird\s([\d\.]+)') 70 m = version_re.match(self.connection.server_version) 71 if not m: 72 raise Exception('Unable to determine Firebird version from version string %r' % self.connection.server_version) 73 server_version = m.groups()[0] 74 cursor = FirebirdCursorWrapper(self.connection) 75 if settings.DEBUG: 76 return util.CursorDebugWrapper(cursor, self) 77 return cursor 78 79 def _commit(self): 80 if self.connection is not None: 81 return self.connection.commit() 82 83 def _rollback(self): 84 if self.connection is not None: 85 return self.connection.rollback() 86 87 def close(self): 88 if self.connection is not None: 89 self.connection.close() 90 self.connection = None 91 92 class FirebirdCursorWrapper(Database.Cursor): 93 """ 94 Django uses "format" ('%s') style placeholders, but firebird uses "qmark" ('?') style. 95 This fixes it -- but note that if you want to use a literal "%s" in a query, 96 you'll need to use "%%s". 97 """ 98 def execute(self, query, params=()): 99 query = self._convert_query(query, len(params)) 100 #print "%s %s" % (query, params) 101 return Database.Cursor.execute(self, query, params) 102 103 def executemany(self, query, params): 104 query = self._convert_query(query, len(params[0])) 105 return Database.Cursor.executemany(self, query, params) 106 107 def _convert_query(self, query, num_params): 108 return query % tuple("?" * num_params) 109 110 supports_constraints = True 111 112 def quote_name(name): 113 # the standard for firebird is not to quote names but in django 114 # it will quote all names uppercased so we can write sql without quotes 115 # because all names without quotes will defualt to uppercased, 116 # like oracle truncate names bigger than 30 chars 117 if not name.startswith('"') and not name.endswith('"'): 118 name = '"%s"' % util.truncate_name(name, get_max_name_length()) 119 return name.upper() 120 121 _quote_sequence_name = lambda n: '"%s_SQ"' % util.truncate_name(n.upper(), get_max_name_length()-3) 122 _quote_trigger_name = lambda n: '"%s_TR"' % util.truncate_name(n.upper(), get_max_name_length()-3) 123 124 def dictfetchone(cursor): 125 "Returns a row from the cursor as a dict" 126 return cursor.fetchonemap() 127 128 def dictfetchmany(cursor, number): 129 "Returns a certain number of rows from a cursor as a dict" 130 return cursor.fetchmanymap(number) 131 132 def dictfetchall(cursor): 133 "Returns all rows from a cursor as a dict" 134 return cursor.fetchallmap() 135 136 def get_last_insert_id(cursor, table_name, pk_name): 137 stmt = server_version < '2' and 'SELECT GEN_ID(%s, 0) FROM RDB$DATABASE' or 'NEXT VALUE FOR %s' 138 cursor.execute(stmt % _quote_sequence_name(table_name)) 139 return cursor.fetchone()[0] 140 141 def get_date_extract_sql(lookup_type, column_name): 142 # lookup_type is 'year', 'month', 'day' 143 return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), column_name) 144 145 def get_date_trunc_sql(lookup_type, column_name): 146 if lookup_type == 'year': 147 sql = "EXTRACT(year FROM %s)||'-01-01 00:00:00'" % column_name 148 elif lookup_type == 'month': 149 sql = "EXTRACT(year FROM %s)||'-'||EXTRACT(month FROM %s)||'-01 00:00:00'" % (column_name, column_name) 150 elif lookup_type == 'day': 151 sql = "EXTRACT(year FROM %s)||'-'||EXTRACT(month FROM %s)||'-'||EXTRACT(day FROM %s)||' 00:00:00'" % (column_name, column_name, column_name) 152 return "CAST(%s AS TIMESTAMP)" % sql 153 154 def get_datetime_cast_sql(): 155 return None 156 157 def get_limit_offset_sql(limit, offset=None): 158 return "" 159 160 def get_random_function_sql(): 161 return "RAND()" 162 163 def get_deferrable_sql(): 164 # Not supported, maybe in Firebird 3.0 165 return "" 166 167 def get_fulltext_search_sql(field_name): 168 # maybe in Firebird 3.0 169 raise NotImplementedError 170 171 def get_drop_foreignkey_sql(): 172 return "DROP CONSTRAINT" 173 174 def get_pk_default_value(): 175 return "NULL" 176 177 def get_max_name_length(): 178 return 30 179 180 def get_sequence_sql(style, table_name, column_name): 181 """To simulate auto-incrementing primary keys in Firebird, we have to 182 create a generator (sequence in Firebird 2) and a trigger. 183 184 Create the sequences and triggers names based only on table name 185 since django only support one auto field per model""" 186 KEYWORD = style.SQL_KEYWORD 187 TABLE = style.SQL_TABLE 188 FIELD = style.SQL_FIELD 189 190 sequence_name = _quote_sequence_name(table_name) 191 column_name = quote_name(column_name) 192 return ["%s %s;" % ( \ 193 KEYWORD(server_version < '2' and 'CREATE GENERATOR' or 'CREATE SEQUENCE'), 194 TABLE(sequence_name)), 195 "\n".join(["%s %s %s %s" % ( \ 196 KEYWORD('CREATE TRIGGER'), 197 TABLE(_quote_trigger_name(table_name)), 198 KEYWORD('FOR'), 199 TABLE(quote_name(table_name))), 200 "%s 0 %s" % ( \ 201 KEYWORD('ACTIVE BEFORE INSERT POSITION'), 202 KEYWORD('AS')), 203 KEYWORD('BEGIN'), 204 " %s ((%s.%s %s) %s (%s.%s = 0)) %s" % ( \ 205 KEYWORD('IF'), 206 KEYWORD('NEW'), 207 FIELD(column_name), 208 KEYWORD('IS NULL'), 209 KEYWORD('OR'), 210 KEYWORD('NEW'), 211 FIELD(column_name), 212 KEYWORD('THEN')), 213 " %s" % KEYWORD('BEGIN'), 214 " %s.%s = %s(%s, 1);" % ( \ 215 KEYWORD('NEW'), 216 FIELD(column_name), 217 KEYWORD('GEN_ID'), 218 TABLE(sequence_name)), 219 " %s" % KEYWORD('END'), 220 KEYWORD('END')])] 221 222 def get_sql_flush(style, tables, sequences): 223 """Return a list of SQL statements required to remove all data from 224 all tables in the database (without actually removing the tables 225 themselves) and put the database in an empty 'initial' state 226 227 For Firebird we gonna take a dangerous workaround: 228 - first create a temporary table 'django_flush$constraints' that 229 will contain all Foreignkey definitions for this database. 230 - next import this definitions into the new table and delete them 231 from system table 'rdb$relation_constraints'. 232 - after the flush is done import the definitions back to the system table 233 and delete the temporary table. 234 """ 235 KEYWORD = style.SQL_KEYWORD 236 TABLE = style.SQL_TABLE 237 FIELD = style.SQL_FIELD 238 239 if tables: 240 temp_table_name = quote_name('django_flush$constraints') 241 orig_table_name = 'RDB$RELATION_CONSTRAINTS' 242 sql = ["\n".join([ 243 "%s %s (" % (KEYWORD('CREATE TABLE'), TABLE(temp_table_name)), 244 " %s %s(31) %s," % (FIELD(quote_name('rdb$constraint_name')), KEYWORD('CHAR'), KEYWORD('CHARACTER SET UNICODE_FSS')), 245 " %s %s(11)," % (FIELD(quote_name('rdb$constraint_type')), KEYWORD('CHAR')), 246 " %s %s(31) %s," % (FIELD(quote_name('rdb$relation_name')), KEYWORD('CHAR'), KEYWORD('CHARACTER SET UNICODE_FSS')), 247 " %s %s(3)," % (FIELD(quote_name('rdb$deferrable')), KEYWORD('CHAR')), 248 " %s %s(3)," % (FIELD(quote_name('rdb$initially_deferred')), KEYWORD('CHAR')), 249 " %s %s(31) %s" % (FIELD(quote_name('rdb$index_name')), KEYWORD('CHAR'), KEYWORD('CHARACTER SET UNICODE_FSS')), 250 ");"]), 251 "%s;" % KEYWORD('COMMIT'), 252 "%s %s %s %s %s %s %s %s = 'FOREIGN KEY';" % ( \ 253 KEYWORD('INSERT INTO'), TABLE(temp_table_name), 254 KEYWORD('SELECT'), FIELD('*'), KEYWORD('FROM'), TABLE(orig_table_name), 255 KEYWORD('WHERE'), FIELD('rdb$constraint_type')), 256 "%s %s %s %s = 'FOREIGN KEY';" % ( \ 257 KEYWORD('DELETE FROM'), TABLE(orig_table_name), 258 KEYWORD('WHERE'), FIELD('rdb$constraint_type')), 259 "%s;" % KEYWORD('COMMIT')] 260 261 sql += ['%s %s;' % \ 262 (KEYWORD('DELETE FROM'), 263 TABLE(quote_name(table)) 264 ) for table in tables] 265 266 sql += ["%s %s %s 0;" % \ 267 (KEYWORD(server_version < '2' and 'SET GENERATOR' or 'ALTER SEQUENCE'), 268 TABLE(_quote_sequence_name(sequence['table'])), 269 KEYWORD(server_version < '2' and 'TO' or 'RESTART WITH') 270 ) for sequence in sequences] 271 return sql + [ 272 "%s %s %s %s %s %s;" % ( \ 273 KEYWORD('INSERT INTO'), TABLE(orig_table_name), 274 KEYWORD('SELECT'), FIELD('*'), KEYWORD('FROM'), TABLE(temp_table_name)), 275 "%s %s;" % (KEYWORD('DROP TABLE'), TABLE(temp_table_name)), 276 "%s;" % KEYWORD('COMMIT')] 277 return [] 278 279 OPERATOR_MAPPING = { 280 'exact': '= %s', 281 'iexact': "= UPPER(%s)", 282 'contains': "LIKE %s ESCAPE '\\'", 283 'icontains': "LIKE UPPER(%s) ESCAPE '\\'", 284 'gt': '> %s', 285 'gte': '>= %s', 286 'lt': '< %s', 287 'lte': '<= %s', 288 'startswith': "LIKE %s ESCAPE '\\'", 289 'endswith': "LIKE %s ESCAPE '\\'", 290 'istartswith': "LIKE UPPER(%s) ESCAPE '\\'", 291 'iendswith': "LIKE UPPER(%s) ESCAPE '\\'", 292 293 'text_icontains': "CONTAINING %s", 294 } -
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 quote_name 3 4 def get_table_list(cursor): 5 "Returns a list of table names in the current database." 6 cursor.execute(""" 7 SELECT rdb$relation_name FROM rdb$relations 8 WHERE rdb$system_flag = 0 AND rdb$view_blr IS NULL ORDER BY rdb$relation_name""") 9 return [str(row[0].strip().lower()) for row in cursor.fetchall()] 10 11 def get_table_description(cursor, table_name): 12 "Returns a description of the table, with the DB-API cursor.description interface." 13 #cursor.execute("SELECT FIRST 1 * FROM %s" % quote_name(table_name)) 14 #return cursor.description 15 # (name, type_code, display_size, internal_size, precision, scale, null_ok) 16 cursor.execute(""" 17 SELECT DISTINCT R.RDB$FIELD_NAME AS FNAME, 18 F.RDB$FIELD_TYPE AS FTYPE, 19 F.RDB$FIELD_LENGTH AS FLENGTH, 20 F.RDB$FIELD_PRECISION AS FPRECISION, 21 F.RDB$FIELD_SCALE AS FSCALE, 22 R.RDB$NULL_FLAG AS NULL_FLAG, 23 R.RDB$FIELD_POSITION 24 FROM RDB$RELATION_FIELDS R 25 JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME 26 WHERE F.RDB$SYSTEM_FLAG=0 and R.RDB$RELATION_NAME= %s 27 ORDER BY R.RDB$FIELD_POSITION 28 """, (table_name,)) 29 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()] 30 31 32 def get_relations(cursor, table_name): 33 """ 34 Returns a dictionary of {field_index: (field_index_other_table, other_table)} 35 representing all relationships to the given table. Indexes are 0-based. 36 """ 37 cursor.execute(""" 38 SELECT seg.rdb$field_name, seg_ref.rdb$field_name, idx_ref.rdb$relation_name 39 FROM rdb$indices idx 40 INNER JOIN rdb$index_segments seg 41 ON seg.rdb$index_name = idx.rdb$index_name 42 INNER JOIN rdb$indices idx_ref 43 ON idx_ref.rdb$index_name = idx.rdb$foreign_key 44 INNER JOIN rdb$index_segments seg_ref 45 ON seg_ref.rdb$index_name = idx_ref.rdb$index_name 46 WHERE idx.rdb$relation_name = %s 47 AND idx.rdb$foreign_key IS NOT NULL""", [table_name]) 48 49 relations = {} 50 for row in cursor.fetchall(): 51 relations[row[0].rstrip()] = (row[1].strip(), row[2].strip()) 52 return relations 53 54 def get_indexes(cursor, table_name): 55 """ 56 Returns a dictionary of fieldname -> infodict for the given table, 57 where each infodict is in the format: 58 {'primary_key': boolean representing whether it's the primary key, 59 'unique': boolean representing whether it's a unique index} 60 """ 61 62 # This query retrieves each field name and index type on the given table. 63 cursor.execute(""" 64 SELECT seg.rdb$field_name, const.rdb$constraint_type 65 FROM rdb$relation_constraints const 66 LEFT JOIN rdb$index_segments seg 67 ON seg.rdb$index_name = const.rdb$index_name 68 WHERE const.rdb$relation_name = %s 69 AND (const.rdb$constraint_type = 'PRIMARY KEY' 70 OR const.rdb$constraint_type = 'UNIQUE')""", [table_name]) 71 indexes = {} 72 for row in cursor.fetchall(): 73 indexes[row[0].strip()] = { 74 'primary_key': ('PRIMARY KEY' == row[1].strip()), 75 'unique': ('UNIQUE' == row[1].strip())} 76 return indexes 77 78 # Maps type codes to Django Field types. 79 # !todo 80 DATA_TYPES_REVERSE = { 81 7: 'BooleanField', 82 7: 'SmallIntegerField', 83 8: 'IntegerField', 84 261: 'TextField', 85 37: 'IPAddressField', 86 37: 'CharField', 87 12: 'DateField', 88 13: 'TimeField', 89 35: 'DateTimeField', 90 10: 'FloatField', 91 } -
django/db/backends/firebird/creation.py
1 from django.core import management 2 import sys, os, time 3 4 # This dictionary maps Field objects to their associated PostgreSQL column 5 # types, as strings. Column-type strings can contain format strings; they'll 6 # be interpolated against the values of Field.__dict__ before being output. 7 # If a column type is set to None, it won't be included in the output. 8 9 DATA_TYPES = { 10 'AutoField': 'INTEGER', 11 'BooleanField': 'SMALLINT', 12 'CharField': 'VARCHAR(%(maxlength)s)', 13 'CommaSeparatedIntegerField': 'VARCHAR(%(maxlength)s)', 14 'DateField': 'DATE', 15 'DateTimeField': 'TIMESTAMP', 16 'FileField': 'VARCHAR(100)', 17 'FilePathField': 'VARCHAR(100)', 18 'FloatField': 'NUMERIC(%(max_digits)s, %(decimal_places)s)', 19 'ImageField': 'VARCHAR(100)', 20 'IntegerField': 'INTEGER', 21 'IPAddressField': 'VARCHAR(15)', 22 'ManyToManyField': None, 23 'NullBooleanField': 'SMALLINT', 24 'OneToOneField': 'INTEGER', 25 'PhoneNumberField': 'VARCHAR(20)', 26 'PositiveIntegerField': 'INTEGER', 27 'PositiveSmallIntegerField': 'SMALLINT', 28 'SlugField': 'VARCHAR(%(maxlength)s)', 29 'SmallIntegerField': 'SMALLINT', 30 'TextField': 'BLOB SUB_TYPE TEXT', 31 'TimeField': 'TIME', 32 'URLField': 'VARCHAR(200)', 33 'USStateField': 'VARCHAR(2)', 34 } 35 36 TEST_DATABASE_PREFIX = 'test_' 37 38 def create_test_db(settings, connection, backend, verbosity, autoclobber): 39 40 if verbosity >= 1: 41 print "Creating test database..." 42 43 if settings.TEST_DATABASE_NAME: 44 if os.path.isfile(settings.DATABASE_NAME): 45 TEST_DATABASE_NAME = os.path.join( 46 os.path.dirname(settings.DATABASE_NAME), 47 settings.TEST_DATABASE_NAME) 48 else: 49 import tempfile 50 tempfile.gettempdir() 51 TEST_DATABASE_NAME = os.path.join( 52 tempfile.gettempdir(), 53 settings.TEST_DATABASE_NAME) 54 else: 55 if os.path.isfile(settings.DATABASE_NAME): 56 TEST_DATABASE_NAME = os.path.join( 57 os.path.dirname(settings.DATABASE_NAME), 58 TEST_DATABASE_PREFIX + os.path.basename(settings.DATABASE_NAME)) 59 else: 60 import tempfile 61 tempfile.gettempdir() 62 TEST_DATABASE_NAME = os.path.join( 63 tempfile.gettempdir(), 64 TEST_DATABASE_PREFIX + settings.DATABASE_NAME) 65 66 settings.DATABASE_NAME = TEST_DATABASE_NAME 67 68 try: 69 _create_test_db(backend, settings) 70 except Exception, e: 71 sys.stderr.write("Got an error creating the test database: %s\n" % e) 72 if not autoclobber: 73 confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_NAME) 74 if autoclobber or confirm == 'yes': 75 try: 76 if verbosity >= 1: 77 print "Destroying old test database..." 78 _destroy_test_db(connection) 79 if verbosity >= 1: 80 print "Creating test database..." 81 _create_test_db(backend, settings) 82 except Exception, e: 83 sys.stderr.write("Got an error recreating the test database: %s\n" % e) 84 sys.exit(2) 85 else: 86 print "Tests cancelled." 87 sys.exit(1) 88 89 management.syncdb(verbosity, interactive=False) 90 91 # Get a cursor (even though we don't need one yet). This has 92 # the side effect of initializing the test database. 93 cursor = connection.cursor() 94 95 96 def destroy_test_db(settings, connection, backend, old_database_name, verbosity): 97 if verbosity >= 1: 98 print "Destroying test database..." 99 100 # To avoid "database is being accessed by other users" errors. 101 time.sleep(1) 102 _destroy_test_db(connection) 103 104 def _create_test_db(backend, settings): 105 connection = backend.Database.create_database(""" 106 CREATE DATABASE '%s' user '%s' password '%s'""" % \ 107 (settings.DATABASE_NAME, settings.DATABASE_USER, settings.DATABASE_PASSWORD)) 108 cursor = connection.cursor() 109 cursor.execute(""" 110 DECLARE EXTERNAL FUNCTION rand 111 RETURNS DOUBLE PRECISION 112 BY VALUE ENTRY_POINT 'IB_UDF_rand' MODULE_NAME 'ib_udf'; 113 """) 114 connection.commit() 115 connection.close() 116 117 def _destroy_test_db(connection): 118 cursor = connection.cursor() 119 connection.connection.drop_database() 120 connection.connection = None 121 No newline at end of file -
django/core/management.py
159 159 Returns list_of_sql, pending_references_dict 160 160 """ 161 161 from django.db import backend, get_creation_module, models 162 from django.conf import settings 162 163 data_types = get_creation_module().DATA_TYPES 163 164 164 165 opts = model._meta … … 177 178 # Make the definition (e.g. 'foo VARCHAR(30)') for this field. 178 179 field_output = [style.SQL_FIELD(backend.quote_name(f.column)), 179 180 style.SQL_COLTYPE(col_type % rel_field.__dict__)] 180 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) 181 column_null_sql = '%sNULL' % (not f.null and 'NOT ' or '') 182 if settings.DATABASE_ENGINE == 'firebird' and f.null: 183 column_null_sql = (not f.null or f.primary_key) and 'NOT NULL' or '' 184 if column_null_sql: 185 field_output.append(style.SQL_KEYWORD(column_null_sql)) 181 186 if f.unique: 182 187 field_output.append(style.SQL_KEYWORD('UNIQUE')) 183 188 if f.primary_key: … … 207 212 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 208 213 full_statement.append(');') 209 214 final_output.append('\n'.join(full_statement)) 215 216 if opts.has_auto_field and hasattr(backend, 'get_sequence_sql'): 217 final_output += backend.get_sequence_sql(style, opts.db_table, opts.pk.column) 210 218 211 219 return final_output, pending_references 212 220 … … 231 239 # So we are careful with character usage here. 232 240 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) 233 241 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ 234 (backend.quote_name(r_table), r_name,242 (backend.quote_name(r_table), backend.quote_name(r_name), 235 243 backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col), 236 244 backend.get_deferrable_sql())) 237 245 del pending_references[model] … … 273 281 style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())))) 274 282 table_output.append(');') 275 283 final_output.append('\n'.join(table_output)) 284 if hasattr(backend, 'get_sequence_sql'): 285 final_output += backend.get_sequence_sql(style, f.m2m_db_table(), 'id') 276 286 return final_output 277 287 278 288 def get_sql_delete(app): … … 456 466 unique = f.unique and 'UNIQUE ' or '' 457 467 output.append( 458 468 style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ 459 style.SQL_TABLE( '%s_%s' % (model._meta.db_table, f.column)) + ' ' + \469 style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ 460 470 style.SQL_KEYWORD('ON') + ' ' + \ 461 471 style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \ 462 472 "(%s);" % style.SQL_FIELD(backend.quote_name(f.column)) -
django/contrib/redirects/models.py
4 4 5 5 class Redirect(models.Model): 6 6 site = models.ForeignKey(Site, radio_admin=models.VERTICAL) 7 old_path = models.CharField(_('redirect from'), maxlength= 200, db_index=True,7 old_path = models.CharField(_('redirect from'), maxlength=100, db_index=False, 8 8 help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'.")) 9 new_path = models.CharField(_('redirect to'), maxlength= 200, blank=True,9 new_path = models.CharField(_('redirect to'), maxlength=100, blank=True, 10 10 help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'.")) 11 11 12 12 class Meta: