blob: dcc46527ca00ceaa81f46078fae950bd3cc9cac6 [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
Andrey Andreevd5809992012-06-28 14:06:54 +0300161 // --------------------------------------------------------------------
162
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 /**
164 * Non-persistent database connection
165 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200166 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300168 public function db_connect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 {
Andrey Andreevdad61c22012-02-13 01:08:06 +0200170 return ( ! empty($this->char_set))
171 ? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set)
172 : @oci_connect($this->username, $this->password, $this->dsn);
Derek Allard2067d1a2008-11-13 22:59:24 +0000173 }
174
175 // --------------------------------------------------------------------
176
177 /**
178 * Persistent database connection
179 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200180 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300182 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 {
Andrey Andreevd5809992012-06-28 14:06:54 +0300184 return empty($this->char_set)
185 ? @oci_pconnect($this->username, $this->password, $this->dsn)
186 : @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set);
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 }
188
189 // --------------------------------------------------------------------
190
191 /**
Andrey Andreev08856b82012-03-03 03:19:28 +0200192 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 *
Andrey Andreev08856b82012-03-03 03:19:28 +0200194 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000195 */
Andrey Andreev08856b82012-03-03 03:19:28 +0200196 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200198 return isset($this->data_cache['version'])
199 ? $this->data_cache['version']
200 : $this->data_cache['version'] = oci_server_version($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 }
202
203 // --------------------------------------------------------------------
204
205 /**
206 * Execute the query
207 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200208 * @param string an SQL query
209 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300211 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200213 /* Oracle must parse the query before it is run. All of the actions with
214 * the query are based on the statement id returned by oci_parse().
215 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 $this->stmt_id = FALSE;
217 $this->_set_stmt_id($sql);
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300218 oci_set_prefetch($this->stmt_id, 1000);
Andrey Andreev99013ed2012-03-05 16:17:32 +0200219 return @oci_execute($this->stmt_id, $this->commit_mode);
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 }
221
Andrey Andreevd5809992012-06-28 14:06:54 +0300222 // --------------------------------------------------------------------
223
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 /**
225 * Generate a statement ID
226 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200227 * @param string an SQL query
228 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 */
Andrey Andreevda123732012-03-20 22:27:40 +0200230 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 {
232 if ( ! is_resource($this->stmt_id))
233 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400234 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000235 }
236 }
237
238 // --------------------------------------------------------------------
239
240 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200241 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300243 * @return resource
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300245 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200247 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 }
249
250 // --------------------------------------------------------------------
251
252 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500253 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200255 * @param string package name in which the stored procedure is in
256 * @param string stored procedure name to execute
257 * @param array parameters
258 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000259 *
260 * params array keys
261 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500262 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200263 * name no the name of the parameter should be in :<param_name> format
264 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
265 * this should be a reference to a variable
266 * type yes the type of the parameter
267 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300269 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100271 if ($package === '' OR $procedure === '' OR ! is_array($params))
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 {
273 if ($this->db_debug)
274 {
275 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
Derek Allardfac8fbc2010-02-05 16:14:49 +0000276 return $this->display_error('db_invalid_query');
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 }
278 return FALSE;
279 }
Barry Mienydd671972010-10-04 16:33:58 +0200280
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200282 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000283
284 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500285 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200287 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200288
Andrey Andreev85facfa2012-01-26 14:12:14 +0200289 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 {
291 $have_cursor = TRUE;
292 }
293 }
Andrey Andreevaa786c92012-01-16 12:14:45 +0200294 $sql = trim($sql, ',') . '); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200295
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 $this->stmt_id = FALSE;
297 $this->_set_stmt_id($sql);
298 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200299 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 }
Barry Mienydd671972010-10-04 16:33:58 +0200301
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 // --------------------------------------------------------------------
303
304 /**
305 * Bind parameters
306 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300307 * @param array
Andrey Andreevaa786c92012-01-16 12:14:45 +0200308 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200310 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000311 {
312 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
313 {
314 return;
315 }
Barry Mienydd671972010-10-04 16:33:58 +0200316
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 foreach ($params as $param)
318 {
Barry Mienydd671972010-10-04 16:33:58 +0200319 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 {
321 if ( ! isset($param[$val]))
322 {
323 $param[$val] = '';
324 }
325 }
326
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300327 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 }
329 }
330
331 // --------------------------------------------------------------------
332
333 /**
334 * Begin Transaction
335 *
Andrey Andreevd5809992012-06-28 14:06:54 +0300336 * @param bool
Barry Mienydd671972010-10-04 16:33:58 +0200337 * @return bool
338 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300339 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 {
341 if ( ! $this->trans_enabled)
342 {
343 return TRUE;
344 }
Barry Mienydd671972010-10-04 16:33:58 +0200345
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 // When transactions are nested we only begin/commit/rollback the outermost ones
347 if ($this->_trans_depth > 0)
348 {
349 return TRUE;
350 }
Barry Mienydd671972010-10-04 16:33:58 +0200351
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 // Reset the transaction failure flag.
353 // If the $test_mode flag is set to TRUE transactions will be rolled back
354 // even if the queries produce a successful result.
355 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200356
Andrey Andreev99013ed2012-03-05 16:17:32 +0200357 $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 return TRUE;
359 }
360
361 // --------------------------------------------------------------------
362
363 /**
364 * Commit Transaction
365 *
Barry Mienydd671972010-10-04 16:33:58 +0200366 * @return bool
367 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300368 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 {
370 if ( ! $this->trans_enabled)
371 {
372 return TRUE;
373 }
374
375 // When transactions are nested we only begin/commit/rollback the outermost ones
376 if ($this->_trans_depth > 0)
377 {
378 return TRUE;
379 }
380
Andrey Andreev99013ed2012-03-05 16:17:32 +0200381 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200382 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000383 }
384
385 // --------------------------------------------------------------------
386
387 /**
388 * Rollback Transaction
389 *
Barry Mienydd671972010-10-04 16:33:58 +0200390 * @return bool
391 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300392 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000393 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200395 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000396 {
397 return TRUE;
398 }
399
Andrey Andreev99013ed2012-03-05 16:17:32 +0200400 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200401 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000402 }
403
404 // --------------------------------------------------------------------
405
406 /**
407 * Escape String
408 *
Andrey Andreevc2905f52012-03-01 14:39:26 +0200409 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000410 * @param bool whether or not the string will be used in a LIKE condition
Andrey Andreevc2905f52012-03-01 14:39:26 +0200411 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300413 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000414 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000415 if (is_array($str))
416 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500417 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200418 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000419 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200420 }
421
422 return $str;
423 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000424
Andrey Andreevc2905f52012-03-01 14:39:26 +0200425 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200426
Derek Jonese4ed5832009-02-20 21:44:59 +0000427 // escape LIKE condition wildcards
428 if ($like === TRUE)
429 {
Andrey Andreevc2905f52012-03-01 14:39:26 +0200430 return str_replace(array($this->_like_escape_chr, '%', '_'),
431 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
432 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000433 }
Barry Mienydd671972010-10-04 16:33:58 +0200434
Derek Jonese4ed5832009-02-20 21:44:59 +0000435 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000436 }
437
438 // --------------------------------------------------------------------
439
440 /**
441 * Affected Rows
442 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200443 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300445 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300447 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 }
449
450 // --------------------------------------------------------------------
451
452 /**
453 * Insert ID
454 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200455 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000456 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300457 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 {
459 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000460 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 }
462
463 // --------------------------------------------------------------------
464
465 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 * Show table query
467 *
468 * Generates a platform-specific query string so that the table names can be fetched
469 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200470 * @param bool
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300471 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300473 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300475 $sql = 'SELECT "TABLE_NAME" FROM "ALL_TABLES"';
Derek Allard2067d1a2008-11-13 22:59:24 +0000476
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100477 if ($prefix_limit !== FALSE && $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300479 return $sql.' WHERE "TABLE_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
480 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000481 }
Barry Mienydd671972010-10-04 16:33:58 +0200482
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 return $sql;
484 }
485
486 // --------------------------------------------------------------------
487
488 /**
489 * Show column query
490 *
491 * Generates a platform-specific query string so that the column names can be fetched
492 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200493 * @param string the table name
494 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300496 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300498 return 'SELECT "COLUMN_NAME" FROM "all_tab_columns" WHERE "TABLE_NAME" = '.$this->escape($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 }
500
501 // --------------------------------------------------------------------
502
503 /**
504 * Field data query
505 *
506 * Generates a platform-specific query so that the column data can be retrieved
507 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200508 * @param string the table name
509 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000510 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300511 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 {
Andrey Andreevd3f13672012-06-24 22:13:21 +0300513 return 'SELECT * FROM '.$this->protect_identifiers($table).' WHERE rownum = 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 }
515
516 // --------------------------------------------------------------------
517
518 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200519 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000520 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200521 * Returns an array containing code and message of the last
522 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200524 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000525 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200526 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200528 /* oci_error() returns an array that already contains the
529 * 'code' and 'message' keys, so we can just return it.
530 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200531 if (is_resource($this->curs_id))
532 {
533 return oci_error($this->curs_id);
534 }
535 elseif (is_resource($this->stmt_id))
536 {
537 return oci_error($this->stmt_id);
538 }
539 elseif (is_resource($this->conn_id))
540 {
541 return oci_error($this->conn_id);
542 }
543
544 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000545 }
Barry Mienydd671972010-10-04 16:33:58 +0200546
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 // --------------------------------------------------------------------
548
549 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000550 * From Tables
551 *
552 * This function implicitly groups FROM tables so there is no confusion
553 * about operator precedence in harmony with SQL standards
554 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200555 * @param array
556 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300558 protected function _from_tables($tables)
Derek Allard2067d1a2008-11-13 22:59:24 +0000559 {
Andrey Andreeve35d7782012-01-19 15:56:20 +0200560 return is_array($tables) ? implode(', ', $tables) : $tables;
Derek Allard2067d1a2008-11-13 22:59:24 +0000561 }
562
563 // --------------------------------------------------------------------
564
565 /**
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300566 * Insert_batch statement
567 *
568 * Generates a platform-specific insert string from the supplied data
569 *
Andrey Andreevda123732012-03-20 22:27:40 +0200570 * @param string the table name
571 * @param array the insert keys
572 * @param array the insert values
573 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300574 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300575 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300576 {
577 $keys = implode(', ', $keys);
578 $sql = "INSERT ALL\n";
579
580 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300581 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300582 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300583 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300584
Andrey Andreevaa786c92012-01-16 12:14:45 +0200585 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 }
587
588 // --------------------------------------------------------------------
589
590 /**
591 * Truncate statement
592 *
593 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300595 * If the database does not support the truncate() command,
596 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000597 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 * @param string the table name
599 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200600 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300601 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000602 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200603 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000604 }
Barry Mienydd671972010-10-04 16:33:58 +0200605
Derek Allard2067d1a2008-11-13 22:59:24 +0000606 // --------------------------------------------------------------------
607
608 /**
609 * Delete statement
610 *
611 * Generates a platform-specific delete string from the supplied data
612 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000613 * @param string the table name
Derek Allard2067d1a2008-11-13 22:59:24 +0000614 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200615 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300616 protected function _delete($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000617 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300618 if ($this->qb_limit)
619 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300620 $this->where('rownum <= ',$this->qb_limit, FALSE);
Andrey Andreevb0478652012-07-18 15:34:46 +0300621 $this->qb_limit = FALSE;
622 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000623
Andrey Andreevb0478652012-07-18 15:34:46 +0300624 return parent::_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000625 }
626
627 // --------------------------------------------------------------------
628
629 /**
630 * Limit string
631 *
632 * Generates a platform-specific LIMIT clause
633 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200634 * @param string the sql query string
Andrey Andreevaa786c92012-01-16 12:14:45 +0200635 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000636 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300637 protected function _limit($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000639 $this->limit_used = TRUE;
Andrey Andreevc9b924c2012-07-19 13:06:02 +0300640 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')'
641 .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1): '');
Barry Mienydd671972010-10-04 16:33:58 +0200642 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000643
644 // --------------------------------------------------------------------
645
646 /**
647 * Close DB Connection
648 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200649 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300651 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000652 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300653 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000654 }
655
Derek Allard2067d1a2008-11-13 22:59:24 +0000656}
657
Derek Allard2067d1a2008-11-13 22:59:24 +0000658/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300659/* Location: ./system/database/drivers/oci8/oci8_driver.php */