PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/external_lib/DB/common.php

https://github.com/OwlManAtt/kittokittokitto
PHP | 2257 lines | 748 code | 171 blank | 1338 comment | 133 complexity | 68e207e86dbd23a405b0aa77a7a74fa4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Contains the DB_common base class
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This source file is subject to version 3.0 of the PHP license
  9. * that is available through the world-wide-web at the following URI:
  10. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  11. * the PHP License and are unable to obtain it through the web, please
  12. * send a note to license@php.net so we can mail you a copy immediately.
  13. *
  14. * @category Database
  15. * @package DB
  16. * @author Stig Bakken <ssb@php.net>
  17. * @author Tomas V.V. Cox <cox@idecnet.com>
  18. * @author Daniel Convissor <danielc@php.net>
  19. * @copyright 1997-2005 The PHP Group
  20. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  21. * @version CVS: $Id: common.php,v 1.140 2007/01/12 02:41:07 aharvey Exp $
  22. * @link http://pear.php.net/package/DB
  23. */
  24. /**
  25. * Obtain the PEAR class so it can be extended from
  26. */
  27. require_once 'PEAR.php';
  28. /**
  29. * DB_common is the base class from which each database driver class extends
  30. *
  31. * All common methods are declared here. If a given DBMS driver contains
  32. * a particular method, that method will overload the one here.
  33. *
  34. * @category Database
  35. * @package DB
  36. * @author Stig Bakken <ssb@php.net>
  37. * @author Tomas V.V. Cox <cox@idecnet.com>
  38. * @author Daniel Convissor <danielc@php.net>
  39. * @copyright 1997-2005 The PHP Group
  40. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  41. * @version Release: 1.7.11
  42. * @link http://pear.php.net/package/DB
  43. */
  44. class DB_common extends PEAR
  45. {
  46. // {{{ properties
  47. /**
  48. * The current default fetch mode
  49. * @var integer
  50. */
  51. var $fetchmode = DB_FETCHMODE_ORDERED;
  52. /**
  53. * The name of the class into which results should be fetched when
  54. * DB_FETCHMODE_OBJECT is in effect
  55. *
  56. * @var string
  57. */
  58. var $fetchmode_object_class = 'stdClass';
  59. /**
  60. * Was a connection present when the object was serialized()?
  61. * @var bool
  62. * @see DB_common::__sleep(), DB_common::__wake()
  63. */
  64. var $was_connected = null;
  65. /**
  66. * The most recently executed query
  67. * @var string
  68. */
  69. var $last_query = '';
  70. /**
  71. * Run-time configuration options
  72. *
  73. * The 'optimize' option has been deprecated. Use the 'portability'
  74. * option instead.
  75. *
  76. * @var array
  77. * @see DB_common::setOption()
  78. */
  79. var $options = array(
  80. 'result_buffering' => 500,
  81. 'persistent' => false,
  82. 'ssl' => false,
  83. 'debug' => 0,
  84. 'seqname_format' => '%s_seq',
  85. 'autofree' => false,
  86. 'portability' => DB_PORTABILITY_NONE,
  87. 'optimize' => 'performance', // Deprecated. Use 'portability'.
  88. );
  89. /**
  90. * The parameters from the most recently executed query
  91. * @var array
  92. * @since Property available since Release 1.7.0
  93. */
  94. var $last_parameters = array();
  95. /**
  96. * The elements from each prepared statement
  97. * @var array
  98. */
  99. var $prepare_tokens = array();
  100. /**
  101. * The data types of the various elements in each prepared statement
  102. * @var array
  103. */
  104. var $prepare_types = array();
  105. /**
  106. * The prepared queries
  107. * @var array
  108. */
  109. var $prepared_queries = array();
  110. /**
  111. * Flag indicating that the last query was a manipulation query.
  112. * @access protected
  113. * @var boolean
  114. */
  115. var $_last_query_manip = false;
  116. /**
  117. * Flag indicating that the next query <em>must</em> be a manipulation
  118. * query.
  119. * @access protected
  120. * @var boolean
  121. */
  122. var $_next_query_manip = false;
  123. // }}}
  124. // {{{ DB_common
  125. /**
  126. * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
  127. *
  128. * @return void
  129. */
  130. function DB_common()
  131. {
  132. $this->PEAR('DB_Error');
  133. }
  134. // }}}
  135. // {{{ __sleep()
  136. /**
  137. * Automatically indicates which properties should be saved
  138. * when PHP's serialize() function is called
  139. *
  140. * @return array the array of properties names that should be saved
  141. */
  142. function __sleep()
  143. {
  144. if ($this->connection) {
  145. // Don't disconnect(), people use serialize() for many reasons
  146. $this->was_connected = true;
  147. } else {
  148. $this->was_connected = false;
  149. }
  150. if (isset($this->autocommit)) {
  151. return array('autocommit',
  152. 'dbsyntax',
  153. 'dsn',
  154. 'features',
  155. 'fetchmode',
  156. 'fetchmode_object_class',
  157. 'options',
  158. 'was_connected',
  159. );
  160. } else {
  161. return array('dbsyntax',
  162. 'dsn',
  163. 'features',
  164. 'fetchmode',
  165. 'fetchmode_object_class',
  166. 'options',
  167. 'was_connected',
  168. );
  169. }
  170. }
  171. // }}}
  172. // {{{ __wakeup()
  173. /**
  174. * Automatically reconnects to the database when PHP's unserialize()
  175. * function is called
  176. *
  177. * The reconnection attempt is only performed if the object was connected
  178. * at the time PHP's serialize() function was run.
  179. *
  180. * @return void
  181. */
  182. function __wakeup()
  183. {
  184. if ($this->was_connected) {
  185. $this->connect($this->dsn, $this->options);
  186. }
  187. }
  188. // }}}
  189. // {{{ __toString()
  190. /**
  191. * Automatic string conversion for PHP 5
  192. *
  193. * @return string a string describing the current PEAR DB object
  194. *
  195. * @since Method available since Release 1.7.0
  196. */
  197. function __toString()
  198. {
  199. $info = strtolower(get_class($this));
  200. $info .= ': (phptype=' . $this->phptype .
  201. ', dbsyntax=' . $this->dbsyntax .
  202. ')';
  203. if ($this->connection) {
  204. $info .= ' [connected]';
  205. }
  206. return $info;
  207. }
  208. // }}}
  209. // {{{ toString()
  210. /**
  211. * DEPRECATED: String conversion method
  212. *
  213. * @return string a string describing the current PEAR DB object
  214. *
  215. * @deprecated Method deprecated in Release 1.7.0
  216. */
  217. function toString()
  218. {
  219. return $this->__toString();
  220. }
  221. // }}}
  222. // {{{ quoteString()
  223. /**
  224. * DEPRECATED: Quotes a string so it can be safely used within string
  225. * delimiters in a query
  226. *
  227. * @param string $string the string to be quoted
  228. *
  229. * @return string the quoted string
  230. *
  231. * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  232. * @deprecated Method deprecated some time before Release 1.2
  233. */
  234. function quoteString($string)
  235. {
  236. $string = $this->quote($string);
  237. if ($string{0} == "'") {
  238. return substr($string, 1, -1);
  239. }
  240. return $string;
  241. }
  242. // }}}
  243. // {{{ quote()
  244. /**
  245. * DEPRECATED: Quotes a string so it can be safely used in a query
  246. *
  247. * @param string $string the string to quote
  248. *
  249. * @return string the quoted string or the string <samp>NULL</samp>
  250. * if the value submitted is <kbd>null</kbd>.
  251. *
  252. * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  253. * @deprecated Deprecated in release 1.6.0
  254. */
  255. function quote($string = null)
  256. {
  257. return ($string === null) ? 'NULL'
  258. : "'" . str_replace("'", "''", $string) . "'";
  259. }
  260. // }}}
  261. // {{{ quoteIdentifier()
  262. /**
  263. * Quotes a string so it can be safely used as a table or column name
  264. *
  265. * Delimiting style depends on which database driver is being used.
  266. *
  267. * NOTE: just because you CAN use delimited identifiers doesn't mean
  268. * you SHOULD use them. In general, they end up causing way more
  269. * problems than they solve.
  270. *
  271. * Portability is broken by using the following characters inside
  272. * delimited identifiers:
  273. * + backtick (<kbd>`</kbd>) -- due to MySQL
  274. * + double quote (<kbd>"</kbd>) -- due to Oracle
  275. * + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
  276. *
  277. * Delimited identifiers are known to generally work correctly under
  278. * the following drivers:
  279. * + mssql
  280. * + mysql
  281. * + mysqli
  282. * + oci8
  283. * + odbc(access)
  284. * + odbc(db2)
  285. * + pgsql
  286. * + sqlite
  287. * + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime
  288. * prior to use)
  289. *
  290. * InterBase doesn't seem to be able to use delimited identifiers
  291. * via PHP 4. They work fine under PHP 5.
  292. *
  293. * @param string $str the identifier name to be quoted
  294. *
  295. * @return string the quoted identifier
  296. *
  297. * @since Method available since Release 1.6.0
  298. */
  299. function quoteIdentifier($str)
  300. {
  301. return '"' . str_replace('"', '""', $str) . '"';
  302. }
  303. // }}}
  304. // {{{ quoteSmart()
  305. /**
  306. * Formats input so it can be safely used in a query
  307. *
  308. * The output depends on the PHP data type of input and the database
  309. * type being used.
  310. *
  311. * @param mixed $in the data to be formatted
  312. *
  313. * @return mixed the formatted data. The format depends on the input's
  314. * PHP type:
  315. * <ul>
  316. * <li>
  317. * <kbd>input</kbd> -> <samp>returns</samp>
  318. * </li>
  319. * <li>
  320. * <kbd>null</kbd> -> the string <samp>NULL</samp>
  321. * </li>
  322. * <li>
  323. * <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
  324. * </li>
  325. * <li>
  326. * <kbd>bool</kbd> -> output depends on the driver in use
  327. * Most drivers return integers: <samp>1</samp> if
  328. * <kbd>true</kbd> or <samp>0</samp> if
  329. * <kbd>false</kbd>.
  330. * Some return strings: <samp>TRUE</samp> if
  331. * <kbd>true</kbd> or <samp>FALSE</samp> if
  332. * <kbd>false</kbd>.
  333. * Finally one returns strings: <samp>T</samp> if
  334. * <kbd>true</kbd> or <samp>F</samp> if
  335. * <kbd>false</kbd>. Here is a list of each DBMS,
  336. * the values returned and the suggested column type:
  337. * <ul>
  338. * <li>
  339. * <kbd>dbase</kbd> -> <samp>T/F</samp>
  340. * (<kbd>Logical</kbd>)
  341. * </li>
  342. * <li>
  343. * <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
  344. * (<kbd>BOOLEAN</kbd>)
  345. * </li>
  346. * <li>
  347. * <kbd>ibase</kbd> -> <samp>1/0</samp>
  348. * (<kbd>SMALLINT</kbd>) [1]
  349. * </li>
  350. * <li>
  351. * <kbd>ifx</kbd> -> <samp>1/0</samp>
  352. * (<kbd>SMALLINT</kbd>) [1]
  353. * </li>
  354. * <li>
  355. * <kbd>msql</kbd> -> <samp>1/0</samp>
  356. * (<kbd>INTEGER</kbd>)
  357. * </li>
  358. * <li>
  359. * <kbd>mssql</kbd> -> <samp>1/0</samp>
  360. * (<kbd>BIT</kbd>)
  361. * </li>
  362. * <li>
  363. * <kbd>mysql</kbd> -> <samp>1/0</samp>
  364. * (<kbd>TINYINT(1)</kbd>)
  365. * </li>
  366. * <li>
  367. * <kbd>mysqli</kbd> -> <samp>1/0</samp>
  368. * (<kbd>TINYINT(1)</kbd>)
  369. * </li>
  370. * <li>
  371. * <kbd>oci8</kbd> -> <samp>1/0</samp>
  372. * (<kbd>NUMBER(1)</kbd>)
  373. * </li>
  374. * <li>
  375. * <kbd>odbc</kbd> -> <samp>1/0</samp>
  376. * (<kbd>SMALLINT</kbd>) [1]
  377. * </li>
  378. * <li>
  379. * <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
  380. * (<kbd>BOOLEAN</kbd>)
  381. * </li>
  382. * <li>
  383. * <kbd>sqlite</kbd> -> <samp>1/0</samp>
  384. * (<kbd>INTEGER</kbd>)
  385. * </li>
  386. * <li>
  387. * <kbd>sybase</kbd> -> <samp>1/0</samp>
  388. * (<kbd>TINYINT(1)</kbd>)
  389. * </li>
  390. * </ul>
  391. * [1] Accommodate the lowest common denominator because not all
  392. * versions of have <kbd>BOOLEAN</kbd>.
  393. * </li>
  394. * <li>
  395. * other (including strings and numeric strings) ->
  396. * the data with single quotes escaped by preceeding
  397. * single quotes, backslashes are escaped by preceeding
  398. * backslashes, then the whole string is encapsulated
  399. * between single quotes
  400. * </li>
  401. * </ul>
  402. *
  403. * @see DB_common::escapeSimple()
  404. * @since Method available since Release 1.6.0
  405. */
  406. function quoteSmart($in)
  407. {
  408. if (is_int($in)) {
  409. return $in;
  410. } elseif (is_float($in)) {
  411. return $this->quoteFloat($in);
  412. } elseif (is_bool($in)) {
  413. return $this->quoteBoolean($in);
  414. } elseif (is_null($in)) {
  415. return 'NULL';
  416. } else {
  417. if ($this->dbsyntax == 'access'
  418. && preg_match('/^#.+#$/', $in))
  419. {
  420. return $this->escapeSimple($in);
  421. }
  422. return "'" . $this->escapeSimple($in) . "'";
  423. }
  424. }
  425. // }}}
  426. // {{{ quoteBoolean()
  427. /**
  428. * Formats a boolean value for use within a query in a locale-independent
  429. * manner.
  430. *
  431. * @param boolean the boolean value to be quoted.
  432. * @return string the quoted string.
  433. * @see DB_common::quoteSmart()
  434. * @since Method available since release 1.7.8.
  435. */
  436. function quoteBoolean($boolean) {
  437. return $boolean ? '1' : '0';
  438. }
  439. // }}}
  440. // {{{ quoteFloat()
  441. /**
  442. * Formats a float value for use within a query in a locale-independent
  443. * manner.
  444. *
  445. * @param float the float value to be quoted.
  446. * @return string the quoted string.
  447. * @see DB_common::quoteSmart()
  448. * @since Method available since release 1.7.8.
  449. */
  450. function quoteFloat($float) {
  451. return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'";
  452. }
  453. // }}}
  454. // {{{ escapeSimple()
  455. /**
  456. * Escapes a string according to the current DBMS's standards
  457. *
  458. * In SQLite, this makes things safe for inserts/updates, but may
  459. * cause problems when performing text comparisons against columns
  460. * containing binary data. See the
  461. * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
  462. *
  463. * @param string $str the string to be escaped
  464. *
  465. * @return string the escaped string
  466. *
  467. * @see DB_common::quoteSmart()
  468. * @since Method available since Release 1.6.0
  469. */
  470. function escapeSimple($str)
  471. {
  472. return str_replace("'", "''", $str);
  473. }
  474. // }}}
  475. // {{{ provides()
  476. /**
  477. * Tells whether the present driver supports a given feature
  478. *
  479. * @param string $feature the feature you're curious about
  480. *
  481. * @return bool whether this driver supports $feature
  482. */
  483. function provides($feature)
  484. {
  485. return $this->features[$feature];
  486. }
  487. // }}}
  488. // {{{ setFetchMode()
  489. /**
  490. * Sets the fetch mode that should be used by default for query results
  491. *
  492. * @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
  493. * or DB_FETCHMODE_OBJECT
  494. * @param string $object_class the class name of the object to be returned
  495. * by the fetch methods when the
  496. * DB_FETCHMODE_OBJECT mode is selected.
  497. * If no class is specified by default a cast
  498. * to object from the assoc array row will be
  499. * done. There is also the posibility to use
  500. * and extend the 'DB_row' class.
  501. *
  502. * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
  503. */
  504. function setFetchMode($fetchmode, $object_class = 'stdClass')
  505. {
  506. switch ($fetchmode) {
  507. case DB_FETCHMODE_OBJECT:
  508. $this->fetchmode_object_class = $object_class;
  509. case DB_FETCHMODE_ORDERED:
  510. case DB_FETCHMODE_ASSOC:
  511. $this->fetchmode = $fetchmode;
  512. break;
  513. default:
  514. return $this->raiseError('invalid fetchmode mode');
  515. }
  516. }
  517. // }}}
  518. // {{{ setOption()
  519. /**
  520. * Sets run-time configuration options for PEAR DB
  521. *
  522. * Options, their data types, default values and description:
  523. * <ul>
  524. * <li>
  525. * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
  526. * <br />should results be freed automatically when there are no
  527. * more rows?
  528. * </li><li>
  529. * <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp>
  530. * <br />how many rows of the result set should be buffered?
  531. * <br />In mysql: mysql_unbuffered_query() is used instead of
  532. * mysql_query() if this value is 0. (Release 1.7.0)
  533. * <br />In oci8: this value is passed to ocisetprefetch().
  534. * (Release 1.7.0)
  535. * </li><li>
  536. * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
  537. * <br />debug level
  538. * </li><li>
  539. * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
  540. * <br />should the connection be persistent?
  541. * </li><li>
  542. * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
  543. * <br />portability mode constant (see below)
  544. * </li><li>
  545. * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
  546. * <br />the sprintf() format string used on sequence names. This
  547. * format is applied to sequence names passed to
  548. * createSequence(), nextID() and dropSequence().
  549. * </li><li>
  550. * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
  551. * <br />use ssl to connect?
  552. * </li>
  553. * </ul>
  554. *
  555. * -----------------------------------------
  556. *
  557. * PORTABILITY MODES
  558. *
  559. * These modes are bitwised, so they can be combined using <kbd>|</kbd>
  560. * and removed using <kbd>^</kbd>. See the examples section below on how
  561. * to do this.
  562. *
  563. * <samp>DB_PORTABILITY_NONE</samp>
  564. * turn off all portability features
  565. *
  566. * This mode gets automatically turned on if the deprecated
  567. * <var>optimize</var> option gets set to <samp>performance</samp>.
  568. *
  569. *
  570. * <samp>DB_PORTABILITY_LOWERCASE</samp>
  571. * convert names of tables and fields to lower case when using
  572. * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
  573. *
  574. * This mode gets automatically turned on in the following databases
  575. * if the deprecated option <var>optimize</var> gets set to
  576. * <samp>portability</samp>:
  577. * + oci8
  578. *
  579. *
  580. * <samp>DB_PORTABILITY_RTRIM</samp>
  581. * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
  582. *
  583. *
  584. * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
  585. * force reporting the number of rows deleted
  586. *
  587. * Some DBMS's don't count the number of rows deleted when performing
  588. * simple <kbd>DELETE FROM tablename</kbd> queries. This portability
  589. * mode tricks such DBMS's into telling the count by adding
  590. * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
  591. *
  592. * This mode gets automatically turned on in the following databases
  593. * if the deprecated option <var>optimize</var> gets set to
  594. * <samp>portability</samp>:
  595. * + fbsql
  596. * + mysql
  597. * + mysqli
  598. * + sqlite
  599. *
  600. *
  601. * <samp>DB_PORTABILITY_NUMROWS</samp>
  602. * enable hack that makes <kbd>numRows()</kbd> work in Oracle
  603. *
  604. * This mode gets automatically turned on in the following databases
  605. * if the deprecated option <var>optimize</var> gets set to
  606. * <samp>portability</samp>:
  607. * + oci8
  608. *
  609. *
  610. * <samp>DB_PORTABILITY_ERRORS</samp>
  611. * makes certain error messages in certain drivers compatible
  612. * with those from other DBMS's
  613. *
  614. * + mysql, mysqli: change unique/primary key constraints
  615. * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
  616. *
  617. * + odbc(access): MS's ODBC driver reports 'no such field' as code
  618. * 07001, which means 'too few parameters.' When this option is on
  619. * that code gets mapped to DB_ERROR_NOSUCHFIELD.
  620. * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
  621. *
  622. * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
  623. * convert null values to empty strings in data output by get*() and
  624. * fetch*(). Needed because Oracle considers empty strings to be null,
  625. * while most other DBMS's know the difference between empty and null.
  626. *
  627. *
  628. * <samp>DB_PORTABILITY_ALL</samp>
  629. * turn on all portability features
  630. *
  631. * -----------------------------------------
  632. *
  633. * Example 1. Simple setOption() example
  634. * <code>
  635. * $db->setOption('autofree', true);
  636. * </code>
  637. *
  638. * Example 2. Portability for lowercasing and trimming
  639. * <code>
  640. * $db->setOption('portability',
  641. * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
  642. * </code>
  643. *
  644. * Example 3. All portability options except trimming
  645. * <code>
  646. * $db->setOption('portability',
  647. * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
  648. * </code>
  649. *
  650. * @param string $option option name
  651. * @param mixed $value value for the option
  652. *
  653. * @return int DB_OK on success. A DB_Error object on failure.
  654. *
  655. * @see DB_common::$options
  656. */
  657. function setOption($option, $value)
  658. {
  659. if (isset($this->options[$option])) {
  660. $this->options[$option] = $value;
  661. /*
  662. * Backwards compatibility check for the deprecated 'optimize'
  663. * option. Done here in case settings change after connecting.
  664. */
  665. if ($option == 'optimize') {
  666. if ($value == 'portability') {
  667. switch ($this->phptype) {
  668. case 'oci8':
  669. $this->options['portability'] =
  670. DB_PORTABILITY_LOWERCASE |
  671. DB_PORTABILITY_NUMROWS;
  672. break;
  673. case 'fbsql':
  674. case 'mysql':
  675. case 'mysqli':
  676. case 'sqlite':
  677. $this->options['portability'] =
  678. DB_PORTABILITY_DELETE_COUNT;
  679. break;
  680. }
  681. } else {
  682. $this->options['portability'] = DB_PORTABILITY_NONE;
  683. }
  684. }
  685. return DB_OK;
  686. }
  687. return $this->raiseError("unknown option $option");
  688. }
  689. // }}}
  690. // {{{ getOption()
  691. /**
  692. * Returns the value of an option
  693. *
  694. * @param string $option the option name you're curious about
  695. *
  696. * @return mixed the option's value
  697. */
  698. function getOption($option)
  699. {
  700. if (isset($this->options[$option])) {
  701. return $this->options[$option];
  702. }
  703. return $this->raiseError("unknown option $option");
  704. }
  705. // }}}
  706. // {{{ prepare()
  707. /**
  708. * Prepares a query for multiple execution with execute()
  709. *
  710. * Creates a query that can be run multiple times. Each time it is run,
  711. * the placeholders, if any, will be replaced by the contents of
  712. * execute()'s $data argument.
  713. *
  714. * Three types of placeholders can be used:
  715. * + <kbd>?</kbd> scalar value (i.e. strings, integers). The system
  716. * will automatically quote and escape the data.
  717. * + <kbd>!</kbd> value is inserted 'as is'
  718. * + <kbd>&</kbd> requires a file name. The file's contents get
  719. * inserted into the query (i.e. saving binary
  720. * data in a db)
  721. *
  722. * Example 1.
  723. * <code>
  724. * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  725. * $data = array(
  726. * "John's text",
  727. * "'it''s good'",
  728. * 'filename.txt'
  729. * );
  730. * $res = $db->execute($sth, $data);
  731. * </code>
  732. *
  733. * Use backslashes to escape placeholder characters if you don't want
  734. * them to be interpreted as placeholders:
  735. * <pre>
  736. * "UPDATE foo SET col=? WHERE col='over \& under'"
  737. * </pre>
  738. *
  739. * With some database backends, this is emulated.
  740. *
  741. * {@internal ibase and oci8 have their own prepare() methods.}}
  742. *
  743. * @param string $query the query to be prepared
  744. *
  745. * @return mixed DB statement resource on success. A DB_Error object
  746. * on failure.
  747. *
  748. * @see DB_common::execute()
  749. */
  750. function prepare($query)
  751. {
  752. $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
  753. PREG_SPLIT_DELIM_CAPTURE);
  754. $token = 0;
  755. $types = array();
  756. $newtokens = array();
  757. foreach ($tokens as $val) {
  758. switch ($val) {
  759. case '?':
  760. $types[$token++] = DB_PARAM_SCALAR;
  761. break;
  762. case '&':
  763. $types[$token++] = DB_PARAM_OPAQUE;
  764. break;
  765. case '!':
  766. $types[$token++] = DB_PARAM_MISC;
  767. break;
  768. default:
  769. $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
  770. }
  771. }
  772. $this->prepare_tokens[] = &$newtokens;
  773. end($this->prepare_tokens);
  774. $k = key($this->prepare_tokens);
  775. $this->prepare_types[$k] = $types;
  776. $this->prepared_queries[$k] = implode(' ', $newtokens);
  777. return $k;
  778. }
  779. // }}}
  780. // {{{ autoPrepare()
  781. /**
  782. * Automaticaly generates an insert or update query and pass it to prepare()
  783. *
  784. * @param string $table the table name
  785. * @param array $table_fields the array of field names
  786. * @param int $mode a type of query to make:
  787. * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  788. * @param string $where for update queries: the WHERE clause to
  789. * append to the SQL statement. Don't
  790. * include the "WHERE" keyword.
  791. *
  792. * @return resource the query handle
  793. *
  794. * @uses DB_common::prepare(), DB_common::buildManipSQL()
  795. */
  796. function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT,
  797. $where = false)
  798. {
  799. $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
  800. if (DB::isError($query)) {
  801. return $query;
  802. }
  803. return $this->prepare($query);
  804. }
  805. // }}}
  806. // {{{ autoExecute()
  807. /**
  808. * Automaticaly generates an insert or update query and call prepare()
  809. * and execute() with it
  810. *
  811. * @param string $table the table name
  812. * @param array $fields_values the associative array where $key is a
  813. * field name and $value its value
  814. * @param int $mode a type of query to make:
  815. * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  816. * @param string $where for update queries: the WHERE clause to
  817. * append to the SQL statement. Don't
  818. * include the "WHERE" keyword.
  819. *
  820. * @return mixed a new DB_result object for successful SELECT queries
  821. * or DB_OK for successul data manipulation queries.
  822. * A DB_Error object on failure.
  823. *
  824. * @uses DB_common::autoPrepare(), DB_common::execute()
  825. */
  826. function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT,
  827. $where = false)
  828. {
  829. $sth = $this->autoPrepare($table, array_keys($fields_values), $mode,
  830. $where);
  831. if (DB::isError($sth)) {
  832. return $sth;
  833. }
  834. $ret =& $this->execute($sth, array_values($fields_values));
  835. $this->freePrepared($sth);
  836. return $ret;
  837. }
  838. // }}}
  839. // {{{ buildManipSQL()
  840. /**
  841. * Produces an SQL query string for autoPrepare()
  842. *
  843. * Example:
  844. * <pre>
  845. * buildManipSQL('table_sql', array('field1', 'field2', 'field3'),
  846. * DB_AUTOQUERY_INSERT);
  847. * </pre>
  848. *
  849. * That returns
  850. * <samp>
  851. * INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
  852. * </samp>
  853. *
  854. * NOTES:
  855. * - This belongs more to a SQL Builder class, but this is a simple
  856. * facility.
  857. * - Be carefull! If you don't give a $where param with an UPDATE
  858. * query, all the records of the table will be updated!
  859. *
  860. * @param string $table the table name
  861. * @param array $table_fields the array of field names
  862. * @param int $mode a type of query to make:
  863. * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  864. * @param string $where for update queries: the WHERE clause to
  865. * append to the SQL statement. Don't
  866. * include the "WHERE" keyword.
  867. *
  868. * @return string the sql query for autoPrepare()
  869. */
  870. function buildManipSQL($table, $table_fields, $mode, $where = false)
  871. {
  872. if (count($table_fields) == 0) {
  873. return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
  874. }
  875. $first = true;
  876. switch ($mode) {
  877. case DB_AUTOQUERY_INSERT:
  878. $values = '';
  879. $names = '';
  880. foreach ($table_fields as $value) {
  881. if ($first) {
  882. $first = false;
  883. } else {
  884. $names .= ',';
  885. $values .= ',';
  886. }
  887. $names .= $value;
  888. $values .= '?';
  889. }
  890. return "INSERT INTO $table ($names) VALUES ($values)";
  891. case DB_AUTOQUERY_UPDATE:
  892. $set = '';
  893. foreach ($table_fields as $value) {
  894. if ($first) {
  895. $first = false;
  896. } else {
  897. $set .= ',';
  898. }
  899. $set .= "$value = ?";
  900. }
  901. $sql = "UPDATE $table SET $set";
  902. if ($where) {
  903. $sql .= " WHERE $where";
  904. }
  905. return $sql;
  906. default:
  907. return $this->raiseError(DB_ERROR_SYNTAX);
  908. }
  909. }
  910. // }}}
  911. // {{{ execute()
  912. /**
  913. * Executes a DB statement prepared with prepare()
  914. *
  915. * Example 1.
  916. * <code>
  917. * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  918. * $data = array(
  919. * "John's text",
  920. * "'it''s good'",
  921. * 'filename.txt'
  922. * );
  923. * $res =& $db->execute($sth, $data);
  924. * </code>
  925. *
  926. * @param resource $stmt a DB statement resource returned from prepare()
  927. * @param mixed $data array, string or numeric data to be used in
  928. * execution of the statement. Quantity of items
  929. * passed must match quantity of placeholders in
  930. * query: meaning 1 placeholder for non-array
  931. * parameters or 1 placeholder per array element.
  932. *
  933. * @return mixed a new DB_result object for successful SELECT queries
  934. * or DB_OK for successul data manipulation queries.
  935. * A DB_Error object on failure.
  936. *
  937. * {@internal ibase and oci8 have their own execute() methods.}}
  938. *
  939. * @see DB_common::prepare()
  940. */
  941. function &execute($stmt, $data = array())
  942. {
  943. $realquery = $this->executeEmulateQuery($stmt, $data);
  944. if (DB::isError($realquery)) {
  945. return $realquery;
  946. }
  947. $result = $this->simpleQuery($realquery);
  948. if ($result === DB_OK || DB::isError($result)) {
  949. return $result;
  950. } else {
  951. $tmp =& new DB_result($this, $result);
  952. return $tmp;
  953. }
  954. }
  955. // }}}
  956. // {{{ executeEmulateQuery()
  957. /**
  958. * Emulates executing prepared statements if the DBMS not support them
  959. *
  960. * @param resource $stmt a DB statement resource returned from execute()
  961. * @param mixed $data array, string or numeric data to be used in
  962. * execution of the statement. Quantity of items
  963. * passed must match quantity of placeholders in
  964. * query: meaning 1 placeholder for non-array
  965. * parameters or 1 placeholder per array element.
  966. *
  967. * @return mixed a string containing the real query run when emulating
  968. * prepare/execute. A DB_Error object on failure.
  969. *
  970. * @access protected
  971. * @see DB_common::execute()
  972. */
  973. function executeEmulateQuery($stmt, $data = array())
  974. {
  975. $stmt = (int)$stmt;
  976. $data = (array)$data;
  977. $this->last_parameters = $data;
  978. if (count($this->prepare_types[$stmt]) != count($data)) {
  979. $this->last_query = $this->prepared_queries[$stmt];
  980. return $this->raiseError(DB_ERROR_MISMATCH);
  981. }
  982. $realquery = $this->prepare_tokens[$stmt][0];
  983. $i = 0;
  984. foreach ($data as $value) {
  985. if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
  986. $realquery .= $this->quoteSmart($value);
  987. } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
  988. $fp = @fopen($value, 'rb');
  989. if (!$fp) {
  990. return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
  991. }
  992. $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
  993. fclose($fp);
  994. } else {
  995. $realquery .= $value;
  996. }
  997. $realquery .= $this->prepare_tokens[$stmt][++$i];
  998. }
  999. return $realquery;
  1000. }
  1001. // }}}
  1002. // {{{ executeMultiple()
  1003. /**
  1004. * Performs several execute() calls on the same statement handle
  1005. *
  1006. * $data must be an array indexed numerically
  1007. * from 0, one execute call is done for every "row" in the array.
  1008. *
  1009. * If an error occurs during execute(), executeMultiple() does not
  1010. * execute the unfinished rows, but rather returns that error.
  1011. *
  1012. * @param resource $stmt query handle from prepare()
  1013. * @param array $data numeric array containing the
  1014. * data to insert into the query
  1015. *
  1016. * @return int DB_OK on success. A DB_Error object on failure.
  1017. *
  1018. * @see DB_common::prepare(), DB_common::execute()
  1019. */
  1020. function executeMultiple($stmt, $data)
  1021. {
  1022. foreach ($data as $value) {
  1023. $res =& $this->execute($stmt, $value);
  1024. if (DB::isError($res)) {
  1025. return $res;
  1026. }
  1027. }
  1028. return DB_OK;
  1029. }
  1030. // }}}
  1031. // {{{ freePrepared()
  1032. /**
  1033. * Frees the internal resources associated with a prepared query
  1034. *
  1035. * @param resource $stmt the prepared statement's PHP resource
  1036. * @param bool $free_resource should the PHP resource be freed too?
  1037. * Use false if you need to get data
  1038. * from the result set later.
  1039. *
  1040. * @return bool TRUE on success, FALSE if $result is invalid
  1041. *
  1042. * @see DB_common::prepare()
  1043. */
  1044. function freePrepared($stmt, $free_resource = true)
  1045. {
  1046. $stmt = (int)$stmt;
  1047. if (isset($this->prepare_tokens[$stmt])) {
  1048. unset($this->prepare_tokens[$stmt]);
  1049. unset($this->prepare_types[$stmt]);
  1050. unset($this->prepared_queries[$stmt]);
  1051. return true;
  1052. }
  1053. return false;
  1054. }
  1055. // }}}
  1056. // {{{ modifyQuery()
  1057. /**
  1058. * Changes a query string for various DBMS specific reasons
  1059. *
  1060. * It is defined here to ensure all drivers have this method available.
  1061. *
  1062. * @param string $query the query string to modify
  1063. *
  1064. * @return string the modified query string
  1065. *
  1066. * @access protected
  1067. * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
  1068. * DB_sqlite::modifyQuery()
  1069. */
  1070. function modifyQuery($query)
  1071. {
  1072. return $query;
  1073. }
  1074. // }}}
  1075. // {{{ modifyLimitQuery()
  1076. /**
  1077. * Adds LIMIT clauses to a query string according to current DBMS standards
  1078. *
  1079. * It is defined here to assure that all implementations
  1080. * have this method defined.
  1081. *
  1082. * @param string $query the query to modify
  1083. * @param int $from the row to start to fetching (0 = the first row)
  1084. * @param int $count the numbers of rows to fetch
  1085. * @param mixed $params array, string or numeric data to be used in
  1086. * execution of the statement. Quantity of items
  1087. * passed must match quantity of placeholders in
  1088. * query: meaning 1 placeholder for non-array
  1089. * parameters or 1 placeholder per array element.
  1090. *
  1091. * @return string the query string with LIMIT clauses added
  1092. *
  1093. * @access protected
  1094. */
  1095. function modifyLimitQuery($query, $from, $count, $params = array())
  1096. {
  1097. return $query;
  1098. }
  1099. // }}}
  1100. // {{{ query()
  1101. /**
  1102. * Sends a query to the database server
  1103. *
  1104. * The query string can be either a normal statement to be sent directly
  1105. * to the server OR if <var>$params</var> are passed the query can have
  1106. * placeholders and it will be passed through prepare() and execute().
  1107. *
  1108. * @param string $query the SQL query or the statement to prepare
  1109. * @param mixed $params array, string or numeric data to be used in
  1110. * execution of the statement. Quantity of items
  1111. * passed must match quantity of placeholders in
  1112. * query: meaning 1 placeholder for non-array
  1113. * parameters or 1 placeholder per array element.
  1114. *
  1115. * @return mixed a new DB_result object for successful SELECT queries
  1116. * or DB_OK for successul data manipulation queries.
  1117. * A DB_Error object on failure.
  1118. *
  1119. * @see DB_result, DB_common::prepare(), DB_common::execute()
  1120. */
  1121. function &query($query, $params = array())
  1122. {
  1123. if (sizeof($params) > 0) {
  1124. $sth = $this->prepare($query);
  1125. if (DB::isError($sth)) {
  1126. return $sth;
  1127. }
  1128. $ret =& $this->execute($sth, $params);
  1129. $this->freePrepared($sth, false);
  1130. return $ret;
  1131. } else {
  1132. $this->last_parameters = array();
  1133. $result = $this->simpleQuery($query);
  1134. if ($result === DB_OK || DB::isError($result)) {
  1135. return $result;
  1136. } else {
  1137. $tmp =& new DB_result($this, $result);
  1138. return $tmp;
  1139. }
  1140. }
  1141. }
  1142. // }}}
  1143. // {{{ limitQuery()
  1144. /**
  1145. * Generates and executes a LIMIT query
  1146. *
  1147. * @param string $query the query
  1148. * @param intr $from the row to start to fetching (0 = the first row)
  1149. * @param int $count the numbers of rows to fetch
  1150. * @param mixed $params array, string or numeric data to be used in
  1151. * execution of the statement. Quantity of items
  1152. * passed must match quantity of placeholders in
  1153. * query: meaning 1 placeholder for non-array
  1154. * parameters or 1 placeholder per array element.
  1155. *
  1156. * @return mixed a new DB_result object for successful SELECT queries
  1157. * or DB_OK for successul data manipulation queries.
  1158. * A DB_Error object on failure.
  1159. */
  1160. function &limitQuery($query, $from, $count, $params = array())
  1161. {
  1162. $query = $this->modifyLimitQuery($query, $from, $count, $params);
  1163. if (DB::isError($query)){
  1164. return $query;
  1165. }
  1166. $result =& $this->query($query, $params);
  1167. if (is_a($result, 'DB_result')) {
  1168. $result->setOption('limit_from', $from);
  1169. $result->setOption('limit_count', $count);
  1170. }
  1171. return $result;
  1172. }
  1173. // }}}
  1174. // {{{ getOne()
  1175. /**
  1176. * Fetches the first column of the first row from a query result
  1177. *
  1178. * Takes care of doing the query and freeing the results when finished.
  1179. *
  1180. * @param string $query the SQL query
  1181. * @param mixed $params array, string or numeric data to be used in
  1182. * execution of the statement. Quantity of items
  1183. * passed must match quantity of placeholders in
  1184. * query: meaning 1 placeholder for non-array
  1185. * parameters or 1 placeholder per array element.
  1186. *
  1187. * @return mixed the returned value of the query.
  1188. * A DB_Error object on failure.
  1189. */
  1190. function &getOne($query, $params = array())
  1191. {
  1192. $params = (array)$params;
  1193. // modifyLimitQuery() would be nice here, but it causes BC issues
  1194. if (sizeof($params) > 0) {
  1195. $sth = $this->prepare($query);
  1196. if (DB::isError($sth)) {
  1197. return $sth;
  1198. }
  1199. $res =& $this->execute($sth, $params);
  1200. $this->freePrepared($sth);
  1201. } else {
  1202. $res =& $this->query($query);
  1203. }
  1204. if (DB::isError($res)) {
  1205. return $res;
  1206. }
  1207. $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
  1208. $res->free();
  1209. if ($err !== DB_OK) {
  1210. return $err;
  1211. }
  1212. return $row[0];
  1213. }
  1214. // }}}
  1215. // {{{ getRow()
  1216. /**
  1217. * Fetches the first row of data returned from a query result
  1218. *
  1219. * Takes care of doing the query and freeing the results when finished.
  1220. *
  1221. * @param string $query the SQL query
  1222. * @param mixed $params array, string or numeric data to be used in
  1223. * execution of the statement. Quantity of items
  1224. * passed must match quantity of placeholders in
  1225. * query: meaning 1 placeholder for non-array
  1226. * parameters or 1 placeholder per array element.
  1227. * @param int $fetchmode the fetch mode to use
  1228. *
  1229. * @return array the first row of results as an array.
  1230. * A DB_Error object on failure.
  1231. */
  1232. function &getRow($query, $params = array(),
  1233. $fetchmode = DB_FETCHMODE_DEFAULT)
  1234. {
  1235. // compat check, the params and fetchmode parameters used to
  1236. // have the opposite order
  1237. if (!is_array($params)) {
  1238. if (is_array($fetchmode)) {
  1239. if ($params === null) {
  1240. $tmp = DB_FETCHMODE_DEFAULT;
  1241. } else {
  1242. $tmp = $params;
  1243. }
  1244. $params = $fetchmode;
  1245. $fetchmode = $tmp;
  1246. } elseif ($params !== null) {
  1247. $fetchmode = $params;
  1248. $params = array();
  1249. }
  1250. }
  1251. // modifyLimitQuery() would be nice here, but it causes BC issues
  1252. if (sizeof($params) > 0) {
  1253. $sth = $this->prepare($query);
  1254. if (DB::isError($sth)) {
  1255. return $sth;
  1256. }
  1257. $res =& $this->execute($sth, $params);
  1258. $this->freePrepared($sth);
  1259. } else {
  1260. $res =& $this->query($query);
  1261. }
  1262. if (DB::isError($res)) {
  1263. return $res;
  1264. }
  1265. $err = $res->fetchInto($row, $fetchmode);
  1266. $res->free();
  1267. if ($err !== DB_OK) {
  1268. return $err;
  1269. }
  1270. return $row;
  1271. }
  1272. // }}}
  1273. // {{{ getCol()
  1274. /**
  1275. * Fetches a single column from a query result and returns it as an
  1276. * indexed array
  1277. *
  1278. * @param string $query the SQL query
  1279. * @param mixed $col which column to return (integer [column number,
  1280. * starting at 0] or string [column name])
  1281. * @param mixed $params array, string or numeric data to be used in
  1282. * execution of the statement. Quantity of items
  1283. * passed must match quantity of placeholders in
  1284. * query: meaning 1 placeholder for non-array
  1285. * parameters or 1 placeholder per array element.
  1286. *
  1287. * @return array the results as an array. A DB_Error object on failure.
  1288. *
  1289. * @see DB_common::query()
  1290. */
  1291. function &getCol($query, $col = 0, $params = array())
  1292. {
  1293. $params = (array)$params;
  1294. if (sizeof($params) > 0) {
  1295. $sth = $this->prepare($query);
  1296. if (DB::isError($sth)) {
  1297. return $sth;
  1298. }
  1299. $res =& $this->execute($sth, $params);
  1300. $this->freePrepared($sth);
  1301. } else {
  1302. $res =& $this->query($query);
  1303. }
  1304. if (DB::isError($res)) {
  1305. return $res;
  1306. }
  1307. $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
  1308. if (!is_array($row = $res->fetchRow($fetchmode))) {
  1309. $ret = array();
  1310. } else {
  1311. if (!array_key_exists($col, $row)) {
  1312. $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
  1313. } else {
  1314. $ret = array($row[$col]);
  1315. while (is_array($row = $res->fetchRow($fetchmode))) {
  1316. $ret[] = $row[$col];
  1317. }
  1318. }
  1319. }
  1320. $res->free();
  1321. if (DB::isError($row)) {
  1322. $ret = $row;
  1323. }
  1324. return $ret;
  1325. }
  1326. // }}}
  1327. // {{{ getAssoc()
  1328. /**
  1329. * Fetches an entire query result and returns it as an
  1330. * associative array using the first column as the key
  1331. *
  1332. * If the result set contains more than two columns, the value
  1333. * will be an array of the values from column 2-n. If the result
  1334. * set contains only two columns, the returned value will be a
  1335. * scalar with the value of the second column (unless forced to an
  1336. * array with the $force_array parameter). A DB error code is
  1337. * returned on errors. If the result set contains fewer than two
  1338. * columns, a DB_ERROR_TRUNCATED error is returned.
  1339. *
  1340. * For example, if the table "mytable" contains:
  1341. *
  1342. * <pre>
  1343. * ID TEXT DATE
  1344. * --------------------------------
  1345. * 1 'one' 944679408
  1346. * 2 'two' 944679408
  1347. * 3 'three' 944679408
  1348. * </pre>
  1349. *
  1350. * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  1351. * <pre>
  1352. * array(
  1353. * '1' => 'one',
  1354. * '2' => 'two',
  1355. * '3' => 'three',
  1356. * )
  1357. * </pre>
  1358. *
  1359. * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  1360. * <pre>
  1361. * array(
  1362. * '1' => array('one', '944679408'),
  1363. * '2' => array('two', '944679408'),
  1364. * '3' => array('three', '944679408')
  1365. * )
  1366. * </pre>
  1367. *
  1368. * If the more than one row occurs with the same value in the
  1369. * first column, the last row overwrites all previous ones by
  1370. * default. Use the $group parameter if you don't want to
  1371. * overwrite like this. Example:
  1372. *
  1373. * <pre>
  1374. * getAssoc('SELECT category,id,name FROM mytable', false, null,
  1375. * DB_FETCHMODE_ASSOC, true) returns:
  1376. *
  1377. * array(
  1378. * '1' => array(array('id' => '4', 'name' => 'number four'),
  1379. * array('id' => '6', 'name' => 'number six')
  1380. * ),
  1381. * '9' => array(array('id' => '4', 'name' => 'number four'),
  1382. * array('id' => '6', 'name' => 'number six')
  1383. * )
  1384. * )
  1385. * </pre>
  1386. *
  1387. * Keep in mind that database functions in PHP usually return string
  1388. * values for results regardless of the database's internal type.
  1389. *
  1390. * @param string $query the SQL query
  1391. * @param bool $force_array used only when the query returns
  1392. * exactly two columns. If true, the values
  1393. * of the returned array will be one-element
  1394. * arrays instead of scalars.
  1395. * @param mixed $params array, string or numeric data to be used in
  1396. * execution of the statement. Quantity of
  1397. * items passed must match quantity of
  1398. * placeholders in query: meaning 1
  1399. * placeholder for non-array parameters or
  1400. * 1 placeholder per array element.
  1401. * @param int $fetchmode the fetch mode to use
  1402. * @param bool $group if true, the values of the returned array
  1403. * is wrapped in another array. If the same
  1404. * key value (in the first column) repeats
  1405. * itself, the values will be appended to
  1406. * this array instead …

Large files files are truncated, but you can click here to view the full file