cubrid_driver.php 17 KB

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