blob: f57e042c523087bb881ccd47aff32415b9a85277 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev24abcb92012-01-05 20:40:15 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreev24abcb92012-01-05 20:40:15 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 1.4.1
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * oci8 Database Adapter Class
42 *
43 * Note: _DB is an extender class that the app controller
Jamie Rumbelow7efad202012-02-19 12:37:00 +000044 * creates dynamically based on whether the query builder
Derek Allard2067d1a2008-11-13 22:59:24 +000045 * class is being used or not.
46 *
Barry Mienydd671972010-10-04 16:33:58 +020047 * @package CodeIgniter
Derek Jones4b9c6292011-07-01 17:40:48 -050048 * @subpackage Drivers
Derek Allard2067d1a2008-11-13 22:59:24 +000049 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050050 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000051 * @link http://codeigniter.com/user_guide/database/
52 */
53
54/**
55 * oci8 Database Adapter Class
56 *
57 * This is a modification of the DB_driver class to
58 * permit access to oracle databases
59 *
Derek Jones4b9c6292011-07-01 17:40:48 -050060 * @author Kelly McArdle
Derek Allard2067d1a2008-11-13 22:59:24 +000061 */
Derek Allard2067d1a2008-11-13 22:59:24 +000062class CI_DB_oci8_driver extends CI_DB {
63
Andrey Andreeva24e52e2012-11-02 03:54:12 +020064 /**
65 * Database driver
66 *
67 * @var string
68 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020069 public $dbdriver = 'oci8';
Barry Mienydd671972010-10-04 16:33:58 +020070
Andrey Andreeva24e52e2012-11-02 03:54:12 +020071 /**
72 * Statement ID
73 *
74 * @var resource
75 */
76 public $stmt_id;
Barry Mienydd671972010-10-04 16:33:58 +020077
Derek Allard2067d1a2008-11-13 22:59:24 +000078 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +020079 * Cursor ID
80 *
81 * @var resource
Derek Allard2067d1a2008-11-13 22:59:24 +000082 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020083 public $curs_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000084
Andrey Andreeva24e52e2012-11-02 03:54:12 +020085 /**
86 * Commit mode flag
87 *
88 * @var int
89 */
90 public $commit_mode = OCI_COMMIT_ON_SUCCESS;
Derek Allard2067d1a2008-11-13 22:59:24 +000091
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030092 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +020093 * Limit used flag
94 *
95 * If we use LIMIT, we'll add a field that will
96 * throw off num_fields later.
97 *
98 * @var bool
99 */
100 public $limit_used;
101
102 // --------------------------------------------------------------------
103
104 /**
105 * List of reserved identifiers
106 *
107 * Identifiers that must NOT be escaped.
108 *
109 * @var string[]
110 */
111 protected $_reserved_identifiers = array('*', 'rownum');
112
113 /**
114 * ORDER BY random keyword
115 *
Andrey Andreev98e46cf2012-11-13 03:01:42 +0200116 * @var array
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200117 */
Andrey Andreev98e46cf2012-11-13 03:01:42 +0200118 protected $_random_keyword = array('ASC', 'ASC'); // not currently supported
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200119
120 /**
121 * COUNT string
122 *
123 * @used-by CI_DB_driver::count_all()
124 * @used-by CI_DB_query_builder::count_all_results()
125 *
126 * @var string
127 */
128 protected $_count_string = 'SELECT COUNT(1) AS ';
129
130 // --------------------------------------------------------------------
131
132 /**
133 * Class constructor
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300134 *
135 * @param array $params
136 * @return void
137 */
Andrey Andreevdad61c22012-02-13 01:08:06 +0200138 public function __construct($params)
139 {
140 parent::__construct($params);
141
142 $valid_dsns = array(
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200143 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
144 // Easy Connect string (Oracle 10g+)
145 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
146 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
147 );
Andrey Andreevdad61c22012-02-13 01:08:06 +0200148
149 /* Space characters don't have any effect when actually
150 * connecting, but can be a hassle while validating the DSN.
151 */
152 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
153
154 if ($this->dsn !== '')
155 {
156 foreach ($valid_dsns as $regexp)
157 {
158 if (preg_match($regexp, $this->dsn))
159 {
160 return;
161 }
162 }
163 }
164
165 // Legacy support for TNS in the hostname configuration field
166 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
167 if (preg_match($valid_dsns['tns'], $this->hostname))
168 {
169 $this->dsn = $this->hostname;
170 return;
171 }
172 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
173 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
174 {
175 /* If the hostname field isn't empty, doesn't contain
176 * ':' and/or '/' and if port and/or database aren't
177 * empty, then the hostname field is most likely indeed
178 * just a hostname. Therefore we'll try and build an
179 * Easy Connect string from these 3 settings, assuming
180 * that the database field is a service name.
181 */
182 $this->dsn = $this->hostname
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200183 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
184 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
Andrey Andreevdad61c22012-02-13 01:08:06 +0200185
186 if (preg_match($valid_dsns['ec'], $this->dsn))
187 {
188 return;
189 }
190 }
191
192 /* At this point, we can only try and validate the hostname and
193 * database fields separately as DSNs.
194 */
195 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
196 {
197 $this->dsn = $this->hostname;
198 return;
199 }
200
201 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
202 foreach ($valid_dsns as $regexp)
203 {
204 if (preg_match($regexp, $this->database))
205 {
206 return;
207 }
208 }
209
210 /* Well - OK, an empty string should work as well.
211 * PHP will try to use environment variables to
212 * determine which Oracle instance to connect to.
213 */
214 $this->dsn = '';
215 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000216
Andrey Andreevd5809992012-06-28 14:06:54 +0300217 // --------------------------------------------------------------------
218
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 /**
220 * Non-persistent database connection
221 *
Andrey Andreev2e171022014-02-25 15:21:41 +0200222 * @param bool $persistent
Andrey Andreevaa786c92012-01-16 12:14:45 +0200223 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 */
Andrey Andreev2e171022014-02-25 15:21:41 +0200225 public function db_connect($persistent = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 {
Andrey Andreev2e171022014-02-25 15:21:41 +0200227 $func = ($persistent === TRUE) ? 'oci_pconnect' : 'oci_connect';
Andrey Andreevd5809992012-06-28 14:06:54 +0300228 return empty($this->char_set)
Andrey Andreev2e171022014-02-25 15:21:41 +0200229 ? $func($this->username, $this->password, $this->dsn)
230 : $func($this->username, $this->password, $this->dsn, $this->char_set);
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 }
232
233 // --------------------------------------------------------------------
234
235 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200236 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200238 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000239 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200240 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000241 {
Andrey Andreev2b730372012-11-05 17:01:11 +0200242 if (isset($this->data_cache['version']))
243 {
244 return $this->data_cache['version'];
245 }
246 elseif ( ! $this->conn_id)
247 {
248 $this->initialize();
249 }
250
251 if ( ! $this->conn_id OR ($version = oci_server_version($this->conn_id)) === FALSE)
252 {
253 return FALSE;
254 }
255
256 return $this->data_cache['version'] = $version;
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 }
258
259 // --------------------------------------------------------------------
260
261 /**
262 * Execute the query
263 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200264 * @param string $sql an SQL query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200265 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300267 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200269 /* Oracle must parse the query before it is run. All of the actions with
270 * the query are based on the statement id returned by oci_parse().
271 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 $this->stmt_id = FALSE;
273 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300274 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300275 return oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 }
277
Andrey Andreevd5809992012-06-28 14:06:54 +0300278 // --------------------------------------------------------------------
279
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 /**
281 * Generate a statement ID
282 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200283 * @param string $sql an SQL query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200284 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000285 */
Andrey Andreevda123732012-03-20 22:27:40 +0200286 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 {
288 if ( ! is_resource($this->stmt_id))
289 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400290 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 }
292 }
293
294 // --------------------------------------------------------------------
295
296 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200297 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300299 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300301 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200303 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 }
305
306 // --------------------------------------------------------------------
307
308 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500309 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200311 * @param string package name in which the stored procedure is in
312 * @param string stored procedure name to execute
313 * @param array parameters
314 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 *
316 * params array keys
317 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500318 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200319 * name no the name of the parameter should be in :<param_name> format
320 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
321 * this should be a reference to a variable
322 * type yes the type of the parameter
323 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300325 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100327 if ($package === '' OR $procedure === '' OR ! is_array($params))
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 {
Andrey Andreeve18de502013-07-17 19:59:20 +0300329 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
330 return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000331 }
Barry Mienydd671972010-10-04 16:33:58 +0200332
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200334 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000335
336 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500337 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200339 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200340
Andrey Andreev85facfa2012-01-26 14:12:14 +0200341 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 $have_cursor = TRUE;
344 }
345 }
Andrey Andreev3ca060a2013-11-27 16:30:31 +0200346 $sql = trim($sql, ',').'); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200347
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 $this->stmt_id = FALSE;
349 $this->_set_stmt_id($sql);
350 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200351 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 }
Barry Mienydd671972010-10-04 16:33:58 +0200353
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 // --------------------------------------------------------------------
355
356 /**
357 * Bind parameters
358 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200359 * @param array $params
Andrey Andreevaa786c92012-01-16 12:14:45 +0200360 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200362 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000363 {
364 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
365 {
366 return;
367 }
Barry Mienydd671972010-10-04 16:33:58 +0200368
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 foreach ($params as $param)
370 {
Barry Mienydd671972010-10-04 16:33:58 +0200371 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 {
373 if ( ! isset($param[$val]))
374 {
375 $param[$val] = '';
376 }
377 }
378
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300379 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000380 }
381 }
382
383 // --------------------------------------------------------------------
384
385 /**
386 * Begin Transaction
387 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200388 * @param bool $test_mode
Barry Mienydd671972010-10-04 16:33:58 +0200389 * @return bool
390 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300391 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 {
393 if ( ! $this->trans_enabled)
394 {
395 return TRUE;
396 }
Barry Mienydd671972010-10-04 16:33:58 +0200397
Derek Allard2067d1a2008-11-13 22:59:24 +0000398 // When transactions are nested we only begin/commit/rollback the outermost ones
399 if ($this->_trans_depth > 0)
400 {
401 return TRUE;
402 }
Barry Mienydd671972010-10-04 16:33:58 +0200403
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 // Reset the transaction failure flag.
405 // If the $test_mode flag is set to TRUE transactions will be rolled back
406 // even if the queries produce a successful result.
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200407 $this->_trans_failure = ($test_mode === TRUE);
Barry Mienydd671972010-10-04 16:33:58 +0200408
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200409 $this->commit_mode = is_php('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 return TRUE;
411 }
412
413 // --------------------------------------------------------------------
414
415 /**
416 * Commit Transaction
417 *
Barry Mienydd671972010-10-04 16:33:58 +0200418 * @return bool
419 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300420 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000421 {
422 if ( ! $this->trans_enabled)
423 {
424 return TRUE;
425 }
426
427 // When transactions are nested we only begin/commit/rollback the outermost ones
428 if ($this->_trans_depth > 0)
429 {
430 return TRUE;
431 }
432
Andrey Andreev99013ed2012-03-05 16:17:32 +0200433 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200434 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000435 }
436
437 // --------------------------------------------------------------------
438
439 /**
440 * Rollback Transaction
441 *
Barry Mienydd671972010-10-04 16:33:58 +0200442 * @return bool
443 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300444 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000445 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200447 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 {
449 return TRUE;
450 }
451
Andrey Andreev99013ed2012-03-05 16:17:32 +0200452 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200453 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 }
455
456 // --------------------------------------------------------------------
457
458 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000459 * Affected Rows
460 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200461 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000462 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300463 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 {
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300465 return oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 }
467
468 // --------------------------------------------------------------------
469
470 /**
471 * Insert ID
472 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200473 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300475 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 {
477 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000478 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 }
480
481 // --------------------------------------------------------------------
482
483 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 * Show table query
485 *
486 * Generates a platform-specific query string so that the table names can be fetched
487 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200488 * @param bool $prefix_limit
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300489 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300491 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300493 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000494
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100495 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000496 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300497 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
498 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 }
Barry Mienydd671972010-10-04 16:33:58 +0200500
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 return $sql;
502 }
503
504 // --------------------------------------------------------------------
505
506 /**
507 * Show column query
508 *
509 * Generates a platform-specific query string so that the column names can be fetched
510 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200511 * @param string $table
Andrey Andreevaa786c92012-01-16 12:14:45 +0200512 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000513 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300514 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000515 {
Andrey Andreeve1580572012-11-16 16:17:54 +0200516 if (strpos($table, '.') !== FALSE)
517 {
518 sscanf($table, '%[^.].%s', $owner, $table);
519 }
520 else
521 {
522 $owner = $this->username;
523 }
524
525 return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS
526 WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).'
527 AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table));
Derek Allard2067d1a2008-11-13 22:59:24 +0000528 }
529
530 // --------------------------------------------------------------------
531
532 /**
Andrey Andreeve1580572012-11-16 16:17:54 +0200533 * Returns an object with field data
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200535 * @param string $table
Andrey Andreeve1580572012-11-16 16:17:54 +0200536 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 */
Andrey Andreev5350f052015-01-12 12:33:37 +0200538 public function field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000539 {
Andrey Andreev5350f052015-01-12 12:33:37 +0200540 if (strpos($table, '.') !== FALSE)
Andrey Andreeve1580572012-11-16 16:17:54 +0200541 {
542 sscanf($table, '%[^.].%s', $owner, $table);
543 }
544 else
545 {
546 $owner = $this->username;
547 }
548
549 $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE
550 FROM ALL_TAB_COLUMNS
551 WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).'
552 AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table));
553
554 if (($query = $this->query($sql)) === FALSE)
555 {
556 return FALSE;
557 }
558 $query = $query->result_object();
559
560 $retval = array();
561 for ($i = 0, $c = count($query); $i < $c; $i++)
562 {
563 $retval[$i] = new stdClass();
564 $retval[$i]->name = $query[$i]->COLUMN_NAME;
565 $retval[$i]->type = $query[$i]->DATA_TYPE;
566
567 $length = ($query[$i]->CHAR_LENGTH > 0)
568 ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION;
569 if ($length === NULL)
570 {
571 $length = $query[$i]->DATA_LENGTH;
572 }
573 $retval[$i]->max_length = $length;
574
575 $default = $query[$i]->DATA_DEFAULT;
576 if ($default === NULL && $query[$i]->NULLABLE === 'N')
577 {
578 $default = '';
579 }
580 $retval[$i]->default = $query[$i]->COLUMN_DEFAULT;
581 }
582
583 return $retval;
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 }
585
586 // --------------------------------------------------------------------
587
588 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200589 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200591 * Returns an array containing code and message of the last
592 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200594 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000595 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200596 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000597 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200598 /* oci_error() returns an array that already contains the
599 * 'code' and 'message' keys, so we can just return it.
600 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200601 if (is_resource($this->curs_id))
602 {
603 return oci_error($this->curs_id);
604 }
605 elseif (is_resource($this->stmt_id))
606 {
607 return oci_error($this->stmt_id);
608 }
609 elseif (is_resource($this->conn_id))
610 {
611 return oci_error($this->conn_id);
612 }
613
614 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000615 }
Barry Mienydd671972010-10-04 16:33:58 +0200616
Derek Allard2067d1a2008-11-13 22:59:24 +0000617 // --------------------------------------------------------------------
618
619 /**
Andrey Andreev083e3c82012-11-06 12:48:32 +0200620 * Insert batch statement
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300621 *
622 * Generates a platform-specific insert string from the supplied data
623 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200624 * @param string $table Table name
625 * @param array $keys INSERT keys
626 * @param array $values INSERT values
Andrey Andreevda123732012-03-20 22:27:40 +0200627 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300628 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300629 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300630 {
631 $keys = implode(', ', $keys);
632 $sql = "INSERT ALL\n";
633
634 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300635 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300636 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300637 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300638
Andrey Andreevaa786c92012-01-16 12:14:45 +0200639 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 }
641
642 // --------------------------------------------------------------------
643
644 /**
645 * Truncate statement
646 *
647 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000648 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200649 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300650 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200652 * @param string $table
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200654 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300655 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000656 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200657 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000658 }
Barry Mienydd671972010-10-04 16:33:58 +0200659
Derek Allard2067d1a2008-11-13 22:59:24 +0000660 // --------------------------------------------------------------------
661
662 /**
663 * Delete statement
664 *
665 * Generates a platform-specific delete string from the supplied data
666 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200667 * @param string $table
Derek Allard2067d1a2008-11-13 22:59:24 +0000668 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200669 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300670 protected function _delete($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000671 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300672 if ($this->qb_limit)
673 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300674 $this->where('rownum <= ',$this->qb_limit, FALSE);
Andrey Andreevb0478652012-07-18 15:34:46 +0300675 $this->qb_limit = FALSE;
676 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000677
Andrey Andreevb0478652012-07-18 15:34:46 +0300678 return parent::_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 }
680
681 // --------------------------------------------------------------------
682
683 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200684 * LIMIT
Derek Allard2067d1a2008-11-13 22:59:24 +0000685 *
686 * Generates a platform-specific LIMIT clause
687 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200688 * @param string $sql SQL Query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200689 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000690 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300691 protected function _limit($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000692 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000693 $this->limit_used = TRUE;
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300694 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')'
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200695 .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1) : '');
Barry Mienydd671972010-10-04 16:33:58 +0200696 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000697
698 // --------------------------------------------------------------------
699
700 /**
701 * Close DB Connection
702 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200703 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000704 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300705 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000706 {
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300707 oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000708 }
709
Derek Allard2067d1a2008-11-13 22:59:24 +0000710}
711
Derek Allard2067d1a2008-11-13 22:59:24 +0000712/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300713/* Location: ./system/database/drivers/oci8/oci8_driver.php */