Редакция 2 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 2 | Редакция 66 | ||
---|---|---|---|
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 | * Contains the DB_common base class
|
6 | * Contains the DB_common base class
|
7 | *
|
7 | *
|
8 | * PHP versions 4 and 5
|
8 | * PHP versions 4 and 5
|
9 | *
|
9 | *
|
10 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
10 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
11 | * that is available through the world-wide-web at the following URI:
|
11 | * that is available through the world-wide-web at the following URI:
|
12 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
12 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
13 | * the PHP License and are unable to obtain it through the web, please
|
13 | * the PHP License and are unable to obtain it through the web, please
|
14 | * send a note to license@php.net so we can mail you a copy immediately.
|
14 | * send a note to license@php.net so we can mail you a copy immediately.
|
15 | *
|
15 | *
|
16 | * @category Database
|
16 | * @category Database
|
17 | * @package DB
|
17 | * @package DB
|
18 | * @author Stig Bakken <ssb@php.net>
|
18 | * @author Stig Bakken <ssb@php.net>
|
19 | * @author Tomas V.V. Cox <cox@idecnet.com>
|
19 | * @author Tomas V.V. Cox <cox@idecnet.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: common.php,v 1.143 2007/09/21 13:40:41 aharvey Exp $
|
23 | * @version CVS: $Id: common.php,v 1.143 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 PEAR class so it can be extended from
|
28 | * Obtain the PEAR class so it can be extended from
|
29 | */
|
29 | */
|
30 | require_once 'PEAR.php'; |
30 | require_once 'PEAR.php'; |
31 | 31 | ||
32 | /**
|
32 | /**
|
33 | * DB_common is the base class from which each database driver class extends
|
33 | * DB_common is the base class from which each database driver class extends
|
34 | *
|
34 | *
|
35 | * All common methods are declared here. If a given DBMS driver contains
|
35 | * All common methods are declared here. If a given DBMS driver contains
|
36 | * a particular method, that method will overload the one here.
|
36 | * a particular method, that method will overload the one here.
|
37 | *
|
37 | *
|
38 | * @category Database
|
38 | * @category Database
|
39 | * @package DB
|
39 | * @package DB
|
40 | * @author Stig Bakken <ssb@php.net>
|
40 | * @author Stig Bakken <ssb@php.net>
|
41 | * @author Tomas V.V. Cox <cox@idecnet.com>
|
41 | * @author Tomas V.V. Cox <cox@idecnet.com>
|
42 | * @author Daniel Convissor <danielc@php.net>
|
42 | * @author Daniel Convissor <danielc@php.net>
|
43 | * @copyright 1997-2007 The PHP Group
|
43 | * @copyright 1997-2007 The PHP Group
|
44 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
44 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
45 | * @version Release: 1.7.13
|
45 | * @version Release: 1.7.13
|
46 | * @link http://pear.php.net/package/DB
|
46 | * @link http://pear.php.net/package/DB
|
47 | */
|
47 | */
|
48 | class DB_common extends PEAR |
48 | class DB_common extends PEAR |
49 | {
|
49 | {
|
50 | // {{{ properties
|
50 | // {{{ properties
|
51 | 51 | ||
52 | /**
|
52 | /**
|
53 | * The current default fetch mode
|
53 | * The current default fetch mode
|
54 | * @var integer
|
54 | * @var integer
|
55 | */
|
55 | */
|
56 | var $fetchmode = DB_FETCHMODE_ORDERED; |
56 | var $fetchmode = DB_FETCHMODE_ORDERED; |
57 | 57 | ||
58 | /**
|
58 | /**
|
59 | * The name of the class into which results should be fetched when
|
59 | * The name of the class into which results should be fetched when
|
60 | * DB_FETCHMODE_OBJECT is in effect
|
60 | * DB_FETCHMODE_OBJECT is in effect
|
61 | *
|
61 | *
|
62 | * @var string
|
62 | * @var string
|
63 | */
|
63 | */
|
64 | var $fetchmode_object_class = 'stdClass'; |
64 | var $fetchmode_object_class = 'stdClass'; |
65 | 65 | ||
66 | /**
|
66 | /**
|
67 | * Was a connection present when the object was serialized()?
|
67 | * Was a connection present when the object was serialized()?
|
68 | * @var bool
|
68 | * @var bool
|
69 | * @see DB_common::__sleep(), DB_common::__wake()
|
69 | * @see DB_common::__sleep(), DB_common::__wake()
|
70 | */
|
70 | */
|
71 | var $was_connected = null; |
71 | var $was_connected = null; |
72 | 72 | ||
73 | /**
|
73 | /**
|
74 | * The most recently executed query
|
74 | * The most recently executed query
|
75 | * @var string
|
75 | * @var string
|
76 | */
|
76 | */
|
77 | var $last_query = ''; |
77 | var $last_query = ''; |
78 | 78 | ||
79 | /**
|
79 | /**
|
80 | * Run-time configuration options
|
80 | * Run-time configuration options
|
81 | *
|
81 | *
|
82 | * The 'optimize' option has been deprecated. Use the 'portability'
|
82 | * The 'optimize' option has been deprecated. Use the 'portability'
|
83 | * option instead.
|
83 | * option instead.
|
84 | *
|
84 | *
|
85 | * @var array
|
85 | * @var array
|
86 | * @see DB_common::setOption()
|
86 | * @see DB_common::setOption()
|
87 | */
|
87 | */
|
88 | var $options = array( |
88 | var $options = array( |
89 | 'result_buffering' => 500, |
89 | 'result_buffering' => 500, |
90 | 'persistent' => false, |
90 | 'persistent' => false, |
91 | 'ssl' => false, |
91 | 'ssl' => false, |
92 | 'debug' => 0, |
92 | 'debug' => 0, |
93 | 'seqname_format' => '%s_seq', |
93 | 'seqname_format' => '%s_seq', |
94 | 'autofree' => false, |
94 | 'autofree' => false, |
95 | 'portability' => DB_PORTABILITY_NONE, |
95 | 'portability' => DB_PORTABILITY_NONE, |
96 | 'optimize' => 'performance', // Deprecated. Use 'portability'. |
96 | 'optimize' => 'performance', // Deprecated. Use 'portability'. |
97 | ); |
97 | ); |
98 | 98 | ||
99 | /**
|
99 | /**
|
100 | * The parameters from the most recently executed query
|
100 | * The parameters from the most recently executed query
|
101 | * @var array
|
101 | * @var array
|
102 | * @since Property available since Release 1.7.0
|
102 | * @since Property available since Release 1.7.0
|
103 | */
|
103 | */
|
104 | var $last_parameters = array(); |
104 | var $last_parameters = array(); |
105 | 105 | ||
106 | /**
|
106 | /**
|
107 | * The elements from each prepared statement
|
107 | * The elements from each prepared statement
|
108 | * @var array
|
108 | * @var array
|
109 | */
|
109 | */
|
110 | var $prepare_tokens = array(); |
110 | var $prepare_tokens = array(); |
111 | 111 | ||
112 | /**
|
112 | /**
|
113 | * The data types of the various elements in each prepared statement
|
113 | * The data types of the various elements in each prepared statement
|
114 | * @var array
|
114 | * @var array
|
115 | */
|
115 | */
|
116 | var $prepare_types = array(); |
116 | var $prepare_types = array(); |
117 | 117 | ||
118 | /**
|
118 | /**
|
119 | * The prepared queries
|
119 | * The prepared queries
|
120 | * @var array
|
120 | * @var array
|
121 | */
|
121 | */
|
122 | var $prepared_queries = array(); |
122 | var $prepared_queries = array(); |
123 | 123 | ||
124 | /**
|
124 | /**
|
125 | * Flag indicating that the last query was a manipulation query.
|
125 | * Flag indicating that the last query was a manipulation query.
|
126 | * @access protected
|
126 | * @access protected
|
127 | * @var boolean
|
127 | * @var boolean
|
128 | */
|
128 | */
|
129 | var $_last_query_manip = false; |
129 | var $_last_query_manip = false; |
130 | 130 | ||
131 | /**
|
131 | /**
|
132 | * Flag indicating that the next query <em>must</em> be a manipulation
|
132 | * Flag indicating that the next query <em>must</em> be a manipulation
|
133 | * query.
|
133 | * query.
|
134 | * @access protected
|
134 | * @access protected
|
135 | * @var boolean
|
135 | * @var boolean
|
136 | */
|
136 | */
|
137 | var $_next_query_manip = false; |
137 | var $_next_query_manip = false; |
138 | 138 | ||
139 | 139 | ||
140 | // }}}
|
140 | // }}}
|
141 | // {{{ DB_common
|
141 | // {{{ DB_common
|
142 | 142 | ||
143 | /**
|
143 | /**
|
144 | * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
|
144 | * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
|
145 | *
|
145 | *
|
146 | * @return void
|
146 | * @return void
|
147 | */
|
147 | */
|
148 | function DB_common() |
148 | function DB_common() |
149 | {
|
149 | {
|
150 | $this->PEAR('DB_Error'); |
150 | $this->PEAR('DB_Error'); |
151 | }
|
151 | }
|
152 | 152 | ||
153 | // }}}
|
153 | // }}}
|
154 | // {{{ __sleep()
|
154 | // {{{ __sleep()
|
155 | 155 | ||
156 | /**
|
156 | /**
|
157 | * Automatically indicates which properties should be saved
|
157 | * Automatically indicates which properties should be saved
|
158 | * when PHP's serialize() function is called
|
158 | * when PHP's serialize() function is called
|
159 | *
|
159 | *
|
160 | * @return array the array of properties names that should be saved
|
160 | * @return array the array of properties names that should be saved
|
161 | */
|
161 | */
|
162 | function __sleep() |
162 | function __sleep() |
163 | {
|
163 | {
|
164 | if ($this->connection) { |
164 | if ($this->connection) { |
165 | // Don't disconnect(), people use serialize() for many reasons
|
165 | // Don't disconnect(), people use serialize() for many reasons
|
166 | $this->was_connected = true; |
166 | $this->was_connected = true; |
167 | } else { |
167 | } else { |
168 | $this->was_connected = false; |
168 | $this->was_connected = false; |
169 | }
|
169 | }
|
170 | if (isset($this->autocommit)) { |
170 | if (isset($this->autocommit)) { |
171 | return array('autocommit', |
171 | return array('autocommit', |
172 | 'dbsyntax', |
172 | 'dbsyntax', |
173 | 'dsn', |
173 | 'dsn', |
174 | 'features', |
174 | 'features', |
175 | 'fetchmode', |
175 | 'fetchmode', |
176 | 'fetchmode_object_class', |
176 | 'fetchmode_object_class', |
177 | 'options', |
177 | 'options', |
178 | 'was_connected', |
178 | 'was_connected', |
179 | ); |
179 | ); |
180 | } else { |
180 | } else { |
181 | return array('dbsyntax', |
181 | return array('dbsyntax', |
182 | 'dsn', |
182 | 'dsn', |
183 | 'features', |
183 | 'features', |
184 | 'fetchmode', |
184 | 'fetchmode', |
185 | 'fetchmode_object_class', |
185 | 'fetchmode_object_class', |
186 | 'options', |
186 | 'options', |
187 | 'was_connected', |
187 | 'was_connected', |
188 | ); |
188 | ); |
189 | }
|
189 | }
|
190 | }
|
190 | }
|
191 | 191 | ||
192 | // }}}
|
192 | // }}}
|
193 | // {{{ __wakeup()
|
193 | // {{{ __wakeup()
|
194 | 194 | ||
195 | /**
|
195 | /**
|
196 | * Automatically reconnects to the database when PHP's unserialize()
|
196 | * Automatically reconnects to the database when PHP's unserialize()
|
197 | * function is called
|
197 | * function is called
|
198 | *
|
198 | *
|
199 | * The reconnection attempt is only performed if the object was connected
|
199 | * The reconnection attempt is only performed if the object was connected
|
200 | * at the time PHP's serialize() function was run.
|
200 | * at the time PHP's serialize() function was run.
|
201 | *
|
201 | *
|
202 | * @return void
|
202 | * @return void
|
203 | */
|
203 | */
|
204 | function __wakeup() |
204 | function __wakeup() |
205 | {
|
205 | {
|
206 | if ($this->was_connected) { |
206 | if ($this->was_connected) { |
207 | $this->connect($this->dsn, $this->options); |
207 | $this->connect($this->dsn, $this->options); |
208 | }
|
208 | }
|
209 | }
|
209 | }
|
210 | 210 | ||
211 | // }}}
|
211 | // }}}
|
212 | // {{{ __toString()
|
212 | // {{{ __toString()
|
213 | 213 | ||
214 | /**
|
214 | /**
|
215 | * Automatic string conversion for PHP 5
|
215 | * Automatic string conversion for PHP 5
|
216 | *
|
216 | *
|
217 | * @return string a string describing the current PEAR DB object
|
217 | * @return string a string describing the current PEAR DB object
|
218 | *
|
218 | *
|
219 | * @since Method available since Release 1.7.0
|
219 | * @since Method available since Release 1.7.0
|
220 | */
|
220 | */
|
221 | function __toString() |
221 | function __toString() |
222 | {
|
222 | {
|
223 | $info = strtolower(get_class($this)); |
223 | $info = strtolower(get_class($this)); |
224 | $info .= ': (phptype=' . $this->phptype . |
224 | $info .= ': (phptype=' . $this->phptype . |
225 | ', dbsyntax=' . $this->dbsyntax . |
225 | ', dbsyntax=' . $this->dbsyntax . |
226 | ')'; |
226 | ')'; |
227 | if ($this->connection) { |
227 | if ($this->connection) { |
228 | $info .= ' [connected]'; |
228 | $info .= ' [connected]'; |
229 | }
|
229 | }
|
230 | return $info; |
230 | return $info; |
231 | }
|
231 | }
|
232 | 232 | ||
233 | // }}}
|
233 | // }}}
|
234 | // {{{ toString()
|
234 | // {{{ toString()
|
235 | 235 | ||
236 | /**
|
236 | /**
|
237 | * DEPRECATED: String conversion method
|
237 | * DEPRECATED: String conversion method
|
238 | *
|
238 | *
|
239 | * @return string a string describing the current PEAR DB object
|
239 | * @return string a string describing the current PEAR DB object
|
240 | *
|
240 | *
|
241 | * @deprecated Method deprecated in Release 1.7.0
|
241 | * @deprecated Method deprecated in Release 1.7.0
|
242 | */
|
242 | */
|
243 | function toString() |
243 | function toString() |
244 | {
|
244 | {
|
245 | return $this->__toString(); |
245 | return $this->__toString(); |
246 | }
|
246 | }
|
247 | 247 | ||
248 | // }}}
|
248 | // }}}
|
249 | // {{{ quoteString()
|
249 | // {{{ quoteString()
|
250 | 250 | ||
251 | /**
|
251 | /**
|
252 | * DEPRECATED: Quotes a string so it can be safely used within string
|
252 | * DEPRECATED: Quotes a string so it can be safely used within string
|
253 | * delimiters in a query
|
253 | * delimiters in a query
|
254 | *
|
254 | *
|
255 | * @param string $string the string to be quoted
|
255 | * @param string $string the string to be quoted
|
256 | *
|
256 | *
|
257 | * @return string the quoted string
|
257 | * @return string the quoted string
|
258 | *
|
258 | *
|
259 | * @see DB_common::quoteSmart(), DB_common::escapeSimple()
|
259 | * @see DB_common::quoteSmart(), DB_common::escapeSimple()
|
260 | * @deprecated Method deprecated some time before Release 1.2
|
260 | * @deprecated Method deprecated some time before Release 1.2
|
261 | */
|
261 | */
|
262 | function quoteString($string) |
262 | function quoteString($string) |
263 | {
|
263 | {
|
264 | $string = $this->quote($string); |
264 | $string = $this->quote($string); |
265 | if ($string{0} == "'") { |
265 | if ($string{0} == "'") { |
266 | return substr($string, 1, -1); |
266 | return substr($string, 1, -1); |
267 | }
|
267 | }
|
268 | return $string; |
268 | return $string; |
269 | }
|
269 | }
|
270 | 270 | ||
271 | // }}}
|
271 | // }}}
|
272 | // {{{ quote()
|
272 | // {{{ quote()
|
273 | 273 | ||
274 | /**
|
274 | /**
|
275 | * DEPRECATED: Quotes a string so it can be safely used in a query
|
275 | * DEPRECATED: Quotes a string so it can be safely used in a query
|
276 | *
|
276 | *
|
277 | * @param string $string the string to quote
|
277 | * @param string $string the string to quote
|
278 | *
|
278 | *
|
279 | * @return string the quoted string or the string <samp>NULL</samp>
|
279 | * @return string the quoted string or the string <samp>NULL</samp>
|
280 | * if the value submitted is <kbd>null</kbd>.
|
280 | * if the value submitted is <kbd>null</kbd>.
|
281 | *
|
281 | *
|
282 | * @see DB_common::quoteSmart(), DB_common::escapeSimple()
|
282 | * @see DB_common::quoteSmart(), DB_common::escapeSimple()
|
283 | * @deprecated Deprecated in release 1.6.0
|
283 | * @deprecated Deprecated in release 1.6.0
|
284 | */
|
284 | */
|
285 | function quote($string = null) |
285 | function quote($string = null) |
286 | {
|
286 | {
|
287 | return ($string === null) ? 'NULL' |
287 | return ($string === null) ? 'NULL' |
288 | : "'" . str_replace("'", "''", $string) . "'"; |
288 | : "'" . str_replace("'", "''", $string) . "'"; |
289 | }
|
289 | }
|
290 | 290 | ||
291 | // }}}
|
291 | // }}}
|
292 | // {{{ quoteIdentifier()
|
292 | // {{{ quoteIdentifier()
|
293 | 293 | ||
294 | /**
|
294 | /**
|
295 | * Quotes a string so it can be safely used as a table or column name
|
295 | * Quotes a string so it can be safely used as a table or column name
|
296 | *
|
296 | *
|
297 | * Delimiting style depends on which database driver is being used.
|
297 | * Delimiting style depends on which database driver is being used.
|
298 | *
|
298 | *
|
299 | * NOTE: just because you CAN use delimited identifiers doesn't mean
|
299 | * NOTE: just because you CAN use delimited identifiers doesn't mean
|
300 | * you SHOULD use them. In general, they end up causing way more
|
300 | * you SHOULD use them. In general, they end up causing way more
|
301 | * problems than they solve.
|
301 | * problems than they solve.
|
302 | *
|
302 | *
|
303 | * Portability is broken by using the following characters inside
|
303 | * Portability is broken by using the following characters inside
|
304 | * delimited identifiers:
|
304 | * delimited identifiers:
|
305 | * + backtick (<kbd>`</kbd>) -- due to MySQL
|
305 | * + backtick (<kbd>`</kbd>) -- due to MySQL
|
306 | * + double quote (<kbd>"</kbd>) -- due to Oracle
|
306 | * + double quote (<kbd>"</kbd>) -- due to Oracle
|
307 | * + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
|
307 | * + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
|
308 | *
|
308 | *
|
309 | * Delimited identifiers are known to generally work correctly under
|
309 | * Delimited identifiers are known to generally work correctly under
|
310 | * the following drivers:
|
310 | * the following drivers:
|
311 | * + mssql
|
311 | * + mssql
|
312 | * + mysql
|
312 | * + mysql
|
313 | * + mysqli
|
313 | * + mysqli
|
314 | * + oci8
|
314 | * + oci8
|
315 | * + odbc(access)
|
315 | * + odbc(access)
|
316 | * + odbc(db2)
|
316 | * + odbc(db2)
|
317 | * + pgsql
|
317 | * + pgsql
|
318 | * + sqlite
|
318 | * + sqlite
|
319 | * + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime
|
319 | * + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime
|
320 | * prior to use)
|
320 | * prior to use)
|
321 | *
|
321 | *
|
322 | * InterBase doesn't seem to be able to use delimited identifiers
|
322 | * InterBase doesn't seem to be able to use delimited identifiers
|
323 | * via PHP 4. They work fine under PHP 5.
|
323 | * via PHP 4. They work fine under PHP 5.
|
324 | *
|
324 | *
|
325 | * @param string $str the identifier name to be quoted
|
325 | * @param string $str the identifier name to be quoted
|
326 | *
|
326 | *
|
327 | * @return string the quoted identifier
|
327 | * @return string the quoted identifier
|
328 | *
|
328 | *
|
329 | * @since Method available since Release 1.6.0
|
329 | * @since Method available since Release 1.6.0
|
330 | */
|
330 | */
|
331 | function quoteIdentifier($str) |
331 | function quoteIdentifier($str) |
332 | {
|
332 | {
|
333 | return '"' . str_replace('"', '""', $str) . '"'; |
333 | return '"' . str_replace('"', '""', $str) . '"'; |
334 | }
|
334 | }
|
335 | 335 | ||
336 | // }}}
|
336 | // }}}
|
337 | // {{{ quoteSmart()
|
337 | // {{{ quoteSmart()
|
338 | 338 | ||
339 | /**
|
339 | /**
|
340 | * Formats input so it can be safely used in a query
|
340 | * Formats input so it can be safely used in a query
|
341 | *
|
341 | *
|
342 | * The output depends on the PHP data type of input and the database
|
342 | * The output depends on the PHP data type of input and the database
|
343 | * type being used.
|
343 | * type being used.
|
344 | *
|
344 | *
|
345 | * @param mixed $in the data to be formatted
|
345 | * @param mixed $in the data to be formatted
|
346 | *
|
346 | *
|
347 | * @return mixed the formatted data. The format depends on the input's
|
347 | * @return mixed the formatted data. The format depends on the input's
|
348 | * PHP type:
|
348 | * PHP type:
|
349 | * <ul>
|
349 | * <ul>
|
350 | * <li>
|
350 | * <li>
|
351 | * <kbd>input</kbd> -> <samp>returns</samp>
|
351 | * <kbd>input</kbd> -> <samp>returns</samp>
|
352 | * </li>
|
352 | * </li>
|
353 | * <li>
|
353 | * <li>
|
354 | * <kbd>null</kbd> -> the string <samp>NULL</samp>
|
354 | * <kbd>null</kbd> -> the string <samp>NULL</samp>
|
355 | * </li>
|
355 | * </li>
|
356 | * <li>
|
356 | * <li>
|
357 | * <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
|
357 | * <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
|
358 | * </li>
|
358 | * </li>
|
359 | * <li>
|
359 | * <li>
|
360 | * <kbd>bool</kbd> -> output depends on the driver in use
|
360 | * <kbd>bool</kbd> -> output depends on the driver in use
|
361 | * Most drivers return integers: <samp>1</samp> if
|
361 | * Most drivers return integers: <samp>1</samp> if
|
362 | * <kbd>true</kbd> or <samp>0</samp> if
|
362 | * <kbd>true</kbd> or <samp>0</samp> if
|
363 | * <kbd>false</kbd>.
|
363 | * <kbd>false</kbd>.
|
364 | * Some return strings: <samp>TRUE</samp> if
|
364 | * Some return strings: <samp>TRUE</samp> if
|
365 | * <kbd>true</kbd> or <samp>FALSE</samp> if
|
365 | * <kbd>true</kbd> or <samp>FALSE</samp> if
|
366 | * <kbd>false</kbd>.
|
366 | * <kbd>false</kbd>.
|
367 | * Finally one returns strings: <samp>T</samp> if
|
367 | * Finally one returns strings: <samp>T</samp> if
|
368 | * <kbd>true</kbd> or <samp>F</samp> if
|
368 | * <kbd>true</kbd> or <samp>F</samp> if
|
369 | * <kbd>false</kbd>. Here is a list of each DBMS,
|
369 | * <kbd>false</kbd>. Here is a list of each DBMS,
|
370 | * the values returned and the suggested column type:
|
370 | * the values returned and the suggested column type:
|
371 | * <ul>
|
371 | * <ul>
|
372 | * <li>
|
372 | * <li>
|
373 | * <kbd>dbase</kbd> -> <samp>T/F</samp>
|
373 | * <kbd>dbase</kbd> -> <samp>T/F</samp>
|
374 | * (<kbd>Logical</kbd>)
|
374 | * (<kbd>Logical</kbd>)
|
375 | * </li>
|
375 | * </li>
|
376 | * <li>
|
376 | * <li>
|
377 | * <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
|
377 | * <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
|
378 | * (<kbd>BOOLEAN</kbd>)
|
378 | * (<kbd>BOOLEAN</kbd>)
|
379 | * </li>
|
379 | * </li>
|
380 | * <li>
|
380 | * <li>
|
381 | * <kbd>ibase</kbd> -> <samp>1/0</samp>
|
381 | * <kbd>ibase</kbd> -> <samp>1/0</samp>
|
382 | * (<kbd>SMALLINT</kbd>) [1]
|
382 | * (<kbd>SMALLINT</kbd>) [1]
|
383 | * </li>
|
383 | * </li>
|
384 | * <li>
|
384 | * <li>
|
385 | * <kbd>ifx</kbd> -> <samp>1/0</samp>
|
385 | * <kbd>ifx</kbd> -> <samp>1/0</samp>
|
386 | * (<kbd>SMALLINT</kbd>) [1]
|
386 | * (<kbd>SMALLINT</kbd>) [1]
|
387 | * </li>
|
387 | * </li>
|
388 | * <li>
|
388 | * <li>
|
389 | * <kbd>msql</kbd> -> <samp>1/0</samp>
|
389 | * <kbd>msql</kbd> -> <samp>1/0</samp>
|
390 | * (<kbd>INTEGER</kbd>)
|
390 | * (<kbd>INTEGER</kbd>)
|
391 | * </li>
|
391 | * </li>
|
392 | * <li>
|
392 | * <li>
|
393 | * <kbd>mssql</kbd> -> <samp>1/0</samp>
|
393 | * <kbd>mssql</kbd> -> <samp>1/0</samp>
|
394 | * (<kbd>BIT</kbd>)
|
394 | * (<kbd>BIT</kbd>)
|
395 | * </li>
|
395 | * </li>
|
396 | * <li>
|
396 | * <li>
|
397 | * <kbd>mysql</kbd> -> <samp>1/0</samp>
|
397 | * <kbd>mysql</kbd> -> <samp>1/0</samp>
|
398 | * (<kbd>TINYINT(1)</kbd>)
|
398 | * (<kbd>TINYINT(1)</kbd>)
|
399 | * </li>
|
399 | * </li>
|
400 | * <li>
|
400 | * <li>
|
401 | * <kbd>mysqli</kbd> -> <samp>1/0</samp>
|
401 | * <kbd>mysqli</kbd> -> <samp>1/0</samp>
|
402 | * (<kbd>TINYINT(1)</kbd>)
|
402 | * (<kbd>TINYINT(1)</kbd>)
|
403 | * </li>
|
403 | * </li>
|
404 | * <li>
|
404 | * <li>
|
405 | * <kbd>oci8</kbd> -> <samp>1/0</samp>
|
405 | * <kbd>oci8</kbd> -> <samp>1/0</samp>
|
406 | * (<kbd>NUMBER(1)</kbd>)
|
406 | * (<kbd>NUMBER(1)</kbd>)
|
407 | * </li>
|
407 | * </li>
|
408 | * <li>
|
408 | * <li>
|
409 | * <kbd>odbc</kbd> -> <samp>1/0</samp>
|
409 | * <kbd>odbc</kbd> -> <samp>1/0</samp>
|
410 | * (<kbd>SMALLINT</kbd>) [1]
|
410 | * (<kbd>SMALLINT</kbd>) [1]
|
411 | * </li>
|
411 | * </li>
|
412 | * <li>
|
412 | * <li>
|
413 | * <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
|
413 | * <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
|
414 | * (<kbd>BOOLEAN</kbd>)
|
414 | * (<kbd>BOOLEAN</kbd>)
|
415 | * </li>
|
415 | * </li>
|
416 | * <li>
|
416 | * <li>
|
417 | * <kbd>sqlite</kbd> -> <samp>1/0</samp>
|
417 | * <kbd>sqlite</kbd> -> <samp>1/0</samp>
|
418 | * (<kbd>INTEGER</kbd>)
|
418 | * (<kbd>INTEGER</kbd>)
|
419 | * </li>
|
419 | * </li>
|
420 | * <li>
|
420 | * <li>
|
421 | * <kbd>sybase</kbd> -> <samp>1/0</samp>
|
421 | * <kbd>sybase</kbd> -> <samp>1/0</samp>
|
422 | * (<kbd>TINYINT(1)</kbd>)
|
422 | * (<kbd>TINYINT(1)</kbd>)
|
423 | * </li>
|
423 | * </li>
|
424 | * </ul>
|
424 | * </ul>
|
425 | * [1] Accommodate the lowest common denominator because not all
|
425 | * [1] Accommodate the lowest common denominator because not all
|
426 | * versions of have <kbd>BOOLEAN</kbd>.
|
426 | * versions of have <kbd>BOOLEAN</kbd>.
|
427 | * </li>
|
427 | * </li>
|
428 | * <li>
|
428 | * <li>
|
429 | * other (including strings and numeric strings) ->
|
429 | * other (including strings and numeric strings) ->
|
430 | * the data with single quotes escaped by preceeding
|
430 | * the data with single quotes escaped by preceeding
|
431 | * single quotes, backslashes are escaped by preceeding
|
431 | * single quotes, backslashes are escaped by preceeding
|
432 | * backslashes, then the whole string is encapsulated
|
432 | * backslashes, then the whole string is encapsulated
|
433 | * between single quotes
|
433 | * between single quotes
|
434 | * </li>
|
434 | * </li>
|
435 | * </ul>
|
435 | * </ul>
|
436 | *
|
436 | *
|
437 | * @see DB_common::escapeSimple()
|
437 | * @see DB_common::escapeSimple()
|
438 | * @since Method available since Release 1.6.0
|
438 | * @since Method available since Release 1.6.0
|
439 | */
|
439 | */
|
440 | function quoteSmart($in) |
440 | function quoteSmart($in) |
441 | {
|
441 | {
|
442 | if (is_int($in)) { |
442 | if (is_int($in)) { |
443 | return $in; |
443 | return $in; |
444 | } elseif (is_float($in)) { |
444 | } elseif (is_float($in)) { |
445 | return $this->quoteFloat($in); |
445 | return $this->quoteFloat($in); |
446 | } elseif (is_bool($in)) { |
446 | } elseif (is_bool($in)) { |
447 | return $this->quoteBoolean($in); |
447 | return $this->quoteBoolean($in); |
448 | } elseif (is_null($in)) { |
448 | } elseif (is_null($in)) { |
449 | return 'NULL'; |
449 | return 'NULL'; |
450 | } else { |
450 | } else { |
451 | if ($this->dbsyntax == 'access' |
451 | if ($this->dbsyntax == 'access' |
452 | && preg_match('/^#.+#$/', $in)) |
452 | && preg_match('/^#.+#$/', $in)) |
453 | {
|
453 | {
|
454 | return $this->escapeSimple($in); |
454 | return $this->escapeSimple($in); |
455 | }
|
455 | }
|
456 | return "'" . $this->escapeSimple($in) . "'"; |
456 | return "'" . $this->escapeSimple($in) . "'"; |
457 | }
|
457 | }
|
458 | }
|
458 | }
|
459 | 459 | ||
460 | // }}}
|
460 | // }}}
|
461 | // {{{ quoteBoolean()
|
461 | // {{{ quoteBoolean()
|
462 | 462 | ||
463 | /**
|
463 | /**
|
464 | * Formats a boolean value for use within a query in a locale-independent
|
464 | * Formats a boolean value for use within a query in a locale-independent
|
465 | * manner.
|
465 | * manner.
|
466 | *
|
466 | *
|
467 | * @param boolean the boolean value to be quoted.
|
467 | * @param boolean the boolean value to be quoted.
|
468 | * @return string the quoted string.
|
468 | * @return string the quoted string.
|
469 | * @see DB_common::quoteSmart()
|
469 | * @see DB_common::quoteSmart()
|
470 | * @since Method available since release 1.7.8.
|
470 | * @since Method available since release 1.7.8.
|
471 | */
|
471 | */
|
472 | function quoteBoolean($boolean) { |
472 | function quoteBoolean($boolean) { |
473 | return $boolean ? '1' : '0'; |
473 | return $boolean ? '1' : '0'; |
474 | }
|
474 | }
|
475 | 475 | ||
476 | // }}}
|
476 | // }}}
|
477 | // {{{ quoteFloat()
|
477 | // {{{ quoteFloat()
|
478 | 478 | ||
479 | /**
|
479 | /**
|
480 | * Formats a float value for use within a query in a locale-independent
|
480 | * Formats a float value for use within a query in a locale-independent
|
481 | * manner.
|
481 | * manner.
|
482 | *
|
482 | *
|
483 | * @param float the float value to be quoted.
|
483 | * @param float the float value to be quoted.
|
484 | * @return string the quoted string.
|
484 | * @return string the quoted string.
|
485 | * @see DB_common::quoteSmart()
|
485 | * @see DB_common::quoteSmart()
|
486 | * @since Method available since release 1.7.8.
|
486 | * @since Method available since release 1.7.8.
|
487 | */
|
487 | */
|
488 | function quoteFloat($float) { |
488 | function quoteFloat($float) { |
489 | return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'"; |
489 | return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'"; |
490 | }
|
490 | }
|
491 | 491 | ||
492 | // }}}
|
492 | // }}}
|
493 | // {{{ escapeSimple()
|
493 | // {{{ escapeSimple()
|
494 | 494 | ||
495 | /**
|
495 | /**
|
496 | * Escapes a string according to the current DBMS's standards
|
496 | * Escapes a string according to the current DBMS's standards
|
497 | *
|
497 | *
|
498 | * In SQLite, this makes things safe for inserts/updates, but may
|
498 | * In SQLite, this makes things safe for inserts/updates, but may
|
499 | * cause problems when performing text comparisons against columns
|
499 | * cause problems when performing text comparisons against columns
|
500 | * containing binary data. See the
|
500 | * containing binary data. See the
|
501 | * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
|
501 | * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
|
502 | *
|
502 | *
|
503 | * @param string $str the string to be escaped
|
503 | * @param string $str the string to be escaped
|
504 | *
|
504 | *
|
505 | * @return string the escaped string
|
505 | * @return string the escaped string
|
506 | *
|
506 | *
|
507 | * @see DB_common::quoteSmart()
|
507 | * @see DB_common::quoteSmart()
|
508 | * @since Method available since Release 1.6.0
|
508 | * @since Method available since Release 1.6.0
|
509 | */
|
509 | */
|
510 | function escapeSimple($str) |
510 | function escapeSimple($str) |
511 | {
|
511 | {
|
512 | return str_replace("'", "''", $str); |
512 | return str_replace("'", "''", $str); |
513 | }
|
513 | }
|
514 | 514 | ||
515 | // }}}
|
515 | // }}}
|
516 | // {{{ provides()
|
516 | // {{{ provides()
|
517 | 517 | ||
518 | /**
|
518 | /**
|
519 | * Tells whether the present driver supports a given feature
|
519 | * Tells whether the present driver supports a given feature
|
520 | *
|
520 | *
|
521 | * @param string $feature the feature you're curious about
|
521 | * @param string $feature the feature you're curious about
|
522 | *
|
522 | *
|
523 | * @return bool whether this driver supports $feature
|
523 | * @return bool whether this driver supports $feature
|
524 | */
|
524 | */
|
525 | function provides($feature) |
525 | function provides($feature) |
526 | {
|
526 | {
|
527 | return $this->features[$feature]; |
527 | return $this->features[$feature]; |
528 | }
|
528 | }
|
529 | 529 | ||
530 | // }}}
|
530 | // }}}
|
531 | // {{{ setFetchMode()
|
531 | // {{{ setFetchMode()
|
532 | 532 | ||
533 | /**
|
533 | /**
|
534 | * Sets the fetch mode that should be used by default for query results
|
534 | * Sets the fetch mode that should be used by default for query results
|
535 | *
|
535 | *
|
536 | * @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
|
536 | * @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
|
537 | * or DB_FETCHMODE_OBJECT
|
537 | * or DB_FETCHMODE_OBJECT
|
538 | * @param string $object_class the class name of the object to be returned
|
538 | * @param string $object_class the class name of the object to be returned
|
539 | * by the fetch methods when the
|
539 | * by the fetch methods when the
|
540 | * DB_FETCHMODE_OBJECT mode is selected.
|
540 | * DB_FETCHMODE_OBJECT mode is selected.
|
541 | * If no class is specified by default a cast
|
541 | * If no class is specified by default a cast
|
542 | * to object from the assoc array row will be
|
542 | * to object from the assoc array row will be
|
543 | * done. There is also the posibility to use
|
543 | * done. There is also the posibility to use
|
544 | * and extend the 'DB_row' class.
|
544 | * and extend the 'DB_row' class.
|
545 | *
|
545 | *
|
546 | * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
|
546 | * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
|
547 | */
|
547 | */
|
548 | function setFetchMode($fetchmode, $object_class = 'stdClass') |
548 | function setFetchMode($fetchmode, $object_class = 'stdClass') |
549 | {
|
549 | {
|
550 | switch ($fetchmode) { |
550 | switch ($fetchmode) { |
551 | case DB_FETCHMODE_OBJECT: |
551 | case DB_FETCHMODE_OBJECT: |
552 | $this->fetchmode_object_class = $object_class; |
552 | $this->fetchmode_object_class = $object_class; |
553 | case DB_FETCHMODE_ORDERED: |
553 | case DB_FETCHMODE_ORDERED: |
554 | case DB_FETCHMODE_ASSOC: |
554 | case DB_FETCHMODE_ASSOC: |
555 | $this->fetchmode = $fetchmode; |
555 | $this->fetchmode = $fetchmode; |
556 | break; |
556 | break; |
557 | default: |
557 | default: |
558 | return $this->raiseError('invalid fetchmode mode'); |
558 | return $this->raiseError('invalid fetchmode mode'); |
559 | }
|
559 | }
|
560 | }
|
560 | }
|
561 | 561 | ||
562 | // }}}
|
562 | // }}}
|
563 | // {{{ setOption()
|
563 | // {{{ setOption()
|
564 | 564 | ||
565 | /**
|
565 | /**
|
566 | * Sets run-time configuration options for PEAR DB
|
566 | * Sets run-time configuration options for PEAR DB
|
567 | *
|
567 | *
|
568 | * Options, their data types, default values and description:
|
568 | * Options, their data types, default values and description:
|
569 | * <ul>
|
569 | * <ul>
|
570 | * <li>
|
570 | * <li>
|
571 | * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
|
571 | * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
|
572 | * <br />should results be freed automatically when there are no
|
572 | * <br />should results be freed automatically when there are no
|
573 | * more rows?
|
573 | * more rows?
|
574 | * </li><li>
|
574 | * </li><li>
|
575 | * <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp>
|
575 | * <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp>
|
576 | * <br />how many rows of the result set should be buffered?
|
576 | * <br />how many rows of the result set should be buffered?
|
577 | * <br />In mysql: mysql_unbuffered_query() is used instead of
|
577 | * <br />In mysql: mysql_unbuffered_query() is used instead of
|
578 | * mysql_query() if this value is 0. (Release 1.7.0)
|
578 | * mysql_query() if this value is 0. (Release 1.7.0)
|
579 | * <br />In oci8: this value is passed to ocisetprefetch().
|
579 | * <br />In oci8: this value is passed to ocisetprefetch().
|
580 | * (Release 1.7.0)
|
580 | * (Release 1.7.0)
|
581 | * </li><li>
|
581 | * </li><li>
|
582 | * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
|
582 | * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
|
583 | * <br />debug level
|
583 | * <br />debug level
|
584 | * </li><li>
|
584 | * </li><li>
|
585 | * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
|
585 | * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
|
586 | * <br />should the connection be persistent?
|
586 | * <br />should the connection be persistent?
|
587 | * </li><li>
|
587 | * </li><li>
|
588 | * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
|
588 | * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
|
589 | * <br />portability mode constant (see below)
|
589 | * <br />portability mode constant (see below)
|
590 | * </li><li>
|
590 | * </li><li>
|
591 | * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
|
591 | * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
|
592 | * <br />the sprintf() format string used on sequence names. This
|
592 | * <br />the sprintf() format string used on sequence names. This
|
593 | * format is applied to sequence names passed to
|
593 | * format is applied to sequence names passed to
|
594 | * createSequence(), nextID() and dropSequence().
|
594 | * createSequence(), nextID() and dropSequence().
|
595 | * </li><li>
|
595 | * </li><li>
|
596 | * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
|
596 | * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
|
597 | * <br />use ssl to connect?
|
597 | * <br />use ssl to connect?
|
598 | * </li>
|
598 | * </li>
|
599 | * </ul>
|
599 | * </ul>
|
600 | *
|
600 | *
|
601 | * -----------------------------------------
|
601 | * -----------------------------------------
|
602 | *
|
602 | *
|
603 | * PORTABILITY MODES
|
603 | * PORTABILITY MODES
|
604 | *
|
604 | *
|
605 | * These modes are bitwised, so they can be combined using <kbd>|</kbd>
|
605 | * These modes are bitwised, so they can be combined using <kbd>|</kbd>
|
606 | * and removed using <kbd>^</kbd>. See the examples section below on how
|
606 | * and removed using <kbd>^</kbd>. See the examples section below on how
|
607 | * to do this.
|
607 | * to do this.
|
608 | *
|
608 | *
|
609 | * <samp>DB_PORTABILITY_NONE</samp>
|
609 | * <samp>DB_PORTABILITY_NONE</samp>
|
610 | * turn off all portability features
|
610 | * turn off all portability features
|
611 | *
|
611 | *
|
612 | * This mode gets automatically turned on if the deprecated
|
612 | * This mode gets automatically turned on if the deprecated
|
613 | * <var>optimize</var> option gets set to <samp>performance</samp>.
|
613 | * <var>optimize</var> option gets set to <samp>performance</samp>.
|
614 | *
|
614 | *
|
615 | *
|
615 | *
|
616 | * <samp>DB_PORTABILITY_LOWERCASE</samp>
|
616 | * <samp>DB_PORTABILITY_LOWERCASE</samp>
|
617 | * convert names of tables and fields to lower case when using
|
617 | * convert names of tables and fields to lower case when using
|
618 | * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
|
618 | * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
|
619 | *
|
619 | *
|
620 | * This mode gets automatically turned on in the following databases
|
620 | * This mode gets automatically turned on in the following databases
|
621 | * if the deprecated option <var>optimize</var> gets set to
|
621 | * if the deprecated option <var>optimize</var> gets set to
|
622 | * <samp>portability</samp>:
|
622 | * <samp>portability</samp>:
|
623 | * + oci8
|
623 | * + oci8
|
624 | *
|
624 | *
|
625 | *
|
625 | *
|
626 | * <samp>DB_PORTABILITY_RTRIM</samp>
|
626 | * <samp>DB_PORTABILITY_RTRIM</samp>
|
627 | * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
|
627 | * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
|
628 | *
|
628 | *
|
629 | *
|
629 | *
|
630 | * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
|
630 | * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
|
631 | * force reporting the number of rows deleted
|
631 | * force reporting the number of rows deleted
|
632 | *
|
632 | *
|
633 | * Some DBMS's don't count the number of rows deleted when performing
|
633 | * Some DBMS's don't count the number of rows deleted when performing
|
634 | * simple <kbd>DELETE FROM tablename</kbd> queries. This portability
|
634 | * simple <kbd>DELETE FROM tablename</kbd> queries. This portability
|
635 | * mode tricks such DBMS's into telling the count by adding
|
635 | * mode tricks such DBMS's into telling the count by adding
|
636 | * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
|
636 | * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
|
637 | *
|
637 | *
|
638 | * This mode gets automatically turned on in the following databases
|
638 | * This mode gets automatically turned on in the following databases
|
639 | * if the deprecated option <var>optimize</var> gets set to
|
639 | * if the deprecated option <var>optimize</var> gets set to
|
640 | * <samp>portability</samp>:
|
640 | * <samp>portability</samp>:
|
641 | * + fbsql
|
641 | * + fbsql
|
642 | * + mysql
|
642 | * + mysql
|
643 | * + mysqli
|
643 | * + mysqli
|
644 | * + sqlite
|
644 | * + sqlite
|
645 | *
|
645 | *
|
646 | *
|
646 | *
|
647 | * <samp>DB_PORTABILITY_NUMROWS</samp>
|
647 | * <samp>DB_PORTABILITY_NUMROWS</samp>
|
648 | * enable hack that makes <kbd>numRows()</kbd> work in Oracle
|
648 | * enable hack that makes <kbd>numRows()</kbd> work in Oracle
|
649 | *
|
649 | *
|
650 | * This mode gets automatically turned on in the following databases
|
650 | * This mode gets automatically turned on in the following databases
|
651 | * if the deprecated option <var>optimize</var> gets set to
|
651 | * if the deprecated option <var>optimize</var> gets set to
|
652 | * <samp>portability</samp>:
|
652 | * <samp>portability</samp>:
|
653 | * + oci8
|
653 | * + oci8
|
654 | *
|
654 | *
|
655 | *
|
655 | *
|
656 | * <samp>DB_PORTABILITY_ERRORS</samp>
|
656 | * <samp>DB_PORTABILITY_ERRORS</samp>
|
657 | * makes certain error messages in certain drivers compatible
|
657 | * makes certain error messages in certain drivers compatible
|
658 | * with those from other DBMS's
|
658 | * with those from other DBMS's
|
659 | *
|
659 | *
|
660 | * + mysql, mysqli: change unique/primary key constraints
|
660 | * + mysql, mysqli: change unique/primary key constraints
|
661 | * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
|
661 | * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
|
662 | *
|
662 | *
|
663 | * + odbc(access): MS's ODBC driver reports 'no such field' as code
|
663 | * + odbc(access): MS's ODBC driver reports 'no such field' as code
|
664 | * 07001, which means 'too few parameters.' When this option is on
|
664 | * 07001, which means 'too few parameters.' When this option is on
|
665 | * that code gets mapped to DB_ERROR_NOSUCHFIELD.
|
665 | * that code gets mapped to DB_ERROR_NOSUCHFIELD.
|
666 | * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
|
666 | * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
|
667 | *
|
667 | *
|
668 | * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
|
668 | * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
|
669 | * convert null values to empty strings in data output by get*() and
|
669 | * convert null values to empty strings in data output by get*() and
|
670 | * fetch*(). Needed because Oracle considers empty strings to be null,
|
670 | * fetch*(). Needed because Oracle considers empty strings to be null,
|
671 | * while most other DBMS's know the difference between empty and null.
|
671 | * while most other DBMS's know the difference between empty and null.
|
672 | *
|
672 | *
|
673 | *
|
673 | *
|
674 | * <samp>DB_PORTABILITY_ALL</samp>
|
674 | * <samp>DB_PORTABILITY_ALL</samp>
|
675 | * turn on all portability features
|
675 | * turn on all portability features
|
676 | *
|
676 | *
|
677 | * -----------------------------------------
|
677 | * -----------------------------------------
|
678 | *
|
678 | *
|
679 | * Example 1. Simple setOption() example
|
679 | * Example 1. Simple setOption() example
|
680 | * <code>
|
680 | * <code>
|
681 | * $db->setOption('autofree', true);
|
681 | * $db->setOption('autofree', true);
|
682 | * </code>
|
682 | * </code>
|
683 | *
|
683 | *
|
684 | * Example 2. Portability for lowercasing and trimming
|
684 | * Example 2. Portability for lowercasing and trimming
|
685 | * <code>
|
685 | * <code>
|
686 | * $db->setOption('portability',
|
686 | * $db->setOption('portability',
|
687 | * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
|
687 | * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
|
688 | * </code>
|
688 | * </code>
|
689 | *
|
689 | *
|
690 | * Example 3. All portability options except trimming
|
690 | * Example 3. All portability options except trimming
|
691 | * <code>
|
691 | * <code>
|
692 | * $db->setOption('portability',
|
692 | * $db->setOption('portability',
|
693 | * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
|
693 | * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
|
694 | * </code>
|
694 | * </code>
|
695 | *
|
695 | *
|
696 | * @param string $option option name
|
696 | * @param string $option option name
|
697 | * @param mixed $value value for the option
|
697 | * @param mixed $value value for the option
|
698 | *
|
698 | *
|
699 | * @return int DB_OK on success. A DB_Error object on failure.
|
699 | * @return int DB_OK on success. A DB_Error object on failure.
|
700 | *
|
700 | *
|
701 | * @see DB_common::$options
|
701 | * @see DB_common::$options
|
702 | */
|
702 | */
|
703 | function setOption($option, $value) |
703 | function setOption($option, $value) |
704 | {
|
704 | {
|
705 | if (isset($this->options[$option])) { |
705 | if (isset($this->options[$option])) { |
706 | $this->options[$option] = $value; |
706 | $this->options[$option] = $value; |
707 | 707 | ||
708 | /*
|
708 | /*
|
709 | * Backwards compatibility check for the deprecated 'optimize'
|
709 | * Backwards compatibility check for the deprecated 'optimize'
|
710 | * option. Done here in case settings change after connecting.
|
710 | * option. Done here in case settings change after connecting.
|
711 | */
|
711 | */
|
712 | if ($option == 'optimize') { |
712 | if ($option == 'optimize') { |
713 | if ($value == 'portability') { |
713 | if ($value == 'portability') { |
714 | switch ($this->phptype) { |
714 | switch ($this->phptype) { |
715 | case 'oci8': |
715 | case 'oci8': |
716 | $this->options['portability'] = |
716 | $this->options['portability'] = |
717 | DB_PORTABILITY_LOWERCASE |
|
717 | DB_PORTABILITY_LOWERCASE |
|
718 | DB_PORTABILITY_NUMROWS;
|
718 | DB_PORTABILITY_NUMROWS;
|
719 | break; |
719 | break; |
720 | case 'fbsql': |
720 | case 'fbsql': |
721 | case 'mysql': |
721 | case 'mysql': |
722 | case 'mysqli': |
722 | case 'mysqli': |
723 | case 'sqlite': |
723 | case 'sqlite': |
724 | $this->options['portability'] = |
724 | $this->options['portability'] = |
725 | DB_PORTABILITY_DELETE_COUNT;
|
725 | DB_PORTABILITY_DELETE_COUNT;
|
726 | break; |
726 | break; |
727 | }
|
727 | }
|
728 | } else { |
728 | } else { |
729 | $this->options['portability'] = DB_PORTABILITY_NONE; |
729 | $this->options['portability'] = DB_PORTABILITY_NONE; |
730 | }
|
730 | }
|
731 | }
|
731 | }
|
732 | 732 | ||
733 | return DB_OK; |
733 | return DB_OK; |
734 | }
|
734 | }
|
735 | return $this->raiseError("unknown option $option"); |
735 | return $this->raiseError("unknown option $option"); |
736 | }
|
736 | }
|
737 | 737 | ||
738 | // }}}
|
738 | // }}}
|
739 | // {{{ getOption()
|
739 | // {{{ getOption()
|
740 | 740 | ||
741 | /**
|
741 | /**
|
742 | * Returns the value of an option
|
742 | * Returns the value of an option
|
743 | *
|
743 | *
|
744 | * @param string $option the option name you're curious about
|
744 | * @param string $option the option name you're curious about
|
745 | *
|
745 | *
|
746 | * @return mixed the option's value
|
746 | * @return mixed the option's value
|
747 | */
|
747 | */
|
748 | function getOption($option) |
748 | function getOption($option) |
749 | {
|
749 | {
|
750 | if (isset($this->options[$option])) { |
750 | if (isset($this->options[$option])) { |
751 | return $this->options[$option]; |
751 | return $this->options[$option]; |
752 | }
|
752 | }
|
753 | return $this->raiseError("unknown option $option"); |
753 | return $this->raiseError("unknown option $option"); |
754 | }
|
754 | }
|
755 | 755 | ||
756 | // }}}
|
756 | // }}}
|
757 | // {{{ prepare()
|
757 | // {{{ prepare()
|
758 | 758 | ||
759 | /**
|
759 | /**
|
760 | * Prepares a query for multiple execution with execute()
|
760 | * Prepares a query for multiple execution with execute()
|
761 | *
|
761 | *
|
762 | * Creates a query that can be run multiple times. Each time it is run,
|
762 | * Creates a query that can be run multiple times. Each time it is run,
|
763 | * the placeholders, if any, will be replaced by the contents of
|
763 | * the placeholders, if any, will be replaced by the contents of
|
764 | * execute()'s $data argument.
|
764 | * execute()'s $data argument.
|
765 | *
|
765 | *
|
766 | * Three types of placeholders can be used:
|
766 | * Three types of placeholders can be used:
|
767 | * + <kbd>?</kbd> scalar value (i.e. strings, integers). The system
|
767 | * + <kbd>?</kbd> scalar value (i.e. strings, integers). The system
|
768 | * will automatically quote and escape the data.
|
768 | * will automatically quote and escape the data.
|
769 | * + <kbd>!</kbd> value is inserted 'as is'
|
769 | * + <kbd>!</kbd> value is inserted 'as is'
|
770 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
770 | * + <kbd>&</kbd> requires a file name. The file's contents get
|
771 | * inserted into the query (i.e. saving binary
|
771 | * inserted into the query (i.e. saving binary
|
772 | * data in a db)
|
772 | * data in a db)
|
773 | *
|
773 | *
|
774 | * Example 1.
|
774 | * Example 1.
|
775 | * <code>
|
775 | * <code>
|
776 | * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
|
776 | * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
|
777 | * $data = array(
|
777 | * $data = array(
|
778 | * "John's text",
|
778 | * "John's text",
|
779 | * "'it''s good'",
|
779 | * "'it''s good'",
|
780 | * 'filename.txt'
|
780 | * 'filename.txt'
|
781 | * );
|
781 | * );
|
782 | * $res = $db->execute($sth, $data);
|
782 | * $res = $db->execute($sth, $data);
|
783 | * </code>
|
783 | * </code>
|
784 | *
|
784 | *
|
785 | * Use backslashes to escape placeholder characters if you don't want
|
785 | * Use backslashes to escape placeholder characters if you don't want
|
786 | * them to be interpreted as placeholders:
|
786 | * them to be interpreted as placeholders:
|
787 | * <pre>
|
787 | * <pre>
|
788 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
788 | * "UPDATE foo SET col=? WHERE col='over \& under'"
|
789 | * </pre>
|
789 | * </pre>
|
790 | *
|
790 | *
|
791 | * With some database backends, this is emulated.
|
791 | * With some database backends, this is emulated.
|
792 | *
|
792 | *
|
793 | * {@internal ibase and oci8 have their own prepare() methods.}}
|
793 | * {@internal ibase and oci8 have their own prepare() methods.}}
|
794 | *
|
794 | *
|
795 | * @param string $query the query to be prepared
|
795 | * @param string $query the query to be prepared
|
796 | *
|
796 | *
|
797 | * @return mixed DB statement resource on success. A DB_Error object
|
797 | * @return mixed DB statement resource on success. A DB_Error object
|
798 | * on failure.
|
798 | * on failure.
|
799 | *
|
799 | *
|
800 | * @see DB_common::execute()
|
800 | * @see DB_common::execute()
|
801 | */
|
801 | */
|
802 | function prepare($query) |
802 | function prepare($query) |
803 | {
|
803 | {
|
804 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
804 | $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
805 | PREG_SPLIT_DELIM_CAPTURE); |
805 | PREG_SPLIT_DELIM_CAPTURE); |
806 | $token = 0; |
806 | $token = 0; |
807 | $types = array(); |
807 | $types = array(); |
808 | $newtokens = array(); |
808 | $newtokens = array(); |
809 | 809 | ||
810 | foreach ($tokens as $val) { |
810 | foreach ($tokens as $val) { |
811 | switch ($val) { |
811 | switch ($val) { |
812 | case '?': |
812 | case '?': |
813 | $types[$token++] = DB_PARAM_SCALAR; |
813 | $types[$token++] = DB_PARAM_SCALAR; |
814 | break; |
814 | break; |
815 | case '&': |
815 | case '&': |
816 | $types[$token++] = DB_PARAM_OPAQUE; |
816 | $types[$token++] = DB_PARAM_OPAQUE; |
817 | break; |
817 | break; |
818 | case '!': |
818 | case '!': |
819 | $types[$token++] = DB_PARAM_MISC; |
819 | $types[$token++] = DB_PARAM_MISC; |
820 | break; |
820 | break; |
821 | default: |
821 | default: |
822 | $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val); |
822 | $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val); |
823 | }
|
823 | }
|
824 | }
|
824 | }
|
825 | 825 | ||
826 | $this->prepare_tokens[] = &$newtokens; |
826 | $this->prepare_tokens[] = &$newtokens; |
827 | end($this->prepare_tokens); |
827 | end($this->prepare_tokens); |
828 | 828 | ||
829 | $k = key($this->prepare_tokens); |
829 | $k = key($this->prepare_tokens); |
830 | $this->prepare_types[$k] = $types; |
830 | $this->prepare_types[$k] = $types; |
831 | $this->prepared_queries[$k] = implode(' ', $newtokens); |
831 | $this->prepared_queries[$k] = implode(' ', $newtokens); |
832 | 832 | ||
833 | return $k; |
833 | return $k; |
834 | }
|
834 | }
|
835 | 835 | ||
836 | // }}}
|
836 | // }}}
|
837 | // {{{ autoPrepare()
|
837 | // {{{ autoPrepare()
|
838 | 838 | ||
839 | /**
|
839 | /**
|
840 | * Automaticaly generates an insert or update query and pass it to prepare()
|
840 | * Automaticaly generates an insert or update query and pass it to prepare()
|
841 | *
|
841 | *
|
842 | * @param string $table the table name
|
842 | * @param string $table the table name
|
843 | * @param array $table_fields the array of field names
|
843 | * @param array $table_fields the array of field names
|
844 | * @param int $mode a type of query to make:
|
844 | * @param int $mode a type of query to make:
|
845 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
845 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
846 | * @param string $where for update queries: the WHERE clause to
|
846 | * @param string $where for update queries: the WHERE clause to
|
847 | * append to the SQL statement. Don't
|
847 | * append to the SQL statement. Don't
|
848 | * include the "WHERE" keyword.
|
848 | * include the "WHERE" keyword.
|
849 | *
|
849 | *
|
850 | * @return resource the query handle
|
850 | * @return resource the query handle
|
851 | *
|
851 | *
|
852 | * @uses DB_common::prepare(), DB_common::buildManipSQL()
|
852 | * @uses DB_common::prepare(), DB_common::buildManipSQL()
|
853 | */
|
853 | */
|
854 | function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, |
854 | function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, |
855 | $where = false) |
855 | $where = false) |
856 | {
|
856 | {
|
857 | $query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
857 | $query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
858 | if (DB::isError($query)) { |
858 | if (DB::isError($query)) { |
859 | return $query; |
859 | return $query; |
860 | }
|
860 | }
|
861 | return $this->prepare($query); |
861 | return $this->prepare($query); |
862 | }
|
862 | }
|
863 | 863 | ||
864 | // }}}
|
864 | // }}}
|
865 | // {{{ autoExecute()
|
865 | // {{{ autoExecute()
|
866 | 866 | ||
867 | /**
|
867 | /**
|
868 | * Automaticaly generates an insert or update query and call prepare()
|
868 | * Automaticaly generates an insert or update query and call prepare()
|
869 | * and execute() with it
|
869 | * and execute() with it
|
870 | *
|
870 | *
|
871 | * @param string $table the table name
|
871 | * @param string $table the table name
|
872 | * @param array $fields_values the associative array where $key is a
|
872 | * @param array $fields_values the associative array where $key is a
|
873 | * field name and $value its value
|
873 | * field name and $value its value
|
874 | * @param int $mode a type of query to make:
|
874 | * @param int $mode a type of query to make:
|
875 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
875 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
876 | * @param string $where for update queries: the WHERE clause to
|
876 | * @param string $where for update queries: the WHERE clause to
|
877 | * append to the SQL statement. Don't
|
877 | * append to the SQL statement. Don't
|
878 | * include the "WHERE" keyword.
|
878 | * include the "WHERE" keyword.
|
879 | *
|
879 | *
|
880 | * @return mixed a new DB_result object for successful SELECT queries
|
880 | * @return mixed a new DB_result object for successful SELECT queries
|
881 | * or DB_OK for successul data manipulation queries.
|
881 | * or DB_OK for successul data manipulation queries.
|
882 | * A DB_Error object on failure.
|
882 | * A DB_Error object on failure.
|
883 | *
|
883 | *
|
884 | * @uses DB_common::autoPrepare(), DB_common::execute()
|
884 | * @uses DB_common::autoPrepare(), DB_common::execute()
|
885 | */
|
885 | */
|
886 | function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, |
886 | function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, |
887 | $where = false) |
887 | $where = false) |
888 | {
|
888 | {
|
889 | $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, |
889 | $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, |
890 | $where); |
890 | $where); |
891 | if (DB::isError($sth)) { |
891 | if (DB::isError($sth)) { |
892 | return $sth; |
892 | return $sth; |
893 | }
|
893 | }
|
894 | $ret = $this->execute($sth, array_values($fields_values)); |
894 | $ret = $this->execute($sth, array_values($fields_values)); |
895 | $this->freePrepared($sth); |
895 | $this->freePrepared($sth); |
896 | return $ret; |
896 | return $ret; |
897 | 897 | ||
898 | }
|
898 | }
|
899 | 899 | ||
900 | // }}}
|
900 | // }}}
|
901 | // {{{ buildManipSQL()
|
901 | // {{{ buildManipSQL()
|
902 | 902 | ||
903 | /**
|
903 | /**
|
904 | * Produces an SQL query string for autoPrepare()
|
904 | * Produces an SQL query string for autoPrepare()
|
905 | *
|
905 | *
|
906 | * Example:
|
906 | * Example:
|
907 | * <pre>
|
907 | * <pre>
|
908 | * buildManipSQL('table_sql', array('field1', 'field2', 'field3'),
|
908 | * buildManipSQL('table_sql', array('field1', 'field2', 'field3'),
|
909 | * DB_AUTOQUERY_INSERT);
|
909 | * DB_AUTOQUERY_INSERT);
|
910 | * </pre>
|
910 | * </pre>
|
911 | *
|
911 | *
|
912 | * That returns
|
912 | * That returns
|
913 | * <samp>
|
913 | * <samp>
|
914 | * INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
|
914 | * INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
|
915 | * </samp>
|
915 | * </samp>
|
916 | *
|
916 | *
|
917 | * NOTES:
|
917 | * NOTES:
|
918 | * - This belongs more to a SQL Builder class, but this is a simple
|
918 | * - This belongs more to a SQL Builder class, but this is a simple
|
919 | * facility.
|
919 | * facility.
|
920 | * - Be carefull! If you don't give a $where param with an UPDATE
|
920 | * - Be carefull! If you don't give a $where param with an UPDATE
|
921 | * query, all the records of the table will be updated!
|
921 | * query, all the records of the table will be updated!
|
922 | *
|
922 | *
|
923 | * @param string $table the table name
|
923 | * @param string $table the table name
|
924 | * @param array $table_fields the array of field names
|
924 | * @param array $table_fields the array of field names
|
925 | * @param int $mode a type of query to make:
|
925 | * @param int $mode a type of query to make:
|
926 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
926 | * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
|
927 | * @param string $where for update queries: the WHERE clause to
|
927 | * @param string $where for update queries: the WHERE clause to
|
928 | * append to the SQL statement. Don't
|
928 | * append to the SQL statement. Don't
|
929 | * include the "WHERE" keyword.
|
929 | * include the "WHERE" keyword.
|
930 | *
|
930 | *
|
931 | * @return string the sql query for autoPrepare()
|
931 | * @return string the sql query for autoPrepare()
|
932 | */
|
932 | */
|
933 | function buildManipSQL($table, $table_fields, $mode, $where = false) |
933 | function buildManipSQL($table, $table_fields, $mode, $where = false) |
934 | {
|
934 | {
|
935 | if (count($table_fields) == 0) { |
935 | if (count($table_fields) == 0) { |
936 | return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
936 | return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
937 | }
|
937 | }
|
938 | $first = true; |
938 | $first = true; |
939 | switch ($mode) { |
939 | switch ($mode) { |
940 | case DB_AUTOQUERY_INSERT: |
940 | case DB_AUTOQUERY_INSERT: |
941 | $values = ''; |
941 | $values = ''; |
942 | $names = ''; |
942 | $names = ''; |
943 | foreach ($table_fields as $value) { |
943 | foreach ($table_fields as $value) { |
944 | if ($first) { |
944 | if ($first) { |
945 | $first = false; |
945 | $first = false; |
946 | } else { |
946 | } else { |
947 | $names .= ','; |
947 | $names .= ','; |
948 | $values .= ','; |
948 | $values .= ','; |
949 | }
|
949 | }
|
950 | $names .= $value; |
950 | $names .= $value; |
951 | $values .= '?'; |
951 | $values .= '?'; |
952 | }
|
952 | }
|
953 | return "INSERT INTO $table ($names) VALUES ($values)"; |
953 | return "INSERT INTO $table ($names) VALUES ($values)"; |
954 | case DB_AUTOQUERY_UPDATE: |
954 | case DB_AUTOQUERY_UPDATE: |
955 | $set = ''; |
955 | $set = ''; |
956 | foreach ($table_fields as $value) { |
956 | foreach ($table_fields as $value) { |
957 | if ($first) { |
957 | if ($first) { |
958 | $first = false; |
958 | $first = false; |
959 | } else { |
959 | } else { |
960 | $set .= ','; |
960 | $set .= ','; |
961 | }
|
961 | }
|
962 | $set .= "$value = ?"; |
962 | $set .= "$value = ?"; |
963 | }
|
963 | }
|
964 | $sql = "UPDATE $table SET $set"; |
964 | $sql = "UPDATE $table SET $set"; |
965 | if ($where) { |
965 | if ($where) { |
966 | $sql .= " WHERE $where"; |
966 | $sql .= " WHERE $where"; |
967 | }
|
967 | }
|
968 | return $sql; |
968 | return $sql; |
969 | default: |
969 | default: |
970 | return $this->raiseError(DB_ERROR_SYNTAX); |
970 | return $this->raiseError(DB_ERROR_SYNTAX); |
971 | }
|
971 | }
|
972 | }
|
972 | }
|
973 | 973 | ||
974 | // }}}
|
974 | // }}}
|
975 | // {{{ execute()
|
975 | // {{{ execute()
|
976 | 976 | ||
977 | /**
|
977 | /**
|
978 | * Executes a DB statement prepared with prepare()
|
978 | * Executes a DB statement prepared with prepare()
|
979 | *
|
979 | *
|
980 | * Example 1.
|
980 | * Example 1.
|
981 | * <code>
|
981 | * <code>
|
982 | * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
|
982 | * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
|
983 | * $data = array(
|
983 | * $data = array(
|
984 | * "John's text",
|
984 | * "John's text",
|
985 | * "'it''s good'",
|
985 | * "'it''s good'",
|
986 | * 'filename.txt'
|
986 | * 'filename.txt'
|
987 | * );
|
987 | * );
|
988 | * $res = $db->execute($sth, $data);
|
988 | * $res = $db->execute($sth, $data);
|
989 | * </code>
|
989 | * </code>
|
990 | *
|
990 | *
|
991 | * @param resource $stmt a DB statement resource returned from prepare()
|
991 | * @param resource $stmt a DB statement resource returned from prepare()
|
992 | * @param mixed $data array, string or numeric data to be used in
|
992 | * @param mixed $data array, string or numeric data to be used in
|
993 | * execution of the statement. Quantity of items
|
993 | * execution of the statement. Quantity of items
|
994 | * passed must match quantity of placeholders in
|
994 | * passed must match quantity of placeholders in
|
995 | * query: meaning 1 placeholder for non-array
|
995 | * query: meaning 1 placeholder for non-array
|
996 | * parameters or 1 placeholder per array element.
|
996 | * parameters or 1 placeholder per array element.
|
997 | *
|
997 | *
|
998 | * @return mixed a new DB_result object for successful SELECT queries
|
998 | * @return mixed a new DB_result object for successful SELECT queries
|
999 | * or DB_OK for successul data manipulation queries.
|
999 | * or DB_OK for successul data manipulation queries.
|
1000 | * A DB_Error object on failure.
|
1000 | * A DB_Error object on failure.
|
1001 | *
|
1001 | *
|
1002 | * {@internal ibase and oci8 have their own execute() methods.}}
|
1002 | * {@internal ibase and oci8 have their own execute() methods.}}
|
1003 | *
|
1003 | *
|
1004 | * @see DB_common::prepare()
|
1004 | * @see DB_common::prepare()
|
1005 | */
|
1005 | */
|
1006 | function &execute($stmt, $data = array()) |
1006 | function &execute($stmt, $data = array()) |
1007 | {
|
1007 | {
|
1008 | $realquery = $this->executeEmulateQuery($stmt, $data); |
1008 | $realquery = $this->executeEmulateQuery($stmt, $data); |
1009 | if (DB::isError($realquery)) { |
1009 | if (DB::isError($realquery)) { |
1010 | return $realquery; |
1010 | return $realquery; |
1011 | }
|
1011 | }
|
1012 | $result = $this->simpleQuery($realquery); |
1012 | $result = $this->simpleQuery($realquery); |
1013 | 1013 | ||
1014 | if ($result === DB_OK || DB::isError($result)) { |
1014 | if ($result === DB_OK || DB::isError($result)) { |
1015 | return $result; |
1015 | return $result; |
1016 | } else { |
1016 | } else { |
1017 | $tmp = new DB_result($this, $result); |
1017 | $tmp = new DB_result($this, $result); |
1018 | return $tmp; |
1018 | return $tmp; |
1019 | }
|
1019 | }
|
1020 | }
|
1020 | }
|
1021 | 1021 | ||
1022 | // }}}
|
1022 | // }}}
|
1023 | // {{{ executeEmulateQuery()
|
1023 | // {{{ executeEmulateQuery()
|
1024 | 1024 | ||
1025 | /**
|
1025 | /**
|
1026 | * Emulates executing prepared statements if the DBMS not support them
|
1026 | * Emulates executing prepared statements if the DBMS not support them
|
1027 | *
|
1027 | *
|
1028 | * @param resource $stmt a DB statement resource returned from execute()
|
1028 | * @param resource $stmt a DB statement resource returned from execute()
|
1029 | * @param mixed $data array, string or numeric data to be used in
|
1029 | * @param mixed $data array, string or numeric data to be used in
|
1030 | * execution of the statement. Quantity of items
|
1030 | * execution of the statement. Quantity of items
|
1031 | * passed must match quantity of placeholders in
|
1031 | * passed must match quantity of placeholders in
|
1032 | * query: meaning 1 placeholder for non-array
|
1032 | * query: meaning 1 placeholder for non-array
|
1033 | * parameters or 1 placeholder per array element.
|
1033 | * parameters or 1 placeholder per array element.
|
1034 | *
|
1034 | *
|
1035 | * @return mixed a string containing the real query run when emulating
|
1035 | * @return mixed a string containing the real query run when emulating
|
1036 | * prepare/execute. A DB_Error object on failure.
|
1036 | * prepare/execute. A DB_Error object on failure.
|
1037 | *
|
1037 | *
|
1038 | * @access protected
|
1038 | * @access protected
|
1039 | * @see DB_common::execute()
|
1039 | * @see DB_common::execute()
|
1040 | */
|
1040 | */
|
1041 | function executeEmulateQuery($stmt, $data = array()) |
1041 | function executeEmulateQuery($stmt, $data = array()) |
1042 | {
|
1042 | {
|
1043 | $stmt = (int)$stmt; |
1043 | $stmt = (int)$stmt; |
1044 | $data = (array)$data; |
1044 | $data = (array)$data; |
1045 | $this->last_parameters = $data; |
1045 | $this->last_parameters = $data; |
1046 | 1046 | ||
1047 | if (count($this->prepare_types[$stmt]) != count($data)) { |
1047 | if (count($this->prepare_types[$stmt]) != count($data)) { |
1048 | $this->last_query = $this->prepared_queries[$stmt]; |
1048 | $this->last_query = $this->prepared_queries[$stmt]; |
1049 | return $this->raiseError(DB_ERROR_MISMATCH); |
1049 | return $this->raiseError(DB_ERROR_MISMATCH); |
1050 | }
|
1050 | }
|
1051 | 1051 | ||
1052 | $realquery = $this->prepare_tokens[$stmt][0]; |
1052 | $realquery = $this->prepare_tokens[$stmt][0]; |
1053 | 1053 | ||
1054 | $i = 0; |
1054 | $i = 0; |
1055 | foreach ($data as $value) { |
1055 | foreach ($data as $value) { |
1056 | if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { |
1056 | if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { |
1057 | $realquery .= $this->quoteSmart($value); |
1057 | $realquery .= $this->quoteSmart($value); |
1058 | } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { |
1058 | } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { |
1059 | $fp = @fopen($value, 'rb'); |
1059 | $fp = @fopen($value, 'rb'); |
1060 | if (!$fp) { |
1060 | if (!$fp) { |
1061 | return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
1061 | return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
1062 | }
|
1062 | }
|
1063 | $realquery .= $this->quoteSmart(fread($fp, filesize($value))); |
1063 | $realquery .= $this->quoteSmart(fread($fp, filesize($value))); |
1064 | fclose($fp); |
1064 | fclose($fp); |
1065 | } else { |
1065 | } else { |
1066 | $realquery .= $value; |
1066 | $realquery .= $value; |
1067 | }
|
1067 | }
|
1068 | 1068 | ||
1069 | $realquery .= $this->prepare_tokens[$stmt][++$i]; |
1069 | $realquery .= $this->prepare_tokens[$stmt][++$i]; |
1070 | }
|
1070 | }
|
1071 | 1071 | ||
1072 | return $realquery; |
1072 | return $realquery; |
1073 | }
|
1073 | }
|
1074 | 1074 | ||
1075 | // }}}
|
1075 | // }}}
|
1076 | // {{{ executeMultiple()
|
1076 | // {{{ executeMultiple()
|
1077 | 1077 | ||
1078 | /**
|
1078 | /**
|
1079 | * Performs several execute() calls on the same statement handle
|
1079 | * Performs several execute() calls on the same statement handle
|
1080 | *
|
1080 | *
|
1081 | * $data must be an array indexed numerically
|
1081 | * $data must be an array indexed numerically
|
1082 | * from 0, one execute call is done for every "row" in the array.
|
1082 | * from 0, one execute call is done for every "row" in the array.
|
1083 | *
|
1083 | *
|
1084 | * If an error occurs during execute(), executeMultiple() does not
|
1084 | * If an error occurs during execute(), executeMultiple() does not
|
1085 | * execute the unfinished rows, but rather returns that error.
|
1085 | * execute the unfinished rows, but rather returns that error.
|
1086 | *
|
1086 | *
|
1087 | * @param resource $stmt query handle from prepare()
|
1087 | * @param resource $stmt query handle from prepare()
|
1088 | * @param array $data numeric array containing the
|
1088 | * @param array $data numeric array containing the
|
1089 | * data to insert into the query
|
1089 | * data to insert into the query
|
1090 | *
|
1090 | *
|
1091 | * @return int DB_OK on success. A DB_Error object on failure.
|
1091 | * @return int DB_OK on success. A DB_Error object on failure.
|
1092 | *
|
1092 | *
|
1093 | * @see DB_common::prepare(), DB_common::execute()
|
1093 | * @see DB_common::prepare(), DB_common::execute()
|
1094 | */
|
1094 | */
|
1095 | function executeMultiple($stmt, $data) |
1095 | function executeMultiple($stmt, $data) |
1096 | {
|
1096 | {
|
1097 | foreach ($data as $value) { |
1097 | foreach ($data as $value) { |
1098 | $res = $this->execute($stmt, $value); |
1098 | $res = $this->execute($stmt, $value); |
1099 | if (DB::isError($res)) { |
1099 | if (DB::isError($res)) { |
1100 | return $res; |
1100 | return $res; |
1101 | }
|
1101 | }
|
1102 | }
|
1102 | }
|
1103 | return DB_OK; |
1103 | return DB_OK; |
1104 | }
|
1104 | }
|
1105 | 1105 | ||
1106 | // }}}
|
1106 | // }}}
|
1107 | // {{{ freePrepared()
|
1107 | // {{{ freePrepared()
|
1108 | 1108 | ||
1109 | /**
|
1109 | /**
|
1110 | * Frees the internal resources associated with a prepared query
|
1110 | * Frees the internal resources associated with a prepared query
|
1111 | *
|
1111 | *
|
1112 | * @param resource $stmt the prepared statement's PHP resource
|
1112 | * @param resource $stmt the prepared statement's PHP resource
|
1113 | * @param bool $free_resource should the PHP resource be freed too?
|
1113 | * @param bool $free_resource should the PHP resource be freed too?
|
1114 | * Use false if you need to get data
|
1114 | * Use false if you need to get data
|
1115 | * from the result set later.
|
1115 | * from the result set later.
|
1116 | *
|
1116 | *
|
1117 | * @return bool TRUE on success, FALSE if $result is invalid
|
1117 | * @return bool TRUE on success, FALSE if $result is invalid
|
1118 | *
|
1118 | *
|
1119 | * @see DB_common::prepare()
|
1119 | * @see DB_common::prepare()
|
1120 | */
|
1120 | */
|
1121 | function freePrepared($stmt, $free_resource = true) |
1121 | function freePrepared($stmt, $free_resource = true) |
1122 | {
|
1122 | {
|
1123 | $stmt = (int)$stmt; |
1123 | $stmt = (int)$stmt; |
1124 | if (isset($this->prepare_tokens[$stmt])) { |
1124 | if (isset($this->prepare_tokens[$stmt])) { |
1125 | unset($this->prepare_tokens[$stmt]); |
1125 | unset($this->prepare_tokens[$stmt]); |
1126 | unset($this->prepare_types[$stmt]); |
1126 | unset($this->prepare_types[$stmt]); |
1127 | unset($this->prepared_queries[$stmt]); |
1127 | unset($this->prepared_queries[$stmt]); |
1128 | return true; |
1128 | return true; |
1129 | }
|
1129 | }
|
1130 | return false; |
1130 | return false; |
1131 | }
|
1131 | }
|
1132 | 1132 | ||
1133 | // }}}
|
1133 | // }}}
|
1134 | // {{{ modifyQuery()
|
1134 | // {{{ modifyQuery()
|
1135 | 1135 | ||
1136 | /**
|
1136 | /**
|
1137 | * Changes a query string for various DBMS specific reasons
|
1137 | * Changes a query string for various DBMS specific reasons
|
1138 | *
|
1138 | *
|
1139 | * It is defined here to ensure all drivers have this method available.
|
1139 | * It is defined here to ensure all drivers have this method available.
|
1140 | *
|
1140 | *
|
1141 | * @param string $query the query string to modify
|
1141 | * @param string $query the query string to modify
|
1142 | *
|
1142 | *
|
1143 | * @return string the modified query string
|
1143 | * @return string the modified query string
|
1144 | *
|
1144 | *
|
1145 | * @access protected
|
1145 | * @access protected
|
1146 | * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
|
1146 | * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
|
1147 | * DB_sqlite::modifyQuery()
|
1147 | * DB_sqlite::modifyQuery()
|
1148 | */
|
1148 | */
|
1149 | function modifyQuery($query) |
1149 | function modifyQuery($query) |
1150 | {
|
1150 | {
|
1151 | return $query; |
1151 | return $query; |
1152 | }
|
1152 | }
|
1153 | 1153 | ||
1154 | // }}}
|
1154 | // }}}
|
1155 | // {{{ modifyLimitQuery()
|
1155 | // {{{ modifyLimitQuery()
|
1156 | 1156 | ||
1157 | /**
|
1157 | /**
|
1158 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
1158 | * Adds LIMIT clauses to a query string according to current DBMS standards
|
1159 | *
|
1159 | *
|
1160 | * It is defined here to assure that all implementations
|
1160 | * It is defined here to assure that all implementations
|
1161 | * have this method defined.
|
1161 | * have this method defined.
|
1162 | *
|
1162 | *
|
1163 | * @param string $query the query to modify
|
1163 | * @param string $query the query to modify
|
1164 | * @param int $from the row to start to fetching (0 = the first row)
|
1164 | * @param int $from the row to start to fetching (0 = the first row)
|
1165 | * @param int $count the numbers of rows to fetch
|
1165 | * @param int $count the numbers of rows to fetch
|
1166 | * @param mixed $params array, string or numeric data to be used in
|
1166 | * @param mixed $params array, string or numeric data to be used in
|
1167 | * execution of the statement. Quantity of items
|
1167 | * execution of the statement. Quantity of items
|
1168 | * passed must match quantity of placeholders in
|
1168 | * passed must match quantity of placeholders in
|
1169 | * query: meaning 1 placeholder for non-array
|
1169 | * query: meaning 1 placeholder for non-array
|
1170 | * parameters or 1 placeholder per array element.
|
1170 | * parameters or 1 placeholder per array element.
|
1171 | *
|
1171 | *
|
1172 | * @return string the query string with LIMIT clauses added
|
1172 | * @return string the query string with LIMIT clauses added
|
1173 | *
|
1173 | *
|
1174 | * @access protected
|
1174 | * @access protected
|
1175 | */
|
1175 | */
|
1176 | function modifyLimitQuery($query, $from, $count, $params = array()) |
1176 | function modifyLimitQuery($query, $from, $count, $params = array()) |
1177 | {
|
1177 | {
|
1178 | return $query; |
1178 | return $query; |
1179 | }
|
1179 | }
|
1180 | 1180 | ||
1181 | // }}}
|
1181 | // }}}
|
1182 | // {{{ query()
|
1182 | // {{{ query()
|
1183 | 1183 | ||
1184 | /**
|
1184 | /**
|
1185 | * Sends a query to the database server
|
1185 | * Sends a query to the database server
|
1186 | *
|
1186 | *
|
1187 | * The query string can be either a normal statement to be sent directly
|
1187 | * The query string can be either a normal statement to be sent directly
|
1188 | * to the server OR if <var>$params</var> are passed the query can have
|
1188 | * to the server OR if <var>$params</var> are passed the query can have
|
1189 | * placeholders and it will be passed through prepare() and execute().
|
1189 | * placeholders and it will be passed through prepare() and execute().
|
1190 | *
|
1190 | *
|
1191 | * @param string $query the SQL query or the statement to prepare
|
1191 | * @param string $query the SQL query or the statement to prepare
|
1192 | * @param mixed $params array, string or numeric data to be used in
|
1192 | * @param mixed $params array, string or numeric data to be used in
|
1193 | * execution of the statement. Quantity of items
|
1193 | * execution of the statement. Quantity of items
|
1194 | * passed must match quantity of placeholders in
|
1194 | * passed must match quantity of placeholders in
|
1195 | * query: meaning 1 placeholder for non-array
|
1195 | * query: meaning 1 placeholder for non-array
|
1196 | * parameters or 1 placeholder per array element.
|
1196 | * parameters or 1 placeholder per array element.
|
1197 | *
|
1197 | *
|
1198 | * @return mixed a new DB_result object for successful SELECT queries
|
1198 | * @return mixed a new DB_result object for successful SELECT queries
|
1199 | * or DB_OK for successul data manipulation queries.
|
1199 | * or DB_OK for successul data manipulation queries.
|
1200 | * A DB_Error object on failure.
|
1200 | * A DB_Error object on failure.
|
1201 | *
|
1201 | *
|
1202 | * @see DB_result, DB_common::prepare(), DB_common::execute()
|
1202 | * @see DB_result, DB_common::prepare(), DB_common::execute()
|
1203 | */
|
1203 | */
|
1204 | function &query($query, $params = array()) |
1204 | function &query($query, $params = array()) |
1205 | {
|
1205 | {
|
1206 | if (sizeof($params) > 0) { |
1206 | if (sizeof($params) > 0) { |
1207 | $sth = $this->prepare($query); |
1207 | $sth = $this->prepare($query); |
1208 | if (DB::isError($sth)) { |
1208 | if (DB::isError($sth)) { |
1209 | return $sth; |
1209 | return $sth; |
1210 | }
|
1210 | }
|
1211 | $ret = $this->execute($sth, $params); |
1211 | $ret = $this->execute($sth, $params); |
1212 | $this->freePrepared($sth, false); |
1212 | $this->freePrepared($sth, false); |
1213 | return $ret; |
1213 | return $ret; |
1214 | } else { |
1214 | } else { |
1215 | $this->last_parameters = array(); |
1215 | $this->last_parameters = array(); |
1216 | $result = $this->simpleQuery($query); |
1216 | $result = $this->simpleQuery($query); |
1217 | if ($result === DB_OK || DB::isError($result)) { |
1217 | if ($result === DB_OK || DB::isError($result)) { |
1218 | return $result; |
1218 | return $result; |
1219 | } else { |
1219 | } else { |
1220 | $tmp = new DB_result($this, $result); |
1220 | $tmp = new DB_result($this, $result); |
1221 | return $tmp; |
1221 | return $tmp; |
1222 | }
|
1222 | }
|
1223 | }
|
1223 | }
|
1224 | }
|
1224 | }
|
1225 | 1225 | ||
1226 | // }}}
|
1226 | // }}}
|
1227 | // {{{ limitQuery()
|
1227 | // {{{ limitQuery()
|
1228 | 1228 | ||
1229 | /**
|
1229 | /**
|
1230 | * Generates and executes a LIMIT query
|
1230 | * Generates and executes a LIMIT query
|
1231 | *
|
1231 | *
|
1232 | * @param string $query the query
|
1232 | * @param string $query the query
|
1233 | * @param intr $from the row to start to fetching (0 = the first row)
|
1233 | * @param intr $from the row to start to fetching (0 = the first row)
|
1234 | * @param int $count the numbers of rows to fetch
|
1234 | * @param int $count the numbers of rows to fetch
|
1235 | * @param mixed $params array, string or numeric data to be used in
|
1235 | * @param mixed $params array, string or numeric data to be used in
|
1236 | * execution of the statement. Quantity of items
|
1236 | * execution of the statement. Quantity of items
|
1237 | * passed must match quantity of placeholders in
|
1237 | * passed must match quantity of placeholders in
|
1238 | * query: meaning 1 placeholder for non-array
|
1238 | * query: meaning 1 placeholder for non-array
|
1239 | * parameters or 1 placeholder per array element.
|
1239 | * parameters or 1 placeholder per array element.
|
1240 | *
|
1240 | *
|
1241 | * @return mixed a new DB_result object for successful SELECT queries
|
1241 | * @return mixed a new DB_result object for successful SELECT queries
|
1242 | * or DB_OK for successul data manipulation queries.
|
1242 | * or DB_OK for successul data manipulation queries.
|
1243 | * A DB_Error object on failure.
|
1243 | * A DB_Error object on failure.
|
1244 | */
|
1244 | */
|
1245 | function &limitQuery($query, $from, $count, $params = array()) |
1245 | function &limitQuery($query, $from, $count, $params = array()) |
1246 | {
|
1246 | {
|
1247 | $query = $this->modifyLimitQuery($query, $from, $count, $params); |
1247 | $query = $this->modifyLimitQuery($query, $from, $count, $params); |
1248 | if (DB::isError($query)){ |
1248 | if (DB::isError($query)){ |
1249 | return $query; |
1249 | return $query; |
1250 | }
|
1250 | }
|
1251 | $result = $this->query($query, $params); |
1251 | $result = $this->query($query, $params); |
1252 | if (is_a($result, 'DB_result')) { |
1252 | if (is_a($result, 'DB_result')) { |
1253 | $result->setOption('limit_from', $from); |
1253 | $result->setOption('limit_from', $from); |
1254 | $result->setOption('limit_count', $count); |
1254 | $result->setOption('limit_count', $count); |
1255 | }
|
1255 | }
|
1256 | return $result; |
1256 | return $result; |
1257 | }
|
1257 | }
|
1258 | 1258 | ||
1259 | // }}}
|
1259 | // }}}
|
1260 | // {{{ getOne()
|
1260 | // {{{ getOne()
|
1261 | 1261 | ||
1262 | /**
|
1262 | /**
|
1263 | * Fetches the first column of the first row from a query result
|
1263 | * Fetches the first column of the first row from a query result
|
1264 | *
|
1264 | *
|
1265 | * Takes care of doing the query and freeing the results when finished.
|
1265 | * Takes care of doing the query and freeing the results when finished.
|
1266 | *
|
1266 | *
|
1267 | * @param string $query the SQL query
|
1267 | * @param string $query the SQL query
|
1268 | * @param mixed $params array, string or numeric data to be used in
|
1268 | * @param mixed $params array, string or numeric data to be used in
|
1269 | * execution of the statement. Quantity of items
|
1269 | * execution of the statement. Quantity of items
|
1270 | * passed must match quantity of placeholders in
|
1270 | * passed must match quantity of placeholders in
|
1271 | * query: meaning 1 placeholder for non-array
|
1271 | * query: meaning 1 placeholder for non-array
|
1272 | * parameters or 1 placeholder per array element.
|
1272 | * parameters or 1 placeholder per array element.
|
1273 | *
|
1273 | *
|
1274 | * @return mixed the returned value of the query.
|
1274 | * @return mixed the returned value of the query.
|
1275 | * A DB_Error object on failure.
|
1275 | * A DB_Error object on failure.
|
1276 | */
|
1276 | */
|
1277 | function &getOne($query, $params = array()) |
1277 | function &getOne($query, $params = array()) |
1278 | {
|
1278 | {
|
1279 | $params = (array)$params; |
1279 | $params = (array)$params; |
1280 | // modifyLimitQuery() would be nice here, but it causes BC issues
|
1280 | // modifyLimitQuery() would be nice here, but it causes BC issues
|
1281 | if (sizeof($params) > 0) { |
1281 | if (sizeof($params) > 0) { |
1282 | $sth = $this->prepare($query); |
1282 | $sth = $this->prepare($query); |
1283 | if (DB::isError($sth)) { |
1283 | if (DB::isError($sth)) { |
1284 | return $sth; |
1284 | return $sth; |
1285 | }
|
1285 | }
|
1286 | $res = $this->execute($sth, $params); |
1286 | $res = $this->execute($sth, $params); |
1287 | $this->freePrepared($sth); |
1287 | $this->freePrepared($sth); |
1288 | } else { |
1288 | } else { |
1289 | $res = $this->query($query); |
1289 | $res = $this->query($query); |
1290 | }
|
1290 | }
|
1291 | 1291 | ||
1292 | if (DB::isError($res)) { |
1292 | if (DB::isError($res)) { |
1293 | return $res; |
1293 | return $res; |
1294 | }
|
1294 | }
|
1295 | 1295 | ||
1296 | $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
1296 | $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
1297 | $res->free(); |
1297 | $res->free(); |
1298 | 1298 | ||
1299 | if ($err !== DB_OK) { |
1299 | if ($err !== DB_OK) { |
1300 | return $err; |
1300 | return $err; |
1301 | }
|
1301 | }
|
1302 | 1302 | ||
1303 | return $row[0]; |
1303 | return $row[0]; |
1304 | }
|
1304 | }
|
1305 | 1305 | ||
1306 | // }}}
|
1306 | // }}}
|
1307 | // {{{ getRow()
|
1307 | // {{{ getRow()
|
1308 | 1308 | ||
1309 | /**
|
1309 | /**
|
1310 | * Fetches the first row of data returned from a query result
|
1310 | * Fetches the first row of data returned from a query result
|
1311 | *
|
1311 | *
|
1312 | * Takes care of doing the query and freeing the results when finished.
|
1312 | * Takes care of doing the query and freeing the results when finished.
|
1313 | *
|
1313 | *
|
1314 | * @param string $query the SQL query
|
1314 | * @param string $query the SQL query
|
1315 | * @param mixed $params array, string or numeric data to be used in
|
1315 | * @param mixed $params array, string or numeric data to be used in
|
1316 | * execution of the statement. Quantity of items
|
1316 | * execution of the statement. Quantity of items
|
1317 | * passed must match quantity of placeholders in
|
1317 | * passed must match quantity of placeholders in
|
1318 | * query: meaning 1 placeholder for non-array
|
1318 | * query: meaning 1 placeholder for non-array
|
1319 | * parameters or 1 placeholder per array element.
|
1319 | * parameters or 1 placeholder per array element.
|
1320 | * @param int $fetchmode the fetch mode to use
|
1320 | * @param int $fetchmode the fetch mode to use
|
1321 | *
|
1321 | *
|
1322 | * @return array the first row of results as an array.
|
1322 | * @return array the first row of results as an array.
|
1323 | * A DB_Error object on failure.
|
1323 | * A DB_Error object on failure.
|
1324 | */
|
1324 | */
|
1325 | function &getRow($query, $params = array(), |
1325 | function &getRow($query, $params = array(), |
1326 | $fetchmode = DB_FETCHMODE_DEFAULT) |
1326 | $fetchmode = DB_FETCHMODE_DEFAULT) |
1327 | {
|
1327 | {
|
1328 | // compat check, the params and fetchmode parameters used to
|
1328 | // compat check, the params and fetchmode parameters used to
|
1329 | // have the opposite order
|
1329 | // have the opposite order
|
1330 | if (!is_array($params)) { |
1330 | if (!is_array($params)) { |
1331 | if (is_array($fetchmode)) { |
1331 | if (is_array($fetchmode)) { |
1332 | if ($params === null) { |
1332 | if ($params === null) { |
1333 | $tmp = DB_FETCHMODE_DEFAULT; |
1333 | $tmp = DB_FETCHMODE_DEFAULT; |
1334 | } else { |
1334 | } else { |
1335 | $tmp = $params; |
1335 | $tmp = $params; |
1336 | }
|
1336 | }
|
1337 | $params = $fetchmode; |
1337 | $params = $fetchmode; |
1338 | $fetchmode = $tmp; |
1338 | $fetchmode = $tmp; |
1339 | } elseif ($params !== null) { |
1339 | } elseif ($params !== null) { |
1340 | $fetchmode = $params; |
1340 | $fetchmode = $params; |
1341 | $params = array(); |
1341 | $params = array(); |
1342 | }
|
1342 | }
|
1343 | }
|
1343 | }
|
1344 | // modifyLimitQuery() would be nice here, but it causes BC issues
|
1344 | // modifyLimitQuery() would be nice here, but it causes BC issues
|
1345 | if (sizeof($params) > 0) { |
1345 | if (sizeof($params) > 0) { |
1346 | $sth = $this->prepare($query); |
1346 | $sth = $this->prepare($query); |
1347 | if (DB::isError($sth)) { |
1347 | if (DB::isError($sth)) { |
1348 | return $sth; |
1348 | return $sth; |
1349 | }
|
1349 | }
|
1350 | $res = $this->execute($sth, $params); |
1350 | $res = $this->execute($sth, $params); |
1351 | $this->freePrepared($sth); |
1351 | $this->freePrepared($sth); |
1352 | } else { |
1352 | } else { |
1353 | $res = $this->query($query); |
1353 | $res = $this->query($query); |
1354 | }
|
1354 | }
|
1355 | 1355 | ||
1356 | if (DB::isError($res)) { |
1356 | if (DB::isError($res)) { |
1357 | return $res; |
1357 | return $res; |
1358 | }
|
1358 | }
|
1359 | 1359 | ||
1360 | $err = $res->fetchInto($row, $fetchmode); |
1360 | $err = $res->fetchInto($row, $fetchmode); |
1361 | 1361 | ||
1362 | $res->free(); |
1362 | $res->free(); |
1363 | 1363 | ||
1364 | if ($err !== DB_OK) { |
1364 | if ($err !== DB_OK) { |
1365 | return $err; |
1365 | return $err; |
1366 | }
|
1366 | }
|
1367 | 1367 | ||
1368 | return $row; |
1368 | return $row; |
1369 | }
|
1369 | }
|
1370 | 1370 | ||
1371 | // }}}
|
1371 | // }}}
|
1372 | // {{{ getCol()
|
1372 | // {{{ getCol()
|
1373 | 1373 | ||
1374 | /**
|
1374 | /**
|
1375 | * Fetches a single column from a query result and returns it as an
|
1375 | * Fetches a single column from a query result and returns it as an
|
1376 | * indexed array
|
1376 | * indexed array
|
1377 | *
|
1377 | *
|
1378 | * @param string $query the SQL query
|
1378 | * @param string $query the SQL query
|
1379 | * @param mixed $col which column to return (integer [column number,
|
1379 | * @param mixed $col which column to return (integer [column number,
|
1380 | * starting at 0] or string [column name])
|
1380 | * starting at 0] or string [column name])
|
1381 | * @param mixed $params array, string or numeric data to be used in
|
1381 | * @param mixed $params array, string or numeric data to be used in
|
1382 | * execution of the statement. Quantity of items
|
1382 | * execution of the statement. Quantity of items
|
1383 | * passed must match quantity of placeholders in
|
1383 | * passed must match quantity of placeholders in
|
1384 | * query: meaning 1 placeholder for non-array
|
1384 | * query: meaning 1 placeholder for non-array
|
1385 | * parameters or 1 placeholder per array element.
|
1385 | * parameters or 1 placeholder per array element.
|
1386 | *
|
1386 | *
|
1387 | * @return array the results as an array. A DB_Error object on failure.
|
1387 | * @return array the results as an array. A DB_Error object on failure.
|
1388 | *
|
1388 | *
|
1389 | * @see DB_common::query()
|
1389 | * @see DB_common::query()
|
1390 | */
|
1390 | */
|
1391 | function &getCol($query, $col = 0, $params = array()) |
1391 | function &getCol($query, $col = 0, $params = array()) |
1392 | {
|
1392 | {
|
1393 | $params = (array)$params; |
1393 | $params = (array)$params; |
1394 | if (sizeof($params) > 0) { |
1394 | if (sizeof($params) > 0) { |
1395 | $sth = $this->prepare($query); |
1395 | $sth = $this->prepare($query); |
1396 | 1396 | ||
1397 | if (DB::isError($sth)) { |
1397 | if (DB::isError($sth)) { |
1398 | return $sth; |
1398 | return $sth; |
1399 | }
|
1399 | }
|
1400 | 1400 | ||
1401 | $res = $this->execute($sth, $params); |
1401 | $res = $this->execute($sth, $params); |
1402 | $this->freePrepared($sth); |
1402 | $this->freePrepared($sth); |
1403 | } else { |
1403 | } else { |
1404 | $res = $this->query($query); |
1404 | $res = $this->query($query); |
1405 | }
|
1405 | }
|
1406 | 1406 | ||
1407 | if (DB::isError($res)) { |
1407 | if (DB::isError($res)) { |
1408 | return $res; |
1408 | return $res; |
1409 | }
|
1409 | }
|
1410 | 1410 | ||
1411 | $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; |
1411 | $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; |
1412 | 1412 | ||
1413 | if (!is_array($row = $res->fetchRow($fetchmode))) { |
1413 | if (!is_array($row = $res->fetchRow($fetchmode))) { |
1414 | $ret = array(); |
1414 | $ret = array(); |
1415 | } else { |
1415 | } else { |
1416 | if (!array_key_exists($col, $row)) { |
1416 | if (!array_key_exists($col, $row)) { |
1417 | $ret = $this->raiseError(DB_ERROR_NOSUCHFIELD); |
1417 | $ret = $this->raiseError(DB_ERROR_NOSUCHFIELD); |
1418 | } else { |
1418 | } else { |
1419 | $ret = array($row[$col]); |
1419 | $ret = array($row[$col]); |
1420 | while (is_array($row = $res->fetchRow($fetchmode))) { |
1420 | while (is_array($row = $res->fetchRow($fetchmode))) { |
1421 | $ret[] = $row[$col]; |
1421 | $ret[] = $row[$col]; |
1422 | }
|
1422 | }
|
1423 | }
|
1423 | }
|
1424 | }
|
1424 | }
|
1425 | 1425 | ||
1426 | $res->free(); |
1426 | $res->free(); |
1427 | 1427 | ||
1428 | if (DB::isError($row)) { |
1428 | if (DB::isError($row)) { |
1429 | $ret = $row; |
1429 | $ret = $row; |
1430 | }
|
1430 | }
|
1431 | 1431 | ||
1432 | return $ret; |
1432 | return $ret; |
1433 | }
|
1433 | }
|
1434 | 1434 | ||
1435 | // }}}
|
1435 | // }}}
|
1436 | // {{{ getAssoc()
|
1436 | // {{{ getAssoc()
|
1437 | 1437 | ||
1438 | /**
|
1438 | /**
|
1439 | * Fetches an entire query result and returns it as an
|
1439 | * Fetches an entire query result and returns it as an
|
1440 | * associative array using the first column as the key
|
1440 | * associative array using the first column as the key
|
1441 | *
|
1441 | *
|
1442 | * If the result set contains more than two columns, the value
|
1442 | * If the result set contains more than two columns, the value
|
1443 | * will be an array of the values from column 2-n. If the result
|
1443 | * will be an array of the values from column 2-n. If the result
|
1444 | * set contains only two columns, the returned value will be a
|
1444 | * set contains only two columns, the returned value will be a
|
1445 | * scalar with the value of the second column (unless forced to an
|
1445 | * scalar with the value of the second column (unless forced to an
|
1446 | * array with the $force_array parameter). A DB error code is
|
1446 | * array with the $force_array parameter). A DB error code is
|
1447 | * returned on errors. If the result set contains fewer than two
|
1447 | * returned on errors. If the result set contains fewer than two
|
1448 | * columns, a DB_ERROR_TRUNCATED error is returned.
|
1448 | * columns, a DB_ERROR_TRUNCATED error is returned.
|
1449 | *
|
1449 | *
|
1450 | * For example, if the table "mytable" contains:
|
1450 | * For example, if the table "mytable" contains:
|
1451 | *
|
1451 | *
|
1452 | * <pre>
|
1452 | * <pre>
|
1453 | * ID TEXT DATE
|
1453 | * ID TEXT DATE
|
1454 | * --------------------------------
|
1454 | * --------------------------------
|
1455 | * 1 'one' 944679408
|
1455 | * 1 'one' 944679408
|
1456 | * 2 'two' 944679408
|
1456 | * 2 'two' 944679408
|
1457 | * 3 'three' 944679408
|
1457 | * 3 'three' 944679408
|
1458 | * </pre>
|
1458 | * </pre>
|
1459 | *
|
1459 | *
|
1460 | * Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
1460 | * Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
1461 | * <pre>
|
1461 | * <pre>
|
1462 | * array(
|
1462 | * array(
|
1463 | * '1' => 'one',
|
1463 | * '1' => 'one',
|
1464 | * '2' => 'two',
|
1464 | * '2' => 'two',
|
1465 | * '3' => 'three',
|
1465 | * '3' => 'three',
|
1466 | * )
|
1466 | * )
|
1467 | * </pre>
|
1467 | * </pre>
|
1468 | *
|
1468 | *
|
1469 | * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
1469 | * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
1470 | * <pre>
|
1470 | * <pre>
|
1471 | * array(
|
1471 | * array(
|
1472 | * '1' => array('one', '944679408'),
|
1472 | * '1' => array('one', '944679408'),
|
1473 | * '2' => array('two', '944679408'),
|
1473 | * '2' => array('two', '944679408'),
|
1474 | * '3' => array('three', '944679408')
|
1474 | * '3' => array('three', '944679408')
|
1475 | * )
|
1475 | * )
|
1476 | * </pre>
|
1476 | * </pre>
|
1477 | *
|
1477 | *
|
1478 | * If the more than one row occurs with the same value in the
|
1478 | * If the more than one row occurs with the same value in the
|
1479 | * first column, the last row overwrites all previous ones by
|
1479 | * first column, the last row overwrites all previous ones by
|
1480 | * default. Use the $group parameter if you don't want to
|
1480 | * default. Use the $group parameter if you don't want to
|
1481 | * overwrite like this. Example:
|
1481 | * overwrite like this. Example:
|
1482 | *
|
1482 | *
|
1483 | * <pre>
|
1483 | * <pre>
|
1484 | * getAssoc('SELECT category,id,name FROM mytable', false, null,
|
1484 | * getAssoc('SELECT category,id,name FROM mytable', false, null,
|
1485 | * DB_FETCHMODE_ASSOC, true) returns:
|
1485 | * DB_FETCHMODE_ASSOC, true) returns:
|
1486 | *
|
1486 | *
|
1487 | * array(
|
1487 | * array(
|
1488 | * '1' => array(array('id' => '4', 'name' => 'number four'),
|
1488 | * '1' => array(array('id' => '4', 'name' => 'number four'),
|
1489 | * array('id' => '6', 'name' => 'number six')
|
1489 | * array('id' => '6', 'name' => 'number six')
|
1490 | * ),
|
1490 | * ),
|
1491 | * '9' => array(array('id' => '4', 'name' => 'number four'),
|
1491 | * '9' => array(array('id' => '4', 'name' => 'number four'),
|
1492 | * array('id' => '6', 'name' => 'number six')
|
1492 | * array('id' => '6', 'name' => 'number six')
|
1493 | * )
|
1493 | * )
|
1494 | * )
|
1494 | * )
|
1495 | * </pre>
|
1495 | * </pre>
|
1496 | *
|
1496 | *
|
1497 | * Keep in mind that database functions in PHP usually return string
|
1497 | * Keep in mind that database functions in PHP usually return string
|
1498 | * values for results regardless of the database's internal type.
|
1498 | * values for results regardless of the database's internal type.
|
1499 | *
|
1499 | *
|
1500 | * @param string $query the SQL query
|
1500 | * @param string $query the SQL query
|
1501 | * @param bool $force_array used only when the query returns
|
1501 | * @param bool $force_array used only when the query returns
|
1502 | * exactly two columns. If true, the values
|
1502 | * exactly two columns. If true, the values
|
1503 | * of the returned array will be one-element
|
1503 | * of the returned array will be one-element
|
1504 | * arrays instead of scalars.
|
1504 | * arrays instead of scalars.
|
1505 | * @param mixed $params array, string or numeric data to be used in
|
1505 | * @param mixed $params array, string or numeric data to be used in
|
1506 | * execution of the statement. Quantity of
|
1506 | * execution of the statement. Quantity of
|
1507 | * items passed must match quantity of
|
1507 | * items passed must match quantity of
|
1508 | * placeholders in query: meaning 1
|
1508 | * placeholders in query: meaning 1
|
1509 | * placeholder for non-array parameters or
|
1509 | * placeholder for non-array parameters or
|
1510 | * 1 placeholder per array element.
|
1510 | * 1 placeholder per array element.
|
1511 | * @param int $fetchmode the fetch mode to use
|
1511 | * @param int $fetchmode the fetch mode to use
|
1512 | * @param bool $group if true, the values of the returned array
|
1512 | * @param bool $group if true, the values of the returned array
|
1513 | * is wrapped in another array. If the same
|
1513 | * is wrapped in another array. If the same
|
1514 | * key value (in the first column) repeats
|
1514 | * key value (in the first column) repeats
|
1515 | * itself, the values will be appended to
|
1515 | * itself, the values will be appended to
|
1516 | * this array instead of overwriting the
|
1516 | * this array instead of overwriting the
|
1517 | * existing values.
|
1517 | * existing values.
|
1518 | *
|
1518 | *
|
1519 | * @return array the associative array containing the query results.
|
1519 | * @return array the associative array containing the query results.
|
1520 | * A DB_Error object on failure.
|
1520 | * A DB_Error object on failure.
|
1521 | */
|
1521 | */
|
1522 | function &getAssoc($query, $force_array = false, $params = array(), |
1522 | function &getAssoc($query, $force_array = false, $params = array(), |
1523 | $fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
1523 | $fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
1524 | {
|
1524 | {
|
1525 | $params = (array)$params; |
1525 | $params = (array)$params; |
1526 | if (sizeof($params) > 0) { |
1526 | if (sizeof($params) > 0) { |
1527 | $sth = $this->prepare($query); |
1527 | $sth = $this->prepare($query); |
1528 | 1528 | ||
1529 | if (DB::isError($sth)) { |
1529 | if (DB::isError($sth)) { |
1530 | return $sth; |
1530 | return $sth; |
1531 | }
|
1531 | }
|
1532 | 1532 | ||
1533 | $res = $this->execute($sth, $params); |
1533 | $res = $this->execute($sth, $params); |
1534 | $this->freePrepared($sth); |
1534 | $this->freePrepared($sth); |
1535 | } else { |
1535 | } else { |
1536 | $res = $this->query($query); |
1536 | $res = $this->query($query); |
1537 | }
|
1537 | }
|
1538 | 1538 | ||
1539 | if (DB::isError($res)) { |
1539 | if (DB::isError($res)) { |
1540 | return $res; |
1540 | return $res; |
1541 | }
|
1541 | }
|
1542 | if ($fetchmode == DB_FETCHMODE_DEFAULT) { |
1542 | if ($fetchmode == DB_FETCHMODE_DEFAULT) { |
1543 | $fetchmode = $this->fetchmode; |
1543 | $fetchmode = $this->fetchmode; |
1544 | }
|
1544 | }
|
1545 | $cols = $res->numCols(); |
1545 | $cols = $res->numCols(); |
1546 | 1546 | ||
1547 | if ($cols < 2) { |
1547 | if ($cols < 2) { |
1548 | $tmp = $this->raiseError(DB_ERROR_TRUNCATED); |
1548 | $tmp = $this->raiseError(DB_ERROR_TRUNCATED); |
1549 | return $tmp; |
1549 | return $tmp; |
1550 | }
|
1550 | }
|
1551 | 1551 | ||
1552 | $results = array(); |
1552 | $results = array(); |
1553 | 1553 | ||
1554 | if ($cols > 2 || $force_array) { |
1554 | if ($cols > 2 || $force_array) { |
1555 | // return array values
|
1555 | // return array values
|
1556 | // XXX this part can be optimized
|
1556 | // XXX this part can be optimized
|
1557 | if ($fetchmode == DB_FETCHMODE_ASSOC) { |
1557 | if ($fetchmode == DB_FETCHMODE_ASSOC) { |
1558 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { |
1558 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { |
1559 | reset($row); |
1559 | reset($row); |
1560 | $key = current($row); |
1560 | $key = current($row); |
1561 | unset($row[key($row)]); |
1561 | unset($row[key($row)]); |
1562 | if ($group) { |
1562 | if ($group) { |
1563 | $results[$key][] = $row; |
1563 | $results[$key][] = $row; |
1564 | } else { |
1564 | } else { |
1565 | $results[$key] = $row; |
1565 | $results[$key] = $row; |
1566 | }
|
1566 | }
|
1567 | }
|
1567 | }
|
1568 | } elseif ($fetchmode == DB_FETCHMODE_OBJECT) { |
1568 | } elseif ($fetchmode == DB_FETCHMODE_OBJECT) { |
1569 | while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { |
1569 | while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { |
1570 | $arr = get_object_vars($row); |
1570 | $arr = get_object_vars($row); |
1571 | $key = current($arr); |
1571 | $key = current($arr); |
1572 | if ($group) { |
1572 | if ($group) { |
1573 | $results[$key][] = $row; |
1573 | $results[$key][] = $row; |
1574 | } else { |
1574 | } else { |
1575 | $results[$key] = $row; |
1575 | $results[$key] = $row; |
1576 | }
|
1576 | }
|
1577 | }
|
1577 | }
|
1578 | } else { |
1578 | } else { |
1579 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
1579 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
1580 | // we shift away the first element to get
|
1580 | // we shift away the first element to get
|
1581 | // indices running from 0 again
|
1581 | // indices running from 0 again
|
1582 | $key = array_shift($row); |
1582 | $key = array_shift($row); |
1583 | if ($group) { |
1583 | if ($group) { |
1584 | $results[$key][] = $row; |
1584 | $results[$key][] = $row; |
1585 | } else { |
1585 | } else { |
1586 | $results[$key] = $row; |
1586 | $results[$key] = $row; |
1587 | }
|
1587 | }
|
1588 | }
|
1588 | }
|
1589 | }
|
1589 | }
|
1590 | if (DB::isError($row)) { |
1590 | if (DB::isError($row)) { |
1591 | $results = $row; |
1591 | $results = $row; |
1592 | }
|
1592 | }
|
1593 | } else { |
1593 | } else { |
1594 | // return scalar values
|
1594 | // return scalar values
|
1595 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
1595 | while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
1596 | if ($group) { |
1596 | if ($group) { |
1597 | $results[$row[0]][] = $row[1]; |
1597 | $results[$row[0]][] = $row[1]; |
1598 | } else { |
1598 | } else { |
1599 | $results[$row[0]] = $row[1]; |
1599 | $results[$row[0]] = $row[1]; |
1600 | }
|
1600 | }
|
1601 | }
|
1601 | }
|
1602 | if (DB::isError($row)) { |
1602 | if (DB::isError($row)) { |
1603 | $results = $row; |
1603 | $results = $row; |
1604 | }
|
1604 | }
|
1605 | }
|
1605 | }
|
1606 | 1606 | ||
1607 | $res->free(); |
1607 | $res->free(); |
1608 | 1608 | ||
1609 | return $results; |
1609 | return $results; |
1610 | }
|
1610 | }
|
1611 | 1611 | ||
1612 | // }}}
|
1612 | // }}}
|
1613 | // {{{ getAll()
|
1613 | // {{{ getAll()
|
1614 | 1614 | ||
1615 | /**
|
1615 | /**
|
1616 | * Fetches all of the rows from a query result
|
1616 | * Fetches all of the rows from a query result
|
1617 | *
|
1617 | *
|
1618 | * @param string $query the SQL query
|
1618 | * @param string $query the SQL query
|
1619 | * @param mixed $params array, string or numeric data to be used in
|
1619 | * @param mixed $params array, string or numeric data to be used in
|
1620 | * execution of the statement. Quantity of
|
1620 | * execution of the statement. Quantity of
|
1621 | * items passed must match quantity of
|
1621 | * items passed must match quantity of
|
1622 | * placeholders in query: meaning 1
|
1622 | * placeholders in query: meaning 1
|
1623 | * placeholder for non-array parameters or
|
1623 | * placeholder for non-array parameters or
|
1624 | * 1 placeholder per array element.
|
1624 | * 1 placeholder per array element.
|
1625 | * @param int $fetchmode the fetch mode to use:
|
1625 | * @param int $fetchmode the fetch mode to use:
|
1626 | * + DB_FETCHMODE_ORDERED
|
1626 | * + DB_FETCHMODE_ORDERED
|
1627 | * + DB_FETCHMODE_ASSOC
|
1627 | * + DB_FETCHMODE_ASSOC
|
1628 | * + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
|
1628 | * + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
|
1629 | * + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
|
1629 | * + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
|
1630 | *
|
1630 | *
|
1631 | * @return array the nested array. A DB_Error object on failure.
|
1631 | * @return array the nested array. A DB_Error object on failure.
|
1632 | */
|
1632 | */
|
1633 | function &getAll($query, $params = array(), |
1633 | function &getAll($query, $params = array(), |
1634 | $fetchmode = DB_FETCHMODE_DEFAULT) |
1634 | $fetchmode = DB_FETCHMODE_DEFAULT) |
1635 | {
|
1635 | {
|
1636 | // compat check, the params and fetchmode parameters used to
|
1636 | // compat check, the params and fetchmode parameters used to
|
1637 | // have the opposite order
|
1637 | // have the opposite order
|
1638 | if (!is_array($params)) { |
1638 | if (!is_array($params)) { |
1639 | if (is_array($fetchmode)) { |
1639 | if (is_array($fetchmode)) { |
1640 | if ($params === null) { |
1640 | if ($params === null) { |
1641 | $tmp = DB_FETCHMODE_DEFAULT; |
1641 | $tmp = DB_FETCHMODE_DEFAULT; |
1642 | } else { |
1642 | } else { |
1643 | $tmp = $params; |
1643 | $tmp = $params; |
1644 | }
|
1644 | }
|
1645 | $params = $fetchmode; |
1645 | $params = $fetchmode; |
1646 | $fetchmode = $tmp; |
1646 | $fetchmode = $tmp; |
1647 | } elseif ($params !== null) { |
1647 | } elseif ($params !== null) { |
1648 | $fetchmode = $params; |
1648 | $fetchmode = $params; |
1649 | $params = array(); |
1649 | $params = array(); |
1650 | }
|
1650 | }
|
1651 | }
|
1651 | }
|
1652 | 1652 | ||
1653 | if (sizeof($params) > 0) { |
1653 | if (sizeof($params) > 0) { |
1654 | $sth = $this->prepare($query); |
1654 | $sth = $this->prepare($query); |
1655 | 1655 | ||
1656 | if (DB::isError($sth)) { |
1656 | if (DB::isError($sth)) { |
1657 | return $sth; |
1657 | return $sth; |
1658 | }
|
1658 | }
|
1659 | 1659 | ||
1660 | $res = $this->execute($sth, $params); |
1660 | $res = $this->execute($sth, $params); |
1661 | $this->freePrepared($sth); |
1661 | $this->freePrepared($sth); |
1662 | } else { |
1662 | } else { |
1663 | $res = $this->query($query); |
1663 | $res = $this->query($query); |
1664 | }
|
1664 | }
|
1665 | 1665 | ||
1666 | if ($res === DB_OK || DB::isError($res)) { |
1666 | if ($res === DB_OK || DB::isError($res)) { |
1667 | return $res; |
1667 | return $res; |
1668 | }
|
1668 | }
|
1669 | 1669 | ||
1670 | $results = array(); |
1670 | $results = array(); |
1671 | while (DB_OK === $res->fetchInto($row, $fetchmode)) { |
1671 | while (DB_OK === $res->fetchInto($row, $fetchmode)) { |
1672 | if ($fetchmode & DB_FETCHMODE_FLIPPED) { |
1672 | if ($fetchmode & DB_FETCHMODE_FLIPPED) { |
1673 | foreach ($row as $key => $val) { |
1673 | foreach ($row as $key => $val) { |
1674 | $results[$key][] = $val; |
1674 | $results[$key][] = $val; |
1675 | }
|
1675 | }
|
1676 | } else { |
1676 | } else { |
1677 | $results[] = $row; |
1677 | $results[] = $row; |
1678 | }
|
1678 | }
|
1679 | }
|
1679 | }
|
1680 | 1680 | ||
1681 | $res->free(); |
1681 | $res->free(); |
1682 | 1682 | ||
1683 | if (DB::isError($row)) { |
1683 | if (DB::isError($row)) { |
1684 | $tmp = $this->raiseError($row); |
1684 | $tmp = $this->raiseError($row); |
1685 | return $tmp; |
1685 | return $tmp; |
1686 | }
|
1686 | }
|
1687 | return $results; |
1687 | return $results; |
1688 | }
|
1688 | }
|
1689 | 1689 | ||
1690 | // }}}
|
1690 | // }}}
|
1691 | // {{{ autoCommit()
|
1691 | // {{{ autoCommit()
|
1692 | 1692 | ||
1693 | /**
|
1693 | /**
|
1694 | * Enables or disables automatic commits
|
1694 | * Enables or disables automatic commits
|
1695 | *
|
1695 | *
|
1696 | * @param bool $onoff true turns it on, false turns it off
|
1696 | * @param bool $onoff true turns it on, false turns it off
|
1697 | *
|
1697 | *
|
1698 | * @return int DB_OK on success. A DB_Error object if the driver
|
1698 | * @return int DB_OK on success. A DB_Error object if the driver
|
1699 | * doesn't support auto-committing transactions.
|
1699 | * doesn't support auto-committing transactions.
|
1700 | */
|
1700 | */
|
1701 | function autoCommit($onoff = false) |
1701 | function autoCommit($onoff = false) |
1702 | {
|
1702 | {
|
1703 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1703 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1704 | }
|
1704 | }
|
1705 | 1705 | ||
1706 | // }}}
|
1706 | // }}}
|
1707 | // {{{ commit()
|
1707 | // {{{ commit()
|
1708 | 1708 | ||
1709 | /**
|
1709 | /**
|
1710 | * Commits the current transaction
|
1710 | * Commits the current transaction
|
1711 | *
|
1711 | *
|
1712 | * @return int DB_OK on success. A DB_Error object on failure.
|
1712 | * @return int DB_OK on success. A DB_Error object on failure.
|
1713 | */
|
1713 | */
|
1714 | function commit() |
1714 | function commit() |
1715 | {
|
1715 | {
|
1716 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1716 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1717 | }
|
1717 | }
|
1718 | 1718 | ||
1719 | // }}}
|
1719 | // }}}
|
1720 | // {{{ rollback()
|
1720 | // {{{ rollback()
|
1721 | 1721 | ||
1722 | /**
|
1722 | /**
|
1723 | * Reverts the current transaction
|
1723 | * Reverts the current transaction
|
1724 | *
|
1724 | *
|
1725 | * @return int DB_OK on success. A DB_Error object on failure.
|
1725 | * @return int DB_OK on success. A DB_Error object on failure.
|
1726 | */
|
1726 | */
|
1727 | function rollback() |
1727 | function rollback() |
1728 | {
|
1728 | {
|
1729 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1729 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1730 | }
|
1730 | }
|
1731 | 1731 | ||
1732 | // }}}
|
1732 | // }}}
|
1733 | // {{{ numRows()
|
1733 | // {{{ numRows()
|
1734 | 1734 | ||
1735 | /**
|
1735 | /**
|
1736 | * Determines the number of rows in a query result
|
1736 | * Determines the number of rows in a query result
|
1737 | *
|
1737 | *
|
1738 | * @param resource $result the query result idenifier produced by PHP
|
1738 | * @param resource $result the query result idenifier produced by PHP
|
1739 | *
|
1739 | *
|
1740 | * @return int the number of rows. A DB_Error object on failure.
|
1740 | * @return int the number of rows. A DB_Error object on failure.
|
1741 | */
|
1741 | */
|
1742 | function numRows($result) |
1742 | function numRows($result) |
1743 | {
|
1743 | {
|
1744 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1744 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1745 | }
|
1745 | }
|
1746 | 1746 | ||
1747 | // }}}
|
1747 | // }}}
|
1748 | // {{{ affectedRows()
|
1748 | // {{{ affectedRows()
|
1749 | 1749 | ||
1750 | /**
|
1750 | /**
|
1751 | * Determines the number of rows affected by a data maniuplation query
|
1751 | * Determines the number of rows affected by a data maniuplation query
|
1752 | *
|
1752 | *
|
1753 | * 0 is returned for queries that don't manipulate data.
|
1753 | * 0 is returned for queries that don't manipulate data.
|
1754 | *
|
1754 | *
|
1755 | * @return int the number of rows. A DB_Error object on failure.
|
1755 | * @return int the number of rows. A DB_Error object on failure.
|
1756 | */
|
1756 | */
|
1757 | function affectedRows() |
1757 | function affectedRows() |
1758 | {
|
1758 | {
|
1759 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1759 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1760 | }
|
1760 | }
|
1761 | 1761 | ||
1762 | // }}}
|
1762 | // }}}
|
1763 | // {{{ getSequenceName()
|
1763 | // {{{ getSequenceName()
|
1764 | 1764 | ||
1765 | /**
|
1765 | /**
|
1766 | * Generates the name used inside the database for a sequence
|
1766 | * Generates the name used inside the database for a sequence
|
1767 | *
|
1767 | *
|
1768 | * The createSequence() docblock contains notes about storing sequence
|
1768 | * The createSequence() docblock contains notes about storing sequence
|
1769 | * names.
|
1769 | * names.
|
1770 | *
|
1770 | *
|
1771 | * @param string $sqn the sequence's public name
|
1771 | * @param string $sqn the sequence's public name
|
1772 | *
|
1772 | *
|
1773 | * @return string the sequence's name in the backend
|
1773 | * @return string the sequence's name in the backend
|
1774 | *
|
1774 | *
|
1775 | * @access protected
|
1775 | * @access protected
|
1776 | * @see DB_common::createSequence(), DB_common::dropSequence(),
|
1776 | * @see DB_common::createSequence(), DB_common::dropSequence(),
|
1777 | * DB_common::nextID(), DB_common::setOption()
|
1777 | * DB_common::nextID(), DB_common::setOption()
|
1778 | */
|
1778 | */
|
1779 | function getSequenceName($sqn) |
1779 | function getSequenceName($sqn) |
1780 | {
|
1780 | {
|
1781 | return sprintf($this->getOption('seqname_format'), |
1781 | return sprintf($this->getOption('seqname_format'), |
1782 | preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); |
1782 | preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); |
1783 | }
|
1783 | }
|
1784 | 1784 | ||
1785 | // }}}
|
1785 | // }}}
|
1786 | // {{{ nextId()
|
1786 | // {{{ nextId()
|
1787 | 1787 | ||
1788 | /**
|
1788 | /**
|
1789 | * Returns the next free id in a sequence
|
1789 | * Returns the next free id in a sequence
|
1790 | *
|
1790 | *
|
1791 | * @param string $seq_name name of the sequence
|
1791 | * @param string $seq_name name of the sequence
|
1792 | * @param boolean $ondemand when true, the seqence is automatically
|
1792 | * @param boolean $ondemand when true, the seqence is automatically
|
1793 | * created if it does not exist
|
1793 | * created if it does not exist
|
1794 | *
|
1794 | *
|
1795 | * @return int the next id number in the sequence.
|
1795 | * @return int the next id number in the sequence.
|
1796 | * A DB_Error object on failure.
|
1796 | * A DB_Error object on failure.
|
1797 | *
|
1797 | *
|
1798 | * @see DB_common::createSequence(), DB_common::dropSequence(),
|
1798 | * @see DB_common::createSequence(), DB_common::dropSequence(),
|
1799 | * DB_common::getSequenceName()
|
1799 | * DB_common::getSequenceName()
|
1800 | */
|
1800 | */
|
1801 | function nextId($seq_name, $ondemand = true) |
1801 | function nextId($seq_name, $ondemand = true) |
1802 | {
|
1802 | {
|
1803 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1803 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1804 | }
|
1804 | }
|
1805 | 1805 | ||
1806 | // }}}
|
1806 | // }}}
|
1807 | // {{{ createSequence()
|
1807 | // {{{ createSequence()
|
1808 | 1808 | ||
1809 | /**
|
1809 | /**
|
1810 | * Creates a new sequence
|
1810 | * Creates a new sequence
|
1811 | *
|
1811 | *
|
1812 | * The name of a given sequence is determined by passing the string
|
1812 | * The name of a given sequence is determined by passing the string
|
1813 | * provided in the <var>$seq_name</var> argument through PHP's sprintf()
|
1813 | * provided in the <var>$seq_name</var> argument through PHP's sprintf()
|
1814 | * function using the value from the <var>seqname_format</var> option as
|
1814 | * function using the value from the <var>seqname_format</var> option as
|
1815 | * the sprintf()'s format argument.
|
1815 | * the sprintf()'s format argument.
|
1816 | *
|
1816 | *
|
1817 | * <var>seqname_format</var> is set via setOption().
|
1817 | * <var>seqname_format</var> is set via setOption().
|
1818 | *
|
1818 | *
|
1819 | * @param string $seq_name name of the new sequence
|
1819 | * @param string $seq_name name of the new sequence
|
1820 | *
|
1820 | *
|
1821 | * @return int DB_OK on success. A DB_Error object on failure.
|
1821 | * @return int DB_OK on success. A DB_Error object on failure.
|
1822 | *
|
1822 | *
|
1823 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
1823 | * @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
1824 | * DB_common::nextID()
|
1824 | * DB_common::nextID()
|
1825 | */
|
1825 | */
|
1826 | function createSequence($seq_name) |
1826 | function createSequence($seq_name) |
1827 | {
|
1827 | {
|
1828 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1828 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1829 | }
|
1829 | }
|
1830 | 1830 | ||
1831 | // }}}
|
1831 | // }}}
|
1832 | // {{{ dropSequence()
|
1832 | // {{{ dropSequence()
|
1833 | 1833 | ||
1834 | /**
|
1834 | /**
|
1835 | * Deletes a sequence
|
1835 | * Deletes a sequence
|
1836 | *
|
1836 | *
|
1837 | * @param string $seq_name name of the sequence to be deleted
|
1837 | * @param string $seq_name name of the sequence to be deleted
|
1838 | *
|
1838 | *
|
1839 | * @return int DB_OK on success. A DB_Error object on failure.
|
1839 | * @return int DB_OK on success. A DB_Error object on failure.
|
1840 | *
|
1840 | *
|
1841 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
1841 | * @see DB_common::createSequence(), DB_common::getSequenceName(),
|
1842 | * DB_common::nextID()
|
1842 | * DB_common::nextID()
|
1843 | */
|
1843 | */
|
1844 | function dropSequence($seq_name) |
1844 | function dropSequence($seq_name) |
1845 | {
|
1845 | {
|
1846 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1846 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1847 | }
|
1847 | }
|
1848 | 1848 | ||
1849 | // }}}
|
1849 | // }}}
|
1850 | // {{{ raiseError()
|
1850 | // {{{ raiseError()
|
1851 | 1851 | ||
1852 | /**
|
1852 | /**
|
1853 | * Communicates an error and invoke error callbacks, etc
|
1853 | * Communicates an error and invoke error callbacks, etc
|
1854 | *
|
1854 | *
|
1855 | * Basically a wrapper for PEAR::raiseError without the message string.
|
1855 | * Basically a wrapper for PEAR::raiseError without the message string.
|
1856 | *
|
1856 | *
|
1857 | * @param mixed integer error code, or a PEAR error object (all
|
1857 | * @param mixed integer error code, or a PEAR error object (all
|
1858 | * other parameters are ignored if this parameter is
|
1858 | * other parameters are ignored if this parameter is
|
1859 | * an object
|
1859 | * an object
|
1860 | * @param int error mode, see PEAR_Error docs
|
1860 | * @param int error mode, see PEAR_Error docs
|
1861 | * @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the
|
1861 | * @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the
|
1862 | * error level (E_USER_NOTICE etc). If error mode is
|
1862 | * error level (E_USER_NOTICE etc). If error mode is
|
1863 | * PEAR_ERROR_CALLBACK, this is the callback function,
|
1863 | * PEAR_ERROR_CALLBACK, this is the callback function,
|
1864 | * either as a function name, or as an array of an
|
1864 | * either as a function name, or as an array of an
|
1865 | * object and method name. For other error modes this
|
1865 | * object and method name. For other error modes this
|
1866 | * parameter is ignored.
|
1866 | * parameter is ignored.
|
1867 | * @param string extra debug information. Defaults to the last
|
1867 | * @param string extra debug information. Defaults to the last
|
1868 | * query and native error code.
|
1868 | * query and native error code.
|
1869 | * @param mixed native error code, integer or string depending the
|
1869 | * @param mixed native error code, integer or string depending the
|
1870 | * backend
|
1870 | * backend
|
1871 | *
|
1871 | *
|
1872 | * @return object the PEAR_Error object
|
1872 | * @return object the PEAR_Error object
|
1873 | *
|
1873 | *
|
1874 | * @see PEAR_Error
|
1874 | * @see PEAR_Error
|
1875 | */
|
1875 | */
|
1876 | function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
1876 | function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
1877 | $userinfo = null, $nativecode = null) |
1877 | $userinfo = null, $nativecode = null) |
1878 | {
|
1878 | {
|
1879 | // The error is yet a DB error object
|
1879 | // The error is yet a DB error object
|
1880 | if (is_object($code)) { |
1880 | if (is_object($code)) { |
1881 | // because we the static PEAR::raiseError, our global
|
1881 | // because we the static PEAR::raiseError, our global
|
1882 | // handler should be used if it is set
|
1882 | // handler should be used if it is set
|
1883 | if ($mode === null && !empty($this->_default_error_mode)) { |
1883 | if ($mode === null && !empty($this->_default_error_mode)) { |
1884 | $mode = $this->_default_error_mode; |
1884 | $mode = $this->_default_error_mode; |
1885 | $options = $this->_default_error_options; |
1885 | $options = $this->_default_error_options; |
1886 | }
|
1886 | }
|
1887 | $tmp = PEAR::raiseError($code, null, $mode, $options, |
1887 | $tmp = PEAR::raiseError($code, null, $mode, $options, |
1888 | null, null, true); |
1888 | null, null, true); |
1889 | return $tmp; |
1889 | return $tmp; |
1890 | }
|
1890 | }
|
1891 | 1891 | ||
1892 | if ($userinfo === null) { |
1892 | if ($userinfo === null) { |
1893 | $userinfo = $this->last_query; |
1893 | $userinfo = $this->last_query; |
1894 | }
|
1894 | }
|
1895 | 1895 | ||
1896 | if ($nativecode) { |
1896 | if ($nativecode) { |
1897 | $userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
1897 | $userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
1898 | } else { |
1898 | } else { |
1899 | $userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']'; |
1899 | $userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']'; |
1900 | }
|
1900 | }
|
1901 | 1901 | ||
1902 | $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
1902 | $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
1903 | 'DB_Error', true); |
1903 | 'DB_Error', true); |
1904 | return $tmp; |
1904 | return $tmp; |
1905 | }
|
1905 | }
|
1906 | 1906 | ||
1907 | // }}}
|
1907 | // }}}
|
1908 | // {{{ errorNative()
|
1908 | // {{{ errorNative()
|
1909 | 1909 | ||
1910 | /**
|
1910 | /**
|
1911 | * Gets the DBMS' native error code produced by the last query
|
1911 | * Gets the DBMS' native error code produced by the last query
|
1912 | *
|
1912 | *
|
1913 | * @return mixed the DBMS' error code. A DB_Error object on failure.
|
1913 | * @return mixed the DBMS' error code. A DB_Error object on failure.
|
1914 | */
|
1914 | */
|
1915 | function errorNative() |
1915 | function errorNative() |
1916 | {
|
1916 | {
|
1917 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1917 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
1918 | }
|
1918 | }
|
1919 | 1919 | ||
1920 | // }}}
|
1920 | // }}}
|
1921 | // {{{ errorCode()
|
1921 | // {{{ errorCode()
|
1922 | 1922 | ||
1923 | /**
|
1923 | /**
|
1924 | * Maps native error codes to DB's portable ones
|
1924 | * Maps native error codes to DB's portable ones
|
1925 | *
|
1925 | *
|
1926 | * Uses the <var>$errorcode_map</var> property defined in each driver.
|
1926 | * Uses the <var>$errorcode_map</var> property defined in each driver.
|
1927 | *
|
1927 | *
|
1928 | * @param string|int $nativecode the error code returned by the DBMS
|
1928 | * @param string|int $nativecode the error code returned by the DBMS
|
1929 | *
|
1929 | *
|
1930 | * @return int the portable DB error code. Return DB_ERROR if the
|
1930 | * @return int the portable DB error code. Return DB_ERROR if the
|
1931 | * current driver doesn't have a mapping for the
|
1931 | * current driver doesn't have a mapping for the
|
1932 | * $nativecode submitted.
|
1932 | * $nativecode submitted.
|
1933 | */
|
1933 | */
|
1934 | function errorCode($nativecode) |
1934 | function errorCode($nativecode) |
1935 | {
|
1935 | {
|
1936 | if (isset($this->errorcode_map[$nativecode])) { |
1936 | if (isset($this->errorcode_map[$nativecode])) { |
1937 | return $this->errorcode_map[$nativecode]; |
1937 | return $this->errorcode_map[$nativecode]; |
1938 | }
|
1938 | }
|
1939 | // Fall back to DB_ERROR if there was no mapping.
|
1939 | // Fall back to DB_ERROR if there was no mapping.
|
1940 | return DB_ERROR; |
1940 | return DB_ERROR; |
1941 | }
|
1941 | }
|
1942 | 1942 | ||
1943 | // }}}
|
1943 | // }}}
|
1944 | // {{{ errorMessage()
|
1944 | // {{{ errorMessage()
|
1945 | 1945 | ||
1946 | /**
|
1946 | /**
|
1947 | * Maps a DB error code to a textual message
|
1947 | * Maps a DB error code to a textual message
|
1948 | *
|
1948 | *
|
1949 | * @param integer $dbcode the DB error code
|
1949 | * @param integer $dbcode the DB error code
|
1950 | *
|
1950 | *
|
1951 | * @return string the error message corresponding to the error code
|
1951 | * @return string the error message corresponding to the error code
|
1952 | * submitted. FALSE if the error code is unknown.
|
1952 | * submitted. FALSE if the error code is unknown.
|
1953 | *
|
1953 | *
|
1954 | * @see DB::errorMessage()
|
1954 | * @see DB::errorMessage()
|
1955 | */
|
1955 | */
|
1956 | function errorMessage($dbcode) |
1956 | function errorMessage($dbcode) |
1957 | {
|
1957 | {
|
1958 | return DB::errorMessage($this->errorcode_map[$dbcode]); |
1958 | return DB::errorMessage($this->errorcode_map[$dbcode]); |
1959 | }
|
1959 | }
|
1960 | 1960 | ||
1961 | // }}}
|
1961 | // }}}
|
1962 | // {{{ tableInfo()
|
1962 | // {{{ tableInfo()
|
1963 | 1963 | ||
1964 | /**
|
1964 | /**
|
1965 | * Returns information about a table or a result set
|
1965 | * Returns information about a table or a result set
|
1966 | *
|
1966 | *
|
1967 | * The format of the resulting array depends on which <var>$mode</var>
|
1967 | * The format of the resulting array depends on which <var>$mode</var>
|
1968 | * you select. The sample output below is based on this query:
|
1968 | * you select. The sample output below is based on this query:
|
1969 | * <pre>
|
1969 | * <pre>
|
1970 | * SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
|
1970 | * SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
|
1971 | * FROM tblFoo
|
1971 | * FROM tblFoo
|
1972 | * JOIN tblBar ON tblFoo.fldId = tblBar.fldId
|
1972 | * JOIN tblBar ON tblFoo.fldId = tblBar.fldId
|
1973 | * </pre>
|
1973 | * </pre>
|
1974 | *
|
1974 | *
|
1975 | * <ul>
|
1975 | * <ul>
|
1976 | * <li>
|
1976 | * <li>
|
1977 | *
|
1977 | *
|
1978 | * <kbd>null</kbd> (default)
|
1978 | * <kbd>null</kbd> (default)
|
1979 | * <pre>
|
1979 | * <pre>
|
1980 | * [0] => Array (
|
1980 | * [0] => Array (
|
1981 | * [table] => tblFoo
|
1981 | * [table] => tblFoo
|
1982 | * [name] => fldId
|
1982 | * [name] => fldId
|
1983 | * [type] => int
|
1983 | * [type] => int
|
1984 | * [len] => 11
|
1984 | * [len] => 11
|
1985 | * [flags] => primary_key not_null
|
1985 | * [flags] => primary_key not_null
|
1986 | * )
|
1986 | * )
|
1987 | * [1] => Array (
|
1987 | * [1] => Array (
|
1988 | * [table] => tblFoo
|
1988 | * [table] => tblFoo
|
1989 | * [name] => fldPhone
|
1989 | * [name] => fldPhone
|
1990 | * [type] => string
|
1990 | * [type] => string
|
1991 | * [len] => 20
|
1991 | * [len] => 20
|
1992 | * [flags] =>
|
1992 | * [flags] =>
|
1993 | * )
|
1993 | * )
|
1994 | * [2] => Array (
|
1994 | * [2] => Array (
|
1995 | * [table] => tblBar
|
1995 | * [table] => tblBar
|
1996 | * [name] => fldId
|
1996 | * [name] => fldId
|
1997 | * [type] => int
|
1997 | * [type] => int
|
1998 | * [len] => 11
|
1998 | * [len] => 11
|
1999 | * [flags] => primary_key not_null
|
1999 | * [flags] => primary_key not_null
|
2000 | * )
|
2000 | * )
|
2001 | * </pre>
|
2001 | * </pre>
|
2002 | *
|
2002 | *
|
2003 | * </li><li>
|
2003 | * </li><li>
|
2004 | *
|
2004 | *
|
2005 | * <kbd>DB_TABLEINFO_ORDER</kbd>
|
2005 | * <kbd>DB_TABLEINFO_ORDER</kbd>
|
2006 | *
|
2006 | *
|
2007 | * <p>In addition to the information found in the default output,
|
2007 | * <p>In addition to the information found in the default output,
|
2008 | * a notation of the number of columns is provided by the
|
2008 | * a notation of the number of columns is provided by the
|
2009 | * <samp>num_fields</samp> element while the <samp>order</samp>
|
2009 | * <samp>num_fields</samp> element while the <samp>order</samp>
|
2010 | * element provides an array with the column names as the keys and
|
2010 | * element provides an array with the column names as the keys and
|
2011 | * their location index number (corresponding to the keys in the
|
2011 | * their location index number (corresponding to the keys in the
|
2012 | * the default output) as the values.</p>
|
2012 | * the default output) as the values.</p>
|
2013 | *
|
2013 | *
|
2014 | * <p>If a result set has identical field names, the last one is
|
2014 | * <p>If a result set has identical field names, the last one is
|
2015 | * used.</p>
|
2015 | * used.</p>
|
2016 | *
|
2016 | *
|
2017 | * <pre>
|
2017 | * <pre>
|
2018 | * [num_fields] => 3
|
2018 | * [num_fields] => 3
|
2019 | * [order] => Array (
|
2019 | * [order] => Array (
|
2020 | * [fldId] => 2
|
2020 | * [fldId] => 2
|
2021 | * [fldTrans] => 1
|
2021 | * [fldTrans] => 1
|
2022 | * )
|
2022 | * )
|
2023 | * </pre>
|
2023 | * </pre>
|
2024 | *
|
2024 | *
|
2025 | * </li><li>
|
2025 | * </li><li>
|
2026 | *
|
2026 | *
|
2027 | * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
|
2027 | * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
|
2028 | *
|
2028 | *
|
2029 | * <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
|
2029 | * <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
|
2030 | * dimensions to the array in which the table names are keys and
|
2030 | * dimensions to the array in which the table names are keys and
|
2031 | * the field names are sub-keys. This is helpful for queries that
|
2031 | * the field names are sub-keys. This is helpful for queries that
|
2032 | * join tables which have identical field names.</p>
|
2032 | * join tables which have identical field names.</p>
|
2033 | *
|
2033 | *
|
2034 | * <pre>
|
2034 | * <pre>
|
2035 | * [num_fields] => 3
|
2035 | * [num_fields] => 3
|
2036 | * [ordertable] => Array (
|
2036 | * [ordertable] => Array (
|
2037 | * [tblFoo] => Array (
|
2037 | * [tblFoo] => Array (
|
2038 | * [fldId] => 0
|
2038 | * [fldId] => 0
|
2039 | * [fldPhone] => 1
|
2039 | * [fldPhone] => 1
|
2040 | * )
|
2040 | * )
|
2041 | * [tblBar] => Array (
|
2041 | * [tblBar] => Array (
|
2042 | * [fldId] => 2
|
2042 | * [fldId] => 2
|
2043 | * )
|
2043 | * )
|
2044 | * )
|
2044 | * )
|
2045 | * </pre>
|
2045 | * </pre>
|
2046 | *
|
2046 | *
|
2047 | * </li>
|
2047 | * </li>
|
2048 | * </ul>
|
2048 | * </ul>
|
2049 | *
|
2049 | *
|
2050 | * The <samp>flags</samp> element contains a space separated list
|
2050 | * The <samp>flags</samp> element contains a space separated list
|
2051 | * of extra information about the field. This data is inconsistent
|
2051 | * of extra information about the field. This data is inconsistent
|
2052 | * between DBMS's due to the way each DBMS works.
|
2052 | * between DBMS's due to the way each DBMS works.
|
2053 | * + <samp>primary_key</samp>
|
2053 | * + <samp>primary_key</samp>
|
2054 | * + <samp>unique_key</samp>
|
2054 | * + <samp>unique_key</samp>
|
2055 | * + <samp>multiple_key</samp>
|
2055 | * + <samp>multiple_key</samp>
|
2056 | * + <samp>not_null</samp>
|
2056 | * + <samp>not_null</samp>
|
2057 | *
|
2057 | *
|
2058 | * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
|
2058 | * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
|
2059 | * elements if <var>$result</var> is a table name. The following DBMS's
|
2059 | * elements if <var>$result</var> is a table name. The following DBMS's
|
2060 | * provide full information from queries:
|
2060 | * provide full information from queries:
|
2061 | * + fbsql
|
2061 | * + fbsql
|
2062 | * + mysql
|
2062 | * + mysql
|
2063 | *
|
2063 | *
|
2064 | * If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
|
2064 | * If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
|
2065 | * turned on, the names of tables and fields will be lowercased.
|
2065 | * turned on, the names of tables and fields will be lowercased.
|
2066 | *
|
2066 | *
|
2067 | * @param object|string $result DB_result object from a query or a
|
2067 | * @param object|string $result DB_result object from a query or a
|
2068 | * string containing the name of a table.
|
2068 | * string containing the name of a table.
|
2069 | * While this also accepts a query result
|
2069 | * While this also accepts a query result
|
2070 | * resource identifier, this behavior is
|
2070 | * resource identifier, this behavior is
|
2071 | * deprecated.
|
2071 | * deprecated.
|
2072 | * @param int $mode either unused or one of the tableInfo modes:
|
2072 | * @param int $mode either unused or one of the tableInfo modes:
|
2073 | * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
|
2073 | * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
|
2074 | * <kbd>DB_TABLEINFO_ORDER</kbd> or
|
2074 | * <kbd>DB_TABLEINFO_ORDER</kbd> or
|
2075 | * <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
|
2075 | * <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
|
2076 | * These are bitwise, so the first two can be
|
2076 | * These are bitwise, so the first two can be
|
2077 | * combined using <kbd>|</kbd>.
|
2077 | * combined using <kbd>|</kbd>.
|
2078 | *
|
2078 | *
|
2079 | * @return array an associative array with the information requested.
|
2079 | * @return array an associative array with the information requested.
|
2080 | * A DB_Error object on failure.
|
2080 | * A DB_Error object on failure.
|
2081 | *
|
2081 | *
|
2082 | * @see DB_common::setOption()
|
2082 | * @see DB_common::setOption()
|
2083 | */
|
2083 | */
|
2084 | function tableInfo($result, $mode = null) |
2084 | function tableInfo($result, $mode = null) |
2085 | {
|
2085 | {
|
2086 | /*
|
2086 | /*
|
2087 | * If the DB_<driver> class has a tableInfo() method, that one
|
2087 | * If the DB_<driver> class has a tableInfo() method, that one
|
2088 | * overrides this one. But, if the driver doesn't have one,
|
2088 | * overrides this one. But, if the driver doesn't have one,
|
2089 | * this method runs and tells users about that fact.
|
2089 | * this method runs and tells users about that fact.
|
2090 | */
|
2090 | */
|
2091 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
2091 | return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
2092 | }
|
2092 | }
|
2093 | 2093 | ||
2094 | // }}}
|
2094 | // }}}
|
2095 | // {{{ getTables()
|
2095 | // {{{ getTables()
|
2096 | 2096 | ||
2097 | /**
|
2097 | /**
|
2098 | * Lists the tables in the current database
|
2098 | * Lists the tables in the current database
|
2099 | *
|
2099 | *
|
2100 | * @return array the list of tables. A DB_Error object on failure.
|
2100 | * @return array the list of tables. A DB_Error object on failure.
|
2101 | *
|
2101 | *
|
2102 | * @deprecated Method deprecated some time before Release 1.2
|
2102 | * @deprecated Method deprecated some time before Release 1.2
|
2103 | */
|
2103 | */
|
2104 | function getTables() |
2104 | function getTables() |
2105 | {
|
2105 | {
|
2106 | return $this->getListOf('tables'); |
2106 | return $this->getListOf('tables'); |
2107 | }
|
2107 | }
|
2108 | 2108 | ||
2109 | // }}}
|
2109 | // }}}
|
2110 | // {{{ getListOf()
|
2110 | // {{{ getListOf()
|
2111 | 2111 | ||
2112 | /**
|
2112 | /**
|
2113 | * Lists internal database information
|
2113 | * Lists internal database information
|
2114 | *
|
2114 | *
|
2115 | * @param string $type type of information being sought.
|
2115 | * @param string $type type of information being sought.
|
2116 | * Common items being sought are:
|
2116 | * Common items being sought are:
|
2117 | * tables, databases, users, views, functions
|
2117 | * tables, databases, users, views, functions
|
2118 | * Each DBMS's has its own capabilities.
|
2118 | * Each DBMS's has its own capabilities.
|
2119 | *
|
2119 | *
|
2120 | * @return array an array listing the items sought.
|
2120 | * @return array an array listing the items sought.
|
2121 | * A DB DB_Error object on failure.
|
2121 | * A DB DB_Error object on failure.
|
2122 | */
|
2122 | */
|
2123 | function getListOf($type) |
2123 | function getListOf($type) |
2124 | {
|
2124 | {
|
2125 | $sql = $this->getSpecialQuery($type); |
2125 | $sql = $this->getSpecialQuery($type); |
2126 | if ($sql === null) { |
2126 | if ($sql === null) { |
2127 | $this->last_query = ''; |
2127 | $this->last_query = ''; |
2128 | return $this->raiseError(DB_ERROR_UNSUPPORTED); |
2128 | return $this->raiseError(DB_ERROR_UNSUPPORTED); |
2129 | } elseif (is_int($sql) || DB::isError($sql)) { |
2129 | } elseif (is_int($sql) || DB::isError($sql)) { |
2130 | // Previous error
|
2130 | // Previous error
|
2131 | return $this->raiseError($sql); |
2131 | return $this->raiseError($sql); |
2132 | } elseif (is_array($sql)) { |
2132 | } elseif (is_array($sql)) { |
2133 | // Already the result
|
2133 | // Already the result
|
2134 | return $sql; |
2134 | return $sql; |
2135 | }
|
2135 | }
|
2136 | // Launch this query
|
2136 | // Launch this query
|
2137 | return $this->getCol($sql); |
2137 | return $this->getCol($sql); |
2138 | }
|
2138 | }
|
2139 | 2139 | ||
2140 | // }}}
|
2140 | // }}}
|
2141 | // {{{ getSpecialQuery()
|
2141 | // {{{ getSpecialQuery()
|
2142 | 2142 | ||
2143 | /**
|
2143 | /**
|
2144 | * Obtains the query string needed for listing a given type of objects
|
2144 | * Obtains the query string needed for listing a given type of objects
|
2145 | *
|
2145 | *
|
2146 | * @param string $type the kind of objects you want to retrieve
|
2146 | * @param string $type the kind of objects you want to retrieve
|
2147 | *
|
2147 | *
|
2148 | * @return string the SQL query string or null if the driver doesn't
|
2148 | * @return string the SQL query string or null if the driver doesn't
|
2149 | * support the object type requested
|
2149 | * support the object type requested
|
2150 | *
|
2150 | *
|
2151 | * @access protected
|
2151 | * @access protected
|
2152 | * @see DB_common::getListOf()
|
2152 | * @see DB_common::getListOf()
|
2153 | */
|
2153 | */
|
2154 | function getSpecialQuery($type) |
2154 | function getSpecialQuery($type) |
2155 | {
|
2155 | {
|
2156 | return $this->raiseError(DB_ERROR_UNSUPPORTED); |
2156 | return $this->raiseError(DB_ERROR_UNSUPPORTED); |
2157 | }
|
2157 | }
|
2158 | 2158 | ||
2159 | // }}}
|
2159 | // }}}
|
2160 | // {{{ nextQueryIsManip()
|
2160 | // {{{ nextQueryIsManip()
|
2161 | 2161 | ||
2162 | /**
|
2162 | /**
|
2163 | * Sets (or unsets) a flag indicating that the next query will be a
|
2163 | * Sets (or unsets) a flag indicating that the next query will be a
|
2164 | * manipulation query, regardless of the usual DB::isManip() heuristics.
|
2164 | * manipulation query, regardless of the usual DB::isManip() heuristics.
|
2165 | *
|
2165 | *
|
2166 | * @param boolean true to set the flag overriding the isManip() behaviour,
|
2166 | * @param boolean true to set the flag overriding the isManip() behaviour,
|
2167 | * false to clear it and fall back onto isManip()
|
2167 | * false to clear it and fall back onto isManip()
|
2168 | *
|
2168 | *
|
2169 | * @return void
|
2169 | * @return void
|
2170 | *
|
2170 | *
|
2171 | * @access public
|
2171 | * @access public
|
2172 | */
|
2172 | */
|
2173 | function nextQueryIsManip($manip) |
2173 | function nextQueryIsManip($manip) |
2174 | {
|
2174 | {
|
2175 | $this->_next_query_manip = $manip; |
2175 | $this->_next_query_manip = $manip; |
2176 | }
|
2176 | }
|
2177 | 2177 | ||
2178 | // }}}
|
2178 | // }}}
|
2179 | // {{{ _checkManip()
|
2179 | // {{{ _checkManip()
|
2180 | 2180 | ||
2181 | /**
|
2181 | /**
|
2182 | * Checks if the given query is a manipulation query. This also takes into
|
2182 | * Checks if the given query is a manipulation query. This also takes into
|
2183 | * account the _next_query_manip flag and sets the _last_query_manip flag
|
2183 | * account the _next_query_manip flag and sets the _last_query_manip flag
|
2184 | * (and resets _next_query_manip) according to the result.
|
2184 | * (and resets _next_query_manip) according to the result.
|
2185 | *
|
2185 | *
|
2186 | * @param string The query to check.
|
2186 | * @param string The query to check.
|
2187 | *
|
2187 | *
|
2188 | * @return boolean true if the query is a manipulation query, false
|
2188 | * @return boolean true if the query is a manipulation query, false
|
2189 | * otherwise
|
2189 | * otherwise
|
2190 | *
|
2190 | *
|
2191 | * @access protected
|
2191 | * @access protected
|
2192 | */
|
2192 | */
|
2193 | function _checkManip($query) |
2193 | function _checkManip($query) |
2194 | {
|
2194 | {
|
2195 | if ($this->_next_query_manip || DB::isManip($query)) { |
2195 | if ($this->_next_query_manip || DB::isManip($query)) { |
2196 | $this->_last_query_manip = true; |
2196 | $this->_last_query_manip = true; |
2197 | } else { |
2197 | } else { |
2198 | $this->_last_query_manip = false; |
2198 | $this->_last_query_manip = false; |
2199 | }
|
2199 | }
|
2200 | $this->_next_query_manip = false; |
2200 | $this->_next_query_manip = false; |
2201 | return $this->_last_query_manip; |
2201 | return $this->_last_query_manip; |
2202 | $manip = $this->_next_query_manip; |
2202 | $manip = $this->_next_query_manip; |
2203 | }
|
2203 | }
|
2204 | 2204 | ||
2205 | // }}}
|
2205 | // }}}
|
2206 | // {{{ _rtrimArrayValues()
|
2206 | // {{{ _rtrimArrayValues()
|
2207 | 2207 | ||
2208 | /**
|
2208 | /**
|
2209 | * Right-trims all strings in an array
|
2209 | * Right-trims all strings in an array
|
2210 | *
|
2210 | *
|
2211 | * @param array $array the array to be trimmed (passed by reference)
|
2211 | * @param array $array the array to be trimmed (passed by reference)
|
2212 | *
|
2212 | *
|
2213 | * @return void
|
2213 | * @return void
|
2214 | *
|
2214 | *
|
2215 | * @access protected
|
2215 | * @access protected
|
2216 | */
|
2216 | */
|
2217 | function _rtrimArrayValues(&$array) |
2217 | function _rtrimArrayValues(&$array) |
2218 | {
|
2218 | {
|
2219 | foreach ($array as $key => $value) { |
2219 | foreach ($array as $key => $value) { |
2220 | if (is_string($value)) { |
2220 | if (is_string($value)) { |
2221 | $array[$key] = rtrim($value); |
2221 | $array[$key] = rtrim($value); |
2222 | }
|
2222 | }
|
2223 | }
|
2223 | }
|
2224 | }
|
2224 | }
|
2225 | 2225 | ||
2226 | // }}}
|
2226 | // }}}
|
2227 | // {{{ _convertNullArrayValuesToEmpty()
|
2227 | // {{{ _convertNullArrayValuesToEmpty()
|
2228 | 2228 | ||
2229 | /**
|
2229 | /**
|
2230 | * Converts all null values in an array to empty strings
|
2230 | * Converts all null values in an array to empty strings
|
2231 | *
|
2231 | *
|
2232 | * @param array $array the array to be de-nullified (passed by reference)
|
2232 | * @param array $array the array to be de-nullified (passed by reference)
|
2233 | *
|
2233 | *
|
2234 | * @return void
|
2234 | * @return void
|
2235 | *
|
2235 | *
|
2236 | * @access protected
|
2236 | * @access protected
|
2237 | */
|
2237 | */
|
2238 | function _convertNullArrayValuesToEmpty(&$array) |
2238 | function _convertNullArrayValuesToEmpty(&$array) |
2239 | {
|
2239 | {
|
2240 | foreach ($array as $key => $value) { |
2240 | foreach ($array as $key => $value) { |
2241 | if (is_null($value)) { |
2241 | if (is_null($value)) { |
2242 | $array[$key] = ''; |
2242 | $array[$key] = ''; |
2243 | }
|
2243 | }
|
2244 | }
|
2244 | }
|
2245 | }
|
2245 | }
|
2246 | 2246 | ||
2247 | // }}}
|
2247 | // }}}
|
2248 | }
|
2248 | }
|
2249 | 2249 | ||
2250 | /*
|
2250 | /*
|
2251 | * Local variables:
|
2251 | * Local variables:
|
2252 | * tab-width: 4
|
2252 | * tab-width: 4
|
2253 | * c-basic-offset: 4
|
2253 | * c-basic-offset: 4
|
2254 | * End:
|
2254 | * End:
|
2255 | */
|
2255 | */
|
2256 | 2256 | ||
2257 | ?>
|
2257 | ?>
|
2258 | 2258 |