def unbounded_varchar(fn): """Target database must support VARCHAR with no length""" return skip_if([ "firebird", "oracle", "mysql" ], "not supported by database" )(fn)
def selectone(fn): """target driver must support the literal statement 'select 1'""" return _chain_decorators_on( fn, skip_if(lambda: testing.against('oracle'), "non-standard SELECT scalar syntax") )
def standalone_binds(fn): """target database/driver supports bound parameters as column expressions without being in the context of a typed column. """ return skip_if(["firebird", "mssql+mxodbc"], "not supported by driver")(fn)
def binary_comparisons(fn): """target database/driver can allow BLOB/BINARY fields to be compared against a bound parameter value. """ return skip_if(["oracle", "mssql"], "not supported by database/driver" )(fn)
def python3(fn): return _chain_decorators_on( fn, skip_if( lambda: sys.version_info < (3,), "Python version 3.xx is required." ) )
def deferrable_or_no_constraints(fn): """Target database must support derferable constraints.""" return skip_if([ no_support('firebird', 'not supported by database'), no_support('mysql', 'not supported by database'), no_support('mssql', 'not supported by database'), ])(fn)
def python25(fn): return _chain_decorators_on( fn, skip_if( lambda: sys.version_info < (2, 5), "Python version 2.5 or greater is required" ) )
def schemas(fn): """Target database must support external schemas, and have one named 'test_schema'.""" return skip_if([ "sqlite", "firebird" ], "no schema support")(fn)
def denormalized_names(fn): """Target database must have 'denormalized', i.e. UPPERCASE as case insensitive names.""" return skip_if( lambda: not testing.db.dialect.requires_name_normalize, "Backend does not require denormalized names." )(fn)
def skip_mysql_on_windows(fn): """Catchall for a large variety of MySQL on Windows failures""" return _chain_decorators_on( fn, skip_if(_has_mysql_on_windows, "Not supported on MySQL + Windows" ) )
def savepoints(fn): """Target database must support savepoints.""" return skip_if([ "access", "sqlite", "sybase", ("mysql", "<", (5, 0, 3)), ("informix", "<", (11, 55, "xC3")) ], "savepoints not supported")(fn)
def boolean_col_expressions(fn): """Target database must support boolean expressions as columns""" return skip_if([ no_support('firebird', 'not supported by database'), no_support('oracle', 'not supported by database'), no_support('mssql', 'not supported by database'), no_support('sybase', 'not supported by database'), no_support('maxdb', 'FIXME: verify not supported by database'), no_support('informix', 'not supported by database'), ])(fn)
def unicode_ddl(fn): """Target driver must support some encoding of Unicode across the wire.""" # TODO: expand to exclude MySQLdb versions w/ broken unicode return skip_if([ no_support('maxdb', 'database support flakey'), no_support('oracle', 'FIXME: no support in database?'), no_support('sybase', 'FIXME: guessing, needs confirmation'), no_support('mssql+pymssql', 'no FreeTDS support'), exclude('mysql', '<', (4, 1, 1), 'no unicode connection support'), ])(fn)
def reflectable_autoincrement(fn): """Target database must support tables that can automatically generate PKs assuming they were reflected. this is essentially all the DBs in "identity" plus Postgresql, which has SERIAL support. FB and Oracle (and sybase?) require the Sequence to be explicitly added, including if the table was reflected. """ return skip_if(["firebird", "oracle", "sybase"], "not supported by database" )(fn)
def identity(fn): """Target database must support GENERATED AS IDENTITY or a facsimile. Includes GENERATED AS IDENTITY, AUTOINCREMENT, AUTO_INCREMENT, or other column DDL feature that fills in a DB-generated identifier at INSERT-time without requiring pre-execution of a SEQUENCE or other artifact. """ return skip_if(["firebird", "oracle", "postgresql", "sybase"], "not supported by database" )(fn)
def ad_hoc_engines(fn): """Test environment must allow ad-hoc engine/connection creation. DBs that scale poorly for many connections, even when closed, i.e. Oracle, may use the "--low-connections" option which flags this requirement as not present. """ return _chain_decorators_on( fn, skip_if(lambda: config.options.low_connections) )
def row_triggers(fn): """Target must support standard statement-running EACH ROW triggers.""" return skip_if([ # no access to same table no_support('mysql', 'requires SUPER priv'), exclude('mysql', '<', (5, 0, 10), 'not supported by database'), # huh? TODO: implement triggers for PG tests, remove this no_support('postgresql', 'PG triggers need to be implemented for tests'), ])(fn)
def independent_connections(fn): """Target must support simultaneous, independent database connections.""" # This is also true of some configurations of UnixODBC and probably win32 # ODBC as well. return skip_if([ no_support("sqlite", "independent connections disabled " "when :memory: connections are used"), exclude("mssql", "<", (9, 0, 0), "SQL Server 2005+ is required for " "independent connections" ) ] )(fn)
def two_phase_transactions(fn): """Target database must support two-phase transactions.""" return skip_if([ no_support('access', 'two-phase xact not supported by database'), no_support('firebird', 'no SA implementation'), no_support('maxdb', 'two-phase xact not supported by database'), no_support('mssql', 'two-phase xact not supported by drivers'), no_support('oracle', 'two-phase xact not implemented in SQLA/oracle'), no_support('drizzle', 'two-phase xact not supported by database'), no_support('sqlite', 'two-phase xact not supported by database'), no_support('sybase', 'two-phase xact not supported by drivers/SQLA'), no_support('postgresql+zxjdbc', 'FIXME: JDBC driver confuses the transaction state, may ' 'need separate XA implementation'), exclude('mysql', '<', (5, 0, 3), 'two-phase xact not supported by database'), ])(fn)
def sane_multi_rowcount(fn): return skip_if( lambda: not testing.db.dialect.supports_sane_multi_rowcount, "driver doesn't support 'sane' multi row count" )
def updateable_autoincrement_pks(fn): """Target must support UPDATE on autoincrement/integer primary key.""" return skip_if(["mssql", "sybase"], "IDENTITY columns can't be updated")(fn)
def correlated_outer_joins(fn): """Target must support an outer join to a subquery which correlates to the parent.""" return skip_if("oracle", 'Raises "ORA-01799: a column may not be ' 'outer-joined to a subquery"')(fn)
def foreign_keys(fn): """Target database must support foreign keys.""" return skip_if( no_support('sqlite', 'not supported by database') )(fn)
def update_nowait(fn): """Target database must support SELECT...FOR UPDATE NOWAIT""" return skip_if(["access", "firebird", "mssql", "mysql", "sqlite", "sybase"], "no FOR UPDATE NOWAIT support" )(fn)
def english_locale_on_postgresql(fn): return _chain_decorators_on( fn, skip_if(lambda: testing.against('postgresql') \ and not testing.db.scalar('SHOW LC_COLLATE').startswith('en')) )
def subqueries(fn): """Target database must support subqueries.""" return skip_if(exclude('mysql', '<', (4, 1, 1)), 'no subquery support')(fn)
def sqlite(fn): return _chain_decorators_on( fn, skip_if(lambda: not _has_sqlite()) )
def views(fn): """Target database must support VIEWs.""" return skip_if("drizzle", "no VIEW support")(fn)
def unicode_connections(fn): """Target driver must support some encoding of Unicode across the wire.""" # TODO: expand to exclude MySQLdb versions w/ broken unicode return skip_if([ exclude('mysql', '<', (4, 1, 1), 'no unicode connection support'), ])(fn)
def cextensions(fn): return skip_if( lambda: not _has_cextensions(), "C extensions not installed" )(fn)