PageRenderTime 59ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/php/MDB/Common.php

https://bitbucket.org/adarshj/convenient_website
PHP | 4548 lines | 2288 code | 280 blank | 1980 comment | 200 complexity | b5919951d8cbc52bf61e8d78d62b2a88 MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-2-Clause, GPL-2.0, LGPL-3.0
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP Version 4 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
  6. // | Stig. S. Bakken, Lukas Smith |
  7. // | All rights reserved. |
  8. // +----------------------------------------------------------------------+
  9. // | MDB is a merge of PEAR DB and Metabases that provides a unified DB |
  10. // | API as well as database abstraction for PHP applications. |
  11. // | This LICENSE is in the BSD license style. |
  12. // | |
  13. // | Redistribution and use in source and binary forms, with or without |
  14. // | modification, are permitted provided that the following conditions |
  15. // | are met: |
  16. // | |
  17. // | Redistributions of source code must retain the above copyright |
  18. // | notice, this list of conditions and the following disclaimer. |
  19. // | |
  20. // | Redistributions in binary form must reproduce the above copyright |
  21. // | notice, this list of conditions and the following disclaimer in the |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // | |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission. |
  28. // | |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
  40. // | POSSIBILITY OF SUCH DAMAGE. |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@backendmedia.com> |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: Common.php,v 1.114.4.22 2004/04/08 19:11:58 lsmith Exp $
  46. /**
  47. * @package MDB
  48. * @author Lukas Smith <smith@backendmedia.com>
  49. */
  50. // }}}
  51. // {{{ MDB_defaultDebugOutput()
  52. /**
  53. * default debug output handler
  54. *
  55. * @param object $db reference to an MDB database object
  56. * @param string $message message that should be appended to the debug
  57. * variable
  58. * @return string the corresponding error message, of FALSE
  59. * if the error code was unknown
  60. * @access public
  61. */
  62. function MDB_defaultDebugOutput(&$db, $message)
  63. {
  64. $db->debug_output .= $db->database . " $message" . $db->getOption('log_line_break');
  65. }
  66. /**
  67. * MDB_Common: Base class that is extended by each MDB driver
  68. *
  69. * @package MDB
  70. * @category Database
  71. * @author Lukas Smith <smith@backendmedia.com>
  72. */
  73. class MDB_Common extends PEAR
  74. {
  75. // {{{ properties
  76. /**
  77. * index of the MDB object withing the global $_MDB_databases array
  78. * @var integer
  79. * @access private
  80. */
  81. var $database = 0;
  82. /**
  83. * @var string
  84. * @access private
  85. */
  86. var $host = '';
  87. /**
  88. * @var string
  89. * @access private
  90. */
  91. var $port = '';
  92. /**
  93. * @var string
  94. * @access private
  95. */
  96. var $user = '';
  97. /**
  98. * @var string
  99. * @access private
  100. */
  101. var $password = '';
  102. /**
  103. * @var string
  104. * @access private
  105. */
  106. var $database_name = '';
  107. /**
  108. * @var array
  109. * @access private
  110. */
  111. var $supported = array();
  112. /**
  113. * $options["persistent"] -> boolean persistent connection true|false?
  114. * $options["debug"] -> integer numeric debug level
  115. * $options["autofree"] -> boolean
  116. * $options["lob_buffer_length"] -> integer LOB buffer length
  117. * $options["log_line_break"] -> string line-break format
  118. * $options["seqname_format"] -> string pattern for sequence name
  119. * $options["includelob"] -> boolean
  120. * $options["includemanager"] -> boolean
  121. * $options["UseTransactions"] -> boolean
  122. * $options["optimize"] -> string 'performance' or 'portability'
  123. * @var array
  124. * @access private
  125. */
  126. var $options = array(
  127. 'persistent' => FALSE,
  128. 'debug' => FALSE,
  129. 'autofree' => FALSE,
  130. 'lob_buffer_length' => 8192,
  131. 'log_line_break' => "\n",
  132. 'seqname_format' => '%s_seq',
  133. 'sequence_col_name' => 'sequence',
  134. 'includelob' => FALSE,
  135. 'includemanager' => FALSE,
  136. 'UseTransactions' => FALSE,
  137. 'optimize' => 'performance',
  138. );
  139. /**
  140. * @var string
  141. * @access private
  142. */
  143. var $escape_quotes = '';
  144. /**
  145. * @var integer
  146. * @access private
  147. */
  148. var $decimal_places = 2;
  149. /**
  150. * @var string
  151. * @access private
  152. */
  153. var $manager_included_constant = '';
  154. /**
  155. * @var string
  156. * @access private
  157. */
  158. var $manager_include = '';
  159. /**
  160. * @var string
  161. * @access private
  162. */
  163. var $manager_class_name = '';
  164. /**
  165. * @var object
  166. * @access private
  167. */
  168. var $manager;
  169. /**
  170. * @var array
  171. * @access private
  172. */
  173. var $warnings = array();
  174. /**
  175. * @var string
  176. * @access private
  177. */
  178. var $debug = '';
  179. /**
  180. * @var string
  181. * @access private
  182. */
  183. var $debug_output = '';
  184. /**
  185. * @var boolean
  186. * @access private
  187. */
  188. var $pass_debug_handle = FALSE;
  189. /**
  190. * @var boolean
  191. * @access private
  192. */
  193. var $auto_commit = TRUE;
  194. /**
  195. * @var boolean
  196. * @access private
  197. */
  198. var $in_transaction = FALSE;
  199. /**
  200. * @var integer
  201. * @access private
  202. */
  203. var $first_selected_row = 0;
  204. /**
  205. * @var integer
  206. * @access private
  207. */
  208. var $selected_row_limit = 0;
  209. /**
  210. * DB type (mysql, oci8, odbc etc.)
  211. * @var string
  212. * @access private
  213. */
  214. var $type;
  215. /**
  216. * @var array
  217. * @access private
  218. */
  219. var $prepared_queries = array();
  220. /**
  221. * @var array
  222. * @access private
  223. */
  224. var $result_types;
  225. /**
  226. * @var string
  227. * @access private
  228. */
  229. var $last_query = '';
  230. /**
  231. * @var integer
  232. * @access private
  233. */
  234. var $fetchmode = MDB_FETCHMODE_ORDERED;
  235. /**
  236. * @var integer
  237. * @access private
  238. */
  239. var $affected_rows = -1;
  240. /**
  241. * @var array
  242. * @access private
  243. */
  244. var $lobs = array();
  245. /**
  246. * @var array
  247. * @access private
  248. */
  249. var $clobs = array();
  250. /**
  251. * @var array
  252. * @access private
  253. */
  254. var $blobs = array();
  255. // }}}
  256. // {{{ constructor
  257. /**
  258. * Constructor
  259. */
  260. function MDB_Common()
  261. {
  262. $database = count($GLOBALS['_MDB_databases']) + 1;
  263. $GLOBALS['_MDB_databases'][$database] = &$this;
  264. $this->database = $database;
  265. $this->PEAR('MDB_Error');
  266. $this->supported = array();
  267. $this->errorcode_map = array();
  268. $this->fetchmode = MDB_FETCHMODE_ORDERED;
  269. }
  270. // }}}
  271. // {{{ __toString()
  272. /**
  273. * String conversation
  274. *
  275. * @return string
  276. * @access public
  277. */
  278. function __toString()
  279. {
  280. $info = get_class($this);
  281. $info .= ': (phptype = ' . $this->phptype . ', dbsyntax = ' . $this->dbsyntax . ')';
  282. if ($this->connection) {
  283. $info .= ' [connected]';
  284. }
  285. return($info);
  286. }
  287. // }}}
  288. // {{{ errorCode()
  289. /**
  290. * Map native error codes to MDB's portable ones. Requires that
  291. * the DB implementation's constructor fills in the $errorcode_map
  292. * property.
  293. *
  294. * @param mixed $nativecode the native error code, as returned by the
  295. * backend database extension (string or integer)
  296. * @return int a portable MDB error code, or FALSE if this MDB
  297. * implementation has no mapping for the given error code.
  298. * @access public
  299. */
  300. function errorCode($nativecode)
  301. {
  302. if (isset($this->errorcode_map[$nativecode])) {
  303. return($this->errorcode_map[$nativecode]);
  304. }
  305. // Fall back to MDB_ERROR if there was no mapping.
  306. return(MDB_ERROR);
  307. }
  308. // }}}
  309. // {{{ errorMessage()
  310. /**
  311. * Map a MDB error code to a textual message. This is actually
  312. * just a wrapper for MDB::errorMessage().
  313. *
  314. * @param integer $dbcode the MDB error code
  315. * @return string the corresponding error message, of FALSE
  316. * if the error code was unknown
  317. * @access public
  318. */
  319. function errorMessage($dbcode)
  320. {
  321. return(MDB::errorMessage($this->errorcode_map[$dbcode]));
  322. }
  323. // }}}
  324. // {{{ raiseError()
  325. /**
  326. * This method is used to communicate an error and invoke error
  327. * callbacks etc. Basically a wrapper for PEAR::raiseError
  328. * without the message string.
  329. *
  330. * @param mixed $code integer error code, or a PEAR error object (all
  331. * other parameters are ignored if this parameter is an object
  332. * @param int $mode error mode, see PEAR_Error docs
  333. * @param mixed $options If error mode is PEAR_ERROR_TRIGGER, this is the
  334. * error level (E_USER_NOTICE etc). If error mode is
  335. * PEAR_ERROR_CALLBACK, this is the callback function, either as a
  336. * function name, or as an array of an object and method name. For
  337. * other error modes this parameter is ignored.
  338. * @param string $userinfo Extra debug information. Defaults to the last
  339. * query and native error code.
  340. * @param mixed $nativecode Native error code, integer or string depending
  341. * the backend.
  342. * @return object a PEAR error object
  343. * @access public
  344. * @see PEAR_Error
  345. */
  346. function &raiseError($code = MDB_ERROR, $mode = NULL, $options = NULL,
  347. $userinfo = NULL, $nativecode = NULL)
  348. {
  349. // The error is yet a MDB error object
  350. if (is_object($code)) {
  351. // because we the static PEAR::raiseError, our global
  352. // handler should be used if it is set
  353. if ($mode === null && !empty($this->_default_error_mode)) {
  354. $mode = $this->_default_error_mode;
  355. $options = $this->_default_error_options;
  356. }
  357. $err = PEAR::raiseError($code, NULL, $mode, $options, NULL, NULL, TRUE);
  358. return($err);
  359. }
  360. if ($userinfo === NULL) {
  361. $userinfo = $this->last_query;
  362. }
  363. if ($nativecode) {
  364. $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
  365. }
  366. $err = PEAR::raiseError(NULL, $code, $mode, $options, $userinfo, 'MDB_Error', TRUE);
  367. return($err);
  368. }
  369. // }}}
  370. // {{{ errorNative()
  371. /**
  372. * returns an errormessage, provides by the database
  373. *
  374. * @return mixed MDB_Error or message
  375. * @access public
  376. */
  377. function errorNative()
  378. {
  379. return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
  380. }
  381. // }}}
  382. // {{{ resetWarnings()
  383. /**
  384. * reset the warning array
  385. *
  386. * @access public
  387. */
  388. function resetWarnings()
  389. {
  390. $this->warnings = array();
  391. }
  392. // }}}
  393. // {{{ getWarnings()
  394. /**
  395. * get all warnings in reverse order.
  396. * This means that the last warning is the first element in the array
  397. *
  398. * @return array with warnings
  399. * @access public
  400. * @see resetWarnings()
  401. */
  402. function getWarnings()
  403. {
  404. return array_reverse($this->warnings);
  405. }
  406. // }}}
  407. // {{{ setOption()
  408. /**
  409. * set the option for the db class
  410. *
  411. * @param string $option option name
  412. * @param mixed $value value for the option
  413. * @return mixed MDB_OK or MDB_Error
  414. * @access public
  415. */
  416. function setOption($option, $value)
  417. {
  418. if (isset($this->options[$option])) {
  419. $this->options[$option] = $value;
  420. return MDB_OK;
  421. }
  422. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
  423. }
  424. // }}}
  425. // {{{ getOption()
  426. /**
  427. * returns the value of an option
  428. *
  429. * @param string $option option name
  430. * @return mixed the option value or error object
  431. * @access public
  432. */
  433. function getOption($option)
  434. {
  435. if (isset($this->options[$option])) {
  436. return($this->options[$option]);
  437. }
  438. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
  439. }
  440. // }}}
  441. // {{{ captureDebugOutput()
  442. /**
  443. * set a debug handler
  444. *
  445. * @param string $capture name of the function that should be used in
  446. * debug()
  447. * @access public
  448. * @see debug()
  449. */
  450. function captureDebugOutput($capture)
  451. {
  452. $this->pass_debug_handle = $capture;
  453. $this->debug = ($capture ? 'MDB_defaultDebugOutput' : '');
  454. }
  455. // }}}
  456. // {{{ debug()
  457. /**
  458. * set a debug message
  459. *
  460. * @param string $message Message with information for the user.
  461. * @access public
  462. */
  463. function debug($message)
  464. {
  465. if (strcmp($function = $this->debug, '')) {
  466. if ($this->pass_debug_handle) {
  467. $function($this, $message);
  468. } else {
  469. $function($message);
  470. }
  471. }
  472. }
  473. // }}}
  474. // {{{ debugOutput()
  475. /**
  476. * output debug info
  477. *
  478. * @return string content of the debug_output class variable
  479. * @access public
  480. */
  481. function debugOutput()
  482. {
  483. return($this->debug_output);
  484. }
  485. // }}}
  486. // {{{ setError() (deprecated)
  487. /**
  488. * set an error (deprecated)
  489. *
  490. * @param string $scope Scope of the error message
  491. * (usually the method tht caused the error)
  492. * @param string $message Message with information for the user.
  493. * @return boolean FALSE
  494. * @access private
  495. */
  496. function setError($scope, $message)
  497. {
  498. $this->last_error = $message;
  499. $this->debug($scope . ': ' . $message);
  500. if (($function = $this->error_handler) != '') {
  501. $error = array(
  502. 'Scope' => $scope,
  503. 'Message' => $message
  504. );
  505. $function($this, $error);
  506. }
  507. return(0);
  508. }
  509. // }}}
  510. // {{{ setErrorHandler() (deprecated)
  511. /**
  512. * Specify a function that is called when an error occurs.
  513. *
  514. * @param string $function Name of the function that will be called on
  515. * error. If an empty string is specified, no handler function is
  516. * called on error. The error handler function receives two arguments.
  517. * The first argument a reference to the driver class object that
  518. * triggered the error.
  519. *
  520. * The second argument is a reference to an associative array that
  521. * provides details about the error that occured. These details provide
  522. * more information than it is returned by the MetabaseError function.
  523. *
  524. * These are the currently supported error detail entries:
  525. *
  526. * Scope
  527. * String that indicates the scope of the driver object class
  528. * within which the error occured.
  529. *
  530. * Message
  531. * Error message as is returned by the MetabaseError function.
  532. * @return string name of last function
  533. * @access public
  534. */
  535. function setErrorHandler($function)
  536. {
  537. $last_function = $this->error_handler;
  538. $this->error_handler = $function;
  539. return($last_function);
  540. }
  541. // }}}
  542. // {{{ error() (deprecated)
  543. /**
  544. * Retrieve the error message text associated with the last operation that
  545. * failed. Some functions may fail but they do not return the reason that
  546. * makes them to fail. This function is meant to retrieve a textual
  547. * description of the failure cause.
  548. *
  549. * @return string the error message text associated with the last failure.
  550. * @access public
  551. */
  552. function error()
  553. {
  554. return($this->last_error);
  555. }
  556. // }}}
  557. // {{{ _quote()
  558. /**
  559. * Quotes a string so it can be safely used in a query. It will quote
  560. * the text so it can safely be used within a query.
  561. *
  562. * @param string $text the input string to quote
  563. * @return string quoted string
  564. * @access private
  565. */
  566. function _quote($text)
  567. {
  568. if (strcmp($this->escape_quotes, "'")) {
  569. $text = str_replace($this->escape_quotes, $this->escape_quotes . $this->escape_quotes, $text);
  570. }
  571. return str_replace("'", $this->escape_quotes . "'", $text);
  572. }
  573. // }}}
  574. // {{{ quoteIdentifier()
  575. /**
  576. * Quote a string so it can be safely used as a table or column name
  577. *
  578. * Delimiting style depends on which database driver is being used.
  579. *
  580. * NOTE: just because you CAN use delimited identifiers doesn't mean
  581. * you SHOULD use them. In general, they end up causing way more
  582. * problems than they solve.
  583. *
  584. * Portability is broken by using the following characters inside
  585. * delimited identifiers:
  586. * + backtick (<kbd>`</kbd>) -- due to MySQL
  587. * + double quote (<kbd>"</kbd>) -- due to Oracle
  588. * + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
  589. *
  590. * Delimited identifiers are known to generally work correctly under
  591. * the following drivers:
  592. * + mssql
  593. * + mysql
  594. * + mysqli
  595. * + oci8
  596. * + odbc(access)
  597. * + odbc(db2)
  598. * + pgsql
  599. * + sqlite
  600. * + sybase
  601. *
  602. * InterBase doesn't seem to be able to use delimited identifiers
  603. * via PHP 4. They work fine under PHP 5.
  604. *
  605. * @param string $str identifier name to be quoted
  606. *
  607. * @return string quoted identifier string
  608. *
  609. * @access public
  610. */
  611. function quoteIdentifier($str)
  612. {
  613. return '"' . str_replace('"', '""', $str) . '"';
  614. }
  615. // }}}
  616. // {{{ _loadModule()
  617. /**
  618. * loads an module
  619. *
  620. * @param string $scope information about what method is being loaded,
  621. * that is used for error messages
  622. * @param string $module name of the module that should be loaded
  623. * (only used for error messages)
  624. * @param string $included_constant name of the constant that should be
  625. * defined when the module has been loaded
  626. * @param string $include name of the script that includes the module
  627. * @access private
  628. */
  629. function _loadModule($scope, $module, $included_constant, $include)
  630. {
  631. if (strlen($included_constant) == 0 || !defined($included_constant)) {
  632. if($include) {
  633. $include = 'MDB/Modules/'.$include;
  634. if(MDB::isError($debug = $this->getOption('debug')) || $debug > 2) {
  635. include_once($include);
  636. } else {
  637. @include_once($include);
  638. }
  639. } else {
  640. return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
  641. $scope . ': it was not specified an existing ' . $module . ' file (' . $include . ')'));
  642. }
  643. }
  644. return(MDB_OK);
  645. }
  646. // }}}
  647. // {{{ loadLob()
  648. /**
  649. * loads the LOB module
  650. *
  651. * @param string $scope information about what method is being loaded,
  652. * that is used for error messages
  653. * @access public
  654. */
  655. function loadLob($scope = '')
  656. {
  657. if (defined('MDB_LOB_INCLUDED')) {
  658. return(MDB_OK);
  659. }
  660. $result = $this->_loadModule($scope, 'LOB',
  661. 'MDB_LOB_INCLUDED', 'LOB.php');
  662. if (MDB::isError($result)) {
  663. return($result);
  664. }
  665. return(MDB_OK);
  666. }
  667. // }}}
  668. // {{{ loadManager()
  669. /**
  670. * loads the Manager module
  671. *
  672. * @param string $scope information about what method is being loaded,
  673. * that is used for error messages
  674. * @access public
  675. */
  676. function loadManager($scope = '')
  677. {
  678. if (isset($this->manager) && is_object($this->manager)) {
  679. return(MDB_OK);
  680. }
  681. $result = $this->_loadModule($scope, 'Manager',
  682. 'MDB_MANAGER_'.strtoupper($this->phptype).'_INCLUDED',
  683. 'Manager/'.$this->phptype.'.php');
  684. if (MDB::isError($result)) {
  685. return($result);
  686. }
  687. $class_name = 'MDB_Manager_'.$this->dbsyntax;
  688. if (!class_exists($class_name)) {
  689. return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
  690. 'Unable to load extension'));
  691. }
  692. @$this->manager = new $class_name;
  693. return(MDB_OK);
  694. }
  695. // }}}
  696. // {{{ autoCommit()
  697. /**
  698. * Define whether database changes done on the database be automatically
  699. * committed. This function may also implicitly start or end a transaction.
  700. *
  701. * @param boolean $auto_commit flag that indicates whether the database
  702. * changes should be committed right after executing every query
  703. * statement. If this argument is 0 a transaction implicitly started.
  704. * Otherwise, if a transaction is in progress it is ended by committing
  705. * any database changes that were pending.
  706. * @return mixed MDB_OK on success, a MDB error on failure
  707. * @access public
  708. */
  709. function autoCommit($auto_commit)
  710. {
  711. $this->debug('AutoCommit: ' . ($auto_commit ? 'On' : 'Off'));
  712. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  713. 'Auto-commit transactions: transactions are not supported'));
  714. }
  715. // }}}
  716. // {{{ commit()
  717. /**
  718. * Commit the database changes done during a transaction that is in
  719. * progress. This function may only be called when auto-committing is
  720. * disabled, otherwise it will fail. Therefore, a new transaction is
  721. * implicitly started after committing the pending changes.
  722. *
  723. * @return mixed MDB_OK on success, a MDB error on failure
  724. * @access public
  725. */
  726. function commit()
  727. {
  728. $this->debug('Commit Transaction');
  729. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  730. 'Commit transaction: commiting transactions are not supported'));
  731. }
  732. // }}}
  733. // {{{ rollback()
  734. /**
  735. * Cancel any database changes done during a transaction that is in
  736. * progress. This function may only be called when auto-committing is
  737. * disabled, otherwise it will fail. Therefore, a new transaction is
  738. * implicitly started after canceling the pending changes.
  739. *
  740. * @return mixed MDB_OK on success, a MDB error on failure
  741. * @access public
  742. */
  743. function rollback()
  744. {
  745. $this->debug('Rollback Transaction');
  746. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  747. 'Rollback transaction: rolling back transactions are not supported'));
  748. }
  749. // }}}
  750. // {{{ disconnect()
  751. /**
  752. * Log out and disconnect from the database.
  753. *
  754. * @return mixed TRUE on success, FALSE if not connected and error
  755. * object on error
  756. * @access public
  757. */
  758. function disconnect()
  759. {
  760. if ($this->in_transaction && !MDB::isError($this->rollback()) && !MDB::isError($this->autoCommit(TRUE))) {
  761. $this->in_transaction = FALSE;
  762. }
  763. return($this->_close());
  764. }
  765. // }}}
  766. // {{{ _close()
  767. /**
  768. * all the RDBMS specific things needed to close a DB connection
  769. *
  770. * @access private
  771. */
  772. function _close()
  773. {
  774. unset($GLOBALS['_MDB_databases'][$this->database]);
  775. }
  776. // }}}
  777. // {{{ setDatabase()
  778. /**
  779. * Select a different database
  780. *
  781. * @param string $name name of the database that should be selected
  782. * @return string name of the database previously connected to
  783. * @access public
  784. */
  785. function setDatabase($name)
  786. {
  787. $previous_database_name = $this->database_name;
  788. $this->database_name = $name;
  789. return($previous_database_name);
  790. }
  791. // }}}
  792. // {{{ setDSN()
  793. /**
  794. * set the DSN
  795. *
  796. * @param mixed $dsninfo DSN string or array
  797. * @return MDB_OK
  798. * @access public
  799. */
  800. function setDSN($dsn)
  801. {
  802. $dsninfo = MDB::parseDSN($dsn);
  803. if(isset($dsninfo['hostspec'])) {
  804. $this->host = $dsninfo['hostspec'];
  805. }
  806. if(isset($dsninfo['port'])) {
  807. $this->port = $dsninfo['port'];
  808. }
  809. if(isset($dsninfo['username'])) {
  810. $this->user = $dsninfo['username'];
  811. }
  812. if(isset($dsninfo['password'])) {
  813. $this->password = $dsninfo['password'];
  814. }
  815. if(isset($dsninfo['database'])) {
  816. $this->database_name = $dsninfo['database'];
  817. }
  818. return(MDB_OK);
  819. }
  820. // }}}
  821. // {{{ getDSN()
  822. /**
  823. * return the DSN as a string
  824. *
  825. * @param string $type type to return
  826. * @return mixed DSN in the chosen type
  827. * @access public
  828. */
  829. function getDSN($type = 'string')
  830. {
  831. switch($type) {
  832. case 'array':
  833. $dsn = array(
  834. 'phptype' => $this->phptype,
  835. 'username' => $this->user,
  836. 'password' => $this->password,
  837. 'hostspec' => $this->host,
  838. 'database' => $this->database_name
  839. );
  840. break;
  841. default:
  842. $dsn = $this->phptype.'://'.$this->user.':'
  843. .$this->password.'@'.$this->host
  844. .($this->port ? (':'.$this->port) : '')
  845. .'/'.$this->database_name;
  846. break;
  847. }
  848. return($dsn);
  849. }
  850. // }}}
  851. // {{{ createDatabase()
  852. /**
  853. * create a new database
  854. *
  855. * @param string $name name of the database that should be created
  856. * @return mixed MDB_OK on success, a MDB error on failure
  857. * @access public
  858. */
  859. function createDatabase($name)
  860. {
  861. $result = $this->loadManager('Create database');
  862. if (MDB::isError($result)) {
  863. return($result);
  864. }
  865. return($this->manager->createDatabase($this, $name));
  866. }
  867. // }}}
  868. // {{{ dropDatabase()
  869. /**
  870. * drop an existing database
  871. *
  872. * @param string $name name of the database that should be dropped
  873. * @return mixed MDB_OK on success, a MDB error on failure
  874. * @access public
  875. */
  876. function dropDatabase($name)
  877. {
  878. $result = $this->loadManager('Drop database');
  879. if (MDB::isError($result)) {
  880. return($result);
  881. }
  882. return($this->manager->dropDatabase($this, $name));
  883. }
  884. // }}}
  885. // {{{ createTable()
  886. /**
  887. * create a new table
  888. *
  889. * @param string $name Name of the database that should be created
  890. * @param array $fields Associative array that contains the definition of
  891. * each field of the new table. The indexes of the array entries are
  892. * the names of the fields of the table an the array entry values are
  893. * associative arrays like those that are meant to be passed with the
  894. * field definitions to get[Type]Declaration() functions.
  895. *
  896. * Example
  897. * array(
  898. * 'id' => array(
  899. * 'type' => 'integer',
  900. * 'unsigned' => 1
  901. * 'notnull' => 1
  902. * 'default' => 0
  903. * ),
  904. * 'name' => array(
  905. * 'type' => 'text',
  906. * 'length' => 12
  907. * ),
  908. * 'password' => array(
  909. * 'type' => 'text',
  910. * 'length' => 12
  911. * )
  912. * );
  913. * @return mixed MDB_OK on success, a MDB error on failure
  914. * @access public
  915. */
  916. function createTable($name, $fields)
  917. {
  918. $result = $this->loadManager('Create table');
  919. if (MDB::isError($result)) {
  920. return($result);
  921. }
  922. return($this->manager->createTable($this, $name, $fields));
  923. }
  924. // }}}
  925. // {{{ dropTable()
  926. /**
  927. * drop an existing table
  928. *
  929. * @param string $name name of the table that should be dropped
  930. * @return mixed MDB_OK on success, a MDB error on failure
  931. * @access public
  932. */
  933. function dropTable($name)
  934. {
  935. $result = $this->loadManager('Drop table');
  936. if (MDB::isError($result)) {
  937. return($result);
  938. }
  939. return($this->manager->dropTable($this, $name));
  940. }
  941. // }}}
  942. // {{{ alterTable()
  943. /**
  944. * alter an existing table
  945. *
  946. * @param string $name name of the table that is intended to be changed.
  947. * @param array $changes associative array that contains the details of
  948. * each type of change that is intended to be performed. The types of
  949. * changes that are currently supported are defined as follows:
  950. *
  951. * name
  952. * New name for the table.
  953. *
  954. * AddedFields
  955. * Associative array with the names of fields to be added as indexes of
  956. * the array. The value of each entry of the array should be set to
  957. * another associative array with the properties of the fields to be
  958. * added. The properties of the fields should be the same as defined by
  959. * the Metabase parser.
  960. *
  961. * Additionally, there should be an entry named Declaration that is
  962. * expected to contain the portion of the field declaration already in
  963. * DBMS specific SQL code as it is used in the CREATE TABLE statement.
  964. *
  965. * RemovedFields
  966. * Associative array with the names of fields to be removed as indexes of
  967. * the array. Currently the values assigned to each entry are ignored. An
  968. * empty array should be used for future compatibility.
  969. *
  970. * RenamedFields
  971. * Associative array with the names of fields to be renamed as indexes of
  972. * the array. The value of each entry of the array should be set to another
  973. * associative array with the entry named name with the new field name and
  974. * the entry named Declaration that is expected to contain the portion of
  975. * the field declaration already in DBMS specific SQL code as it is used
  976. * in the CREATE TABLE statement.
  977. *
  978. * ChangedFields
  979. * Associative array with the names of the fields to be changed as indexes
  980. * of the array. Keep in mind that if it is intended to change either the
  981. * name of a field and any other properties, the ChangedFields array
  982. * entries should have the new names of the fields as array indexes.
  983. *
  984. * The value of each entry of the array should be set to another
  985. * associative array with the properties of the fields to that are meant
  986. * to be changed as array entries. These entries should be assigned to the
  987. * new values of the respective properties. The properties of the fields
  988. * should be the* same as defined by the Metabase parser.
  989. *
  990. * If the default property is meant to be added, removed or changed, there
  991. * should also be an entry with index ChangedDefault assigned to 1.
  992. * Similarly, if the notnull constraint is to be added or removed, there
  993. * should also be an entry with index ChangedNotNull assigned to 1.
  994. *
  995. * Additionally, there should be an entry named Declaration that is
  996. * expected to contain the portion of the field changed declaration
  997. * already in DBMS specific SQL code as it is used in the CREATE TABLE
  998. * statement.
  999. *
  1000. * Example
  1001. * array(
  1002. * 'name' => 'userlist',
  1003. * 'AddedFields' => array(
  1004. * 'quota' => array(
  1005. * 'type' => 'integer',
  1006. * 'unsigned' => 1,
  1007. * 'Declaration' => 'quota INT'
  1008. * )
  1009. * ),
  1010. * 'RemovedFields' => array(
  1011. * 'file_limit' => array(),
  1012. * 'time_limit' => array()
  1013. * ),
  1014. * 'ChangedFields' => array(
  1015. * 'gender' => array(
  1016. * 'default' => 'M',
  1017. * 'ChangeDefault' => 1,
  1018. * 'Declaration' => "gender CHAR(1) DEFAULT 'M'"
  1019. * )
  1020. * ),
  1021. * 'RenamedFields' => array(
  1022. * 'sex' => array(
  1023. * 'name' => 'gender',
  1024. * 'Declaration' => "gender CHAR(1) DEFAULT 'M'"
  1025. * )
  1026. * )
  1027. * )
  1028. *
  1029. * @param boolean $check indicates whether the function should just check
  1030. * if the DBMS driver can perform the requested table alterations if
  1031. * the value is TRUE or actually perform them otherwise.
  1032. * @return mixed MDB_OK on success, a MDB error on failure
  1033. * @access public
  1034. */
  1035. function alterTable($name, $changes, $check)
  1036. {
  1037. $result = $this->loadManager('Alter table');
  1038. if (MDB::isError($result)) {
  1039. return($result);
  1040. }
  1041. return($this->manager->alterTable($this, $name, $changes, $check));
  1042. }
  1043. // }}}
  1044. // {{{ listDatabases()
  1045. /**
  1046. * list all databases
  1047. *
  1048. * @return mixed data array on success, a MDB error on failure
  1049. * @access public
  1050. */
  1051. function listDatabases()
  1052. {
  1053. $result = $this->loadManager('List databases');
  1054. if (MDB::isError($result)) {
  1055. return($result);
  1056. }
  1057. return($this->manager->listDatabases($this));
  1058. }
  1059. // }}}
  1060. // {{{ listUsers()
  1061. /**
  1062. * list all users
  1063. *
  1064. * @return mixed data array on success, a MDB error on failure
  1065. * @access public
  1066. */
  1067. function listUsers()
  1068. {
  1069. $result = $this->loadManager('List users');
  1070. if (MDB::isError($result)) {
  1071. return($result);
  1072. }
  1073. return($this->manager->listUsers($this));
  1074. }
  1075. // }}}
  1076. // {{{ listViews()
  1077. /**
  1078. * list all viewes in the current database
  1079. *
  1080. * @return mixed data array on success, a MDB error on failure
  1081. * @access public
  1082. */
  1083. function listViews()
  1084. {
  1085. $result = $this->loadManager('List views');
  1086. if (MDB::isError($result)) {
  1087. return($result);
  1088. }
  1089. return($this->manager->listViews($this));
  1090. }
  1091. // }}}
  1092. // {{{ listFunctions()
  1093. /**
  1094. * list all functions in the current database
  1095. *
  1096. * @return mixed data array on success, a MDB error on failure
  1097. * @access public
  1098. */
  1099. function listFunctions()
  1100. {
  1101. $result = $this->loadManager('List functions');
  1102. if (MDB::isError($result)) {
  1103. return($result);
  1104. }
  1105. return($this->manager->listFunctions($this));
  1106. }
  1107. // }}}
  1108. // {{{ listTables()
  1109. /**
  1110. * list all tables in the current database
  1111. *
  1112. * @return mixed data array on success, a MDB error on failure
  1113. * @access public
  1114. */
  1115. function listTables()
  1116. {
  1117. $result = $this->loadManager('List tables');
  1118. if (MDB::isError($result)) {
  1119. return($result);
  1120. }
  1121. return($this->manager->listTables($this));
  1122. }
  1123. // }}}
  1124. // {{{ listTableFields()
  1125. /**
  1126. * list all fields in a tables in the current database
  1127. *
  1128. * @param string $table name of table that should be used in method
  1129. * @return mixed data array on success, a MDB error on failure
  1130. * @access public
  1131. */
  1132. function listTableFields($table)
  1133. {
  1134. $result = $this->loadManager('List table fields');
  1135. if (MDB::isError($result)) {
  1136. return($result);
  1137. }
  1138. return($this->manager->listTableFields($this, $table));
  1139. }
  1140. // }}}
  1141. // {{{ getTableFieldDefinition()
  1142. /**
  1143. * get the stucture of a field into an array
  1144. *
  1145. * @param string $table name of table that should be used in method
  1146. * @param string $fields name of field that should be used in method
  1147. * @return mixed data array on success, a MDB error on failure
  1148. * @access public
  1149. */
  1150. function getTableFieldDefinition($table, $field)
  1151. {
  1152. $result = $this->loadManager('Get table field definition');
  1153. if (MDB::isError($result)) {
  1154. return($result);
  1155. }
  1156. return($this->manager->getTableFieldDefinition($this, $table, $field));
  1157. }
  1158. // }}}
  1159. // {{{ getFieldDeclaration()
  1160. /**
  1161. * get declaration of a field
  1162. *
  1163. * @param string $field_name name of the field to be created
  1164. * @param string $field associative array with the name of the properties
  1165. * of the field being declared as array indexes. Currently, the types
  1166. * of supported field properties are as follows:
  1167. *
  1168. * default
  1169. * Boolean value to be used as default for this field.
  1170. *
  1171. * notnull
  1172. * Boolean flag that indicates whether this field is constrained
  1173. * to not be set to NULL.
  1174. * @return mixed string on success, a MDB error on failure
  1175. * @access public
  1176. */
  1177. function getFieldDeclaration($field_name, $field)
  1178. {
  1179. $result = $this->loadManager('Get table field definition');
  1180. if (MDB::isError($result)) {
  1181. return($result);
  1182. }
  1183. return($this->manager->getFieldDeclaration($this, $field_name, $field));
  1184. }
  1185. // }}}
  1186. // {{{ getFieldDeclarationList()
  1187. /**
  1188. * get declaration of a number of field in bulk
  1189. *
  1190. * @param string $fields a multidimensional associative array.
  1191. * The first dimension determines the field name, while the second
  1192. * dimension is keyed with the name of the properties
  1193. * of the field being declared as array indexes. Currently, the types
  1194. * of supported field properties are as follows:
  1195. *
  1196. * default
  1197. * Boolean value to be used as default for this field.
  1198. *
  1199. * notnull
  1200. * Boolean flag that indicates whether this field is constrained
  1201. * to not be set to NULL.
  1202. *
  1203. * default
  1204. * Boolean value to be used as default for this field.
  1205. *
  1206. * notnull
  1207. * Boolean flag that indicates whether this field is constrained
  1208. * to not be set to NULL.
  1209. * @return mixed string on success, a MDB error on failure
  1210. * @access public
  1211. */
  1212. function getFieldDeclarationList($fields)
  1213. {
  1214. $result = $this->loadManager('Get table field list');
  1215. if (MDB::isError($result)) {
  1216. return($result);
  1217. }
  1218. return($this->manager->getFieldDeclarationList($this, $fields));
  1219. }
  1220. // }}}
  1221. // {{{ _isSequenceName()
  1222. /**
  1223. * list all tables in the current database
  1224. *
  1225. * @param string $sqn string that containts name of a potential sequence
  1226. * @return mixed name of the sequence if $sqn is a name of a sequence, else FALSE
  1227. * @access private
  1228. */
  1229. function _isSequenceName($sqn)
  1230. {
  1231. $result = $this->loadManager('is sequence name');
  1232. if (MDB::isError($result)) {
  1233. return($result);
  1234. }
  1235. return($this->manager->_isSequenceName($this, $sqn));
  1236. }
  1237. // }}}
  1238. // {{{ createIndex()
  1239. /**
  1240. * get the stucture of a field into an array
  1241. *
  1242. * @param string $table name of the table on which the index is to be
  1243. * created
  1244. * @param string $name name of the index to be created
  1245. * @param array $definition associative array that defines properties of
  1246. * the index to be created. Currently, only one property named FIELDS
  1247. * is supported. This property is also an associative with the names
  1248. * of the index fields as array indexes. Each entry of this array is
  1249. * set to another type of associative array that specifies properties
  1250. * of the index that are specific to each field.
  1251. *
  1252. * Currently, only the sorting property is supported. It should be
  1253. * used to define the sorting direction of the index. It may be set
  1254. * to either ascending or descending. Not all DBMS support index
  1255. * sorting direction configuration. The DBMS drivers of those that do
  1256. * not support it ignore this property. Use the function support() to
  1257. * determine whether the DBMS driver can manage indexes.
  1258. *
  1259. * Example
  1260. * array(
  1261. * 'FIELDS' => array(
  1262. * 'user_name' => array(
  1263. * 'sorting' => 'ascending'
  1264. * ),
  1265. * 'last_login' => array()
  1266. * )
  1267. * )
  1268. * @return mixed MDB_OK on success, a MDB error on failure
  1269. * @access public
  1270. */
  1271. function createIndex($table, $name, $definition)
  1272. {
  1273. $result = $this->loadManager('Create index');
  1274. if (MDB::isError($result)) {
  1275. return($result);
  1276. }
  1277. return($this->manager->createIndex($this, $table, $name, $definition));
  1278. }
  1279. // }}}
  1280. // {{{ dropIndex()
  1281. /**
  1282. * drop existing index
  1283. *
  1284. * @param string $table name of table that should be used in method
  1285. * @param string $name name of the index to be dropped
  1286. * @return mixed MDB_OK on success, a MDB error on failure
  1287. * @access public
  1288. */
  1289. function dropIndex($table, $name)
  1290. {
  1291. $result = $this->loadManager('Drop index');
  1292. if (MDB::isError($result)) {
  1293. return($result);
  1294. }
  1295. return($this->manager->dropIndex($this, $table , $name));
  1296. }
  1297. // }}}
  1298. // {{{ listTableIndexes()
  1299. /**
  1300. * list all indexes in a table
  1301. *
  1302. * @param string $table name of table that should be used in method
  1303. * @return mixed data array on success, a MDB error on failure
  1304. * @access public
  1305. */
  1306. function listTableIndexes($table)
  1307. {
  1308. $result = $this->loadManager('List table index');
  1309. if (MDB::isError($result)) {
  1310. return($result);
  1311. }
  1312. return($this->manager->listTableIndexes($this, $table));
  1313. }
  1314. // }}}
  1315. // {{{ getTableIndexDefinition()
  1316. /**
  1317. * get the stucture of an index into an array
  1318. *
  1319. * @param string $table name of table that should be used in method
  1320. * @param string $index name of index that should be used in method
  1321. * @return mixed data array on success, a MDB error on failure
  1322. * @access public
  1323. */
  1324. function getTableIndexDefinition($table, $index)
  1325. {
  1326. $result = $this->loadManager('Get table index definition');
  1327. if (MDB::isError($result)) {
  1328. return($result);
  1329. }
  1330. return($this->manager->getTableIndexDefinition($this, $table, $index));
  1331. }
  1332. // }}}
  1333. // {{{ createSequence()
  1334. /**
  1335. * create sequence
  1336. *
  1337. * @param string $name name of the sequence to be created
  1338. * @param string $start start value of the sequence; default is 1
  1339. * @return mixed MDB_OK on success, a MDB error on failure
  1340. * @access public
  1341. */
  1342. function createSequence($name, $start = 1)
  1343. {
  1344. $result = $this->loadManager('Create sequence');
  1345. if (MDB::isError($result)) {
  1346. return($result);
  1347. }
  1348. return($this->manager->createSequence($this, $name, $start));
  1349. }
  1350. // }}}
  1351. // {{{ dropSequence()
  1352. /**
  1353. * drop existing sequence
  1354. *
  1355. * @param string $name name of the sequence to be dropped
  1356. * @return mixed MDB_OK on success, a MDB error on failure
  1357. * @access public
  1358. */
  1359. function dropSequence($name)
  1360. {
  1361. $result = $this->loadManager('Drop sequence');
  1362. if (MDB::isError($result)) {
  1363. return($result);
  1364. }
  1365. return($this->manager->dropSequence($this, $name));
  1366. }
  1367. // }}}
  1368. // {{{ listSequences()
  1369. /**
  1370. * list all tables in the current database
  1371. *
  1372. * @return mixed data array on success, a MDB error on failure
  1373. * @access public
  1374. */
  1375. function listSequences()
  1376. {
  1377. $result = $this->loadManager('List sequences');
  1378. if (MDB::isError($result)) {
  1379. return($result);
  1380. }
  1381. return($this->manager->listSequences($this));
  1382. }
  1383. // }}}
  1384. // {{{ getSequenceDefinition()
  1385. /**
  1386. * get the stucture of a sequence into an array
  1387. *
  1388. * @param string $sequence name of sequence that should be used in method
  1389. * @return mixed data array on success, a MDB error on failure
  1390. * @access public
  1391. */
  1392. function getSequenceDefinition($sequence)
  1393. {
  1394. $result = $this->loadManager('Get sequence definition');
  1395. if (MDB::isError($result)) {
  1396. return($result);
  1397. }
  1398. return($this->manager->getSequenceDefinition($this, $sequence));
  1399. }
  1400. // }}}
  1401. // {{{ query()
  1402. /**
  1403. * Send a query to the database and return any results
  1404. *
  1405. * @param string $query the SQL query
  1406. * @param mixed $types array that contains the types of the columns in
  1407. * the result set
  1408. * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1409. * @access public
  1410. */
  1411. function query($query, $types = NULL)
  1412. {
  1413. $this->debug("Query: $query");
  1414. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Query: database queries are not implemented'));
  1415. }
  1416. // }}}
  1417. // {{{ setSelectedRowRange()
  1418. /**
  1419. * set the range of the next query
  1420. *
  1421. * @param string $first first row to select
  1422. * @param string $limit number of rows to select
  1423. * @return mixed MDB_OK on success, a MDB error on failure
  1424. * @access public
  1425. */
  1426. function setSelectedRowRange($first, $limit)
  1427. {
  1428. if (!isset($this->supported['SelectRowRanges'])) {
  1429. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  1430. 'Set selected row range: selecting row ranges is not supported by this driver'));
  1431. }
  1432. $first = (int)$first;
  1433. if ($first < 0) {
  1434. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1435. 'Set selected row range: it was not specified a valid first selected range row'));
  1436. }
  1437. $limit = (int)$limit;
  1438. if ($limit < 1) {
  1439. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1440. 'Set selected row range: it was not specified a valid selected range row limit'));
  1441. }
  1442. $this->first_selected_row = $first;
  1443. $this->selected_row_limit = $limit;
  1444. return(MDB_OK);
  1445. }
  1446. // }}}
  1447. // {{{ limitQuery()
  1448. /**
  1449. * Generates a limited query
  1450. *
  1451. * @param string $query query
  1452. * @param mixed $types array that contains the types of the columns in
  1453. * the result set
  1454. * @param integer $from the row to start to fetching
  1455. * @param integer $count the numbers of rows to fetch
  1456. * @return mixed a valid ressource pointer or a MDB_Error
  1457. * @access public
  1458. */
  1459. function limitQuery($query, $types = NULL, $from, $count)
  1460. {
  1461. $result = $this->setSelectedRowRange($from, $count);
  1462. if (MDB::isError($result)) {
  1463. return($result);
  1464. }
  1465. return($this->query($query, $types));
  1466. }
  1467. // }}}
  1468. // {{{ subSelect()
  1469. /**
  1470. * simple subselect emulation: leaves the query untouched for all RDBMS
  1471. * that support subselects
  1472. *
  1473. * @access public
  1474. *
  1475. * @param string $query the SQL query for the subselect that may only
  1476. * return a column
  1477. * @param string $quote determines if the data needs to be quoted before
  1478. * being returned
  1479. *
  1480. * @return string the query
  1481. */
  1482. function subSelect($query, $quote = FALSE)
  1483. {
  1484. if ($this->supported['SubSelects'] == 1) {
  1485. return($query);
  1486. }
  1487. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Subselect: subselect not implemented'));
  1488. }
  1489. // }}}
  1490. // {{{ replace()
  1491. /**
  1492. * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
  1493. * query, except that if there is already a row in the table with the same
  1494. * key field values, the REPLACE query just updates its values instead of
  1495. * inserting a new row.
  1496. *
  1497. * The REPLACE type of query does not make part of the SQL standards. Since
  1498. * pratically only MySQL implements it natively, this type of query is
  1499. * emulated through this method for other DBMS using standard types of
  1500. * queries inside a transaction to assure the atomicity of the operation.
  1501. *
  1502. * @param string $table name of the table on which the REPLACE query will
  1503. * be executed.
  1504. * @param array $fields associative array that describes the fields and the
  1505. * values that will be inserted or updated in the specified table. The
  1506. * indexes of the array are the names of all the fields of the table.
  1507. * The values of the array are also associative arrays that describe
  1508. * the values and other properties of the table fields.
  1509. *
  1510. * Here follows a list of field properties that need to be specified:
  1511. *
  1512. * Value
  1513. * Value to be assigned to the specified field. This value may be
  1514. * of specified in database independent type format as this
  1515. * function can perform the necessary datatype conversions.
  1516. *
  1517. * Default: this property is required unless the Null property is
  1518. * set to 1.
  1519. *
  1520. * Type
  1521. * Name of the type of the field. Currently, all types Metabase
  1522. * are supported except for clob and blob.
  1523. *
  1524. * Default: no type conversion
  1525. *
  1526. * Null
  1527. * Boolean property that indicates that the value for this field
  1528. * should be set to NULL.
  1529. *
  1530. * The default value for fields missing in INSERT queries may be
  1531. * specified the definition of a table. Often, the default value
  1532. * is already NULL, but since the REPLACE may be emulated using
  1533. * an UPDATE query, make sure that all fields of the table are
  1534. * listed in this function argument array.
  1535. *
  1536. * Default: 0
  1537. *
  1538. * Key
  1539. * Boolean property that indicates that this field should be
  1540. * handled as a primary key or at least as part of the compound
  1541. * unique index of the table that will determine the row that will
  1542. * updated if it exists or inserted a new row otherwise.
  1543. *
  1544. * This function will fail if no key field is specified or if the
  1545. * value of a key field is set to NULL because fields that are
  1546. * part of unique index they may not be NULL.
  1547. *
  1548. * Default: 0
  1549. * @return mixed MDB_OK on success, a MDB error on failure
  1550. * @access public
  1551. */
  1552. function replace($table, $fields)
  1553. {
  1554. if (!$this->supported['Replace']) {
  1555. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Replace: replace query is not supported'));
  1556. }
  1557. $count = count($fields);
  1558. for($keys = 0, $condition = $insert = $values = '', reset($fields), $field = 0;
  1559. $field < $count;
  1560. next($fields), $field++)
  1561. {
  1562. $name = key($fields);
  1563. if ($field > 0) {
  1564. $insert .= ', ';
  1565. $values .= ', ';
  1566. }
  1567. $insert .= $name;
  1568. if (isset($fields[$name]['Null']) && $fields[$name]['Null']) {
  1569. $value = 'NULL';
  1570. } else {
  1571. if(isset($fields[$name]['Type'])) {
  1572. switch ($fields[$name]['Type']) {
  1573. case 'text':
  1574. $value = $this->getTextValue($fields[$name]['Value']);
  1575. break;
  1576. case 'boolean':
  1577. $value = $this->getBooleanValue($fields[$name]['Value']);
  1578. break;
  1579. case 'integer':
  1580. $value = $this->getIntegerValue($fields[$name]['Value']);
  1581. break;
  1582. case 'decimal':
  1583. $value = $this->getDecimalValue($fields[$name]['Value']);
  1584. break;
  1585. case 'float':
  1586. $value = $this->getFloatValue($fields[$name]['Value']);
  1587. break;
  1588. case 'date':
  1589. $value = $this->getDateValue($fields[$name]['Value']);
  1590. break;
  1591. case 'time':
  1592. $value = $this->getTimeValue($fields[$name]['Value']);
  1593. break;
  1594. case 'timestamp':
  1595. $value = $this->getTimestampValue($fields[$name]['Value']);
  1596. break;
  1597. default:
  1598. return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1599. 'no supported type for field "' . $name . '" specified'));
  1600. }
  1601. } else {
  1602. $value = $fields[$name]['Value'];
  1603. }
  1604. }
  1605. $values .= $value;
  1606. if (isset($fields[$name]['Key']) && $fields[$name]['Key']) {
  1607. if ($value === 'NULL') {
  1608. return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1609. 'key values may not be NULL'));
  1610. }
  1611. $condition .= ($keys ? ' AND ' : ' WHERE ') . $name . '=' . $value;
  1612. $keys++;
  1613. }
  1614. }
  1615. if ($keys == 0) {
  1616. return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1617. 'not specified which fields are keys'));
  1618. }
  1619. $in_transaction = $this->in_transaction;
  1620. if (!$in_transaction && MDB::isError($result = $this->autoCommit(FALSE))) {
  1621. return($result);
  1622. }
  1623. $success = $this->query("DELETE FROM $table$condition");
  1624. if (!MDB::isError($success)) {
  1625. $affected_rows = $this->affected_rows;
  1626. $success = $this->query("INSERT INTO $table ($insert) VALUES ($values)");
  1627. $affected_rows += $this->affected_rows;
  1628. }
  1629. if (!$in_transaction) {
  1630. if (!MDB::isError($success)) {
  1631. if (!MDB::isError($success = $this->commit())
  1632. && !MDB::isError($success = $this->autoCommit(TRUE))
  1633. && isset($this->supported['AffectedRows'])
  1634. ) {
  1635. $this->affected_rows = $affected_rows;
  1636. }
  1637. } else {
  1638. $this->rollback();
  1639. $this->autoCommit(TRUE);
  1640. }
  1641. }
  1642. return($success);
  1643. }
  1644. // }}}
  1645. // {{{ prepareQuery()
  1646. /**
  1647. * Prepares a query for multiple execution with execute().
  1648. * With some database backends, this is emulated.
  1649. * prepareQuery() requires a generic query as string like
  1650. * 'INSERT INTO numbers VALUES(?,?,?)'. The ? are wildcards.
  1651. * Types of wildcards:
  1652. * ? - a quoted scalar value, i.e. strings, integers
  1653. *
  1654. * @param string $ the query to prepare
  1655. * @return mixed resource handle for the prepared query on success, a DB
  1656. * error on failure
  1657. * @access public
  1658. * @see execute
  1659. */
  1660. function prepareQuery($query)
  1661. {
  1662. $this->debug("PrepareQuery: $query");
  1663. $positions = array();
  1664. for($position = 0;
  1665. $position < strlen($query) && is_integer($question = strpos($query, '?', $position));
  1666. ) {
  1667. if (is_integer($quote = strpos($query, "'", $position))
  1668. && $quote < $question
  1669. ) {
  1670. if (!is_integer($end_quote = strpos($query, "'", $quote + 1))) {
  1671. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1672. 'Prepare query: query with an unterminated text string specified'));
  1673. }
  1674. switch ($this->escape_quotes) {
  1675. case '':
  1676. case "'":
  1677. $position = $end_quote + 1;
  1678. break;
  1679. default:
  1680. if ($end_quote == $quote + 1) {
  1681. $position = $end_quote + 1;
  1682. } else {
  1683. if ($query[$end_quote-1] == $this->escape_quotes) {
  1684. $position = $end_quote;
  1685. } else {
  1686. $position = $end_quote + 1;
  1687. }
  1688. }
  1689. break;
  1690. }
  1691. } else {
  1692. $positions[] = $question;
  1693. $position = $question + 1;
  1694. }
  1695. }
  1696. $this->prepared_queries[] = array(
  1697. 'Query' => $query,
  1698. 'Positions' => $positions,
  1699. 'Values' => array(),
  1700. 'Types' => array()
  1701. );
  1702. $prepared_query = count($this->prepared_queries);
  1703. if ($this->selected_row_limit > 0) {
  1704. $this->prepared_queries[$prepared_query-1]['First'] = $this->first_selected_row;
  1705. $this->prepared_queries[$prepared_query-1]['Limit'] = $this->selected_row_limit;
  1706. }
  1707. return($prepared_query);
  1708. }
  1709. // }}}
  1710. // {{{ _validatePreparedQuery()
  1711. /**
  1712. * validate that a handle is infact a prepared query
  1713. *
  1714. * @param int $prepared_query argument is a handle that was returned by
  1715. * the function prepareQuery()
  1716. * @access private
  1717. */
  1718. function _validatePreparedQuery($prepared_query)
  1719. {
  1720. if ($prepared_query < 1 || $prepared_query > count($this->prepared_queries)) {
  1721. return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  1722. 'Validate prepared query: invalid prepared query'));
  1723. }
  1724. if (gettype($this->prepared_queries[$prepared_query-1]) != 'array') {
  1725. return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  1726. 'Validate prepared query: prepared query was already freed'));
  1727. }
  1728. return(MDB_OK);
  1729. }
  1730. // }}}
  1731. // {{{ freePreparedQuery()
  1732. /**
  1733. * Release resources allocated for the specified prepared query.
  1734. *
  1735. * @param int $prepared_query argument is a handle that was returned by
  1736. * the function prepareQuery()
  1737. * @return mixed MDB_OK on success, a MDB error on failure
  1738. * @access public
  1739. */
  1740. function freePreparedQuery($prepared_query)
  1741. {
  1742. $result = $this->_validatePreparedQuery($prepared_query);
  1743. if (MDB::isError($result)) {
  1744. return($result);
  1745. }
  1746. $this->prepared_queries[$prepared_query-1] = '';
  1747. return(MDB_OK);
  1748. }
  1749. // }}}
  1750. // {{{ _executePreparedQuery()
  1751. /**
  1752. * Execute a prepared query statement.
  1753. *
  1754. * @param int $prepared_query argument is a handle that was returned by
  1755. * the function prepareQuery()
  1756. * @param string $query query to be executed
  1757. * @param array $types array that contains the types of the columns in
  1758. * the result set
  1759. * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1760. * @access private
  1761. */
  1762. function _executePreparedQuery($prepared_query, $query, $types = NULL)
  1763. {
  1764. return($this->query($query, $types));
  1765. }
  1766. // }}}
  1767. // {{{ executeQuery()
  1768. /**
  1769. * Execute a prepared query statement.
  1770. *
  1771. * @param int $prepared_query argument is a handle that was returned by
  1772. * the function prepareQuery()
  1773. * @param array $types array that contains the types of the columns in the
  1774. * result set
  1775. * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1776. * @access public
  1777. */
  1778. function executeQuery($prepared_query, $types = NULL)
  1779. {
  1780. $result = $this->_validatePreparedQuery($prepared_query);
  1781. if (MDB::isError($result)) {
  1782. return($result);
  1783. }
  1784. $index = $prepared_query-1;
  1785. $success = MDB_OK;
  1786. $this->clobs[$prepared_query] = $this->blobs[$prepared_query] = array();
  1787. $query = '';
  1788. for($last_position = $position = 0;
  1789. $position < count($this->prepared_queries[$index]['Positions']);
  1790. $position++) {
  1791. if (!isset($this->prepared_queries[$index]['Values'][$position])) {
  1792. return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  1793. 'Execute query: it was not defined query argument '.($position + 1)));
  1794. }
  1795. $current_position = $this->prepared_queries[$index]['Positions'][$position];
  1796. $query .= substr($this->prepared_queries[$index]['Query'], $last_position, $current_position - $last_position);
  1797. $value = $this->prepared_queries[$index]['Values'][$position];
  1798. if ($this->prepared_queries[$index]['IsNULL'][$position]) {
  1799. $query .= $value;
  1800. } else {
  1801. switch ($this->prepared_queries[$index]['Types'][$position]) {
  1802. case 'clob':
  1803. if (!MDB::isError($success = $this->getClobValue($prepared_query, $position + 1, $value))) {
  1804. $this->clobs[$prepared_query][$position + 1] = $success;
  1805. $query .= $this->clobs[$prepared_query][$position + 1];
  1806. }
  1807. break;
  1808. case 'blob':
  1809. if (!MDB::isError($success = $this->getBlobValue($prepared_query, $position + 1, $value))) {
  1810. $this->blobs[$prepared_query][$position + 1] = $success;
  1811. $query .= $this->blobs[$prepared_query][$position + 1];
  1812. }
  1813. break;
  1814. default:
  1815. $query .= $value;
  1816. break;
  1817. }
  1818. }
  1819. $last_position = $current_position + 1;
  1820. }
  1821. if (!MDB::isError($success)) {
  1822. $query .= substr($this->prepared_queries[$index]['Query'], $last_position);
  1823. if ($this->selected_row_limit > 0) {
  1824. $this->prepared_queries[$index]['First'] = $this->first_selected_row;
  1825. $this->prepared_queries[$index]['Limit'] = $this->selected_row_limit;
  1826. }
  1827. if (isset($this->prepared_queries[$index]['Limit'])
  1828. && $this->prepared_queries[$index]['Limit'] > 0
  1829. ) {
  1830. $this->first_selected_row = $this->prepared_queries[$index]['First'];
  1831. $this->selected_row_limit = $this->prepared_queries[$index]['Limit'];
  1832. } else {
  1833. $this->first_selected_row = $this->selected_row_limit = 0;
  1834. }
  1835. $success = $this->_executePreparedQuery($prepared_query, $query, $types);
  1836. }
  1837. for(reset($this->clobs[$prepared_query]), $clob = 0;
  1838. $clob < count($this->clobs[$prepared_query]);
  1839. $clob++, next($this->clobs[$prepared_query])) {
  1840. $this->freeClobValue($prepared_query, key($this->clobs[$prepared_query]), $this->clobs[$prepared_query][key($this->clobs[$prepared_query])], $success);
  1841. }
  1842. unset($this->clobs[$prepared_query]);
  1843. for(reset($this->blobs[$prepared_query]), $blob = 0;
  1844. $blob < count($this->blobs[$prepared_query]);
  1845. $blob++, next($this->blobs[$prepared_query])) {
  1846. $this->freeBlobValue($prepared_query, key($this->blobs[$prepared_query]), $this->blobs[$prepared_query][key($this->blobs[$prepared_query])], $success);
  1847. }
  1848. unset($this->blobs[$prepared_query]);
  1849. return($success);
  1850. }
  1851. // }}}
  1852. // {{{ execute()
  1853. /**
  1854. * Executes a prepared SQL query
  1855. * With execute() the generic query of prepare is assigned with the given
  1856. * data array. The values of the array inserted into the query in the same
  1857. * order like the array order
  1858. *
  1859. * @param resource $prepared_query query handle from prepare()
  1860. * @param array $types array that contains the types of the columns in
  1861. * the result set
  1862. * @param array $params numeric array containing the data to insert into
  1863. * the query
  1864. * @param array $param_types array that contains the types of the values
  1865. * defined in $params
  1866. * @return mixed a new result handle or a MDB_Error when fail
  1867. * @access public
  1868. * @see prepare()
  1869. */
  1870. function execute($prepared_query, $types = NULL, $params = FALSE, $param_types = NULL)
  1871. {
  1872. $this->setParamArray($prepared_query, $params, $param_types);
  1873. return($this->executeQuery($prepared_query, $types));
  1874. }
  1875. // }}}
  1876. // {{{ executeMultiple()
  1877. /**
  1878. * This function does several execute() calls on the same statement handle.
  1879. * $params must be an array indexed numerically from 0, one execute call is
  1880. * done for every 'row' in the array.
  1881. *
  1882. * If an error occurs during execute(), executeMultiple() does not execute
  1883. * the unfinished rows, but rather returns that error.
  1884. *
  1885. * @param resource $stmt query handle from prepare()
  1886. * @param array $types array that contains the types of the columns in
  1887. * the result set
  1888. * @param array $params numeric array containing the
  1889. * data to insert into the query
  1890. * @param array $parAM_types array that contains the types of the values
  1891. * defined in $params
  1892. * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1893. * @access public
  1894. * @see prepare(), execute()
  1895. */
  1896. function executeMultiple($prepared_query, $types = NULL, $params, $param_types = NULL)
  1897. {
  1898. for($i = 0, $j = count($params); $i < $j; $i++) {
  1899. $result = $this->execute($prepared_query, $types, $params[$i], $param_types);
  1900. if (MDB::isError($result)) {
  1901. return($result);
  1902. }
  1903. }
  1904. return(MDB_OK);
  1905. }
  1906. // }}}
  1907. // {{{ setParam()
  1908. /**
  1909. * Set the value of a parameter of a prepared query.
  1910. *
  1911. * @param int $prepared_query argument is a handle that was returned
  1912. * by the function prepareQuery()
  1913. * @param int $parameter the order number of the parameter in the query
  1914. * statement. The order number of the first parameter is 1.
  1915. * @param string $type designation of the type of the parameter to be set.
  1916. * The designation of the currently supported types is as follows:
  1917. * text, boolean, integer, decimal, float, date, time, timestamp,
  1918. * clob, blob
  1919. * @param mixed $value value that is meant to be assigned to specified
  1920. * parameter. The type of the value depends on the $type argument.
  1921. * @param boolean $is_null flag that indicates whether whether the
  1922. * parameter is a NULL
  1923. * @param string $field name of the field that is meant to be assigned
  1924. * with this parameter value when it is of type clob or blob
  1925. * @return mixed MDB_OK on success, a MDB error on failure
  1926. * @access public
  1927. */
  1928. function setParam($prepared_query, $parameter, $type, $value, $is_null = 0, $field = '')
  1929. {
  1930. $result = $this->_validatePreparedQuery($prepared_query);
  1931. if (MDB::isError($result)) {
  1932. return($result);
  1933. }
  1934. $index = $prepared_query - 1;
  1935. if ($parameter < 1 || $parameter > count($this->prepared_queries[$index]['Positions'])) {
  1936. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1937. 'Query set: it was not specified a valid argument number'));
  1938. }
  1939. $this->prepared_queries[$index]['Values'][$parameter-1] = $value;
  1940. $this->prepared_queries[$index]['Types'][$parameter-1] = $type;
  1941. $this->prepared_queries[$index]['Fields'][$parameter-1] = $field;
  1942. $this->prepared_queries[$index]['IsNULL'][$parameter-1] = $is_null;
  1943. return(MDB_OK);
  1944. }
  1945. // }}}
  1946. // {{{ setParamArray()
  1947. /**
  1948. * Set the values of multiple a parameter of a prepared query in bulk.
  1949. *
  1950. * @param int $prepared_query argument is a handle that was returned by
  1951. * the function prepareQuery()
  1952. * @param array $params array thats specifies all necessary infromation
  1953. * for setParam() the array elements must use keys corresponding to
  1954. * the number of the position of the parameter.
  1955. * @param array $types array thats specifies the types of the fields
  1956. * @return mixed MDB_OK on success, a MDB error on failure
  1957. * @access public
  1958. * @see setParam()
  1959. */
  1960. function setParamArray($prepared_query, $params, $types = NULL)
  1961. {
  1962. if (is_array($types)) {
  1963. if (count($params) != count($types)) {
  1964. return $this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1965. 'setParamArray: the number of given types ('.count($types).')'
  1966. .'is not corresponding to the number of given parameters ('.count($params).')');
  1967. }
  1968. for($i = 0, $j = count($params); $i < $j; ++$i) {
  1969. switch ($types[$i]) {
  1970. case 'NULL':
  1971. $success = $this->setParam($prepared_query, $i + 1, $params[$i][0], 'NULL', 1, '');
  1972. break;
  1973. case 'text':
  1974. $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  1975. break;
  1976. case 'clob':
  1977. $success = $this->setParam($prepared_query, $i + 1, 'clob', $params[$i][0], 0, $params[$i][1]);
  1978. break;
  1979. case 'blob':
  1980. $success = $this->setParam($prepared_query, $i + 1, 'blob', $params[$i][0], 0, $params[$i][1]);
  1981. break;
  1982. case 'integer':
  1983. $success = $this->setParam($prepared_query, $i + 1, 'integer', $this->getIntegerValue($params[$i]));
  1984. break;
  1985. case 'boolean':
  1986. $success = $this->setParam($prepared_query, $i + 1, 'boolean', $this->getBooleanValue($params[$i]));
  1987. break;
  1988. case 'date':
  1989. $success = $this->setParam($prepared_query, $i + 1, 'date', $this->getDateValue($params[$i]));
  1990. break;
  1991. case 'timestamp':
  1992. $success = $this->setParam($prepared_query, $i + 1, 'timestamp', $this->getTimestampValue($params[$i]));
  1993. break;
  1994. case 'time':
  1995. $success = $this->setParam($prepared_query, $i + 1, 'time', $this->getTimeValue($params[$i]));
  1996. break;
  1997. case 'float':
  1998. $success = $this->setParam($prepared_query, $i + 1, 'float', $this->getFloatValue($params[$i]));
  1999. break;
  2000. case 'decimal':
  2001. $success = $this->setParam($prepared_query, $i + 1, 'decimal', $this->getDecimalValue($params[$i]));
  2002. break;
  2003. default:
  2004. $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  2005. break;
  2006. }
  2007. if (MDB::isError($success)) {
  2008. return($success);
  2009. }
  2010. }
  2011. } else {
  2012. for($i = 0, $j = count($params); $i < $j; ++$i) {
  2013. $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  2014. if (MDB::isError($success)) {
  2015. return($success);
  2016. }
  2017. }
  2018. }
  2019. return(MDB_OK);
  2020. }
  2021. // }}}
  2022. // {{{ setParamNull()
  2023. /**
  2024. * Set the value of a parameter of a prepared query to NULL.
  2025. *
  2026. * @param int $prepared_query argument is a handle that was returned by
  2027. * the function prepareQuery()
  2028. * @param int $parameter order number of the parameter in the query
  2029. * statement. The order number of the first parameter is 1.
  2030. * @param string $type designation of the type of the parameter to be set.
  2031. * The designation of the currently supported types is list in the
  2032. * usage of the function setParam()
  2033. * @return mixed MDB_OK on success, a MDB error on failure
  2034. * @access public
  2035. * @see setParam()
  2036. */
  2037. function setParamNull($prepared_query, $parameter, $type)
  2038. {
  2039. return($this->setParam($prepared_query, $parameter, $type, 'NULL', 1, ''));
  2040. }
  2041. // }}}
  2042. // {{{ setParamText()
  2043. /**
  2044. * Set a parameter of a prepared query with a text value.
  2045. *
  2046. * @param int $prepared_query argument is a handle that was returned by
  2047. * the function prepareQuery()
  2048. * @param int $parameter order number of the parameter in the query
  2049. * statement. The order number of the first parameter is 1.
  2050. * @param string $value text value that is meant to be assigned to
  2051. * specified parameter.
  2052. * @return mixed MDB_OK on success, a MDB error on failure
  2053. * @access public
  2054. * @see setParam()
  2055. */
  2056. function setParamText($prepared_query, $parameter, $value)
  2057. {
  2058. return($this->setParam($prepared_query, $parameter, 'text', $this->getTextValue($value)));
  2059. }
  2060. // }}}
  2061. // {{{ setParamClob()
  2062. /**
  2063. * Set a parameter of a prepared query with a character large object value.
  2064. *
  2065. * @param int $prepared_query argument is a handle that was returned by
  2066. * the function prepareQuery()
  2067. * @param int $parameter order number of the parameter in the query
  2068. * statement. The order number of the first parameter is 1.
  2069. * @param int $value handle of large object created with createLOB()
  2070. * function from which it will be read the data value that is meant
  2071. * to be assigned to specified parameter.
  2072. * @param string $field name of the field of a INSERT or UPDATE query to
  2073. * which it will be assigned the value to specified parameter.
  2074. * @return mixed MDB_OK on success, a MDB error on failure
  2075. * @access public
  2076. * @see setParam()
  2077. */
  2078. function setParamClob($prepared_query, $parameter, $value, $field)
  2079. {
  2080. return($this->setParam($prepared_query, $parameter, 'clob', $value, 0, $field));
  2081. }
  2082. // }}}
  2083. // {{{ setParamBlob()
  2084. /**
  2085. * Set a parameter of a prepared query with a binary large object value.
  2086. *
  2087. * @param int $prepared_query argument is a handle that was returned by
  2088. * the function prepareQuery()
  2089. * @param int $parameter order number of the parameter in the query
  2090. * statement. The order number of the first parameter is 1.
  2091. * @param int $value handle of large object created with createLOB()
  2092. * function from which it will be read the data value that is meant
  2093. * to be assigned to specified parameter.
  2094. * @param string $field name of the field of a INSERT or UPDATE query to
  2095. * which it will be assigned the value to specified parameter.
  2096. * @return mixed MDB_OK on success, a MDB error on failure
  2097. * @access public
  2098. * @see setParam()
  2099. */
  2100. function setParamBlob($prepared_query, $parameter, $value, $field)
  2101. {
  2102. return($this->setParam($prepared_query, $parameter, 'blob', $value, 0, $field));
  2103. }
  2104. // }}}
  2105. // {{{ setParamInteger()
  2106. /**
  2107. * Set a parameter of a prepared query with a text value.
  2108. *
  2109. * @param int $prepared_query argument is a handle that was returned by
  2110. * the function prepareQuery()
  2111. * @param int $parameter order number of the parameter in the query
  2112. * statement. The order number of the first parameter is 1.
  2113. * @param int $value an integer value that is meant to be assigned to
  2114. * specified parameter.
  2115. * @return mixed MDB_OK on success, a MDB error on failure
  2116. * @access public
  2117. * @see setParam()
  2118. */
  2119. function setParamInteger($prepared_query, $parameter, $value)
  2120. {
  2121. return($this->setParam($prepared_query, $parameter, 'integer', $this->getIntegerValue($value)));
  2122. }
  2123. // }}}
  2124. // {{{ setParamBoolean()
  2125. /**
  2126. * Set a parameter of a prepared query with a boolean value.
  2127. *
  2128. * @param int $prepared_query argument is a handle that was returned by
  2129. * the function prepareQuery()
  2130. * @param int $parameter order number of the parameter in the query
  2131. * statement. The order number of the first parameter is 1.
  2132. * @param boolean $value boolean value that is meant to be assigned to
  2133. * specified parameter.
  2134. * @return mixed MDB_OK on success, a MDB error on failure
  2135. * @access public
  2136. * @see setParam()
  2137. */
  2138. function setParamBoolean($prepared_query, $parameter, $value)
  2139. {
  2140. return($this->setParam($prepared_query, $parameter, 'boolean', $this->getBooleanValue($value)));
  2141. }
  2142. // }}}
  2143. // {{{ setParamDate()
  2144. /**
  2145. * Set a parameter of a prepared query with a date value.
  2146. *
  2147. * @param int $prepared_query argument is a handle that was returned by
  2148. * the function prepareQuery()
  2149. * @param int $parameter order number of the parameter in the query
  2150. * statement. The order number of the first parameter is 1.
  2151. * @param string $value date value that is meant to be assigned to
  2152. * specified parameter.
  2153. * @return mixed MDB_OK on success, a MDB error on failure
  2154. * @access public
  2155. * @see setParam()
  2156. */
  2157. function setParamDate($prepared_query, $parameter, $value)
  2158. {
  2159. return($this->setParam($prepared_query, $parameter, 'date', $this->getDateValue($value)));
  2160. }
  2161. // }}}
  2162. // {{{ setParamTimestamp()
  2163. /**
  2164. * Set a parameter of a prepared query with a time stamp value.
  2165. *
  2166. * @param int $prepared_query argument is a handle that was returned by
  2167. * the function prepareQuery()
  2168. * @param int $parameter order number of the parameter in the query
  2169. * statement. The order number of the first parameter is 1.
  2170. * @param string $value time stamp value that is meant to be assigned to
  2171. * specified parameter.
  2172. * @return mixed MDB_OK on success, a MDB error on failure
  2173. * @access public
  2174. * @see setParam()
  2175. */
  2176. function setParamTimestamp($prepared_query, $parameter, $value)
  2177. {
  2178. return($this->setParam($prepared_query, $parameter, 'timestamp', $this->getTimestampValue($value)));
  2179. }
  2180. // }}}
  2181. // {{{ setParamTime()
  2182. /**
  2183. * Set a parameter of a prepared query with a time value.
  2184. *
  2185. * @param int $prepared_query argument is a handle that was returned by
  2186. * the function prepareQuery()
  2187. * @param int $parameter order number of the parameter in the query
  2188. * statement. The order number of the first parameter is 1.
  2189. * @param string $value time value that is meant to be assigned to
  2190. * specified parameter.
  2191. * @return mixed MDB_OK on success, a MDB error on failure
  2192. * @access public
  2193. * @see setParam()
  2194. */
  2195. function setParamTime($prepared_query, $parameter, $value)
  2196. {
  2197. return($this->setParam($prepared_query, $parameter, 'time', $this->getTimeValue($value)));
  2198. }
  2199. // }}}
  2200. // {{{ setParamFloat()
  2201. /**
  2202. * Set a parameter of a prepared query with a float value.
  2203. *
  2204. * @param int $prepared_query argument is a handle that was returned by
  2205. * the function prepareQuery()
  2206. * @param int $parameter order number of the parameter in the query
  2207. * statement. The order number of the first parameter is 1.
  2208. * @param string $value float value that is meant to be assigned to
  2209. * specified parameter.
  2210. * @return mixed MDB_OK on success, a MDB error on failure
  2211. * @access public
  2212. * @see setParam()
  2213. */
  2214. function setParamFloat($prepared_query, $parameter, $value)
  2215. {
  2216. return($this->setParam($prepared_query, $parameter, 'float', $this->getFloatValue($value)));
  2217. }
  2218. // }}}
  2219. // {{{ setParamDecimal()
  2220. /**
  2221. * Set a parameter of a prepared query with a decimal value.
  2222. *
  2223. * @param int $prepared_query argument is a handle that was returned by
  2224. * the function prepareQuery()
  2225. * @param int $parameter order number of the parameter in the query
  2226. * statement. The order number of the first parameter is 1.
  2227. * @param string $value decimal value that is meant to be assigned to
  2228. * specified parameter.
  2229. * @return mixed MDB_OK on success, a MDB error on failure
  2230. * @access public
  2231. * @see setParam()
  2232. */
  2233. function setParamDecimal($prepared_query, $parameter, $value)
  2234. {
  2235. return($this->setParam($prepared_query, $parameter, 'decimal', $this->getDecimalValue($value)));
  2236. }
  2237. // }}}
  2238. // {{{ setResultTypes()
  2239. /**
  2240. * Define the list of types to be associated with the columns of a given
  2241. * result set.
  2242. *
  2243. * This function may be called before invoking fetchInto(), fetchOne(),
  2244. * fetchRow(), fetchCol() and fetchAll() so that the necessary data type
  2245. * conversions are performed on the data to be retrieved by them. If this
  2246. * function is not called, the type of all result set columns is assumed
  2247. * to be text, thus leading to not perform any conversions.
  2248. *
  2249. * @param resource $result result identifier
  2250. * @param string $types array variable that lists the
  2251. * data types to be expected in the result set columns. If this array
  2252. * contains less types than the number of columns that are returned
  2253. * in the result set, the remaining columns are assumed to be of the
  2254. * type text. Currently, the types clob and blob are not fully
  2255. * supported.
  2256. * @return mixed MDB_OK on success, a MDB error on failure
  2257. * @access public
  2258. */
  2259. function setResultTypes($result, $types)
  2260. {
  2261. $result_value = intval($result);
  2262. if (isset($this->result_types[$result_value])) {
  2263. return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2264. 'Set result types: attempted to redefine the types of the columns of a result set'));
  2265. }
  2266. $columns = $this->numCols($result);
  2267. if (MDB::isError($columns)) {
  2268. return($columns);
  2269. }
  2270. if ($columns < count($types)) {
  2271. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  2272. 'Set result types: it were specified more result types (' . count($types) . ') than result columns (' . $columns . ')'));
  2273. }
  2274. $valid_types = array(
  2275. 'text' => MDB_TYPE_TEXT,
  2276. 'boolean' => MDB_TYPE_BOOLEAN,
  2277. 'integer' => MDB_TYPE_INTEGER,
  2278. 'decimal' => MDB_TYPE_DECIMAL,
  2279. 'float' => MDB_TYPE_FLOAT,
  2280. 'date' => MDB_TYPE_DATE,
  2281. 'time' => MDB_TYPE_TIME,
  2282. 'timestamp' => MDB_TYPE_TIMESTAMP,
  2283. 'clob' => MDB_TYPE_CLOB,
  2284. 'blob' => MDB_TYPE_BLOB
  2285. );
  2286. for($column = 0; $column < count($types); $column++) {
  2287. if (!isset($valid_types[$types[$column]])) {
  2288. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2289. 'Set result types: ' . $types[$column] . ' is not a supported column type'));
  2290. }
  2291. $this->result_types[$result_value][$column] = $valid_types[$types[$column]];
  2292. }
  2293. while ($column < $columns) {
  2294. $this->result_types[$result_value][$column] = MDB_TYPE_TEXT;
  2295. $column++;
  2296. }
  2297. return(MDB_OK);
  2298. }
  2299. // }}}
  2300. // {{{ affectedRows()
  2301. /**
  2302. * returns the affected rows of a query
  2303. *
  2304. * @return mixed MDB_Error or number of rows
  2305. * @access public
  2306. */
  2307. function affectedRows()
  2308. {
  2309. if ($this->affected_rows == -1) {
  2310. return($this->raiseError(MDB_ERROR_NEED_MORE_DATA));
  2311. }
  2312. return($this->affected_rows);
  2313. }
  2314. // }}}
  2315. // {{{ getColumnNames()
  2316. /**
  2317. * Retrieve the names of columns returned by the DBMS in a query result.
  2318. *
  2319. * @param resource $result result identifier
  2320. * @return mixed associative array variable
  2321. * that holds the names of columns. The indexes of the array are
  2322. * the column names mapped to lower case and the values are the
  2323. * respective numbers of the columns starting from 0. Some DBMS may
  2324. * not return any columns when the result set does not contain any
  2325. * rows.
  2326. * a MDB error on failure
  2327. * @access public
  2328. */
  2329. function getColumnNames($result)
  2330. {
  2331. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2332. 'Get column names: obtaining result column names is not implemented'));
  2333. }
  2334. // }}}
  2335. // {{{ numCols()
  2336. /**
  2337. * Count the number of columns returned by the DBMS in a query result.
  2338. *
  2339. * @param resource $result result identifier
  2340. * @return mixed integer value with the number of columns, a MDB error
  2341. * on failure
  2342. * @access public
  2343. */
  2344. function numCols($result)
  2345. {
  2346. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2347. 'Number of columns: obtaining the number of result columns is not implemented'));
  2348. }
  2349. // }}}
  2350. // {{{ endOfResult()
  2351. /**
  2352. * check if the end of the result set has been reached
  2353. *
  2354. * @param resource $result result identifier
  2355. * @return mixed TRUE or FALSE on sucess, a MDB error on failure
  2356. * @access public
  2357. */
  2358. function endOfResult($result)
  2359. {
  2360. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2361. 'End of result: end of result method not implemented'));
  2362. }
  2363. // }}}
  2364. // {{{ setFetchMode()
  2365. /**
  2366. * Sets which fetch mode should be used by default on queries
  2367. * on this connection.
  2368. *
  2369. * @param integer $fetchmode MDB_FETCHMODE_ORDERED or MDB_FETCHMODE_ASSOC,
  2370. * possibly bit-wise OR'ed with MDB_FETCHMODE_FLIPPED.
  2371. * @access public
  2372. * @see MDB_FETCHMODE_ORDERED
  2373. * @see MDB_FETCHMODE_ASSOC
  2374. * @see MDB_FETCHMODE_FLIPPED
  2375. */
  2376. function setFetchMode($fetchmode)
  2377. {
  2378. switch ($fetchmode) {
  2379. case MDB_FETCHMODE_ORDERED:
  2380. case MDB_FETCHMODE_ASSOC:
  2381. $this->fetchmode = $fetchmode;
  2382. break;
  2383. default:
  2384. return($this->raiseError('invalid fetchmode mode'));
  2385. }
  2386. }
  2387. // }}}
  2388. // {{{ fetch()
  2389. /**
  2390. * fetch value from a result set
  2391. *
  2392. * @param resource $result result identifier
  2393. * @param int $row number of the row where the data can be found
  2394. * @param int $field field number where the data can be found
  2395. * @return mixed string on success, a MDB error on failure
  2396. * @access public
  2397. */
  2398. function fetch($result, $row, $field)
  2399. {
  2400. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2401. 'Fetch: fetch result method not implemented'));
  2402. }
  2403. // }}}
  2404. // {{{ fetchLob()
  2405. /**
  2406. * fetch a lob value from a result set
  2407. *
  2408. * @param resource $result result identifier
  2409. * @param int $row number of the row where the data can be found
  2410. * @param int $field field number where the data can be found
  2411. * @return mixed string on success, a MDB error on failure
  2412. * @access public
  2413. */
  2414. function fetchLob($result, $row, $field)
  2415. {
  2416. $lob = count($this->lobs) + 1;
  2417. $this->lobs[$lob] = array(
  2418. 'Result' => $result,
  2419. 'Row' => $row,
  2420. 'Field' => $field,
  2421. 'Position' => 0
  2422. );
  2423. $dst_lob = array(
  2424. 'Database' => $this,
  2425. 'Error' => '',
  2426. 'Type' => 'resultlob',
  2427. 'ResultLOB' => $lob
  2428. );
  2429. if (MDB::isError($lob = $this->createLob($dst_lob))) {
  2430. return($this->raiseError(MDB_ERROR, NULL, NULL,
  2431. 'Fetch LOB result: ' . $dst_lob['Error']));
  2432. }
  2433. return($lob);
  2434. }
  2435. // }}}
  2436. // {{{ _retrieveLob()
  2437. /**
  2438. * fetch a float value from a result set
  2439. *
  2440. * @param int $lob handle to a lob created by the createLob() function
  2441. * @return mixed MDB_OK on success, a MDB error on failure
  2442. * @access private
  2443. */
  2444. function _retrieveLob($lob)
  2445. {
  2446. if (!isset($this->lobs[$lob])) {
  2447. return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  2448. 'Fetch LOB result: it was not specified a valid lob'));
  2449. }
  2450. if (!isset($this->lobs[$lob]['Value'])) {
  2451. $this->lobs[$lob]['Value'] = $this->fetch($this->lobs[$lob]['Result'], $this->lobs[$lob]['Row'], $this->lobs[$lob]['Field']);
  2452. }
  2453. return(MDB_OK);
  2454. }
  2455. // }}}
  2456. // {{{ endOfResultLob()
  2457. /**
  2458. * Determine whether it was reached the end of the large object and
  2459. * therefore there is no more data to be read for the its input stream.
  2460. *
  2461. * @param int $lob handle to a lob created by the createLob() function
  2462. * @return mixed TRUE or FALSE on success, a MDB error on failure
  2463. * @access public
  2464. */
  2465. function endOfResultLob($lob)
  2466. {
  2467. $result = $this->_retrieveLob($lob);
  2468. if (MDB::isError($result)) {
  2469. return($result);
  2470. }
  2471. return($this->lobs[$lob]['Position'] >= strlen($this->lobs[$lob]['Value']));
  2472. }
  2473. // }}}
  2474. // {{{ _readResultLob()
  2475. /**
  2476. * Read data from large object input stream.
  2477. *
  2478. * @param int $lob handle to a lob created by the createLob() function
  2479. * @param blob $data reference to a variable that will hold data to be
  2480. * read from the large object input stream
  2481. * @param int $length integer value that indicates the largest ammount of
  2482. * data to be read from the large object input stream.
  2483. * @return mixed length on success, a MDB error on failure
  2484. * @access private
  2485. */
  2486. function _readResultLob($lob, &$data, $length)
  2487. {
  2488. $result = $this->_retrieveLob($lob);
  2489. if (MDB::isError($result)) {
  2490. return($result);
  2491. }
  2492. $length = min($length, strlen($this->lobs[$lob]['Value']) - $this->lobs[$lob]['Position']);
  2493. $data = substr($this->lobs[$lob]['Value'], $this->lobs[$lob]['Position'], $length);
  2494. $this->lobs[$lob]['Position'] += $length;
  2495. return($length);
  2496. }
  2497. // }}}
  2498. // {{{ _destroyResultLob()
  2499. /**
  2500. * Free any resources allocated during the lifetime of the large object
  2501. * handler object.
  2502. *
  2503. * @param int $lob handle to a lob created by the createLob() function
  2504. * @access private
  2505. */
  2506. function _destroyResultLob($lob)
  2507. {
  2508. if (isset($this->lobs[$lob])) {
  2509. $this->lobs[$lob] = '';
  2510. }
  2511. }
  2512. // }}}
  2513. // {{{ fetchClob()
  2514. /**
  2515. * fetch a clob value from a result set
  2516. *
  2517. * @param resource $result result identifier
  2518. * @param int $row number of the row where the data can be found
  2519. * @param int $field field number where the data can be found
  2520. * @return mixed content of the specified data cell, a MDB error on failure,
  2521. * a MDB error on failure
  2522. * @access public
  2523. */
  2524. function fetchClob($result, $row, $field)
  2525. {
  2526. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2527. 'fetch clob result method is not implemented'));
  2528. }
  2529. // }}}
  2530. // {{{ fetchBlob()
  2531. /**
  2532. * fetch a blob value from a result set
  2533. *
  2534. * @param resource $result result identifier
  2535. * @param int $row number of the row where the data can be found
  2536. * @param int $field field number where the data can be found
  2537. * @return mixed content of the specified data cell, a MDB error on failure
  2538. * @access public
  2539. */
  2540. function fetchBlob($result, $row, $field)
  2541. {
  2542. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2543. 'fetch blob result method is not implemented'));
  2544. }
  2545. // }}}
  2546. // {{{ resultIsNull()
  2547. /**
  2548. * Determine whether the value of a query result located in given row and
  2549. * field is a NULL.
  2550. *
  2551. * @param resource $result result identifier
  2552. * @param int $row number of the row where the data can be found
  2553. * @param int $field field number where the data can be found
  2554. * @return mixed TRUE or FALSE on success, a MDB error on failure
  2555. * @access public
  2556. */
  2557. function resultIsNull($result, $row, $field)
  2558. {
  2559. $result = $this->fetch($result, $row, $field);
  2560. if (MDB::isError($result)) {
  2561. return($result);
  2562. }
  2563. return(!isset($result));
  2564. }
  2565. // }}}
  2566. // {{{ _baseConvertResult()
  2567. /**
  2568. * general type conversion method
  2569. *
  2570. * @param mixed $value refernce to a value to be converted
  2571. * @param int $type constant that specifies which type to convert to
  2572. * @return object a MDB error on failure
  2573. * @access private
  2574. */
  2575. function _baseConvertResult($value, $type)
  2576. {
  2577. switch ($type) {
  2578. case MDB_TYPE_TEXT:
  2579. return($value);
  2580. case MDB_TYPE_BLOB:
  2581. return($value);
  2582. case MDB_TYPE_CLOB:
  2583. return($value);
  2584. case MDB_TYPE_INTEGER:
  2585. return(intval($value));
  2586. case MDB_TYPE_BOOLEAN:
  2587. return ($value == 'Y') ? TRUE : FALSE;
  2588. case MDB_TYPE_DECIMAL:
  2589. return($value);
  2590. case MDB_TYPE_FLOAT:
  2591. return(doubleval($value));
  2592. case MDB_TYPE_DATE:
  2593. return($value);
  2594. case MDB_TYPE_TIME:
  2595. return($value);
  2596. case MDB_TYPE_TIMESTAMP:
  2597. return($value);
  2598. case MDB_TYPE_CLOB:
  2599. return($value);
  2600. case MDB_TYPE_BLOB:
  2601. return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2602. 'BaseConvertResult: attempt to convert result value to an unsupported type ' . $type));
  2603. default:
  2604. return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2605. 'BaseConvertResult: attempt to convert result value to an unknown type ' . $type));
  2606. }
  2607. }
  2608. // }}}
  2609. // {{{ convertResult()
  2610. /**
  2611. * convert a value to a RDBMS indepdenant MDB type
  2612. *
  2613. * @param mixed $value value to be converted
  2614. * @param int $type constant that specifies which type to convert to
  2615. * @return mixed converted value or a MDB error on failure
  2616. * @access public
  2617. */
  2618. function convertResult($value, $type)
  2619. {
  2620. return($this->_baseConvertResult($value, $type));
  2621. }
  2622. // }}}
  2623. // {{{ convertResultRow()
  2624. /**
  2625. * convert a result row
  2626. *
  2627. * @param resource $result result identifier
  2628. * @param array $row array with data
  2629. * @return mixed MDB_OK on success, a MDB error on failure
  2630. * @access public
  2631. */
  2632. function convertResultRow($result, $row)
  2633. {
  2634. $result_value = intval($result);
  2635. if (isset($this->result_types[$result_value])) {
  2636. $current_column = -1;
  2637. foreach($row as $key => $column) {
  2638. ++$current_column;
  2639. if (!isset($this->result_types[$result_value][$current_column])
  2640. ||!isset($column)
  2641. ) {
  2642. continue;
  2643. }
  2644. switch ($type = $this->result_types[$result_value][$current_column]) {
  2645. case MDB_TYPE_TEXT:
  2646. case MDB_TYPE_BLOB:
  2647. case MDB_TYPE_CLOB:
  2648. break;
  2649. case MDB_TYPE_INTEGER:
  2650. $row[$key] = intval($row[$key]);
  2651. break;
  2652. default:
  2653. $value = $this->convertResult($row[$key], $type);
  2654. if (MDB::isError($value)) {
  2655. return $value;
  2656. }
  2657. $row[$key] = $value;
  2658. break;
  2659. }
  2660. }
  2661. }
  2662. return ($row);
  2663. }
  2664. // }}}
  2665. // {{{ fetchDate()
  2666. /**
  2667. * fetch a date value from a result set
  2668. *
  2669. * @param resource $result result identifier
  2670. * @param int $row number of the row where the data can be found
  2671. * @param int $field field number where the data can be found
  2672. * @return mixed content of the specified data cell, a MDB error on failure
  2673. * @access public
  2674. */
  2675. function fetchDate($result, $row, $field)
  2676. {
  2677. $value = $this->fetch($result, $row, $field);
  2678. return($this->convertResult($value, MDB_TYPE_DATE));
  2679. }
  2680. // }}}
  2681. // {{{ fetchTimestamp()
  2682. /**
  2683. * fetch a timestamp value from a result set
  2684. *
  2685. * @param resource $result result identifier
  2686. * @param int $row number of the row where the data can be found
  2687. * @param int $field field number where the data can be found
  2688. * @return mixed content of the specified data cell, a MDB error on failure
  2689. * @access public
  2690. */
  2691. function fetchTimestamp($result, $row, $field)
  2692. {
  2693. $value = $this->fetch($result, $row, $field);
  2694. return($this->convertResult($value, MDB_TYPE_TIMESTAMP));
  2695. }
  2696. // }}}
  2697. // {{{ fetchTime()
  2698. /**
  2699. * fetch a time value from a result set
  2700. *
  2701. * @param resource $result result identifier
  2702. * @param int $row number of the row where the data can be found
  2703. * @param int $field field number where the data can be found
  2704. * @return mixed content of the specified data cell, a MDB error on failure
  2705. * @access public
  2706. */
  2707. function fetchTime($result, $row, $field)
  2708. {
  2709. $value = $this->fetch($result, $row, $field);
  2710. return($this->convertResult($value, MDB_TYPE_TIME));
  2711. }
  2712. // }}}
  2713. // {{{ fetchBoolean()
  2714. /**
  2715. * fetch a boolean value from a result set
  2716. *
  2717. * @param resource $result result identifier
  2718. * @param int $row number of the row where the data can be found
  2719. * @param int $field field number where the data can be found
  2720. * @return mixed content of the specified data cell, a MDB error on failure
  2721. * @access public
  2722. */
  2723. function fetchBoolean($result, $row, $field)
  2724. {
  2725. $value = $this->fetch($result, $row, $field);
  2726. return($this->convertResult($value, MDB_TYPE_BOOLEAN));
  2727. }
  2728. // }}}
  2729. // {{{ fetchFloat()
  2730. /**
  2731. * fetch a float value from a result set
  2732. *
  2733. * @param resource $result result identifier
  2734. * @param int $row number of the row where the data can be found
  2735. * @param int $field field number where the data can be found
  2736. * @return mixed content of the specified data cell, a MDB error on failure
  2737. * @access public
  2738. */
  2739. function fetchFloat($result, $row, $field)
  2740. {
  2741. $value = $this->fetch($result, $row, $field);
  2742. return($this->convertResult($value, MDB_TYPE_FLOAT));
  2743. }
  2744. // }}}
  2745. // {{{ fetchDecimal()
  2746. /**
  2747. * fetch a decimal value from a result set
  2748. *
  2749. * @param resource $result result identifier
  2750. * @param int $row number of the row where the data can be found
  2751. * @param int $field field number where the data can be found
  2752. * @return mixed content of the specified data cell, a MDB error on failure
  2753. * @access public
  2754. */
  2755. function fetchDecimal($result, $row, $field)
  2756. {
  2757. $value = $this->fetch($result, $row, $field);
  2758. return($this->convertResult($value, MDB_TYPE_DECIMAL));
  2759. }
  2760. // }}}
  2761. // {{{ numRows()
  2762. /**
  2763. * returns the number of rows in a result object
  2764. *
  2765. * @param ressource $result a valid result ressouce pointer
  2766. * @return mixed MDB_Error or the number of rows
  2767. * @access public
  2768. */
  2769. function numRows($result)
  2770. {
  2771. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Num Rows: number of rows method not implemented'));
  2772. }
  2773. // }}}
  2774. // {{{ freeResult()
  2775. /**
  2776. * Free the internal resources associated with $result.
  2777. *
  2778. * @param $result result identifier
  2779. * @return boolean TRUE on success, FALSE if $result is invalid
  2780. * @access public
  2781. */
  2782. function freeResult($result)
  2783. {
  2784. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Free Result: free result method not implemented'));
  2785. }
  2786. // }}}
  2787. // {{{ getIntegerDeclaration()
  2788. /**
  2789. * Obtain DBMS specific SQL code portion needed to declare an integer type
  2790. * field to be used in statements like CREATE TABLE.
  2791. *
  2792. * @param string $name name the field to be declared.
  2793. * @param string $field associative array with the name of the properties
  2794. * of the field being declared as array indexes. Currently, the types
  2795. * of supported field properties are as follows:
  2796. *
  2797. * unsigned
  2798. * Boolean flag that indicates whether the field should be
  2799. * declared as unsigned integer if possible.
  2800. *
  2801. * default
  2802. * Integer value to be used as default for this field.
  2803. *
  2804. * notnull
  2805. * Boolean flag that indicates whether this field is constrained
  2806. * to not be set to NULL.
  2807. * @return string DBMS specific SQL code portion that should be used to
  2808. * declare the specified field.
  2809. * @access public
  2810. */
  2811. function getIntegerDeclaration($name, $field)
  2812. {
  2813. if (isset($field['unsigned'])) {
  2814. $this->warnings[] = "unsigned integer field \"$name\" is being
  2815. declared as signed integer";
  2816. }
  2817. return("$name INT" . (isset($field['default']) ? ' DEFAULT ' . $field['default'] : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2818. }
  2819. // }}}
  2820. // {{{ getTextDeclaration()
  2821. /**
  2822. * Obtain DBMS specific SQL code portion needed to declare an text type
  2823. * field to be used in statements like CREATE TABLE.
  2824. *
  2825. * @param string $name name the field to be declared.
  2826. * @param string $field associative array with the name of the properties
  2827. * of the field being declared as array indexes. Currently, the types
  2828. * of supported field properties are as follows:
  2829. *
  2830. * length
  2831. * Integer value that determines the maximum length of the text
  2832. * field. If this argument is missing the field should be
  2833. * declared to have the longest length allowed by the DBMS.
  2834. *
  2835. * default
  2836. * Text value to be used as default for this field.
  2837. *
  2838. * notnull
  2839. * Boolean flag that indicates whether this field is constrained
  2840. * to not be set to NULL.
  2841. * @return string DBMS specific SQL code portion that should be used to
  2842. * declare the specified field.
  2843. * @access public
  2844. */
  2845. function getTextDeclaration($name, $field)
  2846. {
  2847. return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2848. }
  2849. // }}}
  2850. // {{{ getClobDeclaration()
  2851. /**
  2852. * Obtain DBMS specific SQL code portion needed to declare an character
  2853. * large object type field to be used in statements like CREATE TABLE.
  2854. *
  2855. * @param string $name name the field to be declared.
  2856. * @param string $field associative array with the name of the properties
  2857. * of the field being declared as array indexes. Currently, the types
  2858. * of supported field properties are as follows:
  2859. *
  2860. * length
  2861. * Integer value that determines the maximum length of the large
  2862. * object field. If this argument is missing the field should be
  2863. * declared to have the longest length allowed by the DBMS.
  2864. *
  2865. * notnull
  2866. * Boolean flag that indicates whether this field is constrained
  2867. * to not be set to NULL.
  2868. * @return string DBMS specific SQL code portion that should be used to
  2869. * declare the specified field.
  2870. * @access public
  2871. */
  2872. function getClobDeclaration($name, $field)
  2873. {
  2874. return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2875. }
  2876. // }}}
  2877. // {{{ getBlobDeclaration()
  2878. /**
  2879. * Obtain DBMS specific SQL code portion needed to declare an binary large
  2880. * object type field to be used in statements like CREATE TABLE.
  2881. *
  2882. * @param string $name name the field to be declared.
  2883. * @param string $field associative array with the name of the properties
  2884. * of the field being declared as array indexes. Currently, the types
  2885. * of supported field properties are as follows:
  2886. *
  2887. * length
  2888. * Integer value that determines the maximum length of the large
  2889. * object field. If this argument is missing the field should be
  2890. * declared to have the longest length allowed by the DBMS.
  2891. *
  2892. * notnull
  2893. * Boolean flag that indicates whether this field is constrained
  2894. * to not be set to NULL.
  2895. * @return string DBMS specific SQL code portion that should be used to
  2896. * declare the specified field.
  2897. * @access public
  2898. */
  2899. function getBlobDeclaration($name, $field)
  2900. {
  2901. return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2902. }
  2903. // }}}
  2904. // {{{ getBooleanDeclaration()
  2905. /**
  2906. * Obtain DBMS specific SQL code portion needed to declare a boolean type
  2907. * field to be used in statements like CREATE TABLE.
  2908. *
  2909. * @param string $name name the field to be declared.
  2910. * @param string $field associative array with the name of the properties
  2911. * of the field being declared as array indexes. Currently, the types
  2912. * of supported field properties are as follows:
  2913. *
  2914. * default
  2915. * Boolean value to be used as default for this field.
  2916. *
  2917. * notnullL
  2918. * Boolean flag that indicates whether this field is constrained
  2919. * to not be set to NULL.
  2920. * @return string DBMS specific SQL code portion that should be used to
  2921. * declare the specified field.
  2922. * @access public
  2923. */
  2924. function getBooleanDeclaration($name, $field)
  2925. {
  2926. return("$name CHAR (1)" . (isset($field['default']) ? ' DEFAULT ' . $this->getBooleanValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2927. }
  2928. // }}}
  2929. // {{{ getDateDeclaration()
  2930. /**
  2931. * Obtain DBMS specific SQL code portion needed to declare a date type
  2932. * field to be used in statements like CREATE TABLE.
  2933. *
  2934. * @param string $name name the field to be declared.
  2935. * @param string $field associative array with the name of the properties
  2936. * of the field being declared as array indexes. Currently, the types
  2937. * of supported field properties are as follows:
  2938. *
  2939. * default
  2940. * Date value to be used as default for this field.
  2941. *
  2942. * notnull
  2943. * Boolean flag that indicates whether this field is constrained
  2944. * to not be set to NULL.
  2945. * @return string DBMS specific SQL code portion that should be used to
  2946. * declare the specified field.
  2947. * @access public
  2948. */
  2949. function getDateDeclaration($name, $field)
  2950. {
  2951. return("$name CHAR (" . strlen("YYYY-MM-DD") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getDateValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2952. }
  2953. // }}}
  2954. // {{{ getTimestampDeclaration()
  2955. /**
  2956. * Obtain DBMS specific SQL code portion needed to declare a timestamp
  2957. * field to be used in statements like CREATE TABLE.
  2958. *
  2959. * @param string $name name the field to be declared.
  2960. * @param string $field associative array with the name of the properties
  2961. * of the field being declared as array indexes. Currently, the types
  2962. * of supported field properties are as follows:
  2963. *
  2964. * default
  2965. * Timestamp value to be used as default for this field.
  2966. *
  2967. * notnull
  2968. * Boolean flag that indicates whether this field is constrained
  2969. * to not be set to NULL.
  2970. * @return string DBMS specific SQL code portion that should be used to
  2971. * declare the specified field.
  2972. * @access public
  2973. */
  2974. function getTimestampDeclaration($name, $field)
  2975. {
  2976. return("$name CHAR (" . strlen("YYYY-MM-DD HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimestampValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  2977. }
  2978. // }}}
  2979. // {{{ getTimeDeclaration()
  2980. /**
  2981. * Obtain DBMS specific SQL code portion needed to declare a time
  2982. * field to be used in statements like CREATE TABLE.
  2983. *
  2984. * @param string $name name the field to be declared.
  2985. * @param string $field associative array with the name of the properties
  2986. * of the field being declared as array indexes. Currently, the types
  2987. * of supported field properties are as follows:
  2988. *
  2989. * default
  2990. * Time value to be used as default for this field.
  2991. *
  2992. * notnull
  2993. * Boolean flag that indicates whether this field is constrained
  2994. * to not be set to NULL.
  2995. * @return string DBMS specific SQL code portion that should be used to
  2996. * declare the specified field.
  2997. * @access public
  2998. */
  2999. function getTimeDeclaration($name, $field)
  3000. {
  3001. return("$name CHAR (" . strlen("HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimeValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3002. }
  3003. // }}}
  3004. // {{{ getFloatDeclaration()
  3005. /**
  3006. * Obtain DBMS specific SQL code portion needed to declare a float type
  3007. * field to be used in statements like CREATE TABLE.
  3008. *
  3009. * @param string $name name the field to be declared.
  3010. * @param string $field associative array with the name of the properties
  3011. * of the field being declared as array indexes. Currently, the types
  3012. * of supported field properties are as follows:
  3013. *
  3014. * default
  3015. * Float value to be used as default for this field.
  3016. *
  3017. * notnull
  3018. * Boolean flag that indicates whether this field is constrained
  3019. * to not be set to NULL.
  3020. * @return string DBMS specific SQL code portion that should be used to
  3021. * declare the specified field.
  3022. * @access public
  3023. */
  3024. function getFloatDeclaration($name, $field)
  3025. {
  3026. return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getFloatValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3027. }
  3028. // }}}
  3029. // {{{ getDecimalDeclaration()
  3030. /**
  3031. * Obtain DBMS specific SQL code portion needed to declare a decimal type
  3032. * field to be used in statements like CREATE TABLE.
  3033. *
  3034. * @param string $name name the field to be declared.
  3035. * @param string $field associative array with the name of the properties
  3036. * of the field being declared as array indexes. Currently, the types
  3037. * of supported field properties are as follows:
  3038. *
  3039. * default
  3040. * Decimal value to be used as default for this field.
  3041. *
  3042. * notnull
  3043. * Boolean flag that indicates whether this field is constrained
  3044. * to not be set to NULL.
  3045. * @return string DBMS specific SQL code portion that should be used to
  3046. * declare the specified field.
  3047. * @access public
  3048. */
  3049. function getDecimalDeclaration($name, $field)
  3050. {
  3051. return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getDecimalValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3052. }
  3053. // }}}
  3054. // {{{ getIntegerValue()
  3055. /**
  3056. * Convert a text value into a DBMS specific format that is suitable to
  3057. * compose query statements.
  3058. *
  3059. * @param string $value text string value that is intended to be converted.
  3060. * @return string text string that represents the given argument value in
  3061. * a DBMS specific format.
  3062. * @access public
  3063. */
  3064. function getIntegerValue($value)
  3065. {
  3066. return(($value === NULL) ? 'NULL' : (int)$value);
  3067. }
  3068. // }}}
  3069. // {{{ getTextValue()
  3070. /**
  3071. * Convert a text value into a DBMS specific format that is suitable to
  3072. * compose query statements.
  3073. *
  3074. * @param string $value text string value that is intended to be converted.
  3075. * @return string text string that already contains any DBMS specific
  3076. * escaped character sequences.
  3077. * @access public
  3078. */
  3079. function getTextValue($value)
  3080. {
  3081. return(($value === NULL) ? 'NULL' : "'".$this->_quote($value)."'");
  3082. }
  3083. // }}}
  3084. // {{{ getClobValue()
  3085. /**
  3086. * Convert a text value into a DBMS specific format that is suitable to
  3087. * compose query statements.
  3088. *
  3089. * @param resource $prepared_query query handle from prepare()
  3090. * @param $parameter
  3091. * @param $clob
  3092. * @return string text string that represents the given argument value in
  3093. * a DBMS specific format.
  3094. * @access public
  3095. */
  3096. function getClobValue($prepared_query, $parameter, $clob)
  3097. {
  3098. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  3099. 'Get CLOB field value: prepared queries with values of type "clob" are not yet supported'));
  3100. }
  3101. // }}}
  3102. // {{{ freeClobValue()
  3103. /**
  3104. * free a character large object
  3105. *
  3106. * @param resource $prepared_query query handle from prepare()
  3107. * @param string $blob
  3108. * @param string $value
  3109. * @access public
  3110. */
  3111. function freeClobValue($prepared_query, $clob, &$value)
  3112. {
  3113. }
  3114. // }}}
  3115. // {{{ getBlobValue()
  3116. /**
  3117. * Convert a text value into a DBMS specific format that is suitable to
  3118. * compose query statements.
  3119. *
  3120. * @param resource $prepared_query query handle from prepare()
  3121. * @param $parameter
  3122. * @param $blob
  3123. * @return string text string that represents the given argument value in
  3124. * a DBMS specific format.
  3125. * @access public
  3126. */
  3127. function getBlobValue($prepared_query, $parameter, $blob)
  3128. {
  3129. return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  3130. 'Get BLOB field value: prepared queries with values of type "blob" are not yet supported'));
  3131. }
  3132. // }}}
  3133. // {{{ freeBlobValue()
  3134. /**
  3135. * free a binary large object
  3136. *
  3137. * @param resource $prepared_query query handle from prepare()
  3138. * @param string $blob
  3139. * @param string $value
  3140. * @access public
  3141. */
  3142. function freeBlobValue($prepared_query, $blob, &$value)
  3143. {
  3144. }
  3145. // }}}
  3146. // {{{ getBooleanValue()
  3147. /**
  3148. * Convert a text value into a DBMS specific format that is suitable to
  3149. * compose query statements.
  3150. *
  3151. * @param string $value text string value that is intended to be converted.
  3152. * @return string text string that represents the given argument value in
  3153. * a DBMS specific format.
  3154. * @access public
  3155. */
  3156. function getBooleanValue($value)
  3157. {
  3158. return(($value === NULL) ? 'NULL' : ($value ? "'Y'" : "'N'"));
  3159. }
  3160. // }}}
  3161. // {{{ getDateValue()
  3162. /**
  3163. * Convert a text value into a DBMS specific format that is suitable to
  3164. * compose query statements.
  3165. *
  3166. * @param string $value text string value that is intended to be converted.
  3167. * @return string text string that represents the given argument value in
  3168. * a DBMS specific format.
  3169. * @access public
  3170. */
  3171. function getDateValue($value)
  3172. {
  3173. return(($value === NULL) ? 'NULL' : "'$value'");
  3174. }
  3175. // }}}
  3176. // {{{ getTimestampValue()
  3177. /**
  3178. * Convert a text value into a DBMS specific format that is suitable to
  3179. * compose query statements.
  3180. *
  3181. * @param string $value text string value that is intended to be converted.
  3182. * @return string text string that represents the given argument value in
  3183. * a DBMS specific format.
  3184. * @access public
  3185. */
  3186. function getTimestampValue($value)
  3187. {
  3188. return(($value === NULL) ? 'NULL' : "'$value'");
  3189. }
  3190. // }}}
  3191. // {{{ getTimeValue()
  3192. /**
  3193. * Convert a text value into a DBMS specific format that is suitable to
  3194. * compose query statements.
  3195. *
  3196. * @param string $value text string value that is intended to be converted.
  3197. * @return string text string that represents the given argument value in
  3198. * a DBMS specific format.
  3199. * @access public
  3200. */
  3201. function getTimeValue($value)
  3202. {
  3203. return(($value === NULL) ? 'NULL' : "'$value'");
  3204. }
  3205. // }}}
  3206. // {{{ getFloatValue()
  3207. /**
  3208. * Convert a text value into a DBMS specific format that is suitable to
  3209. * compose query statements.
  3210. *
  3211. * @param string $value text string value that is intended to be converted.
  3212. * @return string text string that represents the given argument value in
  3213. * a DBMS specific format.
  3214. * @access public
  3215. */
  3216. function getFloatValue($value)
  3217. {
  3218. return(($value === NULL) ? 'NULL' : "'$value'");
  3219. }
  3220. // }}}
  3221. // {{{ getDecimalValue()
  3222. /**
  3223. * Convert a text value into a DBMS specific format that is suitable to
  3224. * compose query statements.
  3225. *
  3226. * @param string $value text string value that is intended to be converted.
  3227. * @return string text string that represents the given argument value in
  3228. * a DBMS specific format.
  3229. * @access public
  3230. */
  3231. function getDecimalValue($value)
  3232. {
  3233. return(($value === NULL) ? 'NULL' : "'$value'");
  3234. }
  3235. // }}}
  3236. // {{{ getValue()
  3237. /**
  3238. * Convert a text value into a DBMS specific format that is suitable to
  3239. * compose query statements.
  3240. *
  3241. * @param string $type type to which the value should be converted to
  3242. * @param string $value text string value that is intended to be converted.
  3243. * @return string text string that represents the given argument value in
  3244. * a DBMS specific format.
  3245. * @access public
  3246. */
  3247. function getValue($type, $value)
  3248. {
  3249. if (empty($type)) {
  3250. return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  3251. 'getValue: called without type to convert to'));
  3252. }
  3253. if (method_exists($this,"get{$type}Value")) {
  3254. return $this->{"get{$type}Value"}($value);
  3255. }
  3256. return $value;
  3257. }
  3258. // }}}
  3259. // {{{ support()
  3260. /**
  3261. * Tell whether a DB implementation or its backend extension
  3262. * supports a given feature.
  3263. *
  3264. * @param string $feature name of the feature (see the MDB class doc)
  3265. * @return boolean whether this DB implementation supports $feature
  3266. * @access public
  3267. */
  3268. function support($feature)
  3269. {
  3270. return(isset($this->supported[$feature]) && $this->supported[$feature]);
  3271. }
  3272. // }}}
  3273. // {{{ getSequenceName()
  3274. /**
  3275. * adds sequence name formating to a sequence name
  3276. *
  3277. * @param string $sqn name of the sequence
  3278. * @return string formatted sequence name
  3279. * @access public
  3280. */
  3281. function getSequenceName($sqn)
  3282. {
  3283. return sprintf($this->options['seqname_format'],
  3284. preg_replace('/[^a-z0-9_]/i', '_', $sqn));
  3285. }
  3286. // }}}
  3287. // {{{ nextId()
  3288. /**
  3289. * returns the next free id of a sequence
  3290. *
  3291. * @param string $seq_name name of the sequence
  3292. * @param boolean $ondemand when TRUE the seqence is
  3293. * automatic created, if it
  3294. * not exists
  3295. * @return mixed MDB_Error or id
  3296. * @access public
  3297. */
  3298. function nextId($seq_name, $ondemand = FALSE)
  3299. {
  3300. return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
  3301. 'Next Sequence: getting next sequence value not supported'));
  3302. }
  3303. // }}}
  3304. // {{{ currId()
  3305. /**
  3306. * returns the current id of a sequence
  3307. *
  3308. * @param string $seq_name name of the sequence
  3309. * @return mixed MDB_Error or id
  3310. * @access public
  3311. */
  3312. function currId($seq_name)
  3313. {
  3314. $this->warnings[] = 'database does not support getting current
  3315. sequence value, the sequence value was incremented';
  3316. $this->expectError(MDB_ERROR_NOT_CAPABLE);
  3317. $id = $this->nextId($seq_name);
  3318. $this->popExpect(MDB_ERROR_NOT_CAPABLE);
  3319. if (MDB::isError($id)) {
  3320. if ($id->getCode() == MDB_ERROR_NOT_CAPABLE) {
  3321. return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
  3322. 'Current Sequence: getting current sequence value not supported'));
  3323. }
  3324. return($id);
  3325. }
  3326. return($id);
  3327. }
  3328. // }}}
  3329. // {{{ fetchInto()
  3330. /**
  3331. * Fetch a row and return data in an array.
  3332. *
  3333. * @param resource $result result identifier
  3334. * @param int $fetchmode ignored
  3335. * @param int $rownum the row number to fetch
  3336. * @return mixed data array or NULL on success, a MDB error on failure
  3337. * @access public
  3338. */
  3339. function fetchInto($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
  3340. {
  3341. $result_value = intval($result);
  3342. if (MDB::isError($this->endOfResult($result))) {
  3343. $this->freeResult($result);
  3344. $result = $this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  3345. 'Fetch field: result set is empty');
  3346. }
  3347. if ($rownum == NULL) {
  3348. ++$this->highest_fetched_row[$result_value];
  3349. $rownum = $this->highest_fetched_row[$result_value];
  3350. } else {
  3351. $this->highest_fetched_row[$result_value] =
  3352. max($this->highest_fetched_row[$result_value], $row);
  3353. }
  3354. if ($fetchmode == MDB_FETCHMODE_DEFAULT) {
  3355. $fetchmode = $this->fetchmode;
  3356. }
  3357. $columns = $this->numCols($result);
  3358. if (MDB::isError($columns)) {
  3359. return($columns);
  3360. }
  3361. if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3362. $column_names = $this->getColumnNames($result);
  3363. }
  3364. for($column = 0; $column < $columns; $column++) {
  3365. if (!$this->resultIsNull($result, $rownum, $column)) {
  3366. $value = $this->fetch($result, $rownum, $column);
  3367. if ($value === FALSE) {
  3368. if ($this->options['autofree']) {
  3369. $this->freeResult($result);
  3370. }
  3371. return(NULL);
  3372. } elseif (MDB::isError($value)) {
  3373. if ($value->getMessage() == '') {
  3374. if ($this->options['autofree']) {
  3375. $this->freeResult($result);
  3376. }
  3377. return(NULL);
  3378. } else {
  3379. return($value);
  3380. }
  3381. }
  3382. }
  3383. $row[$column] = $value;
  3384. }
  3385. if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3386. $row = array_combine($column_names, $row);
  3387. if (is_array($row) && $this->options['optimize'] == 'portability') {
  3388. $row = array_change_key_case($row, CASE_LOWER);
  3389. }
  3390. }
  3391. if (isset($this->result_types[$result_value])) {
  3392. $row = $this->convertResultRow($result, $row);
  3393. }
  3394. return($row);
  3395. }
  3396. // }}}
  3397. // {{{ fetchOne()
  3398. /**
  3399. * Fetch and return a field of data (it uses fetchInto for that)
  3400. *
  3401. * @param resource $result result identifier
  3402. * @return mixed data on success, a MDB error on failure
  3403. * @access public
  3404. */
  3405. function fetchOne($result)
  3406. {
  3407. $row = $this->fetchInto($result, MDB_FETCHMODE_ORDERED);
  3408. if (!$this->options['autofree'] || $row != NULL) {
  3409. $this->freeResult($result);
  3410. }
  3411. if (is_array($row)) {
  3412. return($row[0]);
  3413. }
  3414. return($row);
  3415. }
  3416. // }}}
  3417. // {{{ fetchRow()
  3418. /**
  3419. * Fetch and return a row of data (it uses fetchInto for that)
  3420. *
  3421. * @param resource $result result identifier
  3422. * @param int $fetchmode how the array data should be indexed
  3423. * @param int $rownum the row number to fetch
  3424. * @return mixed data array on success, a MDB error on failure
  3425. * @access public
  3426. */
  3427. function fetchRow($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
  3428. {
  3429. $row = $this->fetchInto($result, $fetchmode, $rownum);
  3430. if (!$this->options['autofree'] || $row != NULL) {
  3431. $this->freeResult($result);
  3432. }
  3433. return($row);
  3434. }
  3435. // }}}
  3436. // {{{ fetchCol()
  3437. /**
  3438. * Fetch and return a column of data (it uses fetchInto for that)
  3439. *
  3440. * @param resource $result result identifier
  3441. * @param int $colnum the row number to fetch
  3442. * @return mixed data array on success, a MDB error on failure
  3443. * @access public
  3444. */
  3445. function fetchCol($result, $colnum = 0)
  3446. {
  3447. $fetchmode = is_numeric($colnum) ? MDB_FETCHMODE_ORDERED : MDB_FETCHMODE_ASSOC;
  3448. $column = array();
  3449. $row = $this->fetchInto($result, $fetchmode);
  3450. if (is_array($row)) {
  3451. if (!array_key_exists($colnum, $row)) {
  3452. return($this->raiseError(MDB_ERROR_TRUNCATED));
  3453. }
  3454. do {
  3455. $column[] = $row[$colnum];
  3456. } while (is_array($row = $this->fetchInto($result, $fetchmode)));
  3457. }
  3458. if (!$this->options['autofree']) {
  3459. $this->freeResult($result);
  3460. }
  3461. if (MDB::isError($row)) {
  3462. return($row);
  3463. }
  3464. return($column);
  3465. }
  3466. // }}}
  3467. // {{{ fetchAll()
  3468. /**
  3469. * Fetch and return a column of data (it uses fetchInto for that)
  3470. *
  3471. * @param resource $result result identifier
  3472. * @param int $fetchmode how the array data should be indexed
  3473. * @param boolean $rekey if set to TRUE, the $all will have the first
  3474. * column as its first dimension
  3475. * @param boolean $force_array used only when the query returns exactly
  3476. * two columns. If TRUE, the values of the returned array will be
  3477. * one-element arrays instead of scalars.
  3478. * @param boolean $group if TRUE, the values of the returned array is
  3479. * wrapped in another array. If the same key value (in the first
  3480. * column) repeats itself, the values will be appended to this array
  3481. * instead of overwriting the existing values.
  3482. * @return mixed data array on success, a MDB error on failure
  3483. * @access public
  3484. * @see getAssoc()
  3485. */
  3486. function fetchAll($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rekey = FALSE, $force_array = FALSE, $group = FALSE)
  3487. {
  3488. if ($rekey) {
  3489. $cols = $this->numCols($result);
  3490. if (MDB::isError($cols)) {
  3491. return($cols);
  3492. }
  3493. if ($cols < 2) {
  3494. return($this->raiseError(MDB_ERROR_TRUNCATED));
  3495. }
  3496. }
  3497. $all = array();
  3498. while (is_array($row = $this->fetchInto($result, $fetchmode))) {
  3499. if ($rekey) {
  3500. if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3501. $key = reset($row);
  3502. unset($row[key($row)]);
  3503. } else {
  3504. $key = array_shift($row);
  3505. }
  3506. if (!$force_array && count($row) == 1) {
  3507. $row = array_shift($row);
  3508. }
  3509. if ($group) {
  3510. $all[$key][] = $row;
  3511. } else {
  3512. $all[$key] = $row;
  3513. }
  3514. } else {
  3515. if ($fetchmode & MDB_FETCHMODE_FLIPPED) {
  3516. foreach ($row as $key => $val) {
  3517. $all[$key][] = $val;
  3518. }
  3519. } else {
  3520. $all[] = $row;
  3521. }
  3522. }
  3523. }
  3524. if (!$this->options['autofree']) {
  3525. $this->freeResult($result);
  3526. }
  3527. if (MDB::isError($row)) {
  3528. return($row);
  3529. }
  3530. return($all);
  3531. }
  3532. // }}}
  3533. // {{{ queryOne()
  3534. /**
  3535. * Execute the specified query, fetch the value from the first column of
  3536. * the first row of the result set and then frees
  3537. * the result set.
  3538. *
  3539. * @param string $query the SELECT query statement to be executed.
  3540. * @param string $type optional argument that specifies the expected
  3541. * datatype of the result set field, so that an eventual conversion
  3542. * may be performed. The default datatype is text, meaning that no
  3543. * conversion is performed
  3544. * @return mixed field value on success, a MDB error on failure
  3545. * @access public
  3546. */
  3547. function queryOne($query, $type = NULL)
  3548. {
  3549. if ($type != NULL) {
  3550. $type = array($type);
  3551. }
  3552. $result = $this->query($query, $type);
  3553. if (MDB::isError($result)) {
  3554. return($result);
  3555. }
  3556. return($this->fetchOne($result));
  3557. }
  3558. // }}}
  3559. // {{{ queryRow()
  3560. /**
  3561. * Execute the specified query, fetch the values from the first
  3562. * row of the result set into an array and then frees
  3563. * the result set.
  3564. *
  3565. * @param string $query the SELECT query statement to be executed.
  3566. * @param array $types optional array argument that specifies a list of
  3567. * expected datatypes of the result set columns, so that the eventual
  3568. * conversions may be performed. The default list of datatypes is
  3569. * empty, meaning that no conversion is performed.
  3570. * @param int $fetchmode how the array data should be indexed
  3571. * @return mixed data array on success, a MDB error on failure
  3572. * @access public
  3573. */
  3574. function queryRow($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  3575. {
  3576. $result = $this->query($query, $types);
  3577. if (MDB::isError($result)) {
  3578. return($result);
  3579. }
  3580. return($this->fetchRow($result, $fetchmode));
  3581. }
  3582. // }}}
  3583. // {{{ queryCol()
  3584. /**
  3585. * Execute the specified query, fetch the value from the first column of
  3586. * each row of the result set into an array and then frees the result set.
  3587. *
  3588. * @param string $query the SELECT query statement to be executed.
  3589. * @param string $type optional argument that specifies the expected
  3590. * datatype of the result set field, so that an eventual conversion
  3591. * may be performed. The default datatype is text, meaning that no
  3592. * conversion is performed
  3593. * @param int $colnum the row number to fetch
  3594. * @return mixed data array on success, a MDB error on failure
  3595. * @access public
  3596. */
  3597. function queryCol($query, $type = NULL, $colnum = 0)
  3598. {
  3599. if ($type != NULL) {
  3600. $type = array($type);
  3601. }
  3602. $result = $this->query($query, $type);
  3603. if (MDB::isError($result)) {
  3604. return($result);
  3605. }
  3606. return($this->fetchCol($result, $colnum));
  3607. }
  3608. // }}}
  3609. // {{{ queryAll()
  3610. /**
  3611. * Execute the specified query, fetch all the rows of the result set into
  3612. * a two dimensional array and then frees the result set.
  3613. *
  3614. * @param string $query the SELECT query statement to be executed.
  3615. * @param array $types optional array argument that specifies a list of
  3616. * expected datatypes of the result set columns, so that the eventual
  3617. * conversions may be performed. The default list of datatypes is
  3618. * empty, meaning that no conversion is performed.
  3619. * @param int $fetchmode how the array data should be indexed
  3620. * @param boolean $rekey if set to TRUE, the $all will have the first
  3621. * column as its first dimension
  3622. * @param boolean $force_array used only when the query returns exactly
  3623. * two columns. If TRUE, the values of the returned array will be
  3624. * one-element arrays instead of scalars.
  3625. * @param boolean $group if TRUE, the values of the returned array is
  3626. * wrapped in another array. If the same key value (in the first
  3627. * column) repeats itself, the values will be appended to this array
  3628. * instead of overwriting the existing values.
  3629. * @return mixed data array on success, a MDB error on failure
  3630. * @access public
  3631. */
  3632. function queryAll($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT,
  3633. $rekey = FALSE, $force_array = FALSE, $group = FALSE)
  3634. {
  3635. if (MDB::isError($result = $this->query($query, $types))) {
  3636. return($result);
  3637. }
  3638. return($this->fetchAll($result, $fetchmode, $rekey, $force_array, $group));
  3639. }
  3640. // }}}
  3641. // {{{ getOne()
  3642. /**
  3643. * Fetch the first column of the first row of data returned from
  3644. * a query. Takes care of doing the query and freeing the results
  3645. * when finished.
  3646. *
  3647. * @param string $query the SQL query
  3648. * @param string $type string that contains the type of the column in the
  3649. * result set
  3650. * @param array $params if supplied, prepare/execute will be used
  3651. * with this array as execute parameters
  3652. * @param array $param_types array that contains the types of the values
  3653. * defined in $params
  3654. * @return mixed MDB_Error or the returned value of the query
  3655. * @access public
  3656. */
  3657. function getOne($query, $type = NULL, $params = array(), $param_types = NULL)
  3658. {
  3659. if ($type != NULL) {
  3660. $type = array($type);
  3661. }
  3662. settype($params, 'array');
  3663. if (count($params) > 0) {
  3664. $prepared_query = $this->prepareQuery($query);
  3665. if (MDB::isError($prepared_query)) {
  3666. return($prepared_query);
  3667. }
  3668. $this->setParamArray($prepared_query, $params, $param_types);
  3669. $result = $this->executeQuery($prepared_query, $type);
  3670. } else {
  3671. $result = $this->query($query, $type);
  3672. }
  3673. if (MDB::isError($result)) {
  3674. return($result);
  3675. }
  3676. $value = $this->fetchOne($result, MDB_FETCHMODE_ORDERED);
  3677. if (MDB::isError($value)) {
  3678. return($value);
  3679. }
  3680. if (isset($prepared_query)) {
  3681. $result = $this->freePreparedQuery($prepared_query);
  3682. if (MDB::isError($result)) {
  3683. return($result);
  3684. }
  3685. }
  3686. return($value);
  3687. }
  3688. // }}}
  3689. // {{{ getRow()
  3690. /**
  3691. * Fetch the first row of data returned from a query. Takes care
  3692. * of doing the query and freeing the results when finished.
  3693. *
  3694. * @param string $query the SQL query
  3695. * @param array $types array that contains the types of the columns in
  3696. * the result set
  3697. * @param array $params array if supplied, prepare/execute will be used
  3698. * with this array as execute parameters
  3699. * @param array $param_types array that contains the types of the values
  3700. * defined in $params
  3701. * @param integer $fetchmode the fetch mode to use
  3702. * @return array the first row of results as an array indexed from
  3703. * 0, or a MDB error code.
  3704. * @access public
  3705. */
  3706. function getRow($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  3707. {
  3708. settype($params, 'array');
  3709. if (count($params) > 0) {
  3710. $prepared_query = $this->prepareQuery($query);
  3711. if (MDB::isError($prepared_query)) {
  3712. return($prepared_query);
  3713. }
  3714. $this->setParamArray($prepared_query, $params, $param_types);
  3715. $result = $this->executeQuery($prepared_query, $types);
  3716. } else {
  3717. $result = $this->query($query, $types);
  3718. }
  3719. if (MDB::isError($result)) {
  3720. return($result);
  3721. }
  3722. $row = $this->fetchRow($result, $fetchmode);
  3723. if (MDB::isError($row)) {
  3724. return($row);
  3725. }
  3726. if (isset($prepared_query)) {
  3727. $result = $this->freePreparedQuery($prepared_query);
  3728. if (MDB::isError($result)) {
  3729. return($result);
  3730. }
  3731. }
  3732. return($row);
  3733. }
  3734. // }}}
  3735. // {{{ getCol()
  3736. /**
  3737. * Fetch a single column from a result set and return it as an
  3738. * indexed array.
  3739. *
  3740. * @param string $query the SQL query
  3741. * @param string $type string that contains the type of the column in the
  3742. * result set
  3743. * @param array $params array if supplied, prepare/execute will be used
  3744. * with this array as execute parameters
  3745. * @param array $param_types array that contains the types of the values
  3746. * defined in $params
  3747. * @param mixed $colnum which column to return(integer [column number,
  3748. * starting at 0] or string [column name])
  3749. * @return array an indexed array with the data from the first
  3750. * row at index 0, or a MDB error code.
  3751. * @access public
  3752. */
  3753. function getCol($query, $type = NULL, $params = array(), $param_types = NULL, $colnum = 0)
  3754. {
  3755. if ($type != NULL) {
  3756. $type = array($type);
  3757. }
  3758. settype($params, 'array');
  3759. if (count($params) > 0) {
  3760. $prepared_query = $this->prepareQuery($query);
  3761. if (MDB::isError($prepared_query)) {
  3762. return($prepared_query);
  3763. }
  3764. $this->setParamArray($prepared_query, $params, $param_types);
  3765. $result = $this->executeQuery($prepared_query, $type);
  3766. } else {
  3767. $result = $this->query($query, $type);
  3768. }
  3769. if (MDB::isError($result)) {
  3770. return($result);
  3771. }
  3772. $col = $this->fetchCol($result, $colnum);
  3773. if (MDB::isError($col)) {
  3774. return($col);
  3775. }
  3776. if (isset($prepared_query)) {
  3777. $result = $this->freePreparedQuery($prepared_query);
  3778. if (MDB::isError($result)) {
  3779. return($result);
  3780. }
  3781. }
  3782. return($col);
  3783. }
  3784. // }}}
  3785. // {{{ getAssoc()
  3786. /**
  3787. * Fetch the entire result set of a query and return it as an
  3788. * associative array using the first column as the key.
  3789. *
  3790. * If the result set contains more than two columns, the value
  3791. * will be an array of the values from column 2-n. If the result
  3792. * set contains only two columns, the returned value will be a
  3793. * scalar with the value of the second column (unless forced to an
  3794. * array with the $force_array parameter). A MDB error code is
  3795. * returned on errors. If the result set contains fewer than two
  3796. * columns, a MDB_ERROR_TRUNCATED error is returned.
  3797. *
  3798. * For example, if the table 'mytable' contains:
  3799. *
  3800. * ID TEXT DATE
  3801. * --------------------------------
  3802. * 1 'one' 944679408
  3803. * 2 'two' 944679408
  3804. * 3 'three' 944679408
  3805. *
  3806. * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  3807. * array(
  3808. * '1' => 'one',
  3809. * '2' => 'two',
  3810. * '3' => 'three',
  3811. * )
  3812. *
  3813. * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  3814. * array(
  3815. * '1' => array('one', '944679408'),
  3816. * '2' => array('two', '944679408'),
  3817. * '3' => array('three', '944679408')
  3818. * )
  3819. *
  3820. * If the more than one row occurs with the same value in the
  3821. * first column, the last row overwrites all previous ones by
  3822. * default. Use the $group parameter if you don't want to
  3823. * overwrite like this. Example:
  3824. *
  3825. * getAssoc('SELECT category,id,name FROM mytable', NULL, NULL
  3826. * MDB_FETCHMODE_ASSOC, FALSE, TRUE) returns:
  3827. * array(
  3828. * '1' => array(array('id' => '4', 'name' => 'number four'),
  3829. * array('id' => '6', 'name' => 'number six')
  3830. * ),
  3831. * '9' => array(array('id' => '4', 'name' => 'number four'),
  3832. * array('id' => '6', 'name' => 'number six')
  3833. * )
  3834. * )
  3835. *
  3836. * Keep in mind that database functions in PHP usually return string
  3837. * values for results regardless of the database's internal type.
  3838. *
  3839. * @param string $query the SQL query
  3840. * @param array $types array that contains the types of the columns in
  3841. * the result set
  3842. * @param array $params array if supplied, prepare/execute will be used
  3843. * with this array as execute parameters
  3844. * @param array $param_types array that contains the types of the values
  3845. * defined in $params
  3846. * @param boolean $force_array used only when the query returns
  3847. * exactly two columns. If TRUE, the values of the returned array
  3848. * will be one-element arrays instead of scalars.
  3849. * @param boolean $group if TRUE, the values of the returned array
  3850. * is wrapped in another array. If the same key value (in the first
  3851. * column) repeats itself, the values will be appended to this array
  3852. * instead of overwriting the existing values.
  3853. * @return array associative array with results from the query.
  3854. * @access public
  3855. */
  3856. function getAssoc($query, $types = NULL, $params = array(), $param_types = NULL,
  3857. $fetchmode = MDB_FETCHMODE_ORDERED, $force_array = FALSE, $group = FALSE)
  3858. {
  3859. settype($params, 'array');
  3860. if (count($params) > 0) {
  3861. $prepared_query = $this->prepareQuery($query);
  3862. if (MDB::isError($prepared_query)) {
  3863. return($prepared_query);
  3864. }
  3865. $this->setParamArray($prepared_query, $params, $param_types);
  3866. $result = $this->executeQuery($prepared_query, $types);
  3867. } else {
  3868. $result = $this->query($query, $types);
  3869. }
  3870. if (MDB::isError($result)) {
  3871. return($result);
  3872. }
  3873. $all = $this->fetchAll($result, $fetchmode, TRUE, $force_array, $group);
  3874. if (MDB::isError($all)) {
  3875. return($all);
  3876. }
  3877. if (isset($prepared_query)) {
  3878. $result = $this->freePreparedQuery($prepared_query);
  3879. if (MDB::isError($result)) {
  3880. return($result);
  3881. }
  3882. }
  3883. return($all);
  3884. }
  3885. // }}}
  3886. // {{{ getAll()
  3887. /**
  3888. * Fetch all the rows returned from a query.
  3889. *
  3890. * @param string $query the SQL query
  3891. * @param array $types array that contains the types of the columns in
  3892. * the result set
  3893. * @param array $params array if supplied, prepare/execute will be used
  3894. * with this array as execute parameters
  3895. * @param array $param_types array that contains the types of the values
  3896. * defined in $params
  3897. * @param integer $fetchmode the fetch mode to use
  3898. * @return array an nested array, or a MDB error
  3899. * @access public
  3900. */
  3901. function getAll($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  3902. {
  3903. settype($params, 'array');
  3904. if (count($params) > 0) {
  3905. $prepared_query = $this->prepareQuery($query);
  3906. if (MDB::isError($prepared_query)) {
  3907. return($prepared_query);
  3908. }
  3909. $this->setParamArray($prepared_query, $params, $param_types);
  3910. $result = $this->executeQuery($prepared_query, $types);
  3911. } else {
  3912. $result = $this->query($query, $types);
  3913. }
  3914. if (MDB::isError($result)) {
  3915. return($result);
  3916. }
  3917. $all = $this->fetchAll($result, $fetchmode);
  3918. if (MDB::isError($all)) {
  3919. return($all);
  3920. }
  3921. if (isset($prepared_query)) {
  3922. $result = $this->freePreparedQuery($prepared_query);
  3923. if (MDB::isError($result)) {
  3924. return($result);
  3925. }
  3926. }
  3927. return($all);
  3928. }
  3929. // }}}
  3930. // {{{ tableInfo()
  3931. /**
  3932. * returns meta data about the result set
  3933. *
  3934. * @param resource $result result identifier
  3935. * @param mixed $mode depends on implementation
  3936. * @return array an nested array, or a MDB error
  3937. * @access public
  3938. */
  3939. function tableInfo($result, $mode = NULL)
  3940. {
  3941. return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
  3942. }
  3943. // }}}
  3944. // {{{ createLob()
  3945. /**
  3946. * Create a handler object of a specified class with functions to
  3947. * retrieve data from a large object data stream.
  3948. *
  3949. * @param array $arguments An associative array with parameters to create
  3950. * the handler object. The array indexes are the names of
  3951. * the parameters and the array values are the respective
  3952. * parameter values.
  3953. *
  3954. * Some parameters are specific of the class of each type
  3955. * of handler object that is created. The following
  3956. * parameters are common to all handler object classes:
  3957. *
  3958. * Type
  3959. *
  3960. * Name of the type of the built-in supported class
  3961. * that will be used to create the handler object.
  3962. * There are currently four built-in types of handler
  3963. * object classes: data, resultlob, inputfile and
  3964. * outputfile.
  3965. *
  3966. * The data handler class is the default class. It
  3967. * simply reads data from a given data string.
  3968. *
  3969. * The resultlob handler class is meant to read data
  3970. * from a large object retrieved from a query result.
  3971. * This class is not used directly by applications.
  3972. *
  3973. * The inputfile handler class is meant to read data
  3974. * from a file to use in prepared queries with large
  3975. * object field parameters.
  3976. *
  3977. * The outputfile handler class is meant to write to
  3978. * a file data from result columns with large object
  3979. * fields. The functions to read from this type of
  3980. * large object do not return any data. Instead, the
  3981. * data is just written to the output file with the
  3982. * data retrieved from a specified large object handle.
  3983. *
  3984. * Class
  3985. *
  3986. * Name of the class of the handler object that will be
  3987. * created if the Type argument is not specified. This
  3988. * argument should be used when you need to specify a
  3989. * custom handler class.
  3990. *
  3991. * Database
  3992. *
  3993. * Database object as returned by MDB::connect.
  3994. * This is an option argument needed by some handler
  3995. * classes like resultlob.
  3996. *
  3997. * The following arguments are specific of the inputfile
  3998. * handler class:
  3999. *
  4000. * File
  4001. *
  4002. * Integer handle value of a file already opened
  4003. * for writing.
  4004. *
  4005. * FileName
  4006. *
  4007. * Name of a file to be opened for writing if the
  4008. * File argument is not specified.
  4009. *
  4010. * The following arguments are specific of the outputfile
  4011. * handler class:
  4012. *
  4013. * File
  4014. *
  4015. * Integer handle value of a file already opened
  4016. * for writing.
  4017. *
  4018. * FileName
  4019. *
  4020. * Name of a file to be opened for writing if the
  4021. * File argument is not specified.
  4022. *
  4023. * BufferLength
  4024. *
  4025. * Integer value that specifies the length of a
  4026. * buffer that will be used to read from the
  4027. * specified large object.
  4028. *
  4029. * LOB
  4030. *
  4031. * Integer handle value that specifies a large
  4032. * object from which the data to be stored in the
  4033. * output file will be written.
  4034. *
  4035. * Result
  4036. *
  4037. * Integer handle value as returned by the function
  4038. * MDB::query() or MDB::executeQuery() that specifies
  4039. * the result set that contains the large object value
  4040. * to be retrieved. If the LOB argument is specified,
  4041. * this argument is ignored.
  4042. *
  4043. * Row
  4044. *
  4045. * Integer value that specifies the number of the
  4046. * row of the result set that contains the large
  4047. * object value to be retrieved. If the LOB
  4048. * argument is specified, this argument is ignored.
  4049. *
  4050. * Field
  4051. *
  4052. * Integer or string value that specifies the
  4053. * number or the name of the column of the result
  4054. * set that contains the large object value to be
  4055. * retrieved. If the LOB argument is specified,
  4056. * this argument is ignored.
  4057. *
  4058. * Binary
  4059. *
  4060. * Boolean value that specifies whether the large
  4061. * object column to be retrieved is of binary type
  4062. * (blob) or otherwise is of character type (clob).
  4063. * If the LOB argument is specified, this argument
  4064. * is ignored.
  4065. *
  4066. * The following argument is specific of the data
  4067. * handler class:
  4068. *
  4069. * Data
  4070. *
  4071. * String of data that will be returned by the class
  4072. * when it requested with the readLOB() method.
  4073. *
  4074. * The following argument is specific of the resultlob
  4075. * handler class:
  4076. *
  4077. * ResultLOB
  4078. *
  4079. * Integer handle value of a large object result
  4080. * row field.
  4081. * @return integer handle value that should be passed as argument insubsequent
  4082. * calls to functions that retrieve data from the large object input stream.
  4083. * @access public
  4084. */
  4085. function createLob($arguments)
  4086. {
  4087. $result = $this->loadLob('Create LOB');
  4088. if (MDB::isError($result)) {
  4089. return($result);
  4090. }
  4091. $class_name = 'MDB_LOB';
  4092. if (isset($arguments['Type'])) {
  4093. switch ($arguments['Type']) {
  4094. case 'data':
  4095. break;
  4096. case 'resultlob':
  4097. $class_name = 'MDB_LOB_Result';
  4098. break;
  4099. case 'inputfile':
  4100. $class_name = 'MDB_LOB_Input_File';
  4101. break;
  4102. case 'outputfile':
  4103. $class_name = 'MDB_LOB_Output_File';
  4104. break;
  4105. default:
  4106. if (isset($arguments['Error'])) {
  4107. $arguments['Error'] = $arguments['Type'] . ' is not a valid type of large object';
  4108. }
  4109. return($this->raiseError());
  4110. }
  4111. } else {
  4112. if (isset($arguments['Class'])) {
  4113. $class = $arguments['Class'];
  4114. }
  4115. }
  4116. $lob = count($GLOBALS['_MDB_lobs']) + 1;
  4117. $GLOBALS['_MDB_lobs'][$lob] = &new $class_name;
  4118. if (isset($arguments['Database'])) {
  4119. $GLOBALS['_MDB_lobs'][$lob]->database = $arguments['Database'];
  4120. } else {
  4121. $GLOBALS['_MDB_lobs'][$lob]->database = &$this;
  4122. }
  4123. if (MDB::isError($result = $GLOBALS['_MDB_lobs'][$lob]->create($arguments))) {
  4124. $GLOBALS['_MDB_lobs'][$lob]->database->destroyLob($lob);
  4125. return($result);
  4126. }
  4127. return($lob);
  4128. }
  4129. // }}}
  4130. // {{{ readLob()
  4131. /**
  4132. * Read data from large object input stream.
  4133. *
  4134. * @param integer $lob argument handle that is returned by the
  4135. * MDB::createLob() method.
  4136. * @param string $data reference to a variable that will hold data
  4137. * to be read from the large object input stream
  4138. * @param integer $length value that indicates the largest ammount ofdata
  4139. * to be read from the large object input stream.
  4140. * @return mixed the effective number of bytes read from the large object
  4141. * input stream on sucess or an MDB error object.
  4142. * @access public
  4143. * @see endOfLob()
  4144. */
  4145. function readLob($lob, &$data, $length)
  4146. {
  4147. return($GLOBALS['_MDB_lobs'][$lob]->readLob($data, $length));
  4148. }
  4149. // }}}
  4150. // {{{ endOfLob()
  4151. /**
  4152. * Determine whether it was reached the end of the large object and
  4153. * therefore there is no more data to be read for the its input stream.
  4154. *
  4155. * @param integer $lob argument handle that is returned by the
  4156. * MDB::createLob() method.
  4157. * @access public
  4158. * @return boolean flag that indicates whether it was reached the end of the large object input stream
  4159. */
  4160. function endOfLob($lob)
  4161. {
  4162. return($GLOBALS['_MDB_lobs'][$lob]->endOfLob());
  4163. }
  4164. // }}}
  4165. // {{{ destroyLob()
  4166. /**
  4167. * Free any resources allocated during the lifetime of the large object
  4168. * handler object.
  4169. *
  4170. * @param integer $lob argument handle that is returned by the
  4171. * MDB::createLob() method.
  4172. * @access public
  4173. */
  4174. function destroyLob($lob)
  4175. {
  4176. $GLOBALS['_MDB_lobs'][$lob]->destroy();
  4177. unset($GLOBALS['_MDB_lobs'][$lob]);
  4178. }
  4179. // }}}
  4180. // {{{ Destructor
  4181. /**
  4182. * this function closes open transactions to be executed at shutdown
  4183. *
  4184. * @access private
  4185. */
  4186. function _MDB_Common()
  4187. {
  4188. if ($this->in_transaction && !MDB::isError($this->rollback())) {
  4189. $this->autoCommit(TRUE);
  4190. }
  4191. }
  4192. };
  4193. ?>