Index: branches/RC/core/kernel/db/db_connection.php =================================================================== diff -u -N --- branches/RC/core/kernel/db/db_connection.php (revision 11927) +++ branches/RC/core/kernel/db/db_connection.php (revision 0) @@ -1,702 +0,0 @@ -dbType = $dbType; -// $this->initMetaFunctions(); - if (!$errorHandler) { - $this->errorHandler = Array(&$this, 'handleError'); - } - else { - $this->errorHandler = $errorHandler; - } - - $this->_captureStatistics = defined('DBG_CAPTURE_STATISTICS') && DBG_CAPTURE_STATISTICS && !(defined('ADMIN') && ADMIN); - - if (class_exists('kApplication')) { - // prevents "Fatal Error" on 2nd installation step (when database is empty) - $this->Application =& kApplication::Instance(); - } - } - - /** - * Set's custom error - * - * @param int $code - * @param string $msg - * @access public - */ - function setError($code, $msg) - { - $this->errorCode = $code; - $this->errorMessage = $msg; - } - - /** - * Checks if previous query execution - * raised an error. - * - * @return bool - * @access public - */ - function hasError() - { - return !($this->errorCode == 0); - } - - /** - * Caches function specific to requested - * db type - * - * @access private - */ - function initMetaFunctions() - { - $ret = Array(); - switch ($this->dbType) - { - case 'mysql': - $ret = Array(); // only define functions, that name differs from "dbType_" - - break; - - - } - $this->metaFunctions = $ret; - } - - /** - * Get's function for specific db type - * based on it's meta name - * - * @param string $name - * @return string - * @access private - */ - function getMetaFunction($name) - { - /*if (!isset($this->metaFunctions[$name])) { - $this->metaFunctions[$name] = $name; - }*/ - - return $this->dbType.'_'.$name; - } - - - /** - * Try to connect to database server - * using specified parameters and set - * database to $db if connection made - * - * @param string $host - * @param string $user - * @param string $pass - * @param string $db - * @access public - */ - function Connect($host, $user, $pass, $db, $force_new = false) - { - $func = $this->getMetaFunction('connect'); - $this->connectionID = $func($host, $user, $pass, $force_new) or trigger_error("Database connection failed, please check your connection settings", defined('IS_INSTALL') && IS_INSTALL ? E_USER_WARNING : E_USER_ERROR); - if ($this->connectionID) { - if (defined('DBG_SQL_MODE')) { - $this->Query('SET sql_mode = \''.DBG_SQL_MODE.'\''); - } - - if (defined('SQL_COLLATION') && defined('SQL_CHARSET')) { - $this->Query('SET NAMES \''.SQL_CHARSET.'\' COLLATE \''.SQL_COLLATION.'\''); - } - - $this->setDB($db); - $this->showError(); - } - else { - // simulate error, becase php mysql client doesn't provide such information - $this->errorCode = 2003; - $this->errorMessage = "Can't connect to MySQL server on '$host' (113)"; - } - } - - function ReConnect($host, $user, $pass, $db, $force_new = false) - { - $func = $this->getMetaFunction('close'); - $func($this->connectionID); - $this->Connect($host, $user, $pass, $db, $force_new); - } - - /** - * Shows error message from previous operation - * if it failed - * - * @access private - */ - function showError($sql = '') - { - $this->setError(0, ''); // reset error - if ($this->connectionID) { - $func = $this->getMetaFunction('errno'); $this->errorCode = $func($this->connectionID); - if ($this->hasError()) { - $func = $this->getMetaFunction('error'); $this->errorMessage = $func($this->connectionID); - if (is_array($this->errorHandler)) { - $func = $this->errorHandler[1]; - $ret = $this->errorHandler[0]->$func($this->errorCode, $this->errorMessage, $sql); - } - else { - $func = $this->errorHandler; - $ret = $func($this->errorCode,$this->errorMessage,$sql); - } - if (!$ret) exit; - } - } - } - - /** - * Default error handler for sql errors - * - * @param int $code - * @param string $msg - * @param string $sql - * @return bool - * @access private - */ - function handleError($code, $msg, $sql) - { - echo 'Processing SQL: '.$sql.'
'; - echo 'Error ('.$code.'): '.$msg.'
'; - return false; - } - - /** - * Set's database name for connection - * to $new_name - * - * @param string $new_name - * @return bool - * @access public - */ - function setDB($new_name) - { - if (!$this->connectionID) return false; - $func = $this->getMetaFunction('select_db'); - return $func($new_name, $this->connectionID); - } - - /** - * Returns first field of first line - * of recordset if query ok or false - * otherwise - * - * @param string $sql - * @param int $offset - * @return string - * @access public - */ - function GetOne($sql, $offset = 0) - { - $row = $this->GetRow($sql, $offset); - if(!$row) return false; - - return array_shift($row); - } - - /** - * Returns first row of recordset - * if query ok, false otherwise - * - * @param stirng $sql - * @param int $offset - * @return Array - * @access public - */ - function GetRow($sql, $offset = 0) - { - $sql .= ' '.$this->getLimitClause($offset, 1); - $ret = $this->Query($sql); - if(!$ret) return false; - - return array_shift($ret); - } - - /** - * Returns 1st column of recordset as - * one-dimensional array or false otherwise - * Optional parameter $key_field can be used - * to set field name to be used as resulting - * array key - * - * @param string $sql - * @param string $key_field - * @return Array - * @access public - */ - function GetCol($sql, $key_field = null) - { - $rows = $this->Query($sql); - if (!$rows) return $rows; - - $i = 0; $row_count = count($rows); - $ret = Array(); - if (isset($key_field)) { - while ($i < $row_count) { - $ret[$rows[$i][$key_field]] = array_shift($rows[$i]); - $i++; - } - } - else { - while ($i < $row_count) { - $ret[] = array_shift($rows[$i]); - $i++; - } - } - return $ret; - } - - /** - * Queries db with $sql query supplied - * and returns rows selected if any, false - * otherwise. Optional parameter $key_field - * allows to set one of the query fields - * value as key in string array. - * - * @param string $sql - * @param string $key_field - * @return Array - */ - function Query($sql, $key_field = null, $no_debug = false) - { - $this->lastQuery = $sql; - if (!$no_debug) { - $this->_queryCount++; - } - - if ($this->debugMode && !$no_debug) { - return $this->debugQuery($sql,$key_field); - } - $query_func = $this->getMetaFunction('query'); - - // set 1st checkpoint: begin - if ($this->_captureStatistics) { - $start_time = getmicrotime(); - } - // set 1st checkpoint: end - - $this->queryID = $query_func($sql,$this->connectionID); - if (is_resource($this->queryID)) { - $ret = Array(); - $fetch_func = $this->getMetaFunction('fetch_assoc'); - if (isset($key_field)) { - while (($row = $fetch_func($this->queryID))) { - $ret[$row[$key_field]] = $row; - } - } - else { - while (($row = $fetch_func($this->queryID))) { - $ret[] = $row; - } - } - - // set 2nd checkpoint: begin - if ($this->_captureStatistics) { - $query_time = getmicrotime() - $start_time; - if ($query_time > DBG_MAX_SQL_TIME && !$no_debug) { - $this->Application->logSlowQuery($sql, $query_time); - } - $this->_queryTime += $query_time; - } - // set 2nd checkpoint: end - - $this->Destroy(); - return $ret; - } - else { - // set 2nd checkpoint: begin - if ($this->_captureStatistics) { - $this->_queryTime += getmicrotime() - $start_time; - } - // set 2nd checkpoint: end - } - $this->showError($sql); - return false; - } - - function ChangeQuery($sql) - { - $this->Query($sql); - return $this->errorCode == 0 ? true : false; - } - - function debugQuery($sql, $key_field = null) - { - global $debugger; - $query_func = $this->getMetaFunction('query'); - - // set 1st checkpoint: begin - $profileSQLs = defined('DBG_SQL_PROFILE') && DBG_SQL_PROFILE; - if ($profileSQLs) { - $queryID = $debugger->generateID(); - $debugger->profileStart('sql_'.$queryID, $debugger->formatSQL($sql)); - } - // set 1st checkpoint: end - - $this->queryID = $query_func($sql, $this->connectionID); - - if( is_resource($this->queryID) ) - { - $ret = Array(); - $fetch_func = $this->getMetaFunction('fetch_assoc'); - if( isset($key_field) ) - { - while( ($row = $fetch_func($this->queryID)) ) - { - $ret[$row[$key_field]] = $row; - } - } - else - { - while( ($row = $fetch_func($this->queryID)) ) - { - $ret[] = $row; - } - } - - // set 2nd checkpoint: begin - $first_cell = count($ret) == 1 && count(current($ret)) == 1 ? current(current($ret)) : null; - if ($profileSQLs) { - $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows(), $first_cell, $this->_queryCount); - $debugger->profilerAddTotal('sql', 'sql_'.$queryID); - } - // set 2nd checkpoint: end - - $this->Destroy(); - return $ret; - } - else { - // set 2nd checkpoint: begin - if ($profileSQLs) { - $debugger->profileFinish('sql_'.$queryID, null, null, $this->getAffectedRows(), null, $this->_queryCount); - $debugger->profilerAddTotal('sql', 'sql_'.$queryID); - } - // set 2nd checkpoint: end - } - $this->showError($sql); - return false; - } - - /** - * Free memory used to hold recordset handle - * - * @access private - */ - function Destroy() - { - if($this->queryID) - { - $free_func = $this->getMetaFunction('free_result'); - $free_func($this->queryID); - $this->queryID = null; - } - } - - /** - * Returns auto increment field value from - * insert like operation if any, zero otherwise - * - * @return int - * @access public - */ - function getInsertID() - { - $func = $this->getMetaFunction('insert_id'); - return $func($this->connectionID); - } - - /** - * Returns row count affected by last query - * - * @return int - * @access public - */ - function getAffectedRows() - { - $func = $this->getMetaFunction('affected_rows'); - return $func($this->connectionID); - } - - /** - * Returns LIMIT sql clause part for specific db - * - * @param int $offset - * @param int $rows - * @return string - * @access private - */ - function getLimitClause($offset, $rows) - { - if(!($rows > 0)) return ''; - - switch ($this->dbType) { - - default: - return 'LIMIT '.$offset.','.$rows; - break; - } - } - - /** - * If it's a string, adds quotes and backslashes (only work since PHP 4.3.0) - * Otherwise returns as-is - * - * @param mixed $string - */ - function qstr($string) - { - if ( is_null($string) ) { - return 'NULL'; - } - - # This will also quote numeric values. This should be harmless, - # and protects against weird problems that occur when they really - # _are_ strings such as article titles and string->number->string - # conversion is not 1:1. - return "'" . mysql_real_escape_string($string, $this->connectionID) . "'"; - } - - /** - * Returns last error code occured - * - * @return int - */ - function getErrorCode() - { - return $this->errorCode; - } - - /** - * Returns last error message - * - * @return string - * @access public - */ - function getErrorMsg() - { - return $this->errorMessage; - } - - /** - * Performs insert of given data (useful with small number of queries) - * or stores it to perform multiple insert later (useful with large number of queries) - * - * @param Array $fields_hash - * @param string $table - * @param string $type - * @param bool $insert_now - * @return bool - */ - function doInsert($fields_hash, $table, $type = 'INSERT', $insert_now = true) - { - static $value_sqls = Array (); - - if ($insert_now) { - $fields_sql = '`' . implode('`,`', array_keys($fields_hash)) . '`'; - } - - $values_sql = ''; - foreach ($fields_hash as $field_name => $field_value) { - $values_sql .= $this->qstr($field_value) . ','; - } - - // don't use preg here, as it may fail when string is too long - $value_sqls[] = rtrim($values_sql, ','); - - $insert_result = true; - if ($insert_now) { - $insert_count = count($value_sqls); - if (($insert_count > 1) && ($value_sqls[$insert_count - 1] == $value_sqls[$insert_count - 2])) { - // last two records are the same - array_pop($value_sqls); - } - - $sql = strtoupper($type) . ' INTO `' . $table . '` (' . $fields_sql . ') VALUES (' . implode('),(', $value_sqls) . ')'; - $insert_result = $this->ChangeQuery($sql); - $value_sqls = Array (); - } - - return $insert_result; - } - - function doUpdate($fields_hash, $table, $key_clause) - { - if (!$fields_hash) return true; - - $fields_sql = ''; - foreach ($fields_hash as $field_name => $field_value) { - $fields_sql .= '`'.$field_name.'` = ' . $this->qstr($field_value) . ','; - } - - // don't use preg here, as it may fail when string is too long - $fields_sql = rtrim($fields_sql, ','); - - $sql = 'UPDATE `'.$table.'` SET '.$fields_sql.' WHERE '.$key_clause; - - return $this->ChangeQuery($sql); - } - - /** - * Allows to detect table's presense in database - * - * @param string $table_name - * @return bool - */ - function TableFound($table_name) - { - static $table_found = Array(); - - if (!preg_match('/^'.preg_quote(TABLE_PREFIX, '/').'(.*)/', $table_name)) { - $table_name = TABLE_PREFIX.$table_name; - } - - if (!isset($table_found[$table_name])) { - $table_found[$table_name] = $this->Query('SHOW TABLES LIKE "'.$table_name.'"'); - } - - return $table_found[$table_name]; - } - - /** - * Returns query processing statistics - * - * @return Array - */ - function getQueryStatistics() - { - return Array ('time' => $this->_queryTime, 'count' => $this->_queryCount); - } - } -?> \ No newline at end of file