Редакция 2 | Только различия | Учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 2 | Редакция 35 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | 2 | ||
3 | /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 | /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
4 | 4 | ||
5 | /**
|
5 | /**
|
6 | * The PEAR DB driver for PHP's oci8 extension
|
6 | * The PEAR DB driver for PHP's oci8 extension
|
7 | * for interacting with Oracle databases
|
7 | * for interacting with Oracle databases
|
8 | *
|
8 | *
|
9 | * PHP versions 4 and 5
|
9 | * PHP versions 4 and 5
|
10 | *
|
10 | *
|
11 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
11 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
12 | * that is available through the world-wide-web at the following URI:
|
12 | * that is available through the world-wide-web at the following URI:
|
13 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
13 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
14 | * the PHP License and are unable to obtain it through the web, please
|
14 | * the PHP License and are unable to obtain it through the web, please
|
15 | * send a note to license@php.net so we can mail you a copy immediately.
|
15 | * send a note to license@php.net so we can mail you a copy immediately.
|
16 | *
|
16 | *
|
17 | * @category Database
|
17 | * @category Database
|
18 | * @package DB
|
18 | * @package DB
|
19 | * @author James L. Pine <jlp@valinux.com>
|
19 | * @author James L. Pine <jlp@valinux.com>
|
20 | * @author Daniel Convissor <danielc@php.net>
|
20 | * @author Daniel Convissor <danielc@php.net>
|
21 | * @copyright 1997-2007 The PHP Group
|
21 | * @copyright 1997-2007 The PHP Group
|
22 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
22 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
23 | * @version CVS: $Id: oci8.php,v 1.115 2007/09/21 13:40:41 aharvey Exp $
|
23 | * @version CVS: $Id: oci8.php,v 1.115 2007/09/21 13:40:41 aharvey Exp $
|
24 | * @link http://pear.php.net/package/DB
|
24 | * @link http://pear.php.net/package/DB
|
25 | */
|
25 | */
|
26 | 26 | ||
27 | /**
|
27 | /**
|
28 | * Obtain the DB_common class so it can be extended from
|
28 | * Obtain the DB_common class so it can be extended from
|
29 | */
|
29 | */
|
30 | require_once 'DB/common.php'; |
30 | require_once 'DB/common.php'; |
31 | 31 | ||
32 | /**
|
32 | /**
|
33 | * The methods PEAR DB uses to interact with PHP's oci8 extension
|
33 | * The methods PEAR DB uses to interact with PHP's oci8 extension
|
34 | * for interacting with Oracle databases
|
34 | * for interacting with Oracle databases
|
35 | *
|
35 | *
|
36 | * Definitely works with versions 8 and 9 of Oracle.
|
36 | * Definitely works with versions 8 and 9 of Oracle.
|
37 | *
|
37 | *
|
38 | * These methods overload the ones declared in DB_common.
|
38 | * These methods overload the ones declared in DB_common.
|
39 | *
|
39 | *
|
40 | * Be aware... OCIError() only appears to return anything when given a
|
40 | * Be aware... OCIError() only appears to return anything when given a
|
41 | * statement, so functions return the generic DB_ERROR instead of more
|
41 | * statement, so functions return the generic DB_ERROR instead of more
|
42 | * useful errors that have to do with feedback from the database.
|
42 | * useful errors that have to do with feedback from the database.
|
43 | *
|
43 | *
|
44 | * @category Database
|
44 | * @category Database
|
45 | * @package DB
|
45 | * @package DB
|
46 | * @author James L. Pine <jlp@valinux.com>
|
46 | * @author James L. Pine <jlp@valinux.com>
|
47 | * @author Daniel Convissor <danielc@php.net>
|
47 | * @author Daniel Convissor <danielc@php.net>
|
48 | * @copyright 1997-2007 The PHP Group
|
48 | * @copyright 1997-2007 The PHP Group
|
49 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
49 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
50 | * @version Release: 1.7.13
|
50 | * @version Release: 1.7.13
|
51 | * @link http://pear.php.net/package/DB
|
51 | * @link http://pear.php.net/package/DB
|
52 | */
|
52 | */
|
53 | class DB_oci8 extends DB_common |
53 | class DB_oci8 extends DB_common |
54 | {
|
54 | {
|
55 | // {{{ properties
|
55 | // {{{ properties
|
56 | 56 | ||
57 | /**
|
57 | /**
|
58 | * The DB driver type (mysql, oci8, odbc, etc.)
|
58 | * The DB driver type (mysql, oci8, odbc, etc.)
|
59 | * @var string
|
59 | * @var string
|
60 | */
|
60 | */
|
61 | var $phptype = 'oci8'; |
61 | var $phptype = 'oci8'; |
62 | 62 | ||
63 | /**
|
63 | /**
|
64 | * The database syntax variant to be used (db2, access, etc.), if any
|
64 | * The database syntax variant to be used (db2, access, etc.), if any
|
65 | * @var string
|
65 | * @var string
|
66 | */
|
66 | */
|
67 | var $dbsyntax = 'oci8'; |
67 | var $dbsyntax = 'oci8'; |
68 | 68 | ||
69 | /**
|
69 | /**
|
70 | * The capabilities of this DB implementation
|
70 | * The capabilities of this DB implementation
|
71 | *
|
71 | *
|
72 | * The 'new_link' element contains the PHP version that first provided
|
72 | * The 'new_link' element contains the PHP version that first provided
|
73 | * new_link support for this DBMS. Contains false if it's unsupported.
|
73 | * new_link support for this DBMS. Contains false if it's unsupported.
|
74 | *
|
74 | *
|
75 | * Meaning of the 'limit' element:
|
75 | * Meaning of the 'limit' element:
|
76 | * + 'emulate' = emulate with fetch row by number
|
76 | * + 'emulate' = emulate with fetch row by number
|
77 | * + 'alter' = alter the query
|
77 | * + 'alter' = alter the query
|
78 | * + false = skip rows
|
78 | * + false = skip rows
|
79 | *
|
79 | *
|
80 | * @var array
|
80 | * @var array
|
81 | */
|
81 | */
|
82 | var $features = array( |
82 | var $features = array( |
83 | 'limit' => 'alter', |
83 | 'limit' => 'alter', |
84 | 'new_link' => '5.0.0', |
84 | 'new_link' => '5.0.0', |
85 | 'numrows' => 'subquery', |
85 | 'numrows' => 'subquery', |
86 | 'pconnect' => true, |
86 | 'pconnect' => true, |
87 | 'prepare' => true, |
87 | 'prepare' => true, |
88 | 'ssl' => false, |
88 | 'ssl' => false, |
89 | 'transactions' => true, |
89 | 'transactions' => true, |
90 | ); |
90 | ); |
91 | 91 | ||
92 | /**
|
92 | /**
|
93 | * A mapping of native error codes to DB error codes
|
93 | * A mapping of native error codes to DB error codes
|
94 | * @var array
|
94 | * @var array
|
95 | */
|
95 | */
|
96 | var $errorcode_map = array( |
96 | var $errorcode_map = array( |
97 | 1 => DB_ERROR_CONSTRAINT, |
97 | 1 => DB_ERROR_CONSTRAINT, |
98 | 900 => DB_ERROR_SYNTAX, |
98 | 900 => DB_ERROR_SYNTAX, |
99 | 904 => DB_ERROR_NOSUCHFIELD, |
99 | 904 => DB_ERROR_NOSUCHFIELD, |
100 | 913 => DB_ERROR_VALUE_COUNT_ON_ROW, |
100 | 913 => DB_ERROR_VALUE_COUNT_ON_ROW, |
101 | 921 => DB_ERROR_SYNTAX, |
101 | 921 => DB_ERROR_SYNTAX, |
102 | 923 => DB_ERROR_SYNTAX, |
102 | 923 => DB_ERROR_SYNTAX, |
103 | 942 => DB_ERROR_NOSUCHTABLE, |
103 | 942 => DB_ERROR_NOSUCHTABLE, |
104 | 955 => DB_ERROR_ALREADY_EXISTS, |
104 | 955 => DB_ERROR_ALREADY_EXISTS, |
105 | 1400 => DB_ERROR_CONSTRAINT_NOT_NULL, |
105 | 1400 => DB_ERROR_CONSTRAINT_NOT_NULL, |
106 | 1401 => DB_ERROR_INVALID, |
106 | 1401 => DB_ERROR_INVALID, |
107 | 1407 => DB_ERROR_CONSTRAINT_NOT_NULL, |
107 | 1407 => DB_ERROR_CONSTRAINT_NOT_NULL, |
108 | 1418 => DB_ERROR_NOT_FOUND, |
108 | 1418 => DB_ERROR_NOT_FOUND, |
109 | 1476 => DB_ERROR_DIVZERO, |
109 | 1476 => DB_ERROR_DIVZERO, |
110 | 1722 => DB_ERROR_INVALID_NUMBER, |
110 | 1722 => DB_ERROR_INVALID_NUMBER, |
111 | 2289 => DB_ERROR_NOSUCHTABLE, |
111 | 2289 => DB_ERROR_NOSUCHTABLE, |
112 | 2291 => DB_ERROR_CONSTRAINT, |
112 | 2291 => DB_ERROR_CONSTRAINT, |
113 | 2292 => DB_ERROR_CONSTRAINT, |
113 | 2292 => DB_ERROR_CONSTRAINT, |
114 | 2449 => DB_ERROR_CONSTRAINT, |
114 | 2449 => DB_ERROR_CONSTRAINT, |
115 | 12899 => DB_ERROR_INVALID, |
115 | 12899 => DB_ERROR_INVALID, |
116 | ); |
116 | ); |
117 | 117 | ||
118 | /**
|
118 | /**
|
119 | * The raw database connection created by PHP
|
119 | * The raw database connection created by PHP
|
120 | * @var resource
|
120 | * @var resource
|
121 | */
|
121 | */
|
122 | var $connection; |
122 | var $connection; |
123 | 123 | ||
124 | /**
|
124 | /**
|
125 | * The DSN information for connecting to a database
|
125 | * The DSN information for connecting to a database
|
126 | * @var array
|
126 | * @var array
|
127 | */
|
127 | */
|
128 | var $dsn = array(); |
128 | var $dsn = array(); |
129 | 129 | ||
130 | 130 | ||
131 | /**
|
131 | /**
|
132 | * Should data manipulation queries be committed automatically?
|
132 | * Should data manipulation queries be committed automatically?
|
133 | * @var bool
|
133 | * @var bool
|
134 | * @access private
|
134 | * @access private
|
135 | */
|
135 | */
|
136 | var $autocommit = true; |
136 | var $autocommit = true; |
137 | 137 | ||
138 | /**
|
138 | /**
|
139 | * Stores the $data passed to execute() in the oci8 driver
|
139 | * Stores the $data passed to execute() in the oci8 driver
|
140 | *
|
140 | *
|
141 | * Gets reset to array() when simpleQuery() is run.
|
141 | * Gets reset to array() when simpleQuery() is run.
|
142 | *
|
142 | *
|
143 | * Needed in case user wants to call numRows() after prepare/execute
|
143 | * Needed in case user wants to call numRows() after prepare/execute
|
144 | * was used.
|
144 | * was used.
|
145 | *
|
145 | *
|
146 | * @var array
|
146 | * @var array
|
147 | * @access private
|
147 | * @access private
|
148 | */
|
148 | */
|
149 | var $_data = array(); |
149 | var $_data = array(); |
150 | 150 | ||
151 | /**
|
151 | /**
|
152 | * The result or statement handle from the most recently executed query
|
152 | * The result or statement handle from the most recently executed query
|
153 | * @var resource
|
153 | * @var resource
|
154 | */
|
154 | */
|
155 | var $last_stmt; |
155 | var $last_stmt; |
156 | 156 | ||
157 | /**
|
157 | /**
|
158 | * Is the given prepared statement a data manipulation query?
|
158 | * Is the given prepared statement a data manipulation query?
|
159 | * @var array
|
159 | * @var array
|
160 | * @access private
|
160 | * @access private
|
161 | */
|
161 | */
|
162 | var $manip_query = array(); |
162 | var $manip_query = array(); |
163 | 163 | ||
164 | /**
|
164 | /**
|
165 | * Store of prepared SQL queries.
|
165 | * Store of prepared SQL queries.
|
166 | * @var array
|
166 | * @var array
|
167 | * @access private
|
167 | * @access private
|
168 | */
|
168 | */
|
169 | var $_prepared_queries = array(); |
169 | var $_prepared_queries = array(); |
170 | 170 | ||
171 | 171 | ||
172 | // }}}
|
172 | // }}}
|
173 | // {{{ constructor
|
173 | // {{{ constructor
|
174 | 174 | ||
175 | /**
|
175 | /**
|
176 | * This constructor calls <kbd>$this->DB_common()</kbd>
|
176 | * This constructor calls <kbd>$this->DB_common()</kbd>
|
177 | *
|
177 | *
|
178 | * @return void
|
178 | * @return void
|
179 | */
|
179 | */
|
180 | function DB_oci8() |
180 | function DB_oci8() |
181 | {
|
181 | {
|
182 | $this->DB_common(); |
182 | $this->DB_common(); |
183 | }
|
183 | }
|
184 | 184 | ||
185 | // }}}
|
185 | // }}}
|
186 | // {{{ connect()
|
186 | // {{{ connect()
|
187 | 187 | ||
188 | /**
|
188 | /**
|
189 | * Connect to the database server, log in and open the database
|
189 | * Connect to the database server, log in and open the database
|
190 | *
|
190 | *
|
191 | * Don't call this method directly. Use DB::connect() instead.
|
191 | * Don't call this method directly. Use DB::connect() instead.
|
192 | *
|
192 | *
|
193 | * If PHP is at version 5.0.0 or greater:
|
193 | * If PHP is at version 5.0.0 or greater:
|
194 | * + Generally, oci_connect() or oci_pconnect() are used.
|
194 | * + Generally, oci_connect() or oci_pconnect() are used.
|
195 | * + But if the new_link DSN option is set to true, oci_new_connect()
|
195 | * + But if the new_link DSN option is set to true, oci_new_connect()
|
196 | * is used.
|
196 | * is used.
|
197 | *
|
197 | *
|
198 | * When using PHP version 4.x, OCILogon() or OCIPLogon() are used.
|
198 | * When using PHP version 4.x, OCILogon() or OCIPLogon() are used.
|
199 | *
|
199 | *
|
200 | * PEAR DB's oci8 driver supports the following extra DSN options:
|
200 | * PEAR DB's oci8 driver supports the following extra DSN options:
|
201 | * + charset The character set to be used on the connection.
|
201 | * + charset The character set to be used on the connection.
|
202 | * Only used if PHP is at version 5.0.0 or greater
|
202 | * Only used if PHP is at version 5.0.0 or greater
|
203 | * and the Oracle server is at 9.2 or greater.
|
203 | * and the Oracle server is at 9.2 or greater.
|
204 | * Available since PEAR DB 1.7.0.
|
204 | * Available since PEAR DB 1.7.0.
|
205 | * + new_link If set to true, causes subsequent calls to
|
205 | * + new_link If set to true, causes subsequent calls to
|
206 | * connect() to return a new connection link
|
206 | * connect() to return a new connection link
|
207 | * instead of the existing one. WARNING: this is
|
207 | * instead of the existing one. WARNING: this is
|
208 | * not portable to other DBMS's.
|
208 | * not portable to other DBMS's.
|
209 | * Available since PEAR DB 1.7.0.
|
209 | * Available since PEAR DB 1.7.0.
|
210 | *
|
210 | *
|
211 | * @param array $dsn the data source name
|
211 | * @param array $dsn the data source name
|
212 | * @param bool $persistent should the connection be persistent?
|
212 | * @param bool $persistent should the connection be persistent?
|
213 | *
|
213 | *
|
214 | * @return int DB_OK on success. A DB_Error object on failure.
|
214 | * @return int DB_OK on success. A DB_Error object on failure.
|
215 | */
|
215 | */
|
216 | function connect($dsn, $persistent = false) |
216 | function connect($dsn, $persistent = false) |
217 | {
|
217 | {
|
218 | if (!PEAR::loadExtension('oci8')) { |
218 | if (!PEAR::loadExtension('oci8')) { |
219 | return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
219 | return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
220 | }
|
220 | }
|
221 | 221 | ||
222 | $this->dsn = $dsn; |
222 | $this->dsn = $dsn; |
223 | if ($dsn['dbsyntax']) { |
223 | if ($dsn['dbsyntax']) { |
224 | $this->dbsyntax = $dsn['dbsyntax']; |
224 | $this->dbsyntax = $dsn['dbsyntax']; |
225 | }
|
225 | }
|
226 | 226 | ||
227 | // Backwards compatibility with DB < 1.7.0
|
227 | // Backwards compatibility with DB < 1.7.0
|
228 | if (empty($dsn['database']) && !empty($dsn['hostspec'])) { |
228 | if (empty($dsn['database']) && !empty($dsn['hostspec'])) { |
229 | $db = $dsn['hostspec']; |
229 | $db = $dsn['hostspec']; |
230 | } else { |
230 | } else { |
231 | $db = $dsn['database']; |
231 | $db = $dsn['database']; |
232 | }
|
232 | }
|
233 | 233 | ||
234 | if (function_exists('oci_connect')) { |
234 | if (function_exists('oci_connect')) { |
235 | if (isset($dsn['new_link']) |
235 | if (isset($dsn['new_link']) |
236 | && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
236 | && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
237 | {
|
237 | {
|
238 | $connect_function = 'oci_new_connect'; |
238 | $connect_function = 'oci_new_connect'; |
239 | } else { |
239 | } else { |
240 | $connect_function = $persistent ? 'oci_pconnect' |
240 | $connect_function = $persistent ? 'oci_pconnect' |
241 | : 'oci_connect'; |
241 | : 'oci_connect'; |
242 | }
|
242 | }
|
243 | if (isset($this->dsn['port']) && $this->dsn['port']) { |
243 | if (isset($this->dsn['port']) && $this->dsn['port']) { |
244 | $db = '//'.$db.':'.$this->dsn['port']; |
244 | $db = '//'.$db.':'.$this->dsn['port']; |
245 | }
|
245 | }
|
246 | 246 | ||
247 | $char = empty($dsn['charset']) ? null : $dsn['charset']; |
247 | $char = empty($dsn['charset']) ? null : $dsn['charset']; |
248 | $this->connection = @$connect_function($dsn['username'], |
248 | $this->connection = @$connect_function($dsn['username'], |
249 | $dsn['password'], |
249 | $dsn['password'], |
250 | $db, |
250 | $db, |
251 | $char); |
251 | $char); |
252 | $error = OCIError(); |
252 | $error = OCIError(); |
253 | if (!empty($error) && $error['code'] == 12541) { |
253 | if (!empty($error) && $error['code'] == 12541) { |
254 | // Couldn't find TNS listener. Try direct connection.
|
254 | // Couldn't find TNS listener. Try direct connection.
|
255 | $this->connection = @$connect_function($dsn['username'], |
255 | $this->connection = @$connect_function($dsn['username'], |
256 | $dsn['password'], |
256 | $dsn['password'], |
257 | null, |
257 | null, |
258 | $char); |
258 | $char); |
259 | }
|
259 | }
|
260 | } else { |
260 | } else { |
261 | $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; |
261 | $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; |
262 | if ($db) { |
262 | if ($db) { |
263 | $this->connection = @$connect_function($dsn['username'], |
263 | $this->connection = @$connect_function($dsn['username'], |
264 | $dsn['password'], |
264 | $dsn['password'], |
265 | $db); |
265 | $db); |
266 | } elseif ($dsn['username'] || $dsn['password']) { |
266 | } elseif ($dsn['username'] || $dsn['password']) { |
267 | $this->connection = @$connect_function($dsn['username'], |
267 | $this->connection = @$connect_function($dsn['username'], |
268 | $dsn['password']); |
268 | $dsn['password']); |
269 | }
|
269 | }
|
270 | }
|
270 | }
|
271 | 271 | ||
272 | if (!$this->connection) { |
272 | if (!$this->connection) { |
273 | $error = OCIError(); |
273 | $error = OCIError(); |
274 | $error = (is_array($error)) ? $error['message'] : null; |
274 | $error = (is_array($error)) ? $error['message'] : null; |
275 | return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
275 | return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
276 | null, null, null, |
276 | null, null, null, |
277 | $error); |
277 | $error); |
278 | }
|
278 | }
|
279 | return DB_OK; |
279 | return DB_OK; |
280 | }
|
280 | }
|
281 | 281 | ||
282 | // }}}
|
282 | // }}}
|
283 | // {{{ disconnect()
|
283 | // {{{ disconnect()
|
284 | 284 | ||
285 | /**
|
285 | /**
|
286 | * Disconnects from the database server
|
286 | * Disconnects from the database server
|
287 | *
|
287 | *
|
288 | * @return bool TRUE on success, FALSE on failure
|
288 | * @return bool TRUE on success, FALSE on failure
|
289 | */
|
289 | */
|
290 | function disconnect() |
290 | function disconnect() |
291 | {
|
291 | {
|
292 | if (function_exists('oci_close')) { |
292 | if (function_exists('oci_close')) { |
293 | $ret = @oci_close($this->connection); |
293 | $ret = @oci_close($this->connection); |
294 | } else { |
294 | } else { |
295 | $ret = @OCILogOff($this->connection); |
295 | $ret = @OCILogOff($this->connection); |
296 | }
|
296 | }
|
297 | $this->connection = null; |
297 | $this->connection = null; |
298 | return $ret; |
298 | return $ret; |
299 | }
|
299 | }
|
300 | 300 | ||
301 | // }}}
|
301 | // }}}
|
302 | // {{{ simpleQuery()
|
302 | // {{{ simpleQuery()
|
303 | 303 | ||
304 | /**
|
304 | /**
|
305 | * Sends a query to the database server
|
305 | * Sends a query to the database server
|
306 | *
|
306 | *
|
307 | * To determine how many rows of a result set get buffered using
|
307 | * To determine how many rows of a result set get buffered using
|
308 | * ocisetprefetch(), see the "result_buffering" option in setOptions().
|
308 | * ocisetprefetch(), see the "result_buffering" option in setOptions().
|
309 | * This option was added in Release 1.7.0.
|
309 | * This option was added in Release 1.7.0.
|
310 | *
|
310 | *
|
311 | * @param string the SQL query string
|
311 | * @param string the SQL query string
|
312 | *
|
312 | *
|
313 | * @return mixed + a PHP result resrouce for successful SELECT queries
|
313 | * @return mixed + a PHP result resrouce for successful SELECT queries
|
314 | * + the DB_OK constant for other successful queries
|
314 | * + the DB_OK constant for other successful queries
|
315 | * + a DB_Error object on failure
|
315 | * + a DB_Error object on failure
|
316 | */
|
316 | */
|
317 | function simpleQuery($query) |
317 | function simpleQuery($query) |
318 | {
|
318 | {
|
319 | $this->_data = array(); |
319 | $this->_data = array(); |
320 | $this->last_parameters = array(); |
320 | $this->last_parameters = array(); |
321 | $this->last_query = $query; |
321 | $this->last_query = $query; |
322 | $query = $this->modifyQuery($query); |
322 | $query = $this->modifyQuery($query); |
323 | $result = @OCIParse($this->connection, $query); |
323 | $result = @OCIParse($this->connection, $query); |
324 | if (!$result) { |
324 | if (!$result) { |
325 | return $this->oci8RaiseError(); |
325 | return $this->oci8RaiseError(); |
326 | }
|
326 | }
|
327 | if ($this->autocommit) { |
327 | if ($this->autocommit) { |
328 | $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); |
328 | $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); |
329 | } else { |
329 | } else { |
330 | $success = @OCIExecute($result,OCI_DEFAULT); |
330 | $success = @OCIExecute($result,OCI_DEFAULT); |
331 | }
|
331 | }
|
332 | if (!$success) { |
332 | if (!$success) { |
333 | return $this->oci8RaiseError($result); |
333 | return $this->oci8RaiseError($result); |
334 | }
|
334 | }
|
335 | $this->last_stmt = $result; |
335 | $this->last_stmt = $result; |
336 | if ($this->_checkManip($query)) { |
336 | if ($this->_checkManip($query)) { |
337 | return DB_OK; |
337 | return DB_OK; |
338 | } else { |
338 | } else { |
339 | @ocisetprefetch($result, $this->options['result_buffering']); |
339 | @ocisetprefetch($result, $this->options['result_buffering']); |
340 | return $result; |
340 | return $result; |
341 | }
|
341 | }
|
342 | }
|
342 | }
|
343 | 343 | ||
344 | // }}}
|
344 | // }}}
|
345 | // {{{ nextResult()
|
345 | // {{{ nextResult()
|
346 | 346 | ||
347 | /**
|
347 | /**
|
348 | * Move the internal oracle result pointer to the next available result
|
348 | * Move the internal oracle result pointer to the next available result
|
349 | *
|
349 | *
|
350 | * @param a valid oci8 result resource
|
350 | * @param a valid oci8 result resource
|
351 | *
|
351 | *
|
352 | * @access public
|
352 | * @access public
|
353 | *
|
353 | *
|
354 | * @return true if a result is available otherwise return false
|
354 | * @return true if a result is available otherwise return false
|
355 | */
|
355 | */
|
356 | function nextResult($result) |
356 | function nextResult($result) |
357 | {
|
357 | {
|
358 | return false; |
358 | return false; |
359 | }
|
359 | }
|
360 | 360 | ||
361 | // }}}
|
361 | // }}}
|
362 | // {{{ fetchInto()
|
362 | // {{{ fetchInto()
|
363 | 363 | ||
364 | /**
|
364 | /**
|
365 | * Places a row from the result set into the given array
|
365 | * Places a row from the result set into the given array
|
366 | *
|
366 | *
|
367 | * Formating of the array and the data therein are configurable.
|
367 | * Formating of the array and the data therein are configurable.
|
368 | * See DB_result::fetchInto() for more information.
|
368 | * See DB_result::fetchInto() for more information.
|
369 | *
|
369 | *
|
370 | * This method is not meant to be called directly. Use
|
370 | * This method is not meant to be called directly. Use
|
371 | * DB_result::fetchInto() instead. It can't be declared "protected"
|
371 | * DB_result::fetchInto() instead. It can't be declared "protected"
|
372 | * because DB_result is a separate object.
|
372 | * because DB_result is a separate object.
|
373 | *
|
373 | *
|
374 | * @param resource $result the query result resource
|
374 | * @param resource $result the query result resource
|
375 | * @param array $arr the referenced array to put the data in
|
375 | * @param array $arr the referenced array to put the data in
|
376 | * @param int $fetchmode how the resulting array should be indexed
|
376 | * @param int $fetchmode how the resulting array should be indexed
|
377 | * @param int $rownum the row number to fetch (0 = first row)
|
377 | * @param int $rownum the row number to fetch (0 = first row)
|
378 | *
|
378 | *
|
379 | * @return mixed DB_OK on success, NULL when the end of a result set is
|
379 | * @return mixed DB_OK on success, NULL when the end of a result set is
|
380 | * reached or on failure
|
380 | * reached or on failure
|
381 | *
|
381 | *
|
382 | * @see DB_result::fetchInto()
|
382 | * @see DB_result::fetchInto()
|
383 | */
|
383 | */
|
384 | function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
384 | function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
385 | {
|
385 | {
|
386 | if ($rownum !== null) { |
386 | if ($rownum !== null) { |
387 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
387 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
388 | }
|
388 | }
|
389 | if ($fetchmode & DB_FETCHMODE_ASSOC) { |
389 | if ($fetchmode & DB_FETCHMODE_ASSOC) { |
390 | $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
390 | $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
391 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && |
391 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && |
392 | $moredata) |
392 | $moredata) |
393 | {
|
393 | {
|
394 | $arr = array_change_key_case($arr, CASE_LOWER); |
394 | $arr = array_change_key_case($arr, CASE_LOWER); |
395 | }
|
395 | }
|
396 | } else { |
396 | } else { |
397 | $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
397 | $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); |
398 | }
|
398 | }
|
399 | if (!$moredata) { |
399 | if (!$moredata) { |
400 | return null; |
400 | return null; |
401 | }
|
401 | }
|
402 | if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
402 | if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
403 | $this->_rtrimArrayValues($arr); |
403 | $this->_rtrimArrayValues($arr); |
404 | }
|
404 | }
|
405 | if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
405 | if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
406 | $this->_convertNullArrayValuesToEmpty($arr); |
406 | $this->_convertNullArrayValuesToEmpty($arr); |
407 | }
|
407 | }
|
408 | return DB_OK; |
408 | return DB_OK; |
409 | }
|
409 | }
|
410 | 410 | ||
411 | // }}}
|
411 | // }}}
|
412 | // {{{ freeResult()
|
412 | // {{{ freeResult()
|
413 | 413 | ||
414 | /**
|
414 | /**
|
415 | * Deletes the result set and frees the memory occupied by the result set
|
415 | * Deletes the result set and frees the memory occupied by the result set
|
416 | *
|
416 | *
|
417 | * This method is not meant to be called directly. Use
|
417 | * This method is not meant to be called directly. Use
|
418 | * DB_result::free() instead. It can't be declared "protected"
|
418 | * DB_result::free() instead. It can't be declared "protected"
|
419 | * because DB_result is a separate object.
|
419 | * because DB_result is a separate object.
|
420 | *
|
420 | *
|
421 | * @param resource $result PHP's query result resource
|
421 | * @param resource $result PHP's query result resource
|
422 | *
|
422 | *
|
423 | * @return bool TRUE on success, FALSE if $result is invalid
|
423 | * @return bool TRUE on success, FALSE if $result is invalid
|
424 | *
|
424 | *
|
425 | * @see DB_result::free()
|
425 | * @see DB_result::free()
|
426 | */
|
426 | */
|
427 | function freeResult($result) |
427 | function freeResult($result) |
428 | {
|
428 | {
|
429 | return is_resource($result) ? OCIFreeStatement($result) : false; |
429 | return is_resource($result) ? OCIFreeStatement($result) : false; |
430 | }
|
430 | }
|
431 | 431 | ||
432 | /**
|
432 | /**
|
433 | * Frees the internal resources associated with a prepared query
|
433 | * Frees the internal resources associated with a prepared query
|
434 | *
|
434 | *
|
435 | * @param resource $stmt the prepared statement's resource
|
435 | * @param resource $stmt the prepared statement's resource
|
436 | * @param bool $free_resource should the PHP resource be freed too?
|
436 | * @param bool $free_resource should the PHP resource be freed too?
|
437 | * Use false if you need to get data
|
437 | * Use false if you need to get data
|
438 | * from the result set later.
|
438 | * from the result set later.
|
439 | *
|
439 | *
|
440 | * @return bool TRUE on success, FALSE if $result is invalid
|
440 | * @return bool TRUE on success, FALSE if $result is invalid
|
441 | *
|
441 | *
|
442 | * @see DB_oci8::prepare()
|
442 | * @see DB_oci8::prepare()
|
443 | */
|
443 | */
|
444 | function freePrepared($stmt, $free_resource = true) |
444 | function freePrepared($stmt, $free_resource = true) |
445 | {
|
445 | {
|
446 | if (!is_resource($stmt)) { |
446 | if (!is_resource($stmt)) { |
447 | return false; |
447 | return false; |
448 | }
|
448 | }
|
449 | if ($free_resource) { |
449 | if ($free_resource) { |
450 | @ocifreestatement($stmt); |
450 | @ocifreestatement($stmt); |
451 | }
|
451 | }
|
452 | if (isset($this->prepare_types[(int)$stmt])) { |
452 | if (isset($this->prepare_types[(int)$stmt])) { |
453 | unset($this->prepare_types[(int)$stmt]); |
453 | unset($this->prepare_types[(int)$stmt]); |
454 | unset($this->manip_query[(int)$stmt]); |
454 | unset($this->manip_query[(int)$stmt]); |
455 | } else { |
455 | } else { |
456 | return false; |
456 | return false; |
457 | }
|
457 | }
|
458 | return true; |
458 | return true; |
459 | }
|
459 | }
|
460 | 460 | ||
461 | // }}}
|
461 | // }}}
|
462 | // {{{ numRows()
|
462 | // {{{ numRows()
|
463 | 463 | ||
464 | /**
|
464 | /**
|
465 | * Gets the number of rows in a result set
|
465 | * Gets the number of rows in a result set
|
466 | *
|
466 | *
|
467 | * Only works if the DB_PORTABILITY_NUMROWS portability option
|
467 | * Only works if the DB_PORTABILITY_NUMROWS portability option
|
468 | * is turned on.
|
468 | * is turned on.
|
469 | *
|
469 | *
|
470 | * This method is not meant to be called directly. Use
|
470 | * This method is not meant to be called directly. Use
|
471 | * DB_result::numRows() instead. It can't be declared "protected"
|
471 | * DB_result::numRows() instead. It can't be declared "protected"
|
472 | * because DB_result is a separate object.
|
472 | * because DB_result is a separate object.
|
473 | *
|
473 | *
|
474 | * @param resource $result PHP's query result resource
|
474 | * @param resource $result PHP's query result resource
|
475 | *
|
475 | *
|
476 | * @return int the number of rows. A DB_Error object on failure.
|
476 | * @return int the number of rows. A DB_Error object on failure.
|
477 | *
|
477 | *
|
478 | * @see DB_result::numRows(), DB_common::setOption()
|
478 | * @see DB_result::numRows(), DB_common::setOption()
|
479 | */
|
479 | */
|
480 | function numRows($result) |
480 | function numRows($result) |
481 | {
|
481 | {
|
482 | // emulate numRows for Oracle. yuck.
|
482 | // emulate numRows for Oracle. yuck.
|
483 | if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && |
483 | if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && |
484 | $result === $this->last_stmt) |
484 | $result === $this->last_stmt) |
485 | {
|
485 | {
|
486 | $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; |
486 | $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; |
487 | $save_query = $this->last_query; |
487 | $save_query = $this->last_query; |
488 | $save_stmt = $this->last_stmt; |
488 | $save_stmt = $this->last_stmt; |
489 | 489 | ||
490 | $count = $this->query($countquery); |
490 | $count = $this->query($countquery); |
491 | 491 | ||
492 | // Restore the last query and statement.
|
492 | // Restore the last query and statement.
|
493 | $this->last_query = $save_query; |
493 | $this->last_query = $save_query; |
494 | $this->last_stmt = $save_stmt; |
494 | $this->last_stmt = $save_stmt; |
495 | 495 | ||
496 | if (DB::isError($count) || |
496 | if (DB::isError($count) || |
497 | DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) |
497 | DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) |
498 | {
|
498 | {
|
499 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
499 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
500 | }
|
500 | }
|
501 | 501 | ||
502 | return $row[0]; |
502 | return $row[0]; |
503 | }
|
503 | }
|
504 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
504 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
505 | }
|
505 | }
|
506 | 506 | ||
507 | // }}}
|
507 | // }}}
|
508 | // {{{ numCols()
|
508 | // {{{ numCols()
|
509 | 509 | ||
510 | /**
|
510 | /**
|
511 | * Gets the number of columns in a result set
|
511 | * Gets the number of columns in a result set
|
512 | *
|
512 | *
|
513 | * This method is not meant to be called directly. Use
|
513 | * This method is not meant to be called directly. Use
|
514 | * DB_result::numCols() instead. It can't be declared "protected"
|
514 | * DB_result::numCols() instead. It can't be declared "protected"
|
515 | * because DB_result is a separate object.
|
515 | * because DB_result is a separate object.
|
516 | *
|
516 | *
|
517 | * @param resource $result PHP's query result resource
|
517 | * @param resource $result PHP's query result resource
|
518 | *
|
518 | *
|
519 | * @return int the number of columns. A DB_Error object on failure.
|
519 | * @return int the number of columns. A DB_Error object on failure.
|
520 | *
|
520 | *
|
521 | * @see DB_result::numCols()
|
521 | * @see DB_result::numCols()
|
522 | */
|
522 | */
|
523 | function numCols($result) |
523 | function numCols($result) |
524 | {
|
524 | {
|
525 | $cols = @OCINumCols($result); |
525 | $cols = @OCINumCols($result); |
526 | if (!$cols) { |
526 | if (!$cols) { |
527 | return $this->oci8RaiseError($result); |
527 | return $this->oci8RaiseError($result); |
528 | }
|
528 | }
|
529 | return $cols; |
529 | return $cols; |
530 | }
|
530 | }
|
531 | 531 | ||
532 | // }}}
|
532 | // }}}
|
533 | // {{{ prepare()
|
533 | // {{{ prepare()
|
534 | 534 | ||
535 | /**
|
535 | /**
|
536 | * Prepares a query for multiple execution with execute().
|
536 | * Prepares a query for multiple execution with execute().
|
537 | *
|
537 | *
|
538 | * With oci8, this is emulated.
|
538 | * With oci8, this is emulated.
|
539 | *
|
539 | *
|
540 | * prepare() requires a generic query as string like <code>
|
540 | * prepare() requires a generic query as string like <code>
|
541 | * INSERT INTO numbers VALUES (?, ?, ?)
|
541 | * INSERT INTO numbers VALUES (?, ?, ?)
|
542 | * </code>. The <kbd>?</kbd> characters are placeholders.
|
542 | * </code>. The <kbd>?</kbd> characters are placeholders.
|
543 | *
|
543 | *
|
544 | * Three types of placeholders can be used:
|
544 | * Three types of placeholders can be used:
|
545 | * + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
|
545 | * + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
|
546 | * + <kbd>!</kbd> value is inserted 'as is'
|
546 | * + <kbd>!</kbd> value is inserted 'as is'
|
547 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
547 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
548 | * inserted into the query (i.e. saving binary
|
548 | * inserted into the query (i.e. saving binary
|
549 | * data in a db)
|
549 | * data in a db)
|
550 | *
|
550 | *
|
551 | * Use backslashes to escape placeholder characters if you don't want
|
551 | * Use backslashes to escape placeholder characters if you don't want
|
552 | * them to be interpreted as placeholders. Example: <code>
|
552 | * them to be interpreted as placeholders. Example: <code>
|
553 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
553 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
554 | * </code>
|
554 | * </code>
|
555 | *
|
555 | *
|
556 | * @param string $query the query to be prepared
|
556 | * @param string $query the query to be prepared
|
557 | *
|
557 | *
|
558 | * @return mixed DB statement resource on success. DB_Error on failure.
|
558 | * @return mixed DB statement resource on success. DB_Error on failure.
|
559 | *
|
559 | *
|
560 | * @see DB_oci8::execute()
|
560 | * @see DB_oci8::execute()
|
561 | */
|
561 | */
|
562 | function prepare($query) |
562 | function prepare($query) |
563 | {
|
563 | {
|
564 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
564 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
565 | PREG_SPLIT_DELIM_CAPTURE); |
565 | PREG_SPLIT_DELIM_CAPTURE); |
566 | $binds = count($tokens) - 1; |
566 | $binds = count($tokens) - 1; |
567 | $token = 0; |
567 | $token = 0; |
568 | $types = array(); |
568 | $types = array(); |
569 | $newquery = ''; |
569 | $newquery = ''; |
570 | 570 | ||
571 | foreach ($tokens as $key => $val) { |
571 | foreach ($tokens as $key => $val) { |
572 | switch ($val) { |
572 | switch ($val) { |
573 | case '?': |
573 | case '?': |
574 | $types[$token++] = DB_PARAM_SCALAR; |
574 | $types[$token++] = DB_PARAM_SCALAR; |
575 | unset($tokens[$key]); |
575 | unset($tokens[$key]); |
576 | break; |
576 | break; |
577 | case '&': |
577 | case '&': |
578 | $types[$token++] = DB_PARAM_OPAQUE; |
578 | $types[$token++] = DB_PARAM_OPAQUE; |
579 | unset($tokens[$key]); |
579 | unset($tokens[$key]); |
580 | break; |
580 | break; |
581 | case '!': |
581 | case '!': |
582 | $types[$token++] = DB_PARAM_MISC; |
582 | $types[$token++] = DB_PARAM_MISC; |
583 | unset($tokens[$key]); |
583 | unset($tokens[$key]); |
584 | break; |
584 | break; |
585 | default: |
585 | default: |
586 | $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
586 | $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
587 | if ($key != $binds) { |
587 | if ($key != $binds) { |
588 | $newquery .= $tokens[$key] . ':bind' . $token; |
588 | $newquery .= $tokens[$key] . ':bind' . $token; |
589 | } else { |
589 | } else { |
590 | $newquery .= $tokens[$key]; |
590 | $newquery .= $tokens[$key]; |
591 | }
|
591 | }
|
592 | }
|
592 | }
|
593 | }
|
593 | }
|
594 | 594 | ||
595 | $this->last_query = $query; |
595 | $this->last_query = $query; |
596 | $newquery = $this->modifyQuery($newquery); |
596 | $newquery = $this->modifyQuery($newquery); |
597 | if (!$stmt = @OCIParse($this->connection, $newquery)) { |
597 | if (!$stmt = @OCIParse($this->connection, $newquery)) { |
598 | return $this->oci8RaiseError(); |
598 | return $this->oci8RaiseError(); |
599 | }
|
599 | }
|
600 | $this->prepare_types[(int)$stmt] = $types; |
600 | $this->prepare_types[(int)$stmt] = $types; |
601 | $this->manip_query[(int)$stmt] = DB::isManip($query); |
601 | $this->manip_query[(int)$stmt] = DB::isManip($query); |
602 | $this->_prepared_queries[(int)$stmt] = $newquery; |
602 | $this->_prepared_queries[(int)$stmt] = $newquery; |
603 | return $stmt; |
603 | return $stmt; |
604 | }
|
604 | }
|
605 | 605 | ||
606 | // }}}
|
606 | // }}}
|
607 | // {{{ execute()
|
607 | // {{{ execute()
|
608 | 608 | ||
609 | /**
|
609 | /**
|
610 | * Executes a DB statement prepared with prepare().
|
610 | * Executes a DB statement prepared with prepare().
|
611 | *
|
611 | *
|
612 | * To determine how many rows of a result set get buffered using
|
612 | * To determine how many rows of a result set get buffered using
|
613 | * ocisetprefetch(), see the "result_buffering" option in setOptions().
|
613 | * ocisetprefetch(), see the "result_buffering" option in setOptions().
|
614 | * This option was added in Release 1.7.0.
|
614 | * This option was added in Release 1.7.0.
|
615 | *
|
615 | *
|
616 | * @param resource $stmt a DB statement resource returned from prepare()
|
616 | * @param resource $stmt a DB statement resource returned from prepare()
|
617 | * @param mixed $data array, string or numeric data to be used in
|
617 | * @param mixed $data array, string or numeric data to be used in
|
618 | * execution of the statement. Quantity of items
|
618 | * execution of the statement. Quantity of items
|
619 | * passed must match quantity of placeholders in
|
619 | * passed must match quantity of placeholders in
|
620 | * query: meaning 1 for non-array items or the
|
620 | * query: meaning 1 for non-array items or the
|
621 | * quantity of elements in the array.
|
621 | * quantity of elements in the array.
|
622 | *
|
622 | *
|
623 | * @return mixed returns an oic8 result resource for successful SELECT
|
623 | * @return mixed returns an oic8 result resource for successful SELECT
|
624 | * queries, DB_OK for other successful queries.
|
624 | * queries, DB_OK for other successful queries.
|
625 | * A DB error object is returned on failure.
|
625 | * A DB error object is returned on failure.
|
626 | *
|
626 | *
|
627 | * @see DB_oci8::prepare()
|
627 | * @see DB_oci8::prepare()
|
628 | */
|
628 | */
|
629 | function &execute($stmt, $data = array()) |
629 | function &execute($stmt, $data = array()) |
630 | {
|
630 | {
|
631 | $data = (array)$data; |
631 | $data = (array)$data; |
632 | $this->last_parameters = $data; |
632 | $this->last_parameters = $data; |
633 | $this->last_query = $this->_prepared_queries[(int)$stmt]; |
633 | $this->last_query = $this->_prepared_queries[(int)$stmt]; |
634 | $this->_data = $data; |
634 | $this->_data = $data; |
635 | 635 | ||
636 | $types = $this->prepare_types[(int)$stmt]; |
636 | $types = $this->prepare_types[(int)$stmt]; |
637 | if (count($types) != count($data)) { |
637 | if (count($types) != count($data)) { |
638 | $tmp = $this->raiseError(DB_ERROR_MISMATCH); |
638 | $tmp = $this->raiseError(DB_ERROR_MISMATCH); |
639 | return $tmp; |
639 | return $tmp; |
640 | }
|
640 | }
|
641 | 641 | ||
642 | $i = 0; |
642 | $i = 0; |
643 | foreach ($data as $key => $value) { |
643 | foreach ($data as $key => $value) { |
644 | if ($types[$i] == DB_PARAM_MISC) { |
644 | if ($types[$i] == DB_PARAM_MISC) { |
645 | /*
|
645 | /*
|
646 | * Oracle doesn't seem to have the ability to pass a
|
646 | * Oracle doesn't seem to have the ability to pass a
|
647 | * parameter along unchanged, so strip off quotes from start
|
647 | * parameter along unchanged, so strip off quotes from start
|
648 | * and end, plus turn two single quotes to one single quote,
|
648 | * and end, plus turn two single quotes to one single quote,
|
649 | * in order to avoid the quotes getting escaped by
|
649 | * in order to avoid the quotes getting escaped by
|
650 | * Oracle and ending up in the database.
|
650 | * Oracle and ending up in the database.
|
651 | */
|
651 | */
|
652 | $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
652 | $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
653 | $data[$key] = str_replace("''", "'", $data[$key]); |
653 | $data[$key] = str_replace("''", "'", $data[$key]); |
654 | } elseif ($types[$i] == DB_PARAM_OPAQUE) { |
654 | } elseif ($types[$i] == DB_PARAM_OPAQUE) { |
655 | $fp = @fopen($data[$key], 'rb'); |
655 | $fp = @fopen($data[$key], 'rb'); |
656 | if (!$fp) { |
656 | if (!$fp) { |
657 | $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
657 | $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
658 | return $tmp; |
658 | return $tmp; |
659 | }
|
659 | }
|
660 | $data[$key] = fread($fp, filesize($data[$key])); |
660 | $data[$key] = fread($fp, filesize($data[$key])); |
661 | fclose($fp); |
661 | fclose($fp); |
662 | } elseif ($types[$i] == DB_PARAM_SCALAR) { |
662 | } elseif ($types[$i] == DB_PARAM_SCALAR) { |
663 | // Floats have to be converted to a locale-neutral
|
663 | // Floats have to be converted to a locale-neutral
|
664 | // representation.
|
664 | // representation.
|
665 | if (is_float($data[$key])) { |
665 | if (is_float($data[$key])) { |
666 | $data[$key] = $this->quoteFloat($data[$key]); |
666 | $data[$key] = $this->quoteFloat($data[$key]); |
667 | }
|
667 | }
|
668 | }
|
668 | }
|
669 | if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { |
669 | if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { |
670 | $tmp = $this->oci8RaiseError($stmt); |
670 | $tmp = $this->oci8RaiseError($stmt); |
671 | return $tmp; |
671 | return $tmp; |
672 | }
|
672 | }
|
673 | $this->last_query = str_replace(':bind'.$i, $this->quoteSmart($data[$key]), $this->last_query); |
673 | $this->last_query = str_replace(':bind'.$i, $this->quoteSmart($data[$key]), $this->last_query); |
674 | $i++; |
674 | $i++; |
675 | }
|
675 | }
|
676 | if ($this->autocommit) { |
676 | if ($this->autocommit) { |
677 | $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); |
677 | $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); |
678 | } else { |
678 | } else { |
679 | $success = @OCIExecute($stmt, OCI_DEFAULT); |
679 | $success = @OCIExecute($stmt, OCI_DEFAULT); |
680 | }
|
680 | }
|
681 | if (!$success) { |
681 | if (!$success) { |
682 | $tmp = $this->oci8RaiseError($stmt); |
682 | $tmp = $this->oci8RaiseError($stmt); |
683 | return $tmp; |
683 | return $tmp; |
684 | }
|
684 | }
|
685 | $this->last_stmt = $stmt; |
685 | $this->last_stmt = $stmt; |
686 | if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
686 | if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
687 | $this->_last_query_manip = true; |
687 | $this->_last_query_manip = true; |
688 | $this->_next_query_manip = false; |
688 | $this->_next_query_manip = false; |
689 | $tmp = DB_OK; |
689 | $tmp = DB_OK; |
690 | } else { |
690 | } else { |
691 | $this->_last_query_manip = false; |
691 | $this->_last_query_manip = false; |
692 | @ocisetprefetch($stmt, $this->options['result_buffering']); |
692 | @ocisetprefetch($stmt, $this->options['result_buffering']); |
693 | $tmp = new DB_result($this, $stmt); |
693 | $tmp = new DB_result($this, $stmt); |
694 | }
|
694 | }
|
695 | return $tmp; |
695 | return $tmp; |
696 | }
|
696 | }
|
697 | 697 | ||
698 | // }}}
|
698 | // }}}
|
699 | // {{{ autoCommit()
|
699 | // {{{ autoCommit()
|
700 | 700 | ||
701 | /**
|
701 | /**
|
702 | * Enables or disables automatic commits
|
702 | * Enables or disables automatic commits
|
703 | *
|
703 | *
|
704 | * @param bool $onoff true turns it on, false turns it off
|
704 | * @param bool $onoff true turns it on, false turns it off
|
705 | *
|
705 | *
|
706 | * @return int DB_OK on success. A DB_Error object if the driver
|
706 | * @return int DB_OK on success. A DB_Error object if the driver
|
707 | * doesn't support auto-committing transactions.
|
707 | * doesn't support auto-committing transactions.
|
708 | */
|
708 | */
|
709 | function autoCommit($onoff = false) |
709 | function autoCommit($onoff = false) |
710 | {
|
710 | {
|
711 | $this->autocommit = (bool)$onoff;; |
711 | $this->autocommit = (bool)$onoff;; |
712 | return DB_OK; |
712 | return DB_OK; |
713 | }
|
713 | }
|
714 | 714 | ||
715 | // }}}
|
715 | // }}}
|
716 | // {{{ commit()
|
716 | // {{{ commit()
|
717 | 717 | ||
718 | /**
|
718 | /**
|
719 | * Commits the current transaction
|
719 | * Commits the current transaction
|
720 | *
|
720 | *
|
721 | * @return int DB_OK on success. A DB_Error object on failure.
|
721 | * @return int DB_OK on success. A DB_Error object on failure.
|
722 | */
|
722 | */
|
723 | function commit() |
723 | function commit() |
724 | {
|
724 | {
|
725 | $result = @OCICommit($this->connection); |
725 | $result = @OCICommit($this->connection); |
726 | if (!$result) { |
726 | if (!$result) { |
727 | return $this->oci8RaiseError(); |
727 | return $this->oci8RaiseError(); |
728 | }
|
728 | }
|
729 | return DB_OK; |
729 | return DB_OK; |
730 | }
|
730 | }
|
731 | 731 | ||
732 | // }}}
|
732 | // }}}
|
733 | // {{{ rollback()
|
733 | // {{{ rollback()
|
734 | 734 | ||
735 | /**
|
735 | /**
|
736 | * Reverts the current transaction
|
736 | * Reverts the current transaction
|
737 | *
|
737 | *
|
738 | * @return int DB_OK on success. A DB_Error object on failure.
|
738 | * @return int DB_OK on success. A DB_Error object on failure.
|
739 | */
|
739 | */
|
740 | function rollback() |
740 | function rollback() |
741 | {
|
741 | {
|
742 | $result = @OCIRollback($this->connection); |
742 | $result = @OCIRollback($this->connection); |
743 | if (!$result) { |
743 | if (!$result) { |
744 | return $this->oci8RaiseError(); |
744 | return $this->oci8RaiseError(); |
745 | }
|
745 | }
|
746 | return DB_OK; |
746 | return DB_OK; |
747 | }
|
747 | }
|
748 | 748 | ||
749 | // }}}
|
749 | // }}}
|
750 | // {{{ affectedRows()
|
750 | // {{{ affectedRows()
|
751 | 751 | ||
752 | /**
|
752 | /**
|
753 | * Determines the number of rows affected by a data maniuplation query
|
753 | * Determines the number of rows affected by a data maniuplation query
|
754 | *
|
754 | *
|
755 | * 0 is returned for queries that don't manipulate data.
|
755 | * 0 is returned for queries that don't manipulate data.
|
756 | *
|
756 | *
|
757 | * @return int the number of rows. A DB_Error object on failure.
|
757 | * @return int the number of rows. A DB_Error object on failure.
|
758 | */
|
758 | */
|
759 | function affectedRows() |
759 | function affectedRows() |
760 | {
|
760 | {
|
761 | if ($this->last_stmt === false) { |
761 | if ($this->last_stmt === false) { |
762 | return $this->oci8RaiseError(); |
762 | return $this->oci8RaiseError(); |
763 | }
|
763 | }
|
764 | $result = @OCIRowCount($this->last_stmt); |
764 | $result = @OCIRowCount($this->last_stmt); |
765 | if ($result === false) { |
765 | if ($result === false) { |
766 | return $this->oci8RaiseError($this->last_stmt); |
766 | return $this->oci8RaiseError($this->last_stmt); |
767 | }
|
767 | }
|
768 | return $result; |
768 | return $result; |
769 | }
|
769 | }
|
770 | 770 | ||
771 | // }}}
|
771 | // }}}
|
772 | // {{{ modifyQuery()
|
772 | // {{{ modifyQuery()
|
773 | 773 | ||
774 | /**
|
774 | /**
|
775 | * Changes a query string for various DBMS specific reasons
|
775 | * Changes a query string for various DBMS specific reasons
|
776 | *
|
776 | *
|
777 | * "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
|
777 | * "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
|
778 | *
|
778 | *
|
779 | * @param string $query the query string to modify
|
779 | * @param string $query the query string to modify
|
780 | *
|
780 | *
|
781 | * @return string the modified query string
|
781 | * @return string the modified query string
|
782 | *
|
782 | *
|
783 | * @access protected
|
783 | * @access protected
|
784 | */
|
784 | */
|
785 | function modifyQuery($query) |
785 | function modifyQuery($query) |
786 | {
|
786 | {
|
787 | if (preg_match('/^\s*SELECT/i', $query) && |
787 | if (preg_match('/^\s*SELECT/i', $query) && |
788 | !preg_match('/\sFROM\s/i', $query)) { |
788 | !preg_match('/\sFROM\s/i', $query)) { |
789 | $query .= ' FROM dual'; |
789 | $query .= ' FROM dual'; |
790 | }
|
790 | }
|
791 | return $query; |
791 | return $query; |
792 | }
|
792 | }
|
793 | 793 | ||
794 | // }}}
|
794 | // }}}
|
795 | // {{{ modifyLimitQuery()
|
795 | // {{{ modifyLimitQuery()
|
796 | 796 | ||
797 | /**
|
797 | /**
|
798 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
798 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
799 | *
|
799 | *
|
800 | * @param string $query the query to modify
|
800 | * @param string $query the query to modify
|
801 | * @param int $from the row to start to fetching (0 = the first row)
|
801 | * @param int $from the row to start to fetching (0 = the first row)
|
802 | * @param int $count the numbers of rows to fetch
|
802 | * @param int $count the numbers of rows to fetch
|
803 | * @param mixed $params array, string or numeric data to be used in
|
803 | * @param mixed $params array, string or numeric data to be used in
|
804 | * execution of the statement. Quantity of items
|
804 | * execution of the statement. Quantity of items
|
805 | * passed must match quantity of placeholders in
|
805 | * passed must match quantity of placeholders in
|
806 | * query: meaning 1 placeholder for non-array
|
806 | * query: meaning 1 placeholder for non-array
|
807 | * parameters or 1 placeholder per array element.
|
807 | * parameters or 1 placeholder per array element.
|
808 | *
|
808 | *
|
809 | * @return string the query string with LIMIT clauses added
|
809 | * @return string the query string with LIMIT clauses added
|
810 | *
|
810 | *
|
811 | * @access protected
|
811 | * @access protected
|
812 | */
|
812 | */
|
813 | function modifyLimitQuery($query, $from, $count, $params = array()) |
813 | function modifyLimitQuery($query, $from, $count, $params = array()) |
814 | {
|
814 | {
|
815 | // Let Oracle return the name of the columns instead of
|
815 | // Let Oracle return the name of the columns instead of
|
816 | // coding a "home" SQL parser
|
816 | // coding a "home" SQL parser
|
817 | 817 | ||
818 | if (count($params)) { |
818 | if (count($params)) { |
819 | $result = $this->prepare("SELECT * FROM ($query) " |
819 | $result = $this->prepare("SELECT * FROM ($query) " |
820 | . 'WHERE NULL = NULL'); |
820 | . 'WHERE NULL = NULL'); |
821 | $tmp = $this->execute($result, $params); |
821 | $tmp = $this->execute($result, $params); |
822 | } else { |
822 | } else { |
823 | $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; |
823 | $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; |
824 | 824 | ||
825 | if (!$result = @OCIParse($this->connection, $q_fields)) { |
825 | if (!$result = @OCIParse($this->connection, $q_fields)) { |
826 | $this->last_query = $q_fields; |
826 | $this->last_query = $q_fields; |
827 | return $this->oci8RaiseError(); |
827 | return $this->oci8RaiseError(); |
828 | }
|
828 | }
|
829 | if (!@OCIExecute($result, OCI_DEFAULT)) { |
829 | if (!@OCIExecute($result, OCI_DEFAULT)) { |
830 | $this->last_query = $q_fields; |
830 | $this->last_query = $q_fields; |
831 | return $this->oci8RaiseError($result); |
831 | return $this->oci8RaiseError($result); |
832 | }
|
832 | }
|
833 | }
|
833 | }
|
834 | 834 | ||
835 | $ncols = OCINumCols($result); |
835 | $ncols = OCINumCols($result); |
836 | $cols = array(); |
836 | $cols = array(); |
837 | for ( $i = 1; $i <= $ncols; $i++ ) { |
837 | for ( $i = 1; $i <= $ncols; $i++ ) { |
838 | $cols[] = '"' . OCIColumnName($result, $i) . '"'; |
838 | $cols[] = '"' . OCIColumnName($result, $i) . '"'; |
839 | }
|
839 | }
|
840 | $fields = implode(', ', $cols); |
840 | $fields = implode(', ', $cols); |
841 | // XXX Test that (tip by John Lim)
|
841 | // XXX Test that (tip by John Lim)
|
842 | //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
|
842 | //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
|
843 | // // Introduce the FIRST_ROWS Oracle query optimizer
|
843 | // // Introduce the FIRST_ROWS Oracle query optimizer
|
844 | // $query = substr($query, strlen($match[0]), strlen($query));
|
844 | // $query = substr($query, strlen($match[0]), strlen($query));
|
845 | // $query = "SELECT /* +FIRST_ROWS */ " . $query;
|
845 | // $query = "SELECT /* +FIRST_ROWS */ " . $query;
|
846 | //}
|
846 | //}
|
847 | 847 | ||
848 | // Construct the query
|
848 | // Construct the query
|
849 | // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
|
849 | // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
|
850 | // Perhaps this could be optimized with the use of Unions
|
850 | // Perhaps this could be optimized with the use of Unions
|
851 | $query = "SELECT $fields FROM". |
851 | $query = "SELECT $fields FROM". |
852 | " (SELECT rownum as linenum, $fields FROM". |
852 | " (SELECT rownum as linenum, $fields FROM". |
853 | " ($query)". |
853 | " ($query)". |
854 | ' WHERE rownum <= '. ($from + $count) . |
854 | ' WHERE rownum <= '. ($from + $count) . |
855 | ') WHERE linenum >= ' . ++$from; |
855 | ') WHERE linenum >= ' . ++$from; |
856 | return $query; |
856 | return $query; |
857 | }
|
857 | }
|
858 | 858 | ||
859 | // }}}
|
859 | // }}}
|
860 | // {{{ nextId()
|
860 | // {{{ nextId()
|
861 | 861 | ||
862 | /**
|
862 | /**
|
863 | * Returns the next free id in a sequence
|
863 | * Returns the next free id in a sequence
|
864 | *
|
864 | *
|
865 | * @param string $seq_name name of the sequence
|
865 | * @param string $seq_name name of the sequence
|
866 | * @param boolean $ondemand when true, the seqence is automatically
|
866 | * @param boolean $ondemand when true, the seqence is automatically
|
867 | * created if it does not exist
|
867 | * created if it does not exist
|
868 | *
|
868 | *
|
869 | * @return int the next id number in the sequence.
|
869 | * @return int the next id number in the sequence.
|
870 | * A DB_Error object on failure.
|
870 | * A DB_Error object on failure.
|
871 | *
|
871 | *
|
872 | * @see DB_common::nextID(), DB_common::getSequenceName(),
|
872 | * @see DB_common::nextID(), DB_common::getSequenceName(),
|
873 | * DB_oci8::createSequence(), DB_oci8::dropSequence()
|
873 | * DB_oci8::createSequence(), DB_oci8::dropSequence()
|
874 | */
|
874 | */
|
875 | function nextId($seq_name, $ondemand = true) |
875 | function nextId($seq_name, $ondemand = true) |
876 | {
|
876 | {
|
877 | $seqname = $this->getSequenceName($seq_name); |
877 | $seqname = $this->getSequenceName($seq_name); |
878 | $repeat = 0; |
878 | $repeat = 0; |
879 | do { |
879 | do { |
880 | $this->expectError(DB_ERROR_NOSUCHTABLE); |
880 | $this->expectError(DB_ERROR_NOSUCHTABLE); |
881 | $result = $this->query("SELECT ${seqname}.nextval FROM dual"); |
881 | $result = $this->query("SELECT ${seqname}.nextval FROM dual"); |
882 | $this->popExpect(); |
882 | $this->popExpect(); |
883 | if ($ondemand && DB::isError($result) && |
883 | if ($ondemand && DB::isError($result) && |
884 | $result->getCode() == DB_ERROR_NOSUCHTABLE) { |
884 | $result->getCode() == DB_ERROR_NOSUCHTABLE) { |
885 | $repeat = 1; |
885 | $repeat = 1; |
886 | $result = $this->createSequence($seq_name); |
886 | $result = $this->createSequence($seq_name); |
887 | if (DB::isError($result)) { |
887 | if (DB::isError($result)) { |
888 | return $this->raiseError($result); |
888 | return $this->raiseError($result); |
889 | }
|
889 | }
|
890 | } else { |
890 | } else { |
891 | $repeat = 0; |
891 | $repeat = 0; |
892 | }
|
892 | }
|
893 | } while ($repeat); |
893 | } while ($repeat); |
894 | if (DB::isError($result)) { |
894 | if (DB::isError($result)) { |
895 | return $this->raiseError($result); |
895 | return $this->raiseError($result); |
896 | }
|
896 | }
|
897 | $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
897 | $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
898 | return $arr[0]; |
898 | return $arr[0]; |
899 | }
|
899 | }
|
900 | 900 | ||
901 | /**
|
901 | /**
|
902 | * Creates a new sequence
|
902 | * Creates a new sequence
|
903 | *
|
903 | *
|
904 | * @param string $seq_name name of the new sequence
|
904 | * @param string $seq_name name of the new sequence
|
905 | *
|
905 | *
|
906 | * @return int DB_OK on success. A DB_Error object on failure.
|
906 | * @return int DB_OK on success. A DB_Error object on failure.
|
907 | *
|
907 | *
|
908 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
908 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
909 | * DB_oci8::nextID(), DB_oci8::dropSequence()
|
909 | * DB_oci8::nextID(), DB_oci8::dropSequence()
|
910 | */
|
910 | */
|
911 | function createSequence($seq_name) |
911 | function createSequence($seq_name) |
912 | {
|
912 | {
|
913 | return $this->query('CREATE SEQUENCE ' |
913 | return $this->query('CREATE SEQUENCE ' |
914 | . $this->getSequenceName($seq_name)); |
914 | . $this->getSequenceName($seq_name)); |
915 | }
|
915 | }
|
916 | 916 | ||
917 | // }}}
|
917 | // }}}
|
918 | // {{{ dropSequence()
|
918 | // {{{ dropSequence()
|
919 | 919 | ||
920 | /**
|
920 | /**
|
921 | * Deletes a sequence
|
921 | * Deletes a sequence
|
922 | *
|
922 | *
|
923 | * @param string $seq_name name of the sequence to be deleted
|
923 | * @param string $seq_name name of the sequence to be deleted
|
924 | *
|
924 | *
|
925 | * @return int DB_OK on success. A DB_Error object on failure.
|
925 | * @return int DB_OK on success. A DB_Error object on failure.
|
926 | *
|
926 | *
|
927 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
927 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
928 | * DB_oci8::nextID(), DB_oci8::createSequence()
|
928 | * DB_oci8::nextID(), DB_oci8::createSequence()
|
929 | */
|
929 | */
|
930 | function dropSequence($seq_name) |
930 | function dropSequence($seq_name) |
931 | {
|
931 | {
|
932 | return $this->query('DROP SEQUENCE ' |
932 | return $this->query('DROP SEQUENCE ' |
933 | . $this->getSequenceName($seq_name)); |
933 | . $this->getSequenceName($seq_name)); |
934 | }
|
934 | }
|
935 | 935 | ||
936 | // }}}
|
936 | // }}}
|
937 | // {{{ oci8RaiseError()
|
937 | // {{{ oci8RaiseError()
|
938 | 938 | ||
939 | /**
|
939 | /**
|
940 | * Produces a DB_Error object regarding the current problem
|
940 | * Produces a DB_Error object regarding the current problem
|
941 | *
|
941 | *
|
942 | * @param int $errno if the error is being manually raised pass a
|
942 | * @param int $errno if the error is being manually raised pass a
|
943 | * DB_ERROR* constant here. If this isn't passed
|
943 | * DB_ERROR* constant here. If this isn't passed
|
944 | * the error information gathered from the DBMS.
|
944 | * the error information gathered from the DBMS.
|
945 | *
|
945 | *
|
946 | * @return object the DB_Error object
|
946 | * @return object the DB_Error object
|
947 | *
|
947 | *
|
948 | * @see DB_common::raiseError(),
|
948 | * @see DB_common::raiseError(),
|
949 | * DB_oci8::errorNative(), DB_oci8::errorCode()
|
949 | * DB_oci8::errorNative(), DB_oci8::errorCode()
|
950 | */
|
950 | */
|
951 | function oci8RaiseError($errno = null) |
951 | function oci8RaiseError($errno = null) |
952 | {
|
952 | {
|
953 | if ($errno === null) { |
953 | if ($errno === null) { |
954 | $error = @OCIError($this->connection); |
954 | $error = @OCIError($this->connection); |
955 | return $this->raiseError($this->errorCode($error['code']), |
955 | return $this->raiseError($this->errorCode($error['code']), |
956 | null, null, null, $error['message']); |
956 | null, null, null, $error['message']); |
957 | } elseif (is_resource($errno)) { |
957 | } elseif (is_resource($errno)) { |
958 | $error = @OCIError($errno); |
958 | $error = @OCIError($errno); |
959 | return $this->raiseError($this->errorCode($error['code']), |
959 | return $this->raiseError($this->errorCode($error['code']), |
960 | null, null, null, $error['message']); |
960 | null, null, null, $error['message']); |
961 | }
|
961 | }
|
962 | return $this->raiseError($this->errorCode($errno)); |
962 | return $this->raiseError($this->errorCode($errno)); |
963 | }
|
963 | }
|
964 | 964 | ||
965 | // }}}
|
965 | // }}}
|
966 | // {{{ errorNative()
|
966 | // {{{ errorNative()
|
967 | 967 | ||
968 | /**
|
968 | /**
|
969 | * Gets the DBMS' native error code produced by the last query
|
969 | * Gets the DBMS' native error code produced by the last query
|
970 | *
|
970 | *
|
971 | * @return int the DBMS' error code. FALSE if the code could not be
|
971 | * @return int the DBMS' error code. FALSE if the code could not be
|
972 | * determined
|
972 | * determined
|
973 | */
|
973 | */
|
974 | function errorNative() |
974 | function errorNative() |
975 | {
|
975 | {
|
976 | if (is_resource($this->last_stmt)) { |
976 | if (is_resource($this->last_stmt)) { |
977 | $error = @OCIError($this->last_stmt); |
977 | $error = @OCIError($this->last_stmt); |
978 | } else { |
978 | } else { |
979 | $error = @OCIError($this->connection); |
979 | $error = @OCIError($this->connection); |
980 | }
|
980 | }
|
981 | if (is_array($error)) { |
981 | if (is_array($error)) { |
982 | return $error['code']; |
982 | return $error['code']; |
983 | }
|
983 | }
|
984 | return false; |
984 | return false; |
985 | }
|
985 | }
|
986 | 986 | ||
987 | // }}}
|
987 | // }}}
|
988 | // {{{ tableInfo()
|
988 | // {{{ tableInfo()
|
989 | 989 | ||
990 | /**
|
990 | /**
|
991 | * Returns information about a table or a result set
|
991 | * Returns information about a table or a result set
|
992 | *
|
992 | *
|
993 | * NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
993 | * NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
994 | * is a table name.
|
994 | * is a table name.
|
995 | *
|
995 | *
|
996 | * NOTE: flags won't contain index information.
|
996 | * NOTE: flags won't contain index information.
|
997 | *
|
997 | *
|
998 | * @param object|string $result DB_result object from a query or a
|
998 | * @param object|string $result DB_result object from a query or a
|
999 | * string containing the name of a table.
|
999 | * string containing the name of a table.
|
1000 | * While this also accepts a query result
|
1000 | * While this also accepts a query result
|
1001 | * resource identifier, this behavior is
|
1001 | * resource identifier, this behavior is
|
1002 | * deprecated.
|
1002 | * deprecated.
|
1003 | * @param int $mode a valid tableInfo mode
|
1003 | * @param int $mode a valid tableInfo mode
|
1004 | *
|
1004 | *
|
1005 | * @return array an associative array with the information requested.
|
1005 | * @return array an associative array with the information requested.
|
1006 | * A DB_Error object on failure.
|
1006 | * A DB_Error object on failure.
|
1007 | *
|
1007 | *
|
1008 | * @see DB_common::tableInfo()
|
1008 | * @see DB_common::tableInfo()
|
1009 | */
|
1009 | */
|
1010 | function tableInfo($result, $mode = null) |
1010 | function tableInfo($result, $mode = null) |
1011 | {
|
1011 | {
|
1012 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
1012 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
1013 | $case_func = 'strtolower'; |
1013 | $case_func = 'strtolower'; |
1014 | } else { |
1014 | } else { |
1015 | $case_func = 'strval'; |
1015 | $case_func = 'strval'; |
1016 | }
|
1016 | }
|
1017 | 1017 | ||
1018 | $res = array(); |
1018 | $res = array(); |
1019 | 1019 | ||
1020 | if (is_string($result)) { |
1020 | if (is_string($result)) { |
1021 | /*
|
1021 | /*
|
1022 | * Probably received a table name.
|
1022 | * Probably received a table name.
|
1023 | * Create a result resource identifier.
|
1023 | * Create a result resource identifier.
|
1024 | */
|
1024 | */
|
1025 | $result = strtoupper($result); |
1025 | $result = strtoupper($result); |
1026 | $q_fields = 'SELECT column_name, data_type, data_length, ' |
1026 | $q_fields = 'SELECT column_name, data_type, data_length, ' |
1027 | . 'nullable ' |
1027 | . 'nullable ' |
1028 | . 'FROM user_tab_columns ' |
1028 | . 'FROM user_tab_columns ' |
1029 | . "WHERE table_name='$result' ORDER BY column_id"; |
1029 | . "WHERE table_name='$result' ORDER BY column_id"; |
1030 | 1030 | ||
1031 | $this->last_query = $q_fields; |
1031 | $this->last_query = $q_fields; |
1032 | 1032 | ||
1033 | if (!$stmt = @OCIParse($this->connection, $q_fields)) { |
1033 | if (!$stmt = @OCIParse($this->connection, $q_fields)) { |
1034 | return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); |
1034 | return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); |
1035 | }
|
1035 | }
|
1036 | if (!@OCIExecute($stmt, OCI_DEFAULT)) { |
1036 | if (!@OCIExecute($stmt, OCI_DEFAULT)) { |
1037 | return $this->oci8RaiseError($stmt); |
1037 | return $this->oci8RaiseError($stmt); |
1038 | }
|
1038 | }
|
1039 | 1039 | ||
1040 | $i = 0; |
1040 | $i = 0; |
1041 | while (@OCIFetch($stmt)) { |
1041 | while (@OCIFetch($stmt)) { |
1042 | $res[$i] = array( |
1042 | $res[$i] = array( |
1043 | 'table' => $case_func($result), |
1043 | 'table' => $case_func($result), |
1044 | 'name' => $case_func(@OCIResult($stmt, 1)), |
1044 | 'name' => $case_func(@OCIResult($stmt, 1)), |
1045 | 'type' => @OCIResult($stmt, 2), |
1045 | 'type' => @OCIResult($stmt, 2), |
1046 | 'len' => @OCIResult($stmt, 3), |
1046 | 'len' => @OCIResult($stmt, 3), |
1047 | 'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '', |
1047 | 'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '', |
1048 | ); |
1048 | ); |
1049 | if ($mode & DB_TABLEINFO_ORDER) { |
1049 | if ($mode & DB_TABLEINFO_ORDER) { |
1050 | $res['order'][$res[$i]['name']] = $i; |
1050 | $res['order'][$res[$i]['name']] = $i; |
1051 | }
|
1051 | }
|
1052 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1052 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1053 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1053 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1054 | }
|
1054 | }
|
1055 | $i++; |
1055 | $i++; |
1056 | }
|
1056 | }
|
1057 | 1057 | ||
1058 | if ($mode) { |
1058 | if ($mode) { |
1059 | $res['num_fields'] = $i; |
1059 | $res['num_fields'] = $i; |
1060 | }
|
1060 | }
|
1061 | @OCIFreeStatement($stmt); |
1061 | @OCIFreeStatement($stmt); |
1062 | 1062 | ||
1063 | } else { |
1063 | } else { |
1064 | if (isset($result->result)) { |
1064 | if (isset($result->result)) { |
1065 | /*
|
1065 | /*
|
1066 | * Probably received a result object.
|
1066 | * Probably received a result object.
|
1067 | * Extract the result resource identifier.
|
1067 | * Extract the result resource identifier.
|
1068 | */
|
1068 | */
|
1069 | $result = $result->result; |
1069 | $result = $result->result; |
1070 | }
|
1070 | }
|
1071 | 1071 | ||
1072 | $res = array(); |
1072 | $res = array(); |
1073 | 1073 | ||
1074 | if ($result === $this->last_stmt) { |
1074 | if ($result === $this->last_stmt) { |
1075 | $count = @OCINumCols($result); |
1075 | $count = @OCINumCols($result); |
1076 | if ($mode) { |
1076 | if ($mode) { |
1077 | $res['num_fields'] = $count; |
1077 | $res['num_fields'] = $count; |
1078 | }
|
1078 | }
|
1079 | for ($i = 0; $i < $count; $i++) { |
1079 | for ($i = 0; $i < $count; $i++) { |
1080 | $res[$i] = array( |
1080 | $res[$i] = array( |
1081 | 'table' => '', |
1081 | 'table' => '', |
1082 | 'name' => $case_func(@OCIColumnName($result, $i+1)), |
1082 | 'name' => $case_func(@OCIColumnName($result, $i+1)), |
1083 | 'type' => @OCIColumnType($result, $i+1), |
1083 | 'type' => @OCIColumnType($result, $i+1), |
1084 | 'len' => @OCIColumnSize($result, $i+1), |
1084 | 'len' => @OCIColumnSize($result, $i+1), |
1085 | 'flags' => '', |
1085 | 'flags' => '', |
1086 | ); |
1086 | ); |
1087 | if ($mode & DB_TABLEINFO_ORDER) { |
1087 | if ($mode & DB_TABLEINFO_ORDER) { |
1088 | $res['order'][$res[$i]['name']] = $i; |
1088 | $res['order'][$res[$i]['name']] = $i; |
1089 | }
|
1089 | }
|
1090 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1090 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1091 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1091 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1092 | }
|
1092 | }
|
1093 | }
|
1093 | }
|
1094 | } else { |
1094 | } else { |
1095 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1095 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1096 | }
|
1096 | }
|
1097 | }
|
1097 | }
|
1098 | return $res; |
1098 | return $res; |
1099 | }
|
1099 | }
|
1100 | 1100 | ||
1101 | // }}}
|
1101 | // }}}
|
1102 | // {{{ getSpecialQuery()
|
1102 | // {{{ getSpecialQuery()
|
1103 | 1103 | ||
1104 | /**
|
1104 | /**
|
1105 | * Obtains the query string needed for listing a given type of objects
|
1105 | * Obtains the query string needed for listing a given type of objects
|
1106 | *
|
1106 | *
|
1107 | * @param string $type the kind of objects you want to retrieve
|
1107 | * @param string $type the kind of objects you want to retrieve
|
1108 | *
|
1108 | *
|
1109 | * @return string the SQL query string or null if the driver doesn't
|
1109 | * @return string the SQL query string or null if the driver doesn't
|
1110 | * support the object type requested
|
1110 | * support the object type requested
|
1111 | *
|
1111 | *
|
1112 | * @access protected
|
1112 | * @access protected
|
1113 | * @see DB_common::getListOf()
|
1113 | * @see DB_common::getListOf()
|
1114 | */
|
1114 | */
|
1115 | function getSpecialQuery($type) |
1115 | function getSpecialQuery($type) |
1116 | {
|
1116 | {
|
1117 | switch ($type) { |
1117 | switch ($type) { |
1118 | case 'tables': |
1118 | case 'tables': |
1119 | return 'SELECT table_name FROM user_tables'; |
1119 | return 'SELECT table_name FROM user_tables'; |
1120 | case 'synonyms': |
1120 | case 'synonyms': |
1121 | return 'SELECT synonym_name FROM user_synonyms'; |
1121 | return 'SELECT synonym_name FROM user_synonyms'; |
1122 | case 'views': |
1122 | case 'views': |
1123 | return 'SELECT view_name FROM user_views'; |
1123 | return 'SELECT view_name FROM user_views'; |
1124 | default: |
1124 | default: |
1125 | return null; |
1125 | return null; |
1126 | }
|
1126 | }
|
1127 | }
|
1127 | }
|
1128 | 1128 | ||
1129 | // }}}
|
1129 | // }}}
|
1130 | // {{{ quoteFloat()
|
1130 | // {{{ quoteFloat()
|
1131 | 1131 | ||
1132 | /**
|
1132 | /**
|
1133 | * Formats a float value for use within a query in a locale-independent
|
1133 | * Formats a float value for use within a query in a locale-independent
|
1134 | * manner.
|
1134 | * manner.
|
1135 | *
|
1135 | *
|
1136 | * @param float the float value to be quoted.
|
1136 | * @param float the float value to be quoted.
|
1137 | * @return string the quoted string.
|
1137 | * @return string the quoted string.
|
1138 | * @see DB_common::quoteSmart()
|
1138 | * @see DB_common::quoteSmart()
|
1139 | * @since Method available since release 1.7.8.
|
1139 | * @since Method available since release 1.7.8.
|
1140 | */
|
1140 | */
|
1141 | function quoteFloat($float) { |
1141 | function quoteFloat($float) { |
1142 | return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
1142 | return $this->escapeSimple(str_replace(',', '.', strval(floatval($float)))); |
1143 | }
|
1143 | }
|
1144 | 1144 | ||
1145 | // }}}
|
1145 | // }}}
|
1146 | 1146 | ||
1147 | }
|
1147 | }
|
1148 | 1148 | ||
1149 | /*
|
1149 | /*
|
1150 | * Local variables:
|
1150 | * Local variables:
|
1151 | * tab-width: 4
|
1151 | * tab-width: 4
|
1152 | * c-basic-offset: 4
|
1152 | * c-basic-offset: 4
|
1153 | * End:
|
1153 | * End:
|
1154 | */
|
1154 | */
|
1155 | 1155 | ||
1156 | ?>
|
1156 | ?>
|
1157 | 1157 |