cubrid_driver.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.1.6 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author EllisLab Dev Team
  9. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
  10. * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
  11. * @license http://codeigniter.com/user_guide/license.html
  12. * @link http://codeigniter.com
  13. * @since Version 2.0.2
  14. * @filesource
  15. */
  16. // ------------------------------------------------------------------------
  17. /**
  18. * CUBRID Database Adapter Class
  19. *
  20. * Note: _DB is an extender class that the app controller
  21. * creates dynamically based on whether the active record
  22. * class is being used or not.
  23. *
  24. * @package CodeIgniter
  25. * @subpackage Drivers
  26. * @category Database
  27. * @author Esen Sagynov
  28. * @link http://codeigniter.com/user_guide/database/
  29. */
  30. class CI_DB_cubrid_driver extends CI_DB {
  31. // Default CUBRID Broker port. Will be used unless user
  32. // explicitly specifies another one.
  33. const DEFAULT_PORT = 33000;
  34. var $dbdriver = 'cubrid';
  35. // The character used for escaping - no need in CUBRID
  36. var $_escape_char = '';
  37. // clause and character used for LIKE escape sequences - not used in CUBRID
  38. var $_like_escape_str = '';
  39. var $_like_escape_chr = '';
  40. /**
  41. * The syntax to count rows is slightly different across different
  42. * database engines, so this string appears in each driver and is
  43. * used for the count_all() and count_all_results() functions.
  44. */
  45. var $_count_string = 'SELECT COUNT(*) AS ';
  46. var $_random_keyword = ' RAND()'; // database specific random keyword
  47. /**
  48. * Non-persistent database connection
  49. *
  50. * @access private called by the base class
  51. * @return resource
  52. */
  53. function db_connect()
  54. {
  55. // If no port is defined by the user, use the default value
  56. if ($this->port == '')
  57. {
  58. $this->port = self::DEFAULT_PORT;
  59. }
  60. $conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
  61. if ($conn)
  62. {
  63. // Check if a user wants to run queries in dry, i.e. run the
  64. // queries but not commit them.
  65. if (isset($this->auto_commit) && ! $this->auto_commit)
  66. {
  67. cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_FALSE);
  68. }
  69. else
  70. {
  71. cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_TRUE);
  72. $this->auto_commit = TRUE;
  73. }
  74. }
  75. return $conn;
  76. }
  77. // --------------------------------------------------------------------
  78. /**
  79. * Persistent database connection
  80. * In CUBRID persistent DB connection is supported natively in CUBRID
  81. * engine which can be configured in the CUBRID Broker configuration
  82. * file by setting the CCI_PCONNECT parameter to ON. In that case, all
  83. * connections established between the client application and the
  84. * server will become persistent. This is calling the same
  85. * @cubrid_connect function will establish persisten connection
  86. * considering that the CCI_PCONNECT is ON.
  87. *
  88. * @access private called by the base class
  89. * @return resource
  90. */
  91. function db_pconnect()
  92. {
  93. return $this->db_connect();
  94. }
  95. // --------------------------------------------------------------------
  96. /**
  97. * Reconnect
  98. *
  99. * Keep / reestablish the db connection if no queries have been
  100. * sent for a length of time exceeding the server's idle timeout
  101. *
  102. * @access public
  103. * @return void
  104. */
  105. function reconnect()
  106. {
  107. if (cubrid_ping($this->conn_id) === FALSE)
  108. {
  109. $this->conn_id = FALSE;
  110. }
  111. }
  112. // --------------------------------------------------------------------
  113. /**
  114. * Select the database
  115. *
  116. * @access private called by the base class
  117. * @return resource
  118. */
  119. function db_select()
  120. {
  121. // In CUBRID there is no need to select a database as the database
  122. // is chosen at the connection time.
  123. // So, to determine if the database is "selected", all we have to
  124. // do is ping the server and return that value.
  125. return cubrid_ping($this->conn_id);
  126. }
  127. // --------------------------------------------------------------------
  128. /**
  129. * Set client character set
  130. *
  131. * @access public
  132. * @param string
  133. * @param string
  134. * @return resource
  135. */
  136. function db_set_charset($charset, $collation)
  137. {
  138. // In CUBRID, there is no need to set charset or collation.
  139. // This is why returning true will allow the application continue
  140. // its normal process.
  141. return TRUE;
  142. }
  143. // --------------------------------------------------------------------
  144. /**
  145. * Version number query string
  146. *
  147. * @access public
  148. * @return string
  149. */
  150. function _version()
  151. {
  152. // To obtain the CUBRID Server version, no need to run the SQL query.
  153. // CUBRID PHP API provides a function to determin this value.
  154. // This is why we also need to add 'cubrid' value to the list of
  155. // $driver_version_exceptions array in DB_driver class in
  156. // version() function.
  157. return cubrid_get_server_info($this->conn_id);
  158. }
  159. // --------------------------------------------------------------------
  160. /**
  161. * Execute the query
  162. *
  163. * @access private called by the base class
  164. * @param string an SQL query
  165. * @return resource
  166. */
  167. function _execute($sql)
  168. {
  169. $sql = $this->_prep_query($sql);
  170. return @cubrid_query($sql, $this->conn_id);
  171. }
  172. // --------------------------------------------------------------------
  173. /**
  174. * Prep the query
  175. *
  176. * If needed, each database adapter can prep the query string
  177. *
  178. * @access private called by execute()
  179. * @param string an SQL query
  180. * @return string
  181. */
  182. function _prep_query($sql)
  183. {
  184. // No need to prepare
  185. return $sql;
  186. }
  187. // --------------------------------------------------------------------
  188. /**
  189. * Begin Transaction
  190. *
  191. * @access public
  192. * @return bool
  193. */
  194. function trans_begin($test_mode = FALSE)
  195. {
  196. if ( ! $this->trans_enabled)
  197. {
  198. return TRUE;
  199. }
  200. // When transactions are nested we only begin/commit/rollback the outermost ones
  201. if ($this->_trans_depth > 0)
  202. {
  203. return TRUE;
  204. }
  205. // Reset the transaction failure flag.
  206. // If the $test_mode flag is set to TRUE transactions will be rolled back
  207. // even if the queries produce a successful result.
  208. $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
  209. if (cubrid_get_autocommit($this->conn_id))
  210. {
  211. cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
  212. }
  213. return TRUE;
  214. }
  215. // --------------------------------------------------------------------
  216. /**
  217. * Commit Transaction
  218. *
  219. * @access public
  220. * @return bool
  221. */
  222. function trans_commit()
  223. {
  224. if ( ! $this->trans_enabled)
  225. {
  226. return TRUE;
  227. }
  228. // When transactions are nested we only begin/commit/rollback the outermost ones
  229. if ($this->_trans_depth > 0)
  230. {
  231. return TRUE;
  232. }
  233. cubrid_commit($this->conn_id);
  234. if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
  235. {
  236. cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
  237. }
  238. return TRUE;
  239. }
  240. // --------------------------------------------------------------------
  241. /**
  242. * Rollback Transaction
  243. *
  244. * @access public
  245. * @return bool
  246. */
  247. function trans_rollback()
  248. {
  249. if ( ! $this->trans_enabled)
  250. {
  251. return TRUE;
  252. }
  253. // When transactions are nested we only begin/commit/rollback the outermost ones
  254. if ($this->_trans_depth > 0)
  255. {
  256. return TRUE;
  257. }
  258. cubrid_rollback($this->conn_id);
  259. if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
  260. {
  261. cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
  262. }
  263. return TRUE;
  264. }
  265. // --------------------------------------------------------------------
  266. /**
  267. * Escape String
  268. *
  269. * @access public
  270. * @param string
  271. * @param bool whether or not the string will be used in a LIKE condition
  272. * @return string
  273. */
  274. function escape_str($str, $like = FALSE)
  275. {
  276. if (is_array($str))
  277. {
  278. foreach ($str as $key => $val)
  279. {
  280. $str[$key] = $this->escape_str($val, $like);
  281. }
  282. return $str;
  283. }
  284. if (function_exists('cubrid_real_escape_string') AND is_resource($this->conn_id))
  285. {
  286. $str = cubrid_real_escape_string($str, $this->conn_id);
  287. }
  288. else
  289. {
  290. $str = addslashes($str);
  291. }
  292. // escape LIKE condition wildcards
  293. if ($like === TRUE)
  294. {
  295. $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
  296. }
  297. return $str;
  298. }
  299. // --------------------------------------------------------------------
  300. /**
  301. * Affected Rows
  302. *
  303. * @access public
  304. * @return integer
  305. */
  306. function affected_rows()
  307. {
  308. return @cubrid_affected_rows($this->conn_id);
  309. }
  310. // --------------------------------------------------------------------
  311. /**
  312. * Insert ID
  313. *
  314. * @access public
  315. * @return integer
  316. */
  317. function insert_id()
  318. {
  319. return @cubrid_insert_id($this->conn_id);
  320. }
  321. // --------------------------------------------------------------------
  322. /**
  323. * "Count All" query
  324. *
  325. * Generates a platform-specific query string that counts all records in
  326. * the specified table
  327. *
  328. * @access public
  329. * @param string
  330. * @return string
  331. */
  332. function count_all($table = '')
  333. {
  334. if ($table == '')
  335. {
  336. return 0;
  337. }
  338. $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
  339. if ($query->num_rows() == 0)
  340. {
  341. return 0;
  342. }
  343. $row = $query->row();
  344. $this->_reset_select();
  345. return (int) $row->numrows;
  346. }
  347. // --------------------------------------------------------------------
  348. /**
  349. * List table query
  350. *
  351. * Generates a platform-specific query string so that the table names can be fetched
  352. *
  353. * @access private
  354. * @param boolean
  355. * @return string
  356. */
  357. function _list_tables($prefix_limit = FALSE)
  358. {
  359. $sql = "SHOW TABLES";
  360. if ($prefix_limit !== FALSE AND $this->dbprefix != '')
  361. {
  362. $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
  363. }
  364. return $sql;
  365. }
  366. // --------------------------------------------------------------------
  367. /**
  368. * Show column query
  369. *
  370. * Generates a platform-specific query string so that the column names can be fetched
  371. *
  372. * @access public
  373. * @param string the table name
  374. * @return string
  375. */
  376. function _list_columns($table = '')
  377. {
  378. return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
  379. }
  380. // --------------------------------------------------------------------
  381. /**
  382. * Field data query
  383. *
  384. * Generates a platform-specific query so that the column data can be retrieved
  385. *
  386. * @access public
  387. * @param string the table name
  388. * @return object
  389. */
  390. function _field_data($table)
  391. {
  392. return "SELECT * FROM ".$table." LIMIT 1";
  393. }
  394. // --------------------------------------------------------------------
  395. /**
  396. * The error message string
  397. *
  398. * @access private
  399. * @return string
  400. */
  401. function _error_message()
  402. {
  403. return cubrid_error($this->conn_id);
  404. }
  405. // --------------------------------------------------------------------
  406. /**
  407. * The error message number
  408. *
  409. * @access private
  410. * @return integer
  411. */
  412. function _error_number()
  413. {
  414. return cubrid_errno($this->conn_id);
  415. }
  416. // --------------------------------------------------------------------
  417. /**
  418. * Escape the SQL Identifiers
  419. *
  420. * This function escapes column and table names
  421. *
  422. * @access private
  423. * @param string
  424. * @return string
  425. */
  426. function _escape_identifiers($item)
  427. {
  428. if ($this->_escape_char == '')
  429. {
  430. return $item;
  431. }
  432. foreach ($this->_reserved_identifiers as $id)
  433. {
  434. if (strpos($item, '.'.$id) !== FALSE)
  435. {
  436. $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
  437. // remove duplicates if the user already included the escape
  438. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  439. }
  440. }
  441. if (strpos($item, '.') !== FALSE)
  442. {
  443. $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
  444. }
  445. else
  446. {
  447. $str = $this->_escape_char.$item.$this->_escape_char;
  448. }
  449. // remove duplicates if the user already included the escape
  450. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  451. }
  452. // --------------------------------------------------------------------
  453. /**
  454. * From Tables
  455. *
  456. * This function implicitly groups FROM tables so there is no confusion
  457. * about operator precedence in harmony with SQL standards
  458. *
  459. * @access public
  460. * @param type
  461. * @return type
  462. */
  463. function _from_tables($tables)
  464. {
  465. if ( ! is_array($tables))
  466. {
  467. $tables = array($tables);
  468. }
  469. return '('.implode(', ', $tables).')';
  470. }
  471. // --------------------------------------------------------------------
  472. /**
  473. * Insert statement
  474. *
  475. * Generates a platform-specific insert string from the supplied data
  476. *
  477. * @access public
  478. * @param string the table name
  479. * @param array the insert keys
  480. * @param array the insert values
  481. * @return string
  482. */
  483. function _insert($table, $keys, $values)
  484. {
  485. return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
  486. }
  487. // --------------------------------------------------------------------
  488. /**
  489. * Replace statement
  490. *
  491. * Generates a platform-specific replace string from the supplied data
  492. *
  493. * @access public
  494. * @param string the table name
  495. * @param array the insert keys
  496. * @param array the insert values
  497. * @return string
  498. */
  499. function _replace($table, $keys, $values)
  500. {
  501. return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
  502. }
  503. // --------------------------------------------------------------------
  504. /**
  505. * Insert_batch statement
  506. *
  507. * Generates a platform-specific insert string from the supplied data
  508. *
  509. * @access public
  510. * @param string the table name
  511. * @param array the insert keys
  512. * @param array the insert values
  513. * @return string
  514. */
  515. function _insert_batch($table, $keys, $values)
  516. {
  517. return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
  518. }
  519. // --------------------------------------------------------------------
  520. /**
  521. * Update statement
  522. *
  523. * Generates a platform-specific update string from the supplied data
  524. *
  525. * @access public
  526. * @param string the table name
  527. * @param array the update data
  528. * @param array the where clause
  529. * @param array the orderby clause
  530. * @param array the limit clause
  531. * @return string
  532. */
  533. function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
  534. {
  535. foreach ($values as $key => $val)
  536. {
  537. $valstr[] = sprintf('"%s" = %s', $key, $val);
  538. }
  539. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  540. $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
  541. $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
  542. $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
  543. $sql .= $orderby.$limit;
  544. return $sql;
  545. }
  546. // --------------------------------------------------------------------
  547. /**
  548. * Update_Batch statement
  549. *
  550. * Generates a platform-specific batch update string from the supplied data
  551. *
  552. * @access public
  553. * @param string the table name
  554. * @param array the update data
  555. * @param array the where clause
  556. * @return string
  557. */
  558. function _update_batch($table, $values, $index, $where = NULL)
  559. {
  560. $ids = array();
  561. $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
  562. foreach ($values as $key => $val)
  563. {
  564. $ids[] = $val[$index];
  565. foreach (array_keys($val) as $field)
  566. {
  567. if ($field != $index)
  568. {
  569. $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
  570. }
  571. }
  572. }
  573. $sql = "UPDATE ".$table." SET ";
  574. $cases = '';
  575. foreach ($final as $k => $v)
  576. {
  577. $cases .= $k.' = CASE '."\n";
  578. foreach ($v as $row)
  579. {
  580. $cases .= $row."\n";
  581. }
  582. $cases .= 'ELSE '.$k.' END, ';
  583. }
  584. $sql .= substr($cases, 0, -2);
  585. $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
  586. return $sql;
  587. }
  588. // --------------------------------------------------------------------
  589. /**
  590. * Truncate statement
  591. *
  592. * Generates a platform-specific truncate string from the supplied data
  593. * If the database does not support the truncate() command
  594. * This function maps to "DELETE FROM table"
  595. *
  596. * @access public
  597. * @param string the table name
  598. * @return string
  599. */
  600. function _truncate($table)
  601. {
  602. return "TRUNCATE ".$table;
  603. }
  604. // --------------------------------------------------------------------
  605. /**
  606. * Delete statement
  607. *
  608. * Generates a platform-specific delete string from the supplied data
  609. *
  610. * @access public
  611. * @param string the table name
  612. * @param array the where clause
  613. * @param string the limit clause
  614. * @return string
  615. */
  616. function _delete($table, $where = array(), $like = array(), $limit = FALSE)
  617. {
  618. $conditions = '';
  619. if (count($where) > 0 OR count($like) > 0)
  620. {
  621. $conditions = "\nWHERE ";
  622. $conditions .= implode("\n", $this->ar_where);
  623. if (count($where) > 0 && count($like) > 0)
  624. {
  625. $conditions .= " AND ";
  626. }
  627. $conditions .= implode("\n", $like);
  628. }
  629. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  630. return "DELETE FROM ".$table.$conditions.$limit;
  631. }
  632. // --------------------------------------------------------------------
  633. /**
  634. * Limit string
  635. *
  636. * Generates a platform-specific LIMIT clause
  637. *
  638. * @access public
  639. * @param string the sql query string
  640. * @param integer the number of rows to limit the query to
  641. * @param integer the offset value
  642. * @return string
  643. */
  644. function _limit($sql, $limit, $offset)
  645. {
  646. if ($offset == 0)
  647. {
  648. $offset = '';
  649. }
  650. else
  651. {
  652. $offset .= ", ";
  653. }
  654. return $sql."LIMIT ".$offset.$limit;
  655. }
  656. // --------------------------------------------------------------------
  657. /**
  658. * Close DB Connection
  659. *
  660. * @access public
  661. * @param resource
  662. * @return void
  663. */
  664. function _close($conn_id)
  665. {
  666. @cubrid_close($conn_id);
  667. }
  668. }
  669. /* End of file cubrid_driver.php */
  670. /* Location: ./system/database/drivers/cubrid/cubrid_driver.php */