blob: 67bb0403b6c8e4823da52b51d1596a3c1d8db100 [file] [log] [blame]
Andrey Andreev24abcb92012-01-05 20:40:15 +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 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
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
Barry Mienydd671972010-10-04 16:33:58 +020024 * @since Version 1.0
Derek Allard2067d1a2008-11-13 22:59:24 +000025 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * oci8 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 *
Barry Mienydd671972010-10-04 16:33:58 +020035 * @package CodeIgniter
Derek Jones4b9c6292011-07-01 17:40:48 -050036 * @subpackage Drivers
Derek Allard2067d1a2008-11-13 22:59:24 +000037 * @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 */
41
42/**
43 * oci8 Database Adapter Class
44 *
45 * This is a modification of the DB_driver class to
46 * permit access to oracle databases
47 *
Derek Jones4b9c6292011-07-01 17:40:48 -050048 * @author Kelly McArdle
Derek Allard2067d1a2008-11-13 22:59:24 +000049 */
Derek Allard2067d1a2008-11-13 22:59:24 +000050class CI_DB_oci8_driver extends CI_DB {
51
Andrey Andreev24abcb92012-01-05 20:40:15 +020052 public $dbdriver = 'oci8';
Barry Mienydd671972010-10-04 16:33:58 +020053
Derek Allard2067d1a2008-11-13 22:59:24 +000054 // The character used for excaping
Andrey Andreev24abcb92012-01-05 20:40:15 +020055 protected $_escape_char = '"';
Barry Mienydd671972010-10-04 16:33:58 +020056
Derek Jonese4ed5832009-02-20 21:44:59 +000057 // clause and character used for LIKE escape sequences
Andrey Andreevda123732012-03-20 22:27:40 +020058 protected $_like_escape_str = " ESCAPE '%s' ";
Andrey Andreev24abcb92012-01-05 20:40:15 +020059 protected $_like_escape_chr = '!';
Barry Mienydd671972010-10-04 16:33:58 +020060
Derek Allard2067d1a2008-11-13 22:59:24 +000061 /**
62 * The syntax to count rows is slightly different across different
63 * database engines, so this string appears in each driver and is
64 * used for the count_all() and count_all_results() functions.
65 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020066 protected $_count_string = 'SELECT COUNT(1) AS ';
67 protected $_random_keyword = ' ASC'; // not currently supported
Derek Allard2067d1a2008-11-13 22:59:24 +000068
Andrey Andreevd3f13672012-06-24 22:13:21 +030069 protected $_reserved_identifiers = array('*', 'rownum');
70
Derek Allard2067d1a2008-11-13 22:59:24 +000071 // Set "auto commit" by default
Andrey Andreev99013ed2012-03-05 16:17:32 +020072 public $commit_mode = OCI_COMMIT_ON_SUCCESS;
Derek Allard2067d1a2008-11-13 22:59:24 +000073
74 // need to track statement id and cursor id
Andrey Andreev24abcb92012-01-05 20:40:15 +020075 public $stmt_id;
76 public $curs_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000077
78 // if we use a limit, we will add a field that will
79 // throw off num_fields later
Andrey Andreev24abcb92012-01-05 20:40:15 +020080 public $limit_used;
Derek Allard2067d1a2008-11-13 22:59:24 +000081
Andrey Andreevdad61c22012-02-13 01:08:06 +020082 public function __construct($params)
83 {
84 parent::__construct($params);
85
86 $valid_dsns = array(
Andrey Andreevdad61c22012-02-13 01:08:06 +020087 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
Andrey Andreevfcd1f472012-02-13 09:30:16 +020088 // Easy Connect string (Oracle 10g+)
89 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
Andrey Andreevdad61c22012-02-13 01:08:06 +020090 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
91 );
92
93 /* Space characters don't have any effect when actually
94 * connecting, but can be a hassle while validating the DSN.
95 */
96 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
97
98 if ($this->dsn !== '')
99 {
100 foreach ($valid_dsns as $regexp)
101 {
102 if (preg_match($regexp, $this->dsn))
103 {
104 return;
105 }
106 }
107 }
108
109 // Legacy support for TNS in the hostname configuration field
110 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
111 if (preg_match($valid_dsns['tns'], $this->hostname))
112 {
113 $this->dsn = $this->hostname;
114 return;
115 }
116 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
117 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
118 {
119 /* If the hostname field isn't empty, doesn't contain
120 * ':' and/or '/' and if port and/or database aren't
121 * empty, then the hostname field is most likely indeed
122 * just a hostname. Therefore we'll try and build an
123 * Easy Connect string from these 3 settings, assuming
124 * that the database field is a service name.
125 */
126 $this->dsn = $this->hostname
127 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
128 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
129
130 if (preg_match($valid_dsns['ec'], $this->dsn))
131 {
132 return;
133 }
134 }
135
136 /* At this point, we can only try and validate the hostname and
137 * database fields separately as DSNs.
138 */
139 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
140 {
141 $this->dsn = $this->hostname;
142 return;
143 }
144
145 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
146 foreach ($valid_dsns as $regexp)
147 {
148 if (preg_match($regexp, $this->database))
149 {
150 return;
151 }
152 }
153
154 /* Well - OK, an empty string should work as well.
155 * PHP will try to use environment variables to
156 * determine which Oracle instance to connect to.
157 */
158 $this->dsn = '';
159 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000160
161 /**
162 * Non-persistent database connection
163 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200164 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300166 public function db_connect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 {
Andrey Andreevdad61c22012-02-13 01:08:06 +0200168 return ( ! empty($this->char_set))
169 ? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set)
170 : @oci_connect($this->username, $this->password, $this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 }
172
173 // --------------------------------------------------------------------
174
175 /**
176 * Persistent database connection
177 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200178 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300180 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 {
Andrey Andreevdad61c22012-02-13 01:08:06 +0200182 return ( ! empty($this->char_set))
183 ? @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set)
184 : @oci_pconnect($this->username, $this->password, $this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 }
186
187 // --------------------------------------------------------------------
188
189 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200190 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200192 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200194 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000195 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200196 return isset($this->data_cache['version'])
197 ? $this->data_cache['version']
198 : $this->data_cache['version'] = oci_server_version($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 }
200
201 // --------------------------------------------------------------------
202
203 /**
204 * Execute the query
205 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200206 * @param string an SQL query
207 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300209 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200211 /* Oracle must parse the query before it is run. All of the actions with
212 * the query are based on the statement id returned by oci_parse().
213 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 $this->stmt_id = FALSE;
215 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300216 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev99013ed2012-03-05 16:17:32 +0200217 return @oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 }
219
220 /**
221 * Generate a statement ID
222 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200223 * @param string an SQL query
224 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 */
Andrey Andreevda123732012-03-20 22:27:40 +0200226 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 {
228 if ( ! is_resource($this->stmt_id))
229 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400230 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 }
232 }
233
234 // --------------------------------------------------------------------
235
236 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200237 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 *
Andrey Andreevda123732012-03-20 22:27:40 +0200239 * @return cursor id
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300241 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200243 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 }
245
246 // --------------------------------------------------------------------
247
248 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500249 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200251 * @param string package name in which the stored procedure is in
252 * @param string stored procedure name to execute
253 * @param array parameters
254 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 *
256 * params array keys
257 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500258 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200259 * name no the name of the parameter should be in :<param_name> format
260 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
261 * this should be a reference to a variable
262 * type yes the type of the parameter
263 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300265 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100267 if ($package === '' OR $procedure === '' OR ! is_array($params))
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 {
269 if ($this->db_debug)
270 {
271 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
Derek Allardfac8fbc2010-02-05 16:14:49 +0000272 return $this->display_error('db_invalid_query');
Derek Allard2067d1a2008-11-13 22:59:24 +0000273 }
274 return FALSE;
275 }
Barry Mienydd671972010-10-04 16:33:58 +0200276
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200278 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000279
280 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500281 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000282 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200283 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200284
Andrey Andreev85facfa2012-01-26 14:12:14 +0200285 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 {
287 $have_cursor = TRUE;
288 }
289 }
Andrey Andreevaa786c92012-01-16 12:14:45 +0200290 $sql = trim($sql, ',') . '); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200291
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 $this->stmt_id = FALSE;
293 $this->_set_stmt_id($sql);
294 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200295 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 }
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 // --------------------------------------------------------------------
299
300 /**
301 * Bind parameters
302 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200303 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200305 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000306 {
307 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
308 {
309 return;
310 }
Barry Mienydd671972010-10-04 16:33:58 +0200311
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 foreach ($params as $param)
313 {
Barry Mienydd671972010-10-04 16:33:58 +0200314 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 {
316 if ( ! isset($param[$val]))
317 {
318 $param[$val] = '';
319 }
320 }
321
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300322 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 }
324 }
325
326 // --------------------------------------------------------------------
327
328 /**
329 * Begin Transaction
330 *
Barry Mienydd671972010-10-04 16:33:58 +0200331 * @return bool
332 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300333 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 {
335 if ( ! $this->trans_enabled)
336 {
337 return TRUE;
338 }
Barry Mienydd671972010-10-04 16:33:58 +0200339
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 // When transactions are nested we only begin/commit/rollback the outermost ones
341 if ($this->_trans_depth > 0)
342 {
343 return TRUE;
344 }
Barry Mienydd671972010-10-04 16:33:58 +0200345
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 // Reset the transaction failure flag.
347 // If the $test_mode flag is set to TRUE transactions will be rolled back
348 // even if the queries produce a successful result.
349 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200350
Andrey Andreev99013ed2012-03-05 16:17:32 +0200351 $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 return TRUE;
353 }
354
355 // --------------------------------------------------------------------
356
357 /**
358 * Commit Transaction
359 *
Barry Mienydd671972010-10-04 16:33:58 +0200360 * @return bool
361 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300362 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000363 {
364 if ( ! $this->trans_enabled)
365 {
366 return TRUE;
367 }
368
369 // When transactions are nested we only begin/commit/rollback the outermost ones
370 if ($this->_trans_depth > 0)
371 {
372 return TRUE;
373 }
374
Andrey Andreev99013ed2012-03-05 16:17:32 +0200375 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200376 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000377 }
378
379 // --------------------------------------------------------------------
380
381 /**
382 * Rollback Transaction
383 *
Barry Mienydd671972010-10-04 16:33:58 +0200384 * @return bool
385 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300386 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000388 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200389 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000390 {
391 return TRUE;
392 }
393
Andrey Andreev99013ed2012-03-05 16:17:32 +0200394 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200395 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000396 }
397
398 // --------------------------------------------------------------------
399
400 /**
401 * Escape String
402 *
Andrey Andreevc2905f52012-03-01 14:39:26 +0200403 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000404 * @param bool whether or not the string will be used in a LIKE condition
Andrey Andreevc2905f52012-03-01 14:39:26 +0200405 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300407 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000409 if (is_array($str))
410 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500411 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200412 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000413 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200414 }
415
416 return $str;
417 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000418
Andrey Andreevc2905f52012-03-01 14:39:26 +0200419 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200420
Derek Jonese4ed5832009-02-20 21:44:59 +0000421 // escape LIKE condition wildcards
422 if ($like === TRUE)
423 {
Andrey Andreevc2905f52012-03-01 14:39:26 +0200424 return str_replace(array($this->_like_escape_chr, '%', '_'),
425 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
426 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000427 }
Barry Mienydd671972010-10-04 16:33:58 +0200428
Derek Jonese4ed5832009-02-20 21:44:59 +0000429 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 }
431
432 // --------------------------------------------------------------------
433
434 /**
435 * Affected Rows
436 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200437 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300439 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300441 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 }
443
444 // --------------------------------------------------------------------
445
446 /**
447 * Insert ID
448 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200449 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300451 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000452 {
453 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000454 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 }
456
457 // --------------------------------------------------------------------
458
459 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 * Show table query
461 *
462 * Generates a platform-specific query string so that the table names can be fetched
463 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200464 * @param bool
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300465 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300467 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300469 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000470
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100471 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300473 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
474 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 }
Barry Mienydd671972010-10-04 16:33:58 +0200476
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 return $sql;
478 }
479
480 // --------------------------------------------------------------------
481
482 /**
483 * Show column query
484 *
485 * Generates a platform-specific query string so that the column names can be fetched
486 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200487 * @param string the table name
488 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000489 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300490 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300492 return 'SELECT "COLUMN_NAME" FROM "all_tab_columns" WHERE "TABLE_NAME" = '.$this->escape($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 }
494
495 // --------------------------------------------------------------------
496
497 /**
498 * Field data query
499 *
500 * Generates a platform-specific query so that the column data can be retrieved
501 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200502 * @param string the table name
503 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300505 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300507 return 'SELECT * FROM '.$this->protect_identifiers($table).' WHERE rownum = 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000508 }
509
510 // --------------------------------------------------------------------
511
512 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200513 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200515 * Returns an array containing code and message of the last
516 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200518 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200520 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200522 /* oci_error() returns an array that already contains the
523 * 'code' and 'message' keys, so we can just return it.
524 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200525 if (is_resource($this->curs_id))
526 {
527 return oci_error($this->curs_id);
528 }
529 elseif (is_resource($this->stmt_id))
530 {
531 return oci_error($this->stmt_id);
532 }
533 elseif (is_resource($this->conn_id))
534 {
535 return oci_error($this->conn_id);
536 }
537
538 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000539 }
Barry Mienydd671972010-10-04 16:33:58 +0200540
Derek Allard2067d1a2008-11-13 22:59:24 +0000541 // --------------------------------------------------------------------
542
543 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 * From Tables
545 *
546 * This function implicitly groups FROM tables so there is no confusion
547 * about operator precedence in harmony with SQL standards
548 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200549 * @param array
550 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000551 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300552 protected function _from_tables($tables)
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 {
Andrey Andreeve35d7782012-01-19 15:56:20 +0200554 return is_array($tables) ? implode(', ', $tables) : $tables;
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 }
556
557 // --------------------------------------------------------------------
558
559 /**
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300560 * Insert_batch statement
561 *
562 * Generates a platform-specific insert string from the supplied data
563 *
Andrey Andreevda123732012-03-20 22:27:40 +0200564 * @param string the table name
565 * @param array the insert keys
566 * @param array the insert values
567 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300568 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300569 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300570 {
571 $keys = implode(', ', $keys);
572 $sql = "INSERT ALL\n";
573
574 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300575 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300576 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300577 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300578
Andrey Andreevaa786c92012-01-16 12:14:45 +0200579 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000580 }
581
582 // --------------------------------------------------------------------
583
584 /**
585 * Truncate statement
586 *
587 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000588 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300589 * If the database does not support the truncate() command,
590 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000592 * @param string the table name
593 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200594 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300595 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200597 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 }
Barry Mienydd671972010-10-04 16:33:58 +0200599
Derek Allard2067d1a2008-11-13 22:59:24 +0000600 // --------------------------------------------------------------------
601
602 /**
603 * Delete statement
604 *
605 * Generates a platform-specific delete string from the supplied data
606 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000607 * @param string the table name
608 * @param array the where clause
Andrey Andreev5f562462012-04-09 12:06:35 +0300609 * @param array the like clause
Derek Allard2067d1a2008-11-13 22:59:24 +0000610 * @param string the limit clause
611 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200612 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300613 protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000614 {
Andrey Andreev5f562462012-04-09 12:06:35 +0300615 $conditions = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000616
Andrey Andreev5f562462012-04-09 12:06:35 +0300617 empty($where) OR $conditions[] = implode(' ', $where);
618 empty($like) OR $conditions[] = implode(' ', $like);
619 empty($limit) OR $conditions[] = 'rownum <= '.$limit;
Derek Allard2067d1a2008-11-13 22:59:24 +0000620
Andrey Andreevc01d3162012-04-09 12:55:11 +0300621 return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 }
623
624 // --------------------------------------------------------------------
625
626 /**
627 * Limit string
628 *
629 * Generates a platform-specific LIMIT clause
630 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200631 * @param string the sql query string
632 * @param int the number of rows to limit the query to
633 * @param int the offset value
634 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300636 protected function _limit($sql, $limit, $offset)
Derek Allard2067d1a2008-11-13 22:59:24 +0000637 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 $this->limit_used = TRUE;
Andrey Andreevaa786c92012-01-16 12:14:45 +0200639 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit).')'
Andrey Andreev2c35b642012-06-24 03:05:26 +0300640 .($offset ? ' WHERE rnum >= '.$offset : '');
Barry Mienydd671972010-10-04 16:33:58 +0200641 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000642
643 // --------------------------------------------------------------------
644
645 /**
646 * Close DB Connection
647 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200648 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000649 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300650 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300652 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 }
654
Derek Allard2067d1a2008-11-13 22:59:24 +0000655}
656
Derek Allard2067d1a2008-11-13 22:59:24 +0000657/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300658/* Location: ./system/database/drivers/oci8/oci8_driver.php */