blob: 1d6e9567a84f9a728c7b847f08d86e8303262e0a [file] [log] [blame]
Andrey Andreev738497c2012-03-20 14:12:25 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev738497c2012-03-20 14:12:25 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev738497c2012-03-20 14:12:25 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * Postgre Database Adapter Class
30 *
31 * Note: _DB is an extender class that the app controller
Jamie Rumbelow7efad202012-02-19 12:37:00 +000032 * creates dynamically based on whether the query builder
Derek Allard2067d1a2008-11-13 22:59:24 +000033 * class is being used or not.
34 *
35 * @package CodeIgniter
36 * @subpackage Drivers
37 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000039 * @link http://codeigniter.com/user_guide/database/
40 */
41class CI_DB_postgre_driver extends CI_DB {
42
Andrey Andreev738497c2012-03-20 14:12:25 +020043 public $dbdriver = 'postgre';
Barry Mienydd671972010-10-04 16:33:58 +020044
Andrey Andreev738497c2012-03-20 14:12:25 +020045 protected $_escape_char = '"';
Derek Allard2067d1a2008-11-13 22:59:24 +000046
Andrey Andreev738497c2012-03-20 14:12:25 +020047 protected $_random_keyword = ' RANDOM()'; // database specific random keyword
Derek Allard2067d1a2008-11-13 22:59:24 +000048
49 /**
Andrey Andreev6192bc02012-03-26 12:32:32 +030050 * Constructor
Derek Allard2067d1a2008-11-13 22:59:24 +000051 *
Andrey Andreev6192bc02012-03-26 12:32:32 +030052 * Creates a DSN string to be used for db_connect() and db_pconnect()
53 *
54 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020055 */
Andrey Andreev6192bc02012-03-26 12:32:32 +030056 public function __construct($params)
Derek Allard2067d1a2008-11-13 22:59:24 +000057 {
Andrey Andreev6192bc02012-03-26 12:32:32 +030058 parent::__construct($params);
Barry Mienydd671972010-10-04 16:33:58 +020059
Andrey Andreev6192bc02012-03-26 12:32:32 +030060 if ( ! empty($this->dsn))
Derek Allard2067d1a2008-11-13 22:59:24 +000061 {
Andrey Andreev6192bc02012-03-26 12:32:32 +030062 return;
63 }
64
65 $this->dsn === '' OR $this->dsn = '';
66
67 if (strpos($this->hostname, '/') !== FALSE)
68 {
69 // If UNIX sockets are used, we shouldn't set a port
70 $this->port = '';
71 }
72
Andrey Andreevab1d5682012-04-03 20:48:32 +030073 $this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' ';
Andrey Andreev6192bc02012-03-26 12:32:32 +030074
75 if ( ! empty($this->port) && ctype_digit($this->port))
76 {
Andrey Andreevab1d5682012-04-03 20:48:32 +030077 $this->dsn .= 'port='.$this->port.' ';
Andrey Andreev6192bc02012-03-26 12:32:32 +030078 }
79
80 if ($this->username !== '')
81 {
Andrey Andreevab1d5682012-04-03 20:48:32 +030082 $this->dsn .= 'user='.$this->username.' ';
Andrey Andreev6192bc02012-03-26 12:32:32 +030083
84 /* An empty password is valid!
85 *
86 * $db['password'] = NULL must be done in order to ignore it.
87 */
88 $this->password === NULL OR $this->dsn .= "password='".$this->password."' ";
89 }
90
91 $this->database === '' OR $this->dsn .= 'dbname='.$this->database.' ';
92
93 /* We don't have these options as elements in our standard configuration
94 * array, but they might be set by parse_url() if the configuration was
95 * provided via string. Example:
96 *
97 * postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1
98 */
99 foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key)
100 {
101 if (isset($this->$key) && is_string($this->key) && $this->key !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000102 {
Andrey Andreev6192bc02012-03-26 12:32:32 +0300103 $this->dsn .= $key."='".$this->key."' ";
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 }
105 }
Andrey Andreev6192bc02012-03-26 12:32:32 +0300106
107 $this->dsn = rtrim($this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000108 }
109
110 // --------------------------------------------------------------------
111
112 /**
113 * Non-persistent database connection
114 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +0200116 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200117 public function db_connect()
Barry Mienydd671972010-10-04 16:33:58 +0200118 {
Andrey Andreev6192bc02012-03-26 12:32:32 +0300119 return @pg_connect($this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000120 }
121
122 // --------------------------------------------------------------------
123
124 /**
125 * Persistent database connection
126 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000127 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +0200128 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200129 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000130 {
rwillert82408522012-07-10 14:02:01 +0300131 $conn = @pg_pconnect($this->dsn);
132 if ($conn && pg_connection_status($conn) === PGSQL_CONNECTION_BAD)
133 {
134 if (pg_ping($conn) === FALSE)
135 {
136 return FALSE;
137 }
138 }
139 return $conn;
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 }
Barry Mienydd671972010-10-04 16:33:58 +0200141
Derek Allard2067d1a2008-11-13 22:59:24 +0000142 // --------------------------------------------------------------------
143
144 /**
Derek Jones87cbafc2009-02-27 16:29:59 +0000145 * Reconnect
146 *
147 * Keep / reestablish the db connection if no queries have been
148 * sent for a length of time exceeding the server's idle timeout
149 *
Derek Jones87cbafc2009-02-27 16:29:59 +0000150 * @return void
151 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200152 public function reconnect()
Derek Jones87cbafc2009-02-27 16:29:59 +0000153 {
154 if (pg_ping($this->conn_id) === FALSE)
155 {
156 $this->conn_id = FALSE;
157 }
158 }
159
160 // --------------------------------------------------------------------
161
162 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 * Set client character set
164 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 * @param string
Andrey Andreev214583f2012-01-26 16:39:09 +0200166 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 */
Andrey Andreev8e89df82012-03-03 03:48:12 +0200168 protected function _db_set_charset($charset)
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 {
Andrey Andreev8e89df82012-03-03 03:48:12 +0200170 return (pg_set_client_encoding($this->conn_id, $charset) === 0);
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 }
172
173 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200174
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200176 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 * @return string
179 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200180 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200182 if (isset($this->data_cache['version']))
183 {
184 return $this->data_cache['version'];
185 }
186
187 if (($pg_version = pg_version($this->conn_id)) === FALSE)
188 {
189 return FALSE;
190 }
191
192 /* If PHP was compiled with PostgreSQL lib versions earlier
193 * than 7.4, pg_version() won't return the server version
194 * and so we'll have to fall back to running a query in
195 * order to get it.
196 */
197 return isset($pg_version['server'])
198 ? $this->data_cache['version'] = $pg_version['server']
199 : parent::version();
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 }
201
202 // --------------------------------------------------------------------
203
204 /**
205 * Execute the query
206 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000207 * @param string an SQL query
208 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +0200209 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200210 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000211 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 return @pg_query($this->conn_id, $sql);
213 }
Barry Mienydd671972010-10-04 16:33:58 +0200214
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 // --------------------------------------------------------------------
216
217 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 * Begin Transaction
219 *
Andrey Andreev214583f2012-01-26 16:39:09 +0200220 * @param bool
Barry Mienydd671972010-10-04 16:33:58 +0200221 * @return bool
222 */
Andrey Andreeva19beb02012-03-03 04:20:50 +0200223 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeva19beb02012-03-03 04:20:50 +0200226 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 {
228 return TRUE;
229 }
230
231 // Reset the transaction failure flag.
232 // If the $test_mode flag is set to TRUE transactions will be rolled back
233 // even if the queries produce a successful result.
Andrey Andreeva19beb02012-03-03 04:20:50 +0200234 $this->_trans_failure = ($test_mode === TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000235
Andrey Andreev214583f2012-01-26 16:39:09 +0200236 return (bool) @pg_query($this->conn_id, 'BEGIN');
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 }
238
239 // --------------------------------------------------------------------
240
241 /**
242 * Commit Transaction
243 *
Barry Mienydd671972010-10-04 16:33:58 +0200244 * @return bool
245 */
Andrey Andreeva19beb02012-03-03 04:20:50 +0200246 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeva19beb02012-03-03 04:20:50 +0200249 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 {
251 return TRUE;
252 }
253
Andrey Andreev214583f2012-01-26 16:39:09 +0200254 return (bool) @pg_query($this->conn_id, 'COMMIT');
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 }
256
257 // --------------------------------------------------------------------
258
259 /**
260 * Rollback Transaction
261 *
Barry Mienydd671972010-10-04 16:33:58 +0200262 * @return bool
263 */
Andrey Andreeva19beb02012-03-03 04:20:50 +0200264 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeva19beb02012-03-03 04:20:50 +0200267 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 {
269 return TRUE;
270 }
271
Andrey Andreev214583f2012-01-26 16:39:09 +0200272 return (bool) @pg_query($this->conn_id, 'ROLLBACK');
Derek Allard2067d1a2008-11-13 22:59:24 +0000273 }
274
275 // --------------------------------------------------------------------
276
277 /**
278 * Escape String
279 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000281 * @param bool whether or not the string will be used in a LIKE condition
Derek Allard2067d1a2008-11-13 22:59:24 +0000282 * @return string
283 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200284 public function escape_str($str, $like = FALSE)
Derek Jonese4ed5832009-02-20 21:44:59 +0000285 {
286 if (is_array($str))
287 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500288 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200289 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000290 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200291 }
292
293 return $str;
294 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000295
296 $str = pg_escape_string($str);
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Jonese4ed5832009-02-20 21:44:59 +0000298 // escape LIKE condition wildcards
299 if ($like === TRUE)
300 {
Andrey Andreev55201ac2012-03-20 14:20:39 +0200301 return str_replace(array($this->_like_escape_chr, '%', '_'),
302 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
303 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000304 }
Barry Mienydd671972010-10-04 16:33:58 +0200305
Derek Jonese4ed5832009-02-20 21:44:59 +0000306 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 }
Barry Mienydd671972010-10-04 16:33:58 +0200308
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 // --------------------------------------------------------------------
310
311 /**
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700312 * "Smart" Escape String
313 *
314 * Escapes data based on type
315 * Sets boolean and null types
316 *
317 * @param string
318 * @return mixed
319 */
320 public function escape($str)
321 {
Soesapto Joeni Hantorodabeaa12012-05-15 16:37:46 +0700322 if (is_bool($str))
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700323 {
Soesapto Joeni Hantorod2574db2012-05-15 16:28:16 +0700324 return ($str) ? 'TRUE' : 'FALSE';
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700325 }
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700326
Soesapto Joeni Hantorodabeaa12012-05-15 16:37:46 +0700327 return parent::escape($str);
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700328 }
Andrey Andreev242925b2012-05-15 13:03:51 +0300329
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700330 // --------------------------------------------------------------------
331
332 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 * Affected Rows
334 *
Andrey Andreev738497c2012-03-20 14:12:25 +0200335 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200337 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 {
339 return @pg_affected_rows($this->result_id);
340 }
Barry Mienydd671972010-10-04 16:33:58 +0200341
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 // --------------------------------------------------------------------
343
344 /**
345 * Insert ID
346 *
Andrey Andreev738497c2012-03-20 14:12:25 +0200347 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200349 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 {
Andrey Andreev214583f2012-01-26 16:39:09 +0200351 $v = pg_version($this->conn_id);
352 $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4
Barry Mienydd671972010-10-04 16:33:58 +0200353
Andrey Andreev214583f2012-01-26 16:39:09 +0200354 $table = (func_num_args() > 0) ? func_get_arg(0) : NULL;
355 $column = (func_num_args() > 1) ? func_get_arg(1) : NULL;
Barry Mienydd671972010-10-04 16:33:58 +0200356
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100357 if ($table === NULL && $v >= '8.1')
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 {
Andrey Andreev214583f2012-01-26 16:39:09 +0200359 $sql = 'SELECT LASTVAL() AS ins_id';
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 }
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100361 elseif ($table !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000362 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100363 if ($column !== NULL && $v >= '8.0')
Andrey Andreev214583f2012-01-26 16:39:09 +0200364 {
365 $sql = 'SELECT pg_get_serial_sequence(\''.$table."', '".$column."') AS seq";
366 $query = $this->query($sql);
367 $query = $query->row();
368 $seq = $query->seq;
369 }
370 else
371 {
372 // seq_name passed in table parameter
373 $seq = $table;
374 }
375
376 $sql = 'SELECT CURRVAL(\''.$seq."') AS ins_id";
Derek Allard2067d1a2008-11-13 22:59:24 +0000377 }
378 else
379 {
380 return pg_last_oid($this->result_id);
381 }
Andrey Andreev214583f2012-01-26 16:39:09 +0200382
Derek Allard2067d1a2008-11-13 22:59:24 +0000383 $query = $this->query($sql);
Andrey Andreev214583f2012-01-26 16:39:09 +0200384 $query = $query->row();
385 return (int) $query->ins_id;
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 }
387
388 // --------------------------------------------------------------------
389
390 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000391 * Show table query
392 *
393 * Generates a platform-specific query string so that the table names can be fetched
394 *
Andrey Andreev738497c2012-03-20 14:12:25 +0200395 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000396 * @return string
397 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200398 protected function _list_tables($prefix_limit = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200399 {
Andrey Andreev58803fb2012-06-24 00:45:37 +0300400 $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \'public\'';
Barry Mienydd671972010-10-04 16:33:58 +0200401
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100402 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 {
Andrey Andreev58803fb2012-06-24 00:45:37 +0300404 return $sql.' AND "table_name" LIKE \''
405 .$this->escape_like_str($this->dbprefix)."%' "
406 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000407 }
Barry Mienydd671972010-10-04 16:33:58 +0200408
Derek Allard2067d1a2008-11-13 22:59:24 +0000409 return $sql;
410 }
Barry Mienydd671972010-10-04 16:33:58 +0200411
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 // --------------------------------------------------------------------
413
414 /**
415 * Show column query
416 *
417 * Generates a platform-specific query string so that the column names can be fetched
418 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 * @param string the table name
420 * @return string
421 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200422 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000423 {
Andrey Andreev58803fb2012-06-24 00:45:37 +0300424 return 'SELECT "column_name" FROM "information_schema"."columns" WHERE "table_name" = '.$this->escape($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000425 }
426
427 // --------------------------------------------------------------------
428
429 /**
430 * Field data query
431 *
432 * Generates a platform-specific query so that the column data can be retrieved
433 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 * @param string the table name
Andrey Andreev214583f2012-01-26 16:39:09 +0200435 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000436 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200437 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 {
Andrey Andreev214583f2012-01-26 16:39:09 +0200439 return 'SELECT * FROM '.$table.' LIMIT 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 }
441
442 // --------------------------------------------------------------------
443
444 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200445 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200447 * Returns an array containing code and message of the last
448 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200450 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200452 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000453 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200454 return array('code' => '', 'message' => pg_last_error($this->conn_id));
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 }
456
457 // --------------------------------------------------------------------
458
459 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 * From Tables
461 *
462 * This function implicitly groups FROM tables so there is no confusion
463 * about operator precedence in harmony with SQL standards
464 *
Andrey Andreev738497c2012-03-20 14:12:25 +0200465 * @param array
466 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200468 protected function _from_tables($tables)
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 {
Andrey Andreevc78e56a2012-06-08 02:12:07 +0300470 return is_array($tables) ? implode(', ', $tables) : $tables;
Derek Allard2067d1a2008-11-13 22:59:24 +0000471 }
472
473 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200474
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 * Update statement
477 *
478 * Generates a platform-specific update string from the supplied data
479 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 * @param string the table name
481 * @param array the update data
482 * @param array the where clause
Andrey Andreev00541ae2012-04-09 11:43:10 +0300483 * @param array the orderby clause (ignored)
484 * @param array the limit clause (ignored)
485 * @param array the like clause
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 * @return string
487 */
Andrey Andreev00541ae2012-04-09 11:43:10 +0300488 protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000489 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500490 foreach ($values as $key => $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 {
Andrey Andreev00541ae2012-04-09 11:43:10 +0300492 $valstr[] = $key.' = '.$val;
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 }
Barry Mienydd671972010-10-04 16:33:58 +0200494
Andrey Andreev00541ae2012-04-09 11:43:10 +0300495 $where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
Derek Allard2067d1a2008-11-13 22:59:24 +0000496
Andrey Andreev00541ae2012-04-09 11:43:10 +0300497 if ( ! empty($like))
498 {
499 $where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
500 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000501
Andrey Andreev00541ae2012-04-09 11:43:10 +0300502 return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
Derek Allard2067d1a2008-11-13 22:59:24 +0000503 }
Barry Mienydd671972010-10-04 16:33:58 +0200504
Derek Allard2067d1a2008-11-13 22:59:24 +0000505 // --------------------------------------------------------------------
506
507 /**
Andrey Andreevd06acd82012-05-25 00:29:09 +0300508 * Update_Batch statement
509 *
510 * Generates a platform-specific batch update string from the supplied data
511 *
512 * @param string the table name
513 * @param array the update data
514 * @param array the where clause
515 * @return string
516 */
517 protected function _update_batch($table, $values, $index, $where = NULL)
518 {
519 $ids = array();
520 foreach ($values as $key => $val)
521 {
522 $ids[] = $val[$index];
523
524 foreach (array_keys($val) as $field)
525 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100526 if ($field !== $index)
Andrey Andreevd06acd82012-05-25 00:29:09 +0300527 {
528 $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field];
529 }
530 }
531 }
532
533 $cases = '';
534 foreach ($final as $k => $v)
535 {
aroche7f875b72012-07-16 18:22:08 +0300536 $cases .= $k.' = (CASE '.$index."\n"
Andrey Andreevd06acd82012-05-25 00:29:09 +0300537 .implode("\n", $v)."\n"
538 .'ELSE '.$k.' END), ';
539 }
540
541 return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100542 .' WHERE '.(($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
Andrey Andreevd06acd82012-05-25 00:29:09 +0300543 .$index.' IN('.implode(',', $ids).')';
544 }
545
546 // --------------------------------------------------------------------
547
548 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 * Delete statement
550 *
551 * Generates a platform-specific delete string from the supplied data
552 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 * @param string the table name
554 * @param array the where clause
Andrey Andreevc01d3162012-04-09 12:55:11 +0300555 * @param array the like clause
Andrey Andreeva2548362012-04-09 13:03:11 +0300556 * @param string the limit clause (ignored)
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200558 */
Andrey Andreeva2548362012-04-09 13:03:11 +0300559 protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000560 {
Andrey Andreevc01d3162012-04-09 12:55:11 +0300561 $conditions = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000562
Andrey Andreevc01d3162012-04-09 12:55:11 +0300563 empty($where) OR $conditions[] = implode(' ', $where);
564 empty($like) OR $conditions[] = implode(' ', $like);
Derek Allard2067d1a2008-11-13 22:59:24 +0000565
Andrey Andreevc01d3162012-04-09 12:55:11 +0300566 return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 }
568
569 // --------------------------------------------------------------------
Andrey Andreev82e88b92012-04-06 21:18:59 +0300570
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 /**
572 * Limit string
573 *
574 * Generates a platform-specific LIMIT clause
575 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000576 * @param string the sql query string
Andrey Andreev738497c2012-03-20 14:12:25 +0200577 * @param int the number of rows to limit the query to
578 * @param int the offset value
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 * @return string
580 */
Andrey Andreev738497c2012-03-20 14:12:25 +0200581 protected function _limit($sql, $limit, $offset)
Barry Mienydd671972010-10-04 16:33:58 +0200582 {
Andrey Andreev2c35b642012-06-24 03:05:26 +0300583 return $sql.' LIMIT '.$limit.($offset ? ' OFFSET '.$offset : '');
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 }
585
586 // --------------------------------------------------------------------
587
588 /**
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700589 * Where
590 *
591 * Called by where() or or_where()
592 *
593 * @param mixed
594 * @param mixed
595 * @param string
Andrey Andreev58803fb2012-06-24 00:45:37 +0300596 * @param mixed
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700597 * @return object
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700598 */
599 protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
600 {
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700601 if ( ! is_array($key))
602 {
603 $key = array($key => $value);
604 }
605
606 // If the escape value was not set will will base it on the global setting
Andrey Andreev498c1e02012-06-16 03:34:10 +0300607 is_bool($escape) OR $escape = $this->_protect_identifiers;
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700608
609 foreach ($key as $k => $v)
610 {
Andrey Andreev58803fb2012-06-24 00:45:37 +0300611 $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0)
612 ? $this->_group_get_type('')
613 : $this->_group_get_type($type);
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700614
Andrey Andreev35443c62012-06-25 15:34:30 +0300615 if ($escape === TRUE)
616 {
617 $k = (($op = $this->_get_operator($k)) !== FALSE)
Andrey Andreev40f14042012-06-25 17:54:22 +0300618 ? $this->escape_identifiers(trim(substr($k, 0, strpos($k, $op)))).' '.strstr($k, $op)
619 : $this->escape_identifiers(trim($k));
Andrey Andreev35443c62012-06-25 15:34:30 +0300620 }
Andrey Andreev9c14f652012-06-10 14:35:07 +0300621
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700622 if (is_null($v) && ! $this->_has_operator($k))
623 {
624 // value appears not to have been set, assign the test to IS NULL
625 $k .= ' IS NULL';
626 }
627
628 if ( ! is_null($v))
629 {
630 if ($escape === TRUE)
631 {
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700632 $v = ' '.$this->escape($v);
633 }
Soesapto Joeni Hantorod2574db2012-05-15 16:28:16 +0700634 elseif (is_bool($v))
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700635 {
Andrey Andreev242925b2012-05-15 13:03:51 +0300636 $v = ($v ? ' TRUE' : ' FALSE');
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700637 }
638
639 if ( ! $this->_has_operator($k))
640 {
641 $k .= ' = ';
642 }
643 }
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700644
645 $this->qb_where[] = $prefix.$k.$v;
646 if ($this->qb_caching === TRUE)
647 {
648 $this->qb_cache_where[] = $prefix.$k.$v;
649 $this->qb_cache_exists[] = 'where';
650 }
651
652 }
653
654 return $this;
655 }
Andrey Andreev242925b2012-05-15 13:03:51 +0300656
Soesapto Joeni Hantorof25b9292012-05-15 08:10:31 +0700657 // --------------------------------------------------------------------
658
659 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000660 * Close DB Connection
661 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000662 * @return void
663 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300664 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000665 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300666 @pg_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 }
668
Derek Allard2067d1a2008-11-13 22:59:24 +0000669}
670
Derek Allard2067d1a2008-11-13 22:59:24 +0000671/* End of file postgre_driver.php */
Andrey Andreev242925b2012-05-15 13:03:51 +0300672/* Location: ./system/database/drivers/postgre/postgre_driver.php */