From d13c36941c585e84c8986e1eb47a296646cc7a21 Mon Sep 17 00:00:00 2001
From: svncommit <devs@roundcube.net>
Date: Wed, 26 Oct 2005 03:18:10 -0400
Subject: [PATCH] 

---
 program/lib/MDB2/Extended.php               |  605 +++++++++
 program/lib/MDB2/Iterator.php               |  285 ++++
 program/lib/MDB2/Wrapper/peardb.php         |  750 +++++++++++
 program/lib/MDB2/Date.php                   |  180 ++
 program/lib/MDB2/Driver/Datatype/Common.php | 1263 +++++++++++++++++++
 program/lib/MDB2/Driver/Manager/Common.php  |  616 +++++++++
 program/lib/MDB2/LOB.php                    |  146 ++
 7 files changed, 3,845 insertions(+), 0 deletions(-)

diff --git a/program/lib/MDB2/Date.php b/program/lib/MDB2/Date.php
new file mode 100755
index 0000000..df3af2c
--- /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 0000000..808fd18
--- /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 0000000..a9de441
--- /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 0000000..cc308bf
--- /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 0000000..13db77a
--- /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 0000000..c17abc9
--- /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 0000000..a7123b3
--- /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);
+        }
+    }
+}
+?>

--
Gitblit v1.9.1