|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // $Id$ 00004 // 00005 // Definition of eZMySQLiDB class 00006 // 00007 // Created on: <12-Feb-2002 15:54:17 bf> 00008 // 00009 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00010 // SOFTWARE NAME: eZ Publish 00011 // SOFTWARE RELEASE: 4.0.x 00012 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00013 // SOFTWARE LICENSE: GNU General Public License v2.0 00014 // NOTICE: > 00015 // This program is free software; you can redistribute it and/or 00016 // modify it under the terms of version 2.0 of the GNU General 00017 // Public License as published by the Free Software Foundation. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 // GNU General Public License for more details. 00023 // 00024 // You should have received a copy of version 2.0 of the GNU General 00025 // Public License along with this program; if not, write to the Free 00026 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00027 // MA 02110-1301, USA. 00028 // 00029 // 00030 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00031 // 00032 00033 /*! 00034 \class eZMySQLiDB eZMySQLiDB.php 00035 \ingroup eZDB 00036 \brief The eZMySQLiDB class provides MySQL implementation of the database interface. 00037 00038 eZMySQLiDB is the MySQL implementation of eZDB. 00039 \sa eZDB 00040 */ 00041 00042 //require_once( "lib/ezutils/classes/ezdebug.php" ); 00043 ////include_once( "lib/ezutils/classes/ezini.php" ); 00044 //include_once( "lib/ezdb/classes/ezdbinterface.php" ); 00045 00046 class eZMySQLiDB extends eZDBInterface 00047 { 00048 /*! 00049 Create a new eZMySQLiDB object and connects to the database backend. 00050 */ 00051 function eZMySQLiDB( $parameters ) 00052 { 00053 $this->eZDBInterface( $parameters ); 00054 00055 $this->CharsetMapping = array( 'iso-8859-1' => 'latin1', 00056 'iso-8859-2' => 'latin2', 00057 'iso-8859-8' => 'hebrew', 00058 'iso-8859-7' => 'greek', 00059 'iso-8859-9' => 'latin5', 00060 'iso-8859-13' => 'latin7', 00061 'windows-1250' => 'cp1250', 00062 'windows-1251' => 'cp1251', 00063 'windows-1256' => 'cp1256', 00064 'windows-1257' => 'cp1257', 00065 'utf-8' => 'utf8', 00066 'koi8-r' => 'koi8r', 00067 'koi8-u' => 'koi8u' ); 00068 00069 if ( !extension_loaded( 'mysqli' ) ) 00070 { 00071 if ( function_exists( 'eZAppendWarningItem' ) ) 00072 { 00073 eZAppendWarningItem( array( 'error' => array( 'type' => 'ezdb', 00074 'number' => eZDBInterface::ERROR_MISSING_EXTENSION ), 00075 'text' => 'MySQLi extension was not found, the DB handler will not be initialized.' ) ); 00076 $this->IsConnected = false; 00077 } 00078 eZDebug::writeWarning( 'MySQLi extension was not found, the DB handler will not be initialized.', 'eZMySQLiDB' ); 00079 return; 00080 } 00081 00082 /// Connect to master server 00083 if ( !is_object( $this->DBWriteConnection ) ) 00084 { 00085 $connection = $this->connect( $this->Server, $this->DB, $this->User, $this->Password, $this->SocketPath, $this->Charset ); 00086 if ( $this->IsConnected ) 00087 { 00088 $this->DBWriteConnection = $connection; 00089 } 00090 } 00091 00092 // Connect to slave 00093 if ( !is_object( $this->DBConnection ) ) 00094 { 00095 if ( $this->UseSlaveServer === true ) 00096 { 00097 $connection = $this->connect( $this->SlaveServer, $this->SlaveDB, $this->SlaveUser, $this->SlavePassword, $this->SocketPath, $this->Charset ); 00098 } 00099 else 00100 { 00101 $connection = $this->DBWriteConnection; 00102 } 00103 00104 if ( $connection and $this->DBWriteConnection ) 00105 { 00106 $this->DBConnection = $connection; 00107 $this->IsConnected = true; 00108 } 00109 } 00110 00111 // Initialize TempTableList 00112 $this->TempTableList = array(); 00113 00114 eZDebug::createAccumulatorGroup( 'mysqli_total', 'Mysql Total' ); 00115 } 00116 00117 /*! 00118 \private 00119 Opens a new connection to a MySQL database and returns the connection 00120 */ 00121 function connect( $server, $db, $user, $password, $socketPath, $charset = null, $port = false ) 00122 { 00123 $connection = false; 00124 00125 if ( $socketPath !== false ) 00126 { 00127 ini_set( "mysqli.default_socket", $socketPath ); 00128 } 00129 00130 if ( $this->UsePersistentConnection == true ) 00131 { 00132 eZDebug::writeWarning( 'mysqli does not support persistent connections', 'eZMySQLiDB::connect' ); 00133 } 00134 00135 $connection = mysqli_connect( $server, $user, $password, null, $port, $socketPath ); 00136 00137 $dbErrorText = mysqli_connect_error(); 00138 $maxAttempts = $this->connectRetryCount(); 00139 $waitTime = $this->connectRetryWaitTime(); 00140 $numAttempts = 1; 00141 while ( !is_object( $connection ) and $numAttempts <= $maxAttempts ) 00142 { 00143 sleep( $waitTime ); 00144 if ( $this->UsePersistentConnection == true ) 00145 { 00146 eZDebug::writeWarning( 'mysqli does not support persistent connections', 'eZMySQLiDB::connect' ); 00147 } 00148 00149 $connection = mysqli_connect( $this->Server, $this->User, $this->Password, null, $this->Port, $this->SocketPath ); 00150 00151 $numAttempts++; 00152 } 00153 $this->setError(); 00154 00155 $this->IsConnected = true; 00156 00157 if ( !is_object( $connection ) ) 00158 { 00159 eZDebug::writeError( "Connection error: Couldn't connect to database. Please try again later or inform the system administrator.\n$dbErrorText", "eZMySQLiDB" ); 00160 $this->IsConnected = false; 00161 } 00162 00163 if ( $this->IsConnected && $db != null ) 00164 { 00165 $ret = mysqli_select_db( $connection, $db ); 00166 //$this->setError(); 00167 if ( !$ret ) 00168 { 00169 eZDebug::writeError( "Connection error: " . mysqli_errno( $connection ) . ": " . mysqli_error( $connection ), "eZMySQLiDB" ); 00170 $this->IsConnected = false; 00171 } 00172 } 00173 00174 if ( $charset !== null ) 00175 { 00176 $originalCharset = $charset; 00177 ////include_once( 'lib/ezi18n/classes/ezcharsetinfo.php' ); 00178 $charset = eZCharsetInfo::realCharsetCode( $charset ); 00179 // Convert charset names into something MySQL will understand 00180 if ( isset( $this->CharsetMapping[ $charset ] ) ) 00181 $charset = $this->CharsetMapping[ $charset ]; 00182 } 00183 00184 if ( $this->IsConnected and $charset !== null and $this->isCharsetSupported( $charset ) ) 00185 { 00186 $status = mysqli_set_charset( $connection, $charset ); 00187 if ( !$status ) 00188 { 00189 $this->setError(); 00190 eZDebug::writeWarning( "Connection warning: " . mysqli_errno( $connection ) . ": " . mysqli_error( $connection ), "eZMySQLiDB" ); 00191 } 00192 } 00193 00194 return $connection; 00195 } 00196 00197 /*! 00198 \reimp 00199 */ 00200 function databaseName() 00201 { 00202 return 'mysql'; 00203 } 00204 00205 /*! 00206 \reimp 00207 */ 00208 function bindingType( ) 00209 { 00210 return eZDBInterface::BINDING_NO; 00211 } 00212 00213 /*! 00214 \reimp 00215 */ 00216 function bindVariable( $value, $fieldDef = false ) 00217 { 00218 return $value; 00219 } 00220 00221 /*! 00222 Checks if the requested character set matches the one used in the database. 00223 00224 \return \c true if it matches or \c false if it differs. 00225 \param[out] $currentCharset The charset that the database uses. 00226 will only be set if the match fails. 00227 Note: This will be specific to the database. 00228 00229 \note There will be no check for databases using MySQL 4.1.0 or lower since 00230 they do not have proper character set handling. 00231 */ 00232 function checkCharset( $charset, &$currentCharset ) 00233 { 00234 // If we don't have a database yet we shouldn't check it 00235 if ( !$this->DB ) 00236 return true; 00237 00238 $versionInfo = $this->databaseServerVersion(); 00239 00240 // We require MySQL 4.1.1 to use the new character set functionality, 00241 // MySQL 4.1.0 does not have a full implementation of this, see: 00242 // http://dev.mysql.com/doc/mysql/en/Charset.html 00243 // Older version should not check character sets 00244 if ( version_compare( $versionInfo['string'], '4.1.1' ) < 0 ) 00245 return true; 00246 00247 ////include_once( 'lib/ezi18n/classes/ezcharsetinfo.php' ); 00248 00249 if ( is_array( $charset ) ) 00250 { 00251 foreach ( $charset as $charsetItem ) 00252 $realCharset[] = eZCharsetInfo::realCharsetCode( $charsetItem ); 00253 } 00254 else 00255 $realCharset = eZCharsetInfo::realCharsetCode( $charset ); 00256 00257 return $this->checkCharsetPriv( $realCharset, $currentCharset ); 00258 } 00259 00260 /*! 00261 \private 00262 */ 00263 function checkCharsetPriv( $charset, &$currentCharset ) 00264 { 00265 $query = "SHOW CREATE DATABASE `{$this->DB}`"; 00266 $status = mysqli_query( $this->DBConnection, $query ); 00267 $this->reportQuery( 'eZMySQLiDB', $query, false, false ); 00268 if ( !$status ) 00269 { 00270 $this->setError(); 00271 eZDebug::writeWarning( "Connection warning: " . mysqli_errno( $this->DBConnection ) . ": " . mysqli_error( $this->DBConnection ), "eZMySQLiDB" ); 00272 return false; 00273 } 00274 00275 $numRows = mysqli_num_rows( $status ); 00276 if ( $numRows == 0 ) 00277 return false; 00278 00279 for ( $i = 0; $i < $numRows; ++$i ) 00280 { 00281 $tmpRow = mysqli_fetch_array( $status, MYSQLI_ASSOC ); 00282 if ( $tmpRow['Database'] == $this->DB ) 00283 { 00284 $createText = $tmpRow['Create Database']; 00285 if ( preg_match( '#DEFAULT CHARACTER SET ([a-zA-Z0-9_-]+)#', $createText, $matches ) ) 00286 { 00287 $currentCharset = $matches[1]; 00288 ////include_once( 'lib/ezi18n/classes/ezcharsetinfo.php' ); 00289 $currentCharset = eZCharsetInfo::realCharsetCode( $currentCharset ); 00290 // Convert charset names into something MySQL will understand 00291 00292 $key = array_search( $currentCharset, $this->CharsetMapping ); 00293 $unmappedCurrentCharset = ( $key === false ) ? $currentCharset : $key; 00294 00295 if ( is_array( $charset ) ) 00296 { 00297 if ( in_array( $unmappedCurrentCharset, $charset ) ) 00298 { 00299 return $unmappedCurrentCharset; 00300 } 00301 } 00302 else if ( $unmappedCurrentCharset == $charset ) 00303 { 00304 return true; 00305 } 00306 return false; 00307 } 00308 break; 00309 } 00310 } 00311 return true; 00312 } 00313 00314 /*! 00315 \reimp 00316 */ 00317 function query( $sql, $server = false ) 00318 { 00319 if ( $this->IsConnected ) 00320 { 00321 eZDebug::accumulatorStart( 'mysqli_query', 'mysqli_total', 'Mysqli_queries' ); 00322 $orig_sql = $sql; 00323 // The converted sql should not be output 00324 if ( $this->InputTextCodec ) 00325 { 00326 eZDebug::accumulatorStart( 'mysqli_conversion', 'mysqli_total', 'String conversion in mysqli' ); 00327 $sql = $this->InputTextCodec->convertString( $sql ); 00328 eZDebug::accumulatorStop( 'mysqli_conversion' ); 00329 } 00330 00331 if ( $this->OutputSQL ) 00332 { 00333 $this->startTimer(); 00334 } 00335 00336 $sql = trim( $sql ); 00337 00338 // Check if we need to use the master or slave server by default 00339 if ( $server === false ) 00340 { 00341 $server = strncasecmp( $sql, 'select', 6 ) === 0 && $this->TransactionCounter == 0 ? 00342 eZDBInterface::SERVER_SLAVE : eZDBInterface::SERVER_MASTER; 00343 } 00344 00345 $connection = ( $server == eZDBInterface::SERVER_SLAVE ) ? $this->DBConnection : $this->DBWriteConnection; 00346 00347 $analysisText = false; 00348 // If query analysis is enable we need to run the query 00349 // with an EXPLAIN in front of it 00350 // Then we build a human-readable table out of the result 00351 if ( $this->QueryAnalysisOutput ) 00352 { 00353 $analysisResult = mysqli_query( $connection, 'EXPLAIN ' . $sql ); 00354 if ( $analysisResult ) 00355 { 00356 $numRows = mysqli_num_rows( $analysisResult ); 00357 $rows = array(); 00358 if ( $numRows > 0 ) 00359 { 00360 for ( $i = 0; $i < $numRows; ++$i ) 00361 { 00362 if ( $this->InputTextCodec ) 00363 { 00364 $tmpRow = mysqli_fetch_array( $analysisResult, MYSQLI_ASSOC ); 00365 $convRow = array(); 00366 foreach( $tmpRow as $key => $row ) 00367 { 00368 $convRow[$key] = $this->OutputTextCodec->convertString( $row ); 00369 } 00370 $rows[$i] = $convRow; 00371 } 00372 else 00373 $rows[$i] = mysqli_fetch_array( $analysisResult, MYSQLI_ASSOC ); 00374 } 00375 } 00376 00377 // Figure out all columns and their maximum display size 00378 $columns = array(); 00379 foreach ( $rows as $row ) 00380 { 00381 foreach ( $row as $col => $data ) 00382 { 00383 if ( !isset( $columns[$col] ) ) 00384 $columns[$col] = array( 'name' => $col, 00385 'size' => strlen( $col ) ); 00386 $columns[$col]['size'] = max( $columns[$col]['size'], strlen( $data ) ); 00387 } 00388 } 00389 00390 $analysisText = ''; 00391 $delimiterLine = array(); 00392 // Generate the column line and the vertical delimiter 00393 // The look of the table is taken from the MySQL CLI client 00394 // It looks like this: 00395 // +-------+-------+ 00396 // | col_a | col_b | 00397 // +-------+-------+ 00398 // | txt | 42 | 00399 // +-------+-------+ 00400 foreach ( $columns as $col ) 00401 { 00402 $delimiterLine[] = str_repeat( '-', $col['size'] + 2 ); 00403 $colLine[] = ' ' . str_pad( $col['name'], $col['size'], ' ', STR_PAD_RIGHT ) . ' '; 00404 } 00405 $delimiterLine = '+' . join( '+', $delimiterLine ) . "+\n"; 00406 $analysisText = $delimiterLine; 00407 $analysisText .= '|' . join( '|', $colLine ) . "|\n"; 00408 $analysisText .= $delimiterLine; 00409 00410 // Go trough all data and pad them to create the table correctly 00411 foreach ( $rows as $row ) 00412 { 00413 $rowLine = array(); 00414 foreach ( $columns as $col ) 00415 { 00416 $name = $col['name']; 00417 $size = $col['size']; 00418 $data = isset( $row[$name] ) ? $row[$name] : ''; 00419 // Align numerical values to the right (ie. pad left) 00420 $rowLine[] = ' ' . str_pad( $row[$name], $size, ' ', 00421 is_numeric( $row[$name] ) ? STR_PAD_LEFT : STR_PAD_RIGHT ) . ' '; 00422 } 00423 $analysisText .= '|' . join( '|', $rowLine ) . "|\n"; 00424 $analysisText .= $delimiterLine; 00425 } 00426 00427 // Reduce memory usage 00428 unset( $rows, $delimiterLine, $colLine, $columns ); 00429 } 00430 } 00431 00432 $result = mysqli_query( $connection, $sql ); 00433 00434 if ( $this->RecordError and !$result ) 00435 $this->setError(); 00436 00437 if ( $this->OutputSQL ) 00438 { 00439 $this->endTimer(); 00440 00441 if ($this->timeTaken() > $this->SlowSQLTimeout) 00442 { 00443 $num_rows = mysqli_affected_rows( $connection ); 00444 $text = $sql; 00445 00446 // If we have some analysis text we append this to the SQL output 00447 if ( $analysisText !== false ) 00448 $text = "EXPLAIN\n" . $text . "\n\nANALYSIS:\n" . $analysisText; 00449 00450 $this->reportQuery( ( $server == eZDBInterface::SERVER_MASTER ? 'on master : ' : '' ) . 'eZMySQLiDB', $text, $num_rows, $this->timeTaken() ); 00451 } 00452 } 00453 eZDebug::accumulatorStop( 'mysqli_query' ); 00454 if ( $result ) 00455 { 00456 return $result; 00457 } 00458 else 00459 { 00460 eZDebug::writeError( 'Query error (' . mysqli_errno( $connection ) . '): ' . mysqli_error( $connection ) . '. Query: ' . $sql, "eZMySQLiDB" ); 00461 $oldRecordError = $this->RecordError; 00462 // Turn off error handling while we unlock 00463 $this->RecordError = false; 00464 mysqli_query( $connection, 'UNLOCK TABLES' ); 00465 $this->RecordError = $oldRecordError; 00466 00467 $this->reportError(); 00468 00469 return false; 00470 } 00471 } 00472 else 00473 { 00474 eZDebug::writeError( "Trying to do a query without being connected to a database!", "eZMySQLiDB" ); 00475 } 00476 00477 00478 } 00479 00480 /*! 00481 \reimp 00482 */ 00483 function arrayQuery( $sql, $params = array(), $server = false ) 00484 { 00485 $retArray = array(); 00486 if ( $this->IsConnected ) 00487 { 00488 $limit = false; 00489 $offset = 0; 00490 $column = false; 00491 // check for array parameters 00492 if ( is_array( $params ) ) 00493 { 00494 if ( isset( $params["limit"] ) and is_numeric( $params["limit"] ) ) 00495 $limit = $params["limit"]; 00496 00497 if ( isset( $params["offset"] ) and is_numeric( $params["offset"] ) ) 00498 $offset = $params["offset"]; 00499 00500 if ( isset( $params["column"] ) and ( is_numeric( $params["column"] ) or is_string( $params["column"] ) ) ) 00501 $column = $params["column"]; 00502 } 00503 00504 if ( $limit !== false and is_numeric( $limit ) ) 00505 { 00506 $sql .= "\nLIMIT $offset, $limit "; 00507 } 00508 else if ( $offset !== false and is_numeric( $offset ) and $offset > 0 ) 00509 { 00510 $sql .= "\nLIMIT $offset, 18446744073709551615"; // 2^64-1 00511 } 00512 $result = $this->query( $sql, $server ); 00513 00514 if ( $result == false ) 00515 { 00516 $this->reportQuery( 'eZMySQLiDB', $sql, false, false ); 00517 return false; 00518 } 00519 00520 $numRows = mysqli_num_rows( $result ); 00521 if ( $numRows > 0 ) 00522 { 00523 if ( !is_string( $column ) ) 00524 { 00525 eZDebug::accumulatorStart( 'mysqli_loop', 'mysqli_total', 'Looping result' ); 00526 for ( $i=0; $i < $numRows; $i++ ) 00527 { 00528 if ( $this->InputTextCodec ) 00529 { 00530 $tmpRow = mysqli_fetch_array( $result, MYSQLI_ASSOC ); 00531 $convRow = array(); 00532 foreach( $tmpRow as $key => $row ) 00533 { 00534 eZDebug::accumulatorStart( 'mysqli_conversion', 'mysqli_total', 'String conversion in mysqli' ); 00535 $convRow[$key] = $this->OutputTextCodec->convertString( $row ); 00536 eZDebug::accumulatorStop( 'mysqli_conversion' ); 00537 } 00538 $retArray[$i + $offset] = $convRow; 00539 } 00540 else 00541 $retArray[$i + $offset] = mysqli_fetch_array( $result, MYSQLI_ASSOC ); 00542 } 00543 eZDebug::accumulatorStop( 'mysqli_loop' ); 00544 00545 } 00546 else 00547 { 00548 eZDebug::accumulatorStart( 'mysqli_loop', 'mysqli_total', 'Looping result' ); 00549 for ( $i=0; $i < $numRows; $i++ ) 00550 { 00551 $tmp_row = mysqli_fetch_array( $result, MYSQLI_ASSOC ); 00552 if ( $this->InputTextCodec ) 00553 { 00554 eZDebug::accumulatorStart( 'mysqli_conversion', 'mysqli_total', 'String conversion in mysqli' ); 00555 $retArray[$i + $offset] = $this->OutputTextCodec->convertString( $tmp_row[$column] ); 00556 eZDebug::accumulatorStop( 'mysqli_conversion' ); 00557 } 00558 else 00559 $retArray[$i + $offset] =& $tmp_row[$column]; 00560 } 00561 eZDebug::accumulatorStop( 'mysqli_loop' ); 00562 } 00563 } 00564 } 00565 return $retArray; 00566 } 00567 00568 function subString( $string, $from, $len = null ) 00569 { 00570 if ( $len == null ) 00571 { 00572 return " substring( $string from $from ) "; 00573 }else 00574 { 00575 return " substring( $string from $from for $len ) "; 00576 } 00577 } 00578 00579 function concatString( $strings = array() ) 00580 { 00581 $str = implode( "," , $strings ); 00582 return " concat( $str ) "; 00583 } 00584 00585 function md5( $str ) 00586 { 00587 return " MD5( $str ) "; 00588 } 00589 00590 function bitAnd( $arg1, $arg2 ) 00591 { 00592 return 'cast(' . $arg1 . ' & ' . $arg2 . ' AS SIGNED ) '; 00593 } 00594 00595 function bitOr( $arg1, $arg2 ) 00596 { 00597 return 'cast( ' . $arg1 . ' | ' . $arg2 . ' AS SIGNED ) '; 00598 } 00599 00600 /*! 00601 \reimp 00602 */ 00603 function supportedRelationTypeMask() 00604 { 00605 return eZDBInterface::RELATION_TABLE_BIT; 00606 } 00607 00608 /*! 00609 \reimp 00610 */ 00611 function supportedRelationTypes() 00612 { 00613 return array( eZDBInterface::RELATION_TABLE ); 00614 } 00615 00616 /*! 00617 \reimp 00618 */ 00619 function relationCounts( $relationMask ) 00620 { 00621 if ( $relationMask & eZDBInterface::RELATION_TABLE_BIT ) 00622 return $this->relationCount(); 00623 else 00624 return 0; 00625 } 00626 00627 /*! 00628 \reimp 00629 */ 00630 function relationCount( $relationType = eZDBInterface::RELATION_TABLE ) 00631 { 00632 if ( $relationType != eZDBInterface::RELATION_TABLE ) 00633 { 00634 eZDebug::writeError( "Unsupported relation type '$relationType'", 'eZMySQLiDB::relationCount' ); 00635 return false; 00636 } 00637 $count = false; 00638 if ( $this->IsConnected ) 00639 { 00640 $result = mysqli_query( $this->DBConnection, 'SHOW TABLES from `' . $this->DB .'`' ); 00641 $count = mysqli_num_rows( $result ); 00642 mysqli_free_result( $result ); 00643 } 00644 return $count; 00645 } 00646 00647 /*! 00648 \reimp 00649 */ 00650 function relationList( $relationType = eZDBInterface::RELATION_TABLE ) 00651 { 00652 if ( $relationType != eZDBInterface::RELATION_TABLE ) 00653 { 00654 eZDebug::writeError( "Unsupported relation type '$relationType'", 'eZMySQLiDB::relationList' ); 00655 return false; 00656 } 00657 $tables = array(); 00658 if ( $this->IsConnected ) 00659 { 00660 $result = mysqli_query( $this->DBConnection, 'SHOW TABLES from `' . $this->DB .'`' ); 00661 while( $row = mysqli_fetch_row( $result ) ) 00662 { 00663 $tables[] = $row[0]; 00664 } 00665 mysqli_free_result( $result ); 00666 } 00667 return $tables; 00668 } 00669 00670 /*! 00671 \reimp 00672 */ 00673 function eZTableList( $server = eZDBInterface::SERVER_MASTER ) 00674 { 00675 $tables = array(); 00676 if ( $this->IsConnected ) 00677 { 00678 if ( $this->UseSlaveServer && $server == eZDBInterface::SERVER_SLAVE ) 00679 { 00680 $connection = $this->DBConnection; 00681 $db = $this->SlaveDB; 00682 } 00683 else 00684 { 00685 $connection = $this->DBWriteConnection; 00686 $db = $this->DB; 00687 } 00688 00689 $result = mysqli_query( $connection, 'SHOW TABLES from `' . $db .'`' ); 00690 while( $row = mysqli_fetch_row( $result ) ) 00691 { 00692 $tableName = $row[0]; 00693 if ( substr( $tableName, 0, 2 ) == 'ez' ) 00694 { 00695 $tables[$tableName] = eZDBInterface::RELATION_TABLE; 00696 } 00697 } 00698 mysqli_free_result( $result ); 00699 } 00700 return $tables; 00701 } 00702 00703 /*! 00704 \reimp 00705 */ 00706 function relationMatchRegexp( $relationType ) 00707 { 00708 return "#^ez#"; 00709 } 00710 00711 /*! 00712 \reimp 00713 */ 00714 function removeRelation( $relationName, $relationType ) 00715 { 00716 $relationTypeName = $this->relationName( $relationType ); 00717 if ( !$relationTypeName ) 00718 { 00719 eZDebug::writeError( "Unknown relation type '$relationType'", 'eZMySQLiDB::removeRelation' ); 00720 return false; 00721 } 00722 00723 if ( $this->IsConnected ) 00724 { 00725 $sql = "DROP $relationTypeName $relationName"; 00726 return $this->query( $sql ); 00727 } 00728 return false; 00729 } 00730 00731 /*! 00732 \reimp 00733 */ 00734 function lock( $table ) 00735 { 00736 if ( $this->IsConnected ) 00737 { 00738 if ( is_array( $table ) ) 00739 { 00740 $lockQuery = "LOCK TABLES"; 00741 $first = true; 00742 foreach( array_keys( $table ) as $tableKey ) 00743 { 00744 if ( $first == true ) 00745 $first = false; 00746 else 00747 $lockQuery .= ","; 00748 $lockQuery .= " " . $table[$tableKey]['table'] . " WRITE"; 00749 } 00750 $this->query( $lockQuery ); 00751 } 00752 else 00753 { 00754 $this->query( "LOCK TABLES $table WRITE" ); 00755 } 00756 } 00757 } 00758 00759 /*! 00760 \reimp 00761 */ 00762 function unlock() 00763 { 00764 if ( $this->IsConnected ) 00765 { 00766 $this->query( "UNLOCK TABLES" ); 00767 } 00768 } 00769 00770 /*! 00771 \reimp 00772 The query to start the transaction. 00773 */ 00774 function beginQuery() 00775 { 00776 return $this->query("BEGIN WORK"); 00777 } 00778 00779 /*! 00780 \reimp 00781 The query to commit the transaction. 00782 */ 00783 function commitQuery() 00784 { 00785 return $this->query( "COMMIT" ); 00786 } 00787 00788 /*! 00789 \reimp 00790 The query to cancel the transaction. 00791 */ 00792 function rollbackQuery() 00793 { 00794 return $this->query( "ROLLBACK" ); 00795 } 00796 00797 /*! 00798 \reimp 00799 */ 00800 function lastSerialID( $table = false, $column = false ) 00801 { 00802 if ( $this->IsConnected ) 00803 { 00804 $id = mysqli_insert_id( $this->DBWriteConnection ); 00805 return $id; 00806 } 00807 else 00808 return false; 00809 } 00810 00811 /*! 00812 \reimp 00813 */ 00814 function escapeString( $str ) 00815 { 00816 if ( is_object( $this->DBConnection ) ) 00817 { 00818 return mysqli_real_escape_string( $this->DBConnection, $str ); 00819 } 00820 else 00821 { 00822 eZDebug::writeDebug( 'escapeString called before connection is made', 'eZMySQLiDB::escapeString' ); 00823 return $str; 00824 } 00825 } 00826 00827 /*! 00828 \reimp 00829 */ 00830 function close() 00831 { 00832 if ( $this->IsConnected ) 00833 { 00834 mysqli_close( $this->DBConnection ); 00835 mysqli_close( $this->DBWriteConnection ); 00836 } 00837 } 00838 00839 /*! 00840 \reimp 00841 */ 00842 function createDatabase( $dbName ) 00843 { 00844 if ( $this->IsConnected ) 00845 { 00846 $this->query( "CREATE DATABASE $dbName" ); 00847 $this->setError(); 00848 } 00849 } 00850 00851 function removeDatabase( $dbName ) 00852 { 00853 if ( $this->IsConnected ) 00854 { 00855 $this->query( "DROP DATABASE $dbName" ); 00856 $this->setError(); 00857 } 00858 } 00859 00860 /*! 00861 \reimp 00862 */ 00863 function setError() 00864 { 00865 if ( is_object( $this->DBConnection ) ) 00866 { 00867 $this->ErrorMessage = mysqli_error( $this->DBConnection ); 00868 $this->ErrorNumber = mysqli_errno( $this->DBConnection ); 00869 } 00870 else 00871 { 00872 $this->ErrorMessage = mysqli_connect_error(); 00873 $this->ErrorNumber = mysqli_connect_errno(); 00874 } 00875 } 00876 00877 /*! 00878 \reimp 00879 */ 00880 function availableDatabases() 00881 { 00882 $databaseArray = mysqli_query( $this->DBConnection, 'SHOW DATABASES' ); 00883 00884 if ( $this->errorNumber() != 0 ) 00885 { 00886 return null; 00887 } 00888 00889 $databases = array(); 00890 00891 $numRows = mysqli_num_rows( $databaseArray ); 00892 if ( count( $numRows ) == 0 ) 00893 { 00894 return false; 00895 } 00896 00897 while ( $row = mysqli_fetch_row( $databaseArray ) ) 00898 { 00899 // we don't allow "mysql" or "information_schema" database to be shown anywhere 00900 $curDB = $row[0]; 00901 if ( strcasecmp( $curDB, 'mysql' ) != 0 && strcasecmp( $curDB, 'information_schema' ) != 0 ) 00902 { 00903 $databases[] = $curDB; 00904 } 00905 } 00906 return $databases; 00907 } 00908 00909 /*! 00910 \reimp 00911 */ 00912 function databaseServerVersion() 00913 { 00914 if ( is_object( $this->DBConnection ) ) 00915 { 00916 $versionInfo = mysqli_get_server_info( $this->DBConnection ); 00917 00918 $versionArray = explode( '.', $versionInfo ); 00919 00920 return array( 'string' => $versionInfo, 00921 'values' => $versionArray ); 00922 } 00923 00924 return false; 00925 } 00926 00927 /*! 00928 \reimp 00929 */ 00930 function databaseClientVersion() 00931 { 00932 $versionInfo = mysqli_get_client_info(); 00933 00934 $versionArray = explode( '.', $versionInfo ); 00935 00936 return array( 'string' => $versionInfo, 00937 'values' => $versionArray ); 00938 } 00939 00940 /*! 00941 \reimp 00942 */ 00943 function isCharsetSupported( $charset ) 00944 { 00945 return true; 00946 } 00947 00948 function supportsDefaultValuesInsertion() 00949 { 00950 return false; 00951 } 00952 00953 public $CharsetMapping; 00954 protected $TempTableList; 00955 00956 /// \privatesection 00957 } 00958 00959 ?>