PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/system/database/drivers/mysqli/mysqli_driver.php

https://gitlab.com/narugamy/flores-hermano
PHP | 484 lines | 185 code | 68 blank | 231 comment | 22 complexity | bebc525d52c0a69b437f8bfff7237498 MD5 | raw file
  1. <?php
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP
  6. *
  7. * This content is released under the MIT License (MIT)
  8. *
  9. * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy
  12. * of this software and associated documentation files (the "Software"), to deal
  13. * in the Software without restriction, including without limitation the rights
  14. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. * copies of the Software, and to permit persons to whom the Software is
  16. * furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in
  19. * all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. * THE SOFTWARE.
  28. *
  29. * @package CodeIgniter
  30. * @author EllisLab Dev Team
  31. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
  32. * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
  33. * @license http://opensource.org/licenses/MIT MIT License
  34. * @link http://codeigniter.com
  35. * @since Version 1.3.0
  36. * @filesource
  37. */
  38. defined('BASEPATH') OR exit('No direct script access allowed');
  39. /**
  40. * MySQLi Database Adapter Class
  41. *
  42. * Note: _DB is an extender class that the app controller
  43. * creates dynamically based on whether the query builder
  44. * class is being used or not.
  45. *
  46. * @package CodeIgniter
  47. * @subpackage Drivers
  48. * @category Database
  49. * @author EllisLab Dev Team
  50. * @link http://codeigniter.com/user_guide/database/
  51. */
  52. class CI_DB_mysqli_driver extends CI_DB {
  53. /**
  54. * Database driver
  55. *
  56. * @var string
  57. */
  58. public $dbdriver = 'mysqli';
  59. /**
  60. * Compression flag
  61. *
  62. * @var bool
  63. */
  64. public $compress = FALSE;
  65. /**
  66. * DELETE hack flag
  67. *
  68. * Whether to use the MySQL "delete hack" which allows the number
  69. * of affected rows to be shown. Uses a preg_replace when enabled,
  70. * adding a bit more processing to all queries.
  71. *
  72. * @var bool
  73. */
  74. public $delete_hack = TRUE;
  75. /**
  76. * Strict ON flag
  77. *
  78. * Whether we're running in strict SQL mode.
  79. *
  80. * @var bool
  81. */
  82. public $stricton = FALSE;
  83. // --------------------------------------------------------------------
  84. /**
  85. * Identifier escape character
  86. *
  87. * @var string
  88. */
  89. protected $_escape_char = '`';
  90. // --------------------------------------------------------------------
  91. /**
  92. * Database connection
  93. *
  94. * @param bool $persistent
  95. * @return object
  96. * @todo SSL support
  97. */
  98. public function db_connect($persistent = FALSE)
  99. {
  100. // Do we have a socket path?
  101. if ($this->hostname[0] === '/')
  102. {
  103. $hostname = NULL;
  104. $port = NULL;
  105. $socket = $this->hostname;
  106. }
  107. else
  108. {
  109. // Persistent connection support was added in PHP 5.3.0
  110. $hostname = ($persistent === TRUE && is_php('5.3'))
  111. ? 'p:'.$this->hostname : $this->hostname;
  112. $port = empty($this->port) ? NULL : $this->port;
  113. $socket = NULL;
  114. }
  115. $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
  116. $mysqli = mysqli_init();
  117. $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10);
  118. if ($this->stricton)
  119. {
  120. $mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"');
  121. }
  122. return $mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags)
  123. ? $mysqli : FALSE;
  124. }
  125. // --------------------------------------------------------------------
  126. /**
  127. * Reconnect
  128. *
  129. * Keep / reestablish the db connection if no queries have been
  130. * sent for a length of time exceeding the server's idle timeout
  131. *
  132. * @return void
  133. */
  134. public function reconnect()
  135. {
  136. if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE)
  137. {
  138. $this->conn_id = FALSE;
  139. }
  140. }
  141. // --------------------------------------------------------------------
  142. /**
  143. * Select the database
  144. *
  145. * @param string $database
  146. * @return bool
  147. */
  148. public function db_select($database = '')
  149. {
  150. if ($database === '')
  151. {
  152. $database = $this->database;
  153. }
  154. if ($this->conn_id->select_db($database))
  155. {
  156. $this->database = $database;
  157. return TRUE;
  158. }
  159. return FALSE;
  160. }
  161. // --------------------------------------------------------------------
  162. /**
  163. * Set client character set
  164. *
  165. * @param string $charset
  166. * @return bool
  167. */
  168. protected function _db_set_charset($charset)
  169. {
  170. return $this->conn_id->set_charset($charset);
  171. }
  172. // --------------------------------------------------------------------
  173. /**
  174. * Database version number
  175. *
  176. * @return string
  177. */
  178. public function version()
  179. {
  180. if (isset($this->data_cache['version']))
  181. {
  182. return $this->data_cache['version'];
  183. }
  184. return $this->data_cache['version'] = $this->conn_id->server_info;
  185. }
  186. // --------------------------------------------------------------------
  187. /**
  188. * Execute the query
  189. *
  190. * @param string $sql an SQL query
  191. * @return mixed
  192. */
  193. protected function _execute($sql)
  194. {
  195. return $this->conn_id->query($this->_prep_query($sql));
  196. }
  197. // --------------------------------------------------------------------
  198. /**
  199. * Prep the query
  200. *
  201. * If needed, each database adapter can prep the query string
  202. *
  203. * @param string $sql an SQL query
  204. * @return string
  205. */
  206. protected function _prep_query($sql)
  207. {
  208. // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack
  209. // modifies the query so that it a proper number of affected rows is returned.
  210. if ($this->delete_hack === TRUE && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
  211. {
  212. return trim($sql).' WHERE 1=1';
  213. }
  214. return $sql;
  215. }
  216. // --------------------------------------------------------------------
  217. /**
  218. * Begin Transaction
  219. *
  220. * @param bool $test_mode
  221. * @return bool
  222. */
  223. public function trans_begin($test_mode = FALSE)
  224. {
  225. // When transactions are nested we only begin/commit/rollback the outermost ones
  226. if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
  227. {
  228. return TRUE;
  229. }
  230. // Reset the transaction failure flag.
  231. // If the $test_mode flag is set to TRUE transactions will be rolled back
  232. // even if the queries produce a successful result.
  233. $this->_trans_failure = ($test_mode === TRUE);
  234. $this->conn_id->autocommit(FALSE);
  235. return is_php('5.5')
  236. ? $this->conn_id->begin_transaction()
  237. : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
  238. }
  239. // --------------------------------------------------------------------
  240. /**
  241. * Commit Transaction
  242. *
  243. * @return bool
  244. */
  245. public function trans_commit()
  246. {
  247. // When transactions are nested we only begin/commit/rollback the outermost ones
  248. if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
  249. {
  250. return TRUE;
  251. }
  252. if ($this->conn_id->commit())
  253. {
  254. $this->conn_id->autocommit(TRUE);
  255. return TRUE;
  256. }
  257. return FALSE;
  258. }
  259. // --------------------------------------------------------------------
  260. /**
  261. * Rollback Transaction
  262. *
  263. * @return bool
  264. */
  265. public function trans_rollback()
  266. {
  267. // When transactions are nested we only begin/commit/rollback the outermost ones
  268. if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
  269. {
  270. return TRUE;
  271. }
  272. if ($this->conn_id->rollback())
  273. {
  274. $this->conn_id->autocommit(TRUE);
  275. return TRUE;
  276. }
  277. return FALSE;
  278. }
  279. // --------------------------------------------------------------------
  280. /**
  281. * Platform-dependant string escape
  282. *
  283. * @param string
  284. * @return string
  285. */
  286. protected function _escape_str($str)
  287. {
  288. return $this->conn_id->real_escape_string($str);
  289. }
  290. // --------------------------------------------------------------------
  291. /**
  292. * Affected Rows
  293. *
  294. * @return int
  295. */
  296. public function affected_rows()
  297. {
  298. return $this->conn_id->affected_rows;
  299. }
  300. // --------------------------------------------------------------------
  301. /**
  302. * Insert ID
  303. *
  304. * @return int
  305. */
  306. public function insert_id()
  307. {
  308. return $this->conn_id->insert_id;
  309. }
  310. // --------------------------------------------------------------------
  311. /**
  312. * List table query
  313. *
  314. * Generates a platform-specific query string so that the table names can be fetched
  315. *
  316. * @param bool $prefix_limit
  317. * @return string
  318. */
  319. protected function _list_tables($prefix_limit = FALSE)
  320. {
  321. $sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database);
  322. if ($prefix_limit !== FALSE && $this->dbprefix !== '')
  323. {
  324. return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
  325. }
  326. return $sql;
  327. }
  328. // --------------------------------------------------------------------
  329. /**
  330. * Show column query
  331. *
  332. * Generates a platform-specific query string so that the column names can be fetched
  333. *
  334. * @param string $table
  335. * @return string
  336. */
  337. protected function _list_columns($table = '')
  338. {
  339. return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
  340. }
  341. // --------------------------------------------------------------------
  342. /**
  343. * Returns an object with field data
  344. *
  345. * @param string $table
  346. * @return array
  347. */
  348. public function field_data($table)
  349. {
  350. if (($query = $this->query('SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE))) === FALSE)
  351. {
  352. return FALSE;
  353. }
  354. $query = $query->result_object();
  355. $retval = array();
  356. for ($i = 0, $c = count($query); $i < $c; $i++)
  357. {
  358. $retval[$i] = new stdClass();
  359. $retval[$i]->name = $query[$i]->Field;
  360. sscanf($query[$i]->Type, '%[a-z](%d)',
  361. $retval[$i]->type,
  362. $retval[$i]->max_length
  363. );
  364. $retval[$i]->default = $query[$i]->Default;
  365. $retval[$i]->primary_key = (int) ($query[$i]->Key === 'PRI');
  366. }
  367. return $retval;
  368. }
  369. // --------------------------------------------------------------------
  370. /**
  371. * Error
  372. *
  373. * Returns an array containing code and message of the last
  374. * database error that has occurred.
  375. *
  376. * @return array
  377. */
  378. public function error()
  379. {
  380. if ( ! empty($this->conn_id->connect_errno))
  381. {
  382. return array(
  383. 'code' => $this->conn_id->connect_errno,
  384. 'message' => is_php('5.2.9') ? $this->conn_id->connect_error : mysqli_connect_error()
  385. );
  386. }
  387. return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error);
  388. }
  389. // --------------------------------------------------------------------
  390. /**
  391. * FROM tables
  392. *
  393. * Groups tables in FROM clauses if needed, so there is no confusion
  394. * about operator precedence.
  395. *
  396. * @return string
  397. */
  398. protected function _from_tables()
  399. {
  400. if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
  401. {
  402. return '('.implode(', ', $this->qb_from).')';
  403. }
  404. return implode(', ', $this->qb_from);
  405. }
  406. // --------------------------------------------------------------------
  407. /**
  408. * Close DB Connection
  409. *
  410. * @return void
  411. */
  412. protected function _close()
  413. {
  414. $this->conn_id->close();
  415. }
  416. }