PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/1.3b/includes/pear/MDB2.php

http://kfm.googlecode.com/
PHP | 4271 lines | 1844 code | 373 blank | 2054 comment | 300 complexity | 0d4093f6d7db5ec64434116b700e9a82 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, Apache-2.0

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. 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. 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. function loadClass($class_name, $debug)
  294. {
  295. if (!MDB2::classExists($class_name)) {
  296. $file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name).'.php';
  297. if ($debug) {
  298. $include = include_once($file_name);
  299. } else {
  300. $include = @include_once($file_name);
  301. }
  302. if (!$include) {
  303. if (!MDB2::fileExists($file_name)) {
  304. $msg = "unable to find package '$class_name' file '$file_name'";
  305. } else {
  306. $msg = "unable to load class '$class_name' from file '$file_name'";
  307. }
  308. $err =& MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null, $msg);
  309. return $err;
  310. }
  311. }
  312. return MDB2_OK;
  313. }
  314. // }}}
  315. // {{{ function &factory($dsn, $options = false)
  316. /**
  317. * Create a new MDB2 object for the specified database type
  318. *
  319. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  320. * you make sure that you work with a reference of the original
  321. * object instead of a copy (this is a PHP4 quirk).
  322. *
  323. * For example:
  324. * $db =& MDB2::factory($dsn);
  325. * ^^
  326. * And not:
  327. * $db = MDB2::factory($dsn);
  328. *
  329. * @param mixed 'data source name', see the MDB2::parseDSN
  330. * method for a description of the dsn format.
  331. * Can also be specified as an array of the
  332. * format returned by MDB2::parseDSN.
  333. * @param array An associative array of option names and
  334. * their values.
  335. *
  336. * @return mixed a newly created MDB2 object, or false on error
  337. *
  338. * @access public
  339. */
  340. function &factory($dsn, $options = false)
  341. {
  342. $dsninfo = MDB2::parseDSN($dsn);
  343. if (empty($dsninfo['phptype'])) {
  344. $err =& MDB2::raiseError(MDB2_ERROR_NOT_FOUND,
  345. null, null, 'no RDBMS driver specified');
  346. return $err;
  347. }
  348. $class_name = 'MDB2_Driver_'.$dsninfo['phptype'];
  349. $debug = (!empty($options['debug']));
  350. $err = MDB2::loadClass($class_name, $debug);
  351. if (PEAR::isError($err)) {
  352. return $err;
  353. }
  354. $db =& new $class_name();
  355. $db->setDSN($dsninfo);
  356. $err = MDB2::setOptions($db, $options);
  357. if (PEAR::isError($err)) {
  358. return $err;
  359. }
  360. return $db;
  361. }
  362. // }}}
  363. // {{{ function &connect($dsn, $options = false)
  364. /**
  365. * Create a new MDB2 connection object and connect to the specified
  366. * database
  367. *
  368. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  369. * you make sure that you work with a reference of the original
  370. * object instead of a copy (this is a PHP4 quirk).
  371. *
  372. * For example:
  373. * $db =& MDB2::connect($dsn);
  374. * ^^
  375. * And not:
  376. * $db = MDB2::connect($dsn);
  377. * ^^
  378. *
  379. * @param mixed 'data source name', see the MDB2::parseDSN
  380. * method for a description of the dsn format.
  381. * Can also be specified as an array of the
  382. * format returned by MDB2::parseDSN.
  383. * @param array An associative array of option names and
  384. * their values.
  385. *
  386. * @return mixed a newly created MDB2 connection object, or a MDB2
  387. * error object on error
  388. *
  389. * @access public
  390. * @see MDB2::parseDSN
  391. */
  392. function &connect($dsn, $options = false)
  393. {
  394. $db =& MDB2::factory($dsn, $options);
  395. if (PEAR::isError($db)) {
  396. return $db;
  397. }
  398. $err = $db->connect();
  399. if (PEAR::isError($err)) {
  400. $dsn = $db->getDSN('string', 'xxx');
  401. $db->disconnect();
  402. $err->addUserInfo($dsn);
  403. return $err;
  404. }
  405. return $db;
  406. }
  407. // }}}
  408. // {{{ function &singleton($dsn = null, $options = false)
  409. /**
  410. * Returns a MDB2 connection with the requested DSN.
  411. * A new MDB2 connection object is only created if no object with the
  412. * requested DSN exists yet.
  413. *
  414. * IMPORTANT: In order for MDB2 to work properly it is necessary that
  415. * you make sure that you work with a reference of the original
  416. * object instead of a copy (this is a PHP4 quirk).
  417. *
  418. * For example:
  419. * $db =& MDB2::singleton($dsn);
  420. * ^^
  421. * And not:
  422. * $db = MDB2::singleton($dsn);
  423. * ^^
  424. *
  425. * @param mixed 'data source name', see the MDB2::parseDSN
  426. * method for a description of the dsn format.
  427. * Can also be specified as an array of the
  428. * format returned by MDB2::parseDSN.
  429. * @param array An associative array of option names and
  430. * their values.
  431. *
  432. * @return mixed a newly created MDB2 connection object, or a MDB2
  433. * error object on error
  434. *
  435. * @access public
  436. * @see MDB2::parseDSN
  437. */
  438. function &singleton($dsn = null, $options = false)
  439. {
  440. if ($dsn) {
  441. $dsninfo = MDB2::parseDSN($dsn);
  442. $dsninfo = array_merge($GLOBALS['_MDB2_dsninfo_default'], $dsninfo);
  443. $keys = array_keys($GLOBALS['_MDB2_databases']);
  444. for ($i=0, $j=count($keys); $i<$j; ++$i) {
  445. if (isset($GLOBALS['_MDB2_databases'][$keys[$i]])) {
  446. $tmp_dsn = $GLOBALS['_MDB2_databases'][$keys[$i]]->getDSN('array');
  447. if (count(array_diff_assoc($tmp_dsn, $dsninfo)) == 0) {
  448. MDB2::setOptions($GLOBALS['_MDB2_databases'][$keys[$i]], $options);
  449. return $GLOBALS['_MDB2_databases'][$keys[$i]];
  450. }
  451. }
  452. }
  453. } elseif (is_array($GLOBALS['_MDB2_databases']) && reset($GLOBALS['_MDB2_databases'])) {
  454. $db =& $GLOBALS['_MDB2_databases'][key($GLOBALS['_MDB2_databases'])];
  455. return $db;
  456. }
  457. $db =& MDB2::factory($dsn, $options);
  458. return $db;
  459. }
  460. // }}}
  461. // {{{ function loadFile($file)
  462. /**
  463. * load a file (like 'Date')
  464. *
  465. * @param string name of the file in the MDB2 directory (without '.php')
  466. *
  467. * @return string name of the file that was included
  468. *
  469. * @access public
  470. */
  471. function loadFile($file)
  472. {
  473. $file_name = 'MDB2'.DIRECTORY_SEPARATOR.$file.'.php';
  474. if (!MDB2::fileExists($file_name)) {
  475. return MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  476. 'unable to find: '.$file_name);
  477. }
  478. if (!include_once($file_name)) {
  479. return MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  480. 'unable to load driver class: '.$file_name);
  481. }
  482. return $file_name;
  483. }
  484. // }}}
  485. // {{{ function apiVersion()
  486. /**
  487. * Return the MDB2 API version
  488. *
  489. * @return string the MDB2 API version number
  490. *
  491. * @access public
  492. */
  493. function apiVersion()
  494. {
  495. return '2.4.1';
  496. }
  497. // }}}
  498. // {{{ function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  499. /**
  500. * This method is used to communicate an error and invoke error
  501. * callbacks etc. Basically a wrapper for PEAR::raiseError
  502. * without the message string.
  503. *
  504. * @param mixed int error code
  505. *
  506. * @param int error mode, see PEAR_Error docs
  507. *
  508. * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
  509. * error level (E_USER_NOTICE etc). If error mode is
  510. * PEAR_ERROR_CALLBACK, this is the callback function,
  511. * either as a function name, or as an array of an
  512. * object and method name. For other error modes this
  513. * parameter is ignored.
  514. *
  515. * @param string Extra debug information. Defaults to the last
  516. * query and native error code.
  517. *
  518. * @return PEAR_Error instance of a PEAR Error object
  519. *
  520. * @access private
  521. * @see PEAR_Error
  522. */
  523. function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  524. {
  525. $err =& PEAR::raiseError(null, $code, $mode, $options, $userinfo, 'MDB2_Error', true);
  526. return $err;
  527. }
  528. // }}}
  529. // {{{ function isError($data, $code = null)
  530. /**
  531. * Tell whether a value is a MDB2 error.
  532. *
  533. * @param mixed the value to test
  534. * @param int if is an error object, return true
  535. * only if $code is a string and
  536. * $db->getMessage() == $code or
  537. * $code is an integer and $db->getCode() == $code
  538. *
  539. * @return bool true if parameter is an error
  540. *
  541. * @access public
  542. */
  543. function isError($data, $code = null)
  544. {
  545. if (is_a($data, 'MDB2_Error')) {
  546. if (is_null($code)) {
  547. return true;
  548. } elseif (is_string($code)) {
  549. return $data->getMessage() === $code;
  550. } else {
  551. $code = (array)$code;
  552. return in_array($data->getCode(), $code);
  553. }
  554. }
  555. return false;
  556. }
  557. // }}}
  558. // {{{ function isConnection($value)
  559. /**
  560. * Tell whether a value is a MDB2 connection
  561. *
  562. * @param mixed value to test
  563. *
  564. * @return bool whether $value is a MDB2 connection
  565. *
  566. * @access public
  567. */
  568. function isConnection($value)
  569. {
  570. return is_a($value, 'MDB2_Driver_Common');
  571. }
  572. // }}}
  573. // {{{ function isResult($value)
  574. /**
  575. * Tell whether a value is a MDB2 result
  576. *
  577. * @param mixed value to test
  578. *
  579. * @return bool whether $value is a MDB2 result
  580. *
  581. * @access public
  582. */
  583. function isResult($value)
  584. {
  585. return is_a($value, 'MDB2_Result');
  586. }
  587. // }}}
  588. // {{{ function isResultCommon($value)
  589. /**
  590. * Tell whether a value is a MDB2 result implementing the common interface
  591. *
  592. * @param mixed value to test
  593. *
  594. * @return bool whether $value is a MDB2 result implementing the common interface
  595. *
  596. * @access public
  597. */
  598. function isResultCommon($value)
  599. {
  600. return is_a($value, 'MDB2_Result_Common');
  601. }
  602. // }}}
  603. // {{{ function isStatement($value)
  604. /**
  605. * Tell whether a value is a MDB2 statement interface
  606. *
  607. * @param mixed value to test
  608. *
  609. * @return bool whether $value is a MDB2 statement interface
  610. *
  611. * @access public
  612. */
  613. function isStatement($value)
  614. {
  615. return is_a($value, 'MDB2_Statement');
  616. }
  617. // }}}
  618. // {{{ function errorMessage($value = null)
  619. /**
  620. * Return a textual error message for a MDB2 error code
  621. *
  622. * @param int|array integer error code,
  623. null to get the current error code-message map,
  624. or an array with a new error code-message map
  625. *
  626. * @return string error message, or false if the error code was
  627. * not recognized
  628. *
  629. * @access public
  630. */
  631. function errorMessage($value = null)
  632. {
  633. static $errorMessages;
  634. if (is_array($value)) {
  635. $errorMessages = $value;
  636. return MDB2_OK;
  637. }
  638. if (!isset($errorMessages)) {
  639. $errorMessages = array(
  640. MDB2_OK => 'no error',
  641. MDB2_ERROR => 'unknown error',
  642. MDB2_ERROR_ALREADY_EXISTS => 'already exists',
  643. MDB2_ERROR_CANNOT_CREATE => 'can not create',
  644. MDB2_ERROR_CANNOT_ALTER => 'can not alter',
  645. MDB2_ERROR_CANNOT_REPLACE => 'can not replace',
  646. MDB2_ERROR_CANNOT_DELETE => 'can not delete',
  647. MDB2_ERROR_CANNOT_DROP => 'can not drop',
  648. MDB2_ERROR_CONSTRAINT => 'constraint violation',
  649. MDB2_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
  650. MDB2_ERROR_DIVZERO => 'division by zero',
  651. MDB2_ERROR_INVALID => 'invalid',
  652. MDB2_ERROR_INVALID_DATE => 'invalid date or time',
  653. MDB2_ERROR_INVALID_NUMBER => 'invalid number',
  654. MDB2_ERROR_MISMATCH => 'mismatch',
  655. MDB2_ERROR_NODBSELECTED => 'no database selected',
  656. MDB2_ERROR_NOSUCHFIELD => 'no such field',
  657. MDB2_ERROR_NOSUCHTABLE => 'no such table',
  658. MDB2_ERROR_NOT_CAPABLE => 'MDB2 backend not capable',
  659. MDB2_ERROR_NOT_FOUND => 'not found',
  660. MDB2_ERROR_NOT_LOCKED => 'not locked',
  661. MDB2_ERROR_SYNTAX => 'syntax error',
  662. MDB2_ERROR_UNSUPPORTED => 'not supported',
  663. MDB2_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
  664. MDB2_ERROR_INVALID_DSN => 'invalid DSN',
  665. MDB2_ERROR_CONNECT_FAILED => 'connect failed',
  666. MDB2_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
  667. MDB2_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
  668. MDB2_ERROR_NOSUCHDB => 'no such database',
  669. MDB2_ERROR_ACCESS_VIOLATION => 'insufficient permissions',
  670. MDB2_ERROR_LOADMODULE => 'error while including on demand module',
  671. MDB2_ERROR_TRUNCATED => 'truncated',
  672. MDB2_ERROR_DEADLOCK => 'deadlock detected',
  673. );
  674. }
  675. if (is_null($value)) {
  676. return $errorMessages;
  677. }
  678. if (PEAR::isError($value)) {
  679. $value = $value->getCode();
  680. }
  681. return isset($errorMessages[$value]) ?
  682. $errorMessages[$value] : $errorMessages[MDB2_ERROR];
  683. }
  684. // }}}
  685. // {{{ function parseDSN($dsn)
  686. /**
  687. * Parse a data source name.
  688. *
  689. * Additional keys can be added by appending a URI query string to the
  690. * end of the DSN.
  691. *
  692. * The format of the supplied DSN is in its fullest form:
  693. * <code>
  694. * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
  695. * </code>
  696. *
  697. * Most variations are allowed:
  698. * <code>
  699. * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
  700. * phptype://username:password@hostspec/database_name
  701. * phptype://username:password@hostspec
  702. * phptype://username@hostspec
  703. * phptype://hostspec/database
  704. * phptype://hostspec
  705. * phptype(dbsyntax)
  706. * phptype
  707. * </code>
  708. *
  709. * @param string Data Source Name to be parsed
  710. *
  711. * @return array an associative array with the following keys:
  712. * + phptype: Database backend used in PHP (mysql, odbc etc.)
  713. * + dbsyntax: Database used with regards to SQL syntax etc.
  714. * + protocol: Communication protocol to use (tcp, unix etc.)
  715. * + hostspec: Host specification (hostname[:port])
  716. * + database: Database to use on the DBMS server
  717. * + username: User name for login
  718. * + password: Password for login
  719. *
  720. * @access public
  721. * @author Tomas V.V.Cox <cox@idecnet.com>
  722. */
  723. function parseDSN($dsn)
  724. {
  725. $parsed = $GLOBALS['_MDB2_dsninfo_default'];
  726. if (is_array($dsn)) {
  727. $dsn = array_merge($parsed, $dsn);
  728. if (!$dsn['dbsyntax']) {
  729. $dsn['dbsyntax'] = $dsn['phptype'];
  730. }
  731. return $dsn;
  732. }
  733. // Find phptype and dbsyntax
  734. if (($pos = strpos($dsn, '://')) !== false) {
  735. $str = substr($dsn, 0, $pos);
  736. $dsn = substr($dsn, $pos + 3);
  737. } else {
  738. $str = $dsn;
  739. $dsn = null;
  740. }
  741. // Get phptype and dbsyntax
  742. // $str => phptype(dbsyntax)
  743. if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
  744. $parsed['phptype'] = $arr[1];
  745. $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
  746. } else {
  747. $parsed['phptype'] = $str;
  748. $parsed['dbsyntax'] = $str;
  749. }
  750. if (!count($dsn)) {
  751. return $parsed;
  752. }
  753. // Get (if found): username and password
  754. // $dsn => username:password@protocol+hostspec/database
  755. if (($at = strrpos($dsn,'@')) !== false) {
  756. $str = substr($dsn, 0, $at);
  757. $dsn = substr($dsn, $at + 1);
  758. if (($pos = strpos($str, ':')) !== false) {
  759. $parsed['username'] = rawurldecode(substr($str, 0, $pos));
  760. $parsed['password'] = rawurldecode(substr($str, $pos + 1));
  761. } else {
  762. $parsed['username'] = rawurldecode($str);
  763. }
  764. }
  765. // Find protocol and hostspec
  766. // $dsn => proto(proto_opts)/database
  767. if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
  768. $proto = $match[1];
  769. $proto_opts = $match[2] ? $match[2] : false;
  770. $dsn = $match[3];
  771. // $dsn => protocol+hostspec/database (old format)
  772. } else {
  773. if (strpos($dsn, '+') !== false) {
  774. list($proto, $dsn) = explode('+', $dsn, 2);
  775. }
  776. if ( strpos($dsn, '//') === 0
  777. && strpos($dsn, '/', 2) !== false
  778. && $parsed['phptype'] == 'oci8'
  779. ) {
  780. //oracle's "Easy Connect" syntax:
  781. //"username/password@[//]host[:port][/service_name]"
  782. //e.g. "scott/tiger@//mymachine:1521/oracle"
  783. $proto_opts = $dsn;
  784. $dsn = null;
  785. } elseif (strpos($dsn, '/') !== false) {
  786. list($proto_opts, $dsn) = explode('/', $dsn, 2);
  787. } else {
  788. $proto_opts = $dsn;
  789. $dsn = null;
  790. }
  791. }
  792. // process the different protocol options
  793. $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
  794. $proto_opts = rawurldecode($proto_opts);
  795. if (strpos($proto_opts, ':') !== false) {
  796. list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
  797. }
  798. if ($parsed['protocol'] == 'tcp') {
  799. $parsed['hostspec'] = $proto_opts;
  800. } elseif ($parsed['protocol'] == 'unix') {
  801. $parsed['socket'] = $proto_opts;
  802. }
  803. // Get dabase if any
  804. // $dsn => database
  805. if ($dsn) {
  806. // /database
  807. if (($pos = strpos($dsn, '?')) === false) {
  808. $parsed['database'] = $dsn;
  809. // /database?param1=value1&param2=value2
  810. } else {
  811. $parsed['database'] = substr($dsn, 0, $pos);
  812. $dsn = substr($dsn, $pos + 1);
  813. if (strpos($dsn, '&') !== false) {
  814. $opts = explode('&', $dsn);
  815. } else { // database?param1=value1
  816. $opts = array($dsn);
  817. }
  818. foreach ($opts as $opt) {
  819. list($key, $value) = explode('=', $opt);
  820. if (!isset($parsed[$key])) {
  821. // don't allow params overwrite
  822. $parsed[$key] = rawurldecode($value);
  823. }
  824. }
  825. }
  826. }
  827. return $parsed;
  828. }
  829. // }}}
  830. // {{{ function fileExists($file)
  831. /**
  832. * Checks if a file exists in the include path
  833. *
  834. * @param string filename
  835. *
  836. * @return bool true success and false on error
  837. *
  838. * @access public
  839. */
  840. function fileExists($file)
  841. {
  842. // safe_mode does notwork with is_readable()
  843. if (!@ini_get('safe_mode')) {
  844. $dirs = explode(PATH_SEPARATOR, ini_get('include_path'));
  845. foreach ($dirs as $dir) {
  846. if (is_readable($dir . DIRECTORY_SEPARATOR . $file)) {
  847. return true;
  848. }
  849. }
  850. } else {
  851. $fp = @fopen($file, 'r', true);
  852. if (is_resource($fp)) {
  853. @fclose($fp);
  854. return true;
  855. }
  856. }
  857. return false;
  858. }
  859. // }}}
  860. }
  861. // }}}
  862. // {{{ class MDB2_Error extends PEAR_Error
  863. /**
  864. * MDB2_Error implements a class for reporting portable database error
  865. * messages.
  866. *
  867. * @package MDB2
  868. * @category Database
  869. * @author Stig Bakken <ssb@fast.no>
  870. */
  871. class MDB2_Error extends PEAR_Error
  872. {
  873. // {{{ constructor: function MDB2_Error($code = MDB2_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null)
  874. /**
  875. * MDB2_Error constructor.
  876. *
  877. * @param mixed MDB2 error code, or string with error message.
  878. * @param int what 'error mode' to operate in
  879. * @param int what error level to use for $mode & PEAR_ERROR_TRIGGER
  880. * @param smixed additional debug info, such as the last query
  881. */
  882. function MDB2_Error($code = MDB2_ERROR, $mode = PEAR_ERROR_RETURN,
  883. $level = E_USER_NOTICE, $debuginfo = null)
  884. {
  885. if (is_null($code)) {
  886. $code = MDB2_ERROR;
  887. }
  888. $this->PEAR_Error('MDB2 Error: '.MDB2::errorMessage($code), $code,
  889. $mode, $level, $debuginfo);
  890. }
  891. // }}}
  892. }
  893. // }}}
  894. // {{{ class MDB2_Driver_Common extends PEAR
  895. /**
  896. * MDB2_Driver_Common: Base class that is extended by each MDB2 driver
  897. *
  898. * @package MDB2
  899. * @category Database
  900. * @author Lukas Smith <smith@pooteeweet.org>
  901. */
  902. class MDB2_Driver_Common extends PEAR
  903. {
  904. // {{{ Variables (Properties)
  905. /**
  906. * index of the MDB2 object within the $GLOBALS['_MDB2_databases'] array
  907. * @var int
  908. * @access public
  909. */
  910. var $db_index = 0;
  911. /**
  912. * DSN used for the next query
  913. * @var array
  914. * @access protected
  915. */
  916. var $dsn = array();
  917. /**
  918. * DSN that was used to create the current connection
  919. * @var array
  920. * @access protected
  921. */
  922. var $connected_dsn = array();
  923. /**
  924. * connection resource
  925. * @var mixed
  926. * @access protected
  927. */
  928. var $connection = 0;
  929. /**
  930. * if the current opened connection is a persistent connection
  931. * @var bool
  932. * @access protected
  933. */
  934. var $opened_persistent;
  935. /**
  936. * the name of the database for the next query
  937. * @var string
  938. * @access protected
  939. */
  940. var $database_name = '';
  941. /**
  942. * the name of the database currently selected
  943. * @var string
  944. * @access protected
  945. */
  946. var $connected_database_name = '';
  947. /**
  948. * server version information
  949. * @var string
  950. * @access protected
  951. */
  952. var $connected_server_info = '';
  953. /**
  954. * list of all supported features of the given driver
  955. * @var array
  956. * @access public
  957. */
  958. var $supported = array(
  959. 'sequences' => false,
  960. 'indexes' => false,
  961. 'affected_rows' => false,
  962. 'summary_functions' => false,
  963. 'order_by_text' => false,
  964. 'transactions' => false,
  965. 'savepoints' => false,
  966. 'current_id' => false,
  967. 'limit_queries' => false,
  968. 'LOBs' => false,
  969. 'replace' => false,
  970. 'sub_selects' => false,
  971. 'auto_increment' => false,
  972. 'primary_key' => false,
  973. 'result_introspection' => false,
  974. 'prepared_statements' => false,
  975. 'identifier_quoting' => false,
  976. 'pattern_escaping' => false,
  977. 'new_link' => false,
  978. );
  979. /**
  980. * Array of supported options that can be passed to the MDB2 instance.
  981. *
  982. * The options can be set during object creation, using
  983. * MDB2::connect(), MDB2::factory() or MDB2::singleton(). The options can
  984. * also be set after the object is created, using MDB2::setOptions() or
  985. * MDB2_Driver_Common::setOption().
  986. * The list of available option includes:
  987. * <ul>
  988. * <li>$options['ssl'] -> boolean: determines if ssl should be used for connections</li>
  989. * <li>$options['field_case'] -> CASE_LOWER|CASE_UPPER: determines what case to force on field/table names</li>
  990. * <li>$options['disable_query'] -> boolean: determines if queries should be executed</li>
  991. * <li>$options['result_class'] -> string: class used for result sets</li>
  992. * <li>$options['buffered_result_class'] -> string: class used for buffered result sets</li>
  993. * <li>$options['result_wrap_class'] -> string: class used to wrap result sets into</li>
  994. * <li>$options['result_buffering'] -> boolean should results be buffered or not?</li>
  995. * <li>$options['fetch_class'] -> string: class to use when fetch mode object is used</li>
  996. * <li>$options['persistent'] -> boolean: persistent connection?</li>
  997. * <li>$options['debug'] -> integer: numeric debug level</li>
  998. * <li>$options['debug_handler'] -> string: function/method that captures debug messages</li>
  999. * <li>$options['debug_expanded_output'] -> bool: BC option to determine if more context information should be send to the debug handler</li>
  1000. * <li>$options['default_text_field_length'] -> integer: default text field length to use</li>
  1001. * <li>$options['lob_buffer_length'] -> integer: LOB buffer length</li>
  1002. * <li>$options['log_line_break'] -> string: line-break format</li>
  1003. * <li>$options['idxname_format'] -> string: pattern for index name</li>
  1004. * <li>$options['seqname_format'] -> string: pattern for sequence name</li>
  1005. * <li>$options['savepoint_format'] -> string: pattern for auto generated savepoint names</li>
  1006. * <li>$options['statement_format'] -> string: pattern for prepared statement names</li>
  1007. * <li>$options['seqcol_name'] -> string: sequence column name</li>
  1008. * <li>$options['quote_identifier'] -> boolean: if identifier quoting should be done when check_option is used</li>
  1009. * <li>$options['use_transactions'] -> boolean: if transaction use should be enabled</li>
  1010. * <li>$options['decimal_places'] -> integer: number of decimal places to handle</li>
  1011. * <li>$options['portability'] -> integer: portability constant</li>
  1012. * <li>$options['modules'] -> array: short to long module name mapping for __call()</li>
  1013. * <li>$options['emulate_prepared'] -> boolean: force prepared statements to be emulated</li>
  1014. * <li>$options['datatype_map'] -> array: map user defined datatypes to other primitive datatypes</li>
  1015. * <li>$options['datatype_map_callback'] -> array: callback function/method that should be called</li>
  1016. * </ul>
  1017. *
  1018. * @var array
  1019. * @access public
  1020. * @see MDB2::connect()
  1021. * @see MDB2::factory()
  1022. * @see MDB2::singleton()
  1023. * @see MDB2_Driver_Common::setOption()
  1024. */
  1025. var $options = array(
  1026. 'ssl' => false,
  1027. 'field_case' => CASE_LOWER,
  1028. 'disable_query' => false,
  1029. 'result_class' => 'MDB2_Result_%s',
  1030. 'buffered_result_class' => 'MDB2_BufferedResult_%s',
  1031. 'result_wrap_class' => false,
  1032. 'result_buffering' => true,
  1033. 'fetch_class' => 'stdClass',
  1034. 'persistent' => false,
  1035. 'debug' => 0,
  1036. 'debug_handler' => 'MDB2_defaultDebugOutput',
  1037. 'debug_expanded_output' => false,
  1038. 'default_text_field_length' => 4096,
  1039. 'lob_buffer_length' => 8192,
  1040. 'log_line_break' => "\n",
  1041. 'idxname_format' => '%s_idx',
  1042. 'seqname_format' => '%s_seq',
  1043. 'savepoint_format' => 'MDB2_SAVEPOINT_%s',
  1044. 'statement_format' => 'MDB2_STATEMENT_%1$s_%2$s',
  1045. 'seqcol_name' => 'sequence',
  1046. 'quote_identifier' => false,
  1047. 'use_transactions' => true,
  1048. 'decimal_places' => 2,
  1049. 'portability' => MDB2_PORTABILITY_ALL,
  1050. 'modules' => array(
  1051. 'ex' => 'Extended',
  1052. 'dt' => 'Datatype',
  1053. 'mg' => 'Manager',
  1054. 'rv' => 'Reverse',
  1055. 'na' => 'Native',
  1056. 'fc' => 'Function',
  1057. ),
  1058. 'emulate_prepared' => false,
  1059. 'datatype_map' => array(),
  1060. 'datatype_map_callback' => array(),
  1061. 'nativetype_map_callback' => array(),
  1062. );
  1063. /**
  1064. * string array
  1065. * @var string
  1066. * @access protected
  1067. */
  1068. var $string_quoting = array('start' => "'", 'end' => "'", 'escape' => false, 'escape_pattern' => false);
  1069. /**
  1070. * identifier quoting
  1071. * @var array
  1072. * @access protected
  1073. */
  1074. var $identifier_quoting = array('start' => '"', 'end' => '"', 'escape' => '"');
  1075. /**
  1076. * sql comments
  1077. * @var array
  1078. * @access protected
  1079. */
  1080. var $sql_comments = array(
  1081. array('start' => '--', 'end' => "\n", 'escape' => false),
  1082. array('start' => '/*', 'end' => '*/', 'escape' => false),
  1083. );
  1084. /**
  1085. * comparision wildcards
  1086. * @var array
  1087. * @access protected
  1088. */
  1089. var $wildcards = array('%', '_');
  1090. /**
  1091. * column alias keyword
  1092. * @var string
  1093. * @access protected
  1094. */
  1095. var $as_keyword = ' AS ';
  1096. /**
  1097. * warnings
  1098. * @var array
  1099. * @access protected
  1100. */
  1101. var $warnings = array();
  1102. /**
  1103. * string with the debugging information
  1104. * @var string
  1105. * @access public
  1106. */
  1107. var $debug_output = '';
  1108. /**
  1109. * determine if there is an open transaction
  1110. * @var bool
  1111. * @access protected
  1112. */
  1113. var $in_transaction = false;
  1114. /**
  1115. * the smart transaction nesting depth
  1116. * @var int
  1117. * @access protected
  1118. */
  1119. var $nested_transaction_counter = null;
  1120. /**
  1121. * the first error that occured inside a nested transaction
  1122. * @var MDB2_Error|bool
  1123. * @access protected
  1124. */
  1125. var $has_transaction_error = false;
  1126. /**
  1127. * result offset used in the next query
  1128. * @var int
  1129. * @access protected
  1130. */
  1131. var $offset = 0;
  1132. /**
  1133. * result limit used in the next query
  1134. * @var int
  1135. * @access protected
  1136. */
  1137. var $limit = 0;
  1138. /**
  1139. * Database backend used in PHP (mysql, odbc etc.)
  1140. * @var string
  1141. * @access public
  1142. */
  1143. var $phptype;
  1144. /**
  1145. * Database used with regards to SQL syntax etc.
  1146. * @var string
  1147. * @access public
  1148. */
  1149. var $dbsyntax;
  1150. /**
  1151. * the last query sent to the driver
  1152. * @var string
  1153. * @access public
  1154. */
  1155. var $last_query;
  1156. /**
  1157. * the default fetchmode used
  1158. * @var int
  1159. * @access protected
  1160. */
  1161. var $fetchmode = MDB2_FETCHMODE_ORDERED;
  1162. /**
  1163. * array of module instances
  1164. * @var array
  1165. * @access protected
  1166. */
  1167. var $modules = array();
  1168. /**
  1169. * determines of the PHP4 destructor emulation has been enabled yet
  1170. * @var array
  1171. * @access protected
  1172. */
  1173. var $destructor_registered = true;
  1174. // }}}
  1175. // {{{ constructor: function __construct()
  1176. /**
  1177. * Constructor
  1178. */
  1179. function __construct()
  1180. {
  1181. end($GLOBALS['_MDB2_databases']);
  1182. $db_index = key($GLOBALS['_MDB2_databases']) + 1;
  1183. $GLOBALS['_MDB2_databases'][$db_index] = &$this;
  1184. $this->db_index = $db_index;
  1185. }
  1186. // }}}
  1187. // {{{ function MDB2_Driver_Common()
  1188. /**
  1189. * PHP 4 Constructor
  1190. */
  1191. function MDB2_Driver_Common()
  1192. {
  1193. $this->destructor_registered = false;
  1194. $this->__construct();
  1195. }
  1196. // }}}
  1197. // {{{ destructor: function __destruct()
  1198. /**
  1199. * Destructor
  1200. */
  1201. function __destruct()
  1202. {
  1203. $this->disconnect(false);
  1204. }
  1205. // }}}
  1206. // {{{ function free()
  1207. /**
  1208. * Free the internal references so that the instance can be destroyed
  1209. *
  1210. * @return bool true on success, false if result is invalid
  1211. *
  1212. * @access public
  1213. */
  1214. function free()
  1215. {
  1216. unset($GLOBALS['_MDB2_databases'][$this->db_index]);
  1217. unset($this->db_index);
  1218. return MDB2_OK;
  1219. }
  1220. // }}}
  1221. // {{{ function __toString()
  1222. /**
  1223. * String conversation
  1224. *
  1225. * @return string representation of the object
  1226. *
  1227. * @access public
  1228. */
  1229. function __toString()
  1230. {
  1231. $info = get_class($this);
  1232. $info.= ': (phptype = '.$this->phptype.', dbsyntax = '.$this->dbsyntax.')';
  1233. if ($this->connection) {
  1234. $info.= ' [connected]';
  1235. }
  1236. return $info;
  1237. }
  1238. // }}}
  1239. // {{{ function errorInfo($error = null)
  1240. /**
  1241. * This method is used to collect information about an error
  1242. *
  1243. * @param mixed error code or resource
  1244. *
  1245. * @return array with MDB2 errorcode, native error code, native message
  1246. *
  1247. * @access public
  1248. */
  1249. function errorInfo($error = null)
  1250. {
  1251. return array($error, null, null);
  1252. }
  1253. // }}}
  1254. // {{{ function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
  1255. /**
  1256. * This method is used to communicate an error and invoke error
  1257. * callbacks etc. Basically a wrapper for PEAR::raiseError
  1258. * without the message string.
  1259. *
  1260. * @param mixed integer error code, or a PEAR error object (all other
  1261. * parameters are ignored if this parameter is an object
  1262. * @param int error mode, see PEAR_Error docs
  1263. * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
  1264. * error level (E_USER_NOTICE etc). If error mode is
  1265. * PEAR_ERROR_CALLBACK, this is the callback function,
  1266. * either as a function name, or as an array of an
  1267. * object and method name. For other error modes this
  1268. * parameter is ignored.
  1269. * @param string Extra debug information. Defaults to the last
  1270. * query and native error code.
  1271. * @param string name of the method that triggered the error
  1272. *
  1273. * @return PEAR_Error instance of a PEAR Error object
  1274. *
  1275. * @access public
  1276. * @see PEAR_Error
  1277. */
  1278. function &raiseError($code = null, $mode = null, $options = null, $userinfo = null, $method = null)
  1279. {
  1280. $userinfo = "[Error message: $userinfo]\n";
  1281. // The error is yet a MDB2 error object
  1282. if (PEAR::isError($code)) {
  1283. // because we use the static PEAR::raiseError, our global
  1284. // handler should be used if it is set
  1285. if (is_null($mode) && !empty($this->_default_error_mode)) {
  1286. $mode = $this->_default_error_mode;
  1287. $options = $this->_default_error_options;
  1288. }
  1289. if (is_null($userinfo)) {
  1290. $userinfo = $code->getUserinfo();
  1291. }
  1292. $code = $code->getCode();
  1293. } elseif ($code == MDB2_ERROR_NOT_FOUND) {
  1294. // extension not loaded: don't call $this->errorInfo() or the script
  1295. // will die
  1296. } elseif (isset($this->connection)) {
  1297. if (!empty($this->last_query)) {
  1298. $userinfo.= "[Last executed query: {$this->last_query}]\n";
  1299. }
  1300. $native_errno = $native_msg = null;
  1301. list($code, $native_errno, $native_msg) = $this->errorInfo($code);
  1302. if (!is_null($native_errno) && $native_errno !== '') {
  1303. $userinfo.= "[Native code: $native_errno]\n";
  1304. }
  1305. if (!is_null($native_msg) && $native_msg !== '') {
  1306. $userinfo.= "[Native message: ". strip_tags($native_msg) ."]\n";
  1307. }
  1308. if (!is_null($method)) {
  1309. $userinfo = $method.': '.$userinfo;
  1310. }
  1311. }
  1312. $err =& PEAR::raiseError(null, $code, $mode, $options, $userinfo, 'MDB2_Error', true);
  1313. if ($err->getMode() !== PEAR_ERROR_RETURN
  1314. && isset($this->nested_transaction_counter) && !$this->has_transaction_error) {
  1315. $this->has_transaction_error =& $err;
  1316. }
  1317. return $err;
  1318. }
  1319. // }}}
  1320. // {{{ function resetWarnings()
  1321. /**
  1322. * reset the warning array
  1323. *
  1324. * @return void
  1325. *
  1326. * @access public
  1327. */
  1328. function resetWarnings()
  1329. {
  1330. $this->warnings = array();
  1331. }
  1332. // }}}
  1333. // {{{ function getWarnings()
  1334. /**
  1335. * Get all warnings in reverse order.
  1336. * This means that the last warning is the first element in the array
  1337. *
  1338. * @return array with warnings
  1339. *
  1340. * @access public
  1341. * @see resetWarnings()
  1342. */
  1343. function getWarnings()
  1344. {
  1345. return array_reverse($this->warnings);
  1346. }
  1347. // }}}
  1348. // {{{ function setFetchMode($fetchmode, $object_class = 'stdClass')
  1349. /**
  1350. * Sets which fetch mode should be used by default on queries
  1351. * on this connection
  1352. *
  1353. * @param int MDB2_FETCHMODE_ORDERED, MDB2_FETCHMODE_ASSOC
  1354. * or MDB2_FETCHMODE_OBJECT
  1355. * @param string the class name of the object to be returned
  1356. * by the fetch methods when the
  1357. * MDB2_FETCHMODE_OBJECT mode is selected.
  1358. * If no class is specified by default a cast
  1359. * to object from the assoc array row will be
  1360. * done. There is also the possibility to use
  1361. * and extend the 'MDB2_row' class.
  1362. *
  1363. * @return mixed MDB2_OK or MDB2 Error Object
  1364. *
  1365. * @access public
  1366. * @see MDB2_FETCHMODE_ORDERED, MDB2_FETCHMODE_ASSOC, MDB2_FETCHMODE_OBJECT
  1367. */
  1368. function setFetchMode($fetchmode, $object_class = 'stdClass')
  1369. {
  1370. switch ($fetchmode) {
  1371. case MDB2_FETCHMODE_OBJECT:
  1372. $this->options['fetch_class'] = $object_class;
  1373. case MDB2_FETCHMODE_ORDERED:
  1374. case MDB2_FETCHMODE_ASS

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