blob: e8201822d9d19edd2617f03532ae24bddce0b736 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Esen Sagynov2e087942011-08-09 23:35:01 -07002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Esen Sagynov2e087942011-08-09 23:35:01 -07006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev592f4ec2012-03-20 15:10:08 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev592f4ec2012-03-20 15:10:08 +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 *
Esen Sagynov2e087942011-08-09 23:35:01 -070019 * @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)
Esen Sagynov2e087942011-08-09 23:35:01 -070023 * @link http://codeigniter.com
Andrey Andreevcf631202012-02-16 11:36:28 +020024 * @since Version 2.1
Esen Sagynov2e087942011-08-09 23:35:01 -070025 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Esen Sagynov2e087942011-08-09 23:35:01 -070028
Esen Sagynov2e087942011-08-09 23:35:01 -070029/**
30 * CUBRID Database Adapter Class
31 *
32 * Note: _DB is an extender class that the app controller
Jamie Rumbelow7efad202012-02-19 12:37:00 +000033 * creates dynamically based on whether the query builder
Esen Sagynov2e087942011-08-09 23:35:01 -070034 * class is being used or not.
35 *
36 * @package CodeIgniter
37 * @subpackage Drivers
38 * @category Database
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070039 * @author Esen Sagynov
Esen Sagynov2e087942011-08-09 23:35:01 -070040 * @link http://codeigniter.com/user_guide/database/
41 */
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070042class CI_DB_cubrid_driver extends CI_DB {
43
Andrey Andreev592f4ec2012-03-20 15:10:08 +020044 public $dbdriver = 'cubrid';
Esen Sagynov2e087942011-08-09 23:35:01 -070045
46 // The character used for escaping - no need in CUBRID
Andrey Andreev394a3f12012-02-15 14:35:11 +020047 protected $_escape_char = '`';
Esen Sagynov2e087942011-08-09 23:35:01 -070048
Andrey Andreev592f4ec2012-03-20 15:10:08 +020049 protected $_random_keyword = ' RAND()'; // database specific random keyword
Esen Sagynov2e087942011-08-09 23:35:01 -070050
Andrey Andreeva00e5042012-03-26 12:23:13 +030051 // CUBRID-specific properties
52 public $auto_commit = TRUE;
53
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030054 /**
55 * Constructor
56 *
57 * @param array $params
58 * @return void
59 */
Andrey Andreeva00e5042012-03-26 12:23:13 +030060 public function __construct($params)
61 {
62 parent::__construct($params);
63
64 if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches))
65 {
66 if (stripos($matches[2], 'autocommit=off') !== FALSE)
67 {
68 $this->auto_commit = FALSE;
69 }
70 }
71 else
72 {
73 // If no port is defined by the user, use the default value
Andrey Andreeve4c30192012-06-04 15:08:24 +030074 empty($this->port) OR $this->port = 33000;
Andrey Andreeva00e5042012-03-26 12:23:13 +030075 }
76 }
Esen Sagynov2e087942011-08-09 23:35:01 -070077
Andrey Andreev2ea33c32012-10-04 12:37:51 +030078 // --------------------------------------------------------------------
79
Esen Sagynov2e087942011-08-09 23:35:01 -070080 /**
81 * Non-persistent database connection
82 *
Esen Sagynov2e087942011-08-09 23:35:01 -070083 * @return resource
84 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +020085 public function db_connect()
Esen Sagynov2e087942011-08-09 23:35:01 -070086 {
Andrey Andreeva00e5042012-03-26 12:23:13 +030087 return $this->_cubrid_connect();
Esen Sagynov2e087942011-08-09 23:35:01 -070088 }
89
90 // --------------------------------------------------------------------
91
92 /**
93 * Persistent database connection
Andrey Andreev592f4ec2012-03-20 15:10:08 +020094 *
Esen Sagynov2e087942011-08-09 23:35:01 -070095 * In CUBRID persistent DB connection is supported natively in CUBRID
96 * engine which can be configured in the CUBRID Broker configuration
97 * file by setting the CCI_PCONNECT parameter to ON. In that case, all
98 * connections established between the client application and the
Andrey Andreeva00e5042012-03-26 12:23:13 +030099 * server will become persistent.
Esen Sagynov2e087942011-08-09 23:35:01 -0700100 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700101 * @return resource
102 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200103 public function db_pconnect()
Esen Sagynov2e087942011-08-09 23:35:01 -0700104 {
Andrey Andreeva00e5042012-03-26 12:23:13 +0300105 return $this->_cubrid_connect(TRUE);
106 }
107
108 // --------------------------------------------------------------------
109
110 /**
111 * CUBRID connection
112 *
113 * A CUBRID-specific method to create a connection to the database.
114 * Except for determining if a persistent connection should be used,
115 * the rest of the logic is the same for db_connect() and db_pconnect().
116 *
117 * @param bool
118 * @return resource
119 */
120 protected function _cubrid_connect($persistent = FALSE)
121 {
122 if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:([^:]*):([^:]*):(\?.+)?$/', $this->dsn, $matches))
123 {
124 $_temp = ($persistent !== TRUE) ? 'cubrid_connect_with_url' : 'cubrid_pconnect_with_url';
125 $conn_id = ($matches[2] === '' && $matches[3] === '' && $this->username !== '' && $this->password !== '')
126 ? $_temp($this->dsn, $this->username, $this->password)
127 : $_temp($this->dsn);
128 }
129 else
130 {
131 $_temp = ($persistent !== TRUE) ? 'cubrid_connect' : 'cubrid_pconnect';
132 $conn_id = ($this->username !== '')
133 ? $_temp($this->hostname, $this->port, $this->database, $this->username, $this->password)
134 : $_temp($this->hostname, $this->port, $this->database);
135 }
136
137 return $conn_id;
Esen Sagynov2e087942011-08-09 23:35:01 -0700138 }
139
140 // --------------------------------------------------------------------
141
142 /**
143 * Reconnect
144 *
145 * Keep / reestablish the db connection if no queries have been
146 * sent for a length of time exceeding the server's idle timeout
147 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700148 * @return void
149 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200150 public function reconnect()
Esen Sagynov2e087942011-08-09 23:35:01 -0700151 {
152 if (cubrid_ping($this->conn_id) === FALSE)
153 {
154 $this->conn_id = FALSE;
155 }
156 }
157
158 // --------------------------------------------------------------------
159
160 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200161 * Database version number
Esen Sagynov2e087942011-08-09 23:35:01 -0700162 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700163 * @return string
164 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200165 public function version()
Esen Sagynov2e087942011-08-09 23:35:01 -0700166 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200167 return isset($this->data_cache['version'])
168 ? $this->data_cache['version']
169 : $this->data_cache['version'] = cubrid_get_server_info($this->conn_id);
Esen Sagynov2e087942011-08-09 23:35:01 -0700170 }
171
172 // --------------------------------------------------------------------
173
174 /**
175 * Execute the query
176 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700177 * @param string an SQL query
178 * @return resource
179 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200180 protected function _execute($sql)
Esen Sagynov2e087942011-08-09 23:35:01 -0700181 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700182 return @cubrid_query($sql, $this->conn_id);
183 }
184
185 // --------------------------------------------------------------------
186
187 /**
Esen Sagynov2e087942011-08-09 23:35:01 -0700188 * Begin Transaction
189 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300190 * @param bool $test_mode = FALSE
Esen Sagynov2e087942011-08-09 23:35:01 -0700191 * @return bool
192 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200193 public function trans_begin($test_mode = FALSE)
Esen Sagynov2e087942011-08-09 23:35:01 -0700194 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700195 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev7f55d612012-01-26 13:44:28 +0200196 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Esen Sagynov2e087942011-08-09 23:35:01 -0700197 {
198 return TRUE;
199 }
200
201 // Reset the transaction failure flag.
202 // If the $test_mode flag is set to TRUE transactions will be rolled back
203 // even if the queries produce a successful result.
Andrey Andreev7f55d612012-01-26 13:44:28 +0200204 $this->_trans_failure = ($test_mode === TRUE);
Esen Sagynov2e087942011-08-09 23:35:01 -0700205
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700206 if (cubrid_get_autocommit($this->conn_id))
207 {
208 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
209 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700210
211 return TRUE;
212 }
213
214 // --------------------------------------------------------------------
215
216 /**
217 * Commit Transaction
218 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700219 * @return bool
220 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200221 public function trans_commit()
Esen Sagynov2e087942011-08-09 23:35:01 -0700222 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700223 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev7f55d612012-01-26 13:44:28 +0200224 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Esen Sagynov2e087942011-08-09 23:35:01 -0700225 {
226 return TRUE;
227 }
228
229 cubrid_commit($this->conn_id);
230
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700231 if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
232 {
233 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
234 }
235
Esen Sagynov2e087942011-08-09 23:35:01 -0700236 return TRUE;
237 }
238
239 // --------------------------------------------------------------------
240
241 /**
242 * Rollback Transaction
243 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700244 * @return bool
245 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200246 public function trans_rollback()
Esen Sagynov2e087942011-08-09 23:35:01 -0700247 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700248 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev7f55d612012-01-26 13:44:28 +0200249 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Esen Sagynov2e087942011-08-09 23:35:01 -0700250 {
251 return TRUE;
252 }
253
254 cubrid_rollback($this->conn_id);
255
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700256 if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
257 {
258 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
259 }
260
Esen Sagynov2e087942011-08-09 23:35:01 -0700261 return TRUE;
262 }
263
264 // --------------------------------------------------------------------
265
266 /**
267 * Escape String
268 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700269 * @param string
270 * @param bool whether or not the string will be used in a LIKE condition
271 * @return string
272 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200273 public function escape_str($str, $like = FALSE)
Esen Sagynov2e087942011-08-09 23:35:01 -0700274 {
275 if (is_array($str))
276 {
277 foreach ($str as $key => $val)
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700278 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700279 $str[$key] = $this->escape_str($val, $like);
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700280 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700281
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700282 return $str;
283 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700284
Andrey Andreev394a3f12012-02-15 14:35:11 +0200285 if (function_exists('cubrid_real_escape_string') &&
286 (is_resource($this->conn_id)
287 OR (get_resource_type($this->conn_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->conn_id)))))
Esen Sagynov2e087942011-08-09 23:35:01 -0700288 {
289 $str = cubrid_real_escape_string($str, $this->conn_id);
290 }
291 else
292 {
293 $str = addslashes($str);
294 }
295
296 // escape LIKE condition wildcards
297 if ($like === TRUE)
298 {
Andrey Andreev7f55d612012-01-26 13:44:28 +0200299 return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
Esen Sagynov2e087942011-08-09 23:35:01 -0700300 }
301
302 return $str;
303 }
304
305 // --------------------------------------------------------------------
306
307 /**
308 * Affected Rows
309 *
Andrey Andreevea3eec92012-03-01 19:16:23 +0200310 * @return int
Esen Sagynov2e087942011-08-09 23:35:01 -0700311 */
Andrey Andreevea3eec92012-03-01 19:16:23 +0200312 public function affected_rows()
Esen Sagynov2e087942011-08-09 23:35:01 -0700313 {
Andrey Andreevea3eec92012-03-01 19:16:23 +0200314 return @cubrid_affected_rows();
Esen Sagynov2e087942011-08-09 23:35:01 -0700315 }
316
317 // --------------------------------------------------------------------
318
319 /**
320 * Insert ID
321 *
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200322 * @return int
Esen Sagynov2e087942011-08-09 23:35:01 -0700323 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200324 public function insert_id()
Esen Sagynov2e087942011-08-09 23:35:01 -0700325 {
326 return @cubrid_insert_id($this->conn_id);
327 }
328
329 // --------------------------------------------------------------------
330
331 /**
Esen Sagynov2e087942011-08-09 23:35:01 -0700332 * List table query
333 *
334 * Generates a platform-specific query string so that the table names can be fetched
335 *
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200336 * @param bool
Esen Sagynov2e087942011-08-09 23:35:01 -0700337 * @return string
338 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200339 protected function _list_tables($prefix_limit = FALSE)
Esen Sagynov2e087942011-08-09 23:35:01 -0700340 {
Andrey Andreev7f55d612012-01-26 13:44:28 +0200341 $sql = 'SHOW TABLES';
Esen Sagynov2e087942011-08-09 23:35:01 -0700342
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100343 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Esen Sagynov2e087942011-08-09 23:35:01 -0700344 {
Andrey Andreev7f55d612012-01-26 13:44:28 +0200345 return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
Esen Sagynov2e087942011-08-09 23:35:01 -0700346 }
347
348 return $sql;
349 }
350
351 // --------------------------------------------------------------------
352
353 /**
354 * Show column query
355 *
356 * Generates a platform-specific query string so that the column names can be fetched
357 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700358 * @param string the table name
359 * @return string
360 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200361 protected function _list_columns($table = '')
Esen Sagynov2e087942011-08-09 23:35:01 -0700362 {
Andrey Andreev032e7ea2012-03-06 19:48:35 +0200363 return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
Esen Sagynov2e087942011-08-09 23:35:01 -0700364 }
365
366 // --------------------------------------------------------------------
367
368 /**
369 * Field data query
370 *
371 * Generates a platform-specific query so that the column data can be retrieved
372 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700373 * @param string the table name
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200374 * @return string
Esen Sagynov2e087942011-08-09 23:35:01 -0700375 */
Andrey Andreev592f4ec2012-03-20 15:10:08 +0200376 protected function _field_data($table)
Esen Sagynov2e087942011-08-09 23:35:01 -0700377 {
Andrey Andreev7f55d612012-01-26 13:44:28 +0200378 return 'SELECT * FROM '.$table.' LIMIT 1';
Esen Sagynov2e087942011-08-09 23:35:01 -0700379 }
380
381 // --------------------------------------------------------------------
382
383 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200384 * Error
Esen Sagynov2e087942011-08-09 23:35:01 -0700385 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200386 * Returns an array containing code and message of the last
387 * database error that has occured.
Esen Sagynov2e087942011-08-09 23:35:01 -0700388 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200389 * @return array
Esen Sagynov2e087942011-08-09 23:35:01 -0700390 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200391 public function error()
Esen Sagynov2e087942011-08-09 23:35:01 -0700392 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200393 return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id));
Esen Sagynov2e087942011-08-09 23:35:01 -0700394 }
395
Esen Sagynov2e087942011-08-09 23:35:01 -0700396 // --------------------------------------------------------------------
397
398 /**
Esen Sagynov2e087942011-08-09 23:35:01 -0700399 * Update_Batch statement
400 *
401 * Generates a platform-specific batch update string from the supplied data
402 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700403 * @param string the table name
404 * @param array the update data
Andrey Andreevb0478652012-07-18 15:34:46 +0300405 * @param string the where key
Esen Sagynov2e087942011-08-09 23:35:01 -0700406 * @return string
407 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300408 protected function _update_batch($table, $values, $index)
Esen Sagynov2e087942011-08-09 23:35:01 -0700409 {
410 $ids = array();
Esen Sagynov2e087942011-08-09 23:35:01 -0700411 foreach ($values as $key => $val)
412 {
413 $ids[] = $val[$index];
414
415 foreach (array_keys($val) as $field)
416 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100417 if ($field !== $index)
Esen Sagynov2e087942011-08-09 23:35:01 -0700418 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700419 $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
Esen Sagynov2e087942011-08-09 23:35:01 -0700420 }
421 }
422 }
423
Esen Sagynov2e087942011-08-09 23:35:01 -0700424 $cases = '';
Esen Sagynov2e087942011-08-09 23:35:01 -0700425 foreach ($final as $k => $v)
426 {
Andrey Andreev7f55d612012-01-26 13:44:28 +0200427 $cases .= $k." = CASE \n"
428 .implode("\n", $v)
429 .'ELSE '.$k.' END, ';
Esen Sagynov2e087942011-08-09 23:35:01 -0700430 }
431
Andrey Andreevb0478652012-07-18 15:34:46 +0300432 $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE);
433
Andrey Andreevd40459d2012-07-18 16:46:39 +0300434 return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where');
Esen Sagynov2e087942011-08-09 23:35:01 -0700435 }
436
437 // --------------------------------------------------------------------
Andrey Andreev79922c02012-05-23 12:27:17 +0300438
Esen Sagynov2e087942011-08-09 23:35:01 -0700439 /**
Andrey Andreev7eaa14f2012-10-09 11:34:01 +0300440 * FROM tables
441 *
442 * Groups tables in FROM clauses if needed, so there is no confusion
443 * about operator precedence.
444 *
445 * @return string
446 */
447 protected function _from_tables()
448 {
Andrey Andreevfce9abe2012-10-09 11:37:00 +0300449 if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
Andrey Andreev7eaa14f2012-10-09 11:34:01 +0300450 {
451 return '('.implode(', ', $this->qb_from).')';
452 }
453
454 return implode(', ', $this->qb_from);
455 }
456
457 // --------------------------------------------------------------------
458
459 /**
Esen Sagynov2e087942011-08-09 23:35:01 -0700460 * Close DB Connection
461 *
Esen Sagynov2e087942011-08-09 23:35:01 -0700462 * @return void
463 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300464 protected function _close()
Esen Sagynov2e087942011-08-09 23:35:01 -0700465 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300466 @cubrid_close($this->conn_id);
Esen Sagynov2e087942011-08-09 23:35:01 -0700467 }
468
469}
470
Esen Sagynov2e087942011-08-09 23:35:01 -0700471/* End of file cubrid_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300472/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */