blob: e2fa5134907b81761796c514e4a0f8025b14e45b [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
69 // Set "auto commit" by default
Andrey Andreev99013ed2012-03-05 16:17:32 +020070 public $commit_mode = OCI_COMMIT_ON_SUCCESS;
Derek Allard2067d1a2008-11-13 22:59:24 +000071
72 // need to track statement id and cursor id
Andrey Andreev24abcb92012-01-05 20:40:15 +020073 public $stmt_id;
74 public $curs_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000075
76 // if we use a limit, we will add a field that will
77 // throw off num_fields later
Andrey Andreev24abcb92012-01-05 20:40:15 +020078 public $limit_used;
Derek Allard2067d1a2008-11-13 22:59:24 +000079
Andrey Andreevdad61c22012-02-13 01:08:06 +020080 public function __construct($params)
81 {
82 parent::__construct($params);
83
84 $valid_dsns = array(
Andrey Andreevdad61c22012-02-13 01:08:06 +020085 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
Andrey Andreevfcd1f472012-02-13 09:30:16 +020086 // Easy Connect string (Oracle 10g+)
87 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
Andrey Andreevdad61c22012-02-13 01:08:06 +020088 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
89 );
90
91 /* Space characters don't have any effect when actually
92 * connecting, but can be a hassle while validating the DSN.
93 */
94 $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
95
96 if ($this->dsn !== '')
97 {
98 foreach ($valid_dsns as $regexp)
99 {
100 if (preg_match($regexp, $this->dsn))
101 {
102 return;
103 }
104 }
105 }
106
107 // Legacy support for TNS in the hostname configuration field
108 $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
109 if (preg_match($valid_dsns['tns'], $this->hostname))
110 {
111 $this->dsn = $this->hostname;
112 return;
113 }
114 elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
115 && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
116 {
117 /* If the hostname field isn't empty, doesn't contain
118 * ':' and/or '/' and if port and/or database aren't
119 * empty, then the hostname field is most likely indeed
120 * just a hostname. Therefore we'll try and build an
121 * Easy Connect string from these 3 settings, assuming
122 * that the database field is a service name.
123 */
124 $this->dsn = $this->hostname
125 .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
126 .($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
127
128 if (preg_match($valid_dsns['ec'], $this->dsn))
129 {
130 return;
131 }
132 }
133
134 /* At this point, we can only try and validate the hostname and
135 * database fields separately as DSNs.
136 */
137 if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
138 {
139 $this->dsn = $this->hostname;
140 return;
141 }
142
143 $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
144 foreach ($valid_dsns as $regexp)
145 {
146 if (preg_match($regexp, $this->database))
147 {
148 return;
149 }
150 }
151
152 /* Well - OK, an empty string should work as well.
153 * PHP will try to use environment variables to
154 * determine which Oracle instance to connect to.
155 */
156 $this->dsn = '';
157 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000158
159 /**
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 Andreevdad61c22012-02-13 01:08:06 +0200180 return ( ! empty($this->char_set))
181 ? @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set)
182 : @oci_pconnect($this->username, $this->password, $this->dsn);
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
218 /**
219 * Generate a statement ID
220 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200221 * @param string an SQL query
222 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 */
Andrey Andreevda123732012-03-20 22:27:40 +0200224 protected function _set_stmt_id($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 {
226 if ( ! is_resource($this->stmt_id))
227 {
Timothy Warrend2ff0bc2012-03-19 16:52:10 -0400228 $this->stmt_id = oci_parse($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 }
230 }
231
232 // --------------------------------------------------------------------
233
234 /**
Andrey Andreevda123732012-03-20 22:27:40 +0200235 * Get cursor. Returns a cursor from the database
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 *
Andrey Andreevda123732012-03-20 22:27:40 +0200237 * @return cursor id
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300239 public function get_cursor()
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200241 return $this->curs_id = oci_new_cursor($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 }
243
244 // --------------------------------------------------------------------
245
246 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500247 * Stored Procedure. Executes a stored procedure
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200249 * @param string package name in which the stored procedure is in
250 * @param string stored procedure name to execute
251 * @param array parameters
252 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 *
254 * params array keys
255 *
Derek Jones4b9c6292011-07-01 17:40:48 -0500256 * KEY OPTIONAL NOTES
Andrey Andreevaa786c92012-01-16 12:14:45 +0200257 * name no the name of the parameter should be in :<param_name> format
258 * value no the value of the parameter. If this is an OUT or IN OUT parameter,
259 * this should be a reference to a variable
260 * type yes the type of the parameter
261 * length yes the max size of the parameter
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300263 public function stored_procedure($package, $procedure, $params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 {
265 if ($package == '' OR $procedure == '' OR ! is_array($params))
266 {
267 if ($this->db_debug)
268 {
269 log_message('error', 'Invalid query: '.$package.'.'.$procedure);
Derek Allardfac8fbc2010-02-05 16:14:49 +0000270 return $this->display_error('db_invalid_query');
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 }
272 return FALSE;
273 }
Barry Mienydd671972010-10-04 16:33:58 +0200274
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 // build the query string
Andrey Andreeve35d7782012-01-19 15:56:20 +0200276 $sql = 'BEGIN '.$package.'.'.$procedure.'(';
Derek Allard2067d1a2008-11-13 22:59:24 +0000277
278 $have_cursor = FALSE;
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500279 foreach ($params as $param)
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200281 $sql .= $param['name'].',';
Barry Mienydd671972010-10-04 16:33:58 +0200282
Andrey Andreev85facfa2012-01-26 14:12:14 +0200283 if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 {
285 $have_cursor = TRUE;
286 }
287 }
Andrey Andreevaa786c92012-01-16 12:14:45 +0200288 $sql = trim($sql, ',') . '); END;';
Barry Mienydd671972010-10-04 16:33:58 +0200289
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 $this->stmt_id = FALSE;
291 $this->_set_stmt_id($sql);
292 $this->_bind_params($params);
Andrey Andreevaa786c92012-01-16 12:14:45 +0200293 return $this->query($sql, FALSE, $have_cursor);
Derek Allard2067d1a2008-11-13 22:59:24 +0000294 }
Barry Mienydd671972010-10-04 16:33:58 +0200295
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 // --------------------------------------------------------------------
297
298 /**
299 * Bind parameters
300 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200301 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 */
Andrey Andreev1b5a8562012-03-13 13:13:43 +0200303 protected function _bind_params($params)
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 {
305 if ( ! is_array($params) OR ! is_resource($this->stmt_id))
306 {
307 return;
308 }
Barry Mienydd671972010-10-04 16:33:58 +0200309
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 foreach ($params as $param)
311 {
Barry Mienydd671972010-10-04 16:33:58 +0200312 foreach (array('name', 'value', 'type', 'length') as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 {
314 if ( ! isset($param[$val]))
315 {
316 $param[$val] = '';
317 }
318 }
319
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300320 oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000321 }
322 }
323
324 // --------------------------------------------------------------------
325
326 /**
327 * Begin Transaction
328 *
Barry Mienydd671972010-10-04 16:33:58 +0200329 * @return bool
330 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300331 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 {
333 if ( ! $this->trans_enabled)
334 {
335 return TRUE;
336 }
Barry Mienydd671972010-10-04 16:33:58 +0200337
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 // When transactions are nested we only begin/commit/rollback the outermost ones
339 if ($this->_trans_depth > 0)
340 {
341 return TRUE;
342 }
Barry Mienydd671972010-10-04 16:33:58 +0200343
Derek Allard2067d1a2008-11-13 22:59:24 +0000344 // Reset the transaction failure flag.
345 // If the $test_mode flag is set to TRUE transactions will be rolled back
346 // even if the queries produce a successful result.
347 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200348
Andrey Andreev99013ed2012-03-05 16:17:32 +0200349 $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 return TRUE;
351 }
352
353 // --------------------------------------------------------------------
354
355 /**
356 * Commit Transaction
357 *
Barry Mienydd671972010-10-04 16:33:58 +0200358 * @return bool
359 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300360 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 {
362 if ( ! $this->trans_enabled)
363 {
364 return TRUE;
365 }
366
367 // When transactions are nested we only begin/commit/rollback the outermost ones
368 if ($this->_trans_depth > 0)
369 {
370 return TRUE;
371 }
372
Andrey Andreev99013ed2012-03-05 16:17:32 +0200373 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200374 return oci_commit($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000375 }
376
377 // --------------------------------------------------------------------
378
379 /**
380 * Rollback Transaction
381 *
Barry Mienydd671972010-10-04 16:33:58 +0200382 * @return bool
383 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300384 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreeve35d7782012-01-19 15:56:20 +0200387 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000388 {
389 return TRUE;
390 }
391
Andrey Andreev99013ed2012-03-05 16:17:32 +0200392 $this->commit_mode = OCI_COMMIT_ON_SUCCESS;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200393 return oci_rollback($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 }
395
396 // --------------------------------------------------------------------
397
398 /**
399 * Escape String
400 *
Andrey Andreevc2905f52012-03-01 14:39:26 +0200401 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000402 * @param bool whether or not the string will be used in a LIKE condition
Andrey Andreevc2905f52012-03-01 14:39:26 +0200403 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300405 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000407 if (is_array($str))
408 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500409 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200410 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000411 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200412 }
413
414 return $str;
415 }
Derek Jonese4ed5832009-02-20 21:44:59 +0000416
Andrey Andreevc2905f52012-03-01 14:39:26 +0200417 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200418
Derek Jonese4ed5832009-02-20 21:44:59 +0000419 // escape LIKE condition wildcards
420 if ($like === TRUE)
421 {
Andrey Andreevc2905f52012-03-01 14:39:26 +0200422 return str_replace(array($this->_like_escape_chr, '%', '_'),
423 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
424 $str);
Derek Jonese4ed5832009-02-20 21:44:59 +0000425 }
Barry Mienydd671972010-10-04 16:33:58 +0200426
Derek Jonese4ed5832009-02-20 21:44:59 +0000427 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 }
429
430 // --------------------------------------------------------------------
431
432 /**
433 * Affected Rows
434 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200435 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000436 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300437 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300439 return @oci_num_rows($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 }
441
442 // --------------------------------------------------------------------
443
444 /**
445 * Insert ID
446 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200447 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300449 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 {
451 // not supported in oracle
Derek Allardfac8fbc2010-02-05 16:14:49 +0000452 return $this->display_error('db_unsupported_function');
Derek Allard2067d1a2008-11-13 22:59:24 +0000453 }
454
455 // --------------------------------------------------------------------
456
457 /**
458 * "Count All" query
459 *
460 * Generates a platform-specific query string that counts all records in
461 * the specified database
462 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200463 * @param string
464 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300466 public function count_all($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 {
468 if ($table == '')
Derek Allarde37ab382009-02-03 16:13:57 +0000469 {
470 return 0;
471 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000472
Andrey Andreev032e7ea2012-03-06 19:48:35 +0200473 $query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 if ($query == FALSE)
Derek Allarde37ab382009-02-03 16:13:57 +0000475 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 return 0;
Derek Allarde37ab382009-02-03 16:13:57 +0000477 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000478
479 $row = $query->row();
Greg Aker90248ab2011-08-20 14:23:14 -0500480 $this->_reset_select();
Derek Allarde37ab382009-02-03 16:13:57 +0000481 return (int) $row->numrows;
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 }
483
484 // --------------------------------------------------------------------
485
486 /**
487 * Show table query
488 *
489 * Generates a platform-specific query string so that the table names can be fetched
490 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200491 * @param bool
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300492 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300494 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200496 $sql = 'SELECT TABLE_NAME FROM ALL_TABLES';
Derek Allard2067d1a2008-11-13 22:59:24 +0000497
Andrey Andreev1ab62ae2012-01-20 13:04:10 +0200498 if ($prefix_limit !== FALSE && $this->dbprefix != '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200500 return $sql." WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 }
Barry Mienydd671972010-10-04 16:33:58 +0200502
Derek Allard2067d1a2008-11-13 22:59:24 +0000503 return $sql;
504 }
505
506 // --------------------------------------------------------------------
507
508 /**
509 * Show column query
510 *
511 * Generates a platform-specific query string so that the column names can be fetched
512 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200513 * @param string the table name
514 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000515 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300516 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200518 return 'SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = \''.$table.'\'';
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 }
520
521 // --------------------------------------------------------------------
522
523 /**
524 * Field data query
525 *
526 * Generates a platform-specific query so that the column data can be retrieved
527 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200528 * @param string the table name
529 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300531 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000532 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200533 return 'SELECT * FROM '.$table.' WHERE rownum = 1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 }
535
536 // --------------------------------------------------------------------
537
538 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200539 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000540 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200541 * Returns an array containing code and message of the last
542 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000543 *
Andrey Andreev601f8b22012-03-01 20:11:15 +0200544 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000545 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200546 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200548 /* oci_error() returns an array that already contains the
549 * 'code' and 'message' keys, so we can just return it.
550 */
Andrey Andreev601f8b22012-03-01 20:11:15 +0200551 if (is_resource($this->curs_id))
552 {
553 return oci_error($this->curs_id);
554 }
555 elseif (is_resource($this->stmt_id))
556 {
557 return oci_error($this->stmt_id);
558 }
559 elseif (is_resource($this->conn_id))
560 {
561 return oci_error($this->conn_id);
562 }
563
564 return oci_error();
Derek Allard2067d1a2008-11-13 22:59:24 +0000565 }
Barry Mienydd671972010-10-04 16:33:58 +0200566
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 // --------------------------------------------------------------------
568
569 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000570 * From Tables
571 *
572 * This function implicitly groups FROM tables so there is no confusion
573 * about operator precedence in harmony with SQL standards
574 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200575 * @param array
576 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300578 protected function _from_tables($tables)
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 {
Andrey Andreeve35d7782012-01-19 15:56:20 +0200580 return is_array($tables) ? implode(', ', $tables) : $tables;
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 }
582
583 // --------------------------------------------------------------------
584
585 /**
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300586 * Insert_batch statement
587 *
588 * Generates a platform-specific insert string from the supplied data
589 *
Andrey Andreevda123732012-03-20 22:27:40 +0200590 * @param string the table name
591 * @param array the insert keys
592 * @param array the insert values
593 * @return string
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300594 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300595 protected function _insert_batch($table, $keys, $values)
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300596 {
597 $keys = implode(', ', $keys);
598 $sql = "INSERT ALL\n";
599
600 for ($i = 0, $c = count($values); $i < $c; $i++)
Andrey Andreevb83c4082011-09-23 03:32:45 +0300601 {
Andrey Andreev97f36972012-04-05 12:44:36 +0300602 $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
Andrey Andreevb83c4082011-09-23 03:32:45 +0300603 }
Andrey Andreev99c6dd42011-09-23 03:07:01 +0300604
Andrey Andreevaa786c92012-01-16 12:14:45 +0200605 return $sql.'SELECT * FROM dual';
Derek Allard2067d1a2008-11-13 22:59:24 +0000606 }
607
608 // --------------------------------------------------------------------
609
610 /**
611 * Truncate statement
612 *
613 * Generates a platform-specific truncate string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000614 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300615 * If the database does not support the truncate() command,
616 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000617 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000618 * @param string the table name
619 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200620 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300621 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200623 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 }
Barry Mienydd671972010-10-04 16:33:58 +0200625
Derek Allard2067d1a2008-11-13 22:59:24 +0000626 // --------------------------------------------------------------------
627
628 /**
629 * Delete statement
630 *
631 * Generates a platform-specific delete string from the supplied data
632 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 * @param string the table name
634 * @param array the where clause
Andrey Andreev5f562462012-04-09 12:06:35 +0300635 * @param array the like clause
Derek Allard2067d1a2008-11-13 22:59:24 +0000636 * @param string the limit clause
637 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200638 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300639 protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 {
Andrey Andreev5f562462012-04-09 12:06:35 +0300641 $conditions = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000642
Andrey Andreev5f562462012-04-09 12:06:35 +0300643 empty($where) OR $conditions[] = implode(' ', $where);
644 empty($like) OR $conditions[] = implode(' ', $like);
645 empty($limit) OR $conditions[] = 'rownum <= '.$limit;
Derek Allard2067d1a2008-11-13 22:59:24 +0000646
Andrey Andreevc01d3162012-04-09 12:55:11 +0300647 return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
Derek Allard2067d1a2008-11-13 22:59:24 +0000648 }
649
650 // --------------------------------------------------------------------
651
652 /**
653 * Limit string
654 *
655 * Generates a platform-specific LIMIT clause
656 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200657 * @param string the sql query string
658 * @param int the number of rows to limit the query to
659 * @param int the offset value
660 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000661 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300662 protected function _limit($sql, $limit, $offset)
Derek Allard2067d1a2008-11-13 22:59:24 +0000663 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000664 $this->limit_used = TRUE;
Andrey Andreevaa786c92012-01-16 12:14:45 +0200665 return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit).')'
666 .($offset != 0 ? ' WHERE rnum >= '.$offset : '');
Barry Mienydd671972010-10-04 16:33:58 +0200667 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000668
669 // --------------------------------------------------------------------
670
671 /**
672 * Close DB Connection
673 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200674 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000675 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300676 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000677 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300678 @oci_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 }
680
Derek Allard2067d1a2008-11-13 22:59:24 +0000681}
682
Derek Allard2067d1a2008-11-13 22:59:24 +0000683/* End of file oci8_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300684/* Location: ./system/database/drivers/oci8/oci8_driver.php */