eZ Publish  [4.0]
ezmysqlidb.php
Go to the documentation of this file.
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 ?>