PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/j/kfm/includes/pear/MDB2.php

http://kv-webme.googlecode.com/
PHP | 4213 lines | 1819 code | 364 blank | 2030 comment | 298 complexity | 06a8b49acaf098294725b4810de586cd MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, BSD-3-Clause, BSD-2-Clause, Apache-2.0, MIT, LGPL-2.1

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

  1. <?php
  2. // vim: set et ts=4 sw=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | PHP versions 4 and 5 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
  7. // | Stig. S. Bakken, Lukas Smith |
  8. // | All rights reserved. |
  9. // +----------------------------------------------------------------------+
  10. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
  11. // | API as well as database abstraction for PHP applications. |
  12. // | This LICENSE is in the BSD license style. |
  13. // | |
  14. // | Redistribution and use in source and binary forms, with or without |
  15. // | modification, are permitted provided that the following conditions |
  16. // | are met: |
  17. // | |
  18. // | Redistributions of source code must retain the above copyright |
  19. // | notice, this list of conditions and the following disclaimer. |
  20. // | |
  21. // | Redistributions in binary form must reproduce the above copyright |
  22. // | notice, this list of conditions and the following disclaimer in the |
  23. // | documentation and/or other materials provided with the distribution. |
  24. // | |
  25. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
  26. // | Lukas Smith nor the names of his contributors may be used to endorse |
  27. // | or promote products derived from this software without specific prior|
  28. // | written permission. |
  29. // | |
  30. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  31. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  32. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
  33. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
  34. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
  35. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  36. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  37. // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
  38. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  39. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  40. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
  41. // | POSSIBILITY OF SUCH DAMAGE. |
  42. // +----------------------------------------------------------------------+
  43. // | Author: Lukas Smith <smith@pooteeweet.org> |
  44. // +----------------------------------------------------------------------+
  45. //
  46. // $Id: MDB2.php,v 1.292 2007/04/25 09:31:01 quipo Exp $
  47. //
  48. /**
  49. * @package MDB2
  50. * @category Database
  51. * @author Lukas Smith <smith@pooteeweet.org>
  52. */
  53. require_once 'PEAR.php';
  54. // {{{ Error constants
  55. /**
  56. * The method mapErrorCode in each MDB2_dbtype implementation maps
  57. * native error codes to one of these.
  58. *
  59. * If you add an error code here, make sure you also add a textual
  60. * version of it in MDB2::errorMessage().
  61. */
  62. define('MDB2_OK', true);
  63. define('MDB2_ERROR', -1);
  64. define('MDB2_ERROR_SYNTAX', -2);
  65. define('MDB2_ERROR_CONSTRAINT', -3);
  66. define('MDB2_ERROR_NOT_FOUND', -4);
  67. define('MDB2_ERROR_ALREADY_EXISTS', -5);
  68. define('MDB2_ERROR_UNSUPPORTED', -6);
  69. define('MDB2_ERROR_MISMATCH', -7);
  70. define('MDB2_ERROR_INVALID', -8);
  71. define('MDB2_ERROR_NOT_CAPABLE', -9);
  72. define('MDB2_ERROR_TRUNCATED', -10);
  73. define('MDB2_ERROR_INVALID_NUMBER', -11);
  74. define('MDB2_ERROR_INVALID_DATE', -12);
  75. define('MDB2_ERROR_DIVZERO', -13);
  76. define('MDB2_ERROR_NODBSELECTED', -14);
  77. define('MDB2_ERROR_CANNOT_CREATE', -15);
  78. define('MDB2_ERROR_CANNOT_DELETE', -16);
  79. define('MDB2_ERROR_CANNOT_DROP', -17);
  80. define('MDB2_ERROR_NOSUCHTABLE', -18);
  81. define('MDB2_ERROR_NOSUCHFIELD', -19);
  82. define('MDB2_ERROR_NEED_MORE_DATA', -20);
  83. define('MDB2_ERROR_NOT_LOCKED', -21);
  84. define('MDB2_ERROR_VALUE_COUNT_ON_ROW', -22);
  85. define('MDB2_ERROR_INVALID_DSN', -23);
  86. define('MDB2_ERROR_CONNECT_FAILED', -24);
  87. define('MDB2_ERROR_EXTENSION_NOT_FOUND',-25);
  88. define('MDB2_ERROR_NOSUCHDB', -26);
  89. define('MDB2_ERROR_ACCESS_VIOLATION', -27);
  90. define('MDB2_ERROR_CANNOT_REPLACE', -28);
  91. define('MDB2_ERROR_CONSTRAINT_NOT_NULL',-29);
  92. define('MDB2_ERROR_DEADLOCK', -30);
  93. define('MDB2_ERROR_CANNOT_ALTER', -31);
  94. define('MDB2_ERROR_MANAGER', -32);
  95. define('MDB2_ERROR_MANAGER_PARSE', -33);
  96. define('MDB2_ERROR_LOADMODULE', -34);
  97. define('MDB2_ERROR_INSUFFICIENT_DATA', -35);
  98. // }}}
  99. // {{{ Verbose constants
  100. /**
  101. * These are just helper constants to more verbosely express parameters to prepare()
  102. */
  103. define('MDB2_PREPARE_MANIP', false);
  104. define('MDB2_PREPARE_RESULT', null);
  105. // }}}
  106. // {{{ Fetchmode constants
  107. /**
  108. * This is a special constant that tells MDB2 the user hasn't specified
  109. * any particular get mode, so the default should be used.
  110. */
  111. define('MDB2_FETCHMODE_DEFAULT', 0);
  112. /**
  113. * Column data indexed by numbers, ordered from 0 and up
  114. */
  115. define('MDB2_FETCHMODE_ORDERED', 1);
  116. /**
  117. * Column data indexed by column names
  118. */
  119. define('MDB2_FETCHMODE_ASSOC', 2);
  120. /**
  121. * Column data as object properties
  122. */
  123. define('MDB2_FETCHMODE_OBJECT', 3);
  124. /**
  125. * For multi-dimensional results: normally the first level of arrays
  126. * is the row number, and the second level indexed by column number or name.
  127. * MDB2_FETCHMODE_FLIPPED switches this order, so the first level of arrays
  128. * is the column name, and the second level the row number.
  129. */
  130. define('MDB2_FETCHMODE_FLIPPED', 4);
  131. // }}}
  132. // {{{ Portability mode constants
  133. /**
  134. * Portability: turn off all portability features.
  135. * @see MDB2_Driver_Common::setOption()
  136. */
  137. define('MDB2_PORTABILITY_NONE', 0);
  138. /**
  139. * Portability: convert names of tables and fields to case defined in the
  140. * "field_case" option when using the query*(), fetch*() and tableInfo() methods.
  141. * @see MDB2_Driver_Common::setOption()
  142. */
  143. define('MDB2_PORTABILITY_FIX_CASE', 1);
  144. /**
  145. * Portability: right trim the data output by query*() and fetch*().
  146. * @see MDB2_Driver_Common::setOption()
  147. */
  148. define('MDB2_PORTABILITY_RTRIM', 2);
  149. /**
  150. * Portability: force reporting the number of rows deleted.
  151. * @see MDB2_Driver_Common::setOption()
  152. */
  153. define('MDB2_PORTABILITY_DELETE_COUNT', 4);
  154. /**
  155. * Portability: not needed in MDB2 (just left here for compatibility to DB)
  156. * @see MDB2_Driver_Common::setOption()
  157. */
  158. define('MDB2_PORTABILITY_NUMROWS', 8);
  159. /**
  160. * Portability: makes certain error messages in certain drivers compatible
  161. * with those from other DBMS's.
  162. *
  163. * + mysql, mysqli: change unique/primary key constraints
  164. * MDB2_ERROR_ALREADY_EXISTS -> MDB2_ERROR_CONSTRAINT
  165. *
  166. * + odbc(access): MS's ODBC driver reports 'no such field' as code
  167. * 07001, which means 'too few parameters.' When this option is on
  168. * that code gets mapped to MDB2_ERROR_NOSUCHFIELD.
  169. *
  170. * @see MDB2_Driver_Common::setOption()
  171. */
  172. define('MDB2_PORTABILITY_ERRORS', 16);
  173. /**
  174. * Portability: convert empty values to null strings in data output by
  175. * query*() and fetch*().
  176. * @see MDB2_Driver_Common::setOption()
  177. */
  178. define('MDB2_PORTABILITY_EMPTY_TO_NULL', 32);
  179. /**
  180. * Portability: removes database/table qualifiers from associative indexes
  181. * @see MDB2_Driver_Common::setOption()
  182. */
  183. define('MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES', 64);
  184. /**
  185. * Portability: turn on all portability features.
  186. * @see MDB2_Driver_Common::setOption()
  187. */
  188. define('MDB2_PORTABILITY_ALL', 127);
  189. // }}}
  190. // {{{ Globals for class instance tracking
  191. /**
  192. * These are global variables that are used to track the various class instances
  193. */
  194. $GLOBALS['_MDB2_databases'] = array();
  195. $GLOBALS['_MDB2_dsninfo_default'] = array(
  196. 'phptype' => false,
  197. 'dbsyntax' => false,
  198. 'username' => false,
  199. 'password' => false,
  200. 'protocol' => false,
  201. 'hostspec' => false,
  202. 'port' => false,
  203. 'socket' => false,
  204. 'database' => false,
  205. 'mode' => false,
  206. );
  207. // }}}
  208. // {{{ class MDB2
  209. /**
  210. * The main 'MDB2' class is simply a container class with some static
  211. * methods for creating DB objects as well as some utility functions
  212. * common to all parts of DB.
  213. *
  214. * The object model of MDB2 is as follows (indentation means inheritance):
  215. *
  216. * MDB2 The main MDB2 class. This is simply a utility class
  217. * with some 'static' methods for creating MDB2 objects as
  218. * well as common utility functions for other MDB2 classes.
  219. *
  220. * MDB2_Driver_Common The base for each MDB2 implementation. Provides default
  221. * | implementations (in OO lingo virtual methods) for
  222. * | the actual DB implementations as well as a bunch of
  223. * | query utility functions.
  224. * |
  225. * +-MDB2_Driver_mysql The MDB2 implementation for MySQL. Inherits MDB2_Driver_Common.
  226. * When calling MDB2::factory or MDB2::connect for MySQL
  227. * connections, the object returned is an instance of this
  228. * class.
  229. * +-MDB2_Driver_pgsql The MDB2 implementation for PostGreSQL. Inherits MDB2_Driver_Common.
  230. * When calling MDB2::factory or MDB2::connect for PostGreSQL
  231. * connections, the object returned is an instance of this
  232. * class.
  233. *
  234. * @package MDB2
  235. * @category Database
  236. * @author Lukas Smith <smith@pooteeweet.org>
  237. */
  238. class MDB2
  239. {
  240. // {{{ function setOptions(&$db, $options)
  241. /**
  242. * set option array in an exiting database object
  243. *
  244. * @param MDB2_Driver_Common MDB2 object
  245. * @param array An associative array of option names and their values.
  246. *
  247. * @return mixed MDB2_OK or a PEAR Error object
  248. *
  249. * @access public
  250. */
  251. static function setOptions(&$db, $options)
  252. {
  253. if (is_array($options)) {
  254. foreach ($options as $option => $value) {
  255. $test = $db->setOption($option, $value);
  256. if (PEAR::isError($test)) {
  257. return $test;
  258. }
  259. }
  260. }
  261. return MDB2_OK;
  262. }
  263. // }}}
  264. // {{{ function classExists($classname)
  265. /**
  266. * Checks if a class exists without triggering __autoload
  267. *
  268. * @param string classname
  269. *
  270. * @return bool true success and false on error
  271. * @static
  272. * @access public
  273. */
  274. static function classExists($classname)
  275. {
  276. if (version_compare(phpversion(), "5.0", ">=")) {
  277. return class_exists($classname, false);
  278. }
  279. return class_exists($classname);
  280. }
  281. // }}}
  282. // {{{ function loadClass($class_name, $debug)
  283. /**
  284. * Loads a PEAR class.
  285. *
  286. * @param string classname to load
  287. * @param bool if errors should be suppressed
  288. *
  289. * @return mixed true success or PEAR_Error on failure
  290. *
  291. * @access public
  292. */
  293. static function loadClass($class_name, $debug)
  294. {
  295. if (!MDB2::classExists($class_name)) {
  296. $file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name).'.php';
  297. $include = include_once($file_name);
  298. if (!$include) {
  299. if (!MDB2::fileExists($file_name)) {
  300. $msg = "unable to find package '$class_name' file '$file_name'";
  301. } else {
  302. $msg = "unable to load class '$class_name' from file '$file_name'";
  303. }
  304. $err =& MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null, $msg);
  305. return $err;
  306. }
  307. }
  308. return MDB2_OK;
  309. }
  310. // }}}
  311. // {{{ function &factory($dsn, $options = false)
  312. /**
  313. * Create a new MDB2 object for the specified database type
  314. *
  315. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  316. * you make sure that you work with a reference of the original
  317. * object instead of a copy (this is a PHP4 quirk).
  318. *
  319. * For example:
  320. * $db =& MDB2::factory($dsn);
  321. * ^^
  322. * And not:
  323. * $db = MDB2::factory($dsn);
  324. *
  325. * @param mixed 'data source name', see the MDB2::parseDSN
  326. * method for a description of the dsn format.
  327. * Can also be specified as an array of the
  328. * format returned by MDB2::parseDSN.
  329. * @param array An associative array of option names and
  330. * their values.
  331. *
  332. * @return mixed a newly created MDB2 object, or false on error
  333. *
  334. * @access public
  335. */
  336. static function &factory($dsn, $options = false)
  337. {
  338. $dsninfo = MDB2::parseDSN($dsn);
  339. if (empty($dsninfo['phptype'])) {
  340. $err =& MDB2::raiseError(MDB2_ERROR_NOT_FOUND,
  341. null, null, 'no RDBMS driver specified');
  342. return $err;
  343. }
  344. $class_name = 'MDB2_Driver_'.$dsninfo['phptype'];
  345. $debug = (!empty($options['debug']));
  346. $err = MDB2::loadClass($class_name, $debug);
  347. if (PEAR::isError($err)) {
  348. return $err;
  349. }
  350. $db =new $class_name();
  351. $db->setDSN($dsninfo);
  352. $err = MDB2::setOptions($db, $options);
  353. if (PEAR::isError($err)) {
  354. return $err;
  355. }
  356. return $db;
  357. }
  358. // }}}
  359. // {{{ function &connect($dsn, $options = false)
  360. /**
  361. * Create a new MDB2 connection object and connect to the specified
  362. * database
  363. *
  364. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  365. * you make sure that you work with a reference of the original
  366. * object instead of a copy (this is a PHP4 quirk).
  367. *
  368. * For example:
  369. * $db =& MDB2::connect($dsn);
  370. * ^^
  371. * And not:
  372. * $db = MDB2::connect($dsn);
  373. * ^^
  374. *
  375. * @param mixed 'data source name', see the MDB2::parseDSN
  376. * method for a description of the dsn format.
  377. * Can also be specified as an array of the
  378. * format returned by MDB2::parseDSN.
  379. * @param array An associative array of option names and
  380. * their values.
  381. *
  382. * @return mixed a newly created MDB2 connection object, or a MDB2
  383. * error object on error
  384. *
  385. * @access public
  386. * @see MDB2::parseDSN
  387. */
  388. static function &connect($dsn, $options = false)
  389. {
  390. $db =& MDB2::factory($dsn, $options);
  391. if (PEAR::isError($db)) {
  392. return $db;
  393. }
  394. $err = $db->connect();
  395. if (PEAR::isError($err)) {
  396. $dsn = $db->getDSN('string', 'xxx');
  397. $db->disconnect();
  398. $err->addUserInfo($dsn);
  399. return $err;
  400. }
  401. return $db;
  402. }
  403. // }}}
  404. // {{{ function &singleton($dsn = null, $options = false)
  405. /**
  406. * Returns a MDB2 connection with the requested DSN.
  407. * A new MDB2 connection object is only created if no object with the
  408. * requested DSN exists yet.
  409. *
  410. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  411. * you make sure that you work with a reference of the original
  412. * object instead of a copy (this is a PHP4 quirk).
  413. *
  414. * For example:
  415. * $db =& MDB2::singleton($dsn);
  416. * ^^
  417. * And not:
  418. * $db = MDB2::singleton($dsn);
  419. * ^^
  420. *
  421. * @param mixed 'data source name', see the MDB2::parseDSN
  422. * method for a description of the dsn format.
  423. * Can also be specified as an array of the
  424. * format returned by MDB2::parseDSN.
  425. * @param array An associative array of option names and
  426. * their values.
  427. *
  428. * @return mixed a newly created MDB2 connection object, or a MDB2
  429. * error object on error
  430. *
  431. * @access public
  432. * @see MDB2::parseDSN
  433. */
  434. function &singleton($dsn = null, $options = false)
  435. {
  436. if ($dsn) {
  437. $dsninfo = MDB2::parseDSN($dsn);
  438. $dsninfo = array_merge($GLOBALS['_MDB2_dsninfo_default'], $dsninfo);
  439. $keys = array_keys($GLOBALS['_MDB2_databases']);
  440. for ($i=0, $j=count($keys); $i<$j; ++$i) {
  441. if (isset($GLOBALS['_MDB2_databases'][$keys[$i]])) {
  442. $tmp_dsn = $GLOBALS['_MDB2_databases'][$keys[$i]]->getDSN('array');
  443. if (count(array_diff_assoc($tmp_dsn, $dsninfo)) == 0) {
  444. MDB2::setOptions($GLOBALS['_MDB2_databases'][$keys[$i]], $options);
  445. return $GLOBALS['_MDB2_databases'][$keys[$i]];
  446. }
  447. }
  448. }
  449. } elseif (is_array($GLOBALS['_MDB2_databases']) && reset($GLOBALS['_MDB2_databases'])) {
  450. $db =& $GLOBALS['_MDB2_databases'][key($GLOBALS['_MDB2_databases'])];
  451. return $db;
  452. }
  453. $db =& MDB2::factory($dsn, $options);
  454. return $db;
  455. }
  456. // }}}
  457. // {{{ function loadFile($file)
  458. /**
  459. * load a file (like 'Date')
  460. *
  461. * @param string name of the file in the MDB2 directory (without '.php')
  462. *
  463. * @return string name of the file that was included
  464. *
  465. * @access public
  466. */
  467. function loadFile($file)
  468. {
  469. $file_name = 'MDB2'.DIRECTORY_SEPARATOR.$file.'.php';
  470. if (!MDB2::fileExists($file_name)) {
  471. return MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  472. 'unable to find: '.$file_name);
  473. }
  474. if (!include_once($file_name)) {
  475. return MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  476. 'unable to load driver class: '.$file_name);
  477. }
  478. return $file_name;
  479. }
  480. // }}}
  481. // {{{ function apiVersion()
  482. /**
  483. * Return the MDB2 API version
  484. *
  485. * @return string the MDB2 API version number
  486. *
  487. * @access public
  488. */
  489. function apiVersion()
  490. {
  491. return '2.4.1';
  492. }
  493. // }}}
  494. // {{{ function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  495. /**
  496. * This method is used to communicate an error and invoke error
  497. * callbacks etc. Basically a wrapper for PEAR::raiseError
  498. * without the message string.
  499. *
  500. * @param mixed int error code
  501. *
  502. * @param int error mode, see PEAR_Error docs
  503. *
  504. * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
  505. * error level (E_USER_NOTICE etc). If error mode is
  506. * PEAR_ERROR_CALLBACK, this is the callback function,
  507. * either as a function name, or as an array of an
  508. * object and method name. For other error modes this
  509. * parameter is ignored.
  510. *
  511. * @param string Extra debug information. Defaults to the last
  512. * query and native error code.
  513. *
  514. * @return PEAR_Error instance of a PEAR Error object
  515. *
  516. * @access private
  517. * @see PEAR_Error
  518. */
  519. function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  520. {
  521. $err =& PEAR::raiseError(null, $code, $mode, $options, $userinfo, 'MDB2_Error', true);
  522. return $err;
  523. }
  524. // }}}
  525. // {{{ function isError($data, $code = null)
  526. /**
  527. * Tell whether a value is a MDB2 error.
  528. *
  529. * @param mixed the value to test
  530. * @param int if is an error object, return true
  531. * only if $code is a string and
  532. * $db->getMessage() == $code or
  533. * $code is an integer and $db->getCode() == $code
  534. *
  535. * @return bool true if parameter is an error
  536. *
  537. * @access public
  538. */
  539. function isError($data, $code = null)
  540. {
  541. if ($data instanceof MDB2_Error) {
  542. if (is_null($code)) {
  543. return true;
  544. } elseif (is_string($code)) {
  545. return $data->getMessage() === $code;
  546. } else {
  547. $code = (array)$code;
  548. return in_array($data->getCode(), $code);
  549. }
  550. }
  551. return false;
  552. }
  553. // }}}
  554. // {{{ function isConnection($value)
  555. /**
  556. * Tell whether a value is a MDB2 connection
  557. *
  558. * @param mixed value to test
  559. *
  560. * @return bool whether $value is a MDB2 connection
  561. *
  562. * @access public
  563. */
  564. function isConnection($value)
  565. {
  566. return $value instanceof MDB2_Driver_Common;
  567. }
  568. // }}}
  569. // {{{ function isResult($value)
  570. /**
  571. * Tell whether a value is a MDB2 result
  572. *
  573. * @param mixed value to test
  574. *
  575. * @return bool whether $value is a MDB2 result
  576. *
  577. * @access public
  578. */
  579. function isResult($value)
  580. {
  581. return $value instanceof MDB2_Result;
  582. }
  583. // }}}
  584. // {{{ function isResultCommon($value)
  585. /**
  586. * Tell whether a value is a MDB2 result implementing the common interface
  587. *
  588. * @param mixed value to test
  589. *
  590. * @return bool whether $value is a MDB2 result implementing the common interface
  591. *
  592. * @access public
  593. */
  594. static function isResultCommon($value)
  595. {
  596. return $value instanceof MDB2_Result_Common;
  597. }
  598. // }}}
  599. // {{{ function isStatement($value)
  600. /**
  601. * Tell whether a value is a MDB2 statement interface
  602. *
  603. * @param mixed value to test
  604. *
  605. * @return bool whether $value is a MDB2 statement interface
  606. *
  607. * @access public
  608. */
  609. function isStatement($value)
  610. {
  611. return $value instanceof MDB2_Statement;
  612. }
  613. // }}}
  614. // {{{ function errorMessage($value = null)
  615. /**
  616. * Return a textual error message for a MDB2 error code
  617. *
  618. * @param int|array integer error code,
  619. null to get the current error code-message map,
  620. or an array with a new error code-message map
  621. *
  622. * @return string error message, or false if the error code was
  623. * not recognized
  624. *
  625. * @access public
  626. */
  627. function errorMessage($value = null)
  628. {
  629. static $errorMessages;
  630. if (is_array($value)) {
  631. $errorMessages = $value;
  632. return MDB2_OK;
  633. }
  634. if (!isset($errorMessages)) {
  635. $errorMessages = array(
  636. MDB2_OK => 'no error',
  637. MDB2_ERROR => 'unknown error',
  638. MDB2_ERROR_ALREADY_EXISTS => 'already exists',
  639. MDB2_ERROR_CANNOT_CREATE => 'can not create',
  640. MDB2_ERROR_CANNOT_ALTER => 'can not alter',
  641. MDB2_ERROR_CANNOT_REPLACE => 'can not replace',
  642. MDB2_ERROR_CANNOT_DELETE => 'can not delete',
  643. MDB2_ERROR_CANNOT_DROP => 'can not drop',
  644. MDB2_ERROR_CONSTRAINT => 'constraint violation',
  645. MDB2_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
  646. MDB2_ERROR_DIVZERO => 'division by zero',
  647. MDB2_ERROR_INVALID => 'invalid',
  648. MDB2_ERROR_INVALID_DATE => 'invalid date or time',
  649. MDB2_ERROR_INVALID_NUMBER => 'invalid number',
  650. MDB2_ERROR_MISMATCH => 'mismatch',
  651. MDB2_ERROR_NODBSELECTED => 'no database selected',
  652. MDB2_ERROR_NOSUCHFIELD => 'no such field',
  653. MDB2_ERROR_NOSUCHTABLE => 'no such table',
  654. MDB2_ERROR_NOT_CAPABLE => 'MDB2 backend not capable',
  655. MDB2_ERROR_NOT_FOUND => 'not found',
  656. MDB2_ERROR_NOT_LOCKED => 'not locked',
  657. MDB2_ERROR_SYNTAX => 'syntax error',
  658. MDB2_ERROR_UNSUPPORTED => 'not supported',
  659. MDB2_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
  660. MDB2_ERROR_INVALID_DSN => 'invalid DSN',
  661. MDB2_ERROR_CONNECT_FAILED => 'connect failed',
  662. MDB2_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
  663. MDB2_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
  664. MDB2_ERROR_NOSUCHDB => 'no such database',
  665. MDB2_ERROR_ACCESS_VIOLATION => 'insufficient permissions',
  666. MDB2_ERROR_LOADMODULE => 'error while including on demand module',
  667. MDB2_ERROR_TRUNCATED => 'truncated',
  668. MDB2_ERROR_DEADLOCK => 'deadlock detected',
  669. );
  670. }
  671. if (is_null($value)) {
  672. return $errorMessages;
  673. }
  674. if (PEAR::isError($value)) {
  675. $value = $value->getCode();
  676. }
  677. return isset($errorMessages[$value]) ?
  678. $errorMessages[$value] : $errorMessages[MDB2_ERROR];
  679. }
  680. // }}}
  681. // {{{ function parseDSN($dsn)
  682. /**
  683. * Parse a data source name.
  684. *
  685. * Additional keys can be added by appending a URI query string to the
  686. * end of the DSN.
  687. *
  688. * The format of the supplied DSN is in its fullest form:
  689. * <code>
  690. * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
  691. * </code>
  692. *
  693. * Most variations are allowed:
  694. * <code>
  695. * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
  696. * phptype://username:password@hostspec/database_name
  697. * phptype://username:password@hostspec
  698. * phptype://username@hostspec
  699. * phptype://hostspec/database
  700. * phptype://hostspec
  701. * phptype(dbsyntax)
  702. * phptype
  703. * </code>
  704. *
  705. * @param string Data Source Name to be parsed
  706. *
  707. * @return array an associative array with the following keys:
  708. * + phptype: Database backend used in PHP (mysql, odbc etc.)
  709. * + dbsyntax: Database used with regards to SQL syntax etc.
  710. * + protocol: Communication protocol to use (tcp, unix etc.)
  711. * + hostspec: Host specification (hostname[:port])
  712. * + database: Database to use on the DBMS server
  713. * + username: User name for login
  714. * + password: Password for login
  715. *
  716. * @access public
  717. * @author Tomas V.V.Cox <cox@idecnet.com>
  718. */
  719. static function parseDSN($dsn)
  720. {
  721. $parsed = $GLOBALS['_MDB2_dsninfo_default'];
  722. if (is_array($dsn)) {
  723. $dsn = array_merge($parsed, $dsn);
  724. if (!$dsn['dbsyntax']) {
  725. $dsn['dbsyntax'] = $dsn['phptype'];
  726. }
  727. return $dsn;
  728. }
  729. // Find phptype and dbsyntax
  730. if (($pos = strpos($dsn, '://')) !== false) {
  731. $str = substr($dsn, 0, $pos);
  732. $dsn = substr($dsn, $pos + 3);
  733. } else {
  734. $str = $dsn;
  735. $dsn = null;
  736. }
  737. // Get phptype and dbsyntax
  738. // $str => phptype(dbsyntax)
  739. if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
  740. $parsed['phptype'] = $arr[1];
  741. $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
  742. } else {
  743. $parsed['phptype'] = $str;
  744. $parsed['dbsyntax'] = $str;
  745. }
  746. if (!count($dsn)) {
  747. return $parsed;
  748. }
  749. // Get (if found): username and password
  750. // $dsn => username:password@protocol+hostspec/database
  751. if (($at = strrpos($dsn,'@')) !== false) {
  752. $str = substr($dsn, 0, $at);
  753. $dsn = substr($dsn, $at + 1);
  754. if (($pos = strpos($str, ':')) !== false) {
  755. $parsed['username'] = rawurldecode(substr($str, 0, $pos));
  756. $parsed['password'] = rawurldecode(substr($str, $pos + 1));
  757. } else {
  758. $parsed['username'] = rawurldecode($str);
  759. }
  760. }
  761. // Find protocol and hostspec
  762. // $dsn => proto(proto_opts)/database
  763. if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
  764. $proto = $match[1];
  765. $proto_opts = $match[2] ? $match[2] : false;
  766. $dsn = $match[3];
  767. // $dsn => protocol+hostspec/database (old format)
  768. } else {
  769. if (strpos($dsn, '+') !== false) {
  770. list($proto, $dsn) = explode('+', $dsn, 2);
  771. }
  772. if ( strpos($dsn, '//') === 0
  773. && strpos($dsn, '/', 2) !== false
  774. && $parsed['phptype'] == 'oci8'
  775. ) {
  776. //oracle's "Easy Connect" syntax:
  777. //"username/password@[//]host[:port][/service_name]"
  778. //e.g. "scott/tiger@//mymachine:1521/oracle"
  779. $proto_opts = $dsn;
  780. $dsn = null;
  781. } elseif (strpos($dsn, '/') !== false) {
  782. list($proto_opts, $dsn) = explode('/', $dsn, 2);
  783. } else {
  784. $proto_opts = $dsn;
  785. $dsn = null;
  786. }
  787. }
  788. // process the different protocol options
  789. $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
  790. $proto_opts = rawurldecode($proto_opts);
  791. if (strpos($proto_opts, ':') !== false) {
  792. list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
  793. }
  794. if ($parsed['protocol'] == 'tcp') {
  795. $parsed['hostspec'] = $proto_opts;
  796. } elseif ($parsed['protocol'] == 'unix') {
  797. $parsed['socket'] = $proto_opts;
  798. }
  799. // Get dabase if any
  800. // $dsn => database
  801. if ($dsn) {
  802. // /database
  803. if (($pos = strpos($dsn, '?')) === false) {
  804. $parsed['database'] = $dsn;
  805. // /database?param1=value1&param2=value2
  806. } else {
  807. $parsed['database'] = substr($dsn, 0, $pos);
  808. $dsn = substr($dsn, $pos + 1);
  809. if (strpos($dsn, '&') !== false) {
  810. $opts = explode('&', $dsn);
  811. } else { // database?param1=value1
  812. $opts = array($dsn);
  813. }
  814. foreach ($opts as $opt) {
  815. list($key, $value) = explode('=', $opt);
  816. if (!isset($parsed[$key])) {
  817. // don't allow params overwrite
  818. $parsed[$key] = rawurldecode($value);
  819. }
  820. }
  821. }
  822. }
  823. return $parsed;
  824. }
  825. // }}}
  826. // {{{ function fileExists($file)
  827. /**
  828. * Checks if a file exists in the include path
  829. *
  830. * @param string filename
  831. *
  832. * @return bool true success and false on error
  833. *
  834. * @access public
  835. */
  836. function fileExists($file)
  837. {
  838. // safe_mode does notwork with is_readable()
  839. if (!@ini_get('safe_mode')) {
  840. $dirs = explode(PATH_SEPARATOR, ini_get('include_path'));
  841. foreach ($dirs as $dir) {
  842. if (is_readable($dir . DIRECTORY_SEPARATOR . $file)) {
  843. return true;
  844. }
  845. }
  846. } else {
  847. $fp = @fopen($file, 'r', true);
  848. if (is_resource($fp)) {
  849. @fclose($fp);
  850. return true;
  851. }
  852. }
  853. return false;
  854. }
  855. // }}}
  856. }
  857. // }}}
  858. // {{{ class MDB2_Error extends PEAR_Error
  859. /**
  860. * MDB2_Error implements a class for reporting portable database error
  861. * messages.
  862. *
  863. * @package MDB2
  864. * @category Database
  865. * @author Stig Bakken <ssb@fast.no>
  866. */
  867. class MDB2_Error extends PEAR_Error
  868. {
  869. // {{{ constructor: function MDB2_Error($code = MDB2_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null)
  870. /**
  871. * MDB2_Error constructor.
  872. *
  873. * @param mixed MDB2 error code, or string with error message.
  874. * @param int what 'error mode' to operate in
  875. * @param int what error level to use for $mode & PEAR_ERROR_TRIGGER
  876. * @param smixed additional debug info, such as the last query
  877. */
  878. function MDB2_Error($code = MDB2_ERROR, $mode = PEAR_ERROR_RETURN,
  879. $level = E_USER_NOTICE, $debuginfo = null)
  880. {
  881. if (is_null($code)) {
  882. $code = MDB2_ERROR;
  883. }
  884. $this->PEAR_Error('MDB2 Error: '.MDB2::errorMessage($code), $code,
  885. $mode, $level, $debuginfo);
  886. }
  887. // }}}
  888. }
  889. // }}}
  890. // {{{ class MDB2_Driver_Common extends PEAR
  891. /**
  892. * MDB2_Driver_Common: Base class that is extended by each MDB2 driver
  893. *
  894. * @package MDB2
  895. * @category Database
  896. * @author Lukas Smith <smith@pooteeweet.org>
  897. */
  898. class MDB2_Driver_Common extends PEAR
  899. {
  900. // {{{ Variables (Properties)
  901. /**
  902. * index of the MDB2 object within the $GLOBALS['_MDB2_databases'] array
  903. * @var int
  904. * @access public
  905. */
  906. var $db_index = 0;
  907. /**
  908. * DSN used for the next query
  909. * @var array
  910. * @access protected
  911. */
  912. var $dsn = array();
  913. /**
  914. * DSN that was used to create the current connection
  915. * @var array
  916. * @access protected
  917. */
  918. var $connected_dsn = array();
  919. /**
  920. * connection resource
  921. * @var mixed
  922. * @access protected
  923. */
  924. var $connection = 0;
  925. /**
  926. * if the current opened connection is a persistent connection
  927. * @var bool
  928. * @access protected
  929. */
  930. var $opened_persistent;
  931. /**
  932. * the name of the database for the next query
  933. * @var string
  934. * @access protected
  935. */
  936. var $database_name = '';
  937. /**
  938. * the name of the database currently selected
  939. * @var string
  940. * @access protected
  941. */
  942. var $connected_database_name = '';
  943. /**
  944. * server version information
  945. * @var string
  946. * @access protected
  947. */
  948. var $connected_server_info = '';
  949. /**
  950. * list of all supported features of the given driver
  951. * @var array
  952. * @access public
  953. */
  954. var $supported = array(
  955. 'sequences' => false,
  956. 'indexes' => false,
  957. 'affected_rows' => false,
  958. 'summary_functions' => false,
  959. 'order_by_text' => false,
  960. 'transactions' => false,
  961. 'savepoints' => false,
  962. 'current_id' => false,
  963. 'limit_queries' => false,
  964. 'LOBs' => false,
  965. 'replace' => false,
  966. 'sub_selects' => false,
  967. 'auto_increment' => false,
  968. 'primary_key' => false,
  969. 'result_introspection' => false,
  970. 'prepared_statements' => false,
  971. 'identifier_quoting' => false,
  972. 'pattern_escaping' => false,
  973. 'new_link' => false,
  974. );
  975. /**
  976. * Array of supported options that can be passed to the MDB2 instance.
  977. *
  978. * The options can be set during object creation, using
  979. * MDB2::connect(), MDB2::factory() or MDB2::singleton(). The options can
  980. * also be set after the object is created, using MDB2::setOptions() or
  981. * MDB2_Driver_Common::setOption().
  982. * The list of available option includes:
  983. * <ul>
  984. * <li>$options['ssl'] -> boolean: determines if ssl should be used for connections</li>
  985. * <li>$options['field_case'] -> CASE_LOWER|CASE_UPPER: determines what case to force on field/table names</li>
  986. * <li>$options['disable_query'] -> boolean: determines if queries should be executed</li>
  987. * <li>$options['result_class'] -> string: class used for result sets</li>
  988. * <li>$options['buffered_result_class'] -> string: class used for buffered result sets</li>
  989. * <li>$options['result_wrap_class'] -> string: class used to wrap result sets into</li>
  990. * <li>$options['result_buffering'] -> boolean should results be buffered or not?</li>
  991. * <li>$options['fetch_class'] -> string: class to use when fetch mode object is used</li>
  992. * <li>$options['persistent'] -> boolean: persistent connection?</li>
  993. * <li>$options['debug'] -> integer: numeric debug level</li>
  994. * <li>$options['debug_handler'] -> string: function/method that captures debug messages</li>
  995. * <li>$options['debug_expanded_output'] -> bool: BC option to determine if more context information should be send to the debug handler</li>
  996. * <li>$options['default_text_field_length'] -> integer: default text field length to use</li>
  997. * <li>$options['lob_buffer_length'] -> integer: LOB buffer length</li>
  998. * <li>$options['log_line_break'] -> string: line-break format</li>
  999. * <li>$options['idxname_format'] -> string: pattern for index name</li>
  1000. * <li>$options['seqname_format'] -> string: pattern for sequence name</li>
  1001. * <li>$options['savepoint_format'] -> string: pattern for auto generated savepoint names</li>
  1002. * <li>$options['statement_format'] -> string: pattern for prepared statement names</li>
  1003. * <li>$options['seqcol_name'] -> string: sequence column name</li>
  1004. * <li>$options['quote_identifier'] -> boolean: if identifier quoting should be done when check_option is used</li>
  1005. * <li>$options['use_transactions'] -> boolean: if transaction use should be enabled</li>
  1006. * <li>$options['decimal_places'] -> integer: number of decimal places to handle</li>
  1007. * <li>$options['portability'] -> integer: portability constant</li>
  1008. * <li>$options['modules'] -> array: short to long module name mapping for __call()</li>
  1009. * <li>$options['emulate_prepared'] -> boolean: force prepared statements to be emulated</li>
  1010. * <li>$options['datatype_map'] -> array: map user defined datatypes to other primitive datatypes</li>
  1011. * <li>$options['datatype_map_callback'] -> array: callback function/method that should be called</li>
  1012. * </ul>
  1013. *
  1014. * @var array
  1015. * @access public
  1016. * @see MDB2::connect()
  1017. * @see MDB2::factory()
  1018. * @see MDB2::singleton()
  1019. * @see MDB2_Driver_Common::setOption()
  1020. */
  1021. var $options = array(
  1022. 'ssl' => false,
  1023. 'field_case' => CASE_LOWER,
  1024. 'disable_query' => false,
  1025. 'result_class' => 'MDB2_Result_%s',
  1026. 'buffered_result_class' => 'MDB2_BufferedResult_%s',
  1027. 'result_wrap_class' => false,
  1028. 'result_buffering' => true,
  1029. 'fetch_class' => 'stdClass',
  1030. 'persistent' => false,
  1031. 'debug' => 0,
  1032. 'debug_handler' => 'MDB2_defaultDebugOutput',
  1033. 'debug_expanded_output' => false,
  1034. 'default_text_field_length' => 4096,
  1035. 'lob_buffer_length' => 8192,
  1036. 'log_line_break' => "\n",
  1037. 'idxname_format' => '%s_idx',
  1038. 'seqname_format' => '%s_seq',
  1039. 'savepoint_format' => 'MDB2_SAVEPOINT_%s',
  1040. 'statement_format' => 'MDB2_STATEMENT_%1$s_%2$s',
  1041. 'seqcol_name' => 'sequence',
  1042. 'quote_identifier' => false,
  1043. 'use_transactions' => true,
  1044. 'decimal_places' => 2,
  1045. 'portability' => MDB2_PORTABILITY_ALL,
  1046. 'modules' => array(
  1047. 'ex' => 'Extended',
  1048. 'dt' => 'Datatype',
  1049. 'mg' => 'Manager',
  1050. 'rv' => 'Reverse',
  1051. 'na' => 'Native',
  1052. 'fc' => 'Function',
  1053. ),
  1054. 'emulate_prepared' => false,
  1055. 'datatype_map' => array(),
  1056. 'datatype_map_callback' => array(),
  1057. 'nativetype_map_callback' => array(),
  1058. );
  1059. /**
  1060. * string array
  1061. * @var string
  1062. * @access protected
  1063. */
  1064. var $string_quoting = array('start' => "'", 'end' => "'", 'escape' => false, 'escape_pattern' => false);
  1065. /**
  1066. * identifier quoting
  1067. * @var array
  1068. * @access protected
  1069. */
  1070. var $identifier_quoting = array('start' => '"', 'end' => '"', 'escape' => '"');
  1071. /**
  1072. * sql comments
  1073. * @var array
  1074. * @access protected
  1075. */
  1076. var $sql_comments = array(
  1077. array('start' => '--', 'end' => "\n", 'escape' => false),
  1078. array('start' => '/*', 'end' => '*/', 'escape' => false),
  1079. );
  1080. /**
  1081. * comparision wildcards
  1082. * @var array
  1083. * @access protected
  1084. */
  1085. var $wildcards = array('%', '_');
  1086. /**
  1087. * column alias keyword
  1088. * @var string
  1089. * @access protected
  1090. */
  1091. var $as_keyword = ' AS ';
  1092. /**
  1093. * warnings
  1094. * @var array
  1095. * @access protected
  1096. */
  1097. var $warnings = array();
  1098. /**
  1099. * string with the debugging information
  1100. * @var string
  1101. * @access public
  1102. */
  1103. var $debug_output = '';
  1104. /**
  1105. * determine if there is an open transaction
  1106. * @var bool
  1107. * @access protected
  1108. */
  1109. var $in_transaction = false;
  1110. /**
  1111. * the smart transaction nesting depth
  1112. * @var int
  1113. * @access protected
  1114. */
  1115. var $nested_transaction_counter = null;
  1116. /**
  1117. * the first error that occured inside a nested transaction
  1118. * @var MDB2_Error|bool
  1119. * @access protected
  1120. */
  1121. var $has_transaction_error = false;
  1122. /**
  1123. * result offset used in the next query
  1124. * @var int
  1125. * @access protected
  1126. */
  1127. var $offset = 0;
  1128. /**
  1129. * result limit used in the next query
  1130. * @var int
  1131. * @access protected
  1132. */
  1133. var $limit = 0;
  1134. /**
  1135. * Database backend used in PHP (mysql, odbc etc.)
  1136. * @var string
  1137. * @access public
  1138. */
  1139. var $phptype;
  1140. /**
  1141. * Database used with regards to SQL syntax etc.
  1142. * @var string
  1143. * @access public
  1144. */
  1145. var $dbsyntax;
  1146. /**
  1147. * the last query sent to the driver
  1148. * @var string
  1149. * @access public
  1150. */
  1151. var $last_query;
  1152. /**
  1153. * the default fetchmode used
  1154. * @var int
  1155. * @access protected
  1156. */
  1157. var $fetchmode = MDB2_FETCHMODE_ORDERED;
  1158. /**
  1159. * array of module instances
  1160. * @var array
  1161. * @access protected
  1162. */
  1163. var $modules = array();
  1164. /**
  1165. * determines of the PHP4 destructor emulation has been enabled yet
  1166. * @var array
  1167. * @access protected
  1168. */
  1169. var $destructor_registered = true;
  1170. // }}}
  1171. // {{{ constructor: function __construct()
  1172. /**
  1173. * Constructor
  1174. */
  1175. function __construct()
  1176. {
  1177. end($GLOBALS['_MDB2_databases']);
  1178. $db_index = key($GLOBALS['_MDB2_databases']) + 1;
  1179. $GLOBALS['_MDB2_databases'][$db_index] = &$this;
  1180. $this->db_index = $db_index;
  1181. }
  1182. // }}}
  1183. // {{{ destructor: function __destruct()
  1184. /**
  1185. * Destructor
  1186. */
  1187. function __destruct()
  1188. {
  1189. $this->disconnect(false);
  1190. }
  1191. // }}}
  1192. // {{{ function free()
  1193. /**
  1194. * Free the internal references so that the instance can be destroyed
  1195. *
  1196. * @return bool true on success, false if result is invalid
  1197. *
  1198. * @access public
  1199. */
  1200. function free()
  1201. {
  1202. unset($GLOBALS['_MDB2_databases'][$this->db_index]);
  1203. unset($this->db_index);
  1204. return MDB2_OK;
  1205. }
  1206. // }}}
  1207. // {{{ function __toString()
  1208. /**
  1209. * String conversation
  1210. *
  1211. * @return string representation of the object
  1212. *
  1213. * @access public
  1214. */
  1215. function __toString()
  1216. {
  1217. $info = get_class($this);
  1218. $info.= ': (phptype = '.$this->phptype.', dbsyntax = '.$this->dbsyntax.')';
  1219. if ($this->connection) {
  1220. $info.= ' [connected]';
  1221. }
  1222. return $info;
  1223. }
  1224. // }}}
  1225. // {{{ function errorInfo($error = null)
  1226. /**
  1227. * This method is used to collect information about an error
  1228. *
  1229. * @param mixed error code or resource
  1230. *
  1231. * @return array with MDB2 errorcode, native error code, native message
  1232. *
  1233. * @access public
  1234. */
  1235. function errorInfo($error = null)
  1236. {
  1237. return array($error, null, null);
  1238. }
  1239. // }}}
  1240. // {{{ function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  1241. /**
  1242. * This method is used to communicate an error and invoke error
  1243. * callbacks etc. Basically a wrapper for PEAR::raiseError
  1244. * without the message string.
  1245. *
  1246. * @param mixed integer error code, or a PEAR error object (all other
  1247. * parameters are ignored if this parameter is an object
  1248. * @param int error mode, see PEAR_Error docs
  1249. * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
  1250. * error level (E_USER_NOTICE etc). If error mode is
  1251. * PEAR_ERROR_CALLBACK, this is the callback function,
  1252. * either as a function name, or as an array of an
  1253. * object and method name. For other error modes this
  1254. * parameter is ignored.
  1255. * @param string Extra debug information. Defaults to the last
  1256. * query and native error code.
  1257. * @param string name of the method that triggered the error
  1258. *
  1259. * @return PEAR_Error instance of a PEAR Error object
  1260. *
  1261. * @access public
  1262. * @see PEAR_Error
  1263. */
  1264. function &raiseError($code = null, $mode = null, $options = null, $userinfo = null, $method = null)
  1265. {
  1266. $userinfo = "[Error message: $userinfo]\n";
  1267. // The error is yet a MDB2 error object
  1268. if (PEAR::isError($code)) {
  1269. // because we use the static PEAR::raiseError, our global
  1270. // handler should be used if it is set
  1271. if (is_null($mode) && !empty($this->_default_error_mode)) {
  1272. $mode = $this->_default_error_mode;
  1273. $options = $this->_default_error_options;
  1274. }
  1275. if (is_null($userinfo)) {
  1276. $userinfo = $code->getUserinfo();
  1277. }
  1278. $code = $code->getCode();
  1279. } elseif ($code == MDB2_ERROR_NOT_FOUND) {
  1280. // extension not loaded: don't call $this->errorInfo() or the script
  1281. // will die
  1282. } elseif (isset($this->connection)) {
  1283. if (!empty($this->last_query)) {
  1284. $userinfo.= "[Last executed query: {$this->last_query}]\n";
  1285. }
  1286. $native_errno = $native_msg = null;
  1287. list($code, $native_errno, $native_msg) = $this->errorInfo($code);
  1288. if (!is_null($native_errno) && $native_errno !== '') {
  1289. $userinfo.= "[Native code: $native_errno]\n";
  1290. }
  1291. if (!is_null($native_msg) && $native_msg !== '') {
  1292. $userinfo.= "[Native message: ". strip_tags($native_msg) ."]\n";
  1293. }
  1294. if (!is_null($method)) {
  1295. $userinfo = $method.': '.$userinfo;
  1296. }
  1297. }
  1298. $err =& PEAR::raiseError(null, $code, $mode, $options, $userinfo, 'MDB2_Error', true);
  1299. if ($err->getMode() !== PEAR_ERROR_RETURN
  1300. && isset($this->nested_transaction_counter) && !$this->has_transaction_error) {
  1301. $this->has_transaction_error =& $err;
  1302. }
  1303. return $err;
  1304. }
  1305. // }}}
  1306. // {{{ function resetWarnings()
  1307. /**
  1308. * reset the warning array
  1309. *
  1310. * @return void
  1311. *
  1312. * @access public
  1313. */
  1314. function resetWarnings()
  1315. {
  1316. $this->warnings = array();
  1317. }
  1318. // }}}
  1319. // {{{ function getWarnings()
  1320. /**
  1321. * Get all warnings in reverse order.
  1322. * This means that the last warning is the first element in the array
  1323. *
  1324. * @return array with warnings
  1325. *
  1326. * @access public
  1327. * @see resetWarnings()
  1328. */
  1329. function getWarnings()
  1330. {
  1331. return array_reverse($this->warnings);
  1332. }
  1333. // }}}
  1334. // {{{ function setFetchMode($fetchmode, $object_class = 'stdClass')
  1335. /**
  1336. * Sets which fetch mode should be used by default on queries
  1337. * on this connection
  1338. *
  1339. * @param int MDB2_FETCHMODE_ORDERED, MDB2_FETCHMODE_ASSOC
  1340. * or MDB2_FETCHMODE_OBJECT
  1341. * @param string the class name of the object to be returned
  1342. * by the fetch methods when the
  1343. * MDB2_FETCHMODE_OBJECT mode is selected.
  1344. * If no class is specified by default a cast
  1345. * to object from the assoc array row will be
  1346. * done. There is also the possibility to use
  1347. * and extend the 'MDB2_row' class.
  1348. *
  1349. * @return mixed MDB2_OK or MDB2 Error Object
  1350. *
  1351. * @access public
  1352. * @see MDB2_FETCHMODE_ORDERED, MDB2_FETCHMODE_ASSOC, MDB2_FETCHMODE_OBJECT
  1353. */
  1354. function setFetchMode($fetchmode, $object_class = 'stdClass')
  1355. {
  1356. switch ($fetchmode) {
  1357. case MDB2_FETCHMODE_OBJECT:
  1358. $this->options['fetch_class'] = $object_class;
  1359. case MDB2_FETCHMODE_ORDERED:
  1360. case MDB2_FETCHMODE_ASSOC:
  1361. $this->fetchmode = $fetchmode;
  1362. break;
  1363. default:
  1364. return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
  1365. 'invalid fetchmode mode', __FUNCTION__);
  1366. }
  1367. return MDB2_OK;
  1368. }
  1369. // }}}
  1370. // {{{ fu…

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