PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/external_lib/DB/common.php

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

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