blob: 81d73d073d9b6919458a542020fcf651e2861215 [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 Andreev5fd3ae82012-10-24 14:55:35 +030078 /**
79 * Constructor
80 *
81 * @param array $params
82 * @return void
83 */
Andrey Andreevdad61c22012-02-13 01:08:06 +020084 public function __construct($params)
85 {
86 parent::__construct($params);
87
88 $valid_dsns = array(
Andrey Andreevdad61c22012-02-13 01:08:06 +020089 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
Andrey Andreevfcd1f472012-02-13 09:30:16 +020090 // Easy Connect string (Oracle 10g+)
91 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
Andrey Andreevdad61c22012-02-13 01:08:06 +020092 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
93 );
94
95 /* Space characters don't have any effect when actually
96 * connecting, but can be a hassle while validating the DSN.
97 */
98 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
99
100 if ($this->dsn !== '')
101 {
102 foreach ($valid_dsns as $regexp)
103 {
104 if (preg_match($regexp, $this->dsn))
105 {
106 return;
107 }
108 }
109 }
110
111 // Legacy support for TNS in the hostname configuration field
112 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
113 if (preg_match($valid_dsns['tns'], $this->hostname))
114 {
115 $this->dsn = $this->hostname;
116 return;
117 }
118 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
119 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
120 {
121 /* If the hostname field isn't empty, doesn't contain
122 * ':' and/or '/' and if port and/or database aren't
123 * empty, then the hostname field is most likely indeed
124 * just a hostname. Therefore we'll try and build an
125 * Easy Connect string from these 3 settings, assuming
126 * that the database field is a service name.
127 */
128 $this->dsn = $this->hostname
129 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
130 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
131
132 if (preg_match($valid_dsns['ec'], $this->dsn))
133 {
134 return;
135 }
136 }
137
138 /* At this point, we can only try and validate the hostname and
139 * database fields separately as DSNs.
140 */
141 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
142 {
143 $this->dsn = $this->hostname;
144 return;
145 }
146
147 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
148 foreach ($valid_dsns as $regexp)
149 {
150 if (preg_match($regexp, $this->database))
151 {
152 return;
153 }
154 }
155
156 /* Well - OK, an empty string should work as well.
157 * PHP will try to use environment variables to
158 * determine which Oracle instance to connect to.
159 */
160 $this->dsn = '';
161 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000162
Andrey Andreevd5809992012-06-28 14:06:54 +0300163 // --------------------------------------------------------------------
164
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 /**
166 * Non-persistent database connection
167 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200168 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300170 public function db_connect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 {
Andrey Andreevdad61c22012-02-13 01:08:06 +0200172 return ( ! empty($this->char_set))
173 ? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set)
174 : @oci_connect($this->username, $this->password, $this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 }
176
177 // --------------------------------------------------------------------
178
179 /**
180 * Persistent database connection
181 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200182 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300184 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 {
Andrey Andreevd5809992012-06-28 14:06:54 +0300186 return empty($this->char_set)
187 ? @oci_pconnect($this->username, $this->password, $this->dsn)
188 : @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set);
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 }
190
191 // --------------------------------------------------------------------
192
193 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200194 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000195 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200196 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200198 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200200 return isset($this->data_cache['version'])
201 ? $this->data_cache['version']
202 : $this->data_cache['version'] = oci_server_version($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 }
204
205 // --------------------------------------------------------------------
206
207 /**
208 * Execute the query
209 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200210 * @param string an SQL query
211 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300213 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200215 /* Oracle must parse the query before it is run. All of the actions with
216 * the query are based on the statement id returned by oci_parse().
217 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 $this->stmt_id = FALSE;
219 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300220 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev99013ed2012-03-05 16:17:32 +0200221 return @oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 }
223
Andrey Andreevd5809992012-06-28 14:06:54 +0300224 // --------------------------------------------------------------------
225
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 /**
227 * Generate a statement ID
228 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200229 * @param string an SQL query
230 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 */
Andrey Andreevda123732012-03-20 22:27:40 +0200232 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000233 {
234 if ( ! is_resource($this->stmt_id))
235 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400236 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 }
238 }
239
240 // --------------------------------------------------------------------
241
242 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200243 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300245 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300247 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200249 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 }
251
252 // --------------------------------------------------------------------
253
254 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500255 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200257 * @param string package name in which the stored procedure is in
258 * @param string stored procedure name to execute
259 * @param array parameters
260 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 *
262 * params array keys
263 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500264 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200265 * name no the name of the parameter should be in :<param_name> format
266 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
267 * this should be a reference to a variable
268 * type yes the type of the parameter
269 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300271 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100273 if ($package === '' OR $procedure === '' OR ! is_array($params))
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 {
275 if ($this->db_debug)
276 {
277 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
Derek Allardfac8fbc2010-02-05 16:14:49 +0000278 return $this->display_error('db_invalid_query');
Derek Allard2067d1a2008-11-13 22:59:24 +0000279 }
280 return FALSE;
281 }
Barry Mienydd671972010-10-04 16:33:58 +0200282
Derek Allard2067d1a2008-11-13 22:59:24 +0000283 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200284 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000285
286 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500287 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200289 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200290
Andrey Andreev85facfa2012-01-26 14:12:14 +0200291 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 {
293 $have_cursor = TRUE;
294 }
295 }
Andrey Andreevaa786c92012-01-16 12:14:45 +0200296 $sql = trim($sql, ',') . '); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 $this->stmt_id = FALSE;
299 $this->_set_stmt_id($sql);
300 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200301 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 }
Barry Mienydd671972010-10-04 16:33:58 +0200303
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 // --------------------------------------------------------------------
305
306 /**
307 * Bind parameters
308 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300309 * @param array
Andrey Andreevaa786c92012-01-16 12:14:45 +0200310 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000311 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200312 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 {
314 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
315 {
316 return;
317 }
Barry Mienydd671972010-10-04 16:33:58 +0200318
Derek Allard2067d1a2008-11-13 22:59:24 +0000319 foreach ($params as $param)
320 {
Barry Mienydd671972010-10-04 16:33:58 +0200321 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 {
323 if ( ! isset($param[$val]))
324 {
325 $param[$val] = '';
326 }
327 }
328
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300329 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 }
331 }
332
333 // --------------------------------------------------------------------
334
335 /**
336 * Begin Transaction
337 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300338 * @param bool
Barry Mienydd671972010-10-04 16:33:58 +0200339 * @return bool
340 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300341 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 if ( ! $this->trans_enabled)
344 {
345 return TRUE;
346 }
Barry Mienydd671972010-10-04 16:33:58 +0200347
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 // When transactions are nested we only begin/commit/rollback the outermost ones
349 if ($this->_trans_depth > 0)
350 {
351 return TRUE;
352 }
Barry Mienydd671972010-10-04 16:33:58 +0200353
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 // Reset the transaction failure flag.
355 // If the $test_mode flag is set to TRUE transactions will be rolled back
356 // even if the queries produce a successful result.
357 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200358
Andrey Andreev99013ed2012-03-05 16:17:32 +0200359 $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 return TRUE;
361 }
362
363 // --------------------------------------------------------------------
364
365 /**
366 * Commit Transaction
367 *
Barry Mienydd671972010-10-04 16:33:58 +0200368 * @return bool
369 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300370 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000371 {
372 if ( ! $this->trans_enabled)
373 {
374 return TRUE;
375 }
376
377 // When transactions are nested we only begin/commit/rollback the outermost ones
378 if ($this->_trans_depth > 0)
379 {
380 return TRUE;
381 }
382
Andrey Andreev99013ed2012-03-05 16:17:32 +0200383 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200384 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 }
386
387 // --------------------------------------------------------------------
388
389 /**
390 * Rollback Transaction
391 *
Barry Mienydd671972010-10-04 16:33:58 +0200392 * @return bool
393 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300394 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000395 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000396 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200397 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000398 {
399 return TRUE;
400 }
401
Andrey Andreev99013ed2012-03-05 16:17:32 +0200402 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200403 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 }
405
406 // --------------------------------------------------------------------
407
408 /**
409 * Escape String
410 *
Andrey Andreevc2905f52012-03-01 14:39:26 +0200411 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000412 * @param bool whether or not the string will be used in a LIKE condition
Andrey Andreevc2905f52012-03-01 14:39:26 +0200413 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000414 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300415 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000417 if (is_array($str))
418 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500419 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200420 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000421 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200422 }
423
424 return $str;
425 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000426
Andrey Andreevc2905f52012-03-01 14:39:26 +0200427 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200428
Derek Jonese4ed5832009-02-20 21:44:59 +0000429 // escape LIKE condition wildcards
430 if ($like === TRUE)
431 {
Andrey Andreevc2905f52012-03-01 14:39:26 +0200432 return str_replace(array($this->_like_escape_chr, '%', '_'),
433 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
434 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000435 }
Barry Mienydd671972010-10-04 16:33:58 +0200436
Derek Jonese4ed5832009-02-20 21:44:59 +0000437 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 }
439
440 // --------------------------------------------------------------------
441
442 /**
443 * Affected Rows
444 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200445 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300447 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300449 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 }
451
452 // --------------------------------------------------------------------
453
454 /**
455 * Insert ID
456 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200457 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300459 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 {
461 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000462 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 }
464
465 // --------------------------------------------------------------------
466
467 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 * Show table query
469 *
470 * Generates a platform-specific query string so that the table names can be fetched
471 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200472 * @param bool
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300473 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300475 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300477 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000478
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100479 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300481 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
482 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 }
Barry Mienydd671972010-10-04 16:33:58 +0200484
Derek Allard2067d1a2008-11-13 22:59:24 +0000485 return $sql;
486 }
487
488 // --------------------------------------------------------------------
489
490 /**
491 * Show column query
492 *
493 * Generates a platform-specific query string so that the column names can be fetched
494 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200495 * @param string the table name
496 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300498 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300500 return 'SELECT "COLUMN_NAME" FROM "all_tab_columns" WHERE "TABLE_NAME" = '.$this->escape($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 }
502
503 // --------------------------------------------------------------------
504
505 /**
506 * Field data query
507 *
508 * Generates a platform-specific query so that the column data can be retrieved
509 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200510 * @param string the table name
511 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300513 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300515 return 'SELECT * FROM '.$this->protect_identifiers($table).' WHERE rownum = 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000516 }
517
518 // --------------------------------------------------------------------
519
520 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200521 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200523 * Returns an array containing code and message of the last
524 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000525 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200526 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200528 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000529 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200530 /* oci_error() returns an array that already contains the
531 * 'code' and 'message' keys, so we can just return it.
532 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200533 if (is_resource($this->curs_id))
534 {
535 return oci_error($this->curs_id);
536 }
537 elseif (is_resource($this->stmt_id))
538 {
539 return oci_error($this->stmt_id);
540 }
541 elseif (is_resource($this->conn_id))
542 {
543 return oci_error($this->conn_id);
544 }
545
546 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 }
Barry Mienydd671972010-10-04 16:33:58 +0200548
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 // --------------------------------------------------------------------
550
551 /**
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300552 * Insert_batch statement
553 *
554 * Generates a platform-specific insert string from the supplied data
555 *
Andrey Andreevda123732012-03-20 22:27:40 +0200556 * @param string the table name
557 * @param array the insert keys
558 * @param array the insert values
559 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300560 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300561 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300562 {
563 $keys = implode(', ', $keys);
564 $sql = "INSERT ALL\n";
565
566 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300567 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300568 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300569 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300570
Andrey Andreevaa786c92012-01-16 12:14:45 +0200571 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000572 }
573
574 // --------------------------------------------------------------------
575
576 /**
577 * Truncate statement
578 *
579 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000580 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300581 * If the database does not support the truncate() command,
582 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 * @param string the table name
585 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200586 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300587 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000588 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200589 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 }
Barry Mienydd671972010-10-04 16:33:58 +0200591
Derek Allard2067d1a2008-11-13 22:59:24 +0000592 // --------------------------------------------------------------------
593
594 /**
595 * Delete statement
596 *
597 * Generates a platform-specific delete string from the supplied data
598 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000599 * @param string the table name
Derek Allard2067d1a2008-11-13 22:59:24 +0000600 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200601 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300602 protected function _delete($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000603 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300604 if ($this->qb_limit)
605 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300606 $this->where('rownum <= ',$this->qb_limit, FALSE);
Andrey Andreevb0478652012-07-18 15:34:46 +0300607 $this->qb_limit = FALSE;
608 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000609
Andrey Andreevb0478652012-07-18 15:34:46 +0300610 return parent::_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000611 }
612
613 // --------------------------------------------------------------------
614
615 /**
616 * Limit string
617 *
618 * Generates a platform-specific LIMIT clause
619 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200620 * @param string the sql query string
Andrey Andreevaa786c92012-01-16 12:14:45 +0200621 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300623 protected function _limit($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000625 $this->limit_used = TRUE;
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300626 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')'
627 .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1): '');
Barry Mienydd671972010-10-04 16:33:58 +0200628 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000629
630 // --------------------------------------------------------------------
631
632 /**
633 * Close DB Connection
634 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200635 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000636 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300637 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300639 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 }
641
Derek Allard2067d1a2008-11-13 22:59:24 +0000642}
643
Derek Allard2067d1a2008-11-13 22:59:24 +0000644/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300645/* Location: ./system/database/drivers/oci8/oci8_driver.php */