PageRenderTime 54ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/system/database/drivers/postgre/postgre_driver.php

https://gitlab.com/lisit1003/TTPHPServer
PHP | 703 lines | 279 code | 104 blank | 320 comment | 37 complexity | ce9450e1b4015af999aaa0dd35c6c5a9 MD5 | raw file
  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 ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * Postgre 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 ExpressionEngine Dev Team
  27. * @link http://codeigniter.com/user_guide/database/
  28. */
  29. class CI_DB_postgre_driver extends CI_DB {
  30. var $dbdriver = 'postgre';
  31. var $_escape_char = '"';
  32. // clause and character used for LIKE escape sequences
  33. var $_like_escape_str = " ESCAPE '%s' ";
  34. var $_like_escape_chr = '!';
  35. /**
  36. * The syntax to count rows is slightly different across different
  37. * database engines, so this string appears in each driver and is
  38. * used for the count_all() and count_all_results() functions.
  39. */
  40. var $_count_string = "SELECT COUNT(*) AS ";
  41. var $_random_keyword = ' RANDOM()'; // database specific random keyword
  42. /**
  43. * Connection String
  44. *
  45. * @access private
  46. * @return string
  47. */
  48. function _connect_string()
  49. {
  50. $components = array(
  51. 'hostname' => 'host',
  52. 'port' => 'port',
  53. 'database' => 'dbname',
  54. 'username' => 'user',
  55. 'password' => 'password'
  56. );
  57. $connect_string = "";
  58. foreach ($components as $key => $val)
  59. {
  60. if (isset($this->$key) && $this->$key != '')
  61. {
  62. $connect_string .= " $val=".$this->$key;
  63. }
  64. }
  65. return trim($connect_string);
  66. }
  67. // --------------------------------------------------------------------
  68. /**
  69. * Non-persistent database connection
  70. *
  71. * @access private called by the base class
  72. * @return resource
  73. */
  74. function db_connect()
  75. {
  76. return @pg_connect($this->_connect_string());
  77. }
  78. // --------------------------------------------------------------------
  79. /**
  80. * Persistent database connection
  81. *
  82. * @access private called by the base class
  83. * @return resource
  84. */
  85. function db_pconnect()
  86. {
  87. return @pg_pconnect($this->_connect_string());
  88. }
  89. // --------------------------------------------------------------------
  90. /**
  91. * Reconnect
  92. *
  93. * Keep / reestablish the db connection if no queries have been
  94. * sent for a length of time exceeding the server's idle timeout
  95. *
  96. * @access public
  97. * @return void
  98. */
  99. function reconnect()
  100. {
  101. if (pg_ping($this->conn_id) === FALSE)
  102. {
  103. $this->conn_id = FALSE;
  104. }
  105. }
  106. // --------------------------------------------------------------------
  107. /**
  108. * Select the database
  109. *
  110. * @access private called by the base class
  111. * @return resource
  112. */
  113. function db_select()
  114. {
  115. // Not needed for Postgre so we'll return TRUE
  116. return TRUE;
  117. }
  118. // --------------------------------------------------------------------
  119. /**
  120. * Set client character set
  121. *
  122. * @access public
  123. * @param string
  124. * @param string
  125. * @return resource
  126. */
  127. function db_set_charset($charset, $collation)
  128. {
  129. // @todo - add support if needed
  130. return TRUE;
  131. }
  132. // --------------------------------------------------------------------
  133. /**
  134. * Version number query string
  135. *
  136. * @access public
  137. * @return string
  138. */
  139. function _version()
  140. {
  141. return "SELECT version() AS ver";
  142. }
  143. // --------------------------------------------------------------------
  144. /**
  145. * Execute the query
  146. *
  147. * @access private called by the base class
  148. * @param string an SQL query
  149. * @return resource
  150. */
  151. function _execute($sql)
  152. {
  153. $sql = $this->_prep_query($sql);
  154. return @pg_query($this->conn_id, $sql);
  155. }
  156. // --------------------------------------------------------------------
  157. /**
  158. * Prep the query
  159. *
  160. * If needed, each database adapter can prep the query string
  161. *
  162. * @access private called by execute()
  163. * @param string an SQL query
  164. * @return string
  165. */
  166. function _prep_query($sql)
  167. {
  168. return $sql;
  169. }
  170. // --------------------------------------------------------------------
  171. /**
  172. * Begin Transaction
  173. *
  174. * @access public
  175. * @return bool
  176. */
  177. function trans_begin($test_mode = FALSE)
  178. {
  179. if ( ! $this->trans_enabled)
  180. {
  181. return TRUE;
  182. }
  183. // When transactions are nested we only begin/commit/rollback the outermost ones
  184. if ($this->_trans_depth > 0)
  185. {
  186. return TRUE;
  187. }
  188. // Reset the transaction failure flag.
  189. // If the $test_mode flag is set to TRUE transactions will be rolled back
  190. // even if the queries produce a successful result.
  191. $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
  192. return @pg_exec($this->conn_id, "begin");
  193. }
  194. // --------------------------------------------------------------------
  195. /**
  196. * Commit Transaction
  197. *
  198. * @access public
  199. * @return bool
  200. */
  201. function trans_commit()
  202. {
  203. if ( ! $this->trans_enabled)
  204. {
  205. return TRUE;
  206. }
  207. // When transactions are nested we only begin/commit/rollback the outermost ones
  208. if ($this->_trans_depth > 0)
  209. {
  210. return TRUE;
  211. }
  212. return @pg_exec($this->conn_id, "commit");
  213. }
  214. // --------------------------------------------------------------------
  215. /**
  216. * Rollback Transaction
  217. *
  218. * @access public
  219. * @return bool
  220. */
  221. function trans_rollback()
  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. return @pg_exec($this->conn_id, "rollback");
  233. }
  234. // --------------------------------------------------------------------
  235. /**
  236. * Escape String
  237. *
  238. * @access public
  239. * @param string
  240. * @param bool whether or not the string will be used in a LIKE condition
  241. * @return string
  242. */
  243. function escape_str($str, $like = FALSE)
  244. {
  245. if (is_array($str))
  246. {
  247. foreach ($str as $key => $val)
  248. {
  249. $str[$key] = $this->escape_str($val, $like);
  250. }
  251. return $str;
  252. }
  253. $str = pg_escape_string($str);
  254. // escape LIKE condition wildcards
  255. if ($like === TRUE)
  256. {
  257. $str = str_replace( array('%', '_', $this->_like_escape_chr),
  258. array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
  259. $str);
  260. }
  261. return $str;
  262. }
  263. // --------------------------------------------------------------------
  264. /**
  265. * Affected Rows
  266. *
  267. * @access public
  268. * @return integer
  269. */
  270. function affected_rows()
  271. {
  272. return @pg_affected_rows($this->result_id);
  273. }
  274. // --------------------------------------------------------------------
  275. /**
  276. * Insert ID
  277. *
  278. * @access public
  279. * @return integer
  280. */
  281. function insert_id()
  282. {
  283. $v = $this->_version();
  284. $v = $v['server'];
  285. $table = func_num_args() > 0 ? func_get_arg(0) : NULL;
  286. $column = func_num_args() > 1 ? func_get_arg(1) : NULL;
  287. if ($table == NULL && $v >= '8.1')
  288. {
  289. $sql='SELECT LASTVAL() as ins_id';
  290. }
  291. elseif ($table != NULL && $column != NULL && $v >= '8.0')
  292. {
  293. $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
  294. $query = $this->query($sql);
  295. $row = $query->row();
  296. $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
  297. }
  298. elseif ($table != NULL)
  299. {
  300. // seq_name passed in table parameter
  301. $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
  302. }
  303. else
  304. {
  305. return pg_last_oid($this->result_id);
  306. }
  307. $query = $this->query($sql);
  308. $row = $query->row();
  309. return $row->ins_id;
  310. }
  311. // --------------------------------------------------------------------
  312. /**
  313. * "Count All" query
  314. *
  315. * Generates a platform-specific query string that counts all records in
  316. * the specified database
  317. *
  318. * @access public
  319. * @param string
  320. * @return string
  321. */
  322. function count_all($table = '')
  323. {
  324. if ($table == '')
  325. {
  326. return 0;
  327. }
  328. $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
  329. if ($query->num_rows() == 0)
  330. {
  331. return 0;
  332. }
  333. $row = $query->row();
  334. $this->_reset_select();
  335. return (int) $row->numrows;
  336. }
  337. // --------------------------------------------------------------------
  338. /**
  339. * Show table query
  340. *
  341. * Generates a platform-specific query string so that the table names can be fetched
  342. *
  343. * @access private
  344. * @param boolean
  345. * @return string
  346. */
  347. function _list_tables($prefix_limit = FALSE)
  348. {
  349. $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
  350. if ($prefix_limit !== FALSE AND $this->dbprefix != '')
  351. {
  352. $sql .= " AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
  353. }
  354. return $sql;
  355. }
  356. // --------------------------------------------------------------------
  357. /**
  358. * Show column query
  359. *
  360. * Generates a platform-specific query string so that the column names can be fetched
  361. *
  362. * @access public
  363. * @param string the table name
  364. * @return string
  365. */
  366. function _list_columns($table = '')
  367. {
  368. return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
  369. }
  370. // --------------------------------------------------------------------
  371. /**
  372. * Field data query
  373. *
  374. * Generates a platform-specific query so that the column data can be retrieved
  375. *
  376. * @access public
  377. * @param string the table name
  378. * @return object
  379. */
  380. function _field_data($table)
  381. {
  382. return "SELECT * FROM ".$table." LIMIT 1";
  383. }
  384. // --------------------------------------------------------------------
  385. /**
  386. * The error message string
  387. *
  388. * @access private
  389. * @return string
  390. */
  391. function _error_message()
  392. {
  393. return pg_last_error($this->conn_id);
  394. }
  395. // --------------------------------------------------------------------
  396. /**
  397. * The error message number
  398. *
  399. * @access private
  400. * @return integer
  401. */
  402. function _error_number()
  403. {
  404. return '';
  405. }
  406. // --------------------------------------------------------------------
  407. /**
  408. * Escape the SQL Identifiers
  409. *
  410. * This function escapes column and table names
  411. *
  412. * @access private
  413. * @param string
  414. * @return string
  415. */
  416. function _escape_identifiers($item)
  417. {
  418. if ($this->_escape_char == '')
  419. {
  420. return $item;
  421. }
  422. foreach ($this->_reserved_identifiers as $id)
  423. {
  424. if (strpos($item, '.'.$id) !== FALSE)
  425. {
  426. $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
  427. // remove duplicates if the user already included the escape
  428. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  429. }
  430. }
  431. if (strpos($item, '.') !== FALSE)
  432. {
  433. $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
  434. }
  435. else
  436. {
  437. $str = $this->_escape_char.$item.$this->_escape_char;
  438. }
  439. // remove duplicates if the user already included the escape
  440. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  441. }
  442. // --------------------------------------------------------------------
  443. /**
  444. * From Tables
  445. *
  446. * This function implicitly groups FROM tables so there is no confusion
  447. * about operator precedence in harmony with SQL standards
  448. *
  449. * @access public
  450. * @param type
  451. * @return type
  452. */
  453. function _from_tables($tables)
  454. {
  455. if ( ! is_array($tables))
  456. {
  457. $tables = array($tables);
  458. }
  459. return implode(', ', $tables);
  460. }
  461. // --------------------------------------------------------------------
  462. /**
  463. * Insert statement
  464. *
  465. * Generates a platform-specific insert string from the supplied data
  466. *
  467. * @access public
  468. * @param string the table name
  469. * @param array the insert keys
  470. * @param array the insert values
  471. * @return string
  472. */
  473. function _insert($table, $keys, $values)
  474. {
  475. return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
  476. }
  477. // --------------------------------------------------------------------
  478. /**
  479. * Insert_batch statement
  480. *
  481. * Generates a platform-specific insert string from the supplied data
  482. *
  483. * @access public
  484. * @param string the table name
  485. * @param array the insert keys
  486. * @param array the insert values
  487. * @return string
  488. */
  489. function _insert_batch($table, $keys, $values)
  490. {
  491. return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
  492. }
  493. // --------------------------------------------------------------------
  494. /**
  495. * Update statement
  496. *
  497. * Generates a platform-specific update string from the supplied data
  498. *
  499. * @access public
  500. * @param string the table name
  501. * @param array the update data
  502. * @param array the where clause
  503. * @param array the orderby clause
  504. * @param array the limit clause
  505. * @return string
  506. */
  507. function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
  508. {
  509. foreach ($values as $key => $val)
  510. {
  511. $valstr[] = $key." = ".$val;
  512. }
  513. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  514. $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
  515. $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
  516. $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
  517. $sql .= $orderby.$limit;
  518. return $sql;
  519. }
  520. // --------------------------------------------------------------------
  521. /**
  522. * Truncate statement
  523. *
  524. * Generates a platform-specific truncate string from the supplied data
  525. * If the database does not support the truncate() command
  526. * This function maps to "DELETE FROM table"
  527. *
  528. * @access public
  529. * @param string the table name
  530. * @return string
  531. */
  532. function _truncate($table)
  533. {
  534. return "TRUNCATE ".$table;
  535. }
  536. // --------------------------------------------------------------------
  537. /**
  538. * Delete statement
  539. *
  540. * Generates a platform-specific delete string from the supplied data
  541. *
  542. * @access public
  543. * @param string the table name
  544. * @param array the where clause
  545. * @param string the limit clause
  546. * @return string
  547. */
  548. function _delete($table, $where = array(), $like = array(), $limit = FALSE)
  549. {
  550. $conditions = '';
  551. if (count($where) > 0 OR count($like) > 0)
  552. {
  553. $conditions = "\nWHERE ";
  554. $conditions .= implode("\n", $this->ar_where);
  555. if (count($where) > 0 && count($like) > 0)
  556. {
  557. $conditions .= " AND ";
  558. }
  559. $conditions .= implode("\n", $like);
  560. }
  561. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  562. return "DELETE FROM ".$table.$conditions.$limit;
  563. }
  564. // --------------------------------------------------------------------
  565. /**
  566. * Limit string
  567. *
  568. * Generates a platform-specific LIMIT clause
  569. *
  570. * @access public
  571. * @param string the sql query string
  572. * @param integer the number of rows to limit the query to
  573. * @param integer the offset value
  574. * @return string
  575. */
  576. function _limit($sql, $limit, $offset)
  577. {
  578. $sql .= "LIMIT ".$limit;
  579. if ($offset > 0)
  580. {
  581. $sql .= " OFFSET ".$offset;
  582. }
  583. return $sql;
  584. }
  585. // --------------------------------------------------------------------
  586. /**
  587. * Close DB Connection
  588. *
  589. * @access public
  590. * @param resource
  591. * @return void
  592. */
  593. function _close($conn_id)
  594. {
  595. @pg_close($conn_id);
  596. }
  597. }
  598. /* End of file postgre_driver.php */
  599. /* Location: ./system/database/drivers/postgre/postgre_driver.php */