From: Jure Kajzer Date: Tue, 7 Jun 2011 05:09:32 +0000 (+0000) Subject: * fixed table duplication for unit tests X-Git-Tag: 1.31.0-rc.0~29644 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=4922a1cbdaeff0922b8e3b6a0616bbd69bd44d66 * fixed table duplication for unit tests * fixed sequence handling when using DB prefix * deferring constraints on transaction, switching back to immediate on commit/rollback * hardcoded NLS_NUMERIC_CHARACTERS as it breaks using floats in sql if connection is in a non-US-like NLS_LANG (all vars are bound as chars) --- diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index 23d7249e07..b298545821 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -278,6 +278,7 @@ class DatabaseOracle extends DatabaseBase { # removed putenv calls because they interfere with the system globaly $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' ); $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' ); + $this->doQuery( 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS=\'.,\'' ); return $this->mConn; } @@ -298,7 +299,7 @@ class DatabaseOracle extends DatabaseBase { } function execFlags() { - return $this->mTrxLevel ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS; + return $this->mTrxLevel ? OCI_NO_AUTO_COMMIT : OCI_COMMIT_ON_SUCCESS; } function doQuery( $sql ) { @@ -548,7 +549,7 @@ class DatabaseOracle extends DatabaseBase { } $val = ( $wgContLang != null ) ? $wgContLang->checkTitleEncoding( $val ) : $val; - if ( oci_bind_by_name( $stmt, ":$col", $val ) === false ) { + if ( oci_bind_by_name( $stmt, ":$col", $val, -1, SQLT_CHR ) === false ) { $e = oci_error( $stmt ); $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); return false; @@ -686,7 +687,14 @@ class DatabaseOracle extends DatabaseBase { */ private function getSequenceData( $table ) { if ( $this->sequenceData == null ) { - $result = $this->doQuery( 'SELECT lower(us.sequence_name), lower(utc.table_name), lower(utc.column_name) from user_sequences us, user_tab_columns utc where us.sequence_name = utc.table_name||\'_\'||utc.column_name||\'_SEQ\'' ); + $result = $this->doQuery( "SELECT lower(asq.sequence_name), + lower(atc.table_name), + lower(atc.column_name) + FROM all_sequences asq, all_tab_columns atc + WHERE decode(atc.table_name, '{$this->mTablePrefix}MWUSER', '{$this->mTablePrefix}USER', atc.table_name) || '_' || + atc.column_name || '_SEQ' = '{$this->mTablePrefix}' || asq.sequence_name + AND asq.sequence_owner = '{$this->mDBname}' + AND atc.owner = '{$this->mDBname}'" ); while ( ( $row = $result->fetchRow() ) !== false ) { $this->sequenceData[$this->tableName( $row[1] )] = array( @@ -695,7 +703,7 @@ class DatabaseOracle extends DatabaseBase { ); } } - + $table = strtolower( $this->removeIdentifierQuotes( $this->tableName( $table ) ) ); return ( isset( $this->sequenceData[$table] ) ) ? $this->sequenceData[$table] : false; } @@ -810,19 +818,15 @@ class DatabaseOracle extends DatabaseBase { } function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseOracle::duplicateTableStructure' ) { - global $wgDBprefix; - $this->setFlag( DBO_DDLMODE ); - $temporary = $temporary ? 'TRUE' : 'FALSE'; $newName = strtoupper( $newName ); $oldName = strtoupper( $oldName ); - $tabName = substr( $newName, strlen( $wgDBprefix ) ); + $tabName = substr( $newName, strlen( $this->mTablePrefix ) ); $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) ); - $newPrefix = strtoupper( $wgDBprefix ); + $newPrefix = strtoupper( $this->mTablePrefix ); - $this->clearFlag( DBO_DDLMODE ); return $this->doQuery( "BEGIN DUPLICATE_TABLE( '$tabName', '$oldPrefix', '$newPrefix', $temporary ); END;" ); } @@ -936,7 +940,7 @@ class DatabaseOracle extends DatabaseBase { } else { $count = 0; } - return $count != 0; + return $count; } /** @@ -1010,12 +1014,17 @@ class DatabaseOracle extends DatabaseBase { function begin( $fname = 'DatabaseOracle::begin' ) { $this->mTrxLevel = 1; + $this->doQuery( 'SET CONSTRAINTS ALL DEFERRED' ); } function commit( $fname = 'DatabaseOracle::commit' ) { if ( $this->mTrxLevel ) { - oci_commit( $this->mConn ); + $ret = oci_commit( $this->mConn ); + if ( !$ret ) { + throw new DBUnexpectedError( $this, $this->lastError() ); + } $this->mTrxLevel = 0; + $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' ); } } @@ -1023,6 +1032,7 @@ class DatabaseOracle extends DatabaseBase { if ( $this->mTrxLevel ) { oci_rollback( $this->mConn ); $this->mTrxLevel = 0; + $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' ); } } diff --git a/maintenance/oracle/archives/patch_rebuild_dupfunc.sql b/maintenance/oracle/archives/patch_rebuild_dupfunc.sql index 7d637da45c..0a232dbc2c 100644 --- a/maintenance/oracle/archives/patch_rebuild_dupfunc.sql +++ b/maintenance/oracle/archives/patch_rebuild_dupfunc.sql @@ -6,6 +6,7 @@ CREATE OR REPLACE PROCEDURE duplicate_table(p_tabname IN VARCHAR2, e_table_not_exist EXCEPTION; PRAGMA EXCEPTION_INIT(e_table_not_exist, -00942); l_temp_ei_sql VARCHAR2(2000); + l_temporary BOOLEAN := p_temporary; BEGIN BEGIN EXECUTE IMMEDIATE 'DROP TABLE ' || p_newprefix || p_tabname || @@ -14,7 +15,10 @@ BEGIN WHEN e_table_not_exist THEN NULL; END; - IF (p_temporary) THEN + IF (p_tabname = 'SEARCHINDEX') THEN + l_temporary := FALSE; + END IF; + IF (l_temporary) THEN EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ' || p_newprefix || p_tabname || ' AS SELECT * FROM ' || p_oldprefix || p_tabname || ' WHERE ROWNUM = 0'; @@ -53,7 +57,7 @@ BEGIN EXECUTE IMMEDIATE l_temp_ei_sql; END IF; END LOOP; - IF (NOT p_temporary) THEN + IF (NOT l_temporary) THEN FOR rc IN (SELECT REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('REF_CONSTRAINT', constraint_name), 32767, @@ -98,6 +102,29 @@ BEGIN EXECUTE IMMEDIATE l_temp_ei_sql; END IF; END LOOP; + FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', + index_name), + 32767, + 1), + USER || '"."' || p_oldprefix, + USER || '"."' || p_newprefix), + '"' || index_name || '"', + '"' || p_newprefix || index_name || '"') DDLVC2, + index_name, + index_type + FROM user_indexes ui + WHERE table_name = p_oldprefix || p_tabname + AND index_type = 'DOMAIN' + AND NOT EXISTS + (SELECT NULL + FROM user_constraints + WHERE table_name = ui.table_name + AND constraint_name = ui.index_name)) LOOP + l_temp_ei_sql := rc.ddlvc2; + IF nvl(length(l_temp_ei_sql), 0) > 0 THEN + EXECUTE IMMEDIATE l_temp_ei_sql; + END IF; + END LOOP; FOR rc IN (SELECT REPLACE(REPLACE(UPPER(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('TRIGGER', trigger_name), 32767, diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql index 53979d2cff..54bafd0a86 100644 --- a/maintenance/oracle/tables.sql +++ b/maintenance/oracle/tables.sql @@ -718,6 +718,7 @@ CREATE OR REPLACE PROCEDURE duplicate_table(p_tabname IN VARCHAR2, e_table_not_exist EXCEPTION; PRAGMA EXCEPTION_INIT(e_table_not_exist, -00942); l_temp_ei_sql VARCHAR2(2000); + l_temporary BOOLEAN := p_temporary; BEGIN BEGIN EXECUTE IMMEDIATE 'DROP TABLE ' || p_newprefix || p_tabname || @@ -726,7 +727,10 @@ BEGIN WHEN e_table_not_exist THEN NULL; END; - IF (p_temporary) THEN + IF (p_tabname = 'SEARCHINDEX') THEN + l_temporary := FALSE; + END IF; + IF (l_temporary) THEN EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ' || p_newprefix || p_tabname || ' AS SELECT * FROM ' || p_oldprefix || p_tabname || ' WHERE ROWNUM = 0'; @@ -765,7 +769,7 @@ BEGIN EXECUTE IMMEDIATE l_temp_ei_sql; END IF; END LOOP; - IF (NOT p_temporary) THEN + IF (NOT l_temporary) THEN FOR rc IN (SELECT REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('REF_CONSTRAINT', constraint_name), 32767, @@ -810,6 +814,29 @@ BEGIN EXECUTE IMMEDIATE l_temp_ei_sql; END IF; END LOOP; + FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', + index_name), + 32767, + 1), + USER || '"."' || p_oldprefix, + USER || '"."' || p_newprefix), + '"' || index_name || '"', + '"' || p_newprefix || index_name || '"') DDLVC2, + index_name, + index_type + FROM user_indexes ui + WHERE table_name = p_oldprefix || p_tabname + AND index_type = 'DOMAIN' + AND NOT EXISTS + (SELECT NULL + FROM user_constraints + WHERE table_name = ui.table_name + AND constraint_name = ui.index_name)) LOOP + l_temp_ei_sql := rc.ddlvc2; + IF nvl(length(l_temp_ei_sql), 0) > 0 THEN + EXECUTE IMMEDIATE l_temp_ei_sql; + END IF; + END LOOP; FOR rc IN (SELECT REPLACE(REPLACE(UPPER(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('TRIGGER', trigger_name), 32767, @@ -827,6 +854,7 @@ BEGIN END IF; END LOOP; END; + /*$mw$*/ /*$mw$*/