Редакция 2 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 2 | Редакция 94 | ||
---|---|---|---|
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 interbase extension
|
6 | * The PEAR DB driver for PHP's interbase extension
|
7 | * for interacting with Interbase and Firebird databases
|
7 | * for interacting with Interbase and Firebird databases
|
8 | *
|
8 | *
|
9 | * While this class works with PHP 4, PHP's InterBase extension is
|
9 | * While this class works with PHP 4, PHP's InterBase extension is
|
10 | * unstable in PHP 4. Use PHP 5.
|
10 | * unstable in PHP 4. Use PHP 5.
|
11 | *
|
11 | *
|
12 | * PHP versions 4 and 5
|
12 | * PHP versions 4 and 5
|
13 | *
|
13 | *
|
14 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
14 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
15 | * that is available through the world-wide-web at the following URI:
|
15 | * that is available through the world-wide-web at the following URI:
|
16 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
16 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
17 | * the PHP License and are unable to obtain it through the web, please
|
17 | * the PHP License and are unable to obtain it through the web, please
|
18 | * send a note to license@php.net so we can mail you a copy immediately.
|
18 | * send a note to license@php.net so we can mail you a copy immediately.
|
19 | *
|
19 | *
|
20 | * @category Database
|
20 | * @category Database
|
21 | * @package DB
|
21 | * @package DB
|
22 | * @author Sterling Hughes <sterling@php.net>
|
22 | * @author Sterling Hughes <sterling@php.net>
|
23 | * @author Daniel Convissor <danielc@php.net>
|
23 | * @author Daniel Convissor <danielc@php.net>
|
24 | * @copyright 1997-2007 The PHP Group
|
24 | * @copyright 1997-2007 The PHP Group
|
25 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
25 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
26 | * @version CVS: $Id: ibase.php,v 1.116 2007/09/21 13:40:41 aharvey Exp $
|
26 | * @version CVS: $Id: ibase.php,v 1.116 2007/09/21 13:40:41 aharvey Exp $
|
27 | * @link http://pear.php.net/package/DB
|
27 | * @link http://pear.php.net/package/DB
|
28 | */
|
28 | */
|
29 | 29 | ||
30 | /**
|
30 | /**
|
31 | * Obtain the DB_common class so it can be extended from
|
31 | * Obtain the DB_common class so it can be extended from
|
32 | */
|
32 | */
|
33 | require_once 'DB/common.php'; |
33 | require_once 'DB/common.php'; |
34 | 34 | ||
35 | /**
|
35 | /**
|
36 | * The methods PEAR DB uses to interact with PHP's interbase extension
|
36 | * The methods PEAR DB uses to interact with PHP's interbase extension
|
37 | * for interacting with Interbase and Firebird databases
|
37 | * for interacting with Interbase and Firebird databases
|
38 | *
|
38 | *
|
39 | * These methods overload the ones declared in DB_common.
|
39 | * These methods overload the ones declared in DB_common.
|
40 | *
|
40 | *
|
41 | * While this class works with PHP 4, PHP's InterBase extension is
|
41 | * While this class works with PHP 4, PHP's InterBase extension is
|
42 | * unstable in PHP 4. Use PHP 5.
|
42 | * unstable in PHP 4. Use PHP 5.
|
43 | *
|
43 | *
|
44 | * NOTICE: limitQuery() only works for Firebird.
|
44 | * NOTICE: limitQuery() only works for Firebird.
|
45 | *
|
45 | *
|
46 | * @category Database
|
46 | * @category Database
|
47 | * @package DB
|
47 | * @package DB
|
48 | * @author Sterling Hughes <sterling@php.net>
|
48 | * @author Sterling Hughes <sterling@php.net>
|
49 | * @author Daniel Convissor <danielc@php.net>
|
49 | * @author Daniel Convissor <danielc@php.net>
|
50 | * @copyright 1997-2007 The PHP Group
|
50 | * @copyright 1997-2007 The PHP Group
|
51 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
51 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
52 | * @version Release: 1.7.13
|
52 | * @version Release: 1.7.13
|
53 | * @link http://pear.php.net/package/DB
|
53 | * @link http://pear.php.net/package/DB
|
54 | * @since Class became stable in Release 1.7.0
|
54 | * @since Class became stable in Release 1.7.0
|
55 | */
|
55 | */
|
56 | class DB_ibase extends DB_common |
56 | class DB_ibase extends DB_common |
57 | {
|
57 | {
|
58 | // {{{ properties
|
58 | // {{{ properties
|
59 | 59 | ||
60 | /**
|
60 | /**
|
61 | * The DB driver type (mysql, oci8, odbc, etc.)
|
61 | * The DB driver type (mysql, oci8, odbc, etc.)
|
62 | * @var string
|
62 | * @var string
|
63 | */
|
63 | */
|
64 | var $phptype = 'ibase'; |
64 | var $phptype = 'ibase'; |
65 | 65 | ||
66 | /**
|
66 | /**
|
67 | * The database syntax variant to be used (db2, access, etc.), if any
|
67 | * The database syntax variant to be used (db2, access, etc.), if any
|
68 | * @var string
|
68 | * @var string
|
69 | */
|
69 | */
|
70 | var $dbsyntax = 'ibase'; |
70 | var $dbsyntax = 'ibase'; |
71 | 71 | ||
72 | /**
|
72 | /**
|
73 | * The capabilities of this DB implementation
|
73 | * The capabilities of this DB implementation
|
74 | *
|
74 | *
|
75 | * The 'new_link' element contains the PHP version that first provided
|
75 | * The 'new_link' element contains the PHP version that first provided
|
76 | * new_link support for this DBMS. Contains false if it's unsupported.
|
76 | * new_link support for this DBMS. Contains false if it's unsupported.
|
77 | *
|
77 | *
|
78 | * Meaning of the 'limit' element:
|
78 | * Meaning of the 'limit' element:
|
79 | * + 'emulate' = emulate with fetch row by number
|
79 | * + 'emulate' = emulate with fetch row by number
|
80 | * + 'alter' = alter the query
|
80 | * + 'alter' = alter the query
|
81 | * + false = skip rows
|
81 | * + false = skip rows
|
82 | *
|
82 | *
|
83 | * NOTE: only firebird supports limit.
|
83 | * NOTE: only firebird supports limit.
|
84 | *
|
84 | *
|
85 | * @var array
|
85 | * @var array
|
86 | */
|
86 | */
|
87 | var $features = array( |
87 | var $features = array( |
88 | 'limit' => false, |
88 | 'limit' => false, |
89 | 'new_link' => false, |
89 | 'new_link' => false, |
90 | 'numrows' => 'emulate', |
90 | 'numrows' => 'emulate', |
91 | 'pconnect' => true, |
91 | 'pconnect' => true, |
92 | 'prepare' => true, |
92 | 'prepare' => true, |
93 | 'ssl' => false, |
93 | 'ssl' => false, |
94 | 'transactions' => true, |
94 | 'transactions' => true, |
95 | ); |
95 | ); |
96 | 96 | ||
97 | /**
|
97 | /**
|
98 | * A mapping of native error codes to DB error codes
|
98 | * A mapping of native error codes to DB error codes
|
99 | * @var array
|
99 | * @var array
|
100 | */
|
100 | */
|
101 | var $errorcode_map = array( |
101 | var $errorcode_map = array( |
102 | -104 => DB_ERROR_SYNTAX, |
102 | -104 => DB_ERROR_SYNTAX, |
103 | -150 => DB_ERROR_ACCESS_VIOLATION, |
103 | -150 => DB_ERROR_ACCESS_VIOLATION, |
104 | -151 => DB_ERROR_ACCESS_VIOLATION, |
104 | -151 => DB_ERROR_ACCESS_VIOLATION, |
105 | -155 => DB_ERROR_NOSUCHTABLE, |
105 | -155 => DB_ERROR_NOSUCHTABLE, |
106 | -157 => DB_ERROR_NOSUCHFIELD, |
106 | -157 => DB_ERROR_NOSUCHFIELD, |
107 | -158 => DB_ERROR_VALUE_COUNT_ON_ROW, |
107 | -158 => DB_ERROR_VALUE_COUNT_ON_ROW, |
108 | -170 => DB_ERROR_MISMATCH, |
108 | -170 => DB_ERROR_MISMATCH, |
109 | -171 => DB_ERROR_MISMATCH, |
109 | -171 => DB_ERROR_MISMATCH, |
110 | -172 => DB_ERROR_INVALID, |
110 | -172 => DB_ERROR_INVALID, |
111 | // -204 => // Covers too many errors, need to use regex on msg
|
111 | // -204 => // Covers too many errors, need to use regex on msg
|
112 | -205 => DB_ERROR_NOSUCHFIELD, |
112 | -205 => DB_ERROR_NOSUCHFIELD, |
113 | -206 => DB_ERROR_NOSUCHFIELD, |
113 | -206 => DB_ERROR_NOSUCHFIELD, |
114 | -208 => DB_ERROR_INVALID, |
114 | -208 => DB_ERROR_INVALID, |
115 | -219 => DB_ERROR_NOSUCHTABLE, |
115 | -219 => DB_ERROR_NOSUCHTABLE, |
116 | -297 => DB_ERROR_CONSTRAINT, |
116 | -297 => DB_ERROR_CONSTRAINT, |
117 | -303 => DB_ERROR_INVALID, |
117 | -303 => DB_ERROR_INVALID, |
118 | -413 => DB_ERROR_INVALID_NUMBER, |
118 | -413 => DB_ERROR_INVALID_NUMBER, |
119 | -530 => DB_ERROR_CONSTRAINT, |
119 | -530 => DB_ERROR_CONSTRAINT, |
120 | -551 => DB_ERROR_ACCESS_VIOLATION, |
120 | -551 => DB_ERROR_ACCESS_VIOLATION, |
121 | -552 => DB_ERROR_ACCESS_VIOLATION, |
121 | -552 => DB_ERROR_ACCESS_VIOLATION, |
122 | // -607 => // Covers too many errors, need to use regex on msg
|
122 | // -607 => // Covers too many errors, need to use regex on msg
|
123 | -625 => DB_ERROR_CONSTRAINT_NOT_NULL, |
123 | -625 => DB_ERROR_CONSTRAINT_NOT_NULL, |
124 | -803 => DB_ERROR_CONSTRAINT, |
124 | -803 => DB_ERROR_CONSTRAINT, |
125 | -804 => DB_ERROR_VALUE_COUNT_ON_ROW, |
125 | -804 => DB_ERROR_VALUE_COUNT_ON_ROW, |
126 | // -902 => // Covers too many errors, need to use regex on msg
|
126 | // -902 => // Covers too many errors, need to use regex on msg
|
127 | -904 => DB_ERROR_CONNECT_FAILED, |
127 | -904 => DB_ERROR_CONNECT_FAILED, |
128 | -922 => DB_ERROR_NOSUCHDB, |
128 | -922 => DB_ERROR_NOSUCHDB, |
129 | -923 => DB_ERROR_CONNECT_FAILED, |
129 | -923 => DB_ERROR_CONNECT_FAILED, |
130 | -924 => DB_ERROR_CONNECT_FAILED |
130 | -924 => DB_ERROR_CONNECT_FAILED |
131 | ); |
131 | ); |
132 | 132 | ||
133 | /**
|
133 | /**
|
134 | * The raw database connection created by PHP
|
134 | * The raw database connection created by PHP
|
135 | * @var resource
|
135 | * @var resource
|
136 | */
|
136 | */
|
137 | var $connection; |
137 | var $connection; |
138 | 138 | ||
139 | /**
|
139 | /**
|
140 | * The DSN information for connecting to a database
|
140 | * The DSN information for connecting to a database
|
141 | * @var array
|
141 | * @var array
|
142 | */
|
142 | */
|
143 | var $dsn = array(); |
143 | var $dsn = array(); |
144 | 144 | ||
145 | 145 | ||
146 | /**
|
146 | /**
|
147 | * The number of rows affected by a data manipulation query
|
147 | * The number of rows affected by a data manipulation query
|
148 | * @var integer
|
148 | * @var integer
|
149 | * @access private
|
149 | * @access private
|
150 | */
|
150 | */
|
151 | var $affected = 0; |
151 | var $affected = 0; |
152 | 152 | ||
153 | /**
|
153 | /**
|
154 | * Should data manipulation queries be committed automatically?
|
154 | * Should data manipulation queries be committed automatically?
|
155 | * @var bool
|
155 | * @var bool
|
156 | * @access private
|
156 | * @access private
|
157 | */
|
157 | */
|
158 | var $autocommit = true; |
158 | var $autocommit = true; |
159 | 159 | ||
160 | /**
|
160 | /**
|
161 | * The prepared statement handle from the most recently executed statement
|
161 | * The prepared statement handle from the most recently executed statement
|
162 | *
|
162 | *
|
163 | * {@internal Mainly here because the InterBase/Firebird API is only
|
163 | * {@internal Mainly here because the InterBase/Firebird API is only
|
164 | * able to retrieve data from result sets if the statemnt handle is
|
164 | * able to retrieve data from result sets if the statemnt handle is
|
165 | * still in scope.}}
|
165 | * still in scope.}}
|
166 | *
|
166 | *
|
167 | * @var resource
|
167 | * @var resource
|
168 | */
|
168 | */
|
169 | var $last_stmt; |
169 | var $last_stmt; |
170 | 170 | ||
171 | /**
|
171 | /**
|
172 | * Is the given prepared statement a data manipulation query?
|
172 | * Is the given prepared statement a data manipulation query?
|
173 | * @var array
|
173 | * @var array
|
174 | * @access private
|
174 | * @access private
|
175 | */
|
175 | */
|
176 | var $manip_query = array(); |
176 | var $manip_query = array(); |
177 | 177 | ||
178 | 178 | ||
179 | // }}}
|
179 | // }}}
|
180 | // {{{ constructor
|
180 | // {{{ constructor
|
181 | 181 | ||
182 | /**
|
182 | /**
|
183 | * This constructor calls <kbd>$this->DB_common()</kbd>
|
183 | * This constructor calls <kbd>$this->DB_common()</kbd>
|
184 | *
|
184 | *
|
185 | * @return void
|
185 | * @return void
|
186 | */
|
186 | */
|
187 | function DB_ibase() |
187 | function DB_ibase() |
188 | {
|
188 | {
|
189 | $this->DB_common(); |
189 | $this->DB_common(); |
190 | }
|
190 | }
|
191 | 191 | ||
192 | // }}}
|
192 | // }}}
|
193 | // {{{ connect()
|
193 | // {{{ connect()
|
194 | 194 | ||
195 | /**
|
195 | /**
|
196 | * Connect to the database server, log in and open the database
|
196 | * Connect to the database server, log in and open the database
|
197 | *
|
197 | *
|
198 | * Don't call this method directly. Use DB::connect() instead.
|
198 | * Don't call this method directly. Use DB::connect() instead.
|
199 | *
|
199 | *
|
200 | * PEAR DB's ibase driver supports the following extra DSN options:
|
200 | * PEAR DB's ibase driver supports the following extra DSN options:
|
201 | * + buffers The number of database buffers to allocate for the
|
201 | * + buffers The number of database buffers to allocate for the
|
202 | * server-side cache.
|
202 | * server-side cache.
|
203 | * + charset The default character set for a database.
|
203 | * + charset The default character set for a database.
|
204 | * + dialect The default SQL dialect for any statement
|
204 | * + dialect The default SQL dialect for any statement
|
205 | * executed within a connection. Defaults to the
|
205 | * executed within a connection. Defaults to the
|
206 | * highest one supported by client libraries.
|
206 | * highest one supported by client libraries.
|
207 | * Functional only with InterBase 6 and up.
|
207 | * Functional only with InterBase 6 and up.
|
208 | * + role Functional only with InterBase 5 and up.
|
208 | * + role Functional only with InterBase 5 and up.
|
209 | *
|
209 | *
|
210 | * @param array $dsn the data source name
|
210 | * @param array $dsn the data source name
|
211 | * @param bool $persistent should the connection be persistent?
|
211 | * @param bool $persistent should the connection be persistent?
|
212 | *
|
212 | *
|
213 | * @return int DB_OK on success. A DB_Error object on failure.
|
213 | * @return int DB_OK on success. A DB_Error object on failure.
|
214 | */
|
214 | */
|
215 | function connect($dsn, $persistent = false) |
215 | function connect($dsn, $persistent = false) |
216 | {
|
216 | {
|
217 | if (!PEAR::loadExtension('interbase')) { |
217 | if (!PEAR::loadExtension('interbase')) { |
218 | return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
218 | return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
219 | }
|
219 | }
|
220 | 220 | ||
221 | $this->dsn = $dsn; |
221 | $this->dsn = $dsn; |
222 | if ($dsn['dbsyntax']) { |
222 | if ($dsn['dbsyntax']) { |
223 | $this->dbsyntax = $dsn['dbsyntax']; |
223 | $this->dbsyntax = $dsn['dbsyntax']; |
224 | }
|
224 | }
|
225 | if ($this->dbsyntax == 'firebird') { |
225 | if ($this->dbsyntax == 'firebird') { |
226 | $this->features['limit'] = 'alter'; |
226 | $this->features['limit'] = 'alter'; |
227 | }
|
227 | }
|
228 | 228 | ||
229 | $params = array( |
229 | $params = array( |
230 | $dsn['hostspec'] |
230 | $dsn['hostspec'] |
231 | ? ($dsn['hostspec'] . ':' . $dsn['database']) |
231 | ? ($dsn['hostspec'] . ':' . $dsn['database']) |
232 | : $dsn['database'], |
232 | : $dsn['database'], |
233 | $dsn['username'] ? $dsn['username'] : null, |
233 | $dsn['username'] ? $dsn['username'] : null, |
234 | $dsn['password'] ? $dsn['password'] : null, |
234 | $dsn['password'] ? $dsn['password'] : null, |
235 | isset($dsn['charset']) ? $dsn['charset'] : null, |
235 | isset($dsn['charset']) ? $dsn['charset'] : null, |
236 | isset($dsn['buffers']) ? $dsn['buffers'] : null, |
236 | isset($dsn['buffers']) ? $dsn['buffers'] : null, |
237 | isset($dsn['dialect']) ? $dsn['dialect'] : null, |
237 | isset($dsn['dialect']) ? $dsn['dialect'] : null, |
238 | isset($dsn['role']) ? $dsn['role'] : null, |
238 | isset($dsn['role']) ? $dsn['role'] : null, |
239 | ); |
239 | ); |
240 | 240 | ||
241 | $connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; |
241 | $connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; |
242 | 242 | ||
243 | $this->connection = @call_user_func_array($connect_function, $params); |
243 | $this->connection = @call_user_func_array($connect_function, $params); |
244 | if (!$this->connection) { |
244 | if (!$this->connection) { |
245 | return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); |
245 | return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); |
246 | }
|
246 | }
|
247 | return DB_OK; |
247 | return DB_OK; |
248 | }
|
248 | }
|
249 | 249 | ||
250 | // }}}
|
250 | // }}}
|
251 | // {{{ disconnect()
|
251 | // {{{ disconnect()
|
252 | 252 | ||
253 | /**
|
253 | /**
|
254 | * Disconnects from the database server
|
254 | * Disconnects from the database server
|
255 | *
|
255 | *
|
256 | * @return bool TRUE on success, FALSE on failure
|
256 | * @return bool TRUE on success, FALSE on failure
|
257 | */
|
257 | */
|
258 | function disconnect() |
258 | function disconnect() |
259 | {
|
259 | {
|
260 | $ret = @ibase_close($this->connection); |
260 | $ret = @ibase_close($this->connection); |
261 | $this->connection = null; |
261 | $this->connection = null; |
262 | return $ret; |
262 | return $ret; |
263 | }
|
263 | }
|
264 | 264 | ||
265 | // }}}
|
265 | // }}}
|
266 | // {{{ simpleQuery()
|
266 | // {{{ simpleQuery()
|
267 | 267 | ||
268 | /**
|
268 | /**
|
269 | * Sends a query to the database server
|
269 | * Sends a query to the database server
|
270 | *
|
270 | *
|
271 | * @param string the SQL query string
|
271 | * @param string the SQL query string
|
272 | *
|
272 | *
|
273 | * @return mixed + a PHP result resrouce for successful SELECT queries
|
273 | * @return mixed + a PHP result resrouce for successful SELECT queries
|
274 | * + the DB_OK constant for other successful queries
|
274 | * + the DB_OK constant for other successful queries
|
275 | * + a DB_Error object on failure
|
275 | * + a DB_Error object on failure
|
276 | */
|
276 | */
|
277 | function simpleQuery($query) |
277 | function simpleQuery($query) |
278 | {
|
278 | {
|
279 | $ismanip = $this->_checkManip($query); |
279 | $ismanip = $this->_checkManip($query); |
280 | $this->last_query = $query; |
280 | $this->last_query = $query; |
281 | $query = $this->modifyQuery($query); |
281 | $query = $this->modifyQuery($query); |
282 | $result = @ibase_query($this->connection, $query); |
282 | $result = @ibase_query($this->connection, $query); |
283 | 283 | ||
284 | if (!$result) { |
284 | if (!$result) { |
285 | return $this->ibaseRaiseError(); |
285 | return $this->ibaseRaiseError(); |
286 | }
|
286 | }
|
287 | if ($this->autocommit && $ismanip) { |
287 | if ($this->autocommit && $ismanip) { |
288 | @ibase_commit($this->connection); |
288 | @ibase_commit($this->connection); |
289 | }
|
289 | }
|
290 | if ($ismanip) { |
290 | if ($ismanip) { |
291 | $this->affected = $result; |
291 | $this->affected = $result; |
292 | return DB_OK; |
292 | return DB_OK; |
293 | } else { |
293 | } else { |
294 | $this->affected = 0; |
294 | $this->affected = 0; |
295 | return $result; |
295 | return $result; |
296 | }
|
296 | }
|
297 | }
|
297 | }
|
298 | 298 | ||
299 | // }}}
|
299 | // }}}
|
300 | // {{{ modifyLimitQuery()
|
300 | // {{{ modifyLimitQuery()
|
301 | 301 | ||
302 | /**
|
302 | /**
|
303 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
303 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
304 | *
|
304 | *
|
305 | * Only works with Firebird.
|
305 | * Only works with Firebird.
|
306 | *
|
306 | *
|
307 | * @param string $query the query to modify
|
307 | * @param string $query the query to modify
|
308 | * @param int $from the row to start to fetching (0 = the first row)
|
308 | * @param int $from the row to start to fetching (0 = the first row)
|
309 | * @param int $count the numbers of rows to fetch
|
309 | * @param int $count the numbers of rows to fetch
|
310 | * @param mixed $params array, string or numeric data to be used in
|
310 | * @param mixed $params array, string or numeric data to be used in
|
311 | * execution of the statement. Quantity of items
|
311 | * execution of the statement. Quantity of items
|
312 | * passed must match quantity of placeholders in
|
312 | * passed must match quantity of placeholders in
|
313 | * query: meaning 1 placeholder for non-array
|
313 | * query: meaning 1 placeholder for non-array
|
314 | * parameters or 1 placeholder per array element.
|
314 | * parameters or 1 placeholder per array element.
|
315 | *
|
315 | *
|
316 | * @return string the query string with LIMIT clauses added
|
316 | * @return string the query string with LIMIT clauses added
|
317 | *
|
317 | *
|
318 | * @access protected
|
318 | * @access protected
|
319 | */
|
319 | */
|
320 | function modifyLimitQuery($query, $from, $count, $params = array()) |
320 | function modifyLimitQuery($query, $from, $count, $params = array()) |
321 | {
|
321 | {
|
322 | if ($this->dsn['dbsyntax'] == 'firebird') { |
322 | if ($this->dsn['dbsyntax'] == 'firebird') { |
323 | $query = preg_replace('/^([\s(])*SELECT/i', |
323 | $query = preg_replace('/^([\s(])*SELECT/i', |
324 | "SELECT FIRST $count SKIP $from", $query); |
324 | "SELECT FIRST $count SKIP $from", $query); |
325 | }
|
325 | }
|
326 | return $query; |
326 | return $query; |
327 | }
|
327 | }
|
328 | 328 | ||
329 | // }}}
|
329 | // }}}
|
330 | // {{{ nextResult()
|
330 | // {{{ nextResult()
|
331 | 331 | ||
332 | /**
|
332 | /**
|
333 | * Move the internal ibase result pointer to the next available result
|
333 | * Move the internal ibase result pointer to the next available result
|
334 | *
|
334 | *
|
335 | * @param a valid fbsql result resource
|
335 | * @param a valid fbsql result resource
|
336 | *
|
336 | *
|
337 | * @access public
|
337 | * @access public
|
338 | *
|
338 | *
|
339 | * @return true if a result is available otherwise return false
|
339 | * @return true if a result is available otherwise return false
|
340 | */
|
340 | */
|
341 | function nextResult($result) |
341 | function nextResult($result) |
342 | {
|
342 | {
|
343 | return false; |
343 | return false; |
344 | }
|
344 | }
|
345 | 345 | ||
346 | // }}}
|
346 | // }}}
|
347 | // {{{ fetchInto()
|
347 | // {{{ fetchInto()
|
348 | 348 | ||
349 | /**
|
349 | /**
|
350 | * Places a row from the result set into the given array
|
350 | * Places a row from the result set into the given array
|
351 | *
|
351 | *
|
352 | * Formating of the array and the data therein are configurable.
|
352 | * Formating of the array and the data therein are configurable.
|
353 | * See DB_result::fetchInto() for more information.
|
353 | * See DB_result::fetchInto() for more information.
|
354 | *
|
354 | *
|
355 | * This method is not meant to be called directly. Use
|
355 | * This method is not meant to be called directly. Use
|
356 | * DB_result::fetchInto() instead. It can't be declared "protected"
|
356 | * DB_result::fetchInto() instead. It can't be declared "protected"
|
357 | * because DB_result is a separate object.
|
357 | * because DB_result is a separate object.
|
358 | *
|
358 | *
|
359 | * @param resource $result the query result resource
|
359 | * @param resource $result the query result resource
|
360 | * @param array $arr the referenced array to put the data in
|
360 | * @param array $arr the referenced array to put the data in
|
361 | * @param int $fetchmode how the resulting array should be indexed
|
361 | * @param int $fetchmode how the resulting array should be indexed
|
362 | * @param int $rownum the row number to fetch (0 = first row)
|
362 | * @param int $rownum the row number to fetch (0 = first row)
|
363 | *
|
363 | *
|
364 | * @return mixed DB_OK on success, NULL when the end of a result set is
|
364 | * @return mixed DB_OK on success, NULL when the end of a result set is
|
365 | * reached or on failure
|
365 | * reached or on failure
|
366 | *
|
366 | *
|
367 | * @see DB_result::fetchInto()
|
367 | * @see DB_result::fetchInto()
|
368 | */
|
368 | */
|
369 | function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
369 | function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
370 | {
|
370 | {
|
371 | if ($rownum !== null) { |
371 | if ($rownum !== null) { |
372 | return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
372 | return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
373 | }
|
373 | }
|
374 | if ($fetchmode & DB_FETCHMODE_ASSOC) { |
374 | if ($fetchmode & DB_FETCHMODE_ASSOC) { |
375 | if (function_exists('ibase_fetch_assoc')) { |
375 | if (function_exists('ibase_fetch_assoc')) { |
376 | $arr = @ibase_fetch_assoc($result); |
376 | $arr = @ibase_fetch_assoc($result); |
377 | } else { |
377 | } else { |
378 | $arr = get_object_vars(ibase_fetch_object($result)); |
378 | $arr = get_object_vars(ibase_fetch_object($result)); |
379 | }
|
379 | }
|
380 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
380 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
381 | $arr = array_change_key_case($arr, CASE_LOWER); |
381 | $arr = array_change_key_case($arr, CASE_LOWER); |
382 | }
|
382 | }
|
383 | } else { |
383 | } else { |
384 | $arr = @ibase_fetch_row($result); |
384 | $arr = @ibase_fetch_row($result); |
385 | }
|
385 | }
|
386 | if (!$arr) { |
386 | if (!$arr) { |
387 | return null; |
387 | return null; |
388 | }
|
388 | }
|
389 | if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
389 | if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
390 | $this->_rtrimArrayValues($arr); |
390 | $this->_rtrimArrayValues($arr); |
391 | }
|
391 | }
|
392 | if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
392 | if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
393 | $this->_convertNullArrayValuesToEmpty($arr); |
393 | $this->_convertNullArrayValuesToEmpty($arr); |
394 | }
|
394 | }
|
395 | return DB_OK; |
395 | return DB_OK; |
396 | }
|
396 | }
|
397 | 397 | ||
398 | // }}}
|
398 | // }}}
|
399 | // {{{ freeResult()
|
399 | // {{{ freeResult()
|
400 | 400 | ||
401 | /**
|
401 | /**
|
402 | * Deletes the result set and frees the memory occupied by the result set
|
402 | * Deletes the result set and frees the memory occupied by the result set
|
403 | *
|
403 | *
|
404 | * This method is not meant to be called directly. Use
|
404 | * This method is not meant to be called directly. Use
|
405 | * DB_result::free() instead. It can't be declared "protected"
|
405 | * DB_result::free() instead. It can't be declared "protected"
|
406 | * because DB_result is a separate object.
|
406 | * because DB_result is a separate object.
|
407 | *
|
407 | *
|
408 | * @param resource $result PHP's query result resource
|
408 | * @param resource $result PHP's query result resource
|
409 | *
|
409 | *
|
410 | * @return bool TRUE on success, FALSE if $result is invalid
|
410 | * @return bool TRUE on success, FALSE if $result is invalid
|
411 | *
|
411 | *
|
412 | * @see DB_result::free()
|
412 | * @see DB_result::free()
|
413 | */
|
413 | */
|
414 | function freeResult($result) |
414 | function freeResult($result) |
415 | {
|
415 | {
|
416 | return is_resource($result) ? ibase_free_result($result) : false; |
416 | return is_resource($result) ? ibase_free_result($result) : false; |
417 | }
|
417 | }
|
418 | 418 | ||
419 | // }}}
|
419 | // }}}
|
420 | // {{{ freeQuery()
|
420 | // {{{ freeQuery()
|
421 | 421 | ||
422 | function freeQuery($query) |
422 | function freeQuery($query) |
423 | {
|
423 | {
|
424 | return is_resource($query) ? ibase_free_query($query) : false; |
424 | return is_resource($query) ? ibase_free_query($query) : false; |
425 | }
|
425 | }
|
426 | 426 | ||
427 | // }}}
|
427 | // }}}
|
428 | // {{{ affectedRows()
|
428 | // {{{ affectedRows()
|
429 | 429 | ||
430 | /**
|
430 | /**
|
431 | * Determines the number of rows affected by a data maniuplation query
|
431 | * Determines the number of rows affected by a data maniuplation query
|
432 | *
|
432 | *
|
433 | * 0 is returned for queries that don't manipulate data.
|
433 | * 0 is returned for queries that don't manipulate data.
|
434 | *
|
434 | *
|
435 | * @return int the number of rows. A DB_Error object on failure.
|
435 | * @return int the number of rows. A DB_Error object on failure.
|
436 | */
|
436 | */
|
437 | function affectedRows() |
437 | function affectedRows() |
438 | {
|
438 | {
|
439 | if (is_integer($this->affected)) { |
439 | if (is_integer($this->affected)) { |
440 | return $this->affected; |
440 | return $this->affected; |
441 | }
|
441 | }
|
442 | return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
442 | return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); |
443 | }
|
443 | }
|
444 | 444 | ||
445 | // }}}
|
445 | // }}}
|
446 | // {{{ numCols()
|
446 | // {{{ numCols()
|
447 | 447 | ||
448 | /**
|
448 | /**
|
449 | * Gets the number of columns in a result set
|
449 | * Gets the number of columns in a result set
|
450 | *
|
450 | *
|
451 | * This method is not meant to be called directly. Use
|
451 | * This method is not meant to be called directly. Use
|
452 | * DB_result::numCols() instead. It can't be declared "protected"
|
452 | * DB_result::numCols() instead. It can't be declared "protected"
|
453 | * because DB_result is a separate object.
|
453 | * because DB_result is a separate object.
|
454 | *
|
454 | *
|
455 | * @param resource $result PHP's query result resource
|
455 | * @param resource $result PHP's query result resource
|
456 | *
|
456 | *
|
457 | * @return int the number of columns. A DB_Error object on failure.
|
457 | * @return int the number of columns. A DB_Error object on failure.
|
458 | *
|
458 | *
|
459 | * @see DB_result::numCols()
|
459 | * @see DB_result::numCols()
|
460 | */
|
460 | */
|
461 | function numCols($result) |
461 | function numCols($result) |
462 | {
|
462 | {
|
463 | $cols = @ibase_num_fields($result); |
463 | $cols = @ibase_num_fields($result); |
464 | if (!$cols) { |
464 | if (!$cols) { |
465 | return $this->ibaseRaiseError(); |
465 | return $this->ibaseRaiseError(); |
466 | }
|
466 | }
|
467 | return $cols; |
467 | return $cols; |
468 | }
|
468 | }
|
469 | 469 | ||
470 | // }}}
|
470 | // }}}
|
471 | // {{{ prepare()
|
471 | // {{{ prepare()
|
472 | 472 | ||
473 | /**
|
473 | /**
|
474 | * Prepares a query for multiple execution with execute().
|
474 | * Prepares a query for multiple execution with execute().
|
475 | *
|
475 | *
|
476 | * prepare() requires a generic query as string like <code>
|
476 | * prepare() requires a generic query as string like <code>
|
477 | * INSERT INTO numbers VALUES (?, ?, ?)
|
477 | * INSERT INTO numbers VALUES (?, ?, ?)
|
478 | * </code>. The <kbd>?</kbd> characters are placeholders.
|
478 | * </code>. The <kbd>?</kbd> characters are placeholders.
|
479 | *
|
479 | *
|
480 | * Three types of placeholders can be used:
|
480 | * Three types of placeholders can be used:
|
481 | * + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
|
481 | * + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
|
482 | * + <kbd>!</kbd> value is inserted 'as is'
|
482 | * + <kbd>!</kbd> value is inserted 'as is'
|
483 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
483 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
484 | * inserted into the query (i.e. saving binary
|
484 | * inserted into the query (i.e. saving binary
|
485 | * data in a db)
|
485 | * data in a db)
|
486 | *
|
486 | *
|
487 | * Use backslashes to escape placeholder characters if you don't want
|
487 | * Use backslashes to escape placeholder characters if you don't want
|
488 | * them to be interpreted as placeholders. Example: <code>
|
488 | * them to be interpreted as placeholders. Example: <code>
|
489 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
489 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
490 | * </code>
|
490 | * </code>
|
491 | *
|
491 | *
|
492 | * @param string $query query to be prepared
|
492 | * @param string $query query to be prepared
|
493 | * @return mixed DB statement resource on success. DB_Error on failure.
|
493 | * @return mixed DB statement resource on success. DB_Error on failure.
|
494 | */
|
494 | */
|
495 | function prepare($query) |
495 | function prepare($query) |
496 | {
|
496 | {
|
497 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
497 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
498 | PREG_SPLIT_DELIM_CAPTURE); |
498 | PREG_SPLIT_DELIM_CAPTURE); |
499 | $token = 0; |
499 | $token = 0; |
500 | $types = array(); |
500 | $types = array(); |
501 | $newquery = ''; |
501 | $newquery = ''; |
502 | 502 | ||
503 | foreach ($tokens as $key => $val) { |
503 | foreach ($tokens as $key => $val) { |
504 | switch ($val) { |
504 | switch ($val) { |
505 | case '?': |
505 | case '?': |
506 | $types[$token++] = DB_PARAM_SCALAR; |
506 | $types[$token++] = DB_PARAM_SCALAR; |
507 | break; |
507 | break; |
508 | case '&': |
508 | case '&': |
509 | $types[$token++] = DB_PARAM_OPAQUE; |
509 | $types[$token++] = DB_PARAM_OPAQUE; |
510 | break; |
510 | break; |
511 | case '!': |
511 | case '!': |
512 | $types[$token++] = DB_PARAM_MISC; |
512 | $types[$token++] = DB_PARAM_MISC; |
513 | break; |
513 | break; |
514 | default: |
514 | default: |
515 | $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
515 | $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); |
516 | $newquery .= $tokens[$key] . '?'; |
516 | $newquery .= $tokens[$key] . '?'; |
517 | }
|
517 | }
|
518 | }
|
518 | }
|
519 | 519 | ||
520 | $newquery = substr($newquery, 0, -1); |
520 | $newquery = substr($newquery, 0, -1); |
521 | $this->last_query = $query; |
521 | $this->last_query = $query; |
522 | $newquery = $this->modifyQuery($newquery); |
522 | $newquery = $this->modifyQuery($newquery); |
523 | $stmt = @ibase_prepare($this->connection, $newquery); |
523 | $stmt = @ibase_prepare($this->connection, $newquery); |
524 | 524 | ||
525 | if ($stmt === false) { |
525 | if ($stmt === false) { |
526 | $stmt = $this->ibaseRaiseError(); |
526 | $stmt = $this->ibaseRaiseError(); |
527 | } else { |
527 | } else { |
528 | $this->prepare_types[(int)$stmt] = $types; |
528 | $this->prepare_types[(int)$stmt] = $types; |
529 | $this->manip_query[(int)$stmt] = DB::isManip($query); |
529 | $this->manip_query[(int)$stmt] = DB::isManip($query); |
530 | }
|
530 | }
|
531 | 531 | ||
532 | return $stmt; |
532 | return $stmt; |
533 | }
|
533 | }
|
534 | 534 | ||
535 | // }}}
|
535 | // }}}
|
536 | // {{{ execute()
|
536 | // {{{ execute()
|
537 | 537 | ||
538 | /**
|
538 | /**
|
539 | * Executes a DB statement prepared with prepare().
|
539 | * Executes a DB statement prepared with prepare().
|
540 | *
|
540 | *
|
541 | * @param resource $stmt a DB statement resource returned from prepare()
|
541 | * @param resource $stmt a DB statement resource returned from prepare()
|
542 | * @param mixed $data array, string or numeric data to be used in
|
542 | * @param mixed $data array, string or numeric data to be used in
|
543 | * execution of the statement. Quantity of items
|
543 | * execution of the statement. Quantity of items
|
544 | * passed must match quantity of placeholders in
|
544 | * passed must match quantity of placeholders in
|
545 | * query: meaning 1 for non-array items or the
|
545 | * query: meaning 1 for non-array items or the
|
546 | * quantity of elements in the array.
|
546 | * quantity of elements in the array.
|
547 | * @return object a new DB_Result or a DB_Error when fail
|
547 | * @return object a new DB_Result or a DB_Error when fail
|
548 | * @see DB_ibase::prepare()
|
548 | * @see DB_ibase::prepare()
|
549 | * @access public
|
549 | * @access public
|
550 | */
|
550 | */
|
551 | function &execute($stmt, $data = array()) |
551 | function &execute($stmt, $data = array()) |
552 | {
|
552 | {
|
553 | $data = (array)$data; |
553 | $data = (array)$data; |
554 | $this->last_parameters = $data; |
554 | $this->last_parameters = $data; |
555 | 555 | ||
556 | $types = $this->prepare_types[(int)$stmt]; |
556 | $types = $this->prepare_types[(int)$stmt]; |
557 | if (count($types) != count($data)) { |
557 | if (count($types) != count($data)) { |
558 | $tmp = $this->raiseError(DB_ERROR_MISMATCH); |
558 | $tmp = $this->raiseError(DB_ERROR_MISMATCH); |
559 | return $tmp; |
559 | return $tmp; |
560 | }
|
560 | }
|
561 | 561 | ||
562 | $i = 0; |
562 | $i = 0; |
563 | foreach ($data as $key => $value) { |
563 | foreach ($data as $key => $value) { |
564 | if ($types[$i] == DB_PARAM_MISC) { |
564 | if ($types[$i] == DB_PARAM_MISC) { |
565 | /*
|
565 | /*
|
566 | * ibase doesn't seem to have the ability to pass a
|
566 | * ibase doesn't seem to have the ability to pass a
|
567 | * parameter along unchanged, so strip off quotes from start
|
567 | * parameter along unchanged, so strip off quotes from start
|
568 | * and end, plus turn two single quotes to one single quote,
|
568 | * and end, plus turn two single quotes to one single quote,
|
569 | * in order to avoid the quotes getting escaped by
|
569 | * in order to avoid the quotes getting escaped by
|
570 | * ibase and ending up in the database.
|
570 | * ibase and ending up in the database.
|
571 | */
|
571 | */
|
572 | $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
572 | $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); |
573 | $data[$key] = str_replace("''", "'", $data[$key]); |
573 | $data[$key] = str_replace("''", "'", $data[$key]); |
574 | } elseif ($types[$i] == DB_PARAM_OPAQUE) { |
574 | } elseif ($types[$i] == DB_PARAM_OPAQUE) { |
575 | $fp = @fopen($data[$key], 'rb'); |
575 | $fp = @fopen($data[$key], 'rb'); |
576 | if (!$fp) { |
576 | if (!$fp) { |
577 | $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
577 | $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
578 | return $tmp; |
578 | return $tmp; |
579 | }
|
579 | }
|
580 | $data[$key] = fread($fp, filesize($data[$key])); |
580 | $data[$key] = fread($fp, filesize($data[$key])); |
581 | fclose($fp); |
581 | fclose($fp); |
582 | }
|
582 | }
|
583 | $i++; |
583 | $i++; |
584 | }
|
584 | }
|
585 | 585 | ||
586 | array_unshift($data, $stmt); |
586 | array_unshift($data, $stmt); |
587 | 587 | ||
588 | $res = call_user_func_array('ibase_execute', $data); |
588 | $res = call_user_func_array('ibase_execute', $data); |
589 | if (!$res) { |
589 | if (!$res) { |
590 | $tmp = $this->ibaseRaiseError(); |
590 | $tmp = $this->ibaseRaiseError(); |
591 | return $tmp; |
591 | return $tmp; |
592 | }
|
592 | }
|
593 | /* XXX need this?
|
593 | /* XXX need this?
|
594 | if ($this->autocommit && $this->manip_query[(int)$stmt]) {
|
594 | if ($this->autocommit && $this->manip_query[(int)$stmt]) {
|
595 | @ibase_commit($this->connection);
|
595 | @ibase_commit($this->connection);
|
596 | }*/
|
596 | }*/
|
597 | $this->last_stmt = $stmt; |
597 | $this->last_stmt = $stmt; |
598 | if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
598 | if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) { |
599 | $this->_last_query_manip = true; |
599 | $this->_last_query_manip = true; |
600 | $this->_next_query_manip = false; |
600 | $this->_next_query_manip = false; |
601 | $tmp = DB_OK; |
601 | $tmp = DB_OK; |
602 | } else { |
602 | } else { |
603 | $this->_last_query_manip = false; |
603 | $this->_last_query_manip = false; |
604 | $tmp = new DB_result($this, $res); |
604 | $tmp = new DB_result($this, $res); |
605 | }
|
605 | }
|
606 | return $tmp; |
606 | return $tmp; |
607 | }
|
607 | }
|
608 | 608 | ||
609 | /**
|
609 | /**
|
610 | * Frees the internal resources associated with a prepared query
|
610 | * Frees the internal resources associated with a prepared query
|
611 | *
|
611 | *
|
612 | * @param resource $stmt the prepared statement's PHP resource
|
612 | * @param resource $stmt the prepared statement's PHP resource
|
613 | * @param bool $free_resource should the PHP resource be freed too?
|
613 | * @param bool $free_resource should the PHP resource be freed too?
|
614 | * Use false if you need to get data
|
614 | * Use false if you need to get data
|
615 | * from the result set later.
|
615 | * from the result set later.
|
616 | *
|
616 | *
|
617 | * @return bool TRUE on success, FALSE if $result is invalid
|
617 | * @return bool TRUE on success, FALSE if $result is invalid
|
618 | *
|
618 | *
|
619 | * @see DB_ibase::prepare()
|
619 | * @see DB_ibase::prepare()
|
620 | */
|
620 | */
|
621 | function freePrepared($stmt, $free_resource = true) |
621 | function freePrepared($stmt, $free_resource = true) |
622 | {
|
622 | {
|
623 | if (!is_resource($stmt)) { |
623 | if (!is_resource($stmt)) { |
624 | return false; |
624 | return false; |
625 | }
|
625 | }
|
626 | if ($free_resource) { |
626 | if ($free_resource) { |
627 | @ibase_free_query($stmt); |
627 | @ibase_free_query($stmt); |
628 | }
|
628 | }
|
629 | unset($this->prepare_tokens[(int)$stmt]); |
629 | unset($this->prepare_tokens[(int)$stmt]); |
630 | unset($this->prepare_types[(int)$stmt]); |
630 | unset($this->prepare_types[(int)$stmt]); |
631 | unset($this->manip_query[(int)$stmt]); |
631 | unset($this->manip_query[(int)$stmt]); |
632 | return true; |
632 | return true; |
633 | }
|
633 | }
|
634 | 634 | ||
635 | // }}}
|
635 | // }}}
|
636 | // {{{ autoCommit()
|
636 | // {{{ autoCommit()
|
637 | 637 | ||
638 | /**
|
638 | /**
|
639 | * Enables or disables automatic commits
|
639 | * Enables or disables automatic commits
|
640 | *
|
640 | *
|
641 | * @param bool $onoff true turns it on, false turns it off
|
641 | * @param bool $onoff true turns it on, false turns it off
|
642 | *
|
642 | *
|
643 | * @return int DB_OK on success. A DB_Error object if the driver
|
643 | * @return int DB_OK on success. A DB_Error object if the driver
|
644 | * doesn't support auto-committing transactions.
|
644 | * doesn't support auto-committing transactions.
|
645 | */
|
645 | */
|
646 | function autoCommit($onoff = false) |
646 | function autoCommit($onoff = false) |
647 | {
|
647 | {
|
648 | $this->autocommit = $onoff ? 1 : 0; |
648 | $this->autocommit = $onoff ? 1 : 0; |
649 | return DB_OK; |
649 | return DB_OK; |
650 | }
|
650 | }
|
651 | 651 | ||
652 | // }}}
|
652 | // }}}
|
653 | // {{{ commit()
|
653 | // {{{ commit()
|
654 | 654 | ||
655 | /**
|
655 | /**
|
656 | * Commits the current transaction
|
656 | * Commits the current transaction
|
657 | *
|
657 | *
|
658 | * @return int DB_OK on success. A DB_Error object on failure.
|
658 | * @return int DB_OK on success. A DB_Error object on failure.
|
659 | */
|
659 | */
|
660 | function commit() |
660 | function commit() |
661 | {
|
661 | {
|
662 | return @ibase_commit($this->connection); |
662 | return @ibase_commit($this->connection); |
663 | }
|
663 | }
|
664 | 664 | ||
665 | // }}}
|
665 | // }}}
|
666 | // {{{ rollback()
|
666 | // {{{ rollback()
|
667 | 667 | ||
668 | /**
|
668 | /**
|
669 | * Reverts the current transaction
|
669 | * Reverts the current transaction
|
670 | *
|
670 | *
|
671 | * @return int DB_OK on success. A DB_Error object on failure.
|
671 | * @return int DB_OK on success. A DB_Error object on failure.
|
672 | */
|
672 | */
|
673 | function rollback() |
673 | function rollback() |
674 | {
|
674 | {
|
675 | return @ibase_rollback($this->connection); |
675 | return @ibase_rollback($this->connection); |
676 | }
|
676 | }
|
677 | 677 | ||
678 | // }}}
|
678 | // }}}
|
679 | // {{{ transactionInit()
|
679 | // {{{ transactionInit()
|
680 | 680 | ||
681 | function transactionInit($trans_args = 0) |
681 | function transactionInit($trans_args = 0) |
682 | {
|
682 | {
|
683 | return $trans_args |
683 | return $trans_args |
684 | ? @ibase_trans($trans_args, $this->connection) |
684 | ? @ibase_trans($trans_args, $this->connection) |
685 | : @ibase_trans(); |
685 | : @ibase_trans(); |
686 | }
|
686 | }
|
687 | 687 | ||
688 | // }}}
|
688 | // }}}
|
689 | // {{{ nextId()
|
689 | // {{{ nextId()
|
690 | 690 | ||
691 | /**
|
691 | /**
|
692 | * Returns the next free id in a sequence
|
692 | * Returns the next free id in a sequence
|
693 | *
|
693 | *
|
694 | * @param string $seq_name name of the sequence
|
694 | * @param string $seq_name name of the sequence
|
695 | * @param boolean $ondemand when true, the seqence is automatically
|
695 | * @param boolean $ondemand when true, the seqence is automatically
|
696 | * created if it does not exist
|
696 | * created if it does not exist
|
697 | *
|
697 | *
|
698 | * @return int the next id number in the sequence.
|
698 | * @return int the next id number in the sequence.
|
699 | * A DB_Error object on failure.
|
699 | * A DB_Error object on failure.
|
700 | *
|
700 | *
|
701 | * @see DB_common::nextID(), DB_common::getSequenceName(),
|
701 | * @see DB_common::nextID(), DB_common::getSequenceName(),
|
702 | * DB_ibase::createSequence(), DB_ibase::dropSequence()
|
702 | * DB_ibase::createSequence(), DB_ibase::dropSequence()
|
703 | */
|
703 | */
|
704 | function nextId($seq_name, $ondemand = true) |
704 | function nextId($seq_name, $ondemand = true) |
705 | {
|
705 | {
|
706 | $sqn = strtoupper($this->getSequenceName($seq_name)); |
706 | $sqn = strtoupper($this->getSequenceName($seq_name)); |
707 | $repeat = 0; |
707 | $repeat = 0; |
708 | do { |
708 | do { |
709 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
709 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
710 | $result = $this->query("SELECT GEN_ID(${sqn}, 1) " |
710 | $result = $this->query("SELECT GEN_ID(${sqn}, 1) " |
711 | . 'FROM RDB$GENERATORS ' |
711 | . 'FROM RDB$GENERATORS ' |
712 | . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); |
712 | . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); |
713 | $this->popErrorHandling(); |
713 | $this->popErrorHandling(); |
714 | if ($ondemand && DB::isError($result)) { |
714 | if ($ondemand && DB::isError($result)) { |
715 | $repeat = 1; |
715 | $repeat = 1; |
716 | $result = $this->createSequence($seq_name); |
716 | $result = $this->createSequence($seq_name); |
717 | if (DB::isError($result)) { |
717 | if (DB::isError($result)) { |
718 | return $result; |
718 | return $result; |
719 | }
|
719 | }
|
720 | } else { |
720 | } else { |
721 | $repeat = 0; |
721 | $repeat = 0; |
722 | }
|
722 | }
|
723 | } while ($repeat); |
723 | } while ($repeat); |
724 | if (DB::isError($result)) { |
724 | if (DB::isError($result)) { |
725 | return $this->raiseError($result); |
725 | return $this->raiseError($result); |
726 | }
|
726 | }
|
727 | $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
727 | $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); |
728 | $result->free(); |
728 | $result->free(); |
729 | return $arr[0]; |
729 | return $arr[0]; |
730 | }
|
730 | }
|
731 | 731 | ||
732 | // }}}
|
732 | // }}}
|
733 | // {{{ createSequence()
|
733 | // {{{ createSequence()
|
734 | 734 | ||
735 | /**
|
735 | /**
|
736 | * Creates a new sequence
|
736 | * Creates a new sequence
|
737 | *
|
737 | *
|
738 | * @param string $seq_name name of the new sequence
|
738 | * @param string $seq_name name of the new sequence
|
739 | *
|
739 | *
|
740 | * @return int DB_OK on success. A DB_Error object on failure.
|
740 | * @return int DB_OK on success. A DB_Error object on failure.
|
741 | *
|
741 | *
|
742 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
742 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
743 | * DB_ibase::nextID(), DB_ibase::dropSequence()
|
743 | * DB_ibase::nextID(), DB_ibase::dropSequence()
|
744 | */
|
744 | */
|
745 | function createSequence($seq_name) |
745 | function createSequence($seq_name) |
746 | {
|
746 | {
|
747 | $sqn = strtoupper($this->getSequenceName($seq_name)); |
747 | $sqn = strtoupper($this->getSequenceName($seq_name)); |
748 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
748 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
749 | $result = $this->query("CREATE GENERATOR ${sqn}"); |
749 | $result = $this->query("CREATE GENERATOR ${sqn}"); |
750 | $this->popErrorHandling(); |
750 | $this->popErrorHandling(); |
751 | 751 | ||
752 | return $result; |
752 | return $result; |
753 | }
|
753 | }
|
754 | 754 | ||
755 | // }}}
|
755 | // }}}
|
756 | // {{{ dropSequence()
|
756 | // {{{ dropSequence()
|
757 | 757 | ||
758 | /**
|
758 | /**
|
759 | * Deletes a sequence
|
759 | * Deletes a sequence
|
760 | *
|
760 | *
|
761 | * @param string $seq_name name of the sequence to be deleted
|
761 | * @param string $seq_name name of the sequence to be deleted
|
762 | *
|
762 | *
|
763 | * @return int DB_OK on success. A DB_Error object on failure.
|
763 | * @return int DB_OK on success. A DB_Error object on failure.
|
764 | *
|
764 | *
|
765 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
765 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
766 | * DB_ibase::nextID(), DB_ibase::createSequence()
|
766 | * DB_ibase::nextID(), DB_ibase::createSequence()
|
767 | */
|
767 | */
|
768 | function dropSequence($seq_name) |
768 | function dropSequence($seq_name) |
769 | {
|
769 | {
|
770 | return $this->query('DELETE FROM RDB$GENERATORS ' |
770 | return $this->query('DELETE FROM RDB$GENERATORS ' |
771 | . "WHERE RDB\$GENERATOR_NAME='" |
771 | . "WHERE RDB\$GENERATOR_NAME='" |
772 | . strtoupper($this->getSequenceName($seq_name)) |
772 | . strtoupper($this->getSequenceName($seq_name)) |
773 | . "'"); |
773 | . "'"); |
774 | }
|
774 | }
|
775 | 775 | ||
776 | // }}}
|
776 | // }}}
|
777 | // {{{ _ibaseFieldFlags()
|
777 | // {{{ _ibaseFieldFlags()
|
778 | 778 | ||
779 | /**
|
779 | /**
|
780 | * Get the column's flags
|
780 | * Get the column's flags
|
781 | *
|
781 | *
|
782 | * Supports "primary_key", "unique_key", "not_null", "default",
|
782 | * Supports "primary_key", "unique_key", "not_null", "default",
|
783 | * "computed" and "blob".
|
783 | * "computed" and "blob".
|
784 | *
|
784 | *
|
785 | * @param string $field_name the name of the field
|
785 | * @param string $field_name the name of the field
|
786 | * @param string $table_name the name of the table
|
786 | * @param string $table_name the name of the table
|
787 | *
|
787 | *
|
788 | * @return string the flags
|
788 | * @return string the flags
|
789 | *
|
789 | *
|
790 | * @access private
|
790 | * @access private
|
791 | */
|
791 | */
|
792 | function _ibaseFieldFlags($field_name, $table_name) |
792 | function _ibaseFieldFlags($field_name, $table_name) |
793 | {
|
793 | {
|
794 | $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' |
794 | $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' |
795 | .' FROM RDB$INDEX_SEGMENTS I' |
795 | .' FROM RDB$INDEX_SEGMENTS I' |
796 | .' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' |
796 | .' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' |
797 | .' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' |
797 | .' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' |
798 | .' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; |
798 | .' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; |
799 | 799 | ||
800 | $result = @ibase_query($this->connection, $sql); |
800 | $result = @ibase_query($this->connection, $sql); |
801 | if (!$result) { |
801 | if (!$result) { |
802 | return $this->ibaseRaiseError(); |
802 | return $this->ibaseRaiseError(); |
803 | }
|
803 | }
|
804 | 804 | ||
805 | $flags = ''; |
805 | $flags = ''; |
806 | if ($obj = @ibase_fetch_object($result)) { |
806 | if ($obj = @ibase_fetch_object($result)) { |
807 | @ibase_free_result($result); |
807 | @ibase_free_result($result); |
808 | if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { |
808 | if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { |
809 | $flags .= 'primary_key '; |
809 | $flags .= 'primary_key '; |
810 | }
|
810 | }
|
811 | if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { |
811 | if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { |
812 | $flags .= 'unique_key '; |
812 | $flags .= 'unique_key '; |
813 | }
|
813 | }
|
814 | }
|
814 | }
|
815 | 815 | ||
816 | $sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' |
816 | $sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' |
817 | .' R.RDB$DEFAULT_SOURCE AS DSOURCE,' |
817 | .' R.RDB$DEFAULT_SOURCE AS DSOURCE,' |
818 | .' F.RDB$FIELD_TYPE AS FTYPE,' |
818 | .' F.RDB$FIELD_TYPE AS FTYPE,' |
819 | .' F.RDB$COMPUTED_SOURCE AS CSOURCE' |
819 | .' F.RDB$COMPUTED_SOURCE AS CSOURCE' |
820 | .' FROM RDB$RELATION_FIELDS R ' |
820 | .' FROM RDB$RELATION_FIELDS R ' |
821 | .' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' |
821 | .' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' |
822 | .' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' |
822 | .' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' |
823 | .' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; |
823 | .' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; |
824 | 824 | ||
825 | $result = @ibase_query($this->connection, $sql); |
825 | $result = @ibase_query($this->connection, $sql); |
826 | if (!$result) { |
826 | if (!$result) { |
827 | return $this->ibaseRaiseError(); |
827 | return $this->ibaseRaiseError(); |
828 | }
|
828 | }
|
829 | if ($obj = @ibase_fetch_object($result)) { |
829 | if ($obj = @ibase_fetch_object($result)) { |
830 | @ibase_free_result($result); |
830 | @ibase_free_result($result); |
831 | if (isset($obj->NFLAG)) { |
831 | if (isset($obj->NFLAG)) { |
832 | $flags .= 'not_null '; |
832 | $flags .= 'not_null '; |
833 | }
|
833 | }
|
834 | if (isset($obj->DSOURCE)) { |
834 | if (isset($obj->DSOURCE)) { |
835 | $flags .= 'default '; |
835 | $flags .= 'default '; |
836 | }
|
836 | }
|
837 | if (isset($obj->CSOURCE)) { |
837 | if (isset($obj->CSOURCE)) { |
838 | $flags .= 'computed '; |
838 | $flags .= 'computed '; |
839 | }
|
839 | }
|
840 | if (isset($obj->FTYPE) && $obj->FTYPE == 261) { |
840 | if (isset($obj->FTYPE) && $obj->FTYPE == 261) { |
841 | $flags .= 'blob '; |
841 | $flags .= 'blob '; |
842 | }
|
842 | }
|
843 | }
|
843 | }
|
844 | 844 | ||
845 | return trim($flags); |
845 | return trim($flags); |
846 | }
|
846 | }
|
847 | 847 | ||
848 | // }}}
|
848 | // }}}
|
849 | // {{{ ibaseRaiseError()
|
849 | // {{{ ibaseRaiseError()
|
850 | 850 | ||
851 | /**
|
851 | /**
|
852 | * Produces a DB_Error object regarding the current problem
|
852 | * Produces a DB_Error object regarding the current problem
|
853 | *
|
853 | *
|
854 | * @param int $errno if the error is being manually raised pass a
|
854 | * @param int $errno if the error is being manually raised pass a
|
855 | * DB_ERROR* constant here. If this isn't passed
|
855 | * DB_ERROR* constant here. If this isn't passed
|
856 | * the error information gathered from the DBMS.
|
856 | * the error information gathered from the DBMS.
|
857 | *
|
857 | *
|
858 | * @return object the DB_Error object
|
858 | * @return object the DB_Error object
|
859 | *
|
859 | *
|
860 | * @see DB_common::raiseError(),
|
860 | * @see DB_common::raiseError(),
|
861 | * DB_ibase::errorNative(), DB_ibase::errorCode()
|
861 | * DB_ibase::errorNative(), DB_ibase::errorCode()
|
862 | */
|
862 | */
|
863 | function &ibaseRaiseError($errno = null) |
863 | function &ibaseRaiseError($errno = null) |
864 | {
|
864 | {
|
865 | if ($errno === null) { |
865 | if ($errno === null) { |
866 | $errno = $this->errorCode($this->errorNative()); |
866 | $errno = $this->errorCode($this->errorNative()); |
867 | }
|
867 | }
|
868 | $tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg()); |
868 | $tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg()); |
869 | return $tmp; |
869 | return $tmp; |
870 | }
|
870 | }
|
871 | 871 | ||
872 | // }}}
|
872 | // }}}
|
873 | // {{{ errorNative()
|
873 | // {{{ errorNative()
|
874 | 874 | ||
875 | /**
|
875 | /**
|
876 | * Gets the DBMS' native error code produced by the last query
|
876 | * Gets the DBMS' native error code produced by the last query
|
877 | *
|
877 | *
|
878 | * @return int the DBMS' error code. NULL if there is no error code.
|
878 | * @return int the DBMS' error code. NULL if there is no error code.
|
879 | *
|
879 | *
|
880 | * @since Method available since Release 1.7.0
|
880 | * @since Method available since Release 1.7.0
|
881 | */
|
881 | */
|
882 | function errorNative() |
882 | function errorNative() |
883 | {
|
883 | {
|
884 | if (function_exists('ibase_errcode')) { |
884 | if (function_exists('ibase_errcode')) { |
885 | return @ibase_errcode(); |
885 | return @ibase_errcode(); |
886 | }
|
886 | }
|
887 | if (preg_match('/^Dynamic SQL Error SQL error code = ([0-9-]+)/i', |
887 | if (preg_match('/^Dynamic SQL Error SQL error code = ([0-9-]+)/i', |
888 | @ibase_errmsg(), $m)) { |
888 | @ibase_errmsg(), $m)) { |
889 | return (int)$m[1]; |
889 | return (int)$m[1]; |
890 | }
|
890 | }
|
891 | return null; |
891 | return null; |
892 | }
|
892 | }
|
893 | 893 | ||
894 | // }}}
|
894 | // }}}
|
895 | // {{{ errorCode()
|
895 | // {{{ errorCode()
|
896 | 896 | ||
897 | /**
|
897 | /**
|
898 | * Maps native error codes to DB's portable ones
|
898 | * Maps native error codes to DB's portable ones
|
899 | *
|
899 | *
|
900 | * @param int $nativecode the error code returned by the DBMS
|
900 | * @param int $nativecode the error code returned by the DBMS
|
901 | *
|
901 | *
|
902 | * @return int the portable DB error code. Return DB_ERROR if the
|
902 | * @return int the portable DB error code. Return DB_ERROR if the
|
903 | * current driver doesn't have a mapping for the
|
903 | * current driver doesn't have a mapping for the
|
904 | * $nativecode submitted.
|
904 | * $nativecode submitted.
|
905 | *
|
905 | *
|
906 | * @since Method available since Release 1.7.0
|
906 | * @since Method available since Release 1.7.0
|
907 | */
|
907 | */
|
908 | function errorCode($nativecode = null) |
908 | function errorCode($nativecode = null) |
909 | {
|
909 | {
|
910 | if (isset($this->errorcode_map[$nativecode])) { |
910 | if (isset($this->errorcode_map[$nativecode])) { |
911 | return $this->errorcode_map[$nativecode]; |
911 | return $this->errorcode_map[$nativecode]; |
912 | }
|
912 | }
|
913 | 913 | ||
914 | static $error_regexps; |
914 | static $error_regexps; |
915 | if (!isset($error_regexps)) { |
915 | if (!isset($error_regexps)) { |
916 | $error_regexps = array( |
916 | $error_regexps = array( |
917 | '/generator .* is not defined/'
|
917 | '/generator .* is not defined/'
|
918 | => DB_ERROR_SYNTAX, // for compat. w ibase_errcode() |
918 | => DB_ERROR_SYNTAX, // for compat. w ibase_errcode() |
919 | '/table.*(not exist|not found|unknown)/i'
|
919 | '/table.*(not exist|not found|unknown)/i'
|
920 | => DB_ERROR_NOSUCHTABLE, |
920 | => DB_ERROR_NOSUCHTABLE, |
921 | '/table .* already exists/i'
|
921 | '/table .* already exists/i'
|
922 | => DB_ERROR_ALREADY_EXISTS, |
922 | => DB_ERROR_ALREADY_EXISTS, |
923 | '/unsuccessful metadata update .* failed attempt to store duplicate value/i'
|
923 | '/unsuccessful metadata update .* failed attempt to store duplicate value/i'
|
924 | => DB_ERROR_ALREADY_EXISTS, |
924 | => DB_ERROR_ALREADY_EXISTS, |
925 | '/unsuccessful metadata update .* not found/i'
|
925 | '/unsuccessful metadata update .* not found/i'
|
926 | => DB_ERROR_NOT_FOUND, |
926 | => DB_ERROR_NOT_FOUND, |
927 | '/validation error for column .* value "\*\*\* null/i'
|
927 | '/validation error for column .* value "\*\*\* null/i'
|
928 | => DB_ERROR_CONSTRAINT_NOT_NULL, |
928 | => DB_ERROR_CONSTRAINT_NOT_NULL, |
929 | '/violation of [\w ]+ constraint/i'
|
929 | '/violation of [\w ]+ constraint/i'
|
930 | => DB_ERROR_CONSTRAINT, |
930 | => DB_ERROR_CONSTRAINT, |
931 | '/conversion error from string/i'
|
931 | '/conversion error from string/i'
|
932 | => DB_ERROR_INVALID_NUMBER, |
932 | => DB_ERROR_INVALID_NUMBER, |
933 | '/no permission for/i'
|
933 | '/no permission for/i'
|
934 | => DB_ERROR_ACCESS_VIOLATION, |
934 | => DB_ERROR_ACCESS_VIOLATION, |
935 | '/arithmetic exception, numeric overflow, or string truncation/i'
|
935 | '/arithmetic exception, numeric overflow, or string truncation/i'
|
936 | => DB_ERROR_INVALID, |
936 | => DB_ERROR_INVALID, |
937 | '/feature is not supported/i'
|
937 | '/feature is not supported/i'
|
938 | => DB_ERROR_NOT_CAPABLE, |
938 | => DB_ERROR_NOT_CAPABLE, |
939 | ); |
939 | ); |
940 | }
|
940 | }
|
941 | 941 | ||
942 | $errormsg = @ibase_errmsg(); |
942 | $errormsg = @ibase_errmsg(); |
943 | foreach ($error_regexps as $regexp => $code) { |
943 | foreach ($error_regexps as $regexp => $code) { |
944 | if (preg_match($regexp, $errormsg)) { |
944 | if (preg_match($regexp, $errormsg)) { |
945 | return $code; |
945 | return $code; |
946 | }
|
946 | }
|
947 | }
|
947 | }
|
948 | return DB_ERROR; |
948 | return DB_ERROR; |
949 | }
|
949 | }
|
950 | 950 | ||
951 | // }}}
|
951 | // }}}
|
952 | // {{{ tableInfo()
|
952 | // {{{ tableInfo()
|
953 | 953 | ||
954 | /**
|
954 | /**
|
955 | * Returns information about a table or a result set
|
955 | * Returns information about a table or a result set
|
956 | *
|
956 | *
|
957 | * NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
957 | * NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
958 | * is a table name.
|
958 | * is a table name.
|
959 | *
|
959 | *
|
960 | * @param object|string $result DB_result object from a query or a
|
960 | * @param object|string $result DB_result object from a query or a
|
961 | * string containing the name of a table.
|
961 | * string containing the name of a table.
|
962 | * While this also accepts a query result
|
962 | * While this also accepts a query result
|
963 | * resource identifier, this behavior is
|
963 | * resource identifier, this behavior is
|
964 | * deprecated.
|
964 | * deprecated.
|
965 | * @param int $mode a valid tableInfo mode
|
965 | * @param int $mode a valid tableInfo mode
|
966 | *
|
966 | *
|
967 | * @return array an associative array with the information requested.
|
967 | * @return array an associative array with the information requested.
|
968 | * A DB_Error object on failure.
|
968 | * A DB_Error object on failure.
|
969 | *
|
969 | *
|
970 | * @see DB_common::tableInfo()
|
970 | * @see DB_common::tableInfo()
|
971 | */
|
971 | */
|
972 | function tableInfo($result, $mode = null) |
972 | function tableInfo($result, $mode = null) |
973 | {
|
973 | {
|
974 | if (is_string($result)) { |
974 | if (is_string($result)) { |
975 | /*
|
975 | /*
|
976 | * Probably received a table name.
|
976 | * Probably received a table name.
|
977 | * Create a result resource identifier.
|
977 | * Create a result resource identifier.
|
978 | */
|
978 | */
|
979 | $id = @ibase_query($this->connection, |
979 | $id = @ibase_query($this->connection, |
980 | "SELECT * FROM $result WHERE 1=0"); |
980 | "SELECT * FROM $result WHERE 1=0"); |
981 | $got_string = true; |
981 | $got_string = true; |
982 | } elseif (isset($result->result)) { |
982 | } elseif (isset($result->result)) { |
983 | /*
|
983 | /*
|
984 | * Probably received a result object.
|
984 | * Probably received a result object.
|
985 | * Extract the result resource identifier.
|
985 | * Extract the result resource identifier.
|
986 | */
|
986 | */
|
987 | $id = $result->result; |
987 | $id = $result->result; |
988 | $got_string = false; |
988 | $got_string = false; |
989 | } else { |
989 | } else { |
990 | /*
|
990 | /*
|
991 | * Probably received a result resource identifier.
|
991 | * Probably received a result resource identifier.
|
992 | * Copy it.
|
992 | * Copy it.
|
993 | * Deprecated. Here for compatibility only.
|
993 | * Deprecated. Here for compatibility only.
|
994 | */
|
994 | */
|
995 | $id = $result; |
995 | $id = $result; |
996 | $got_string = false; |
996 | $got_string = false; |
997 | }
|
997 | }
|
998 | 998 | ||
999 | if (!is_resource($id)) { |
999 | if (!is_resource($id)) { |
1000 | return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); |
1000 | return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); |
1001 | }
|
1001 | }
|
1002 | 1002 | ||
1003 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
1003 | if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
1004 | $case_func = 'strtolower'; |
1004 | $case_func = 'strtolower'; |
1005 | } else { |
1005 | } else { |
1006 | $case_func = 'strval'; |
1006 | $case_func = 'strval'; |
1007 | }
|
1007 | }
|
1008 | 1008 | ||
1009 | $count = @ibase_num_fields($id); |
1009 | $count = @ibase_num_fields($id); |
1010 | $res = array(); |
1010 | $res = array(); |
1011 | 1011 | ||
1012 | if ($mode) { |
1012 | if ($mode) { |
1013 | $res['num_fields'] = $count; |
1013 | $res['num_fields'] = $count; |
1014 | }
|
1014 | }
|
1015 | 1015 | ||
1016 | for ($i = 0; $i < $count; $i++) { |
1016 | for ($i = 0; $i < $count; $i++) { |
1017 | $info = @ibase_field_info($id, $i); |
1017 | $info = @ibase_field_info($id, $i); |
1018 | $res[$i] = array( |
1018 | $res[$i] = array( |
1019 | 'table' => $got_string ? $case_func($result) : '', |
1019 | 'table' => $got_string ? $case_func($result) : '', |
1020 | 'name' => $case_func($info['name']), |
1020 | 'name' => $case_func($info['name']), |
1021 | 'type' => $info['type'], |
1021 | 'type' => $info['type'], |
1022 | 'len' => $info['length'], |
1022 | 'len' => $info['length'], |
1023 | 'flags' => ($got_string) |
1023 | 'flags' => ($got_string) |
1024 | ? $this->_ibaseFieldFlags($info['name'], $result) |
1024 | ? $this->_ibaseFieldFlags($info['name'], $result) |
1025 | : '', |
1025 | : '', |
1026 | ); |
1026 | ); |
1027 | if ($mode & DB_TABLEINFO_ORDER) { |
1027 | if ($mode & DB_TABLEINFO_ORDER) { |
1028 | $res['order'][$res[$i]['name']] = $i; |
1028 | $res['order'][$res[$i]['name']] = $i; |
1029 | }
|
1029 | }
|
1030 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1030 | if ($mode & DB_TABLEINFO_ORDERTABLE) { |
1031 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1031 | $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
1032 | }
|
1032 | }
|
1033 | }
|
1033 | }
|
1034 | 1034 | ||
1035 | // free the result only if we were called on a table
|
1035 | // free the result only if we were called on a table
|
1036 | if ($got_string) { |
1036 | if ($got_string) { |
1037 | @ibase_free_result($id); |
1037 | @ibase_free_result($id); |
1038 | }
|
1038 | }
|
1039 | return $res; |
1039 | return $res; |
1040 | }
|
1040 | }
|
1041 | 1041 | ||
1042 | // }}}
|
1042 | // }}}
|
1043 | // {{{ getSpecialQuery()
|
1043 | // {{{ getSpecialQuery()
|
1044 | 1044 | ||
1045 | /**
|
1045 | /**
|
1046 | * Obtains the query string needed for listing a given type of objects
|
1046 | * Obtains the query string needed for listing a given type of objects
|
1047 | *
|
1047 | *
|
1048 | * @param string $type the kind of objects you want to retrieve
|
1048 | * @param string $type the kind of objects you want to retrieve
|
1049 | *
|
1049 | *
|
1050 | * @return string the SQL query string or null if the driver doesn't
|
1050 | * @return string the SQL query string or null if the driver doesn't
|
1051 | * support the object type requested
|
1051 | * support the object type requested
|
1052 | *
|
1052 | *
|
1053 | * @access protected
|
1053 | * @access protected
|
1054 | * @see DB_common::getListOf()
|
1054 | * @see DB_common::getListOf()
|
1055 | */
|
1055 | */
|
1056 | function getSpecialQuery($type) |
1056 | function getSpecialQuery($type) |
1057 | {
|
1057 | {
|
1058 | switch ($type) { |
1058 | switch ($type) { |
1059 | case 'tables': |
1059 | case 'tables': |
1060 | return 'SELECT DISTINCT R.RDB$RELATION_NAME FROM ' |
1060 | return 'SELECT DISTINCT R.RDB$RELATION_NAME FROM ' |
1061 | . 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0'; |
1061 | . 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0'; |
1062 | case 'views': |
1062 | case 'views': |
1063 | return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS'; |
1063 | return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS'; |
1064 | case 'users': |
1064 | case 'users': |
1065 | return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES'; |
1065 | return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES'; |
1066 | default: |
1066 | default: |
1067 | return null; |
1067 | return null; |
1068 | }
|
1068 | }
|
1069 | }
|
1069 | }
|
1070 | 1070 | ||
1071 | // }}}
|
1071 | // }}}
|
1072 | 1072 | ||
1073 | }
|
1073 | }
|
1074 | 1074 | ||
1075 | /*
|
1075 | /*
|
1076 | * Local variables:
|
1076 | * Local variables:
|
1077 | * tab-width: 4
|
1077 | * tab-width: 4
|
1078 | * c-basic-offset: 4
|
1078 | * c-basic-offset: 4
|
1079 | * End:
|
1079 | * End:
|
1080 | */
|
1080 | */
|
1081 | 1081 | ||
1082 | ?>
|
1082 | ?>
|
1083 | 1083 |