PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/libs/model/datasources/dbo/dbo_mysqli.php

https://github.com/cgajardo/repositorium
PHP | 332 lines | 175 code | 30 blank | 127 comment | 47 complexity | f7357918fe38737fd78a890dccbd9182 MD5 | raw file
  1. <?php
  2. /**
  3. * MySQLi layer for DBO
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package cake
  16. * @subpackage cake.cake.libs.model.datasources.dbo
  17. * @since CakePHP(tm) v 1.1.4.2974
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. App::import('Datasource', 'DboMysql');
  21. /**
  22. * MySQLi DBO driver object
  23. *
  24. * Provides connection and SQL generation for MySQL RDMS using PHP's MySQLi Interface
  25. *
  26. * @package cake
  27. * @subpackage cake.cake.libs.model.datasources.dbo
  28. */
  29. class DboMysqli extends DboMysqlBase {
  30. /**
  31. * Datasource Description
  32. *
  33. * @var string
  34. */
  35. var $description = "Mysqli DBO Driver";
  36. /**
  37. * Base configuration settings for Mysqli driver
  38. *
  39. * @var array
  40. */
  41. var $_baseConfig = array(
  42. 'persistent' => true,
  43. 'host' => 'localhost',
  44. 'login' => 'root',
  45. 'password' => '',
  46. 'database' => 'cake',
  47. 'port' => '3306',
  48. 'socket' => null
  49. );
  50. /**
  51. * Connects to the database using options in the given configuration array.
  52. *
  53. * @return boolean True if the database could be connected, else false
  54. */
  55. function connect() {
  56. $config = $this->config;
  57. $this->connected = false;
  58. $this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port'], $config['socket']);
  59. if ($this->connection !== false) {
  60. $this->connected = true;
  61. }
  62. $this->_useAlias = (bool)version_compare(mysqli_get_server_info($this->connection), "4.1", ">=");
  63. if (!empty($config['encoding'])) {
  64. $this->setEncoding($config['encoding']);
  65. }
  66. return $this->connected;
  67. }
  68. /**
  69. * Check that MySQLi is installed/enabled
  70. *
  71. * @return boolean
  72. */
  73. function enabled() {
  74. return extension_loaded('mysqli');
  75. }
  76. /**
  77. * Disconnects from database.
  78. *
  79. * @return boolean True if the database could be disconnected, else false
  80. */
  81. function disconnect() {
  82. if (isset($this->results) && is_resource($this->results)) {
  83. mysqli_free_result($this->results);
  84. }
  85. $this->connected = !@mysqli_close($this->connection);
  86. return !$this->connected;
  87. }
  88. /**
  89. * Executes given SQL statement.
  90. *
  91. * @param string $sql SQL statement
  92. * @return resource Result resource identifier
  93. * @access protected
  94. */
  95. function _execute($sql) {
  96. if (preg_match('/^\s*call/i', $sql)) {
  97. return $this->_executeProcedure($sql);
  98. }
  99. return mysqli_query($this->connection, $sql);
  100. }
  101. /**
  102. * Executes given SQL statement (procedure call).
  103. *
  104. * @param string $sql SQL statement (procedure call)
  105. * @return resource Result resource identifier for first recordset
  106. * @access protected
  107. */
  108. function _executeProcedure($sql) {
  109. $answer = mysqli_multi_query($this->connection, $sql);
  110. $firstResult = mysqli_store_result($this->connection);
  111. if (mysqli_more_results($this->connection)) {
  112. while ($lastResult = mysqli_next_result($this->connection));
  113. }
  114. return $firstResult;
  115. }
  116. /**
  117. * Returns an array of sources (tables) in the database.
  118. *
  119. * @return array Array of tablenames in the database
  120. */
  121. function listSources() {
  122. $cache = parent::listSources();
  123. if ($cache !== null) {
  124. return $cache;
  125. }
  126. $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
  127. if (!$result) {
  128. return array();
  129. }
  130. $tables = array();
  131. while ($line = mysqli_fetch_row($result)) {
  132. $tables[] = $line[0];
  133. }
  134. parent::listSources($tables);
  135. return $tables;
  136. }
  137. /**
  138. * Returns a quoted and escaped string of $data for use in an SQL statement.
  139. *
  140. * @param string $data String to be prepared for use in an SQL statement
  141. * @param string $column The column into which this data will be inserted
  142. * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
  143. * @return string Quoted and escaped data
  144. */
  145. function value($data, $column = null, $safe = false) {
  146. $parent = parent::value($data, $column, $safe);
  147. if ($parent != null) {
  148. return $parent;
  149. }
  150. if ($data === null || (is_array($data) && empty($data))) {
  151. return 'NULL';
  152. }
  153. if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
  154. return "''";
  155. }
  156. if (empty($column)) {
  157. $column = $this->introspectType($data);
  158. }
  159. switch ($column) {
  160. case 'boolean':
  161. return $this->boolean((bool)$data);
  162. break;
  163. case 'integer' :
  164. case 'float' :
  165. case null :
  166. if ($data === '') {
  167. return 'NULL';
  168. }
  169. if ((is_int($data) || is_float($data) || $data === '0') || (
  170. is_numeric($data) && strpos($data, ',') === false &&
  171. $data[0] != '0' && strpos($data, 'e') === false)) {
  172. return $data;
  173. }
  174. default:
  175. $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
  176. break;
  177. }
  178. return $data;
  179. }
  180. /**
  181. * Returns a formatted error message from previous database operation.
  182. *
  183. * @return string Error message with error number
  184. */
  185. function lastError() {
  186. if (mysqli_errno($this->connection)) {
  187. return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
  188. }
  189. return null;
  190. }
  191. /**
  192. * Returns number of affected rows in previous database operation. If no previous operation exists,
  193. * this returns false.
  194. *
  195. * @return integer Number of affected rows
  196. */
  197. function lastAffected() {
  198. if ($this->_result) {
  199. return mysqli_affected_rows($this->connection);
  200. }
  201. return null;
  202. }
  203. /**
  204. * Returns number of rows in previous resultset. If no previous resultset exists,
  205. * this returns false.
  206. *
  207. * @return integer Number of rows in resultset
  208. */
  209. function lastNumRows() {
  210. if ($this->hasResult()) {
  211. return mysqli_num_rows($this->_result);
  212. }
  213. return null;
  214. }
  215. /**
  216. * Returns the ID generated from the previous INSERT operation.
  217. *
  218. * @param unknown_type $source
  219. * @return in
  220. */
  221. function lastInsertId($source = null) {
  222. $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
  223. if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
  224. return $id[0]['insertID'];
  225. }
  226. return null;
  227. }
  228. /**
  229. * Enter description here...
  230. *
  231. * @param unknown_type $results
  232. */
  233. function resultSet(&$results) {
  234. if (isset($this->results) && is_resource($this->results) && $this->results != $results) {
  235. mysqli_free_result($this->results);
  236. }
  237. $this->results =& $results;
  238. $this->map = array();
  239. $numFields = mysqli_num_fields($results);
  240. $index = 0;
  241. $j = 0;
  242. while ($j < $numFields) {
  243. $column = mysqli_fetch_field_direct($results, $j);
  244. if (!empty($column->table)) {
  245. $this->map[$index++] = array($column->table, $column->name);
  246. } else {
  247. $this->map[$index++] = array(0, $column->name);
  248. }
  249. $j++;
  250. }
  251. }
  252. /**
  253. * Fetches the next row from the current result set
  254. *
  255. * @return unknown
  256. */
  257. function fetchResult() {
  258. if ($row = mysqli_fetch_row($this->results)) {
  259. $resultRow = array();
  260. foreach ($row as $index => $field) {
  261. $table = $column = null;
  262. if (count($this->map[$index]) === 2) {
  263. list($table, $column) = $this->map[$index];
  264. }
  265. $resultRow[$table][$column] = $row[$index];
  266. }
  267. return $resultRow;
  268. }
  269. return false;
  270. }
  271. /**
  272. * Gets the database encoding
  273. *
  274. * @return string The database encoding
  275. */
  276. function getEncoding() {
  277. return mysqli_client_encoding($this->connection);
  278. }
  279. /**
  280. * Query charset by collation
  281. *
  282. * @param string $name Collation name
  283. * @return string Character set name
  284. */
  285. function getCharsetName($name) {
  286. if ((bool)version_compare(mysqli_get_server_info($this->connection), "5", ">=")) {
  287. $cols = $this->query('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME= ' . $this->value($name) . ';');
  288. if (isset($cols[0]['COLLATIONS']['CHARACTER_SET_NAME'])) {
  289. return $cols[0]['COLLATIONS']['CHARACTER_SET_NAME'];
  290. }
  291. }
  292. return false;
  293. }
  294. /**
  295. * Checks if the result is valid
  296. *
  297. * @return boolean True if the result is valid, else false
  298. */
  299. function hasResult() {
  300. return is_object($this->_result);
  301. }
  302. }