blob: 316f17a5d5d155bae44bb5387da89110f6c93243 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
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 Andreev24abcb92012-01-05 20:40:15 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev24abcb92012-01-05 20:40:15 +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 *
Barry Mienydd671972010-10-04 16:33:58 +020019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, 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
Barry Mienydd671972010-10-04 16:33:58 +020024 * @since Version 1.0
Derek Allard2067d1a2008-11-13 22:59:24 +000025 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * oci8 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
Derek Allard2067d1a2008-11-13 22:59:24 +000034 * class is being used or not.
35 *
Barry Mienydd671972010-10-04 16:33:58 +020036 * @package CodeIgniter
Derek Jones4b9c6292011-07-01 17:40:48 -050037 * @subpackage Drivers
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050039 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000040 * @link http://codeigniter.com/user_guide/database/
41 */
42
43/**
44 * oci8 Database Adapter Class
45 *
46 * This is a modification of the DB_driver class to
47 * permit access to oracle databases
48 *
Derek Jones4b9c6292011-07-01 17:40:48 -050049 * @author Kelly McArdle
Derek Allard2067d1a2008-11-13 22:59:24 +000050 */
Derek Allard2067d1a2008-11-13 22:59:24 +000051class CI_DB_oci8_driver extends CI_DB {
52
Andrey Andreeva24e52e2012-11-02 03:54:12 +020053 /**
54 * Database driver
55 *
56 * @var string
57 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020058 public $dbdriver = 'oci8';
Barry Mienydd671972010-10-04 16:33:58 +020059
Andrey Andreeva24e52e2012-11-02 03:54:12 +020060 /**
61 * Statement ID
62 *
63 * @var resource
64 */
65 public $stmt_id;
Barry Mienydd671972010-10-04 16:33:58 +020066
Derek Allard2067d1a2008-11-13 22:59:24 +000067 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +020068 * Cursor ID
69 *
70 * @var resource
Derek Allard2067d1a2008-11-13 22:59:24 +000071 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020072 public $curs_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000073
Andrey Andreeva24e52e2012-11-02 03:54:12 +020074 /**
75 * Commit mode flag
76 *
77 * @var int
78 */
79 public $commit_mode = OCI_COMMIT_ON_SUCCESS;
Derek Allard2067d1a2008-11-13 22:59:24 +000080
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030081 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +020082 * Limit used flag
83 *
84 * If we use LIMIT, we'll add a field that will
85 * throw off num_fields later.
86 *
87 * @var bool
88 */
89 public $limit_used;
90
91 // --------------------------------------------------------------------
92
93 /**
94 * List of reserved identifiers
95 *
96 * Identifiers that must NOT be escaped.
97 *
98 * @var string[]
99 */
100 protected $_reserved_identifiers = array('*', 'rownum');
101
102 /**
103 * ORDER BY random keyword
104 *
Andrey Andreev98e46cf2012-11-13 03:01:42 +0200105 * @var array
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200106 */
Andrey Andreev98e46cf2012-11-13 03:01:42 +0200107 protected $_random_keyword = array('ASC', 'ASC'); // not currently supported
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200108
109 /**
110 * COUNT string
111 *
112 * @used-by CI_DB_driver::count_all()
113 * @used-by CI_DB_query_builder::count_all_results()
114 *
115 * @var string
116 */
117 protected $_count_string = 'SELECT COUNT(1) AS ';
118
119 // --------------------------------------------------------------------
120
121 /**
122 * Class constructor
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300123 *
124 * @param array $params
125 * @return void
126 */
Andrey Andreevdad61c22012-02-13 01:08:06 +0200127 public function __construct($params)
128 {
129 parent::__construct($params);
130
131 $valid_dsns = array(
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200132 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
133 // Easy Connect string (Oracle 10g+)
134 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
135 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
136 );
Andrey Andreevdad61c22012-02-13 01:08:06 +0200137
138 /* Space characters don't have any effect when actually
139 * connecting, but can be a hassle while validating the DSN.
140 */
141 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
142
143 if ($this->dsn !== '')
144 {
145 foreach ($valid_dsns as $regexp)
146 {
147 if (preg_match($regexp, $this->dsn))
148 {
149 return;
150 }
151 }
152 }
153
154 // Legacy support for TNS in the hostname configuration field
155 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
156 if (preg_match($valid_dsns['tns'], $this->hostname))
157 {
158 $this->dsn = $this->hostname;
159 return;
160 }
161 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
162 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
163 {
164 /* If the hostname field isn't empty, doesn't contain
165 * ':' and/or '/' and if port and/or database aren't
166 * empty, then the hostname field is most likely indeed
167 * just a hostname. Therefore we'll try and build an
168 * Easy Connect string from these 3 settings, assuming
169 * that the database field is a service name.
170 */
171 $this->dsn = $this->hostname
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200172 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
173 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
Andrey Andreevdad61c22012-02-13 01:08:06 +0200174
175 if (preg_match($valid_dsns['ec'], $this->dsn))
176 {
177 return;
178 }
179 }
180
181 /* At this point, we can only try and validate the hostname and
182 * database fields separately as DSNs.
183 */
184 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
185 {
186 $this->dsn = $this->hostname;
187 return;
188 }
189
190 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
191 foreach ($valid_dsns as $regexp)
192 {
193 if (preg_match($regexp, $this->database))
194 {
195 return;
196 }
197 }
198
199 /* Well - OK, an empty string should work as well.
200 * PHP will try to use environment variables to
201 * determine which Oracle instance to connect to.
202 */
203 $this->dsn = '';
204 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000205
Andrey Andreevd5809992012-06-28 14:06:54 +0300206 // --------------------------------------------------------------------
207
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 /**
209 * Non-persistent database connection
210 *
Andrey Andreev2e171022014-02-25 15:21:41 +0200211 * @param bool $persistent
Andrey Andreevaa786c92012-01-16 12:14:45 +0200212 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000213 */
Andrey Andreev2e171022014-02-25 15:21:41 +0200214 public function db_connect($persistent = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 {
Andrey Andreev2e171022014-02-25 15:21:41 +0200216 $func = ($persistent === TRUE) ? 'oci_pconnect' : 'oci_connect';
Andrey Andreevd5809992012-06-28 14:06:54 +0300217 return empty($this->char_set)
Andrey Andreev2e171022014-02-25 15:21:41 +0200218 ? $func($this->username, $this->password, $this->dsn)
219 : $func($this->username, $this->password, $this->dsn, $this->char_set);
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 }
221
222 // --------------------------------------------------------------------
223
224 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200225 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200227 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200229 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000230 {
Andrey Andreev2b730372012-11-05 17:01:11 +0200231 if (isset($this->data_cache['version']))
232 {
233 return $this->data_cache['version'];
234 }
235 elseif ( ! $this->conn_id)
236 {
237 $this->initialize();
238 }
239
240 if ( ! $this->conn_id OR ($version = oci_server_version($this->conn_id)) === FALSE)
241 {
242 return FALSE;
243 }
244
245 return $this->data_cache['version'] = $version;
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 }
247
248 // --------------------------------------------------------------------
249
250 /**
251 * Execute the query
252 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200253 * @param string $sql an SQL query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200254 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300256 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200258 /* Oracle must parse the query before it is run. All of the actions with
259 * the query are based on the statement id returned by oci_parse().
260 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 $this->stmt_id = FALSE;
262 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300263 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev99013ed2012-03-05 16:17:32 +0200264 return @oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 }
266
Andrey Andreevd5809992012-06-28 14:06:54 +0300267 // --------------------------------------------------------------------
268
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 /**
270 * Generate a statement ID
271 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200272 * @param string $sql an SQL query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200273 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 */
Andrey Andreevda123732012-03-20 22:27:40 +0200275 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 {
277 if ( ! is_resource($this->stmt_id))
278 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400279 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 }
281 }
282
283 // --------------------------------------------------------------------
284
285 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200286 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300288 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000289 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300290 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200292 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 }
294
295 // --------------------------------------------------------------------
296
297 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500298 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200300 * @param string package name in which the stored procedure is in
301 * @param string stored procedure name to execute
302 * @param array parameters
303 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 *
305 * params array keys
306 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500307 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200308 * name no the name of the parameter should be in :<param_name> format
309 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
310 * this should be a reference to a variable
311 * type yes the type of the parameter
312 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300314 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100316 if ($package === '' OR $procedure === '' OR ! is_array($params))
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 {
Andrey Andreeve18de502013-07-17 19:59:20 +0300318 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
319 return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 }
Barry Mienydd671972010-10-04 16:33:58 +0200321
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200323 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000324
325 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500326 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200328 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200329
Andrey Andreev85facfa2012-01-26 14:12:14 +0200330 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000331 {
332 $have_cursor = TRUE;
333 }
334 }
Andrey Andreev3ca060a2013-11-27 16:30:31 +0200335 $sql = trim($sql, ',').'); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200336
Derek Allard2067d1a2008-11-13 22:59:24 +0000337 $this->stmt_id = FALSE;
338 $this->_set_stmt_id($sql);
339 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200340 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 }
Barry Mienydd671972010-10-04 16:33:58 +0200342
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 // --------------------------------------------------------------------
344
345 /**
346 * Bind parameters
347 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200348 * @param array $params
Andrey Andreevaa786c92012-01-16 12:14:45 +0200349 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200351 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 {
353 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
354 {
355 return;
356 }
Barry Mienydd671972010-10-04 16:33:58 +0200357
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 foreach ($params as $param)
359 {
Barry Mienydd671972010-10-04 16:33:58 +0200360 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 {
362 if ( ! isset($param[$val]))
363 {
364 $param[$val] = '';
365 }
366 }
367
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300368 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 }
370 }
371
372 // --------------------------------------------------------------------
373
374 /**
375 * Begin Transaction
376 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200377 * @param bool $test_mode
Barry Mienydd671972010-10-04 16:33:58 +0200378 * @return bool
379 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300380 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 {
382 if ( ! $this->trans_enabled)
383 {
384 return TRUE;
385 }
Barry Mienydd671972010-10-04 16:33:58 +0200386
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 // When transactions are nested we only begin/commit/rollback the outermost ones
388 if ($this->_trans_depth > 0)
389 {
390 return TRUE;
391 }
Barry Mienydd671972010-10-04 16:33:58 +0200392
Derek Allard2067d1a2008-11-13 22:59:24 +0000393 // Reset the transaction failure flag.
394 // If the $test_mode flag is set to TRUE transactions will be rolled back
395 // even if the queries produce a successful result.
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200396 $this->_trans_failure = ($test_mode === TRUE);
Barry Mienydd671972010-10-04 16:33:58 +0200397
Andrey Andreev1a61ba42014-03-24 16:53:16 +0200398 $this->commit_mode = is_php('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000399 return TRUE;
400 }
401
402 // --------------------------------------------------------------------
403
404 /**
405 * Commit Transaction
406 *
Barry Mienydd671972010-10-04 16:33:58 +0200407 * @return bool
408 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300409 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 {
411 if ( ! $this->trans_enabled)
412 {
413 return TRUE;
414 }
415
416 // When transactions are nested we only begin/commit/rollback the outermost ones
417 if ($this->_trans_depth > 0)
418 {
419 return TRUE;
420 }
421
Andrey Andreev99013ed2012-03-05 16:17:32 +0200422 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200423 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000424 }
425
426 // --------------------------------------------------------------------
427
428 /**
429 * Rollback Transaction
430 *
Barry Mienydd671972010-10-04 16:33:58 +0200431 * @return bool
432 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300433 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000435 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200436 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 {
438 return TRUE;
439 }
440
Andrey Andreev99013ed2012-03-05 16:17:32 +0200441 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200442 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 }
444
445 // --------------------------------------------------------------------
446
447 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 * Affected Rows
449 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200450 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300452 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000453 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300454 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 }
456
457 // --------------------------------------------------------------------
458
459 /**
460 * Insert ID
461 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200462 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300464 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 {
466 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000467 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 }
469
470 // --------------------------------------------------------------------
471
472 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 * Show table query
474 *
475 * Generates a platform-specific query string so that the table names can be fetched
476 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200477 * @param bool $prefix_limit
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300478 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300480 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000481 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300482 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000483
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100484 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000485 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300486 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
487 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000488 }
Barry Mienydd671972010-10-04 16:33:58 +0200489
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 return $sql;
491 }
492
493 // --------------------------------------------------------------------
494
495 /**
496 * Show column query
497 *
498 * Generates a platform-specific query string so that the column names can be fetched
499 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200500 * @param string $table
Andrey Andreevaa786c92012-01-16 12:14:45 +0200501 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000502 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300503 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 {
Andrey Andreeve1580572012-11-16 16:17:54 +0200505 if (strpos($table, '.') !== FALSE)
506 {
507 sscanf($table, '%[^.].%s', $owner, $table);
508 }
509 else
510 {
511 $owner = $this->username;
512 }
513
514 return 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS
515 WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).'
516 AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table));
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 }
518
519 // --------------------------------------------------------------------
520
521 /**
Andrey Andreeve1580572012-11-16 16:17:54 +0200522 * Returns an object with field data
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200524 * @param string $table
Andrey Andreeve1580572012-11-16 16:17:54 +0200525 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000526 */
Andrey Andreeve1580572012-11-16 16:17:54 +0200527 public function field_data($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000528 {
Andrey Andreeve1580572012-11-16 16:17:54 +0200529 if ($table === '')
530 {
531 return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
532 }
533 elseif (strpos($table, '.') !== FALSE)
534 {
535 sscanf($table, '%[^.].%s', $owner, $table);
536 }
537 else
538 {
539 $owner = $this->username;
540 }
541
542 $sql = 'SELECT COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, DATA_PRECISION, DATA_LENGTH, DATA_DEFAULT, NULLABLE
543 FROM ALL_TAB_COLUMNS
544 WHERE UPPER(OWNER) = '.$this->escape(strtoupper($owner)).'
545 AND UPPER(TABLE_NAME) = '.$this->escape(strtoupper($table));
546
547 if (($query = $this->query($sql)) === FALSE)
548 {
549 return FALSE;
550 }
551 $query = $query->result_object();
552
553 $retval = array();
554 for ($i = 0, $c = count($query); $i < $c; $i++)
555 {
556 $retval[$i] = new stdClass();
557 $retval[$i]->name = $query[$i]->COLUMN_NAME;
558 $retval[$i]->type = $query[$i]->DATA_TYPE;
559
560 $length = ($query[$i]->CHAR_LENGTH > 0)
561 ? $query[$i]->CHAR_LENGTH : $query[$i]->DATA_PRECISION;
562 if ($length === NULL)
563 {
564 $length = $query[$i]->DATA_LENGTH;
565 }
566 $retval[$i]->max_length = $length;
567
568 $default = $query[$i]->DATA_DEFAULT;
569 if ($default === NULL && $query[$i]->NULLABLE === 'N')
570 {
571 $default = '';
572 }
573 $retval[$i]->default = $query[$i]->COLUMN_DEFAULT;
574 }
575
576 return $retval;
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 }
578
579 // --------------------------------------------------------------------
580
581 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200582 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200584 * Returns an array containing code and message of the last
585 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200587 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000588 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200589 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200591 /* oci_error() returns an array that already contains the
592 * 'code' and 'message' keys, so we can just return it.
593 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200594 if (is_resource($this->curs_id))
595 {
596 return oci_error($this->curs_id);
597 }
598 elseif (is_resource($this->stmt_id))
599 {
600 return oci_error($this->stmt_id);
601 }
602 elseif (is_resource($this->conn_id))
603 {
604 return oci_error($this->conn_id);
605 }
606
607 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 }
Barry Mienydd671972010-10-04 16:33:58 +0200609
Derek Allard2067d1a2008-11-13 22:59:24 +0000610 // --------------------------------------------------------------------
611
612 /**
Andrey Andreev083e3c82012-11-06 12:48:32 +0200613 * Insert batch statement
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300614 *
615 * Generates a platform-specific insert string from the supplied data
616 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200617 * @param string $table Table name
618 * @param array $keys INSERT keys
619 * @param array $values INSERT values
Andrey Andreevda123732012-03-20 22:27:40 +0200620 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300621 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300622 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300623 {
624 $keys = implode(', ', $keys);
625 $sql = "INSERT ALL\n";
626
627 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300628 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300629 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300630 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300631
Andrey Andreevaa786c92012-01-16 12:14:45 +0200632 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 }
634
635 // --------------------------------------------------------------------
636
637 /**
638 * Truncate statement
639 *
640 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000641 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200642 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300643 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200645 * @param string $table
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200647 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300648 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000649 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200650 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 }
Barry Mienydd671972010-10-04 16:33:58 +0200652
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 // --------------------------------------------------------------------
654
655 /**
656 * Delete statement
657 *
658 * Generates a platform-specific delete string from the supplied data
659 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200660 * @param string $table
Derek Allard2067d1a2008-11-13 22:59:24 +0000661 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200662 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300663 protected function _delete($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000664 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300665 if ($this->qb_limit)
666 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300667 $this->where('rownum <= ',$this->qb_limit, FALSE);
Andrey Andreevb0478652012-07-18 15:34:46 +0300668 $this->qb_limit = FALSE;
669 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000670
Andrey Andreevb0478652012-07-18 15:34:46 +0300671 return parent::_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000672 }
673
674 // --------------------------------------------------------------------
675
676 /**
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200677 * LIMIT
Derek Allard2067d1a2008-11-13 22:59:24 +0000678 *
679 * Generates a platform-specific LIMIT clause
680 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200681 * @param string $sql SQL Query
Andrey Andreevaa786c92012-01-16 12:14:45 +0200682 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000683 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300684 protected function _limit($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000685 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000686 $this->limit_used = TRUE;
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300687 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 +0200688 .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1) : '');
Barry Mienydd671972010-10-04 16:33:58 +0200689 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000690
691 // --------------------------------------------------------------------
692
693 /**
694 * Close DB Connection
695 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200696 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000697 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300698 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000699 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300700 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000701 }
702
Derek Allard2067d1a2008-11-13 22:59:24 +0000703}
704
Derek Allard2067d1a2008-11-13 22:59:24 +0000705/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300706/* Location: ./system/database/drivers/oci8/oci8_driver.php */