mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #21844: Move quote_parameter off of Operations and rename
This commit is contained in:
		| @@ -975,15 +975,6 @@ class BaseDatabaseOperations(object): | ||||
|         """ | ||||
|         raise NotImplementedError('subclasses of BaseDatabaseOperations may require a quote_name() method') | ||||
|  | ||||
|     def quote_parameter(self, value): | ||||
|         """ | ||||
|         Returns a quoted version of the value so it's safe to use in an SQL | ||||
|         string. This should NOT be used to prepare SQL statements to send to | ||||
|         the database; it is meant for outputting SQL statements to a file | ||||
|         or the console for later execution by a developer/DBA. | ||||
|         """ | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     def random_function_sql(self): | ||||
|         """ | ||||
|         Returns an SQL expression that returns a random value. | ||||
|   | ||||
| @@ -311,11 +311,6 @@ class DatabaseOperations(BaseDatabaseOperations): | ||||
|             return name  # Quoting once is enough. | ||||
|         return "`%s`" % name | ||||
|  | ||||
|     def quote_parameter(self, value): | ||||
|         # Inner import to allow module to fail to load gracefully | ||||
|         import MySQLdb.converters | ||||
|         return MySQLdb.escape(value, MySQLdb.converters.conversions) | ||||
|  | ||||
|     def random_function_sql(self): | ||||
|         return 'RAND()' | ||||
|  | ||||
|   | ||||
| @@ -24,3 +24,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|  | ||||
|     sql_create_pk = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s PRIMARY KEY (%(columns)s)" | ||||
|     sql_delete_pk = "ALTER TABLE %(table)s DROP PRIMARY KEY" | ||||
|  | ||||
|     def quote_value(self, value): | ||||
|         # Inner import to allow module to fail to load gracefully | ||||
|         import MySQLdb.converters | ||||
|         return MySQLdb.escape(value, MySQLdb.converters.conversions) | ||||
|   | ||||
| @@ -326,16 +326,6 @@ WHEN (new.%(col_name)s IS NULL) | ||||
|         name = name.replace('%', '%%') | ||||
|         return name.upper() | ||||
|  | ||||
|     def quote_parameter(self, value): | ||||
|         if isinstance(value, (datetime.date, datetime.time, datetime.datetime)): | ||||
|             return "'%s'" % value | ||||
|         elif isinstance(value, six.string_types): | ||||
|             return repr(value) | ||||
|         elif isinstance(value, bool): | ||||
|             return "1" if value else "0" | ||||
|         else: | ||||
|             return str(value) | ||||
|  | ||||
|     def random_function_sql(self): | ||||
|         return "DBMS_RANDOM.RANDOM" | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| import copy | ||||
| import datetime | ||||
|  | ||||
| from django.utils import six | ||||
| from django.db.backends.schema import BaseDatabaseSchemaEditor | ||||
| from django.db.utils import DatabaseError | ||||
|  | ||||
| @@ -15,6 +17,16 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|     sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s" | ||||
|     sql_delete_table = "DROP TABLE %(table)s CASCADE CONSTRAINTS" | ||||
|  | ||||
|     def quote_value(self, value): | ||||
|         if isinstance(value, (datetime.date, datetime.time, datetime.datetime)): | ||||
|             return "'%s'" % value | ||||
|         elif isinstance(value, six.string_types): | ||||
|             return repr(value) | ||||
|         elif isinstance(value, bool): | ||||
|             return "1" if value else "0" | ||||
|         else: | ||||
|             return str(value) | ||||
|  | ||||
|     def delete_model(self, model): | ||||
|         # Run superclass action | ||||
|         super(DatabaseSchemaEditor, self).delete_model(model) | ||||
| @@ -92,4 +104,4 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|         return self.normalize_name(for_name + "_" + suffix) | ||||
|  | ||||
|     def prepare_default(self, value): | ||||
|         return self.connection.ops.quote_parameter(value) | ||||
|         return self.quote_value(value) | ||||
|   | ||||
| @@ -98,11 +98,6 @@ class DatabaseOperations(BaseDatabaseOperations): | ||||
|             return name  # Quoting once is enough. | ||||
|         return '"%s"' % name | ||||
|  | ||||
|     def quote_parameter(self, value): | ||||
|         # Inner import so backend fails nicely if it's not present | ||||
|         import psycopg2 | ||||
|         return psycopg2.extensions.adapt(value) | ||||
|  | ||||
|     def set_time_zone_sql(self): | ||||
|         return "SET TIME ZONE %s" | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,11 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|     sql_delete_sequence = "DROP SEQUENCE IF EXISTS %(sequence)s CASCADE" | ||||
|     sql_set_sequence_max = "SELECT setval('%(sequence)s', MAX(%(column)s)) FROM %(table)s" | ||||
|  | ||||
|     def quote_value(self, value): | ||||
|         # Inner import so backend fails nicely if it's not present | ||||
|         import psycopg2 | ||||
|         return psycopg2.extensions.adapt(value) | ||||
|  | ||||
|     def _alter_column_type_sql(self, table, column, type): | ||||
|         """ | ||||
|         Makes ALTER TYPE with SERIAL make sense. | ||||
|   | ||||
| @@ -89,7 +89,7 @@ class BaseDatabaseSchemaEditor(object): | ||||
|         # Log the command we're running, then run it | ||||
|         logger.debug("%s; (params %r)" % (sql, params)) | ||||
|         if self.collect_sql: | ||||
|             self.collected_sql.append((sql % tuple(map(self.connection.ops.quote_parameter, params))) + ";") | ||||
|             self.collected_sql.append((sql % tuple(map(self.quote_value, params))) + ";") | ||||
|         else: | ||||
|             with self.connection.cursor() as cursor: | ||||
|                 cursor.execute(sql, params) | ||||
| @@ -166,6 +166,16 @@ class BaseDatabaseSchemaEditor(object): | ||||
|             default = default() | ||||
|         return default | ||||
|  | ||||
|     def quote_value(self, value): | ||||
|         """ | ||||
|         Returns a quoted version of the value so it's safe to use in an SQL | ||||
|         string. This is not safe against injection from user code; it is | ||||
|         intended only for use in making SQL scripts or preparing default values | ||||
|         for particularly tricky backends (defaults are not user-defined, though, | ||||
|         so this is safe). | ||||
|         """ | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     # Actions | ||||
|  | ||||
|     def create_model(self, model): | ||||
|   | ||||
| @@ -215,25 +215,6 @@ class DatabaseOperations(BaseDatabaseOperations): | ||||
|             return name  # Quoting once is enough. | ||||
|         return '"%s"' % name | ||||
|  | ||||
|     def quote_parameter(self, value): | ||||
|         # Inner import to allow nice failure for backend if not present | ||||
|         import _sqlite3 | ||||
|         try: | ||||
|             value = _sqlite3.adapt(value) | ||||
|         except _sqlite3.ProgrammingError: | ||||
|             pass | ||||
|         # Manual emulation of SQLite parameter quoting | ||||
|         if isinstance(value, type(True)): | ||||
|             return str(int(value)) | ||||
|         elif isinstance(value, six.integer_types): | ||||
|             return str(value) | ||||
|         elif isinstance(value, six.string_types): | ||||
|             return '"%s"' % six.text_type(value) | ||||
|         elif value is None: | ||||
|             return "NULL" | ||||
|         else: | ||||
|             raise ValueError("Cannot quote parameter value %r" % value) | ||||
|  | ||||
|     def no_limit_value(self): | ||||
|         return -1 | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| from django.utils import six | ||||
| from django.apps.registry import Apps | ||||
| from django.db.backends.schema import BaseDatabaseSchemaEditor | ||||
| from django.db.models.fields.related import ManyToManyField | ||||
| @@ -8,6 +9,25 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|     sql_delete_table = "DROP TABLE %(table)s" | ||||
|     sql_create_inline_fk = "REFERENCES %(to_table)s (%(to_column)s)" | ||||
|  | ||||
|     def quote_value(self, value): | ||||
|         # Inner import to allow nice failure for backend if not present | ||||
|         import _sqlite3 | ||||
|         try: | ||||
|             value = _sqlite3.adapt(value) | ||||
|         except _sqlite3.ProgrammingError: | ||||
|             pass | ||||
|         # Manual emulation of SQLite parameter quoting | ||||
|         if isinstance(value, type(True)): | ||||
|             return str(int(value)) | ||||
|         elif isinstance(value, six.integer_types): | ||||
|             return str(value) | ||||
|         elif isinstance(value, six.string_types): | ||||
|             return '"%s"' % six.text_type(value) | ||||
|         elif value is None: | ||||
|             return "NULL" | ||||
|         else: | ||||
|             raise ValueError("Cannot quote parameter value %r" % value) | ||||
|  | ||||
|     def _remake_table(self, model, create_fields=[], delete_fields=[], alter_fields=[], rename_fields=[], override_uniques=None): | ||||
|         """ | ||||
|         Shortcut to transform a model from old_model into new_model | ||||
| @@ -31,7 +51,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|             body[field.name] = field | ||||
|             # If there's a default, insert it into the copy map | ||||
|             if field.has_default(): | ||||
|                 mapping[field.column] = self.connection.ops.quote_parameter( | ||||
|                 mapping[field.column] = self.quote_value( | ||||
|                     field.get_default() | ||||
|                 ) | ||||
|         # Add in any altered fields | ||||
|   | ||||
		Reference in New Issue
	
	Block a user