fix typo, DieDebug -> DebugDie
[lhc/web/wiklou.git] / includes / Database.php
index 75440d6..ae03568 100644 (file)
@@ -2,7 +2,6 @@
 /**
  * This file deals with MySQL interface functions 
  * and query specifics/optimisations
- * @version # $Id$
  * @package MediaWiki
  */
 
@@ -27,7 +26,6 @@ define( 'DEADLOCK_DELAY_MAX', 1500000 );
 /**
  * Database abstraction object
  * @package MediaWiki
- * @version # $Id$
  */
 class Database {
 
@@ -180,6 +178,11 @@ class Database {
         */
        function open( $server, $user, $password, $dbName ) {
                # Test for missing mysql.so
+               # First try to load it
+               if (!@extension_loaded('mysql')) {
+                       @dl('mysql.so');
+               }
+
                # Otherwise we get a suppressed fatal error, which is very hard to track down
                if ( !function_exists( 'mysql_connect' ) ) {
                        die( "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
@@ -387,7 +390,8 @@ class Database {
        /**
         * Prepare & execute an SQL statement, quoting and inserting arguments
         * in the appropriate places.
-        * @param 
+        * @param string $query
+        * @param string $args (default null)
         */
        function safeQuery( $query, $args = null ) {
                $prepared = $this->prepare( $query, 'Database::safeQuery' );
@@ -507,8 +511,8 @@ class Database {
         * The value inserted should be fetched from nextSequenceValue()
         *
         * Example:
-        * $id = $dbw->nextSequenceValue('cur_cur_id_seq');
-        * $dbw->insert('cur',array('cur_id' => $id));
+        * $id = $dbw->nextSequenceValue('page_page_id_seq');
+        * $dbw->insert('page',array('page_id' => $id));
         * $id = $dbw->insertId();
         */
        function insertId() { return mysql_insert_id( $this->mConn ); }
@@ -523,14 +527,29 @@ class Database {
         * Get the last error number
         * See mysql_errno()
         */
-       function lastErrno() { return mysql_errno(); }
+       function lastErrno() { 
+               if ( $this->mConn ) {
+                       return mysql_errno( $this->mConn ); 
+               } else {
+                       return mysql_errno();
+               }
+       }
        
        /**
         * Get a description of the last error
         * See mysql_error() for more details
         */
-       function lastError() { return mysql_error(); }
-       
+       function lastError() { 
+               if ( $this->mConn ) {
+                       $error = mysql_error( $this->mConn ); 
+               } else {
+                       $error = mysql_error();
+               }
+               if( $error ) {
+                       $error .= ' (' . $this->mServer . ')';
+               }
+               return $error;
+       }       
        /**
         * Get the number of rows affected by the last write query
         * See mysql_affected_rows() for more details
@@ -617,7 +636,7 @@ class Database {
         */
        function select( $table, $vars, $conds='', $fname = 'Database::select', $options = array() )
        {
-               if ( is_array( $vars ) ) {
+               if( is_array( $vars ) ) {
                        $vars = implode( ',', $vars );
                }
                if( is_array( $table ) ) {
@@ -630,7 +649,7 @@ class Database {
 
                list( $useIndex, $tailOpts ) = $this->makeSelectOptions( $options );
                
-               if ( $conds !== false && $conds != '' ) {
+               if( !empty( $conds ) ) {
                        if ( is_array( $conds ) ) {
                                $conds = $this->makeList( $conds, LIST_AND );
                        }
@@ -649,8 +668,9 @@ class Database {
         * $conds: a condition map, terms are ANDed together. 
         *   Items with numeric keys are taken to be literal conditions
         * Takes an array of selected variables, and a condition map, which is ANDed
-        * e.g. selectRow( "cur", array( "cur_id" ), array( "cur_namespace" => 0, "cur_title" => "Astronomy" ) )
-        *   would return an object where $obj->cur_id is the ID of the Astronomy article
+        * e.g: selectRow( "page", array( "page_id" ), array( "page_namespace" =>
+        * NS_MAIN, "page_title" => "Astronomy" ) )   would return an object where
+        * $obj- >page_id is the ID of the Astronomy article
         *
         * @todo migrate documentation to phpdocumentor format
         */
@@ -1129,10 +1149,15 @@ class Database {
         * $varMap must be an associative array of the form array( 'dest1' => 'source1', ...)
         * Source items may be literals rather than field names, but strings should be quoted with Database::addQuotes()
         * $conds may be "*" to copy the whole table
+        * srcTable may be an array of tables.
         */
        function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = 'Database::insertSelect' ) {
                $destTable = $this->tableName( $destTable );
-               $srcTable = $this->tableName( $srcTable );
+                if( is_array( $srcTable ) ) {
+                        $srcTable =  implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+               } else { 
+                       $srcTable = $this->tableName( $srcTable );
+               }
                $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
                        ' SELECT ' . implode( ',', $varMap ) . 
                        " FROM $srcTable";
@@ -1233,9 +1258,17 @@ class Database {
         * @param integer $timeout the maximum number of seconds to wait for synchronisation
         */
        function masterPosWait( $file, $pos, $timeout ) {
+               $fname = 'Database::masterPosWait';
+               wfProfileIn( $fname );
+               
+               
+               # Commit any open transactions
+               $this->immediateCommit();
+               
+               # Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set
                $encFile = $this->strencode( $file );
                $sql = "SELECT MASTER_POS_WAIT('$encFile', $pos, $timeout)";
-               $res = $this->query( $sql, 'Database::masterPosWait' );
+               $res = $this->doQuery( $sql );
                if ( $res && $row = $this->fetchRow( $res ) ) {
                        $this->freeResult( $res );
                        return $row[0];
@@ -1363,7 +1396,6 @@ class Database {
  *
  * @package MediaWiki
  * @see Database
- * @version # $Id$
  */
 class DatabaseMysql extends Database {
        # Inherit all
@@ -1374,7 +1406,6 @@ class DatabaseMysql extends Database {
  * Result wrapper for grabbing data queried by someone else
  *
  * @package MediaWiki
- * @version # $Id$ 
  */
 class ResultWrapper {
        var $db, $result;
@@ -1429,7 +1460,41 @@ class ResultWrapper {
  */
 function wfEmergencyAbort( &$conn, $error ) {
        global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgSiteNotice, $wgOutputEncoding;
+       global $wgSitename, $wgServer;
        
+       # I give up, Brion is right. Getting the message cache to work when there is no DB is tricky.
+       # Hard coding strings instead.
+
+       $noconnect = 'Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. <br />
+$1';
+       $mainpage = 'Main Page';
+       $searchdisabled = <<<EOT
+<p style="margin: 1.5em 2em 1em">$wgSitename search is disabled for performance reasons. You can search via Google in the meantime.
+<span style="font-size: 89%; display: block; margin-left: .2em">Note that their indexes of $wgSitename content may be out of date.</span></p>',
+EOT;
+
+       $googlesearch = "
+<!-- SiteSearch Google -->
+<FORM method=GET action=\"http://www.google.com/search\">
+<TABLE bgcolor=\"#FFFFFF\"><tr><td>
+<A HREF=\"http://www.google.com/\">
+<IMG SRC=\"http://www.google.com/logos/Logo_40wht.gif\"
+border=\"0\" ALT=\"Google\"></A>
+</td>
+<td>
+<INPUT TYPE=text name=q size=31 maxlength=255 value=\"$1\">
+<INPUT type=submit name=btnG VALUE=\"Google Search\">
+<font size=-1>
+<input type=hidden name=domains value=\"$wgServer\"><br /><input type=radio name=sitesearch value=\"\"> WWW <input type=radio name=sitesearch value=\"$wgServer\" checked> $wgServer <br />
+<input type='hidden' name='ie' value='$2'>
+<input type='hidden' name='oe' value='$2'>
+</font>
+</td></tr></TABLE>
+</FORM>
+<!-- SiteSearch Google -->";
+       $cachederror = "The following is a cached copy of the requested page, and may not be up to date. ";
+
+
        if( !headers_sent() ) {
                header( 'HTTP/1.0 500 Internal Server Error' );
                header( 'Content-type: text/html; charset='.$wgOutputEncoding );
@@ -1438,7 +1503,9 @@ function wfEmergencyAbort( &$conn, $error ) {
                header( 'Pragma: nocache' );
        }
        $msg = $wgSiteNotice;
-       if($msg == '') $msg = wfMsgNoDB( 'noconnect', $error );
+       if($msg == '') {
+               $msg = str_replace( '$1', $error, $noconnect );
+       }
        $text = $msg;
 
        if($wgUseFileCache) {
@@ -1449,18 +1516,19 @@ function wfEmergencyAbort( &$conn, $error ) {
                                $t = Title::newFromURL( $title );
                        } elseif (@/**/$_REQUEST['search']) {
                                $search = $_REQUEST['search'];
-                               echo wfMsgNoDB( 'searchdisabled' );
-                               echo wfMsgNoDB( 'googlesearch', htmlspecialchars( $search ), $wgInputEncoding );
+                               echo $searchdisabled;
+                               echo str_replace( array( '$1', '$2' ), array( htmlspecialchars( $search ), 
+                                 $wgInputEncoding ), $googlesearch );
                                wfErrorExit();
                        } else {
-                               $t = Title::newFromText( wfMsgNoDBForContent( 'mainpage' ) );
+                               $t = Title::newFromText( $mainpage );
                        }
                }
 
                $cache = new CacheManager( $t );
                if( $cache->isFileCached() ) {
                        $msg = '<p style="color: red"><b>'.$msg."<br />\n" .
-                               wfMsgNoDB( 'cachederror' ) . "</b></p>\n";
+                               $cachederror . "</b></p>\n";
                        
                        $tag = '<div id="article">';
                        $text = str_replace(