dbo_mysqli.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: dbo_mysqli.php 8261 2009-07-28 20:08:24Z DarkAngelBGE $ */
00003 /**
00004  * MySQLi layer for DBO
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs.model.datasources.dbo
00021  * @since         CakePHP(tm) v 1.1.4.2974
00022  * @version       $Revision: 8261 $
00023  * @modifiedby    $LastChangedBy: DarkAngelBGE $
00024  * @lastmodified  $Date: 2009-07-28 16:08:24 -0400 (Tue, 28 Jul 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 App::import('Core', 'DboMysql');
00028 /**
00029  * MySQLi DBO driver object
00030  *
00031  * Provides connection and SQL generation for MySQL RDMS using PHP's MySQLi Interface
00032  *
00033  * @package       cake
00034  * @subpackage    cake.cake.libs.model.datasources.dbo
00035  */
00036 class DboMysqli extends DboMysqlBase {
00037 /**
00038  * Enter description here...
00039  *
00040  * @var unknown_type
00041  */
00042     var $description = "Mysqli DBO Driver";
00043 /**
00044  * Base configuration settings for Mysqli driver
00045  *
00046  * @var array
00047  */
00048     var $_baseConfig = array(
00049         'persistent' => true,
00050         'host' => 'localhost',
00051         'login' => 'root',
00052         'password' => '',
00053         'database' => 'cake',
00054         'port' => '3306',
00055         'connect' => 'mysqli_connect'
00056     );
00057 /**
00058  * Connects to the database using options in the given configuration array.
00059  *
00060  * @return boolean True if the database could be connected, else false
00061  */
00062     function connect() {
00063         $config = $this->config;
00064         $this->connected = false;
00065 
00066         if (is_numeric($config['port'])) {
00067             $config['socket'] = null;
00068         } else {
00069             $config['socket'] = $config['port'];
00070             $config['port'] = null;
00071         }
00072 
00073         $this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port'], $config['socket']);
00074 
00075         if ($this->connection !== false) {
00076             $this->connected = true;
00077         }
00078         
00079         $this->_useAlias = (bool)version_compare(mysqli_get_server_info($this->connection), "4.1", ">=");
00080         
00081         if (!empty($config['encoding'])) {
00082             $this->setEncoding($config['encoding']);
00083         }
00084         return $this->connected;
00085     }
00086 /**
00087  * Disconnects from database.
00088  *
00089  * @return boolean True if the database could be disconnected, else false
00090  */
00091     function disconnect() {
00092         if (isset($this->results) && is_resource($this->results)) {
00093             mysqli_free_result($this->results);
00094         }
00095         $this->connected = !@mysqli_close($this->connection);
00096         return !$this->connected;
00097     }
00098 /**
00099  * Executes given SQL statement.
00100  *
00101  * @param string $sql SQL statement
00102  * @return resource Result resource identifier
00103  * @access protected
00104  */
00105     function _execute($sql) {
00106         if (preg_match('/^\s*call/i', $sql)) {
00107             return $this->_executeProcedure($sql);
00108         }
00109         return mysqli_query($this->connection, $sql);
00110     }
00111 /**
00112  * Executes given SQL statement (procedure call).
00113  *
00114  * @param string $sql SQL statement (procedure call)
00115  * @return resource Result resource identifier for first recordset
00116  * @access protected
00117  */
00118     function _executeProcedure($sql) {
00119         $answer = mysqli_multi_query($this->connection, $sql);
00120 
00121         $firstResult = mysqli_store_result($this->connection);
00122 
00123         if (mysqli_more_results($this->connection)) {
00124             while ($lastResult = mysqli_next_result($this->connection));
00125         }
00126         return $firstResult;
00127     }
00128 /**
00129  * Returns an array of sources (tables) in the database.
00130  *
00131  * @return array Array of tablenames in the database
00132  */
00133     function listSources() {
00134         $cache = parent::listSources();
00135         if ($cache != null) {
00136             return $cache;
00137         }
00138         $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
00139 
00140         if (!$result) {
00141             return array();
00142         }
00143 
00144         $tables = array();
00145 
00146         while ($line = mysqli_fetch_array($result)) {
00147             $tables[] = $line[0];
00148         }
00149         parent::listSources($tables);
00150         return $tables;
00151     }
00152 /**
00153  * Returns an array of the fields in given table name.
00154  *
00155  * @param string $tableName Name of database table to inspect
00156  * @return array Fields in table. Keys are name and type
00157  */
00158     function describe(&$model) {
00159 
00160         $cache = parent::describe($model);
00161         if ($cache != null) {
00162             return $cache;
00163         }
00164 
00165         $fields = false;
00166         $cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
00167 
00168         foreach ($cols as $column) {
00169             $colKey = array_keys($column);
00170             if (isset($column[$colKey[0]]) && !isset($column[0])) {
00171                 $column[0] = $column[$colKey[0]];
00172             }
00173             if (isset($column[0])) {
00174                 $fields[$column[0]['Field']] = array(
00175                     'type'      => $this->column($column[0]['Type']),
00176                     'null'      => ($column[0]['Null'] == 'YES' ? true : false),
00177                     'default'   => $column[0]['Default'],
00178                     'length'    => $this->length($column[0]['Type'])
00179                 );
00180                 if (!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
00181                     $fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
00182                 }
00183             }
00184         }
00185 
00186         $this->__cacheDescription($this->fullTableName($model, false), $fields);
00187         return $fields;
00188     }
00189 /**
00190  * Returns a quoted and escaped string of $data for use in an SQL statement.
00191  *
00192  * @param string $data String to be prepared for use in an SQL statement
00193  * @param string $column The column into which this data will be inserted
00194  * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
00195  * @return string Quoted and escaped data
00196  */
00197     function value($data, $column = null, $safe = false) {
00198         $parent = parent::value($data, $column, $safe);
00199 
00200         if ($parent != null) {
00201             return $parent;
00202         }
00203         if ($data === null || (is_array($data) && empty($data))) {
00204             return 'NULL';
00205         }
00206         if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
00207             return "''";
00208         }
00209         if (empty($column)) {
00210             $column = $this->introspectType($data);
00211         }
00212 
00213         switch ($column) {
00214             case 'boolean':
00215                 return $this->boolean((bool)$data);
00216             break;
00217             case 'integer' :
00218             case 'float' :
00219             case null :
00220                 if ($data === '') {
00221                     return 'NULL';
00222                 }
00223                 if ((is_int($data) || is_float($data) || $data === '0') || (
00224                     is_numeric($data) && strpos($data, ',') === false &&
00225                     $data[0] != '0' && strpos($data, 'e') === false)) {
00226                         return $data;
00227                     }
00228             default:
00229                 $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
00230             break;
00231         }
00232 
00233         return $data;
00234     }
00235 /**
00236  * Returns a formatted error message from previous database operation.
00237  *
00238  * @return string Error message with error number
00239  */
00240     function lastError() {
00241         if (mysqli_errno($this->connection)) {
00242             return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
00243         }
00244         return null;
00245     }
00246 /**
00247  * Returns number of affected rows in previous database operation. If no previous operation exists,
00248  * this returns false.
00249  *
00250  * @return integer Number of affected rows
00251  */
00252     function lastAffected() {
00253         if ($this->_result) {
00254             return mysqli_affected_rows($this->connection);
00255         }
00256         return null;
00257     }
00258 /**
00259  * Returns number of rows in previous resultset. If no previous resultset exists,
00260  * this returns false.
00261  *
00262  * @return integer Number of rows in resultset
00263  */
00264     function lastNumRows() {
00265         if ($this->hasResult()) {
00266             return mysqli_num_rows($this->_result);
00267         }
00268         return null;
00269     }
00270 /**
00271  * Returns the ID generated from the previous INSERT operation.
00272  *
00273  * @param unknown_type $source
00274  * @return in
00275  */
00276     function lastInsertId($source = null) {
00277         $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
00278         if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
00279             return $id[0]['insertID'];
00280         }
00281         return null;
00282     }
00283 /**
00284  * Converts database-layer column types to basic types
00285  *
00286  * @param string $real Real database-layer column type (i.e. "varchar(255)")
00287  * @return string Abstract column type (i.e. "string")
00288  */
00289     function column($real) {
00290         if (is_array($real)) {
00291             $col = $real['name'];
00292             if (isset($real['limit'])) {
00293                 $col .= '('.$real['limit'].')';
00294             }
00295             return $col;
00296         }
00297 
00298         $col = str_replace(')', '', $real);
00299         $limit = $this->length($real);
00300         if (strpos($col, '(') !== false) {
00301             list($col, $vals) = explode('(', $col);
00302         }
00303 
00304         if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
00305             return $col;
00306         }
00307         if (($col == 'tinyint' && $limit == 1) || $col == 'boolean') {
00308             return 'boolean';
00309         }
00310         if (strpos($col, 'int') !== false) {
00311             return 'integer';
00312         }
00313         if (strpos($col, 'char') !== false || $col == 'tinytext') {
00314             return 'string';
00315         }
00316         if (strpos($col, 'text') !== false) {
00317             return 'text';
00318         }
00319         if (strpos($col, 'blob') !== false || $col == 'binary') {
00320             return 'binary';
00321         }
00322         if (strpos($col, 'float') !== false || strpos($col, 'double') !== false || strpos($col, 'decimal') !== false) {
00323             return 'float';
00324         }
00325         if (strpos($col, 'enum') !== false) {
00326             return "enum($vals)";
00327         }
00328         return 'text';
00329     }
00330 /**
00331  * Gets the length of a database-native column description, or null if no length
00332  *
00333  * @param string $real Real database-layer column type (i.e. "varchar(255)")
00334  * @return integer An integer representing the length of the column
00335  */
00336     function length($real) {
00337         $col = str_replace(array(')', 'unsigned'), '', $real);
00338         $limit = null;
00339     
00340         if (strpos($col, '(') !== false) {
00341             list($col, $limit) = explode('(', $col);
00342         }
00343     
00344         if ($limit != null) {
00345             return intval($limit);
00346         }
00347         return null;
00348     }
00349 /**
00350  * Enter description here...
00351  *
00352  * @param unknown_type $results
00353  */
00354     function resultSet(&$results) {
00355         if (isset($this->results) && is_resource($this->results) && $this->results != $results) {
00356             mysqli_free_result($this->results);
00357         }
00358         $this->results =& $results;
00359         $this->map = array();
00360         $numFields = mysqli_num_fields($results);
00361         $index = 0;
00362         $j = 0;
00363         while ($j < $numFields) {
00364             $column = mysqli_fetch_field_direct($results, $j);
00365             if (!empty($column->table)) {
00366                 $this->map[$index++] = array($column->table, $column->name);
00367             } else {
00368                 $this->map[$index++] = array(0, $column->name);
00369             }
00370             $j++;
00371         }
00372     }
00373 /**
00374  * Fetches the next row from the current result set
00375  *
00376  * @return unknown
00377  */
00378     function fetchResult() {
00379         if ($row = mysqli_fetch_row($this->results)) {
00380             $resultRow = array();
00381             $i = 0;
00382             foreach ($row as $index => $field) {
00383                 $table = $column = null;
00384                 if (count($this->map[$index]) == 2) {
00385                     list($table, $column) = $this->map[$index];
00386                 }
00387                 $resultRow[$table][$column] = $row[$index];
00388                 $i++;
00389             }
00390             return $resultRow;
00391         }
00392         return false;
00393     }
00394 /**
00395  * Gets the database encoding
00396  *
00397  * @return string The database encoding
00398  */
00399     function getEncoding() {
00400         return mysqli_client_encoding($this->connection);
00401     }
00402 /**
00403  * Checks if the result is valid
00404  *
00405  * @return boolean True if the result is valid, else false
00406  */
00407     function hasResult() {
00408         return is_object($this->_result);
00409     }
00410 }
00411 ?>

Generated on Sun Nov 22 00:30:53 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7