common.php 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Stig Bakken <ssb@php.net> |
  17. // | Tomas V.V.Cox <cox@idecnet.com> |
  18. // | Maintainer: Daniel Convissor <danielc@php.net> |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: common.php,v 1.91 2004/02/19 08:08:06 danielc Exp $
  22. require_once 'PEAR.php';
  23. /**
  24. * DB_common is a base class for DB implementations, and must be
  25. * inherited by all such
  26. *
  27. * @package DB
  28. * @version $Id: common.php,v 1.91 2004/02/19 08:08:06 danielc Exp $
  29. * @category Database
  30. * @author Stig Bakken <ssb@php.net>
  31. * @author Tomas V.V.Cox <cox@idecnet.com>
  32. */
  33. class DB_common extends PEAR
  34. {
  35. // {{{ properties
  36. /**
  37. * assoc of capabilities for this DB implementation
  38. * $features['limit'] => 'emulate' => emulate with fetch row by number
  39. * 'alter' => alter the query
  40. * false => skip rows
  41. * @var array
  42. */
  43. var $features = array();
  44. /**
  45. * assoc mapping native error codes to DB ones
  46. * @var array
  47. */
  48. var $errorcode_map = array();
  49. /**
  50. * DB type (mysql, oci8, odbc etc.)
  51. * @var string
  52. */
  53. var $phptype;
  54. /**
  55. * @var string
  56. */
  57. var $prepare_tokens;
  58. /**
  59. * @var string
  60. */
  61. var $prepare_types;
  62. /**
  63. * @var string
  64. */
  65. var $prepared_queries;
  66. /**
  67. * @var integer
  68. */
  69. var $prepare_maxstmt = 0;
  70. /**
  71. * @var string
  72. */
  73. var $last_query = '';
  74. /**
  75. * @var integer
  76. */
  77. var $fetchmode = DB_FETCHMODE_ORDERED;
  78. /**
  79. * @var string
  80. */
  81. var $fetchmode_object_class = 'stdClass';
  82. /**
  83. * Run-time configuration options.
  84. *
  85. * The 'optimize' option has been deprecated. Use the 'portability'
  86. * option instead.
  87. *
  88. * @see DB_common::setOption()
  89. * @var array
  90. */
  91. var $options = array(
  92. 'persistent' => false,
  93. 'ssl' => false,
  94. 'debug' => 0,
  95. 'seqname_format' => '%s_seq',
  96. 'autofree' => false,
  97. 'portability' => DB_PORTABILITY_NONE,
  98. 'optimize' => 'performance', // Deprecated. Use 'portability'.
  99. );
  100. /**
  101. * DB handle
  102. * @var resource
  103. */
  104. var $dbh;
  105. // }}}
  106. // {{{ toString()
  107. /**
  108. * String conversation
  109. *
  110. * @return string
  111. * @access private
  112. */
  113. function toString()
  114. {
  115. $info = strtolower(get_class($this));
  116. $info .= ': (phptype=' . $this->phptype .
  117. ', dbsyntax=' . $this->dbsyntax .
  118. ')';
  119. if ($this->connection) {
  120. $info .= ' [connected]';
  121. }
  122. return $info;
  123. }
  124. // }}}
  125. // {{{ constructor
  126. /**
  127. * Constructor
  128. */
  129. function DB_common()
  130. {
  131. $this->PEAR('DB_Error');
  132. }
  133. // }}}
  134. // {{{ quoteString()
  135. /**
  136. * DEPRECATED: Quotes a string so it can be safely used within string
  137. * delimiters in a query
  138. *
  139. * @return string quoted string
  140. *
  141. * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  142. * @deprecated Deprecated in release 1.2 or lower
  143. * @internal
  144. */
  145. function quoteString($string)
  146. {
  147. $string = $this->quote($string);
  148. if ($string{0} == "'") {
  149. return substr($string, 1, -1);
  150. }
  151. return $string;
  152. }
  153. // }}}
  154. // {{{ quote()
  155. /**
  156. * DEPRECATED: Quotes a string so it can be safely used in a query
  157. *
  158. * @param string $string the input string to quote
  159. *
  160. * @return string The NULL string or the string quotes
  161. * in magic_quote_sybase style
  162. *
  163. * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  164. * @deprecated Deprecated in release 1.6.0
  165. * @internal
  166. */
  167. function quote($string = null)
  168. {
  169. return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'";
  170. }
  171. // }}}
  172. // {{{ quoteIdentifier()
  173. /**
  174. * Quote a string so it can be safely used as a table or column name
  175. *
  176. * Delimiting style depends on which database driver is being used.
  177. *
  178. * NOTE: just because you CAN use delimited identifiers doesn't mean
  179. * you SHOULD use them. In general, they end up causing way more
  180. * problems than they solve.
  181. *
  182. * Portability is broken by using the following characters inside
  183. * delimited identifiers:
  184. * + backtick (<kbd>`</kbd>) -- due to MySQL
  185. * + double quote (<kbd>"</kbd>) -- due to Oracle
  186. * + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
  187. *
  188. * Delimited identifiers are known to generally work correctly under
  189. * the following drivers:
  190. * + mssql
  191. * + mysql
  192. * + mysqli
  193. * + oci8
  194. * + odbc(access)
  195. * + odbc(db2)
  196. * + pgsql
  197. * + sqlite
  198. * + sybase
  199. *
  200. * InterBase doesn't seem to be able to use delimited identifiers
  201. * via PHP 4. They work fine under PHP 5.
  202. *
  203. * @param string $str identifier name to be quoted
  204. *
  205. * @return string quoted identifier string
  206. *
  207. * @since 1.6.0
  208. * @access public
  209. */
  210. function quoteIdentifier($str)
  211. {
  212. return '"' . str_replace('"', '""', $str) . '"';
  213. }
  214. // }}}
  215. // {{{ quoteSmart()
  216. /**
  217. * Format input so it can be safely used in a query
  218. *
  219. * The output depends on the PHP data type of input and the database
  220. * type being used.
  221. *
  222. * @param mixed $in data to be quoted
  223. *
  224. * @return mixed the format of the results depends on the input's
  225. * PHP type:
  226. *
  227. * <ul>
  228. * <li>
  229. * <kbd>input</kbd> -> <samp>returns</samp>
  230. * </li>
  231. * <li>
  232. * <kbd>null</kbd> -> the string <samp>NULL</samp>
  233. * </li>
  234. * <li>
  235. * <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
  236. * </li>
  237. * <li>
  238. * &type.bool; -> output depends on the driver in use
  239. * Most drivers return integers: <samp>1</samp> if
  240. * <kbd>true</kbd> or <samp>0</samp> if
  241. * <kbd>false</kbd>.
  242. * Some return strings: <samp>TRUE</samp> if
  243. * <kbd>true</kbd> or <samp>FALSE</samp> if
  244. * <kbd>false</kbd>.
  245. * Finally one returns strings: <samp>T</samp> if
  246. * <kbd>true</kbd> or <samp>F</samp> if
  247. * <kbd>false</kbd>. Here is a list of each DBMS,
  248. * the values returned and the suggested column type:
  249. * <ul>
  250. * <li>
  251. * <kbd>dbase</kbd> -> <samp>T/F</samp>
  252. * (<kbd>Logical</kbd>)
  253. * </li>
  254. * <li>
  255. * <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
  256. * (<kbd>BOOLEAN</kbd>)
  257. * </li>
  258. * <li>
  259. * <kbd>ibase</kbd> -> <samp>1/0</samp>
  260. * (<kbd>SMALLINT</kbd>) [1]
  261. * </li>
  262. * <li>
  263. * <kbd>ifx</kbd> -> <samp>1/0</samp>
  264. * (<kbd>SMALLINT</kbd>) [1]
  265. * </li>
  266. * <li>
  267. * <kbd>msql</kbd> -> <samp>1/0</samp>
  268. * (<kbd>INTEGER</kbd>)
  269. * </li>
  270. * <li>
  271. * <kbd>mssql</kbd> -> <samp>1/0</samp>
  272. * (<kbd>BIT</kbd>)
  273. * </li>
  274. * <li>
  275. * <kbd>mysql</kbd> -> <samp>1/0</samp>
  276. * (<kbd>TINYINT(1)</kbd>)
  277. * </li>
  278. * <li>
  279. * <kbd>mysqli</kbd> -> <samp>1/0</samp>
  280. * (<kbd>TINYINT(1)</kbd>)
  281. * </li>
  282. * <li>
  283. * <kbd>oci8</kbd> -> <samp>1/0</samp>
  284. * (<kbd>NUMBER(1)</kbd>)
  285. * </li>
  286. * <li>
  287. * <kbd>odbc</kbd> -> <samp>1/0</samp>
  288. * (<kbd>SMALLINT</kbd>) [1]
  289. * </li>
  290. * <li>
  291. * <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
  292. * (<kbd>BOOLEAN</kbd>)
  293. * </li>
  294. * <li>
  295. * <kbd>sqlite</kbd> -> <samp>1/0</samp>
  296. * (<kbd>INTEGER</kbd>)
  297. * </li>
  298. * <li>
  299. * <kbd>sybase</kbd> -> <samp>1/0</samp>
  300. * (<kbd>TINYINT(1)</kbd>)
  301. * </li>
  302. * </ul>
  303. * [1] Accommodate the lowest common denominator because not all
  304. * versions of have <kbd>BOOLEAN</kbd>.
  305. * </li>
  306. * <li>
  307. * other (including strings and numeric strings) ->
  308. * the data with single quotes escaped by preceeding
  309. * single quotes, backslashes are escaped by preceeding
  310. * backslashes, then the whole string is encapsulated
  311. * between single quotes
  312. * </li>
  313. * </ul>
  314. *
  315. * @since 1.6.0
  316. * @see DB_common::escapeSimple()
  317. * @access public
  318. */
  319. function quoteSmart($in)
  320. {
  321. if (is_int($in) || is_double($in)) {
  322. return $in;
  323. } elseif (is_bool($in)) {
  324. return $in ? 1 : 0;
  325. } elseif (is_null($in)) {
  326. return 'NULL';
  327. } else {
  328. return "'" . $this->escapeSimple($in) . "'";
  329. }
  330. }
  331. // }}}
  332. // {{{ escapeSimple()
  333. /**
  334. * Escape a string according to the current DBMS's standards
  335. *
  336. * @param string $str the string to be escaped
  337. *
  338. * @return string the escaped string
  339. *
  340. * @since 1.6.0
  341. * @see DB_common::quoteSmart()
  342. * @access public
  343. */
  344. function escapeSimple($str) {
  345. return str_replace("'", "''", $str);
  346. }
  347. // }}}
  348. // {{{ provides()
  349. /**
  350. * Tell whether a DB implementation or its backend extension
  351. * supports a given feature
  352. *
  353. * @param array $feature name of the feature (see the DB class doc)
  354. * @return bool whether this DB implementation supports $feature
  355. * @access public
  356. */
  357. function provides($feature)
  358. {
  359. return $this->features[$feature];
  360. }
  361. // }}}
  362. // {{{ errorCode()
  363. /**
  364. * Map native error codes to DB's portable ones
  365. *
  366. * Requires that the DB implementation's constructor fills
  367. * in the <var>$errorcode_map</var> property.
  368. *
  369. * @param mixed $nativecode the native error code, as returned by the
  370. * backend database extension (string or integer)
  371. *
  372. * @return int a portable DB error code, or DB_ERROR if this DB
  373. * implementation has no mapping for the given error code.
  374. *
  375. * @access public
  376. */
  377. function errorCode($nativecode)
  378. {
  379. if (isset($this->errorcode_map[$nativecode])) {
  380. return $this->errorcode_map[$nativecode];
  381. }
  382. // Fall back to DB_ERROR if there was no mapping.
  383. return DB_ERROR;
  384. }
  385. // }}}
  386. // {{{ errorMessage()
  387. /**
  388. * Map a DB error code to a textual message. This is actually
  389. * just a wrapper for DB::errorMessage()
  390. *
  391. * @param integer $dbcode the DB error code
  392. *
  393. * @return string the corresponding error message, of FALSE
  394. * if the error code was unknown
  395. *
  396. * @access public
  397. */
  398. function errorMessage($dbcode)
  399. {
  400. return DB::errorMessage($this->errorcode_map[$dbcode]);
  401. }
  402. // }}}
  403. // {{{ raiseError()
  404. /**
  405. * Communicate an error and invoke error callbacks, etc
  406. *
  407. * Basically a wrapper for PEAR::raiseError without the message string.
  408. *
  409. * @param mixed integer error code, or a PEAR error object (all
  410. * other parameters are ignored if this parameter is
  411. * an object
  412. *
  413. * @param int error mode, see PEAR_Error docs
  414. *
  415. * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
  416. * error level (E_USER_NOTICE etc). If error mode is
  417. * PEAR_ERROR_CALLBACK, this is the callback function,
  418. * either as a function name, or as an array of an
  419. * object and method name. For other error modes this
  420. * parameter is ignored.
  421. *
  422. * @param string Extra debug information. Defaults to the last
  423. * query and native error code.
  424. *
  425. * @param mixed Native error code, integer or string depending the
  426. * backend.
  427. *
  428. * @return object a PEAR error object
  429. *
  430. * @access public
  431. * @see PEAR_Error
  432. */
  433. function &raiseError($code = DB_ERROR, $mode = null, $options = null,
  434. $userinfo = null, $nativecode = null)
  435. {
  436. // The error is yet a DB error object
  437. if (is_object($code)) {
  438. // because we the static PEAR::raiseError, our global
  439. // handler should be used if it is set
  440. if ($mode === null && !empty($this->_default_error_mode)) {
  441. $mode = $this->_default_error_mode;
  442. $options = $this->_default_error_options;
  443. }
  444. $tmp = PEAR::raiseError($code, null, $mode, $options, null, null, true);
  445. return $tmp;
  446. }
  447. if ($userinfo === null) {
  448. $userinfo = $this->last_query;
  449. }
  450. if ($nativecode) {
  451. $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
  452. }
  453. $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo,
  454. 'DB_Error', true);
  455. return $tmp;
  456. }
  457. // }}}
  458. // {{{ setFetchMode()
  459. /**
  460. * Sets which fetch mode should be used by default on queries
  461. * on this connection
  462. *
  463. * @param integer $fetchmode DB_FETCHMODE_ORDERED or
  464. * DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with
  465. * DB_FETCHMODE_FLIPPED.
  466. *
  467. * @param string $object_class The class of the object
  468. * to be returned by the fetch methods when
  469. * the DB_FETCHMODE_OBJECT mode is selected.
  470. * If no class is specified by default a cast
  471. * to object from the assoc array row will be done.
  472. * There is also the posibility to use and extend the
  473. * 'DB_Row' class.
  474. *
  475. * @see DB_FETCHMODE_ORDERED
  476. * @see DB_FETCHMODE_ASSOC
  477. * @see DB_FETCHMODE_FLIPPED
  478. * @see DB_FETCHMODE_OBJECT
  479. * @see DB_Row::DB_Row()
  480. * @access public
  481. */
  482. function setFetchMode($fetchmode, $object_class = null)
  483. {
  484. switch ($fetchmode) {
  485. case DB_FETCHMODE_OBJECT:
  486. if ($object_class) {
  487. $this->fetchmode_object_class = $object_class;
  488. }
  489. case DB_FETCHMODE_ORDERED:
  490. case DB_FETCHMODE_ASSOC:
  491. $this->fetchmode = $fetchmode;
  492. break;
  493. default:
  494. return $this->raiseError('invalid fetchmode mode');
  495. }
  496. }
  497. // }}}
  498. // {{{ setOption()
  499. /**
  500. * Set run-time configuration options for PEAR DB
  501. *
  502. * Options, their data types, default values and description:
  503. * <ul>
  504. * <li>
  505. * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
  506. * <br />should results be freed automatically when there are no
  507. * more rows?
  508. * </li><li>
  509. * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
  510. * <br />debug level
  511. * </li><li>
  512. * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
  513. * <br />should the connection be persistent?
  514. * </li><li>
  515. * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
  516. * <br />portability mode constant (see below)
  517. * </li><li>
  518. * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
  519. * <br />the sprintf() format string used on sequence names. This
  520. * format is applied to sequence names passed to
  521. * createSequence(), nextID() and dropSequence().
  522. * </li><li>
  523. * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
  524. * <br />use ssl to connect?
  525. * </li>
  526. * </ul>
  527. *
  528. * -----------------------------------------
  529. *
  530. * PORTABILITY MODES
  531. *
  532. * These modes are bitwised, so they can be combined using <kbd>|</kbd>
  533. * and removed using <kbd>^</kbd>. See the examples section below on how
  534. * to do this.
  535. *
  536. * <samp>DB_PORTABILITY_NONE</samp>
  537. * turn off all portability features
  538. *
  539. * This mode gets automatically turned on if the deprecated
  540. * <var>optimize</var> option gets set to <samp>performance</samp>.
  541. *
  542. *
  543. * <samp>DB_PORTABILITY_LOWERCASE</samp>
  544. * convert names of tables and fields to lower case when using
  545. * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
  546. *
  547. * This mode gets automatically turned on in the following databases
  548. * if the deprecated option <var>optimize</var> gets set to
  549. * <samp>portability</samp>:
  550. * + oci8
  551. *
  552. *
  553. * <samp>DB_PORTABILITY_RTRIM</samp>
  554. * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
  555. *
  556. *
  557. * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
  558. * force reporting the number of rows deleted
  559. *
  560. * Some DBMS's don't count the number of rows deleted when performing
  561. * simple <kbd>DELETE FROM tablename</kbd> queries. This portability
  562. * mode tricks such DBMS's into telling the count by adding
  563. * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
  564. *
  565. * This mode gets automatically turned on in the following databases
  566. * if the deprecated option <var>optimize</var> gets set to
  567. * <samp>portability</samp>:
  568. * + fbsql
  569. * + mysql
  570. * + mysqli
  571. * + sqlite
  572. *
  573. *
  574. * <samp>DB_PORTABILITY_NUMROWS</samp>
  575. * enable hack that makes <kbd>numRows()</kbd> work in Oracle
  576. *
  577. * This mode gets automatically turned on in the following databases
  578. * if the deprecated option <var>optimize</var> gets set to
  579. * <samp>portability</samp>:
  580. * + oci8
  581. *
  582. *
  583. * <samp>DB_PORTABILITY_ERRORS</samp>
  584. * makes certain error messages in certain drivers compatible
  585. * with those from other DBMS's
  586. *
  587. * + mysql, mysqli: change unique/primary key constraints
  588. * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
  589. *
  590. * + odbc(access): MS's ODBC driver reports 'no such field' as code
  591. * 07001, which means 'too few parameters.' When this option is on
  592. * that code gets mapped to DB_ERROR_NOSUCHFIELD.
  593. * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
  594. *
  595. *
  596. * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
  597. * convert null values to empty strings in data output by get*() and
  598. * fetch*(). Needed because Oracle considers empty strings to be null,
  599. * while most other DBMS's know the difference between empty and null.
  600. *
  601. *
  602. * <samp>DB_PORTABILITY_ALL</samp>
  603. * turn on all portability features
  604. *
  605. * -----------------------------------------
  606. *
  607. * Example 1. Simple setOption() example
  608. * <code> <?php
  609. * $dbh->setOption('autofree', true);
  610. * ?></code>
  611. *
  612. * Example 2. Portability for lowercasing and trimming
  613. * <code> <?php
  614. * $dbh->setOption('portability',
  615. * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
  616. * ?></code>
  617. *
  618. * Example 3. All portability options except trimming
  619. * <code> <?php
  620. * $dbh->setOption('portability',
  621. * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
  622. * ?></code>
  623. *
  624. * @param string $option option name
  625. * @param mixed $value value for the option
  626. *
  627. * @return int DB_OK on success. DB_Error object on failure.
  628. *
  629. * @see DB_common::$options
  630. */
  631. function setOption($option, $value)
  632. {
  633. if (isset($this->options[$option])) {
  634. $this->options[$option] = $value;
  635. /*
  636. * Backwards compatibility check for the deprecated 'optimize'
  637. * option. Done here in case settings change after connecting.
  638. */
  639. if ($option == 'optimize') {
  640. if ($value == 'portability') {
  641. switch ($this->phptype) {
  642. case 'oci8':
  643. $this->options['portability'] =
  644. DB_PORTABILITY_LOWERCASE |
  645. DB_PORTABILITY_NUMROWS;
  646. break;
  647. case 'fbsql':
  648. case 'mysql':
  649. case 'mysqli':
  650. case 'sqlite':
  651. $this->options['portability'] =
  652. DB_PORTABILITY_DELETE_COUNT;
  653. break;
  654. }
  655. } else {
  656. $this->options['portability'] = DB_PORTABILITY_NONE;
  657. }
  658. }
  659. return DB_OK;
  660. }
  661. return $this->raiseError("unknown option $option");
  662. }
  663. // }}}
  664. // {{{ getOption()
  665. /**
  666. * Returns the value of an option
  667. *
  668. * @param string $option option name
  669. *
  670. * @return mixed the option value
  671. */
  672. function getOption($option)
  673. {
  674. if (isset($this->options[$option])) {
  675. return $this->options[$option];
  676. }
  677. return $this->raiseError("unknown option $option");
  678. }
  679. // }}}
  680. // {{{ prepare()
  681. /**
  682. * Prepares a query for multiple execution with execute()
  683. *
  684. * Creates a query that can be run multiple times. Each time it is run,
  685. * the placeholders, if any, will be replaced by the contents of
  686. * execute()'s $data argument.
  687. *
  688. * Three types of placeholders can be used:
  689. * + <kbd>?</kbd> scalar value (i.e. strings, integers). The system
  690. * will automatically quote and escape the data.
  691. * + <kbd>!</kbd> value is inserted 'as is'
  692. * + <kbd>&</kbd> requires a file name. The file's contents get
  693. * inserted into the query (i.e. saving binary
  694. * data in a db)
  695. *
  696. * Example 1.
  697. * <code> <?php
  698. * $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  699. * $data = array(
  700. * "John's text",
  701. * "'it''s good'",
  702. * 'filename.txt'
  703. * );
  704. * $res = $dbh->execute($sth, $data);
  705. * ?></code>
  706. *
  707. * Use backslashes to escape placeholder characters if you don't want
  708. * them to be interpreted as placeholders:
  709. * <pre>
  710. * "UPDATE foo SET col=? WHERE col='over \& under'"
  711. * </pre>
  712. *
  713. * With some database backends, this is emulated.
  714. *
  715. * {@internal ibase and oci8 have their own prepare() methods.}}
  716. *
  717. * @param string $query query to be prepared
  718. *
  719. * @return mixed DB statement resource on success. DB_Error on failure.
  720. *
  721. * @see DB_common::execute()
  722. * @access public
  723. */
  724. function prepare($query)
  725. {
  726. $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
  727. PREG_SPLIT_DELIM_CAPTURE);
  728. $token = 0;
  729. $types = array();
  730. $newtokens = array();
  731. foreach ($tokens as $val) {
  732. switch ($val) {
  733. case '?':
  734. $types[$token++] = DB_PARAM_SCALAR;
  735. break;
  736. case '&':
  737. $types[$token++] = DB_PARAM_OPAQUE;
  738. break;
  739. case '!':
  740. $types[$token++] = DB_PARAM_MISC;
  741. break;
  742. default:
  743. $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
  744. }
  745. }
  746. $this->prepare_tokens[] = &$newtokens;
  747. end($this->prepare_tokens);
  748. $k = key($this->prepare_tokens);
  749. $this->prepare_types[$k] = $types;
  750. $this->prepared_queries[$k] = implode(' ', $newtokens);
  751. return $k;
  752. }
  753. // }}}
  754. // {{{ autoPrepare()
  755. /**
  756. * Automaticaly generate an insert or update query and pass it to prepare()
  757. *
  758. * @param string $table name of the table
  759. * @param array $table_fields ordered array containing the fields names
  760. * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
  761. * @param string $where in case of update queries, this string will be put after the sql WHERE statement
  762. * @return resource handle for the query
  763. * @see DB_common::prepare(), DB_common::buildManipSQL()
  764. * @access public
  765. */
  766. function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, $where = false)
  767. {
  768. $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
  769. return $this->prepare($query);
  770. }
  771. // }}}
  772. // {{{ autoExecute()
  773. /**
  774. * Automaticaly generate an insert or update query and call prepare()
  775. * and execute() with it
  776. *
  777. * @param string $table name of the table
  778. * @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value
  779. * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
  780. * @param string $where in case of update queries, this string will be put after the sql WHERE statement
  781. * @return mixed a new DB_Result or a DB_Error when fail
  782. * @see DB_common::autoPrepare(), DB_common::buildManipSQL()
  783. * @access public
  784. */
  785. function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, $where = false)
  786. {
  787. $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, $where);
  788. $ret =& $this->execute($sth, array_values($fields_values));
  789. $this->freePrepared($sth);
  790. return $ret;
  791. }
  792. // }}}
  793. // {{{ buildManipSQL()
  794. /**
  795. * Make automaticaly an sql query for prepare()
  796. *
  797. * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), DB_AUTOQUERY_INSERT)
  798. * will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
  799. * NB : - This belongs more to a SQL Builder class, but this is a simple facility
  800. * - Be carefull ! If you don't give a $where param with an UPDATE query, all
  801. * the records of the table will be updated !
  802. *
  803. * @param string $table name of the table
  804. * @param array $table_fields ordered array containing the fields names
  805. * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
  806. * @param string $where in case of update queries, this string will be put after the sql WHERE statement
  807. * @return string sql query for prepare()
  808. * @access public
  809. */
  810. function buildManipSQL($table, $table_fields, $mode, $where = false)
  811. {
  812. if (count($table_fields) == 0) {
  813. $this->raiseError(DB_ERROR_NEED_MORE_DATA);
  814. }
  815. $first = true;
  816. switch ($mode) {
  817. case DB_AUTOQUERY_INSERT:
  818. $values = '';
  819. $names = '';
  820. foreach ($table_fields as $value) {
  821. if ($first) {
  822. $first = false;
  823. } else {
  824. $names .= ',';
  825. $values .= ',';
  826. }
  827. $names .= $value;
  828. $values .= '?';
  829. }
  830. return "INSERT INTO $table ($names) VALUES ($values)";
  831. case DB_AUTOQUERY_UPDATE:
  832. $set = '';
  833. foreach ($table_fields as $value) {
  834. if ($first) {
  835. $first = false;
  836. } else {
  837. $set .= ',';
  838. }
  839. $set .= "$value = ?";
  840. }
  841. $sql = "UPDATE $table SET $set";
  842. if ($where) {
  843. $sql .= " WHERE $where";
  844. }
  845. return $sql;
  846. default:
  847. $this->raiseError(DB_ERROR_SYNTAX);
  848. }
  849. }
  850. // }}}
  851. // {{{ execute()
  852. /**
  853. * Executes a DB statement prepared with prepare()
  854. *
  855. * Example 1.
  856. * <code> <?php
  857. * $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  858. * $data = array(
  859. * "John's text",
  860. * "'it''s good'",
  861. * 'filename.txt'
  862. * );
  863. * $res =& $dbh->execute($sth, $data);
  864. * ?></code>
  865. *
  866. * @param resource $stmt a DB statement resource returned from prepare()
  867. * @param mixed $data array, string or numeric data to be used in
  868. * execution of the statement. Quantity of items
  869. * passed must match quantity of placeholders in
  870. * query: meaning 1 placeholder for non-array
  871. * parameters or 1 placeholder per array element.
  872. *
  873. * @return object a new DB_Result or a DB_Error when fail
  874. *
  875. * {@internal ibase and oci8 have their own execute() methods.}}
  876. *
  877. * @see DB_common::prepare()
  878. * @access public
  879. */
  880. function &execute($stmt, $data = array())
  881. {
  882. $realquery = $this->executeEmulateQuery($stmt, $data);
  883. if (DB::isError($realquery)) {
  884. return $realquery;
  885. }
  886. $result = $this->simpleQuery($realquery);
  887. if (DB::isError($result) || $result === DB_OK) {
  888. return $result;
  889. } else {
  890. $tmp =& new DB_result($this, $result);
  891. return $tmp;
  892. }
  893. }
  894. // }}}
  895. // {{{ executeEmulateQuery()
  896. /**
  897. * Emulates the execute statement, when not supported
  898. *
  899. * @param resource $stmt a DB statement resource returned from execute()
  900. * @param mixed $data array, string or numeric data to be used in
  901. * execution of the statement. Quantity of items
  902. * passed must match quantity of placeholders in
  903. * query: meaning 1 placeholder for non-array
  904. * parameters or 1 placeholder per array element.
  905. *
  906. * @return mixed a string containing the real query run when emulating
  907. * prepare/execute. A DB error code is returned on failure.
  908. *
  909. * @see DB_common::execute()
  910. * @access private
  911. */
  912. function executeEmulateQuery($stmt, $data = array())
  913. {
  914. if (!is_array($data)) {
  915. $data = array($data);
  916. }
  917. if (count($this->prepare_types[$stmt]) != count($data)) {
  918. $this->last_query = $this->prepared_queries[$stmt];
  919. return $this->raiseError(DB_ERROR_MISMATCH);
  920. }
  921. $realquery = $this->prepare_tokens[$stmt][0];
  922. $i = 0;
  923. foreach ($data as $value) {
  924. if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
  925. $realquery .= $this->quoteSmart($value);
  926. } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
  927. $fp = @fopen($value, 'rb');
  928. if (!$fp) {
  929. return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
  930. }
  931. $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
  932. fclose($fp);
  933. } else {
  934. $realquery .= $value;
  935. }
  936. $realquery .= $this->prepare_tokens[$stmt][++$i];
  937. }
  938. return $realquery;
  939. }
  940. // }}}
  941. // {{{ executeMultiple()
  942. /**
  943. * This function does several execute() calls on the same
  944. * statement handle
  945. *
  946. * $data must be an array indexed numerically
  947. * from 0, one execute call is done for every "row" in the array.
  948. *
  949. * If an error occurs during execute(), executeMultiple() does not
  950. * execute the unfinished rows, but rather returns that error.
  951. *
  952. * @param resource $stmt query handle from prepare()
  953. * @param array $data numeric array containing the
  954. * data to insert into the query
  955. *
  956. * @return mixed DB_OK or DB_Error
  957. *
  958. * @see DB_common::prepare(), DB_common::execute()
  959. * @access public
  960. */
  961. function executeMultiple($stmt, $data)
  962. {
  963. foreach ($data as $value) {
  964. $res =& $this->execute($stmt, $value);
  965. if (DB::isError($res)) {
  966. return $res;
  967. }
  968. }
  969. return DB_OK;
  970. }
  971. // }}}
  972. // {{{ freePrepared()
  973. /**
  974. * Free the resource used in a prepared query
  975. *
  976. * @param $stmt The resurce returned by the prepare() function
  977. * @see DB_common::prepare()
  978. */
  979. function freePrepared($stmt)
  980. {
  981. // Free the internal prepared vars
  982. if (isset($this->prepare_tokens[$stmt])) {
  983. unset($this->prepare_tokens[$stmt]);
  984. unset($this->prepare_types[$stmt]);
  985. unset($this->prepared_queries[$stmt]);
  986. return true;
  987. }
  988. return false;
  989. }
  990. // }}}
  991. // {{{ modifyQuery()
  992. /**
  993. * This method is used by backends to alter queries for various
  994. * reasons
  995. *
  996. * It is defined here to assure that all implementations
  997. * have this method defined.
  998. *
  999. * @param string $query query to modify
  1000. *
  1001. * @return the new (modified) query
  1002. *
  1003. * @access private
  1004. */
  1005. function modifyQuery($query) {
  1006. return $query;
  1007. }
  1008. // }}}
  1009. // {{{ modifyLimitQuery()
  1010. /**
  1011. * This method is used by backends to alter limited queries
  1012. *
  1013. * @param string $query query to modify
  1014. * @param integer $from the row to start to fetching
  1015. * @param integer $count the numbers of rows to fetch
  1016. *
  1017. * @return the new (modified) query
  1018. *
  1019. * @access private
  1020. */
  1021. function modifyLimitQuery($query, $from, $count)
  1022. {
  1023. return $query;
  1024. }
  1025. // }}}
  1026. // {{{ query()
  1027. /**
  1028. * Send a query to the database and return any results with a
  1029. * DB_result object
  1030. *
  1031. * The query string can be either a normal statement to be sent directly
  1032. * to the server OR if <var>$params</var> are passed the query can have
  1033. * placeholders and it will be passed through prepare() and execute().
  1034. *
  1035. * @param string $query the SQL query or the statement to prepare
  1036. * @param mixed $params array, string or numeric data to be used in
  1037. * execution of the statement. Quantity of items
  1038. * passed must match quantity of placeholders in
  1039. * query: meaning 1 placeholder for non-array
  1040. * parameters or 1 placeholder per array element.
  1041. *
  1042. * @return mixed a DB_result object or DB_OK on success, a DB
  1043. * error on failure
  1044. *
  1045. * @see DB_result, DB_common::prepare(), DB_common::execute()
  1046. * @access public
  1047. */
  1048. function &query($query, $params = array())
  1049. {
  1050. if (sizeof($params) > 0) {
  1051. $sth = $this->prepare($query);
  1052. if (DB::isError($sth)) {
  1053. return $sth;
  1054. }
  1055. $ret =& $this->execute($sth, $params);
  1056. $this->freePrepared($sth);
  1057. return $ret;
  1058. } else {
  1059. $result = $this->simpleQuery($query);
  1060. if (DB::isError($result) || $result === DB_OK) {
  1061. return $result;
  1062. } else {
  1063. $tmp =& new DB_result($this, $result);
  1064. return $tmp;
  1065. }
  1066. }
  1067. }
  1068. // }}}
  1069. // {{{ limitQuery()
  1070. /**
  1071. * Generates a limited query
  1072. *
  1073. * @param string $query query
  1074. * @param integer $from the row to start to fetching
  1075. * @param integer $count the numbers of rows to fetch
  1076. * @param array $params required for a statement
  1077. *
  1078. * @return mixed a DB_Result object, DB_OK or a DB_Error
  1079. *
  1080. * @access public
  1081. */
  1082. function &limitQuery($query, $from, $count, $params = array())
  1083. {
  1084. $query = $this->modifyLimitQuery($query, $from, $count);
  1085. if (DB::isError($query)){
  1086. return $query;
  1087. }
  1088. $result =& $this->query($query, $params);
  1089. if (is_a($result, 'DB_result')) {
  1090. $result->setOption('limit_from', $from);
  1091. $result->setOption('limit_count', $count);
  1092. }
  1093. return $result;
  1094. }
  1095. // }}}
  1096. // {{{ getOne()
  1097. /**
  1098. * Fetch the first column of the first row of data returned from
  1099. * a query
  1100. *
  1101. * Takes care of doing the query and freeing the results when finished.
  1102. *
  1103. * @param string $query the SQL query
  1104. * @param mixed $params array, string or numeric data to be used in
  1105. * execution of the statement. Quantity of items
  1106. * passed must match quantity of placeholders in
  1107. * query: meaning 1 placeholder for non-array
  1108. * parameters or 1 placeholder per array element.
  1109. *
  1110. * @return mixed the returned value of the query. DB_Error on failure.
  1111. *
  1112. * @access public
  1113. */
  1114. function &getOne($query, $params = array())
  1115. {
  1116. settype($params, 'array');
  1117. if (sizeof($params) > 0) {
  1118. $sth = $this->prepare($query);
  1119. if (DB::isError($sth)) {
  1120. return $sth;
  1121. }
  1122. $res =& $this->execute($sth, $params);
  1123. $this->freePrepared($sth);
  1124. } else {
  1125. $res =& $this->query($query);
  1126. }
  1127. if (DB::isError($res)) {
  1128. return $res;
  1129. }
  1130. $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
  1131. $res->free();
  1132. if ($err !== DB_OK) {
  1133. return $err;
  1134. }
  1135. return $row[0];
  1136. }
  1137. // }}}
  1138. // {{{ getRow()
  1139. /**
  1140. * Fetch the first row of data returned from a query
  1141. *
  1142. * Takes care of doing the query and freeing the results when finished.
  1143. *
  1144. * @param string $query the SQL query
  1145. * @param array $params array to be used in execution of the statement.
  1146. * Quantity of array elements must match quantity
  1147. * of placeholders in query. This function does
  1148. * NOT support scalars.
  1149. * @param int $fetchmode the fetch mode to use
  1150. *
  1151. * @return array the first row of results as an array indexed from
  1152. * 0, or a DB error code.
  1153. *
  1154. * @access public
  1155. */
  1156. function &getRow($query,
  1157. $params = array(),
  1158. $fetchmode = DB_FETCHMODE_DEFAULT)
  1159. {
  1160. // compat check, the params and fetchmode parameters used to
  1161. // have the opposite order
  1162. if (!is_array($params)) {
  1163. if (is_array($fetchmode)) {
  1164. if ($params === null) {
  1165. $tmp = DB_FETCHMODE_DEFAULT;
  1166. } else {
  1167. $tmp = $params;
  1168. }
  1169. $params = $fetchmode;
  1170. $fetchmode = $tmp;
  1171. } elseif ($params !== null) {
  1172. $fetchmode = $params;
  1173. $params = array();
  1174. }
  1175. }
  1176. if (sizeof($params) > 0) {
  1177. $sth = $this->prepare($query);
  1178. if (DB::isError($sth)) {
  1179. return $sth;
  1180. }
  1181. $res =& $this->execute($sth, $params);
  1182. $this->freePrepared($sth);
  1183. } else {
  1184. $res =& $this->query($query);
  1185. }
  1186. if (DB::isError($res)) {
  1187. return $res;
  1188. }
  1189. $err = $res->fetchInto($row, $fetchmode);
  1190. $res->free();
  1191. if ($err !== DB_OK) {
  1192. return $err;
  1193. }
  1194. return $row;
  1195. }
  1196. // }}}
  1197. // {{{ getCol()
  1198. /**
  1199. * Fetch a single column from a result set and return it as an
  1200. * indexed array
  1201. *
  1202. * @param string $query the SQL query
  1203. * @param mixed $col which column to return (integer [column number,
  1204. * starting at 0] or string [column name])
  1205. * @param mixed $params array, string or numeric data to be used in
  1206. * execution of the statement. Quantity of items
  1207. * passed must match quantity of placeholders in
  1208. * query: meaning 1 placeholder for non-array
  1209. * parameters or 1 placeholder per array element.
  1210. *
  1211. * @return array an indexed array with the data from the first
  1212. * row at index 0, or a DB error code
  1213. *
  1214. * @see DB_common::query()
  1215. * @access public
  1216. */
  1217. function &getCol($query, $col = 0, $params = array())
  1218. {
  1219. settype($params, 'array');
  1220. if (sizeof($params) > 0) {
  1221. $sth = $this->prepare($query);
  1222. if (DB::isError($sth)) {
  1223. return $sth;
  1224. }
  1225. $res =& $this->execute($sth, $params);
  1226. $this->freePrepared($sth);
  1227. } else {
  1228. $res =& $this->query($query);
  1229. }
  1230. if (DB::isError($res)) {
  1231. return $res;
  1232. }
  1233. $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
  1234. $ret = array();
  1235. while (is_array($row = $res->fetchRow($fetchmode))) {
  1236. $ret[] = $row[$col];
  1237. }
  1238. $res->free();
  1239. if (DB::isError($row)) {
  1240. $ret = $row;
  1241. }
  1242. return $ret;
  1243. }
  1244. // }}}
  1245. // {{{ getAssoc()
  1246. /**
  1247. * Fetch the entire result set of a query and return it as an
  1248. * associative array using the first column as the key
  1249. *
  1250. * If the result set contains more than two columns, the value
  1251. * will be an array of the values from column 2-n. If the result
  1252. * set contains only two columns, the returned value will be a
  1253. * scalar with the value of the second column (unless forced to an
  1254. * array with the $force_array parameter). A DB error code is
  1255. * returned on errors. If the result set contains fewer than two
  1256. * columns, a DB_ERROR_TRUNCATED error is returned.
  1257. *
  1258. * For example, if the table "mytable" contains:
  1259. *
  1260. * <pre>
  1261. * ID TEXT DATE
  1262. * --------------------------------
  1263. * 1 'one' 944679408
  1264. * 2 'two' 944679408
  1265. * 3 'three' 944679408
  1266. * </pre>
  1267. *
  1268. * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  1269. * <pre>
  1270. * array(
  1271. * '1' => 'one',
  1272. * '2' => 'two',
  1273. * '3' => 'three',
  1274. * )
  1275. * </pre>
  1276. *
  1277. * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  1278. * <pre>
  1279. * array(
  1280. * '1' => array('one', '944679408'),
  1281. * '2' => array('two', '944679408'),
  1282. * '3' => array('three', '944679408')
  1283. * )
  1284. * </pre>
  1285. *
  1286. * If the more than one row occurs with the same value in the
  1287. * first column, the last row overwrites all previous ones by
  1288. * default. Use the $group parameter if you don't want to
  1289. * overwrite like this. Example:
  1290. *
  1291. * <pre>
  1292. * getAssoc('SELECT category,id,name FROM mytable', false, null,
  1293. * DB_FETCHMODE_ASSOC, true) returns:
  1294. *
  1295. * array(
  1296. * '1' => array(array('id' => '4', 'name' => 'number four'),
  1297. * array('id' => '6', 'name' => 'number six')
  1298. * ),
  1299. * '9' => array(array('id' => '4', 'name' => 'number four'),
  1300. * array('id' => '6', 'name' => 'number six')
  1301. * )
  1302. * )
  1303. * </pre>
  1304. *
  1305. * Keep in mind that database functions in PHP usually return string
  1306. * values for results regardless of the database's internal type.
  1307. *
  1308. * @param string $query the SQL query
  1309. * @param boolean $force_array used only when the query returns
  1310. * exactly two columns. If true, the values
  1311. * of the returned array will be one-element
  1312. * arrays instead of scalars.
  1313. * @param mixed $params array, string or numeric data to be used in
  1314. * execution of the statement. Quantity of items
  1315. * passed must match quantity of placeholders in
  1316. * query: meaning 1 placeholder for non-array
  1317. * parameters or 1 placeholder per array element.
  1318. * @param boolean $group if true, the values of the returned array
  1319. * is wrapped in another array. If the same
  1320. * key value (in the first column) repeats
  1321. * itself, the values will be appended to
  1322. * this array instead of overwriting the
  1323. * existing values.
  1324. *
  1325. * @return array associative array with results from the query.
  1326. * DB Error on failure.
  1327. *
  1328. * @access public
  1329. */
  1330. function &getAssoc($query, $force_array = false, $params = array(),
  1331. $fetchmode = DB_FETCHMODE_DEFAULT, $group = false)
  1332. {
  1333. settype($params, 'array');
  1334. if (sizeof($params) > 0) {
  1335. $sth = $this->prepare($query);
  1336. if (DB::isError($sth)) {
  1337. return $sth;
  1338. }
  1339. $res =& $this->execute($sth, $params);
  1340. $this->freePrepared($sth);
  1341. } else {
  1342. $res =& $this->query($query);
  1343. }
  1344. if (DB::isError($res)) {
  1345. return $res;
  1346. }
  1347. if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  1348. $fetchmode = $this->fetchmode;
  1349. }
  1350. $cols = $res->numCols();
  1351. if ($cols < 2) {
  1352. $tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
  1353. return $tmp;
  1354. }
  1355. $results = array();
  1356. if ($cols > 2 || $force_array) {
  1357. // return array values
  1358. // XXX this part can be optimized
  1359. if ($fetchmode == DB_FETCHMODE_ASSOC) {
  1360. while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
  1361. reset($row);
  1362. $key = current($row);
  1363. unset($row[key($row)]);
  1364. if ($group) {
  1365. $results[$key][] = $row;
  1366. } else {
  1367. $results[$key] = $row;
  1368. }
  1369. }
  1370. } elseif ($fetchmode == DB_FETCHMODE_OBJECT) {
  1371. while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) {
  1372. $arr = get_object_vars($row);
  1373. $key = current($arr);
  1374. if ($group) {
  1375. $results[$key][] = $row;
  1376. } else {
  1377. $results[$key] = $row;
  1378. }
  1379. }
  1380. } else {
  1381. while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1382. // we shift away the first element to get
  1383. // indices running from 0 again
  1384. $key = array_shift($row);
  1385. if ($group) {
  1386. $results[$key][] = $row;
  1387. } else {
  1388. $results[$key] = $row;
  1389. }
  1390. }
  1391. }
  1392. if (DB::isError($row)) {
  1393. $results = $row;
  1394. }
  1395. } else {
  1396. // return scalar values
  1397. while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1398. if ($group) {
  1399. $results[$row[0]][] = $row[1];
  1400. } else {
  1401. $results[$row[0]] = $row[1];
  1402. }
  1403. }
  1404. if (DB::isError($row)) {
  1405. $results = $row;
  1406. }
  1407. }
  1408. $res->free();
  1409. return $results;
  1410. }
  1411. // }}}
  1412. // {{{ getAll()
  1413. /**
  1414. * Fetch all the rows returned from a query
  1415. *
  1416. * @param string $query the SQL query
  1417. * @param array $params array to be used in execution of the statement.
  1418. * Quantity of array elements must match quantity
  1419. * of placeholders in query. This function does
  1420. * NOT support scalars.
  1421. * @param int $fetchmode the fetch mode to use
  1422. *
  1423. * @return array an nested array. DB error on failure.
  1424. *
  1425. * @access public
  1426. */
  1427. function &getAll($query,
  1428. $params = array(),
  1429. $fetchmode = DB_FETCHMODE_DEFAULT)
  1430. {
  1431. // compat check, the params and fetchmode parameters used to
  1432. // have the opposite order
  1433. if (!is_array($params)) {
  1434. if (is_array($fetchmode)) {
  1435. if ($params === null) {
  1436. $tmp = DB_FETCHMODE_DEFAULT;
  1437. } else {
  1438. $tmp = $params;
  1439. }
  1440. $params = $fetchmode;
  1441. $fetchmode = $tmp;
  1442. } elseif ($params !== null) {
  1443. $fetchmode = $params;
  1444. $params = array();
  1445. }
  1446. }
  1447. if (sizeof($params) > 0) {
  1448. $sth = $this->prepare($query);
  1449. if (DB::isError($sth)) {
  1450. return $sth;
  1451. }
  1452. $res =& $this->execute($sth, $params);
  1453. $this->freePrepared($sth);
  1454. } else {
  1455. $res =& $this->query($query);
  1456. }
  1457. if (DB::isError($res) || $res == DB_OK) {
  1458. return $res;
  1459. }
  1460. $results = array();
  1461. while (DB_OK === $res->fetchInto($row, $fetchmode)) {
  1462. if ($fetchmode & DB_FETCHMODE_FLIPPED) {
  1463. foreach ($row as $key => $val) {
  1464. $results[$key][] = $val;
  1465. }
  1466. } else {
  1467. $results[] = $row;
  1468. }
  1469. }
  1470. $res->free();
  1471. if (DB::isError($row)) {
  1472. $tmp =& $this->raiseError($row);
  1473. return $tmp;
  1474. }
  1475. return $results;
  1476. }
  1477. // }}}
  1478. // {{{ autoCommit()
  1479. /**
  1480. * enable automatic Commit
  1481. *
  1482. * @param boolean $onoff
  1483. * @return mixed DB_Error
  1484. *
  1485. * @access public
  1486. */
  1487. function autoCommit($onoff=false)
  1488. {
  1489. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1490. }
  1491. // }}}
  1492. // {{{ commit()
  1493. /**
  1494. * starts a Commit
  1495. *
  1496. * @return mixed DB_Error
  1497. *
  1498. * @access public
  1499. */
  1500. function commit()
  1501. {
  1502. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1503. }
  1504. // }}}
  1505. // {{{ rollback()
  1506. /**
  1507. * starts a rollback
  1508. *
  1509. * @return mixed DB_Error
  1510. *
  1511. * @access public
  1512. */
  1513. function rollback()
  1514. {
  1515. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1516. }
  1517. // }}}
  1518. // {{{ numRows()
  1519. /**
  1520. * Returns the number of rows in a result object
  1521. *
  1522. * @param object DB_Result the result object to check
  1523. *
  1524. * @return mixed DB_Error or the number of rows
  1525. *
  1526. * @access public
  1527. */
  1528. function numRows($result)
  1529. {
  1530. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1531. }
  1532. // }}}
  1533. // {{{ affectedRows()
  1534. /**
  1535. * Returns the affected rows of a query
  1536. *
  1537. * @return mixed DB_Error or number of rows
  1538. *
  1539. * @access public
  1540. */
  1541. function affectedRows()
  1542. {
  1543. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1544. }
  1545. // }}}
  1546. // {{{ errorNative()
  1547. /**
  1548. * Returns an errormessage, provides by the database
  1549. *
  1550. * @return mixed DB_Error or message
  1551. *
  1552. * @access public
  1553. */
  1554. function errorNative()
  1555. {
  1556. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1557. }
  1558. // }}}
  1559. // {{{ getSequenceName()
  1560. /**
  1561. * Generate the name used inside the database for a sequence
  1562. *
  1563. * The createSequence() docblock contains notes about storing sequence
  1564. * names.
  1565. *
  1566. * @param string $sqn the sequence's public name
  1567. *
  1568. * @return string the sequence's name in the backend
  1569. *
  1570. * @see DB_common::createSequence(), DB_common::dropSequence(),
  1571. * DB_common::nextID(), DB_common::setOption()
  1572. * @access private
  1573. */
  1574. function getSequenceName($sqn)
  1575. {
  1576. return sprintf($this->getOption('seqname_format'),
  1577. preg_replace('/[^a-z0-9_.]/i', '_', $sqn));
  1578. }
  1579. // }}}
  1580. // {{{ nextId()
  1581. /**
  1582. * Returns the next free id in a sequence
  1583. *
  1584. * @param string $seq_name name of the sequence
  1585. * @param boolean $ondemand when true, the seqence is automatically
  1586. * created if it does not exist
  1587. *
  1588. * @return int the next id number in the sequence. DB_Error if problem.
  1589. *
  1590. * @see DB_common::createSequence(), DB_common::dropSequence(),
  1591. * DB_common::getSequenceName()
  1592. * @access public
  1593. */
  1594. function nextId($seq_name, $ondemand = true)
  1595. {
  1596. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1597. }
  1598. // }}}
  1599. // {{{ createSequence()
  1600. /**
  1601. * Creates a new sequence
  1602. *
  1603. * The name of a given sequence is determined by passing the string
  1604. * provided in the <var>$seq_name</var> argument through PHP's sprintf()
  1605. * function using the value from the <var>seqname_format</var> option as
  1606. * the sprintf()'s format argument.
  1607. *
  1608. * <var>seqname_format</var> is set via setOption().
  1609. *
  1610. * @param string $seq_name name of the new sequence
  1611. *
  1612. * @return int DB_OK on success. A DB_Error object is returned if
  1613. * problems arise.
  1614. *
  1615. * @see DB_common::dropSequence(), DB_common::getSequenceName(),
  1616. * DB_common::nextID()
  1617. * @access public
  1618. */
  1619. function createSequence($seq_name)
  1620. {
  1621. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1622. }
  1623. // }}}
  1624. // {{{ dropSequence()
  1625. /**
  1626. * Deletes a sequence
  1627. *
  1628. * @param string $seq_name name of the sequence to be deleted
  1629. *
  1630. * @return int DB_OK on success. DB_Error if problems.
  1631. *
  1632. * @see DB_common::createSequence(), DB_common::getSequenceName(),
  1633. * DB_common::nextID()
  1634. * @access public
  1635. */
  1636. function dropSequence($seq_name)
  1637. {
  1638. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1639. }
  1640. // }}}
  1641. // {{{ tableInfo()
  1642. /**
  1643. * Returns information about a table or a result set
  1644. *
  1645. * The format of the resulting array depends on which <var>$mode</var>
  1646. * you select. The sample output below is based on this query:
  1647. * <pre>
  1648. * SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
  1649. * FROM tblFoo
  1650. * JOIN tblBar ON tblFoo.fldId = tblBar.fldId
  1651. * </pre>
  1652. *
  1653. * <ul>
  1654. * <li>
  1655. *
  1656. * <kbd>null</kbd> (default)
  1657. * <pre>
  1658. * [0] => Array (
  1659. * [table] => tblFoo
  1660. * [name] => fldId
  1661. * [type] => int
  1662. * [len] => 11
  1663. * [flags] => primary_key not_null
  1664. * )
  1665. * [1] => Array (
  1666. * [table] => tblFoo
  1667. * [name] => fldPhone
  1668. * [type] => string
  1669. * [len] => 20
  1670. * [flags] =>
  1671. * )
  1672. * [2] => Array (
  1673. * [table] => tblBar
  1674. * [name] => fldId
  1675. * [type] => int
  1676. * [len] => 11
  1677. * [flags] => primary_key not_null
  1678. * )
  1679. * </pre>
  1680. *
  1681. * </li><li>
  1682. *
  1683. * <kbd>DB_TABLEINFO_ORDER</kbd>
  1684. *
  1685. * <p>In addition to the information found in the default output,
  1686. * a notation of the number of columns is provided by the
  1687. * <samp>num_fields</samp> element while the <samp>order</samp>
  1688. * element provides an array with the column names as the keys and
  1689. * their location index number (corresponding to the keys in the
  1690. * the default output) as the values.</p>
  1691. *
  1692. * <p>If a result set has identical field names, the last one is
  1693. * used.</p>
  1694. *
  1695. * <pre>
  1696. * [num_fields] => 3
  1697. * [order] => Array (
  1698. * [fldId] => 2
  1699. * [fldTrans] => 1
  1700. * )
  1701. * </pre>
  1702. *
  1703. * </li><li>
  1704. *
  1705. * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
  1706. *
  1707. * <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
  1708. * dimensions to the array in which the table names are keys and
  1709. * the field names are sub-keys. This is helpful for queries that
  1710. * join tables which have identical field names.</p>
  1711. *
  1712. * <pre>
  1713. * [num_fields] => 3
  1714. * [ordertable] => Array (
  1715. * [tblFoo] => Array (
  1716. * [fldId] => 0
  1717. * [fldPhone] => 1
  1718. * )
  1719. * [tblBar] => Array (
  1720. * [fldId] => 2
  1721. * )
  1722. * )
  1723. * </pre>
  1724. *
  1725. * </li>
  1726. * </ul>
  1727. *
  1728. * The <samp>flags</samp> element contains a space separated list
  1729. * of extra information about the field. This data is inconsistent
  1730. * between DBMS's due to the way each DBMS works.
  1731. * + <samp>primary_key</samp>
  1732. * + <samp>unique_key</samp>
  1733. * + <samp>multiple_key</samp>
  1734. * + <samp>not_null</samp>
  1735. *
  1736. * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
  1737. * elements if <var>$result</var> is a table name. The following DBMS's
  1738. * provide full information from queries:
  1739. * + fbsql
  1740. * + mysql
  1741. *
  1742. * If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
  1743. * turned on, the names of tables and fields will be lowercased.
  1744. *
  1745. * @param object|string $result DB_result object from a query or a
  1746. * string containing the name of a table.
  1747. * While this also accepts a query result
  1748. * resource identifier, this behavior is
  1749. * deprecated.
  1750. * @param int $mode either unused or one of the tableInfo modes:
  1751. * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
  1752. * <kbd>DB_TABLEINFO_ORDER</kbd> or
  1753. * <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
  1754. * These are bitwise, so the first two can be
  1755. * combined using <kbd>|</kbd>.
  1756. * @return array an associative array with the information requested.
  1757. * If something goes wrong an error object is returned.
  1758. *
  1759. * @see DB_common::setOption()
  1760. * @access public
  1761. */
  1762. function tableInfo($result, $mode = null)
  1763. {
  1764. /*
  1765. * If the DB_<driver> class has a tableInfo() method, that one
  1766. * overrides this one. But, if the driver doesn't have one,
  1767. * this method runs and tells users about that fact.
  1768. */
  1769. return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1770. }
  1771. // }}}
  1772. // {{{ getTables()
  1773. /**
  1774. * @deprecated Deprecated in release 1.2 or lower
  1775. */
  1776. function getTables()
  1777. {
  1778. return $this->getListOf('tables');
  1779. }
  1780. // }}}
  1781. // {{{ getListOf()
  1782. /**
  1783. * list internal DB info
  1784. * valid values for $type are db dependent,
  1785. * often: databases, users, view, functions
  1786. *
  1787. * @param string $type type of requested info
  1788. *
  1789. * @return mixed DB_Error or the requested data
  1790. *
  1791. * @access public
  1792. */
  1793. function getListOf($type)
  1794. {
  1795. $sql = $this->getSpecialQuery($type);
  1796. if ($sql === null) { // No support
  1797. return $this->raiseError(DB_ERROR_UNSUPPORTED);
  1798. } elseif (is_int($sql) || DB::isError($sql)) { // Previous error
  1799. return $this->raiseError($sql);
  1800. } elseif (is_array($sql)) { // Already the result
  1801. return $sql;
  1802. }
  1803. return $this->getCol($sql); // Launch this query
  1804. }
  1805. // }}}
  1806. // {{{ getSpecialQuery()
  1807. /**
  1808. * Returns the query needed to get some backend info
  1809. *
  1810. * @param string $type What kind of info you want to retrieve
  1811. *
  1812. * @return string The SQL query string
  1813. *
  1814. * @access public
  1815. */
  1816. function getSpecialQuery($type)
  1817. {
  1818. return $this->raiseError(DB_ERROR_UNSUPPORTED);
  1819. }
  1820. // }}}
  1821. // {{{ _rtrimArrayValues()
  1822. /**
  1823. * Right trim all strings in an array
  1824. *
  1825. * @param array $array the array to be trimmed (passed by reference)
  1826. * @return void
  1827. * @access private
  1828. */
  1829. function _rtrimArrayValues(&$array) {
  1830. foreach ($array as $key => $value) {
  1831. if (is_string($value)) {
  1832. $array[$key] = rtrim($value);
  1833. }
  1834. }
  1835. }
  1836. // }}}
  1837. // {{{ _convertNullArrayValuesToEmpty()
  1838. /**
  1839. * Convert all null values in an array to empty strings
  1840. *
  1841. * @param array $array the array to be de-nullified (passed by reference)
  1842. * @return void
  1843. * @access private
  1844. */
  1845. function _convertNullArrayValuesToEmpty(&$array) {
  1846. foreach ($array as $key => $value) {
  1847. if (is_null($value)) {
  1848. $array[$key] = '';
  1849. }
  1850. }
  1851. }
  1852. // }}}
  1853. }
  1854. /*
  1855. * Local variables:
  1856. * tab-width: 4
  1857. * c-basic-offset: 4
  1858. * End:
  1859. */
  1860. ?>