Fixed bug #11599: TYPO3 dies without an error message when the mysql-module for php...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_db.php
old mode 100755 (executable)
new mode 100644 (file)
index 7606f82..e64e38d
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2004-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 2004-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -25,7 +25,9 @@
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 /**
- * Contains the class "t3lib_db" containing functions for building SQL queries and mysql wrappers, thus providing a foundational API to all database interaction.
+ * Contains the class "t3lib_db" containing functions for building SQL queries
+ * and mysql wrappers, thus providing a foundational API to all database
+ * interaction.
  * This class is instantiated globally as $TYPO3_DB in TYPO3 scripts.
  *
  * $Id$
@@ -268,7 +270,7 @@ class t3lib_DB {
                $mmWhere.= ($local_table AND $foreign_table) ? ' AND ' : '';
                $mmWhere.= $foreign_table ? ($foreign_table_as ? $foreign_table_as : $foreign_table).'.uid='.$mm_table.'.uid_foreign' : '';
 
-               return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+               return $this->exec_SELECTquery(
                                        $select,
                                        ($local_table ? $local_table.',' : '').$mm_table.($foreign_table ? ','. $foreign_table.($foreign_table_as ? ' AS '.$foreign_table_as : '') : ''),
                                        $mmWhere.' '.$whereClause,              // whereClauseMightContainGroupOrderBy
@@ -330,6 +332,24 @@ class t3lib_DB {
                return $output;
        }
 
+       /**
+        * Counts the number of rows in a table.
+        *
+        * @param       string          $field: Name of the field to use in the COUNT() expression (e.g. '*')
+        * @param       string          $table: Name of the table to count rows for
+        * @param       string          $where: (optional) WHERE statement of the query
+        * @return      mixed           Number of rows counter (integer) or false if something went wrong (boolean)
+        */
+       public function exec_SELECTcountRows($field, $table, $where = '') {
+               $count = false;
+               $resultSet = $this->exec_SELECTquery('COUNT(' . $field . ')', $table, $where);
+               if ($resultSet !== false) {
+                       list($count) = $this->sql_fetch_row($resultSet);
+                       $this->sql_free_result($resultSet);
+               }
+               return $count;
+       }
+
 
 
 
@@ -354,7 +374,6 @@ class t3lib_DB {
         * @param       array           See exec_INSERTquery()
         * @param       string/array            See fullQuoteArray()
         * @return      string          Full SQL query for INSERT (unless $fields_values does not contain any elements in which case it will be false)
-        * @deprecated                  use exec_INSERTquery() instead if possible!
         */
        function INSERTquery($table,$fields_values,$no_quote_fields=FALSE)      {
 
@@ -389,7 +408,6 @@ class t3lib_DB {
         * @param       array           See exec_UPDATEquery()
         * @param       array           See fullQuoteArray()
         * @return      string          Full SQL query for UPDATE (unless $fields_values does not contain any elements in which case it will be false)
-        * @deprecated                  use exec_UPDATEquery() instead if possible!
         */
        function UPDATEquery($table,$where,$fields_values,$no_quote_fields=FALSE)       {
 
@@ -430,7 +448,6 @@ class t3lib_DB {
         * @param       string          See exec_DELETEquery()
         * @param       string          See exec_DELETEquery()
         * @return      string          Full SQL query for DELETE
-        * @deprecated                  use exec_DELETEquery() instead if possible!
         */
        function DELETEquery($table,$where)     {
                if (is_string($where))  {
@@ -459,7 +476,6 @@ class t3lib_DB {
         * @param       string          See exec_SELECTquery()
         * @param       string          See exec_SELECTquery()
         * @return      string          Full SQL query for SELECT
-        * @deprecated                  use exec_SELECTquery() instead if possible!
         */
        function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')        {
 
@@ -503,8 +519,9 @@ class t3lib_DB {
         * @return      string          WHERE clause for a query
         */
        function listQuery($field, $value, $table)      {
-               $command = $this->quoteStr($value, $table);
-               $where = '('.$field.' LIKE \'%,'.$command.',%\' OR '.$field.' LIKE \''.$command.',%\' OR '.$field.' LIKE \'%,'.$command.'\' OR '.$field.'=\''.$command.'\')';
+               $pattern = $this->quoteStr($value, $table);
+               $patternForLike = $this->escapeStrForLike($pattern, $table);
+               $where = '('.$field.' LIKE \'%,'.$patternForLike.',%\' OR '.$field.' LIKE \''.$patternForLike.',%\' OR '.$field.' LIKE \'%,'.$patternForLike.'\' OR '.$field.'=\''.$pattern.'\')';
                return $where;
        }
 
@@ -744,12 +761,13 @@ class t3lib_DB {
        /**
         * Executes query
         * mysql() wrapper function
-        * DEPRECATED - use exec_* functions from this class instead!
-        * Usage count/core: 9
+        * Usage count/core: 0
         *
         * @param       string          Database name
         * @param       string          Query to execute
         * @return      pointer         Result pointer / DBAL object
+        * @deprecated since TYPO3 3.6
+        * @see sql_query()
         */
        function sql($db,$query)        {
                $res = mysql_query($query, $this->link);
@@ -783,6 +801,16 @@ class t3lib_DB {
        }
 
        /**
+        * Returns the error number on the last sql() execution
+        * mysql_errno() wrapper function
+        *
+        * @return      int             MySQL error number.
+        */
+       function sql_errno() {
+               return mysql_errno($this->link);
+       }
+
+       /**
         * Returns the number of selected rows.
         * mysql_num_rows() wrapper function
         * Usage count/core: 85
@@ -898,16 +926,37 @@ class t3lib_DB {
        function sql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password)   {
                        // mysql_error() is tied to an established connection
                        // if the connection fails we need a different method to get the error message
-               ini_set('track_errors', 1);
-               ini_set('html_errors', 0);
+               @ini_set('track_errors', 1);
+               @ini_set('html_errors', 0);
+
+                       // check if MySQL extension is loaded
+               if (!extension_loaded('mysql')) {
+                       t3lib_BEfunc::typo3PrintError('Database Error', 'You don\'t seem to have MySQL-support for PHP installed!');
+                       exit;
+               }
+
+                       // Check for client compression
+               $isLocalhost = ($TYPO3_db_host == 'localhost' || $TYPO3_db_host == '127.0.0.1');
                if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])  {
-                       $this->link = @mysql_connect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password);
+                       if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'] && !$isLocalhost) {
+                                       // We use PHP's default value for 4th parameter (new_link), which is false.
+                                       // See PHP sources, for example: file php-5.2.5/ext/mysql/php_mysql.c, function php_mysql_do_connect(), near line 525
+                               $this->link = @mysql_connect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password, false, MYSQL_CLIENT_COMPRESS);
+                       } else {
+                               $this->link = @mysql_connect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password);
+                       }
                } else {
-                       $this->link = @mysql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password);
+                       if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'] && !$isLocalhost) {
+                                       // See comment about 4th parameter in block above
+                               $this->link = @mysql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password, false, MYSQL_CLIENT_COMPRESS);
+                       } else {
+                               $this->link = @mysql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password);
+                       }
                }
+
                $error_msg = $php_errormsg;
-               ini_restore('track_errors');
-               ini_restore('html_errors');
+               @ini_restore('track_errors');
+               @ini_restore('html_errors');
 
                if (!$this->link) {
                        t3lib_div::sysLog('Could not connect to MySQL server '.$TYPO3_db_host.' with user '.$TYPO3_db_username.': '.$error_msg,'Core',4);
@@ -984,11 +1033,13 @@ class t3lib_DB {
        function admin_get_tables()     {
                $whichTables = array();
 
-               $tables_result = mysql_query('SHOW TABLE STATUS FROM '.TYPO3_db, $this->link);
+               $tables_result = mysql_query('SHOW TABLE STATUS FROM `'.TYPO3_db.'`', $this->link);
                if (!mysql_error())     {
                        while ($theTable = mysql_fetch_assoc($tables_result)) {
                                $whichTables[$theTable['Name']] = $theTable;
                        }
+
+                       $this->sql_free_result($tables_result);
                }
 
                return $whichTables;
@@ -1010,6 +1061,8 @@ class t3lib_DB {
                        $output[$fieldRow['Field']] = $fieldRow;
                }
 
+               $this->sql_free_result($columns_res);
+
                return $output;
        }
 
@@ -1028,6 +1081,8 @@ class t3lib_DB {
                        $output[] = $keyRow;
                }
 
+               $this->sql_free_result($keyRes);
+
                return $output;
        }
 
@@ -1044,8 +1099,12 @@ class t3lib_DB {
                $output = array();
 
                $columns_res = mysql_query('SHOW CHARACTER SET', $this->link);
-               while ($row = mysql_fetch_assoc($columns_res)) {
-                       $output[$row['Charset']] = $row;
+               if ($columns_res) {
+                       while (($row = mysql_fetch_assoc($columns_res))) {
+                               $output[$row['Charset']] = $row;
+                       }
+
+                       $this->sql_free_result($columns_res);
                }
 
                return $output;
@@ -1129,12 +1188,12 @@ class t3lib_DB {
 
                $error = $this->sql_error();
                if ($error)     {
-                       echo t3lib_div::view_array(array(
+                       debug(array(
                                'caller' => 't3lib_DB::'.$func,
                                'ERROR' => $error,
                                'lastBuiltQuery' => ($query ? $query : $this->debug_lastBuiltQuery),
                                'debug_backtrace' => t3lib_div::debug_trail()
-                       ));
+                       ), 'SQL debug');
                }
        }
 
@@ -1148,7 +1207,7 @@ class t3lib_DB {
                if (!$res) {
                        $trace = FALSE;
                        $msg = 'Invalid database result resource detected';
-                       $trace = debug_backtrace();
+                       $trace = debug_backtrace();
                        array_shift($trace);
                        $cnt = count($trace);
                        for ($i=0; $i<$cnt; $i++)       {
@@ -1157,7 +1216,17 @@ class t3lib_DB {
                        }
                        $msg .= ': function t3lib_DB->' . $trace[0]['function'] . ' called from file ' . substr($trace[0]['file'],strlen(PATH_site)+2) . ' in line ' . $trace[0]['line'];
                        t3lib_div::sysLog($msg.'. Use a devLog extension to get more details.', 'Core/t3lib_db', 3);
-                       t3lib_div::devLog($msg.'.', 'Core/t3lib_db', 3, $trace);
+                       // Send to devLog if enabled
+                       if (TYPO3_DLOG) {
+                               $debugLogData = array(
+                                       'SQL Error' => $this->sql_error(),
+                                       'Backtrace' => $trace,
+                               );
+                               if ($this->debug_lastBuiltQuery) {
+                                       $debugLogData = array('SQL Query' => $this->debug_lastBuiltQuery) + $debugLogData;
+                               }
+                               t3lib_div::devLog($msg . '.', 'Core/t3lib_db', 3, $debugLogData);
+                       }
 
                        return FALSE;
                }
@@ -1186,7 +1255,7 @@ class t3lib_DB {
                        return false;
                }
 
-               $error = $GLOBALS['TYPO3_DB']->sql_error();
+               $error = $this->sql_error();
                $trail = t3lib_div::debug_trail();
 
                $explain_tables = array();
@@ -1261,4 +1330,5 @@ class t3lib_DB {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php'])       {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php']);
 }
-?>
+
+?>
\ No newline at end of file