blob: 72cbce5c193faa83c1d824d046d9b16aadd19e3d [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 Allard2067d1a2008-11-13 22:59:24 +000057 /**
58 * The syntax to count rows is slightly different across different
59 * database engines, so this string appears in each driver and is
60 * used for the count_all() and count_all_results() functions.
61 */
Andrey Andreev24abcb92012-01-05 20:40:15 +020062 protected $_count_string = 'SELECT COUNT(1) AS ';
63 protected $_random_keyword = ' ASC'; // not currently supported
Derek Allard2067d1a2008-11-13 22:59:24 +000064
Andrey Andreevd3f13672012-06-24 22:13:21 +030065 protected $_reserved_identifiers = array('*', 'rownum');
66
Derek Allard2067d1a2008-11-13 22:59:24 +000067 // Set "auto commit" by default
Andrey Andreev99013ed2012-03-05 16:17:32 +020068 public $commit_mode = OCI_COMMIT_ON_SUCCESS;
Derek Allard2067d1a2008-11-13 22:59:24 +000069
70 // need to track statement id and cursor id
Andrey Andreev24abcb92012-01-05 20:40:15 +020071 public $stmt_id;
72 public $curs_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000073
74 // if we use a limit, we will add a field that will
75 // throw off num_fields later
Andrey Andreev24abcb92012-01-05 20:40:15 +020076 public $limit_used;
Derek Allard2067d1a2008-11-13 22:59:24 +000077
Andrey Andreevdad61c22012-02-13 01:08:06 +020078 public function __construct($params)
79 {
80 parent::__construct($params);
81
82 $valid_dsns = array(
Andrey Andreevdad61c22012-02-13 01:08:06 +020083 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
Andrey Andreevfcd1f472012-02-13 09:30:16 +020084 // Easy Connect string (Oracle 10g+)
85 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
Andrey Andreevdad61c22012-02-13 01:08:06 +020086 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
87 );
88
89 /* Space characters don't have any effect when actually
90 * connecting, but can be a hassle while validating the DSN.
91 */
92 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
93
94 if ($this->dsn !== '')
95 {
96 foreach ($valid_dsns as $regexp)
97 {
98 if (preg_match($regexp, $this->dsn))
99 {
100 return;
101 }
102 }
103 }
104
105 // Legacy support for TNS in the hostname configuration field
106 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
107 if (preg_match($valid_dsns['tns'], $this->hostname))
108 {
109 $this->dsn = $this->hostname;
110 return;
111 }
112 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
113 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
114 {
115 /* If the hostname field isn't empty, doesn't contain
116 * ':' and/or '/' and if port and/or database aren't
117 * empty, then the hostname field is most likely indeed
118 * just a hostname. Therefore we'll try and build an
119 * Easy Connect string from these 3 settings, assuming
120 * that the database field is a service name.
121 */
122 $this->dsn = $this->hostname
123 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
124 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
125
126 if (preg_match($valid_dsns['ec'], $this->dsn))
127 {
128 return;
129 }
130 }
131
132 /* At this point, we can only try and validate the hostname and
133 * database fields separately as DSNs.
134 */
135 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
136 {
137 $this->dsn = $this->hostname;
138 return;
139 }
140
141 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
142 foreach ($valid_dsns as $regexp)
143 {
144 if (preg_match($regexp, $this->database))
145 {
146 return;
147 }
148 }
149
150 /* Well - OK, an empty string should work as well.
151 * PHP will try to use environment variables to
152 * determine which Oracle instance to connect to.
153 */
154 $this->dsn = '';
155 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000156
Andrey Andreevd5809992012-06-28 14:06:54 +0300157 // --------------------------------------------------------------------
158
Derek Allard2067d1a2008-11-13 22:59:24 +0000159 /**
160 * Non-persistent database connection
161 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200162 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300164 public function db_connect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 {
Andrey Andreevdad61c22012-02-13 01:08:06 +0200166 return ( ! empty($this->char_set))
167 ? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set)
168 : @oci_connect($this->username, $this->password, $this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 }
170
171 // --------------------------------------------------------------------
172
173 /**
174 * Persistent database connection
175 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200176 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300178 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 {
Andrey Andreevd5809992012-06-28 14:06:54 +0300180 return empty($this->char_set)
181 ? @oci_pconnect($this->username, $this->password, $this->dsn)
182 : @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set);
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 }
184
185 // --------------------------------------------------------------------
186
187 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200188 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200190 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200192 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200194 return isset($this->data_cache['version'])
195 ? $this->data_cache['version']
196 : $this->data_cache['version'] = oci_server_version($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 }
198
199 // --------------------------------------------------------------------
200
201 /**
202 * Execute the query
203 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200204 * @param string an SQL query
205 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000206 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300207 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200209 /* Oracle must parse the query before it is run. All of the actions with
210 * the query are based on the statement id returned by oci_parse().
211 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 $this->stmt_id = FALSE;
213 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300214 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev99013ed2012-03-05 16:17:32 +0200215 return @oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 }
217
Andrey Andreevd5809992012-06-28 14:06:54 +0300218 // --------------------------------------------------------------------
219
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 /**
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 Andreevd5809992012-06-28 14:06:54 +0300239 * @return resource
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 Andreevd5809992012-06-28 14:06:54 +0300303 * @param array
Andrey Andreevaa786c92012-01-16 12:14:45 +0200304 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200306 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 {
308 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
309 {
310 return;
311 }
Barry Mienydd671972010-10-04 16:33:58 +0200312
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 foreach ($params as $param)
314 {
Barry Mienydd671972010-10-04 16:33:58 +0200315 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 {
317 if ( ! isset($param[$val]))
318 {
319 $param[$val] = '';
320 }
321 }
322
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300323 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 }
325 }
326
327 // --------------------------------------------------------------------
328
329 /**
330 * Begin Transaction
331 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300332 * @param bool
Barry Mienydd671972010-10-04 16:33:58 +0200333 * @return bool
334 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300335 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 {
337 if ( ! $this->trans_enabled)
338 {
339 return TRUE;
340 }
Barry Mienydd671972010-10-04 16:33:58 +0200341
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 // When transactions are nested we only begin/commit/rollback the outermost ones
343 if ($this->_trans_depth > 0)
344 {
345 return TRUE;
346 }
Barry Mienydd671972010-10-04 16:33:58 +0200347
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 // Reset the transaction failure flag.
349 // If the $test_mode flag is set to TRUE transactions will be rolled back
350 // even if the queries produce a successful result.
351 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200352
Andrey Andreev99013ed2012-03-05 16:17:32 +0200353 $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 return TRUE;
355 }
356
357 // --------------------------------------------------------------------
358
359 /**
360 * Commit Transaction
361 *
Barry Mienydd671972010-10-04 16:33:58 +0200362 * @return bool
363 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300364 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000365 {
366 if ( ! $this->trans_enabled)
367 {
368 return TRUE;
369 }
370
371 // When transactions are nested we only begin/commit/rollback the outermost ones
372 if ($this->_trans_depth > 0)
373 {
374 return TRUE;
375 }
376
Andrey Andreev99013ed2012-03-05 16:17:32 +0200377 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200378 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000379 }
380
381 // --------------------------------------------------------------------
382
383 /**
384 * Rollback Transaction
385 *
Barry Mienydd671972010-10-04 16:33:58 +0200386 * @return bool
387 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300388 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000390 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200391 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 {
393 return TRUE;
394 }
395
Andrey Andreev99013ed2012-03-05 16:17:32 +0200396 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200397 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000398 }
399
400 // --------------------------------------------------------------------
401
402 /**
403 * Escape String
404 *
Andrey Andreevc2905f52012-03-01 14:39:26 +0200405 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000406 * @param bool whether or not the string will be used in a LIKE condition
Andrey Andreevc2905f52012-03-01 14:39:26 +0200407 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300409 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000411 if (is_array($str))
412 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500413 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200414 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000415 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200416 }
417
418 return $str;
419 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000420
Andrey Andreevc2905f52012-03-01 14:39:26 +0200421 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200422
Derek Jonese4ed5832009-02-20 21:44:59 +0000423 // escape LIKE condition wildcards
424 if ($like === TRUE)
425 {
Andrey Andreevc2905f52012-03-01 14:39:26 +0200426 return str_replace(array($this->_like_escape_chr, '%', '_'),
427 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
428 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000429 }
Barry Mienydd671972010-10-04 16:33:58 +0200430
Derek Jonese4ed5832009-02-20 21:44:59 +0000431 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 }
433
434 // --------------------------------------------------------------------
435
436 /**
437 * Affected Rows
438 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200439 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300441 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300443 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 }
445
446 // --------------------------------------------------------------------
447
448 /**
449 * Insert ID
450 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200451 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000452 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300453 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 {
455 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000456 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 }
458
459 // --------------------------------------------------------------------
460
461 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000462 * Show table query
463 *
464 * Generates a platform-specific query string so that the table names can be fetched
465 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200466 * @param bool
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300467 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300469 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300471 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000472
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100473 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300475 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
476 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 }
Barry Mienydd671972010-10-04 16:33:58 +0200478
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 return $sql;
480 }
481
482 // --------------------------------------------------------------------
483
484 /**
485 * Show column query
486 *
487 * Generates a platform-specific query string so that the column names can be fetched
488 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200489 * @param string the table name
490 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300492 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300494 return 'SELECT "COLUMN_NAME" FROM "all_tab_columns" WHERE "TABLE_NAME" = '.$this->escape($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 }
496
497 // --------------------------------------------------------------------
498
499 /**
500 * Field data query
501 *
502 * Generates a platform-specific query so that the column data can be retrieved
503 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200504 * @param string the table name
505 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300507 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000508 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300509 return 'SELECT * FROM '.$this->protect_identifiers($table).' WHERE rownum = 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000510 }
511
512 // --------------------------------------------------------------------
513
514 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200515 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000516 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200517 * Returns an array containing code and message of the last
518 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200520 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200522 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200524 /* oci_error() returns an array that already contains the
525 * 'code' and 'message' keys, so we can just return it.
526 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200527 if (is_resource($this->curs_id))
528 {
529 return oci_error($this->curs_id);
530 }
531 elseif (is_resource($this->stmt_id))
532 {
533 return oci_error($this->stmt_id);
534 }
535 elseif (is_resource($this->conn_id))
536 {
537 return oci_error($this->conn_id);
538 }
539
540 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000541 }
Barry Mienydd671972010-10-04 16:33:58 +0200542
Derek Allard2067d1a2008-11-13 22:59:24 +0000543 // --------------------------------------------------------------------
544
545 /**
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300546 * Insert_batch statement
547 *
548 * Generates a platform-specific insert string from the supplied data
549 *
Andrey Andreevda123732012-03-20 22:27:40 +0200550 * @param string the table name
551 * @param array the insert keys
552 * @param array the insert values
553 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300554 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300555 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300556 {
557 $keys = implode(', ', $keys);
558 $sql = "INSERT ALL\n";
559
560 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300561 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300562 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300563 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300564
Andrey Andreevaa786c92012-01-16 12:14:45 +0200565 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 }
567
568 // --------------------------------------------------------------------
569
570 /**
571 * Truncate statement
572 *
573 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000574 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300575 * If the database does not support the truncate() command,
576 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 * @param string the table name
579 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200580 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300581 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200583 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 }
Barry Mienydd671972010-10-04 16:33:58 +0200585
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 // --------------------------------------------------------------------
587
588 /**
589 * Delete statement
590 *
591 * Generates a platform-specific delete string from the supplied data
592 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 * @param string the table name
594 * @param array the where clause
Andrey Andreev5f562462012-04-09 12:06:35 +0300595 * @param array the like clause
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 * @param string the limit clause
597 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200598 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300599 protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000600 {
Andrey Andreev5f562462012-04-09 12:06:35 +0300601 $conditions = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000602
Andrey Andreev5f562462012-04-09 12:06:35 +0300603 empty($where) OR $conditions[] = implode(' ', $where);
604 empty($like) OR $conditions[] = implode(' ', $like);
605 empty($limit) OR $conditions[] = 'rownum <= '.$limit;
Derek Allard2067d1a2008-11-13 22:59:24 +0000606
Andrey Andreevc01d3162012-04-09 12:55:11 +0300607 return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 }
609
610 // --------------------------------------------------------------------
611
612 /**
613 * Limit string
614 *
615 * Generates a platform-specific LIMIT clause
616 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200617 * @param string the sql query string
618 * @param int the number of rows to limit the query to
619 * @param int the offset value
620 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000621 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300622 protected function _limit($sql, $limit, $offset)
Derek Allard2067d1a2008-11-13 22:59:24 +0000623 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 $this->limit_used = TRUE;
Andrey Andreevd5809992012-06-28 14:06:54 +0300625 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit + 1).')'
626 .($offset ? ' WHERE rnum >= '.($offset + 1): '');
Barry Mienydd671972010-10-04 16:33:58 +0200627 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000628
629 // --------------------------------------------------------------------
630
631 /**
632 * Close DB Connection
633 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200634 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300636 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000637 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300638 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000639 }
640
Derek Allard2067d1a2008-11-13 22:59:24 +0000641}
642
Derek Allard2067d1a2008-11-13 22:59:24 +0000643/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300644/* Location: ./system/database/drivers/oci8/oci8_driver.php */