From: Mike Bayer Date: Fri, 12 Mar 2010 23:22:20 +0000 (+0000) Subject: consolidate unicode/CLOB handling X-Git-Tag: rel_0_6beta2~54^2~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f0093805515a76e8c53b80b5ed53dd21acb3195;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git consolidate unicode/CLOB handling --- diff --git a/lib/sqlalchemy/dialects/oracle/__init__.py b/lib/sqlalchemy/dialects/oracle/__init__.py index eb47e80cb2..78d3c8faba 100644 --- a/lib/sqlalchemy/dialects/oracle/__init__.py +++ b/lib/sqlalchemy/dialects/oracle/__init__.py @@ -5,11 +5,13 @@ base.dialect = cx_oracle.dialect from sqlalchemy.dialects.oracle.base import \ VARCHAR, NVARCHAR, CHAR, DATE, DATETIME, NUMBER,\ BLOB, BFILE, CLOB, NCLOB, TIMESTAMP, RAW,\ - FLOAT, DOUBLE_PRECISION, LONG, dialect, INTERVAL + FLOAT, DOUBLE_PRECISION, LONG, dialect, INTERVAL,\ + VARCHAR2, NVARCHAR2 __all__ = ( 'VARCHAR', 'NVARCHAR', 'CHAR', 'DATE', 'DATETIME', 'NUMBER', 'BLOB', 'BFILE', 'CLOB', 'NCLOB', 'TIMESTAMP', 'RAW', -'FLOAT', 'DOUBLE_PRECISION', 'LONG', 'dialect', 'INTERVAL' +'FLOAT', 'DOUBLE_PRECISION', 'LONG', 'dialect', 'INTERVAL', +'VARCHAR2', 'NVARCHAR2' ) diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index ffadc84f87..eccf11380d 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -120,7 +120,15 @@ from sqlalchemy import types as sqltypes from sqlalchemy.types import VARCHAR, NVARCHAR, CHAR, DATE, DATETIME, \ BLOB, CLOB, TIMESTAMP, FLOAT -RESERVED_WORDS = set('''SHARE RAW DROP BETWEEN FROM DESC OPTION PRIOR LONG THEN DEFAULT ALTER IS INTO MINUS INTEGER NUMBER GRANT IDENTIFIED ALL TO ORDER ON FLOAT DATE HAVING CLUSTER NOWAIT RESOURCE ANY TABLE INDEX FOR UPDATE WHERE CHECK SMALLINT WITH DELETE BY ASC REVOKE LIKE SIZE RENAME NOCOMPRESS NULL GROUP VALUES AS IN VIEW EXCLUSIVE COMPRESS SYNONYM SELECT INSERT EXISTS NOT TRIGGER ELSE CREATE INTERSECT PCTFREE DISTINCT USER CONNECT SET MODE OF UNIQUE VARCHAR2 VARCHAR LOCK OR CHAR DECIMAL UNION PUBLIC AND START UID COMMENT'''.split()) +RESERVED_WORDS = set('SHARE RAW DROP BETWEEN FROM DESC OPTION PRIOR LONG THEN ' + 'DEFAULT ALTER IS INTO MINUS INTEGER NUMBER GRANT IDENTIFIED ' + 'ALL TO ORDER ON FLOAT DATE HAVING CLUSTER NOWAIT RESOURCE ANY ' + 'TABLE INDEX FOR UPDATE WHERE CHECK SMALLINT WITH DELETE BY ASC ' + 'REVOKE LIKE SIZE RENAME NOCOMPRESS NULL GROUP VALUES AS IN VIEW ' + 'EXCLUSIVE COMPRESS SYNONYM SELECT INSERT EXISTS NOT TRIGGER ' + 'ELSE CREATE INTERSECT PCTFREE DISTINCT USER CONNECT SET MODE ' + 'OF UNIQUE VARCHAR2 VARCHAR LOCK OR CHAR DECIMAL UNION PUBLIC ' + 'AND START UID COMMENT'.split()) class RAW(sqltypes.LargeBinary): pass diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index c5e24cbb35..b9f567d344 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -100,19 +100,11 @@ class _LOBMixin(object): # return the cx_oracle.LOB directly. return None - super_process = super(_LOBMixin, self).result_processor(dialect, coltype) - if super_process: - def process(value): - if value is not None: - return super_process(value.read()) - else: - return super_process(value) - else: - def process(value): - if value is not None: - return value.read() - else: - return value + def process(value): + if value is not None: + return value.read() + else: + return value return process class _NativeUnicodeMixin(object): @@ -123,7 +115,7 @@ class _NativeUnicodeMixin(object): return None elif self.convert_unicode != 'force' and \ dialect._cx_oracle_native_nvarchar and \ - coltype == dialect.dbapi.UNICODE: + coltype in dialect._cx_oracle_unicode_types: return None else: return super(_NativeUnicodeMixin, self).result_processor(dialect, coltype) @@ -143,27 +135,23 @@ class _OracleText(_LOBMixin, sqltypes.Text): class _OracleString(_NativeUnicodeMixin, sqltypes.String): pass -class _OracleUnicodeText(_NativeUnicodeMixin, sqltypes.UnicodeText): +class _OracleUnicodeText(_LOBMixin, _NativeUnicodeMixin, sqltypes.UnicodeText): def get_dbapi_type(self, dbapi): return dbapi.NCLOB def result_processor(self, dialect, coltype): - if not dialect.auto_convert_lobs: - # return the cx_oracle.LOB directly. + lob_processor = _LOBMixin.result_processor(self, dialect, coltype) + if lob_processor is None: return None - if dialect._cx_oracle_native_nvarchar: + string_processor = _NativeUnicodeMixin.result_processor(self, dialect, coltype) + + if string_processor is None: + return lob_processor + else: def process(value): - if value is not None: - return value.read() - else: - return value + return string_processor(lob_processor(value)) return process - else: - # TODO: this is wrong - we are getting a LOB here - # no matter what version of oracle, so process() - # is still needed - return super(_OracleUnicodeText, self).result_processor(dialect, coltype) class _OracleInteger(sqltypes.Integer): def result_processor(self, dialect, coltype): @@ -352,17 +340,19 @@ class Oracle_cx_oracle(OracleDialect): if self.dbapi is not None and not hasattr(self.dbapi, 'UNICODE'): # cx_Oracle WITH_UNICODE mode. *only* python # unicode objects accepted for anything - self._cx_oracle_string_types = set([self.dbapi.STRING]) + self._cx_oracle_string_types = set([self.dbapi.STRING, self.dbapi.NCLOB]) self.supports_unicode_statements = True self.supports_unicode_binds = True self._cx_oracle_with_unicode = True else: self._cx_oracle_with_unicode = False if self.dbapi is not None: - self._cx_oracle_string_types = set([self.dbapi.UNICODE, self.dbapi.STRING]) + self._cx_oracle_string_types = set([self.dbapi.UNICODE, self.dbapi.NCLOB, self.dbapi.STRING]) + self._cx_oracle_unicode_types = set([self.dbapi.UNICODE, self.dbapi.NCLOB]) else: self._cx_oracle_string_types = set() - + + if self.dbapi is None or \ not self.auto_convert_lobs or \ not hasattr(self.dbapi, 'CLOB'):