From: Philip Jenvey Date: Tue, 11 Aug 2009 05:12:50 +0000 (+0000) Subject: move postgresql's % escape handling out of base X-Git-Tag: rel_0_6beta1~335 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1b43a06aaccf9ed17db7364896dab50761a44e34;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git move postgresql's % escape handling out of base --- diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 57f2161c13..321601a838 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -223,11 +223,6 @@ class PGCompiler(compiler.SQLCompiler): return '%s NOT ILIKE %s' % (self.process(binary.left), self.process(binary.right)) \ + (escape and ' ESCAPE \'%s\'' % escape or '') - def post_process_text(self, text): - if '%%' in text: - util.warn("The SQLAlchemy postgresql dialect now automatically escapes '%' in text() expressions to '%%'.") - return text.replace('%', '%%') - def visit_sequence(self, seq): if seq.optional: return None @@ -373,6 +368,7 @@ class PGDefaultRunner(base.DefaultRunner): else: return None + class PGTypeCompiler(compiler.GenericTypeCompiler): def visit_INET(self, type_): return "INET" @@ -425,16 +421,13 @@ class PGTypeCompiler(compiler.GenericTypeCompiler): def visit_ARRAY(self, type_): return self.process(type_.item_type) + '[]' + class PGIdentifierPreparer(compiler.IdentifierPreparer): def _unquote_identifier(self, value): if value[0] == self.initial_quote: - value = value[1:-1].replace('""','"') + value = value[1:-1].replace(self.escape_to_quote, self.escape_quote) return value - def _escape_identifier(self, value): - value = value.replace('"', '""') - # TODO: might want to move this to psycopg2 + pg8000 individually - return value.replace('%', '%%') class PGInspector(reflection.Inspector): diff --git a/lib/sqlalchemy/dialects/postgresql/pg8000.py b/lib/sqlalchemy/dialects/postgresql/pg8000.py index e8dd03113f..2a5c4e0325 100644 --- a/lib/sqlalchemy/dialects/postgresql/pg8000.py +++ b/lib/sqlalchemy/dialects/postgresql/pg8000.py @@ -22,7 +22,7 @@ from sqlalchemy.engine import default import decimal from sqlalchemy import util from sqlalchemy import types as sqltypes -from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler +from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler, PGIdentifierPreparer class _PGNumeric(sqltypes.Numeric): def bind_processor(self, dialect): @@ -39,13 +39,27 @@ class _PGNumeric(sqltypes.Numeric): return value return process + class PostgreSQL_pg8000ExecutionContext(default.DefaultExecutionContext): pass + class PostgreSQL_pg8000Compiler(PGCompiler): def visit_mod(self, binary, **kw): return self.process(binary.left) + " %% " + self.process(binary.right) - + + def post_process_text(self, text): + if '%%' in text: + util.warn("The SQLAlchemy postgresql dialect now automatically escapes '%' in text() " + "expressions to '%%'.") + return text.replace('%', '%%') + + +class PostgreSQL_pg8000IdentifierPreparer(PGIdentifierPreparer): + def _escape_identifier(self, value): + value = value.replace(self.escape_quote, self.escape_to_quote) + return value.replace('%', '%%') + class PostgreSQL_pg8000(PGDialect): driver = 'pg8000' @@ -58,6 +72,7 @@ class PostgreSQL_pg8000(PGDialect): supports_sane_multi_rowcount = False execution_ctx_cls = PostgreSQL_pg8000ExecutionContext statement_compiler = PostgreSQL_pg8000Compiler + preparer = PostgreSQL_pg8000IdentifierPreparer colspecs = util.update_copy( PGDialect.colspecs, diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index a428878ae0..973bacd068 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -42,7 +42,7 @@ from sqlalchemy.engine import base, default from sqlalchemy.sql import expression from sqlalchemy.sql import operators as sql_operators from sqlalchemy import types as sqltypes -from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler +from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler, PGIdentifierPreparer class _PGNumeric(sqltypes.Numeric): def bind_processor(self, dialect): @@ -93,6 +93,7 @@ class PostgreSQL_psycopg2ExecutionContext(default.DefaultExecutionContext): else: return base.ResultProxy(self) + class PostgreSQL_psycopg2Compiler(PGCompiler): def visit_mod(self, binary, **kw): return self.process(binary.left) + " %% " + self.process(binary.right) @@ -100,6 +101,13 @@ class PostgreSQL_psycopg2Compiler(PGCompiler): def post_process_text(self, text): return text.replace('%', '%%') + +class PostgreSQL_psycopg2IdentifierPreparer(PGIdentifierPreparer): + def _escape_identifier(self, value): + value = value.replace(self.escape_quote, self.escape_to_quote) + return value.replace('%', '%%') + + class PostgreSQL_psycopg2(PGDialect): driver = 'psycopg2' supports_unicode_statements = False @@ -107,6 +115,7 @@ class PostgreSQL_psycopg2(PGDialect): supports_sane_multi_rowcount = False execution_ctx_cls = PostgreSQL_psycopg2ExecutionContext statement_compiler = PostgreSQL_psycopg2Compiler + preparer = PostgreSQL_psycopg2IdentifierPreparer colspecs = util.update_copy( PGDialect.colspecs, diff --git a/lib/sqlalchemy/dialects/postgresql/zxjdbc.py b/lib/sqlalchemy/dialects/postgresql/zxjdbc.py index b707d2d9eb..7c540e46b2 100644 --- a/lib/sqlalchemy/dialects/postgresql/zxjdbc.py +++ b/lib/sqlalchemy/dialects/postgresql/zxjdbc.py @@ -7,18 +7,9 @@ The official Postgresql JDBC driver is at http://jdbc.postgresql.org/. """ from sqlalchemy.connectors.zxJDBC import ZxJDBCConnector -from sqlalchemy.dialects.postgresql.base import PGCompiler, PGDialect - -class PostgreSQL_jdbcCompiler(PGCompiler): - - def post_process_text(self, text): - # Don't escape '%' like PGCompiler - return text - +from sqlalchemy.dialects.postgresql.base import PGDialect class PostgreSQL_jdbc(ZxJDBCConnector, PGDialect): - statement_compiler = PostgreSQL_jdbcCompiler - jdbc_db_name = 'postgresql' jdbc_driver_name = 'org.postgresql.Driver'