summaryrefslogtreecommitdiff
path: root/program/lib/MDB2
diff options
context:
space:
mode:
Diffstat (limited to 'program/lib/MDB2')
-rwxr-xr-xprogram/lib/MDB2/Date.php180
-rwxr-xr-xprogram/lib/MDB2/Driver/Datatype/Common.php1263
-rwxr-xr-xprogram/lib/MDB2/Driver/Manager/Common.php616
-rwxr-xr-xprogram/lib/MDB2/Extended.php605
-rwxr-xr-xprogram/lib/MDB2/Iterator.php285
-rwxr-xr-xprogram/lib/MDB2/LOB.php146
-rwxr-xr-xprogram/lib/MDB2/Wrapper/peardb.php750
7 files changed, 3845 insertions, 0 deletions
diff --git a/program/lib/MDB2/Date.php b/program/lib/MDB2/Date.php
new file mode 100755
index 000000000..df3af2c3d
--- /dev/null
+++ b/program/lib/MDB2/Date.php
@@ -0,0 +1,180 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+//
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+/**
+ * Several methods to convert the MDB2 native timestamp format (ISO based)
+ * to and from data structures that are convienient to worth with in side of php.
+ * For more complex date arithmetic please take a look at the Date package in PEAR
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class MDB2_Date
+{
+ // {{{ mdbNow()
+
+ /**
+ * return the current datetime
+ *
+ * @return string current datetime in the MDB2 format
+ * @access public
+ */
+ function mdbNow()
+ {
+ return date('Y-m-d H:i:s');
+ }
+
+ // }}}
+ // {{{ mdbToday()
+
+ /**
+ * return the current date
+ *
+ * @return string current date in the MDB2 format
+ * @access public
+ */
+ function mdbToday()
+ {
+ return date('Y-m-d');
+ }
+
+ // }}}
+ // {{{ mdbTime()
+
+ /**
+ * return the current time
+ *
+ * @return string current time in the MDB2 format
+ * @access public
+ */
+ function mdbTime()
+ {
+ return date('H:i:s');
+ }
+
+ // }}}
+ // {{{ date2Mdbstamp()
+
+ /**
+ * convert a date into a MDB2 timestamp
+ *
+ * @param integer $hour hour of the date
+ * @param integer $minute minute of the date
+ * @param integer $second second of the date
+ * @param integer $month month of the date
+ * @param integer $day day of the date
+ * @param integer $year year of the date
+ * @return string a valid MDB2 timestamp
+ * @access public
+ */
+ function date2Mdbstamp($hour = null, $minute = null, $second = null,
+ $month = null, $day = null, $year = null)
+ {
+ return MDB2_Date::unix2Mdbstamp(mktime($hour, $minute, $second, $month, $day, $year, -1));
+ }
+
+ // }}}
+ // {{{ unix2Mdbstamp()
+
+ /**
+ * convert a unix timestamp into a MDB2 timestamp
+ *
+ * @param integer $unix_timestamp a valid unix timestamp
+ * @return string a valid MDB2 timestamp
+ * @access public
+ */
+ function unix2Mdbstamp($unix_timestamp)
+ {
+ return date('Y-m-d H:i:s', $unix_timestamp);
+ }
+
+ // }}}
+ // {{{ mdbstamp2Unix()
+
+ /**
+ * convert a MDB2 timestamp into a unix timestamp
+ *
+ * @param integer $mdb_timestamp a valid MDB2 timestamp
+ * @return string unix timestamp with the time stored in the MDB2 format
+ * @access public
+ */
+ function mdbstamp2Unix($mdb_timestamp)
+ {
+ $arr = MDB2_Date::mdbstamp2Date($mdb_timestamp);
+
+ return mktime($arr['hour'], $arr['minute'], $arr['second'], $arr['month'], $arr['day'], $arr['year'], -1);
+ }
+
+ // }}}
+ // {{{ mdbstamp2Date()
+
+ /**
+ * convert a MDB2 timestamp into an array containing all
+ * values necessary to pass to php's date() function
+ *
+ * @param integer $mdb_timestamp a valid MDB2 timestamp
+ * @return array with the time split
+ * @access public
+ */
+ function mdbstamp2Date($mdb_timestamp)
+ {
+ list($arr['year'], $arr['month'], $arr['day'], $arr['hour'], $arr['minute'], $arr['second']) =
+ sscanf($mdb_timestamp, "%04u-%02u-%02u %02u:%02u:%02u");
+ return $arr;
+ }
+
+ // }}}
+}
+
+?>
diff --git a/program/lib/MDB2/Driver/Datatype/Common.php b/program/lib/MDB2/Driver/Datatype/Common.php
new file mode 100755
index 000000000..808fd1881
--- /dev/null
+++ b/program/lib/MDB2/Driver/Datatype/Common.php
@@ -0,0 +1,1263 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'MDB2/LOB.php';
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+/**
+ * MDB2_Driver_Common: Base class that is extended by each MDB2 driver
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class MDB2_Driver_Datatype_Common extends MDB2_Module_Common
+{
+ var $valid_types = array(
+ 'text' => true,
+ 'boolean' => true,
+ 'integer' => true,
+ 'decimal' => true,
+ 'float' => true,
+ 'date' => true,
+ 'time' => true,
+ 'timestamp' => true,
+ 'clob' => true,
+ 'blob' => true,
+ );
+
+ /**
+ * contains all LOB objects created with this MDB2 instance
+ * @var array
+ * @access protected
+ */
+ var $lobs = array();
+
+ // }}}
+ // {{{ setResultTypes()
+
+ /**
+ * Define the list of types to be associated with the columns of a given
+ * result set.
+ *
+ * This function may be called before invoking fetchRow(), fetchOne()
+ * fetchCole() and fetchAll() so that the necessary data type
+ * conversions are performed on the data to be retrieved by them. If this
+ * function is not called, the type of all result set columns is assumed
+ * to be text, thus leading to not perform any conversions.
+ *
+ * @param resource $result result identifier
+ * @param string $types array variable that lists the
+ * data types to be expected in the result set columns. If this array
+ * contains less types than the number of columns that are returned
+ * in the result set, the remaining columns are assumed to be of the
+ * type text. Currently, the types clob and blob are not fully
+ * supported.
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function setResultTypes(&$result, $types)
+ {
+ $types = is_array($types) ? array_values($types) : array($types);
+ foreach ($types as $key => $type) {
+ if (!isset($this->valid_types[$type])) {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'setResultTypes: ' . $type . ' for '. $key .' is not a supported column type');
+ }
+ }
+ $result->types = $types;
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ _baseConvertResult()
+
+ /**
+ * general type conversion method
+ *
+ * @param mixed $value refernce to a value to be converted
+ * @param int $type constant that specifies which type to convert to
+ * @return object a MDB2 error on failure
+ * @access protected
+ */
+ function _baseConvertResult($value, $type)
+ {
+ switch ($type) {
+ case 'text':
+ return $value;
+ case 'integer':
+ return intval($value);
+ case 'boolean':
+ return $value == 'Y';
+ case 'decimal':
+ return $value;
+ case 'float':
+ return doubleval($value);
+ case 'date':
+ return $value;
+ case 'time':
+ return $value;
+ case 'timestamp':
+ return $value;
+ case 'clob':
+ case 'blob':
+ $this->lobs[] = array(
+ 'buffer' => null,
+ 'position' => 0,
+ 'lob_index' => null,
+ 'endOfLOB' => false,
+ 'ressource' => $value,
+ 'value' => null,
+ );
+ end($this->lobs);
+ $lob_index = key($this->lobs);
+ $this->lobs[$lob_index]['lob_index'] = $lob_index;
+ return fopen('MDB2LOB://'.$lob_index.'@'.$this->db_index, 'r+');
+ }
+
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_INVALID, null, null,
+ 'attempt to convert result value to an unknown type ' . $type);
+ }
+
+ // }}}
+ // {{{ convertResult()
+
+ /**
+ * convert a value to a RDBMS indepdenant MDB2 type
+ *
+ * @param mixed $value value to be converted
+ * @param int $type constant that specifies which type to convert to
+ * @return mixed converted value or a MDB2 error on failure
+ * @access public
+ */
+ function convertResult($value, $type)
+ {
+ if (is_null($value)) {
+ return null;
+ }
+ return $this->_baseConvertResult($value, $type);
+ }
+
+ // }}}
+ // {{{ convertResultRow()
+
+ /**
+ * convert a result row
+ *
+ * @param resource $result result identifier
+ * @param array $row array with data
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function convertResultRow($types, $row)
+ {
+ if (is_array($types)) {
+ $current_column = -1;
+ foreach ($row as $key => $column) {
+ ++$current_column;
+ if (!isset($column) || !isset($types[$current_column])) {
+ continue;
+ }
+ $value = $this->convertResult($row[$key], $types[$current_column]);
+ if (PEAR::isError($value)) {
+ return $value;
+ }
+ $row[$key] = $value;
+ }
+ }
+ return $row;
+ }
+
+ // }}}
+ // {{{ getDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare
+ * of the given type
+ *
+ * @param string $type type to which the value should be converted to
+ * @param string $name name the field to be declared.
+ * @param string $field definition of the field
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access public
+ */
+ function getDeclaration($type, $name, $field)
+ {
+ if (!method_exists($this, "_get{$type}Declaration")) {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError('type not defined: '.$type);
+ }
+ return $this->{"_get{$type}Declaration"}($name, $field);
+ }
+
+ // }}}
+ // {{{ _getIntegerDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare an integer type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * unsigned
+ * Boolean flag that indicates whether the field should be
+ * declared as unsigned integer if possible.
+ *
+ * default
+ * Integer value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getIntegerDeclaration($name, $field)
+ {
+ if (array_key_exists('unsigned', $field) && $field['unsigned']) {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ $db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
+ }
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'integer') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' INT'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getTextDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare an text type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * length
+ * Integer value that determines the maximum length of the text
+ * field. If this argument is missing the field should be
+ * declared to have the longest length allowed by the DBMS.
+ *
+ * default
+ * Text value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getTextDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'text') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ $type = array_key_exists('length', $field) ? 'CHAR ('.$field['length'].')' : 'TEXT';
+ return $name.' '.$type.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getCLOBDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare an character
+ * large object type field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * length
+ * Integer value that determines the maximum length of the large
+ * object field. If this argument is missing the field should be
+ * declared to have the longest length allowed by the DBMS.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getCLOBDeclaration($name, $field)
+ {
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ $type = array_key_exists('length', $field) ? 'CHAR ('.$field['length'].')' : 'TEXT';
+ return $name.' '.$type.$notnull;
+ }
+
+ // }}}
+ // {{{ _getBLOBDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare an binary large
+ * object type field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * length
+ * Integer value that determines the maximum length of the large
+ * object field. If this argument is missing the field should be
+ * declared to have the longest length allowed by the DBMS.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getBLOBDeclaration($name, $field)
+ {
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ $type = array_key_exists('length', $field) ? 'CHAR ('.$field['length'].')' : 'TEXT';
+ return $name.' '.$type.$notnull;
+ }
+
+ // }}}
+ // {{{ _getBooleanDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a boolean type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Boolean value to be used as default for this field.
+ *
+ * notnullL
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getBooleanDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'boolean') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' CHAR (1)'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getDateDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a date type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Date value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getDateDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'date') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' CHAR ('.strlen('YYYY-MM-DD').')'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getTimestampDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a timestamp
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Timestamp value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getTimestampDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'timestamp') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getTimeDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a time
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Time value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getTimeDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'time') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' CHAR ('.strlen('HH:MM:SS').')'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getFloatDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a float type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Float value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getFloatDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'float') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' TEXT'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ _getDecimalDeclaration()
+
+ /**
+ * Obtain DBMS specific SQL code portion needed to declare a decimal type
+ * field to be used in statements like CREATE TABLE.
+ *
+ * @param string $name name the field to be declared.
+ * @param array $field associative array with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Decimal value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ * @return string DBMS specific SQL code portion that should be used to
+ * declare the specified field.
+ * @access protected
+ */
+ function _getDecimalDeclaration($name, $field)
+ {
+ $default = array_key_exists('default', $field) ? ' DEFAULT '.
+ $this->quote($field['default'], 'decimal') : '';
+ $notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
+ return $name.' TEXT'.$default.$notnull;
+ }
+
+ // }}}
+ // {{{ compareDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access public
+ */
+ function compareDefinition($current, $previous)
+ {
+ $type = array_key_exists('type', $current) ? $current['type'] : null;
+
+ if (!method_exists($this, "_compare{$type}Definition")) {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'type "'.$current['type'].'" is not yet supported');
+ }
+
+ if (!array_key_exists('type', $previous) || $previous['type'] != $type) {
+ return $current;
+ }
+
+ $change = $this->{"_compare{$type}Definition"}($current, $previous);
+
+ $previous_notnull = array_key_exists('notnull', $previous) ? $previous['notnull'] : false;
+ $notnull = array_key_exists('notnull', $current) ? $current['notnull'] : false;
+ if ($previous_notnull != $notnull) {
+ $change['notnull'] = true;
+ }
+
+ $previous_default = array_key_exists('default', $previous) ? $previous['default'] :
+ ($previous_notnull ? '' : null);
+ $default = array_key_exists('default', $current) ? $current['default'] :
+ ($notnull ? '' : null);
+ if ($previous_default !== $default) {
+ $change['default'] = true;
+ }
+
+ return $change;
+ }
+
+ // }}}
+ // {{{ _compareIntegerDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an integer field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareIntegerDefinition($current, $previous)
+ {
+ $change = array();
+ $previous_unsigned = array_key_exists('unsigned', $previous) ? $previous['unsigned'] : false;
+ $unsigned = array_key_exists('unsigned', $current) ? $current['unsigned'] : false;
+ if ($previous_unsigned != $unsigned) {
+ $change['unsigned'] = true;
+ }
+ $previous_autoincrement = array_key_exists('autoincrement', $previous) ? $previous['autoincrement'] : false;
+ $autoincrement = array_key_exists('autoincrement', $current) ? $current['autoincrement'] : false;
+ if ($previous_autoincrement != $autoincrement) {
+ $change['autoincrement'] = true;
+ }
+ return $change;
+ }
+
+ // }}}
+ // {{{ _compareTextDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an text field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareTextDefinition($current, $previous)
+ {
+ $change = array();
+ $previous_length = array_key_exists('length', $previous) ? $previous['length'] : 0;
+ $length = array_key_exists('length', $current) ? $current['length'] : 0;
+ if ($previous_length != $length) {
+ $change['length'] = true;
+ }
+ return $change;
+ }
+
+ // }}}
+ // {{{ _compareCLOBDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an CLOB field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareCLOBDefinition($current, $previous)
+ {
+ return $this->_compareTextDefinition($current, $previous);
+ }
+
+ // }}}
+ // {{{ _compareBLOBDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an BLOB field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareBLOBDefinition($current, $previous)
+ {
+ return $this->_compareTextDefinition($current, $previous);
+ }
+
+ // }}}
+ // {{{ _compareDateDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an date field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareDateDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ _compareTimeDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an time field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareTimeDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ _compareTimestampDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an timestamp field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareTimestampDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ _compareBooleanDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an boolean field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareBooleanDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ _compareFloatDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an float field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareFloatDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ _compareDecimalDefinition()
+
+ /**
+ * Obtain an array of changes that may need to applied to an decimal field
+ *
+ * @param array $current new definition
+ * @param array $previous old definition
+ * @return array containg all changes that will need to be applied
+ * @access protected
+ */
+ function _compareDecimalDefinition($current, $previous)
+ {
+ return array();
+ }
+
+ // }}}
+ // {{{ quote()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @param string $type type to which the value should be converted to
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access public
+ */
+ function quote($value, $type = null, $quote = true)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if (is_null($value)
+ || ($value === '' && $db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL)
+ ) {
+ if (!$quote) {
+ return null;
+ }
+ return 'NULL';
+ }
+
+ if (is_null($type)) {
+ switch (gettype($value)) {
+ case 'integer':
+ $type = 'integer';
+ break;
+ case 'double':
+ // todo
+ $type = 'decimal';
+ $type = 'float';
+ break;
+ case 'boolean':
+ $type = 'boolean';
+ break;
+ case 'array':
+ case 'object':
+ $type = 'text';
+ break;
+ default:
+ if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value)) {
+ $type = 'timestamp';
+ } elseif (preg_match('/^\d{2}:\d{2}$/', $value)) {
+ $type = 'time';
+ } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
+ $type = 'date';
+ } else {
+ $type = 'text';
+ }
+ break;
+ }
+ }
+
+ if (!method_exists($this, "_quote{$type}")) {
+ return $db->raiseError('type not defined: '.$type);
+ }
+ $value = $this->{"_quote{$type}"}($value);
+
+ // ugly hack to remove single quotes
+ if (!$quote && isset($value[0]) && $value[0] === "'") {
+ $value = substr($value, 1, -1);
+ }
+
+ return $value;
+ }
+
+ // }}}
+ // {{{ _quoteInteger()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteInteger($value)
+ {
+ return (int)$value;
+ }
+
+ // }}}
+ // {{{ _quoteText()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that already contains any DBMS specific
+ * escaped character sequences.
+ * @access protected
+ */
+ function _quoteText($value)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return "'".$db->escape($value)."'";
+ }
+
+ // }}}
+ // {{{ _readFile()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param $value
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _readFile($value)
+ {
+ $close = false;
+ if (preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
+ $close = true;
+ if ($match[1] == 'file://') {
+ $value = $match[2];
+ }
+ $value = @fopen($value, 'r');
+ }
+
+ if (is_resource($value)) {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ $fp = $value;
+ $value = '';
+ while (!@feof($fp)) {
+ $value.= @fread($fp, $db->options['lob_buffer_length']);
+ }
+ if ($close) {
+ @fclose($fp);
+ }
+ }
+
+ return $value;
+ }
+
+ // }}}
+ // {{{ _quoteLOB()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param $value
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteLOB($value)
+ {
+ $value = $this->_readFile($value);
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ _quoteCLOB()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param $value
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteCLOB($value)
+ {
+ return $this->_quoteLOB($value);
+ }
+
+ // }}}
+ // {{{ _quoteBLOB()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param $value
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteBLOB($value)
+ {
+ return $this->_quoteLOB($value);
+ }
+
+ // }}}
+ // {{{ _quoteBoolean()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteBoolean($value)
+ {
+ return ($value ? "'Y'" : "'N'");
+ }
+
+ // }}}
+ // {{{ _quoteDate()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteDate($value)
+ {
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ _quoteTimestamp()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteTimestamp($value)
+ {
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ _quoteTime()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteTime($value)
+ {
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ _quoteFloat()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteFloat($value)
+ {
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ _quoteDecimal()
+
+ /**
+ * Convert a text value into a DBMS specific format that is suitable to
+ * compose query statements.
+ *
+ * @param string $value text string value that is intended to be converted.
+ * @return string text string that represents the given argument value in
+ * a DBMS specific format.
+ * @access protected
+ */
+ function _quoteDecimal($value)
+ {
+ return $this->_quoteText($value);
+ }
+
+ // }}}
+ // {{{ writeLOBToFile()
+
+ /**
+ * retrieve LOB from the database
+ *
+ * @param resource $lob stream handle
+ * @param string $file name of the file into which the LOb should be fetched
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access protected
+ */
+ function writeLOBToFile($lob, $file)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ $fp = fopen($file, 'wb');
+ while (!feof($lob)) {
+ $result = fread($lob, $db->options['lob_buffer_length']);
+ $read = strlen($result);
+ if (fwrite($fp, $result, $read) != $read) {
+ fclose($fp);
+ return $db->raiseError(MDB2_ERROR, null, null,
+ 'writeLOBToFile: could not write to the output file');
+ }
+ }
+ fclose($fp);
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ _retrieveLOB()
+
+ /**
+ * retrieve LOB from the database
+ *
+ * @param resource $lob stream handle
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access protected
+ */
+ function _retrieveLOB(&$lob)
+ {
+ if (is_null($lob['value'])) {
+ $lob['value'] = $lob['ressource'];
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ readLOB()
+
+ /**
+ * Read data from large object input stream.
+ *
+ * @param resource $lob stream handle
+ * @param string $data reference to a variable that will hold data
+ * to be read from the large object input stream
+ * @param integer $length value that indicates the largest ammount ofdata
+ * to be read from the large object input stream.
+ * @return mixed the effective number of bytes read from the large object
+ * input stream on sucess or an MDB2 error object.
+ * @access public
+ * @see endOfLOB()
+ */
+ function _readLOB($lob, $length)
+ {
+ return substr($lob['value'], $lob['position'], $length);
+ }
+
+ // }}}
+ // {{{ _endOfLOB()
+
+ /**
+ * Determine whether it was reached the end of the large object and
+ * therefore there is no more data to be read for the its input stream.
+ *
+ * @param resource $lob stream handle
+ * @return mixed true or false on success, a MDB2 error on failure
+ * @access protected
+ */
+ function _endOfLOB($lob)
+ {
+ return $lob['endOfLOB'];
+ }
+
+ // }}}
+ // {{{ destroyLOB()
+
+ /**
+ * Free any resources allocated during the lifetime of the large object
+ * handler object.
+ *
+ * @param resource $lob stream handle
+ * @access public
+ */
+ function destroyLOB($lob)
+ {
+ $lob_data = stream_get_meta_data($lob);
+ $lob_index = $lob_data['wrapper_data']->lob_index;
+ fclose($lob);
+ if (isset($this->lobs[$lob_index])) {
+ $this->_destroyLOB($lob_index);
+ unset($this->lobs[$lob_index]);
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ _destroyLOB()
+
+ /**
+ * Free any resources allocated during the lifetime of the large object
+ * handler object.
+ *
+ * @param int $lob_index from the lob array
+ * @access private
+ */
+ function _destroyLOB($lob_index)
+ {
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ implodeArray()
+
+ /**
+ * apply a type to all values of an array and return as a comma seperated string
+ * useful for generating IN statements
+ *
+ * @access public
+ *
+ * @param array $array data array
+ * @param string $type determines type of the field
+ *
+ * @return string comma seperated values
+ */
+ function implodeArray($array, $type = false)
+ {
+ if (!is_array($array) || empty($array)) {
+ return 'NULL';
+ }
+ if ($type) {
+ foreach ($array as $value) {
+ $return[] = $this->quote($value, $type);
+ }
+ } else {
+ $return = $array;
+ }
+ return implode(', ', $return);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/program/lib/MDB2/Driver/Manager/Common.php b/program/lib/MDB2/Driver/Manager/Common.php
new file mode 100755
index 000000000..a9de44163
--- /dev/null
+++ b/program/lib/MDB2/Driver/Manager/Common.php
@@ -0,0 +1,616 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+//
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+/**
+ * Base class for the management modules that is extended by each MDB2 driver
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class MDB2_Driver_Manager_Common extends MDB2_Module_Common
+{
+ // }}}
+ // {{{ getFieldDeclarationList()
+
+ /**
+ * get declaration of a number of field in bulk
+ *
+ * @param string $fields a multidimensional associative array.
+ * The first dimension determines the field name, while the second
+ * dimension is keyed with the name of the properties
+ * of the field being declared as array indexes. Currently, the types
+ * of supported field properties are as follows:
+ *
+ * default
+ * Boolean value to be used as default for this field.
+ *
+ * notnull
+ * Boolean flag that indicates whether this field is constrained
+ * to not be set to null.
+ *
+ * @return mixed string on success, a MDB2 error on failure
+ * @access public
+ */
+ function getFieldDeclarationList($fields)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if (is_array($fields)) {
+ foreach ($fields as $field_name => $field) {
+ $query = $db->getDeclaration($field['type'], $field_name, $field);
+ if (PEAR::isError($query)) {
+ return $query;
+ }
+ $query_fields[] = $query;
+ }
+ return implode(',', $query_fields);
+ }
+ return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
+ 'getFieldDeclarationList: the definition of the table "'.$table_name.'" does not contain any fields');
+ }
+
+ // }}}
+ // {{{ _isSequenceName()
+
+ /**
+ * list all tables in the current database
+ *
+ * @param string $sqn string that containts name of a potential sequence
+ * @return mixed name of the sequence if $sqn is a name of a sequence, else false
+ * @access protected
+ */
+ function _isSequenceName($sqn)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ $seq_pattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $db->options['seqname_format']).'$/i';
+ $seq_name = preg_replace($seq_pattern, '\\1', $sqn);
+ if ($seq_name && $sqn == $db->getSequenceName($seq_name)) {
+ return $seq_name;
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ createDatabase()
+
+ /**
+ * create a new database
+ *
+ * @param string $name name of the database that should be created
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function createDatabase($database)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'createDatabase: database creation is not supported');
+ }
+
+ // }}}
+ // {{{ dropDatabase()
+
+ /**
+ * drop an existing database
+ *
+ * @param string $name name of the database that should be dropped
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function dropDatabase($database)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'dropDatabase: database dropping is not supported');
+ }
+
+ // }}}
+ // {{{ createTable()
+
+ /**
+ * create a new table
+ *
+ * @param string $name Name of the database that should be created
+ * @param array $fields Associative array that contains the definition of each field of the new table
+ * The indexes of the array entries are the names of the fields of the table an
+ * the array entry values are associative arrays like those that are meant to be
+ * passed with the field definitions to get[Type]Declaration() functions.
+ *
+ * Example
+ * array(
+ *
+ * 'id' => array(
+ * 'type' => 'integer',
+ * 'unsigned' => 1
+ * 'notnull' => 1
+ * 'default' => 0
+ * ),
+ * 'name' => array(
+ * 'type' => 'text',
+ * 'length' => 12
+ * ),
+ * 'password' => array(
+ * 'type' => 'text',
+ * 'length' => 12
+ * )
+ * );
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function createTable($name, $fields)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if (!$name) {
+ return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
+ 'createTable: no valid table name specified');
+ }
+ if (empty($fields)) {
+ return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
+ 'createTable: no fields specified for table "'.$name.'"');
+ }
+ $query_fields = $this->getFieldDeclarationList($fields);
+ if (PEAR::isError($query_fields)) {
+ return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
+ 'createTable: unkown error');
+ }
+ $query = "CREATE TABLE $name ($query_fields)";
+ return $db->query($query);
+ }
+
+ // }}}
+ // {{{ dropTable()
+
+ /**
+ * drop an existing table
+ *
+ * @param string $name name of the table that should be dropped
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function dropTable($name)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->query("DROP TABLE $name");
+ }
+
+ // }}}
+ // {{{ alterTable()
+
+ /**
+ * alter an existing table
+ *
+ * @param string $name name of the table that is intended to be changed.
+ * @param array $changes associative array that contains the details of each type
+ * of change that is intended to be performed. The types of
+ * changes that are currently supported are defined as follows:
+ *
+ * name
+ *
+ * New name for the table.
+ *
+ * add
+ *
+ * Associative array with the names of fields to be added as
+ * indexes of the array. The value of each entry of the array
+ * should be set to another associative array with the properties
+ * of the fields to be added. The properties of the fields should
+ * be the same as defined by the Metabase parser.
+ *
+ *
+ * remove
+ *
+ * Associative array with the names of fields to be removed as indexes
+ * of the array. Currently the values assigned to each entry are ignored.
+ * An empty array should be used for future compatibility.
+ *
+ * rename
+ *
+ * Associative array with the names of fields to be renamed as indexes
+ * of the array. The value of each entry of the array should be set to
+ * another associative array with the entry named name with the new
+ * field name and the entry named Declaration that is expected to contain
+ * the portion of the field declaration already in DBMS specific SQL code
+ * as it is used in the CREATE TABLE statement.
+ *
+ * change
+ *
+ * Associative array with the names of the fields to be changed as indexes
+ * of the array. Keep in mind that if it is intended to change either the
+ * name of a field and any other properties, the change array entries
+ * should have the new names of the fields as array indexes.
+ *
+ * The value of each entry of the array should be set to another associative
+ * array with the properties of the fields to that are meant to be changed as
+ * array entries. These entries should be assigned to the new values of the
+ * respective properties. The properties of the fields should be the same
+ * as defined by the Metabase parser.
+ *
+ * Example
+ * array(
+ * 'name' => 'userlist',
+ * 'add' => array(
+ * 'quota' => array(
+ * 'type' => 'integer',
+ * 'unsigned' => 1
+ * )
+ * ),
+ * 'remove' => array(
+ * 'file_limit' => array(),
+ * 'time_limit' => array()
+ * ),
+ * 'change' => array(
+ * 'gender' => array(
+ * 'default' => 'M',
+ * )
+ * ),
+ * 'rename' => array(
+ * 'sex' => array(
+ * 'name' => 'gender',
+ * )
+ * )
+ * )
+ * @param boolean $check indicates whether the function should just check if the DBMS driver
+ * can perform the requested table alterations if the value is true or
+ * actually perform them otherwise.
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function alterTable($name, $changes, $check)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'alterTable: database table alterations are not supported');
+ }
+
+ // }}}
+ // {{{ listDatabases()
+
+ /**
+ * list all databases
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listDatabases()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listDatabases: list databases is not supported');
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * list all users
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listUsers()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listUsers: list user is not supported');
+ }
+
+ // }}}
+ // {{{ listViews()
+
+ /**
+ * list all views in the current database
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listViews()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listViews: list view is not supported');
+ }
+
+ // }}}
+ // {{{ listFunctions()
+
+ /**
+ * list all functions in the current database
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listFunctions()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listFunctions: list function is not supported');
+ }
+
+ // }}}
+ // {{{ listTables()
+
+ /**
+ * list all tables in the current database
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listTables()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listTables: list tables is not supported');
+ }
+
+ // }}}
+ // {{{ listTableFields()
+
+ /**
+ * list all fields in a tables in the current database
+ *
+ * @param string $table name of table that should be used in method
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listTableFields($table)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listTableFields: list table fields is not supported');
+ }
+
+ // }}}
+ // {{{ createIndex()
+
+ /**
+ * get the stucture of a field into an array
+ *
+ * @param string $table name of the table on which the index is to be created
+ * @param string $name name of the index to be created
+ * @param array $definition associative array that defines properties of the index to be created.
+ * Currently, only one property named FIELDS is supported. This property
+ * is also an associative with the names of the index fields as array
+ * indexes. Each entry of this array is set to another type of associative
+ * array that specifies properties of the index that are specific to
+ * each field.
+ *
+ * Currently, only the sorting property is supported. It should be used
+ * to define the sorting direction of the index. It may be set to either
+ * ascending or descending.
+ *
+ * Not all DBMS support index sorting direction configuration. The DBMS
+ * drivers of those that do not support it ignore this property. Use the
+ * function supports() to determine whether the DBMS driver can manage indexes.
+ *
+ * Example
+ * array(
+ * 'fields' => array(
+ * 'user_name' => array(
+ * 'sorting' => 'ascending'
+ * ),
+ * 'last_login' => array()
+ * )
+ * )
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function createIndex($table, $name, $definition)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'createIndex: Creating Indexes is not supported');
+ }
+
+ // }}}
+ // {{{ dropIndex()
+
+ /**
+ * drop existing index
+ *
+ * @param string $table name of table that should be used in method
+ * @param string $name name of the index to be dropped
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function dropIndex($table, $name)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->query("DROP INDEX $name");
+ }
+
+ // }}}
+ // {{{ listTableIndexes()
+
+ /**
+ * list all indexes in a table
+ *
+ * @param string $table name of table that should be used in method
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listTableIndexes($table)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listTableIndexes: List Indexes is not supported');
+ }
+
+ // }}}
+ // {{{ createSequence()
+
+ /**
+ * create sequence
+ *
+ * @param string $seq_name name of the sequence to be created
+ * @param string $start start value of the sequence; default is 1
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function createSequence($seq_name, $start = 1)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'createSequence: sequence creation not supported');
+ }
+
+ // }}}
+ // {{{ dropSequence()
+
+ /**
+ * drop existing sequence
+ *
+ * @param string $seq_name name of the sequence to be dropped
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ function dropSequence($name)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'dropSequence: sequence dropping not supported');
+ }
+
+ // }}}
+ // {{{ listSequences()
+
+ /**
+ * list all sequences in the current database
+ *
+ * @return mixed data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function listSequences()
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
+ 'listSequences: List sequences is not supported');
+ }
+}
+
+?>
diff --git a/program/lib/MDB2/Extended.php b/program/lib/MDB2/Extended.php
new file mode 100755
index 000000000..cc308bfe0
--- /dev/null
+++ b/program/lib/MDB2/Extended.php
@@ -0,0 +1,605 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+/**
+ * Used by autoPrepare()
+ */
+define('MDB2_AUTOQUERY_INSERT', 1);
+define('MDB2_AUTOQUERY_UPDATE', 2);
+
+/**
+ * MDB2_Extended: class which adds several high level methods to MDB2
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class MDB2_Extended extends MDB2_Module_Common
+{
+ // }}}
+ // {{{ autoPrepare()
+
+ /**
+ * Make automaticaly an insert or update query and call prepare() with it
+ *
+ * @param string $table name of the table
+ * @param array $table_fields ordered array containing the fields names
+ * @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
+ * @param string $where in case of update queries, this string will be put after the sql WHERE statement
+ * @return resource handle for the query
+ * @param mixed $types array that contains the types of the placeholders
+ * @param mixed $result_types array that contains the types of the columns in
+ * the result set
+ * @see buildManipSQL
+ * @access public
+ */
+ function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT,
+ $where = false, $types = null, $result_types = null)
+ {
+ $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
+ if (PEAR::isError($query)) {
+ return $query;
+ }
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ return $db->prepare($query, $types, $result_types);
+ }
+
+ // {{{
+ // }}} autoExecute()
+
+ /**
+ * Make automaticaly an insert or update query and call prepare() and execute() with it
+ *
+ * @param string $table name of the table
+ * @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value
+ * @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
+ * @param string $where in case of update queries, this string will be put after the sql WHERE statement
+ * @param mixed $types array that contains the types of the placeholders
+ * @param mixed $result_types array that contains the types of the columns in
+ * the result set
+ * @param mixed $result_class string which specifies which result class to use
+ * @return mixed a new MDB2_Result or a MDB2 Error Object when fail
+ * @see buildManipSQL
+ * @see autoPrepare
+ * @access public
+ */
+ function &autoExecute($table, $fields_values, $mode = MDB2_AUTOQUERY_INSERT,
+ $where = false, $types = null, $result_types = null, $result_class = true)
+ {
+ $stmt = $this->autoPrepare($table, array_keys($fields_values), $mode, $where, $types, $result_types);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+ $params = array_values($fields_values);
+ $stmt->bindParamArray($params);
+ $result =& $stmt->execute($result_class);
+ $stmt->free();
+ return $result;
+ }
+
+ // {{{
+ // }}} buildManipSQL()
+
+ /**
+ * Make automaticaly an sql query for prepare()
+ *
+ * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), MDB2_AUTOQUERY_INSERT)
+ * will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
+ * NB : - This belongs more to a SQL Builder class, but this is a simple facility
+ * - Be carefull ! If you don't give a $where param with an UPDATE query, all
+ * the records of the table will be updated !
+ *
+ * @param string $table name of the table
+ * @param array $table_fields ordered array containing the fields names
+ * @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
+ * @param string $where in case of update queries, this string will be put after the sql WHERE statement
+ * @return string sql query for prepare()
+ * @access public
+ */
+ function buildManipSQL($table, $table_fields, $mode, $where = false)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if (count($table_fields) == 0) {
+ return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
+ }
+ switch ($mode) {
+ case MDB2_AUTOQUERY_INSERT:
+ $cols = implode(', ', $table_fields);
+ $values = '?'.str_repeat(', ?', count($table_fields)-1);
+ return 'INSERT INTO '.$table.' ('.$cols.') VALUES ('.$values.')';
+ break;
+ case MDB2_AUTOQUERY_UPDATE:
+ $set = implode(' = ?, ', $table_fields).' = ?';
+ $sql = 'UPDATE '.$table.' SET '.$set;
+ if ($where !== false) {
+ $sql.= ' WHERE '.$where;
+ }
+ return $sql;
+ break;
+ }
+ return $db->raiseError(MDB2_ERROR_SYNTAX);
+ }
+
+ // {{{
+ // }}} limitQuery()
+
+ /**
+ * Generates a limited query
+ *
+ * @param string $query query
+ * @param mixed $types array that contains the types of the columns in
+ * the result set
+ * @param integer $from the row to start to fetching
+ * @param integer $count the numbers of rows to fetch
+ * @param mixed $result_class string which specifies which result class to use
+ * @return mixed a valid ressource pointer or a MDB2 Error Object
+ * @access public
+ */
+ function &limitQuery($query, $types, $count, $from = 0, $result_class = true)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ $result = $db->setLimit($count, $from);
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+ $result =& $db->query($query, $types, $result_class);
+ return $result;
+ }
+
+ // {{{
+ // }}} getOne()
+
+ /**
+ * Fetch the first column of the first row of data returned from
+ * a query. Takes care of doing the query and freeing the results
+ * when finished.
+ *
+ * @param string $query the SQL query
+ * @param string $type string that contains the type of the column in the
+ * result set
+ * @param array $params if supplied, prepare/execute will be used
+ * with this array as execute parameters
+ * @param array $param_types array that contains the types of the values
+ * defined in $params
+ * @param mixed $colnum which column to return
+ * @return mixed MDB2_OK or data on success, a MDB2 error on failure
+ * @access public
+ */
+ function getOne($query, $type = null, $params = array(),
+ $param_types = null, $colnum = 0)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ settype($params, 'array');
+ settype($type, 'array');
+ if (count($params) == 0) {
+ return $db->queryOne($query, $type, $colnum);
+ }
+
+ $stmt = $db->prepare($query, $param_types, $type);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+
+ $stmt->bindParamArray($params);
+ $result = $stmt->execute();
+ if (!MDB2::isResultCommon($result)) {
+ return $result;
+ }
+
+ $one = $result->fetchOne($colnum);
+ $stmt->free();
+ $result->free();
+ return $one;
+ }
+
+ // }}}
+ // {{{ getRow()
+
+ /**
+ * Fetch the first row of data returned from a query. Takes care
+ * of doing the query and freeing the results when finished.
+ *
+ * @param string $query the SQL query
+ * @param array $types array that contains the types of the columns in
+ * the result set
+ * @param array $params array if supplied, prepare/execute will be used
+ * with this array as execute parameters
+ * @param array $param_types array that contains the types of the values
+ * defined in $params
+ * @param integer $fetchmode the fetch mode to use
+ * @return mixed MDB2_OK or data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function getRow($query, $types = null, $params = array(),
+ $param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ settype($params, 'array');
+ if (count($params) == 0) {
+ return $db->queryRow($query, $types, $fetchmode);
+ }
+
+ $stmt = $db->prepare($query, $param_types, $types);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+
+ $stmt->bindParamArray($params);
+ $result = $stmt->execute();
+ if (!MDB2::isResultCommon($result)) {
+ return $result;
+ }
+
+ $row = $result->fetchRow($fetchmode);
+ $stmt->free();
+ $result->free();
+ return $row;
+ }
+
+ // }}}
+ // {{{ getCol()
+
+ /**
+ * Fetch a single column from a result set and return it as an
+ * indexed array.
+ *
+ * @param string $query the SQL query
+ * @param string $type string that contains the type of the column in the
+ * result set
+ * @param array $params array if supplied, prepare/execute will be used
+ * with this array as execute parameters
+ * @param array $param_types array that contains the types of the values
+ * defined in $params
+ * @param mixed $colnum which column to return
+ * @return mixed MDB2_OK or data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function getCol($query, $type = null, $params = array(),
+ $param_types = null, $colnum = 0)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ settype($params, 'array');
+ settype($type, 'array');
+ if (count($params) == 0) {
+ return $db->queryCol($query, $type, $colnum);
+ }
+
+ $stmt = $db->prepare($query, $param_types, $type);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+
+ $stmt->bindParamArray($params);
+ $result = $stmt->execute();
+ if (!MDB2::isResultCommon($result)) {
+ return $result;
+ }
+
+ $col = $result->fetchCol($colnum);
+ $stmt->free();
+ $result->free();
+ return $col;
+ }
+
+ // }}}
+ // {{{ getAll()
+
+ /**
+ * Fetch all the rows returned from a query.
+ *
+ * @param string $query the SQL query
+ * @param array $types array that contains the types of the columns in
+ * the result set
+ * @param array $params array if supplied, prepare/execute will be used
+ * with this array as execute parameters
+ * @param array $param_types array that contains the types of the values
+ * defined in $params
+ * @param integer $fetchmode the fetch mode to use
+ * @param boolean $rekey if set to true, the $all will have the first
+ * column as its first dimension
+ * @param boolean $force_array used only when the query returns exactly
+ * two columns. If true, the values of the returned array will be
+ * one-element arrays instead of scalars.
+ * @param boolean $group if true, the values of the returned array is
+ * wrapped in another array. If the same key value (in the first
+ * column) repeats itself, the values will be appended to this array
+ * instead of overwriting the existing values.
+ * @return mixed MDB2_OK or data array on success, a MDB2 error on failure
+ * @access public
+ */
+ function getAll($query, $types = null, $params = array(),
+ $param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT,
+ $rekey = false, $force_array = false, $group = false)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ settype($params, 'array');
+ if (count($params) == 0) {
+ return $db->queryAll($query, $types, $fetchmode, $rekey, $force_array, $group);
+ }
+
+ $stmt = $db->prepare($query, $param_types, $types);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+
+ $stmt->bindParamArray($params);
+ $result = $stmt->execute();
+ if (!MDB2::isResultCommon($result)) {
+ return $result;
+ }
+
+ $all = $result->fetchAll($fetchmode, $rekey, $force_array, $group);
+ $stmt->free();
+ $result->free();
+ return $all;
+ }
+
+ // }}}
+ // {{{ getAssoc()
+
+ /**
+ * Fetch the entire result set of a query and return it as an
+ * associative array using the first column as the key.
+ *
+ * If the result set contains more than two columns, the value
+ * will be an array of the values from column 2-n. If the result
+ * set contains only two columns, the returned value will be a
+ * scalar with the value of the second column (unless forced to an
+ * array with the $force_array parameter). A MDB error code is
+ * returned on errors. If the result set contains fewer than two
+ * columns, a MDB2_ERROR_TRUNCATED error is returned.
+ *
+ * For example, if the table 'mytable' contains:
+ *
+ * ID TEXT DATE
+ * --------------------------------
+ * 1 'one' 944679408
+ * 2 'two' 944679408
+ * 3 'three' 944679408
+ *
+ * Then the call getAssoc('SELECT id,text FROM mytable') returns:
+ * array(
+ * '1' => 'one',
+ * '2' => 'two',
+ * '3' => 'three',
+ * )
+ *
+ * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
+ * array(
+ * '1' => array('one', '944679408'),
+ * '2' => array('two', '944679408'),
+ * '3' => array('three', '944679408')
+ * )
+ *
+ * If the more than one row occurs with the same value in the
+ * first column, the last row overwrites all previous ones by
+ * default. Use the $group parameter if you don't want to
+ * overwrite like this. Example:
+ *
+ * getAssoc('SELECT category,id,name FROM mytable', null, null
+ * MDB2_FETCHMODE_ASSOC, false, true) returns:
+ * array(
+ * '1' => array(array('id' => '4', 'name' => 'number four'),
+ * array('id' => '6', 'name' => 'number six')
+ * ),
+ * '9' => array(array('id' => '4', 'name' => 'number four'),
+ * array('id' => '6', 'name' => 'number six')
+ * )
+ * )
+ *
+ * Keep in mind that database functions in PHP usually return string
+ * values for results regardless of the database's internal type.
+ *
+ * @param string $query the SQL query
+ * @param array $types array that contains the types of the columns in
+ * the result set
+ * @param array $params array if supplied, prepare/execute will be used
+ * with this array as execute parameters
+ * @param array $param_types array that contains the types of the values
+ * defined in $params
+ * @param boolean $force_array used only when the query returns
+ * exactly two columns. If TRUE, the values of the returned array
+ * will be one-element arrays instead of scalars.
+ * @param boolean $group if TRUE, the values of the returned array
+ * is wrapped in another array. If the same key value (in the first
+ * column) repeats itself, the values will be appended to this array
+ * instead of overwriting the existing values.
+ * @return array associative array with results from the query.
+ * @access public
+ */
+ function getAssoc($query, $types = null, $params = array(), $param_types = null,
+ $fetchmode = MDB2_FETCHMODE_DEFAULT, $force_array = false, $group = false)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ settype($params, 'array');
+ if (count($params) == 0) {
+ return $db->queryAll($query, $types, $fetchmode, true, $force_array, $group);
+ }
+
+ $stmt = $db->prepare($query, $param_types, $types);
+ if (PEAR::isError($stmt)) {
+ return $stmt;
+ }
+
+ $stmt->bindParamArray($params);
+ $result = $stmt->execute();
+ if (!MDB2::isResultCommon($result)) {
+ return $result;
+ }
+
+ $all = $result->fetchAll($fetchmode, true, $force_array, $group);
+ $stmt->free();
+ $result->free();
+ return $all;
+ }
+
+ // }}}
+ // {{{ executeMultiple()
+
+ /**
+ * This function does several execute() calls on the same statement handle.
+ * $params must be an array indexed numerically from 0, one execute call is
+ * done for every 'row' in the array.
+ *
+ * If an error occurs during execute(), executeMultiple() does not execute
+ * the unfinished rows, but rather returns that error.
+ *
+ * @param resource $stmt query handle from prepare()
+ * @param array $params numeric array containing the
+ * data to insert into the query
+ * @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ * @see prepare(), execute()
+ */
+ function executeMultiple(&$stmt, $params = null)
+ {
+ for ($i = 0, $j = count($params); $i < $j; $i++) {
+ $stmt->bindParamArray($params[$i]);
+ $result = $stmt->execute();
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ getBeforeID()
+
+ /**
+ * returns the next free id of a sequence if the RDBMS
+ * does not support auto increment
+ *
+ * @param string $table name of the table into which a new row was inserted
+ * @param boolean $ondemand when true the seqence is
+ * automatic created, if it
+ * not exists
+ *
+ * @return mixed MDB2 Error Object or id
+ * @access public
+ */
+ function getBeforeID($table, $field, $ondemand = true)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if ($db->supports('auto_increment') !== true) {
+ $seq = $table.(empty($field) ? '' : '_'.$field);
+ $id = $db->nextID($seq, $ondemand);
+ if (PEAR::isError($id)) {
+ return $id;
+ }
+ return $db->quote($id, 'integer');
+ }
+ return 'NULL';
+ }
+
+ // }}}
+ // {{{ getAfterID()
+
+ /**
+ * returns the autoincrement ID if supported or $id
+ *
+ * @param mixed $id value as returned by getBeforeId()
+ * @param string $table name of the table into which a new row was inserted
+ * @return mixed MDB2 Error Object or id
+ * @access public
+ */
+ function getAfterID($id, $table, $field)
+ {
+ $db =& $this->getDBInstance();
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+
+ if ($db->supports('auto_increment') !== true) {
+ return $id;
+ }
+ return $db->lastInsertID($table, $field);
+ }
+
+}
+?> \ No newline at end of file
diff --git a/program/lib/MDB2/Iterator.php b/program/lib/MDB2/Iterator.php
new file mode 100755
index 000000000..13db77a97
--- /dev/null
+++ b/program/lib/MDB2/Iterator.php
@@ -0,0 +1,285 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP version 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class MDB2_Iterator implements Iterator
+{
+ protected $fetchmode;
+ protected $result;
+ protected $row;
+
+ // {{{ constructor
+
+ /**
+ * Constructor
+ */
+ public function __construct($result, $fetchmode = MDB2_FETCHMODE_DEFAULT)
+ {
+ $this->result = $result;
+ $this->fetchmode = $fetchmode;
+ }
+
+ // }}}
+ // {{{ seek()
+
+ /**
+ * seek forward to a specific row in a result set
+ *
+ * @param int $rownum number of the row where the data can be found
+ * @return void
+ * @access public
+ */
+ public function seek($rownum)
+ {
+ $this->row = null;
+ if ($this->result) {
+ $this->result->seek($rownum);
+ }
+ }
+
+ // }}}
+ // {{{ next()
+
+ /**
+ * Fetch next row of data
+ *
+ * @return void
+ * @access public
+ */
+ public function next()
+ {
+ $this->row = null;
+ }
+
+ // }}}
+ // {{{ current()
+
+ /**
+ * return a row of data
+ *
+ * @return void
+ * @access public
+ */
+ public function current()
+ {
+ if (is_null($this->row)) {
+ $row = $this->result->fetchRow($this->fetchmode);
+ if (PEAR::isError($row)) {
+ $row = false;
+ }
+ $this->row = $row;
+ }
+ return $this->row;
+ }
+
+ // }}}
+ // {{{ valid()
+
+ /**
+ * check if the end of the result set has been reached
+ *
+ * @return mixed true or false on sucess, a MDB2 error on failure
+ * @access public
+ */
+ public function valid()
+ {
+ return (bool)$this->current();
+ }
+
+ // }}}
+ // {{{ free()
+
+ /**
+ * Free the internal resources associated with result.
+ *
+ * @return boolean true on success, false if result is invalid
+ * @access public
+ */
+ public function free()
+ {
+ if ($this->result) {
+ return $this->result->free();
+ }
+ $this->result = null;
+ $this->row = null;
+ return false;
+ }
+
+ // }}}
+ // {{{ key()
+
+ /**
+ * nothing, but Iterator wants to implement this.
+ *
+ * @return void
+ * @access public
+ */
+ public function key()
+ {
+ if ($this->result) {
+ return $this->result->rowCount();
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ rewind()
+
+ /**
+ * seek to the first row in a result set
+ *
+ * @return void
+ * @access public
+ */
+ public function rewind()
+ {
+ }
+
+ // }}}
+ // {{{ destructor
+
+ /**
+ * Destructor
+ */
+ public function __destruct()
+ {
+ $this->free();
+ }
+}
+
+class MDB2_BufferedIterator extends MDB2_Iterator implements SeekableIterator
+{
+ // }}}
+ // {{{ valid()
+
+ /**
+ * check if the end of the result set has been reached
+ *
+ * @return mixed true or false on sucess, a MDB2 error on failure
+ * @access public
+ */
+ public function valid()
+ {
+ if ($this->result) {
+ return $this->result->valid();
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{count()
+
+ /**
+ * returns the number of rows in a result object
+ *
+ * @return mixed MDB2 Error Object or the number of rows
+ * @access public
+ */
+ public function count()
+ {
+ if ($this->result) {
+ return $this->result->numRows();
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ hasPrev()
+
+ /**
+ * check if there is a previous row
+ *
+ * @return mixed true or false on sucess, a MDB2 error on failure
+ * @access public
+ */
+ public function hasPrev()
+ {
+ if ($this->result) {
+ return $this->result->rowCount() > 0;
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ rewind()
+
+ /**
+ * seek to the first row in a result set
+ *
+ * @return mixed MDB2_OK on success, a MDB2 error on failure
+ * @access public
+ */
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ // }}}
+ // {{{ prev()
+
+ /**
+ * move internal row point to the previous row
+ * Fetch and return a row of data
+ *
+ * @return void
+ * @access public
+ */
+ public function prev()
+ {
+ if ($this->hasPrev()) {
+ $this->seek($this->result->rowCount() - 1);
+ } else {
+ return false;
+ }
+ return $this->next();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/program/lib/MDB2/LOB.php b/program/lib/MDB2/LOB.php
new file mode 100755
index 000000000..c17abc9fb
--- /dev/null
+++ b/program/lib/MDB2/LOB.php
@@ -0,0 +1,146 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP version 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+require_once 'MDB2.php';
+
+class MDB2_LOB
+{
+ var $db_index;
+ var $lob_index;
+ var $lob;
+
+ function stream_open($path, $mode, $options, &$opened_path)
+ {
+ if (!preg_match('/^rb?\+?$/', $mode)) {
+ return false;
+ }
+ $url = parse_url($path);
+ if (!array_key_exists('host', $url) && !array_key_exists('user', $url)) {
+ return false;
+ }
+ $this->db_index = $url['host'];
+ if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
+ return false;
+ }
+ $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
+ $this->lob_index = $url['user'];
+ if (!isset($db->datatype->lobs[$this->lob_index])) {
+ return false;
+ }
+ $this->lob =& $db->datatype->lobs[$this->lob_index];
+ $db->datatype->_retrieveLOB($this->lob);
+ return true;
+ }
+
+ function stream_read($count)
+ {
+ if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
+ $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
+
+ $data = $db->datatype->_readLOB($this->lob, $count);
+ $length = strlen($data);
+ if ($length == 0) {
+ $this->lob['endOfLOB'] = true;
+ }
+ $this->lob['position'] += $length;
+ return $data;
+ }
+ }
+
+ function stream_write($data)
+ {
+ return 0;
+ }
+
+ function stream_tell()
+ {
+ return $this->lob['position'];
+ }
+
+ function stream_eof()
+ {
+ if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
+ return true;
+ }
+ $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
+ $result = $db->datatype->_endOfLOB($this->lob);
+ if (version_compare(phpversion(), "5.0", ">=")
+ && version_compare(phpversion(), "5.1", "<")
+ ) {
+ return !$result;
+ }
+ return $result;
+ }
+
+ function stream_seek($offset, $whence)
+ {
+ return false;
+ }
+
+ function stream_close()
+ {
+ if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
+ $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
+ if (isset($db->datatype->lobs[$this->lob_index])) {
+ $db->datatype->_destroyLOB($this->lob_index);
+ unset($db->datatype->lobs[$this->lob_index]);
+ }
+ }
+ }
+}
+
+if (!stream_wrapper_register("MDB2LOB", "MDB2_LOB")) {
+ MDB2::raiseError();
+ return false;
+}
+
+?> \ No newline at end of file
diff --git a/program/lib/MDB2/Wrapper/peardb.php b/program/lib/MDB2/Wrapper/peardb.php
new file mode 100755
index 000000000..a7123b3cc
--- /dev/null
+++ b/program/lib/MDB2/Wrapper/peardb.php
@@ -0,0 +1,750 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
+// | API as well as database abstraction for PHP applications. |
+// | This LICENSE is in the BSD license style. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution. |
+// | |
+// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
+// | Lukas Smith nor the names of his contributors may be used to endorse |
+// | or promote products derived from this software without specific prior|
+// | written permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
+// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
+// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
+// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
+// +----------------------------------------------------------------------+
+// | Author: Lukas Smith <smith@pooteeweet.org> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+//
+
+/**
+ * Wrapper that makes MDB2 behave like PEAR DB
+ * WARNING: this wrapper is broken and unmaintained
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+
+require_once 'MDB2.php';
+
+/*
+ * The method mapErrorCode in each MDB2_dbtype implementation maps
+ * native error codes to one of these.
+ *
+ * If you add an error code here, make sure you also add a textual
+ * version of it in DB::errorMessage().
+ */
+
+define('DB_OK', MDB2_OK);
+define('DB_ERROR', MDB2_ERROR);
+define('DB_ERROR_SYNTAX', MDB2_ERROR_SYNTAX);
+define('DB_ERROR_CONSTRAINT', MDB2_ERROR_CONSTRAINT);
+define('DB_ERROR_NOT_FOUND', MDB2_ERROR_NOT_FOUND);
+define('DB_ERROR_ALREADY_EXISTS', MDB2_ERROR_ALREADY_EXISTS);
+define('DB_ERROR_UNSUPPORTED', MDB2_ERROR_UNSUPPORTED);
+define('DB_ERROR_MISMATCH', MDB2_ERROR_MISMATCH);
+define('DB_ERROR_INVALID', MDB2_ERROR_INVALID);
+define('DB_ERROR_NOT_CAPABLE', MDB2_ERROR_NOT_CAPABLE);
+define('DB_ERROR_TRUNCATED', MDB2_ERROR_TRUNCATED);
+define('DB_ERROR_INVALID_NUMBER', MDB2_ERROR_INVALID_NUMBER);
+define('DB_ERROR_INVALID_DATE', MDB2_ERROR_INVALID_DATE);
+define('DB_ERROR_DIVZERO', MDB2_ERROR_DIVZERO);
+define('DB_ERROR_NODBSELECTED', MDB2_ERROR_NODBSELECTED);
+define('DB_ERROR_CANNOT_CREATE', MDB2_ERROR_CANNOT_CREATE);
+define('DB_ERROR_CANNOT_DROP', MDB2_ERROR_CANNOT_DROP);
+define('DB_ERROR_NOSUCHTABLE', MDB2_ERROR_NOSUCHTABLE);
+define('DB_ERROR_NOSUCHFIELD', MDB2_ERROR_NOSUCHFIELD);
+define('DB_ERROR_NEED_MORE_DATA', MDB2_ERROR_NEED_MORE_DATA);
+define('DB_ERROR_NOT_LOCKED', MDB2_ERROR_NOT_LOCKED);
+define('DB_ERROR_VALUE_COUNT_ON_ROW', MDB2_ERROR_VALUE_COUNT_ON_ROW);
+define('DB_ERROR_INVALID_DSN', MDB2_ERROR_INVALID_DSN);
+define('DB_ERROR_CONNECT_FAILED', MDB2_ERROR_CONNECT_FAILED);
+define('DB_ERROR_EXTENSION_NOT_FOUND', MDB2_ERROR_EXTENSION_NOT_FOUND);
+define('DB_ERROR_ACCESS_VIOLATION', MDB2_ERROR_ACCESS_VIOLATION);
+define('DB_ERROR_NOSUCHDB', MDB2_ERROR_NOSUCHDB);
+
+define('DB_WARNING', -1000);
+define('DB_WARNING_READ_ONLY', -1001);
+
+define('DB_PARAM_SCALAR', 1);
+define('DB_PARAM_OPAQUE', 2);
+define('DB_PARAM_MISC', 3);
+
+define('DB_BINMODE_PASSTHRU', 1);
+define('DB_BINMODE_RETURN', 2);
+define('DB_BINMODE_CONVERT', 3);
+
+define('DB_FETCHMODE_DEFAULT', MDB2_FETCHMODE_DEFAULT);
+define('DB_FETCHMODE_ORDERED', MDB2_FETCHMODE_ORDERED);
+define('DB_FETCHMODE_ASSOC', MDB2_FETCHMODE_ASSOC);
+define('DB_FETCHMODE_OBJECT', MDB2_FETCHMODE_OBJECT);
+define('DB_FETCHMODE_FLIPPED', MDB2_FETCHMODE_FLIPPED);
+
+define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
+define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
+define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
+
+require_once 'MDB2/Extended.php';
+define('DB_AUTOQUERY_INSERT', MDB2_AUTOQUERY_INSERT);
+define('DB_AUTOQUERY_UPDATE', MDB2_AUTOQUERY_UPDATE);
+
+require_once 'MDB2/Driver/Reverse/Common.php';
+define('DB_TABLEINFO_ORDER', MDB2_TABLEINFO_ORDER);
+define('DB_TABLEINFO_ORDERTABLE', MDB2_TABLEINFO_ORDERTABLE);
+define('DB_TABLEINFO_FULL', MDB2_TABLEINFO_FULL);
+
+define('DB_PORTABILITY_NONE', MDB2_PORTABILITY_NONE);
+define('DB_PORTABILITY_LOWERCASE', MDB2_PORTABILITY_FIX_CASE);
+define('DB_PORTABILITY_RTRIM', MDB2_PORTABILITY_RTRIM);
+define('DB_PORTABILITY_DELETE_COUNT', MDB2_PORTABILITY_DELETE_COUNT);
+define('DB_PORTABILITY_NUMROWS', MDB2_PORTABILITY_NUMROWS);
+define('DB_PORTABILITY_ERRORS', MDB2_PORTABILITY_ERRORS);
+define('DB_PORTABILITY_NULL_TO_EMPTY', MDB2_PORTABILITY_EMPTY_TO_NULL);
+define('DB_PORTABILITY_ALL', MDB2_PORTABILITY_ALL);
+
+/**
+ * Wrapper that makes MDB2 behave like PEAR DB
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class DB
+{
+ function &factory($type)
+ {
+ $db =& MDB2::factory($type);
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+ $obj =& new MDB2_PEARProxy($db);
+ return $obj;
+ }
+
+ function &connect($dsn, $options = false)
+ {
+ if (!is_array($options) && $options) {
+ $options = array('persistent' => true);
+ }
+ $db =& MDB2::connect($dsn, $options);
+ if (PEAR::isError($db)) {
+ return $db;
+ }
+ $obj =& new MDB2_PEARProxy($db);
+ return $obj;
+ }
+
+ function apiVersion()
+ {
+ return 2;
+ }
+
+ function isError($value)
+ {
+ return PEAR::isError($value);
+ }
+
+ function isManip($query)
+ {
+ return MDB2::isManip($query);
+ }
+
+ function errorMessage($value)
+ {
+ return MDB2::errorMessage($value);
+ }
+
+ function parseDSN($dsn)
+ {
+ return MDB2::parseDSN($dsn);
+ }
+
+ function assertExtension($name)
+ {
+ if (!extension_loaded($name)) {
+ $dlext = OS_WINDOWS ? '.dll' : '.so';
+ @dl($name . $dlext);
+ }
+ return extension_loaded($name);
+ }
+}
+
+/**
+ * MDB2_Error implements a class for reporting portable database error
+ * messages.
+ *
+ * @package MDB2
+ * @category Database
+ * @author Stig Bakken <ssb@fast.no>
+ */
+class DB_Error extends PEAR_Error
+{
+ function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
+ $level = E_USER_NOTICE, $debuginfo = null)
+ {
+ if (is_int($code)) {
+ $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
+ } else {
+ $this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo);
+ }
+ }
+}
+
+/**
+ * Wrapper that makes MDB2 behave like PEAR DB
+ *
+ * @package MDB2
+ * @category Database
+ * @author Lukas Smith <smith@pooteeweet.org>
+ */
+class DB_result extends MDB2_Result_Common
+{
+ var $result;
+ var $row_counter = null;
+
+ var $limit_from = null;
+
+ var $limit_count = null;
+
+ function DB_result($result)
+ {
+ $this->result = $result;
+ }
+
+ function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
+ {
+ $arr = $this->result->fetchRow($fetchmode, $rownum);
+ if ($this->result->mdb->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
+ $this->_convertNullArrayValuesToEmpty($arr);
+ }
+ return $arr;
+ }
+
+ function fetchInto(&$arr, $fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
+ {
+ $arr = $this->fetchRow($fetchmode, $rownum);
+ if ($this->result->mdb->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
+ $this->_convertNullArrayValuesToEmpty($arr);
+ }
+ return DB_OK;
+ }
+
+ function _convertNullArrayValuesToEmpty(&$array)
+ {
+ if (is_array($array)) {
+ foreach ($array as $key => $value) {
+ if (is_null($value)) {
+ $array[$key] = '';
+ }
+ }
+ }
+ }
+
+ function numCols()
+ {
+ return $this->result->numCols();
+ }
+
+ function numRows()
+ {
+ return $this->result->numRows();
+ }
+
+ function nextResult()
+ {
+ return $this->result->nextResult();
+ }
+
+ function free()
+ {
+ $err = $this->result->free();
+ if (PEAR::isError($err)) {
+ return $err;
+ }
+ $this->result = false;
+ return true;
+ }
+
+ function tableInfo($mode = null)
+ {
+ $this->result->db->loadModule('Reverse');
+ return $this->result->db->reverse->tableInfo($this->result, $mode);
+ }
+
+ function getRowCounter()
+ {
+ return $this->result->rowCount()+1+$this->result->offset;
+ }
+}
+
+class DB_row
+{
+ function DB_row(&$arr)
+ {
+ for (reset($arr); $key = key($arr); next($arr)) {
+ $this->$key = &$arr[$key];
+ }
+ }
+}
+
+class MDB2_PEARProxy extends PEAR
+{
+ var $db_object;
+ var $phptype;
+ var $connection;
+ var $dsn;
+
+ function MDB2_PEARProxy(&$db_object)
+ {
+ $this->db_object =& $db_object;
+ $this->PEAR('DB_Error');
+ $this->db_object->setOption('seqcol_name', 'id');
+ $this->db_object->setOption('result_wrap_class', 'DB_result');
+ $this->phptype = $this->db_object->phptype;
+ $this->connection = $this->db_object->connection;
+ $this->dsn = $this->db_object->getDSN();
+ }
+
+ function connect($dsninfo, $persistent = false)
+ {
+ $this->options['persistent'] = $presistent;
+ return $this->db_object->connect();
+ }
+
+ function disconnect()
+ {
+ return $this->db_object->disconnect();
+ }
+
+ function toString()
+ {
+ return $this->db_object->__toString();
+ }
+
+ function quoteString($string)
+ {
+ $string = $this->quote($string);
+ if ($string{0} == "'") {
+ return substr($string, 1, -1);
+ }
+ return $string;
+ }
+
+ function quote($string)
+ {
+ if (is_null($string)) {
+ return 'NULL';
+ }
+ return $this->db_object->quote($string);
+ }
+
+ function escapeSimple($str)
+ {
+ return $this->db_object->escape($str);
+ }
+
+ function quoteSmart($in)
+ {
+ if (is_int($in) || is_double($in)) {
+ return $in;
+ } elseif (is_bool($in)) {
+ return $in ? 1 : 0;
+ } elseif (is_null($in)) {
+ return 'NULL';
+ } else {
+ return "'" . $this->escapeSimple($in) . "'";
+ }
+ }
+
+ function quoteIdentifier($string)
+ {
+ return $this->db_object->quoteIdentifier($string);
+ }
+
+ // map?
+ function provides($feature)
+ {
+ return $this->db_object->support($feature);
+ }
+
+ // remove?
+ function errorCode($nativecode)
+ {
+ return $this->db_object->errorCode($nativecode);
+ }
+
+ // remove?
+ function errorMessage($dbcode)
+ {
+ return $this->db_object->errorMessage($dbcode);
+ }
+
+ // remove?
+ function &raiseError($code = MDB2_ERROR, $mode = null, $options = null,
+ $userinfo = null, $nativecode = null)
+ {
+ return $this->db_object->raiseError($code, $mode, $options, $userinfo, $nativecode);
+ }
+
+ function setFetchMode($fetchmode, $object_class = 'stdClass')
+ {
+ return $this->db_object->setFetchMode($fetchmode, $object_class);
+ }
+
+ function setOption($option, $value)
+ {
+ return $this->db_object->setOption($option, $value);
+ }
+
+ function getOption($option)
+ {
+ return $this->db_object->getOption($option);
+ }
+
+ function prepare($query)
+ {
+ // parse for ! and &
+ // set types
+ return $this->db_object->prepare($query);
+ }
+
+ function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT, $where = false)
+ {
+ $this->db_object->loadModule('Extended');
+ // types
+ return $this->db_object->extended->autoPrepare($table, $table_fields, $mode, $where);
+ }
+
+ function &autoExecute($table, $fields_values, $mode, $where)
+ {
+ $this->db_object->loadModule('Extended');
+ // types
+ return $this->db_object->extended->autoExecute($table, $fields_values, $mode, $where);
+ }
+
+ function buildManipSQL($table, $table_fields, $mode, $where = false)
+ {
+ $this->db_object->loadModule('Extended');
+ return $this->db_object->extended->buildManipSQL($table, $table_fields, $mode, $where);
+ }
+
+ function &execute($stmt, $data = false)
+ {
+ $stmt->bindParamArray($data);
+ return $stmt->execute();
+ }
+
+ function executeMultiple($stmt, $data)
+ {
+ $this->db_object->loadModule('Extended');
+ return $this->db_object->extended->executeMultiple($stmt, null, $data);
+ }
+
+ function &query($query, $params = array()) {
+ if (sizeof($params) > 0) {
+ $sth = $this->db_object->prepare($query);
+ if (PEAR::isError($sth)) {
+ return $sth;
+ }
+ if (!is_array($params)) {
+ $params = array($params);
+ }
+ $stmt->bindParamArray($params);
+ return $stmt->execute();
+ }
+ return $this->db_object->query($query);
+ }
+
+ function simpleQuery($query) {
+ $result = $this->db_object->query($query);
+ if (PEAR::isError($result) || $result === MDB2_OK) {
+ return $result;
+ } else {
+ return $result->result->getResource();
+ }
+ }
+
+ function limitQuery($query, $from, $count, $params = array())
+ {
+ $result = $this->db_object->setLimit($count, $from);
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+ $result =& $this->query($query, $params);
+ return $result;
+ }
+
+ function _convertNullArrayValuesToEmpty(&$array)
+ {
+ if (is_array($array)) {
+ foreach ($array as $key => $value) {
+ if (is_null($value)) {
+ $array[$key] = '';
+ }
+ }
+ }
+ }
+
+ function &getOne($query, $params = array())
+ {
+ $result = $this->query($query, $params);
+ $one = $result->result->fetchOne();
+ if (is_null($one)) {
+ $one = '';
+ }
+ return $one;
+ }
+
+ function &getRow($query,
+ $params = array(),
+ $fetchmode = MDB2_FETCHMODE_DEFAULT)
+ {
+ if (!is_array($params)) {
+ if (is_array($fetchmode)) {
+ if (is_null($params)) {
+ $tmp = DB_FETCHMODE_DEFAULT;
+ } else {
+ $tmp = $params;
+ }
+ $params = $fetchmode;
+ $fetchmode = $tmp;
+ } elseif (!is_null($params)) {
+ $fetchmode = $params;
+ $params = array();
+ }
+ }
+ $result =& $this->query($query, $params);
+ return $result->result->fetchRow($fetchmode);
+ }
+
+ function &getCol($query, $col = 0, $params = array())
+ {
+ $result =& $this->query($query, $params);
+ $col = $result->result->fetchCol($col);
+ $this->_convertNullArrayValuesToEmpty($col);
+ return $col;
+ }
+
+ function &getAssoc($query, $force_array = false, $params = array(),
+ $fetchmode = MDB2_FETCHMODE_ORDERED, $group = false)
+ {
+ $result =& $this->query($query, $params);
+ $all = $result->result->fetchAll($fetchmode, true, $force_array, $group);
+ $first = reset($all);
+ if (isset($first) && $this->db_object->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
+ if (is_array($first)) {
+ foreach ($all as $key => $arr) {
+ $this->_convertNullArrayValuesToEmpty($all[$key]);
+ }
+ } elseif (is_object($first)) {
+ foreach ($all as $key => $arr) {
+ $tmp = get_object_vars($all[$key]);
+ if (is_array($tmp)) {
+ $this->_convertNullArrayValuesToEmpty($tmp);
+ foreach ($tmp as $key2 => $column) {
+ $all[$key]->{$key2} = $column;
+ }
+ }
+ }
+ }
+ }
+ return $all;
+ }
+
+ function &getAll($query,
+ $params = null,
+ $fetchmode = MDB2_FETCHMODE_DEFAULT)
+ {
+ if (!is_array($params)) {
+ if (is_array($fetchmode)) {
+ if (is_null($params)) {
+ $tmp = DB_FETCHMODE_DEFAULT;
+ } else {
+ $tmp = $params;
+ }
+ $params = $fetchmode;
+ $fetchmode = $tmp;
+ } elseif (!is_null($params)) {
+ $fetchmode = $params;
+ $params = array();
+ }
+ }
+ $result =& $this->query($query, $params);
+ $all = $result->result->fetchAll($fetchmode);
+ $first = reset($all);
+ if (isset($first) && $this->db_object->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
+ if (is_array($first)) {
+ foreach ($all as $key => $arr) {
+ $this->_convertNullArrayValuesToEmpty($all[$key]);
+ }
+ } elseif (is_object($first)) {
+ foreach ($all as $key => $arr) {
+ $tmp = get_object_vars($all[$key]);
+ if (is_array($tmp)) {
+ $this->_convertNullArrayValuesToEmpty($tmp);
+ foreach ($tmp as $key2 => $column) {
+ $all[$key]->{$key2} = $column;
+ }
+ }
+ }
+ }
+ }
+ return $all;
+ }
+
+ function autoCommit($onoff = false)
+ {
+ return $this->db_object->autoCommit($onoff);
+ }
+
+ function commit()
+ {
+ return $this->db_object->commit();
+ }
+
+ function rollback()
+ {
+ return $this->db_object->rollback();
+ }
+
+ function affectedRows()
+ {
+ return $this->db_object->affectedRows();
+ }
+
+ // remove?
+ function errorNative()
+ {
+ return $this->db_object->errorNative();
+ }
+
+ function nextId($seq_name, $ondemand = true)
+ {
+ return $this->db_object->nextID($seq_name, $ondemand);
+ }
+
+ function createSequence($seq_name)
+ {
+ $this->db_object->loadModule('Manager');
+ return $this->db_object->manager->createSequence($seq_name, 1);
+ }
+
+ function dropSequence($seq_name)
+ {
+ $this->db_object->loadModule('Manager');
+ return $this->db_object->manager->dropSequence($seq_name);
+ }
+
+ function &_wrapResource($result)
+ {
+ if (is_resource($result)) {
+ $result_class = $this->db_object->getOption('result_buffering')
+ ? $this->db_object->getOption('buffered_result_class') : $$this->db_object->getOption('result_class');
+ $class_name = sprintf($result_class, $this->db_object->phptype);
+ $result =& new $class_name($this->db_object, $result);
+ }
+ return $result;
+ }
+
+ function fetchInto($result, &$arr, $fetchmode, $rownum = null)
+ {
+ $result = $this->_wrapResource($result);
+ if (!is_null($rownum)) {
+ $result->result->seek($rownum);
+ }
+ $arr = $result->fetchRow($fetchmode);
+ }
+
+ function freePrepared($prepared)
+ {
+ return $this->db_object->freePrepared($prepared);
+ }
+
+ function freeResult($result)
+ {
+ $result = $this->_wrapResource($result);
+ return $result->free();
+ }
+
+ function numCols($result)
+ {
+ $result = $this->_wrapResource($result);
+ return $result->numCols();
+ }
+
+ function numRows($result)
+ {
+ $result = $this->_wrapResource($result);
+ return $result->numRows();
+ }
+
+ function nextResult($result)
+ {
+ $result = $this->_wrapResource($result);
+ return $result->nextResult();
+ }
+
+ function tableInfo($result, $mode = null)
+ {
+ $result = $this->_wrapResource($result);
+ if (is_string($result) || MDB2::isResultCommon($result)) {
+ $this->db_object->loadModule('Reverse');
+ return $this->db_object->reverse->tableInfo($result, $mode);
+ }
+ return $result->tableInfo($mode);
+ }
+
+ function getTables()
+ {
+ return $this->getListOf('tables');
+ }
+
+ function getListOf($type)
+ {
+ $this->db_object->loadModule('Manager');
+ switch ($type) {
+ case 'tables':
+ return $this->db_object->manager->listTables();
+ case 'views':
+ return $this->db_object->manager->listViews();
+ case 'users':
+ return $this->db_object->manager->listUsers();
+ case 'functions':
+ return $this->db_object->manager->listFunctions();
+ case 'databases':
+ return $this->db_object->manager->listDatabases();
+ default:
+ return $this->db_object->raiseError(MDB2_ERROR_UNSUPPORTED);
+ }
+ }
+}
+?>