X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fdb%2FDatabaseIbm_db2.php;h=ed37939747797fa28e9dbd14001cb6c56f7f3122;hb=f675c6bf054aea9c14b329366b23d2ae5e78fdb3;hp=a3a6829b775729770f9dc81de6cd02bbfafd90c8;hpb=cadc951d151d7519baade36bcd0e1e678d87b94b;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/db/DatabaseIbm_db2.php b/includes/db/DatabaseIbm_db2.php index a3a6829b77..ed37939747 100644 --- a/includes/db/DatabaseIbm_db2.php +++ b/includes/db/DatabaseIbm_db2.php @@ -114,7 +114,7 @@ class DatabaseIbm_db2 extends DatabaseBase { protected $mPHPError = false; protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname; - protected $mOut, $mOpened = false; + protected $mOpened = false; protected $mTablePrefix; protected $mFlags; @@ -144,7 +144,7 @@ class DatabaseIbm_db2 extends DatabaseBase { public $mStmtOptions = array(); /** Default schema */ - const USE_GLOBAL = 'mediawiki'; + const USE_GLOBAL = 'get from global'; /** Option that applies to nothing */ const NONE_OPTION = 0x00; @@ -245,11 +245,6 @@ class DatabaseIbm_db2 extends DatabaseBase { return 'ibm_db2'; } - ###################################### - # Setup - ###################################### - - /** * * @param $server String: hostname of database server @@ -259,19 +254,12 @@ class DatabaseIbm_db2 extends DatabaseBase { * @param $flags Integer: database behaviour flags (optional, unused) * @param $schema String */ - public function DatabaseIbm_db2( $server = false, $user = false, + public function __construct( $server = false, $user = false, $password = false, $dbName = false, $flags = 0, $schema = self::USE_GLOBAL ) { - - global $wgOut, $wgDBmwschema; - # Can't get a reference if it hasn't been set yet - if ( !isset( $wgOut ) ) { - $wgOut = null; - } - $this->mOut =& $wgOut; - $this->mFlags = DBO_TRX | $flags; + global $wgDBmwschema; if ( $schema == self::USE_GLOBAL ) { $this->mSchema = $wgDBmwschema; @@ -280,6 +268,10 @@ class DatabaseIbm_db2 extends DatabaseBase { } // configure the connection and statement objects + /* + $this->setDB2Option( 'cursor', 'DB2_SCROLLABLE', + self::CONN_OPTION | self::STMT_OPTION ); + */ $this->setDB2Option( 'db2_attr_case', 'DB2_CASE_LOWER', self::CONN_OPTION | self::STMT_OPTION ); $this->setDB2Option( 'deferred_prepare', 'DB2_DEFERRED_PREPARE_ON', @@ -287,7 +279,7 @@ class DatabaseIbm_db2 extends DatabaseBase { $this->setDB2Option( 'rowcount', 'DB2_ROWCOUNT_PREFETCH_ON', self::STMT_OPTION ); - $this->open( $server, $user, $password, $dbName ); + parent::__construct( $server, $user, $password, $dbName, DBO_TRX | $flags ); } /** @@ -333,26 +325,17 @@ class DatabaseIbm_db2 extends DatabaseBase { * @return a fresh connection */ public function open( $server, $user, $password, $dbName ) { - // Load the port number - global $wgDBport; wfProfileIn( __METHOD__ ); - // Load IBM DB2 driver if missing + # Load IBM DB2 driver if missing wfDl( 'ibm_db2' ); - // Test for IBM DB2 support, to avoid suppressed fatal error + # Test for IBM DB2 support, to avoid suppressed fatal error if ( !function_exists( 'db2_connect' ) ) { - $error = <<installPrint( $error ); - $this->reportConnectionError( $error ); + throw new DBConnectionError( $this, "DB2 functions missing, have you enabled the ibm_db2 extension for PHP?" ); } - if ( strlen( $user ) < 1 ) { - return null; - } + global $wgDBport; // Close existing connection $this->close(); @@ -365,22 +348,26 @@ ERROR; $this->openUncataloged( $dbName, $user, $password, $server, $port ); - // Apply connection config - db2_set_option( $this->mConn, $this->mConnOptions, 1 ); - // Some MediaWiki code is still transaction-less (?). - // The strategy is to keep AutoCommit on for that code - // but switch it off whenever a transaction is begun. - db2_autocommit( $this->mConn, DB2_AUTOCOMMIT_ON ); - if ( !$this->mConn ) { $this->installPrint( "DB connection error\n" ); $this->installPrint( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" ); $this->installPrint( $this->lastError() . "\n" ); - return null; + wfProfileOut( __METHOD__ ); + wfDebug( "DB connection error\n" ); + wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" ); + wfDebug( $this->lastError() . "\n" ); + throw new DBConnectionError( $this, $this->lastError() ); } + // Apply connection config + db2_set_option( $this->mConn, $this->mConnOptions, 1 ); + // Some MediaWiki code is still transaction-less (?). + // The strategy is to keep AutoCommit on for that code + // but switch it off whenever a transaction is begun. + db2_autocommit( $this->mConn, DB2_AUTOCOMMIT_ON ); + $this->mOpened = true; $this->applySchema(); @@ -400,16 +387,8 @@ ERROR; */ protected function openUncataloged( $dbName, $user, $password, $server, $port ) { - $str = "DRIVER={IBM DB2 ODBC DRIVER};"; - $str .= "DATABASE=$dbName;"; - $str .= "HOSTNAME=$server;"; - // port was formerly validated to not be 0 - $str .= "PORT=$port;"; - $str .= "PROTOCOL=TCPIP;"; - $str .= "UID=$user;"; - $str .= "PWD=$password;"; - - @$this->mConn = db2_pconnect( $str, $user, $password ); + $dsn = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$dbName;CHARSET=UTF-8;HOSTNAME=$server;PORT=$port;PROTOCOL=TCPIP;UID=$user;PWD=$password;"; + @$this->mConn = db2_pconnect($dsn, "", "", array()); } /** @@ -428,23 +407,6 @@ ERROR; } } - /** - * Returns a fresh instance of this class - * - * @param $server String: hostname of database server - * @param $user String: username - * @param $password String - * @param $dbName String: database name on the server - * @param $flags Integer: database behaviour flags (optional, unused) - * @return DatabaseIbm_db2 object - */ - static function newFromParams( $server, $user, $password, $dbName, - $flags = 0 ) - { - return new DatabaseIbm_db2( $server, $user, $password, $dbName, - $flags ); - } - /** * Retrieves the most current database error * Forces a database rollback @@ -496,10 +458,16 @@ ERROR; /*private*/ public function doQuery( $sql ) { $this->applySchema(); - + + // Needed to handle any UTF-8 encoding issues in the raw sql + // Note that we fully support prepared statements for DB2 + // prepare() and execute() should be used instead of doQuery() whenever possible + $sql = utf8_decode($sql); + $ret = db2_exec( $this->mConn, $sql, $this->mStmtOptions ); if( $ret == false ) { $error = db2_stmt_errormsg(); + $this->installPrint( "
$sql
" ); $this->installPrint( $error ); throw new DBUnexpectedError( $this, 'SQL error: ' @@ -524,10 +492,11 @@ ERROR; */ public function tableExists( $table ) { $schema = $this->mSchema; - $sql = <<< EOF -SELECT COUNT( * ) FROM SYSIBM.SYSTABLES ST -WHERE ST.NAME = '$table' AND ST.CREATOR = '$schema' -EOF; + + $sql = "SELECT COUNT( * ) FROM SYSIBM.SYSTABLES ST WHERE ST.NAME = '" . + strtoupper( $table ) . + "' AND ST.CREATOR = '" . + strtoupper( $schema ) . "'"; $res = $this->query( $sql ); if ( !$res ) { return false; @@ -576,12 +545,15 @@ EOF; if ( $res instanceof ResultWrapper ) { $res = $res->result; } - @$row = db2_fetch_array( $res ); - if ( $this->lastErrno() ) { - throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' - . htmlspecialchars( $this->lastError() ) ); + if ( db2_num_rows( $res ) > 0) { + @$row = db2_fetch_array( $res ); + if ( $this->lastErrno() ) { + throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' + . htmlspecialchars( $this->lastError() ) ); + } + return $row; } - return $row; + return false; } /** @@ -806,9 +778,10 @@ EOF; * Handle reserved keyword replacement in table names * * @param $name Object + * @param $name Boolean * @return String */ - public function tableName( $name ) { + public function tableName( $name, $quoted = true ) { // we want maximum compatibility with MySQL schema return $name; } @@ -924,9 +897,9 @@ EOF; } else { $sql .= '( ?' . str_repeat( ',?', $key_count-1 ) . ' )'; } - //$this->installPrint( "Preparing the following SQL:" ); - //$this->installPrint( "$sql" ); - //$this->installPrint( print_r( $args, true )); + $this->installPrint( "Preparing the following SQL:" ); + $this->installPrint( "$sql" ); + $this->installPrint( print_r( $args, true )); $stmt = $this->prepare( $sql ); // start a transaction/enter transaction mode @@ -958,7 +931,7 @@ EOF; $overhead = "SAVEPOINT $ignore ON ROLLBACK RETAIN CURSORS"; db2_exec( $this->mConn, $overhead, $this->mStmtOptions ); - $this->execute( $stmt, $row ); + $res2 = $this->execute( $stmt, $row ); if ( !$res2 ) { $this->installPrint( 'Last error:' ); @@ -999,18 +972,22 @@ EOF; */ private function removeNullPrimaryKeys( $table, $args ) { $schema = $this->mSchema; + // find out the primary keys - $keyres = db2_primary_keys( $this->mConn, null, strtoupper( $schema ), - strtoupper( $table ) - ); + $keyres = $this->doQuery( "SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = '" + . strtoupper( $table ) + . "' AND TBCREATOR = '" + . strtoupper( $schema ) + . "' AND KEYSEQ > 0" ); + $keys = array(); for ( - $row = $this->fetchObject( $keyres ); + $row = $this->fetchRow( $keyres ); $row != null; - $row = $this->fetchObject( $keyres ) + $row = $this->fetchRow( $keyres ) ) { - $keys[] = strtolower( $row->column_name ); + $keys[] = strtolower( $row[0] ); } // remove primary keys foreach ( $args as $ai => $row ) { @@ -1145,10 +1122,7 @@ EOF; } # Now insert the row - $sql = "INSERT INTO $table ( " - . $this->makeList( array_keys( $row ), LIST_NAMES ) - .' ) VALUES ( ' . $this->makeList( $row, LIST_COMMA ) . ' )'; - $this->query( $sql, $fname ); + $this->insert($table, $row); } } @@ -1162,6 +1136,7 @@ EOF; if ( $res instanceof ResultWrapper ) { $res = $res->result; } + if ( $this->mNumRows ) { return $this->mNumRows; } else { @@ -1526,7 +1501,7 @@ SQL; $sql = <<