From e5deaae52880e7ddb7efab0b190e5f5c750f55c4 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 12 May 2008 08:19:32 -0400
Subject: [PATCH] - Updated PEAR::DB package to version 1.7.13

---
 program/lib/DB/ifx.php     |   18 
 program/lib/DB/msql.php    |   39 +
 CHANGELOG                  |    3 
 program/lib/DB/mysql.php   |   39 +
 program/lib/DB/storage.php |   10 
 program/lib/DB/dbase.php   |   70 +-
 program/lib/DB/sybase.php  |   67 ++
 program/lib/DB/odbc.php    |   10 
 program/lib/DB/common.php  |  150 ++++++-
 program/lib/DB/oci8.php    |  133 ++++--
 program/lib/DB/mysqli.php  |   46 +
 program/lib/DB/pgsql.php   |  131 +++--
 program/lib/DB.php         |  151 ++++++-
 program/lib/DB/ibase.php   |   45 +
 program/lib/DB/fbsql.php   |   71 +-
 program/lib/DB/sqlite.php  |   35 +
 program/lib/DB/mssql.php   |   79 +++
 17 files changed, 761 insertions(+), 336 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 7d4c81c..beb2823 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,9 @@
 CHANGELOG RoundCube Webmail
 ---------------------------
 
+2008/05/12 (alec)
+- Updated PEAR::DB package to version 1.7.13
+
 2008/05/10 (alec)
 - Make password input fields of type password in installer (#1484886)
 
diff --git a/program/lib/DB.php b/program/lib/DB.php
index e2beeca..f769133 100644
--- a/program/lib/DB.php
+++ b/program/lib/DB.php
@@ -18,7 +18,7 @@
  * @author     Stig Bakken <ssb@php.net>
  * @author     Tomas V.V.Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -424,9 +424,9 @@
  * @author     Stig Bakken <ssb@php.net>
  * @author     Tomas V.V.Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB
@@ -467,7 +467,7 @@
             return $tmp;
         }
 
-        @$obj =& new $classname;
+        @$obj = new $classname;
 
         foreach ($options as $option => $value) {
             $test = $obj->setOption($option, $value);
@@ -544,7 +544,7 @@
             return $tmp;
         }
 
-        @$obj =& new $classname;
+        @$obj = new $classname;
 
         foreach ($options as $option => $value) {
             $test = $obj->setOption($option, $value);
@@ -555,7 +555,11 @@
 
         $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
         if (DB::isError($err)) {
-            $err->addUserInfo($dsn);
+            if (is_array($dsn)) {
+                $err->addUserInfo(DB::getDSNString($dsn, true));
+            } else {
+                $err->addUserInfo($dsn);
+            }
             return $err;
         }
 
@@ -572,7 +576,7 @@
      */
     function apiVersion()
     {
-        return '@package_version@';
+        return '1.7.13';
     }
 
     // }}}
@@ -625,7 +629,7 @@
     {
         $manips = 'INSERT|UPDATE|DELETE|REPLACE|'
                 . 'CREATE|DROP|'
-                . 'LOAD DATA|SELECT .* INTO|COPY|'
+                . 'LOAD DATA|SELECT .* INTO .* FROM|COPY|'
                 . 'ALTER|GRANT|REVOKE|'
                 . 'LOCK|UNLOCK';
         if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
@@ -808,13 +812,11 @@
         // process the different protocol options
         $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
         $proto_opts = rawurldecode($proto_opts);
+        if (strpos($proto_opts, ':') !== false) {
+            list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
+        }
         if ($parsed['protocol'] == 'tcp') {
-            if (strpos($proto_opts, ':') !== false) {
-                list($parsed['hostspec'],
-                     $parsed['port']) = explode(':', $proto_opts);
-            } else {
-                $parsed['hostspec'] = $proto_opts;
-            }
+            $parsed['hostspec'] = $proto_opts;
         } elseif ($parsed['protocol'] == 'unix') {
             $parsed['socket'] = $proto_opts;
         }
@@ -848,6 +850,82 @@
     }
 
     // }}}
+    // {{{ getDSNString()
+
+    /**
+     * Returns the given DSN in a string format suitable for output.
+     *
+     * @param array|string the DSN to parse and format
+     * @param boolean true to hide the password, false to include it
+     * @return string
+     */
+    function getDSNString($dsn, $hidePassword) {
+        /* Calling parseDSN will ensure that we have all the array elements
+         * defined, and means that we deal with strings and array in the same
+         * manner. */
+        $dsnArray = DB::parseDSN($dsn);
+        
+        if ($hidePassword) {
+            $dsnArray['password'] = 'PASSWORD';
+        }
+
+        /* Protocol is special-cased, as using the default "tcp" along with an
+         * Oracle TNS connection string fails. */
+        if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') {
+            $dsnArray['protocol'] = false;
+        }
+        
+        // Now we just have to construct the actual string. This is ugly.
+        $dsnString = $dsnArray['phptype'];
+        if ($dsnArray['dbsyntax']) {
+            $dsnString .= '('.$dsnArray['dbsyntax'].')';
+        }
+        $dsnString .= '://'
+                     .$dsnArray['username']
+                     .':'
+                     .$dsnArray['password']
+                     .'@'
+                     .$dsnArray['protocol'];
+        if ($dsnArray['socket']) {
+            $dsnString .= '('.$dsnArray['socket'].')';
+        }
+        if ($dsnArray['protocol'] && $dsnArray['hostspec']) {
+            $dsnString .= '+';
+        }
+        $dsnString .= $dsnArray['hostspec'];
+        if ($dsnArray['port']) {
+            $dsnString .= ':'.$dsnArray['port'];
+        }
+        $dsnString .= '/'.$dsnArray['database'];
+        
+        /* Option handling. Unfortunately, parseDSN simply places options into
+         * the top-level array, so we'll first get rid of the fields defined by
+         * DB and see what's left. */
+        unset($dsnArray['phptype'],
+              $dsnArray['dbsyntax'],
+              $dsnArray['username'],
+              $dsnArray['password'],
+              $dsnArray['protocol'],
+              $dsnArray['socket'],
+              $dsnArray['hostspec'],
+              $dsnArray['port'],
+              $dsnArray['database']
+        );
+        if (count($dsnArray) > 0) {
+            $dsnString .= '?';
+            $i = 0;
+            foreach ($dsnArray as $key => $value) {
+                if (++$i > 1) {
+                    $dsnString .= '&';
+                }
+                $dsnString .= $key.'='.$value;
+            }
+        }
+
+        return $dsnString;
+    }
+    
+    // }}}
 }
 
 // }}}
@@ -860,9 +938,9 @@
  * @category   Database
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_Error extends PEAR_Error
@@ -907,9 +985,9 @@
  * @category   Database
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_result
@@ -1089,7 +1167,7 @@
             $fetchmode = DB_FETCHMODE_ASSOC;
             $object_class = $this->fetchmode_object_class;
         }
-        if ($this->limit_from !== null) {
+        if (is_null($rownum) && $this->limit_from !== null) {
             if ($this->row_counter === null) {
                 $this->row_counter = $this->limit_from;
                 // Skip rows
@@ -1121,7 +1199,7 @@
                 if ($object_class == 'stdClass') {
                     $arr = (object) $arr;
                 } else {
-                    $arr = &new $object_class($arr);
+                    $arr = new $object_class($arr);
                 }
             }
             return $arr;
@@ -1171,7 +1249,7 @@
             $fetchmode = DB_FETCHMODE_ASSOC;
             $object_class = $this->fetchmode_object_class;
         }
-        if ($this->limit_from !== null) {
+        if (is_null($rownum) && $this->limit_from !== null) {
             if ($this->row_counter === null) {
                 $this->row_counter = $this->limit_from;
                 // Skip rows
@@ -1253,10 +1331,33 @@
             while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
                 $i++;
             }
-            return $i;
+            $count = $i;
         } else {
-            return $this->dbh->numRows($this->result);
+            $count = $this->dbh->numRows($this->result);
         }
+
+        /* fbsql is checked for here because limit queries are implemented
+         * using a TOP() function, which results in fbsql_num_rows still
+         * returning the total number of rows that would have been returned,
+         * rather than the real number. As a result, we'll just do the limit
+         * calculations for fbsql in the same way as a database with emulated
+         * limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
+         * because that only gets the result resource, rather than the full
+         * DB_Result object. */
+        if (($this->dbh->features['limit'] === 'emulate'
+             && $this->limit_from !== null)
+            || $this->dbh->phptype == 'fbsql') {
+            $limit_count = is_null($this->limit_count) ? $count : $this->limit_count;
+            if ($count < $this->limit_from) {
+                $count = 0;
+            } elseif ($count < ($this->limit_from + $limit_count)) {
+                $count -= $this->limit_from;
+            } else {
+                $count = $limit_count;
+            }
+        }
+
+        return $count;
     }
 
     // }}}
@@ -1349,9 +1450,9 @@
  * @category   Database
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  * @see        DB_common::setFetchMode()
  */
diff --git a/program/lib/DB/common.php b/program/lib/DB/common.php
index 7988e71..f54dedc 100644
--- a/program/lib/DB/common.php
+++ b/program/lib/DB/common.php
@@ -18,7 +18,7 @@
  * @author     Stig Bakken <ssb@php.net>
  * @author     Tomas V.V. Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -40,9 +40,9 @@
  * @author     Stig Bakken <ssb@php.net>
  * @author     Tomas V.V. Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_common extends PEAR
@@ -120,6 +120,21 @@
      * @var array
      */
     var $prepared_queries = array();
+
+    /**
+     * Flag indicating that the last query was a manipulation query.
+     * @access protected
+     * @var boolean
+     */
+    var $_last_query_manip = false;
+
+    /**
+     * Flag indicating that the next query <em>must</em> be a manipulation
+     * query.
+     * @access protected
+     * @var boolean
+     */
+    var $_next_query_manip = false;
 
 
     // }}}
@@ -424,17 +439,56 @@
      */
     function quoteSmart($in)
     {
-        if (is_int($in) || is_double($in)) {
+        if (is_int($in)) {
             return $in;
+        } elseif (is_float($in)) {
+            return $this->quoteFloat($in);
         } elseif (is_bool($in)) {
-            return $in ? 1 : 0;
+            return $this->quoteBoolean($in);
         } elseif (is_null($in)) {
             return 'NULL';
         } else {
+            if ($this->dbsyntax == 'access'
+                && preg_match('/^#.+#$/', $in))
+            {
+                return $this->escapeSimple($in);
+            }
             return "'" . $this->escapeSimple($in) . "'";
         }
     }
 
+    // }}}
+    // {{{ quoteBoolean()
+
+    /**
+     * Formats a boolean value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param boolean the boolean value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteBoolean($boolean) {
+        return $boolean ? '1' : '0';
+    }
+     
+    // }}}
+    // {{{ quoteFloat()
+
+    /**
+     * Formats a float value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param float the float value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteFloat($float) {
+        return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'";
+    }
+     
     // }}}
     // {{{ escapeSimple()
 
@@ -837,7 +891,7 @@
         if (DB::isError($sth)) {
             return $sth;
         }
-        $ret =& $this->execute($sth, array_values($fields_values));
+        $ret = $this->execute($sth, array_values($fields_values));
         $this->freePrepared($sth);
         return $ret;
 
@@ -931,7 +985,7 @@
      *     "'it''s good'",
      *     'filename.txt'
      * );
-     * $res =& $db->execute($sth, $data);
+     * $res = $db->execute($sth, $data);
      * </code>
      *
      * @param resource $stmt  a DB statement resource returned from prepare()
@@ -960,7 +1014,7 @@
         if ($result === DB_OK || DB::isError($result)) {
             return $result;
         } else {
-            $tmp =& new DB_result($this, $result);
+            $tmp = new DB_result($this, $result);
             return $tmp;
         }
     }
@@ -1041,7 +1095,7 @@
     function executeMultiple($stmt, $data)
     {
         foreach ($data as $value) {
-            $res =& $this->execute($stmt, $value);
+            $res = $this->execute($stmt, $value);
             if (DB::isError($res)) {
                 return $res;
             }
@@ -1154,7 +1208,7 @@
             if (DB::isError($sth)) {
                 return $sth;
             }
-            $ret =& $this->execute($sth, $params);
+            $ret = $this->execute($sth, $params);
             $this->freePrepared($sth, false);
             return $ret;
         } else {
@@ -1163,7 +1217,7 @@
             if ($result === DB_OK || DB::isError($result)) {
                 return $result;
             } else {
-                $tmp =& new DB_result($this, $result);
+                $tmp = new DB_result($this, $result);
                 return $tmp;
             }
         }
@@ -1194,7 +1248,7 @@
         if (DB::isError($query)){
             return $query;
         }
-        $result =& $this->query($query, $params);
+        $result = $this->query($query, $params);
         if (is_a($result, 'DB_result')) {
             $result->setOption('limit_from', $from);
             $result->setOption('limit_count', $count);
@@ -1229,10 +1283,10 @@
             if (DB::isError($sth)) {
                 return $sth;
             }
-            $res =& $this->execute($sth, $params);
+            $res = $this->execute($sth, $params);
             $this->freePrepared($sth);
         } else {
-            $res =& $this->query($query);
+            $res = $this->query($query);
         }
 
         if (DB::isError($res)) {
@@ -1293,10 +1347,10 @@
             if (DB::isError($sth)) {
                 return $sth;
             }
-            $res =& $this->execute($sth, $params);
+            $res = $this->execute($sth, $params);
             $this->freePrepared($sth);
         } else {
-            $res =& $this->query($query);
+            $res = $this->query($query);
         }
 
         if (DB::isError($res)) {
@@ -1344,10 +1398,10 @@
                 return $sth;
             }
 
-            $res =& $this->execute($sth, $params);
+            $res = $this->execute($sth, $params);
             $this->freePrepared($sth);
         } else {
-            $res =& $this->query($query);
+            $res = $this->query($query);
         }
 
         if (DB::isError($res)) {
@@ -1360,7 +1414,7 @@
             $ret = array();
         } else {
             if (!array_key_exists($col, $row)) {
-                $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
+                $ret = $this->raiseError(DB_ERROR_NOSUCHFIELD);
             } else {
                 $ret = array($row[$col]);
                 while (is_array($row = $res->fetchRow($fetchmode))) {
@@ -1476,10 +1530,10 @@
                 return $sth;
             }
 
-            $res =& $this->execute($sth, $params);
+            $res = $this->execute($sth, $params);
             $this->freePrepared($sth);
         } else {
-            $res =& $this->query($query);
+            $res = $this->query($query);
         }
 
         if (DB::isError($res)) {
@@ -1491,7 +1545,7 @@
         $cols = $res->numCols();
 
         if ($cols < 2) {
-            $tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
+            $tmp = $this->raiseError(DB_ERROR_TRUNCATED);
             return $tmp;
         }
 
@@ -1603,10 +1657,10 @@
                 return $sth;
             }
 
-            $res =& $this->execute($sth, $params);
+            $res = $this->execute($sth, $params);
             $this->freePrepared($sth);
         } else {
-            $res =& $this->query($query);
+            $res = $this->query($query);
         }
 
         if ($res === DB_OK || DB::isError($res)) {
@@ -1627,7 +1681,7 @@
         $res->free();
 
         if (DB::isError($row)) {
-            $tmp =& $this->raiseError($row);
+            $tmp = $this->raiseError($row);
             return $tmp;
         }
         return $results;
@@ -2103,6 +2157,52 @@
     }
 
     // }}}
+    // {{{ nextQueryIsManip()
+
+    /**
+     * Sets (or unsets) a flag indicating that the next query will be a
+     * manipulation query, regardless of the usual DB::isManip() heuristics.
+     *
+     * @param boolean true to set the flag overriding the isManip() behaviour,
+     * false to clear it and fall back onto isManip()
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function nextQueryIsManip($manip)
+    {
+        $this->_next_query_manip = $manip;
+    }
+
+    // }}}
+    // {{{ _checkManip()
+
+    /**
+     * Checks if the given query is a manipulation query. This also takes into
+     * account the _next_query_manip flag and sets the _last_query_manip flag
+     * (and resets _next_query_manip) according to the result.
+     *
+     * @param string The query to check.
+     *
+     * @return boolean true if the query is a manipulation query, false
+     * otherwise
+     *
+     * @access protected
+     */
+    function _checkManip($query)
+    {
+        if ($this->_next_query_manip || DB::isManip($query)) {
+            $this->_last_query_manip = true;
+        } else {
+            $this->_last_query_manip = false;
+        }
+        $this->_next_query_manip = false;
+        return $this->_last_query_manip;
+        $manip = $this->_next_query_manip;
+    }
+
+    // }}}
     // {{{ _rtrimArrayValues()
 
     /**
diff --git a/program/lib/DB/dbase.php b/program/lib/DB/dbase.php
index 6026f15..25455cc 100644
--- a/program/lib/DB/dbase.php
+++ b/program/lib/DB/dbase.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Tomas V.V. Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -39,9 +39,9 @@
  * @package    DB
  * @author     Tomas V.V. Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_dbase extends DB_common
@@ -188,7 +188,7 @@
      *     'portability' => DB_PORTABILITY_ALL,
      * );
      *
-     * $db =& DB::connect($dsn, $options);
+     * $db = DB::connect($dsn, $options);
      * if (PEAR::isError($db)) {
      *     die($db->getMessage());
      * }
@@ -214,7 +214,7 @@
          * Turn track_errors on for entire script since $php_errormsg
          * is the only way to find errors from the dbase extension.
          */
-        ini_set('track_errors', 1);
+        @ini_set('track_errors', 1);
         $php_errormsg = '';
 
         if (!file_exists($dsn['database'])) {
@@ -273,7 +273,7 @@
     {
         // emulate result resources
         $this->res_row[(int)$this->result] = 0;
-        $tmp =& new DB_result($this, $this->result++);
+        $tmp = new DB_result($this, $this->result++);
         return $tmp;
     }
 
@@ -326,6 +326,26 @@
     }
 
     // }}}
+    // {{{ freeResult()
+
+    /**
+     * Deletes the result set and frees the memory occupied by the result set.
+     *
+     * This method is a no-op for dbase, as there aren't result resources in
+     * the same sense as most other database backends.
+     *
+     * @param resource $result  PHP's query result resource
+     *
+     * @return bool  TRUE on success, FALSE if $result is invalid
+     *
+     * @see DB_result::free()
+     */
+    function freeResult($result)
+    {
+        return true;
+    }
+
+    // }}}
     // {{{ numCols()
 
     /**
@@ -368,41 +388,21 @@
     }
 
     // }}}
-    // {{{ quoteSmart()
+    // {{{ quoteBoolean()
 
     /**
-     * Formats input so it can be safely used in a query
+     * Formats a boolean value for use within a query in a locale-independent
+     * manner.
      *
-     * @param mixed $in  the data to be formatted
-     *
-     * @return mixed  the formatted data.  The format depends on the input's
-     *                 PHP type:
-     *                 + null = the string <samp>NULL</samp>
-     *                 + boolean = <samp>T</samp> if true or
-     *                   <samp>F</samp> if false.  Use the <kbd>Logical</kbd>
-     *                   data type.
-     *                 + integer or double = the unquoted number
-     *                 + other (including strings and numeric strings) =
-     *                   the data with single quotes escaped by preceeding
-     *                   single quotes then the whole string is encapsulated
-     *                   between single quotes
-     *
+     * @param boolean the boolean value to be quoted.
+     * @return string the quoted string.
      * @see DB_common::quoteSmart()
-     * @since Method available since Release 1.6.0
+     * @since Method available since release 1.7.8.
      */
-    function quoteSmart($in)
-    {
-        if (is_int($in) || is_double($in)) {
-            return $in;
-        } elseif (is_bool($in)) {
-            return $in ? 'T' : 'F';
-        } elseif (is_null($in)) {
-            return 'NULL';
-        } else {
-            return "'" . $this->escapeSimple($in) . "'";
-        }
+    function quoteBoolean($boolean) {
+        return $boolean ? 'T' : 'F';
     }
-
+     
     // }}}
     // {{{ tableInfo()
 
diff --git a/program/lib/DB/fbsql.php b/program/lib/DB/fbsql.php
index b25868d..8ebcccd 100644
--- a/program/lib/DB/fbsql.php
+++ b/program/lib/DB/fbsql.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Frank M. Kromann <frank@frontbase.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -39,9 +39,9 @@
  * @package    DB
  * @author     Frank M. Kromann <frank@frontbase.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  * @since      Class functional since Release 1.7.0
  */
@@ -171,10 +171,10 @@
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
         } else {
-            ini_set('track_errors', 1);
+            @ini_set('track_errors', 1);
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
-            ini_set('track_errors', $ini);
+            @ini_set('track_errors', $ini);
         }
 
         if (!$this->connection) {
@@ -229,7 +229,7 @@
         }
         // Determine which queries that should return data, and which
         // should return an error code only.
-        if (DB::isManip($query)) {
+        if ($this->_checkManip($query)) {
             return DB_OK;
         }
         return $result;
@@ -320,7 +320,7 @@
      */
     function freeResult($result)
     {
-        return @fbsql_free_result($result);
+        return is_resource($result) ? fbsql_free_result($result) : false;
     }
 
     // }}}
@@ -353,7 +353,7 @@
      */
     function commit()
     {
-        @fbsql_commit();
+        @fbsql_commit($this->connection);
     }
 
     // }}}
@@ -366,7 +366,7 @@
      */
     function rollback()
     {
-        @fbsql_rollback();
+        @fbsql_rollback($this->connection);
     }
 
     // }}}
@@ -431,7 +431,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             $result = @fbsql_affected_rows($this->connection);
         } else {
             $result = 0;
@@ -543,7 +543,7 @@
      */
     function modifyLimitQuery($query, $from, $count, $params = array())
     {
-        if (DB::isManip($query)) {
+        if (DB::isManip($query) || $this->_next_query_manip) {
             return preg_replace('/^([\s(])*SELECT/i',
                                 "\\1SELECT TOP($count)", $query);
         } else {
@@ -553,38 +553,37 @@
     }
 
     // }}}
-    // {{{ quoteSmart()
+    // {{{ quoteBoolean()
 
     /**
-     * Formats input so it can be safely used in a query
+     * Formats a boolean value for use within a query in a locale-independent
+     * manner.
      *
-     * @param mixed $in  the data to be formatted
-     *
-     * @return mixed  the formatted data.  The format depends on the input's
-     *                 PHP type:
-     *                 + null = the string <samp>NULL</samp>
-     *                 + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
-     *                 + integer or double = the unquoted number
-     *                 + other (including strings and numeric strings) =
-     *                   the data escaped according to FrontBase's settings
-     *                   then encapsulated between single quotes
-     *
+     * @param boolean the boolean value to be quoted.
+     * @return string the quoted string.
      * @see DB_common::quoteSmart()
-     * @since Method available since Release 1.6.0
+     * @since Method available since release 1.7.8.
      */
-    function quoteSmart($in)
-    {
-        if (is_int($in) || is_double($in)) {
-            return $in;
-        } elseif (is_bool($in)) {
-            return $in ? 'TRUE' : 'FALSE';
-        } elseif (is_null($in)) {
-            return 'NULL';
-        } else {
-            return "'" . $this->escapeSimple($in) . "'";
-        }
+    function quoteBoolean($boolean) {
+        return $boolean ? 'TRUE' : 'FALSE';
     }
+     
+    // }}}
+    // {{{ quoteFloat()
 
+    /**
+     * Formats a float value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param float the float value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteFloat($float) {
+        return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
+    }
+     
     // }}}
     // {{{ fbsqlRaiseError()
 
diff --git a/program/lib/DB/ibase.php b/program/lib/DB/ibase.php
index b5e2386..913fbf3 100644
--- a/program/lib/DB/ibase.php
+++ b/program/lib/DB/ibase.php
@@ -21,7 +21,7 @@
  * @package    DB
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -47,9 +47,9 @@
  * @package    DB
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  * @since      Class became stable in Release 1.7.0
  */
@@ -123,6 +123,7 @@
         -625 => DB_ERROR_CONSTRAINT_NOT_NULL,
         -803 => DB_ERROR_CONSTRAINT,
         -804 => DB_ERROR_VALUE_COUNT_ON_ROW,
+        // -902 =>  // Covers too many errors, need to use regex on msg
         -904 => DB_ERROR_CONNECT_FAILED,
         -922 => DB_ERROR_NOSUCHDB,
         -923 => DB_ERROR_CONNECT_FAILED,
@@ -275,7 +276,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $query = $this->modifyQuery($query);
         $result = @ibase_query($this->connection, $query);
@@ -412,7 +413,7 @@
      */
     function freeResult($result)
     {
-        return @ibase_free_result($result);
+        return is_resource($result) ? ibase_free_result($result) : false;
     }
 
     // }}}
@@ -420,8 +421,7 @@
 
     function freeQuery($query)
     {
-        @ibase_free_query($query);
-        return true;
+        return is_resource($query) ? ibase_free_query($query) : false;
     }
 
     // }}}
@@ -521,8 +521,14 @@
         $this->last_query = $query;
         $newquery = $this->modifyQuery($newquery);
         $stmt = @ibase_prepare($this->connection, $newquery);
-        $this->prepare_types[(int)$stmt] = $types;
-        $this->manip_query[(int)$stmt]   = DB::isManip($query);
+
+        if ($stmt === false) {
+            $stmt = $this->ibaseRaiseError();
+        } else {
+            $this->prepare_types[(int)$stmt] = $types;
+            $this->manip_query[(int)$stmt]   = DB::isManip($query);
+        }
+
         return $stmt;
     }
 
@@ -547,9 +553,9 @@
         $data = (array)$data;
         $this->last_parameters = $data;
 
-        $types =& $this->prepare_types[(int)$stmt];
+        $types = $this->prepare_types[(int)$stmt];
         if (count($types) != count($data)) {
-            $tmp =& $this->raiseError(DB_ERROR_MISMATCH);
+            $tmp = $this->raiseError(DB_ERROR_MISMATCH);
             return $tmp;
         }
 
@@ -568,7 +574,7 @@
             } elseif ($types[$i] == DB_PARAM_OPAQUE) {
                 $fp = @fopen($data[$key], 'rb');
                 if (!$fp) {
-                    $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
+                    $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
                     return $tmp;
                 }
                 $data[$key] = fread($fp, filesize($data[$key]));
@@ -581,7 +587,7 @@
 
         $res = call_user_func_array('ibase_execute', $data);
         if (!$res) {
-            $tmp =& $this->ibaseRaiseError();
+            $tmp = $this->ibaseRaiseError();
             return $tmp;
         }
         /* XXX need this?
@@ -589,10 +595,13 @@
             @ibase_commit($this->connection);
         }*/
         $this->last_stmt = $stmt;
-        if ($this->manip_query[(int)$stmt]) {
+        if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
+            $this->_last_query_manip = true;
+            $this->_next_query_manip = false;
             $tmp = DB_OK;
         } else {
-            $tmp =& new DB_result($this, $res);
+            $this->_last_query_manip = false;
+            $tmp = new DB_result($this, $res);
         }
         return $tmp;
     }
@@ -698,7 +707,7 @@
         $repeat = 0;
         do {
             $this->pushErrorHandling(PEAR_ERROR_RETURN);
-            $result =& $this->query("SELECT GEN_ID(${sqn}, 1) "
+            $result = $this->query("SELECT GEN_ID(${sqn}, 1) "
                                    . 'FROM RDB$GENERATORS '
                                    . "WHERE RDB\$GENERATOR_NAME='${sqn}'");
             $this->popErrorHandling();
@@ -856,7 +865,7 @@
         if ($errno === null) {
             $errno = $this->errorCode($this->errorNative());
         }
-        $tmp =& $this->raiseError($errno, null, null, null, @ibase_errmsg());
+        $tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg());
         return $tmp;
     }
 
@@ -925,6 +934,8 @@
                     => DB_ERROR_ACCESS_VIOLATION,
                 '/arithmetic exception, numeric overflow, or string truncation/i'
                     => DB_ERROR_INVALID,
+                '/feature is not supported/i'
+                    => DB_ERROR_NOT_CAPABLE,
             );
         }
 
diff --git a/program/lib/DB/ifx.php b/program/lib/DB/ifx.php
index 22575c7..f08cf66 100644
--- a/program/lib/DB/ifx.php
+++ b/program/lib/DB/ifx.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Tomas V.V.Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -46,9 +46,9 @@
  * @package    DB
  * @author     Tomas V.V.Cox <cox@idecnet.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_ifx extends DB_common
@@ -101,6 +101,7 @@
         '-236'    => DB_ERROR_VALUE_COUNT_ON_ROW,
         '-239'    => DB_ERROR_CONSTRAINT,
         '-253'    => DB_ERROR_SYNTAX,
+        '-268'    => DB_ERROR_CONSTRAINT,
         '-292'    => DB_ERROR_CONSTRAINT_NOT_NULL,
         '-310'    => DB_ERROR_ALREADY_EXISTS,
         '-316'    => DB_ERROR_ALREADY_EXISTS,
@@ -113,6 +114,7 @@
         '-691'    => DB_ERROR_CONSTRAINT,
         '-692'    => DB_ERROR_CONSTRAINT,
         '-703'    => DB_ERROR_CONSTRAINT_NOT_NULL,
+        '-1202'   => DB_ERROR_DIVZERO,
         '-1204'   => DB_ERROR_INVALID_DATE,
         '-1205'   => DB_ERROR_INVALID_DATE,
         '-1206'   => DB_ERROR_INVALID_DATE,
@@ -243,10 +245,10 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $this->affected   = null;
-        if (preg_match('/(SELECT)/i', $query)) {    //TESTME: Use !DB::isManip()?
+        if (preg_match('/(SELECT|EXECUTE)/i', $query)) {    //TESTME: Use !DB::isManip()?
             // the scroll is needed for fetching absolute row numbers
             // in a select query result
             $result = @ifx_query($query, $this->connection, IFX_SCROLL);
@@ -268,7 +270,7 @@
         $this->affected = @ifx_affected_rows($result);
         // Determine which queries should return data, and which
         // should return an error code only.
-        if (preg_match('/(SELECT)/i', $query)) {
+        if (preg_match('/(SELECT|EXECUTE)/i', $query)) {
             return $result;
         }
         // XXX Testme: free results inside a transaction
@@ -309,7 +311,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             return $this->affected;
         } else {
             return 0;
@@ -420,7 +422,7 @@
      */
     function freeResult($result)
     {
-        return @ifx_free_result($result);
+        return is_resource($result) ? ifx_free_result($result) : false;
     }
 
     // }}}
diff --git a/program/lib/DB/msql.php b/program/lib/DB/msql.php
index 81ca855..e396833 100644
--- a/program/lib/DB/msql.php
+++ b/program/lib/DB/msql.php
@@ -21,7 +21,7 @@
  * @category   Database
  * @package    DB
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -45,9 +45,9 @@
  * @category   Database
  * @package    DB
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  * @since      Class not functional until Release 1.7.0
  */
@@ -153,7 +153,7 @@
      *     'portability' => DB_PORTABILITY_ALL,
      * );
      * 
-     * $db =& DB::connect($dsn, $options);
+     * $db = DB::connect($dsn, $options);
      * if (PEAR::isError($db)) {
      *     die($db->getMessage());
      * }
@@ -190,10 +190,10 @@
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
         } else {
-            ini_set('track_errors', 1);
+            @ini_set('track_errors', 1);
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
-            ini_set('track_errors', $ini);
+            @ini_set('track_errors', $ini);
         }
 
         if (!$this->connection) {
@@ -251,7 +251,7 @@
         }
         // Determine which queries that should return data, and which
         // should return an error code only.
-        if (DB::isManip($query)) {
+        if ($this->_checkManip($query)) {
             $this->_result = $result;
             return DB_OK;
         } else {
@@ -350,7 +350,7 @@
      */
     function freeResult($result)
     {
-        return @msql_free_result($result);
+        return is_resource($result) ? msql_free_result($result) : false;
     }
 
     // }}}
@@ -443,7 +443,7 @@
         $repeat = false;
         do {
             $this->pushErrorHandling(PEAR_ERROR_RETURN);
-            $result =& $this->query("SELECT _seq FROM ${seqname}");
+            $result = $this->query("SELECT _seq FROM ${seqname}");
             $this->popErrorHandling();
             if ($ondemand && DB::isError($result) &&
                 $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@@ -531,6 +531,22 @@
     }
 
     // }}}
+    // {{{ quoteFloat()
+
+    /**
+     * Formats a float value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param float the float value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteFloat($float) {
+        return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
+    }
+     
+    // }}}
     // {{{ escapeSimple()
 
     /**
@@ -598,6 +614,11 @@
     function errorCode($errormsg)
     {
         static $error_regexps;
+        
+        // PHP 5.2+ prepends the function name to $php_errormsg, so we need
+        // this hack to work around it, per bug #9599.
+        $errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg);
+
         if (!isset($error_regexps)) {
             $error_regexps = array(
                 '/^Access to database denied/i'
diff --git a/program/lib/DB/mssql.php b/program/lib/DB/mssql.php
index a84db89..8452f08 100644
--- a/program/lib/DB/mssql.php
+++ b/program/lib/DB/mssql.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -35,13 +35,21 @@
  *
  * These methods overload the ones declared in DB_common.
  *
+ * DB's mssql driver is only for Microsfoft SQL Server databases.
+ *
+ * If you're connecting to a Sybase database, you MUST specify "sybase"
+ * as the "phptype" in the DSN.
+ *
+ * This class only works correctly if you have compiled PHP using
+ * --with-mssql=[dir_to_FreeTDS].
+ *
  * @category   Database
  * @package    DB
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_mssql extends DB_common
@@ -89,19 +97,40 @@
      */
     // XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
     var $errorcode_map = array(
+        102   => DB_ERROR_SYNTAX,
         110   => DB_ERROR_VALUE_COUNT_ON_ROW,
         155   => DB_ERROR_NOSUCHFIELD,
+        156   => DB_ERROR_SYNTAX,
         170   => DB_ERROR_SYNTAX,
         207   => DB_ERROR_NOSUCHFIELD,
         208   => DB_ERROR_NOSUCHTABLE,
         245   => DB_ERROR_INVALID_NUMBER,
+        319   => DB_ERROR_SYNTAX,
+        321   => DB_ERROR_NOSUCHFIELD,
+        325   => DB_ERROR_SYNTAX,
+        336   => DB_ERROR_SYNTAX,
         515   => DB_ERROR_CONSTRAINT_NOT_NULL,
         547   => DB_ERROR_CONSTRAINT,
+        1018  => DB_ERROR_SYNTAX,
+        1035  => DB_ERROR_SYNTAX,
         1913  => DB_ERROR_ALREADY_EXISTS,
+        2209  => DB_ERROR_SYNTAX,
+        2223  => DB_ERROR_SYNTAX,
+        2248  => DB_ERROR_SYNTAX,
+        2256  => DB_ERROR_SYNTAX,
+        2257  => DB_ERROR_SYNTAX,
         2627  => DB_ERROR_CONSTRAINT,
         2714  => DB_ERROR_ALREADY_EXISTS,
+        3607  => DB_ERROR_DIVZERO,
         3701  => DB_ERROR_NOSUCHTABLE,
+        7630  => DB_ERROR_SYNTAX,
         8134  => DB_ERROR_DIVZERO,
+        9303  => DB_ERROR_SYNTAX,
+        9317  => DB_ERROR_SYNTAX,
+        9318  => DB_ERROR_SYNTAX,
+        9331  => DB_ERROR_SYNTAX,
+        9332  => DB_ERROR_SYNTAX,
+        15253 => DB_ERROR_SYNTAX,
     );
 
     /**
@@ -244,7 +273,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         if (!@mssql_select_db($this->_db, $this->connection)) {
             return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
@@ -316,7 +345,7 @@
             }
         }
         if ($fetchmode & DB_FETCHMODE_ASSOC) {
-            $arr = @mssql_fetch_array($result, MSSQL_ASSOC);
+            $arr = @mssql_fetch_assoc($result);
             if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
                 $arr = array_change_key_case($arr, CASE_LOWER);
             }
@@ -353,7 +382,7 @@
      */
     function freeResult($result)
     {
-        return @mssql_free_result($result);
+        return is_resource($result) ? mssql_free_result($result) : false;
     }
 
     // }}}
@@ -483,7 +512,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             $res = @mssql_query('select @@rowcount', $this->connection);
             if (!$res) {
                 return $this->mssqlRaiseError();
@@ -537,7 +566,15 @@
                     return $this->raiseError($result);
                 }
             } elseif (!DB::isError($result)) {
-                $result =& $this->query("SELECT @@IDENTITY FROM $seqname");
+                $result = $this->query("SELECT IDENT_CURRENT('$seqname')");
+                if (DB::isError($result)) {
+                    /* Fallback code for MS SQL Server 7.0, which doesn't have
+                     * IDENT_CURRENT. This is *not* safe for concurrent
+                     * requests, and really, if you're using it, you're in a
+                     * world of hurt. Nevertheless, it's here to ensure BC. See
+                     * bug #181 for the gory details.*/
+                    $result = $this->query("SELECT @@IDENTITY FROM $seqname");
+                }
                 $repeat = 0;
             } else {
                 $repeat = false;
@@ -745,16 +782,22 @@
         }
 
         for ($i = 0; $i < $count; $i++) {
+            if ($got_string) {
+                $flags = $this->_mssql_field_flags($result,
+                        @mssql_field_name($id, $i));
+                if (DB::isError($flags)) {
+                    return $flags;
+                }
+            } else {
+                $flags = '';
+            }
+
             $res[$i] = array(
                 'table' => $got_string ? $case_func($result) : '',
                 'name'  => $case_func(@mssql_field_name($id, $i)),
                 'type'  => @mssql_field_type($id, $i),
                 'len'   => @mssql_field_length($id, $i),
-                // We only support flags for table
-                'flags' => $got_string
-                           ? $this->_mssql_field_flags($result,
-                                                       @mssql_field_name($id, $i))
-                           : '',
+                'flags' => $flags,
             );
             if ($mode & DB_TABLEINFO_ORDER) {
                 $res['order'][$res[$i]['name']] = $i;
@@ -805,7 +848,10 @@
             $tableName = $table;
 
             // get unique and primary keys
-            $res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC);
+            $res = $this->getAll("EXEC SP_HELPINDEX $table", DB_FETCHMODE_ASSOC);
+            if (DB::isError($res)) {
+                return $res;
+            }
 
             foreach ($res as $val) {
                 $keys = explode(', ', $val['index_keys']);
@@ -828,7 +874,10 @@
             }
 
             // get auto_increment, not_null and timestamp
-            $res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC);
+            $res = $this->getAll("EXEC SP_COLUMNS $table", DB_FETCHMODE_ASSOC);
+            if (DB::isError($res)) {
+                return $res;
+            }
 
             foreach ($res as $val) {
                 $val = array_change_key_case($val, CASE_LOWER);
diff --git a/program/lib/DB/mysql.php b/program/lib/DB/mysql.php
index 5b737b6..91572e1 100644
--- a/program/lib/DB/mysql.php
+++ b/program/lib/DB/mysql.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -39,9 +39,9 @@
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_mysql extends DB_common
@@ -111,6 +111,9 @@
         1146 => DB_ERROR_NOSUCHTABLE,
         1216 => DB_ERROR_CONSTRAINT,
         1217 => DB_ERROR_CONSTRAINT,
+        1356 => DB_ERROR_DIVZERO,
+        1451 => DB_ERROR_CONSTRAINT,
+        1452 => DB_ERROR_CONSTRAINT,
     );
 
     /**
@@ -236,10 +239,10 @@
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
         } else {
-            ini_set('track_errors', 1);
+            @ini_set('track_errors', 1);
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
-            ini_set('track_errors', $ini);
+            @ini_set('track_errors', $ini);
         }
 
         if (!$this->connection) {
@@ -297,7 +300,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $query = $this->modifyQuery($query);
         if ($this->_db) {
@@ -419,7 +422,7 @@
      */
     function freeResult($result)
     {
-        return @mysql_free_result($result);
+        return is_resource($result) ? mysql_free_result($result) : false;
     }
 
     // }}}
@@ -555,7 +558,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             return @mysql_affected_rows($this->connection);
         } else {
             return 0;
@@ -752,9 +755,10 @@
 
     /**
      * Quotes a string so it can be safely used as a table or column name
+     * (WARNING: using names that require this is a REALLY BAD IDEA)
      *
-     * MySQL can't handle the backtick character (<kbd>`</kbd>) in
-     * table or column names.
+     * WARNING:  Older versions of MySQL can't handle the backtick
+     * character (<kbd>`</kbd>) in table or column names.
      *
      * @param string $str  identifier name to be quoted
      *
@@ -765,7 +769,7 @@
      */
     function quoteIdentifier($str)
     {
-        return '`' . $str . '`';
+        return '`' . str_replace('`', '``', $str) . '`';
     }
 
     // }}}
@@ -852,7 +856,7 @@
      */
     function modifyLimitQuery($query, $from, $count, $params = array())
     {
-        if (DB::isManip($query)) {
+        if (DB::isManip($query) || $this->_next_query_manip) {
             return $query . " LIMIT $count";
         } else {
             return $query . " LIMIT $from, $count";
@@ -928,12 +932,19 @@
     function tableInfo($result, $mode = null)
     {
         if (is_string($result)) {
+            // Fix for bug #11580.
+            if ($this->_db) {
+                if (!@mysql_select_db($this->_db, $this->connection)) {
+                    return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
+                }
+            }
+            
             /*
              * Probably received a table name.
              * Create a result resource identifier.
              */
-            $id = @mysql_list_fields($this->dsn['database'],
-                                     $result, $this->connection);
+            $id = @mysql_query("SELECT * FROM $result LIMIT 0",
+                               $this->connection);
             $got_string = true;
         } elseif (isset($result->result)) {
             /*
diff --git a/program/lib/DB/mysqli.php b/program/lib/DB/mysqli.php
index bf742e2..6cf9125 100644
--- a/program/lib/DB/mysqli.php
+++ b/program/lib/DB/mysqli.php
@@ -17,7 +17,7 @@
  * @category   Database
  * @package    DB
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -41,9 +41,9 @@
  * @category   Database
  * @package    DB
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  * @since      Class functional since Release 1.6.3
  */
@@ -114,6 +114,9 @@
         1146 => DB_ERROR_NOSUCHTABLE,
         1216 => DB_ERROR_CONSTRAINT,
         1217 => DB_ERROR_CONSTRAINT,
+        1356 => DB_ERROR_DIVZERO,
+        1451 => DB_ERROR_CONSTRAINT,
+        1452 => DB_ERROR_CONSTRAINT,
     );
 
     /**
@@ -210,6 +213,10 @@
         MYSQLI_TYPE_VAR_STRING  => 'varchar',
         MYSQLI_TYPE_STRING      => 'char',
         MYSQLI_TYPE_GEOMETRY    => 'geometry',
+        /* These constants are conditionally compiled in ext/mysqli, so we'll
+         * define them by number rather than constant. */
+        16                      => 'bit',
+        246                     => 'decimal',
     );
 
 
@@ -264,7 +271,7 @@
      *     'ssl' => true,
      * );
      * 
-     * $db =& DB::connect($dsn, $options);
+     * $db = DB::connect($dsn, $options);
      * if (PEAR::isError($db)) {
      *     die($db->getMessage());
      * }
@@ -287,10 +294,10 @@
         }
 
         $ini = ini_get('track_errors');
-        ini_set('track_errors', 1);
+        @ini_set('track_errors', 1);
         $php_errormsg = '';
 
-        if ($this->getOption('ssl') === true) {
+        if (((int) $this->getOption('ssl')) === 1) {
             $init = mysqli_init();
             mysqli_ssl_set(
                 $init,
@@ -322,7 +329,7 @@
             );
         }
 
-        ini_set('track_errors', $ini);
+        @ini_set('track_errors', $ini);
 
         if (!$this->connection) {
             if (($err = @mysqli_connect_error()) != '') {
@@ -372,7 +379,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $query = $this->modifyQuery($query);
         if ($this->_db) {
@@ -490,7 +497,7 @@
      */
     function freeResult($result)
     {
-        return @mysqli_free_result($result);
+        return is_resource($result) ? mysqli_free_result($result) : false;
     }
 
     // }}}
@@ -626,7 +633,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             return @mysqli_affected_rows($this->connection);
         } else {
             return 0;
@@ -823,9 +830,10 @@
 
     /**
      * Quotes a string so it can be safely used as a table or column name
+     * (WARNING: using names that require this is a REALLY BAD IDEA)
      *
-     * MySQL can't handle the backtick character (<kbd>`</kbd>) in
-     * table or column names.
+     * WARNING:  Older versions of MySQL can't handle the backtick
+     * character (<kbd>`</kbd>) in table or column names.
      *
      * @param string $str  identifier name to be quoted
      *
@@ -836,7 +844,7 @@
      */
     function quoteIdentifier($str)
     {
-        return '`' . $str . '`';
+        return '`' . str_replace('`', '``', $str) . '`';
     }
 
     // }}}
@@ -878,7 +886,7 @@
      */
     function modifyLimitQuery($query, $from, $count, $params = array())
     {
-        if (DB::isManip($query)) {
+        if (DB::isManip($query) || $this->_next_query_manip) {
             return $query . " LIMIT $count";
         } else {
             return $query . " LIMIT $from, $count";
@@ -954,6 +962,13 @@
     function tableInfo($result, $mode = null)
     {
         if (is_string($result)) {
+            // Fix for bug #11580.
+            if ($this->_db) {
+                if (!@mysqli_select_db($this->connection, $this->_db)) {
+                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
+                }
+            }
+
             /*
              * Probably received a table name.
              * Create a result resource identifier.
@@ -1015,7 +1030,8 @@
                 'type'  => isset($this->mysqli_types[$tmp->type])
                                     ? $this->mysqli_types[$tmp->type]
                                     : 'unknown',
-                'len'   => $tmp->max_length,
+                // http://bugs.php.net/?id=36579
+                'len'   => $tmp->length,
                 'flags' => $flags,
             );
 
diff --git a/program/lib/DB/oci8.php b/program/lib/DB/oci8.php
index c610a04..f2f8e3d 100644
--- a/program/lib/DB/oci8.php
+++ b/program/lib/DB/oci8.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     James L. Pine <jlp@valinux.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -45,9 +45,9 @@
  * @package    DB
  * @author     James L. Pine <jlp@valinux.com>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_oci8 extends DB_common
@@ -94,24 +94,25 @@
      * @var array
      */
     var $errorcode_map = array(
-        1    => DB_ERROR_CONSTRAINT,
-        900  => DB_ERROR_SYNTAX,
-        904  => DB_ERROR_NOSUCHFIELD,
-        913  => DB_ERROR_VALUE_COUNT_ON_ROW,
-        921  => DB_ERROR_SYNTAX,
-        923  => DB_ERROR_SYNTAX,
-        942  => DB_ERROR_NOSUCHTABLE,
-        955  => DB_ERROR_ALREADY_EXISTS,
-        1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
-        1401 => DB_ERROR_INVALID,
-        1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
-        1418 => DB_ERROR_NOT_FOUND,
-        1476 => DB_ERROR_DIVZERO,
-        1722 => DB_ERROR_INVALID_NUMBER,
-        2289 => DB_ERROR_NOSUCHTABLE,
-        2291 => DB_ERROR_CONSTRAINT,
-        2292 => DB_ERROR_CONSTRAINT,
-        2449 => DB_ERROR_CONSTRAINT,
+        1     => DB_ERROR_CONSTRAINT,
+        900   => DB_ERROR_SYNTAX,
+        904   => DB_ERROR_NOSUCHFIELD,
+        913   => DB_ERROR_VALUE_COUNT_ON_ROW,
+        921   => DB_ERROR_SYNTAX,
+        923   => DB_ERROR_SYNTAX,
+        942   => DB_ERROR_NOSUCHTABLE,
+        955   => DB_ERROR_ALREADY_EXISTS,
+        1400  => DB_ERROR_CONSTRAINT_NOT_NULL,
+        1401  => DB_ERROR_INVALID,
+        1407  => DB_ERROR_CONSTRAINT_NOT_NULL,
+        1418  => DB_ERROR_NOT_FOUND,
+        1476  => DB_ERROR_DIVZERO,
+        1722  => DB_ERROR_INVALID_NUMBER,
+        2289  => DB_ERROR_NOSUCHTABLE,
+        2291  => DB_ERROR_CONSTRAINT,
+        2292  => DB_ERROR_CONSTRAINT,
+        2449  => DB_ERROR_CONSTRAINT,
+        12899 => DB_ERROR_INVALID,
     );
 
     /**
@@ -159,6 +160,13 @@
      * @access private
      */
     var $manip_query = array();
+
+    /**
+     * Store of prepared SQL queries.
+     * @var array
+     * @access private
+     */
+    var $_prepared_queries = array();
 
 
     // }}}
@@ -216,6 +224,13 @@
             $this->dbsyntax = $dsn['dbsyntax'];
         }
 
+        // Backwards compatibility with DB < 1.7.0
+        if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
+            $db = $dsn['hostspec'];
+        } else {
+            $db = $dsn['database'];
+        }
+
         if (function_exists('oci_connect')) {
             if (isset($dsn['new_link'])
                 && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
@@ -225,12 +240,8 @@
                 $connect_function = $persistent ? 'oci_pconnect'
                                     : 'oci_connect';
             }
-
-            // Backwards compatibility with DB < 1.7.0
-            if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
-                $db = $dsn['hostspec'];
-            } else {
-                $db = $dsn['database'];
+            if (isset($this->dsn['port']) && $this->dsn['port']) {
+                $db = '//'.$db.':'.$this->dsn['port'];
             }
 
             $char = empty($dsn['charset']) ? null : $dsn['charset'];
@@ -248,10 +259,10 @@
             }
         } else {
             $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
-            if ($dsn['hostspec']) {
+            if ($db) {
                 $this->connection = @$connect_function($dsn['username'],
                                                        $dsn['password'],
-                                                       $dsn['hostspec']);
+                                                       $db);
             } elseif ($dsn['username'] || $dsn['password']) {
                 $this->connection = @$connect_function($dsn['username'],
                                                        $dsn['password']);
@@ -322,7 +333,7 @@
             return $this->oci8RaiseError($result);
         }
         $this->last_stmt = $result;
-        if (DB::isManip($query)) {
+        if ($this->_checkManip($query)) {
             return DB_OK;
         } else {
             @ocisetprefetch($result, $this->options['result_buffering']);
@@ -415,7 +426,7 @@
      */
     function freeResult($result)
     {
-        return @OCIFreeStatement($result);
+        return is_resource($result) ? OCIFreeStatement($result) : false;
     }
 
     /**
@@ -476,20 +487,18 @@
             $save_query = $this->last_query;
             $save_stmt = $this->last_stmt;
 
-            if (count($this->_data)) {
-                $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
-                $count = $this->execute($smt, $this->_data);
-            } else {
-                $count =& $this->query($countquery);
-            }
+            $count = $this->query($countquery);
 
+            // Restore the last query and statement.
+            $this->last_query = $save_query;
+            $this->last_stmt = $save_stmt;
+            
             if (DB::isError($count) ||
                 DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
             {
-                $this->last_query = $save_query;
-                $this->last_stmt = $save_stmt;
                 return $this->raiseError(DB_ERROR_NOT_CAPABLE);
             }
+
             return $row[0];
         }
         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
@@ -590,6 +599,7 @@
         }
         $this->prepare_types[(int)$stmt] = $types;
         $this->manip_query[(int)$stmt] = DB::isManip($query);
+        $this->_prepared_queries[(int)$stmt] = $newquery;
         return $stmt;
     }
 
@@ -620,11 +630,12 @@
     {
         $data = (array)$data;
         $this->last_parameters = $data;
+        $this->last_query = $this->_prepared_queries[(int)$stmt];
         $this->_data = $data;
 
-        $types =& $this->prepare_types[(int)$stmt];
+        $types = $this->prepare_types[(int)$stmt];
         if (count($types) != count($data)) {
-            $tmp =& $this->raiseError(DB_ERROR_MISMATCH);
+            $tmp = $this->raiseError(DB_ERROR_MISMATCH);
             return $tmp;
         }
 
@@ -643,16 +654,23 @@
             } elseif ($types[$i] == DB_PARAM_OPAQUE) {
                 $fp = @fopen($data[$key], 'rb');
                 if (!$fp) {
-                    $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
+                    $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
                     return $tmp;
                 }
                 $data[$key] = fread($fp, filesize($data[$key]));
                 fclose($fp);
+            } elseif ($types[$i] == DB_PARAM_SCALAR) {
+                // Floats have to be converted to a locale-neutral
+                // representation.
+                if (is_float($data[$key])) {
+                    $data[$key] = $this->quoteFloat($data[$key]);
+                }
             }
             if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
                 $tmp = $this->oci8RaiseError($stmt);
                 return $tmp;
             }
+            $this->last_query = str_replace(':bind'.$i, $this->quoteSmart($data[$key]), $this->last_query);
             $i++;
         }
         if ($this->autocommit) {
@@ -665,11 +683,14 @@
             return $tmp;
         }
         $this->last_stmt = $stmt;
-        if ($this->manip_query[(int)$stmt]) {
+        if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
+            $this->_last_query_manip = true;
+            $this->_next_query_manip = false;
             $tmp = DB_OK;
         } else {
+            $this->_last_query_manip = false;
             @ocisetprefetch($stmt, $this->options['result_buffering']);
-            $tmp =& new DB_result($this, $stmt);
+            $tmp = new DB_result($this, $stmt);
         }
         return $tmp;
     }
@@ -797,7 +818,7 @@
         if (count($params)) {
             $result = $this->prepare("SELECT * FROM ($query) "
                                      . 'WHERE NULL = NULL');
-            $tmp =& $this->execute($result, $params);
+            $tmp = $this->execute($result, $params);
         } else {
             $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
 
@@ -857,7 +878,7 @@
         $repeat = 0;
         do {
             $this->expectError(DB_ERROR_NOSUCHTABLE);
-            $result =& $this->query("SELECT ${seqname}.nextval FROM dual");
+            $result = $this->query("SELECT ${seqname}.nextval FROM dual");
             $this->popExpect();
             if ($ondemand && DB::isError($result) &&
                 $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@@ -1015,7 +1036,7 @@
             if (!@OCIExecute($stmt, OCI_DEFAULT)) {
                 return $this->oci8RaiseError($stmt);
             }
-
+            
             $i = 0;
             while (@OCIFetch($stmt)) {
                 $res[$i] = array(
@@ -1098,12 +1119,30 @@
                 return 'SELECT table_name FROM user_tables';
             case 'synonyms':
                 return 'SELECT synonym_name FROM user_synonyms';
+            case 'views':
+                return 'SELECT view_name FROM user_views';
             default:
                 return null;
         }
     }
 
     // }}}
+    // {{{ quoteFloat()
+
+    /**
+     * Formats a float value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param float the float value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteFloat($float) {
+        return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
+    }
+     
+    // }}}
 
 }
 
diff --git a/program/lib/DB/odbc.php b/program/lib/DB/odbc.php
index c920d7a..350ec85 100644
--- a/program/lib/DB/odbc.php
+++ b/program/lib/DB/odbc.php
@@ -18,7 +18,7 @@
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -42,9 +42,9 @@
  * @package    DB
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_odbc extends DB_common
@@ -266,7 +266,7 @@
         }
         // Determine which queries that should return data, and which
         // should return an error code only.
-        if (DB::isManip($query)) {
+        if ($this->_checkManip($query)) {
             $this->affected = $result; // For affectedRows()
             return DB_OK;
         }
@@ -367,7 +367,7 @@
      */
     function freeResult($result)
     {
-        return @odbc_free_result($result);
+        return is_resource($result) ? odbc_free_result($result) : false;
     }
 
     // }}}
diff --git a/program/lib/DB/pgsql.php b/program/lib/DB/pgsql.php
index ae229af..fc3762a 100644
--- a/program/lib/DB/pgsql.php
+++ b/program/lib/DB/pgsql.php
@@ -19,7 +19,7 @@
  * @author     Rui Hirokawa <hirokawa@php.net>
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -41,9 +41,9 @@
  * @author     Rui Hirokawa <hirokawa@php.net>
  * @author     Stig Bakken <ssb@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_pgsql extends DB_common
@@ -193,7 +193,7 @@
      *     'portability' => DB_PORTABILITY_ALL,
      * );
      * 
-     * $db =& DB::connect($dsn, $options);
+     * $db = DB::connect($dsn, $options);
      * if (PEAR::isError($db)) {
      *     die($db->getMessage());
      * }
@@ -277,10 +277,10 @@
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
         } else {
-            ini_set('track_errors', 1);
+            @ini_set('track_errors', 1);
             $this->connection = @call_user_func_array($connect_function,
                                                       $params);
-            ini_set('track_errors', $ini);
+            @ini_set('track_errors', $ini);
         }
 
         if (!$this->connection) {
@@ -320,7 +320,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $query = $this->modifyQuery($query);
         if (!$this->autocommit && $ismanip) {
@@ -336,19 +336,26 @@
         if (!$result) {
             return $this->pgsqlRaiseError();
         }
-        // Determine which queries that should return data, and which
-        // should return an error code only.
+
+        /*
+         * Determine whether queries produce affected rows, result or nothing.
+         *
+         * This logic was introduced in version 1.1 of the file by ssb,
+         * though the regex has been modified slightly since then.
+         *
+         * PostgreSQL commands:
+         * ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
+         * CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
+         * GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
+         * REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
+         * UNLISTEN, UPDATE, VACUUM
+         */
         if ($ismanip) {
             $this->affected = @pg_affected_rows($result);
             return DB_OK;
-        } elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) {
-            /* PostgreSQL commands:
-               ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
-               CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
-               GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
-               REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
-               UNLISTEN, UPDATE, VACUUM
-            */
+        } elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW)\s/si',
+                             $query))
+        {
             $this->row[(int)$result] = 0; // reset the row counter.
             $numrows = $this->numRows($result);
             if (is_object($numrows)) {
@@ -471,38 +478,21 @@
     }
 
     // }}}
-    // {{{ quoteSmart()
+    // {{{ quoteBoolean()
 
     /**
-     * Formats input so it can be safely used in a query
+     * Formats a boolean value for use within a query in a locale-independent
+     * manner.
      *
-     * @param mixed $in  the data to be formatted
-     *
-     * @return mixed  the formatted data.  The format depends on the input's
-     *                 PHP type:
-     *                 + null = the string <samp>NULL</samp>
-     *                 + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
-     *                 + integer or double = the unquoted number
-     *                 + other (including strings and numeric strings) =
-     *                   the data escaped according to MySQL's settings
-     *                   then encapsulated between single quotes
-     *
+     * @param boolean the boolean value to be quoted.
+     * @return string the quoted string.
      * @see DB_common::quoteSmart()
-     * @since Method available since Release 1.6.0
+     * @since Method available since release 1.7.8.
      */
-    function quoteSmart($in)
-    {
-        if (is_int($in) || is_double($in)) {
-            return $in;
-        } elseif (is_bool($in)) {
-            return $in ? 'TRUE' : 'FALSE';
-        } elseif (is_null($in)) {
-            return 'NULL';
-        } else {
-            return "'" . $this->escapeSimple($in) . "'";
-        }
+    function quoteBoolean($boolean) {
+        return $boolean ? 'TRUE' : 'FALSE';
     }
-
+     
     // }}}
     // {{{ escapeSimple()
 
@@ -511,9 +501,6 @@
      *
      * {@internal PostgreSQL treats a backslash as an escape character,
      * so they are escaped as well.
-     *
-     * Not using pg_escape_string() yet because it requires PostgreSQL
-     * to be at version 7.2 or greater.}}
      *
      * @param string $str  the string to be escaped
      *
@@ -524,7 +511,21 @@
      */
     function escapeSimple($str)
     {
-        return str_replace("'", "''", str_replace('\\', '\\\\', $str));
+        if (function_exists('pg_escape_string')) {
+            /* This fixes an undocumented BC break in PHP 5.2.0 which changed
+             * the prototype of pg_escape_string. I'm not thrilled about having
+             * to sniff the PHP version, quite frankly, but it's the only way
+             * to deal with the problem. Revision 1.331.2.13.2.10 on
+             * php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the
+             * record. */
+            if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
+                return pg_escape_string($this->connection, $str);
+            } else {
+                return pg_escape_string($str);
+            }
+        } else {
+            return str_replace("'", "''", str_replace('\\', '\\\\', $str));
+        }
     }
 
     // }}}
@@ -675,7 +676,7 @@
         $repeat = false;
         do {
             $this->pushErrorHandling(PEAR_ERROR_RETURN);
-            $result =& $this->query("SELECT NEXTVAL('${seqname}')");
+            $result = $this->query("SELECT NEXTVAL('${seqname}')");
             $this->popErrorHandling();
             if ($ondemand && DB::isError($result) &&
                 $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@@ -779,6 +780,10 @@
     function pgsqlRaiseError($errno = null)
     {
         $native = $this->errorNative();
+        if (!$native) {
+            $native = 'Database connection has been lost.';
+            $errno = DB_ERROR_CONNECT_FAILED;
+        }
         if ($errno === null) {
             $errno = $this->errorCode($native);
         }
@@ -815,12 +820,12 @@
         static $error_regexps;
         if (!isset($error_regexps)) {
             $error_regexps = array(
+                '/column .* (of relation .*)?does not exist/i'
+                    => DB_ERROR_NOSUCHFIELD,
                 '/(relation|sequence|table).*does not exist|class .* not found/i'
                     => DB_ERROR_NOSUCHTABLE,
                 '/index .* does not exist/'
                     => DB_ERROR_NOT_FOUND,
-                '/column .* does not exist/i'
-                    => DB_ERROR_NOSUCHFIELD,
                 '/relation .* already exists/i'
                     => DB_ERROR_ALREADY_EXISTS,
                 '/(divide|division) by zero$/i'
@@ -976,22 +981,33 @@
     {
         $field_name = @pg_fieldname($resource, $num_field);
 
+        // Check if there's a schema in $table_name and update things
+        // accordingly.
+        $from = 'pg_attribute f, pg_class tab, pg_type typ';
+        if (strpos($table_name, '.') !== false) {
+            $from .= ', pg_namespace nsp';
+            list($schema, $table) = explode('.', $table_name);
+            $tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'";
+        } else {
+            $tableWhere = "tab.relname = '$table_name'";
+        }
+
         $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
-                                FROM pg_attribute f, pg_class tab, pg_type typ
+                                FROM $from
                                 WHERE tab.relname = typ.typname
                                 AND typ.typrelid = f.attrelid
                                 AND f.attname = '$field_name'
-                                AND tab.relname = '$table_name'");
+                                AND $tableWhere");
         if (@pg_numrows($result) > 0) {
             $row = @pg_fetch_row($result, 0);
             $flags  = ($row[0] == 't') ? 'not_null ' : '';
 
             if ($row[1] == 't') {
                 $result = @pg_exec($this->connection, "SELECT a.adsrc
-                                    FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
+                                    FROM $from, pg_attrdef a
                                     WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
                                     AND f.attrelid = a.adrelid AND f.attname = '$field_name'
-                                    AND tab.relname = '$table_name' AND f.attnum = a.adnum");
+                                    AND $tableWhere AND f.attnum = a.adnum");
                 $row = @pg_fetch_row($result, 0);
                 $num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]);
                 $flags .= 'default_' . rawurlencode($num) . ' ';
@@ -1000,12 +1016,12 @@
             $flags = '';
         }
         $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
-                                FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
+                                FROM $from, pg_index i
                                 WHERE tab.relname = typ.typname
                                 AND typ.typrelid = f.attrelid
                                 AND f.attrelid = i.indrelid
                                 AND f.attname = '$field_name'
-                                AND tab.relname = '$table_name'");
+                                AND $tableWhere");
         $count = @pg_numrows($result);
 
         for ($i = 0; $i < $count ; $i++) {
@@ -1066,6 +1082,9 @@
                         . ' FROM pg_catalog.pg_tables'
                         . ' WHERE schemaname NOT IN'
                         . " ('pg_catalog', 'information_schema', 'pg_toast')";
+            case 'schema.views':
+                return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname"
+                        . " NOT IN ('information_schema', 'pg_catalog')";
             case 'views':
                 // Table cols: viewname | viewowner | definition
                 return 'SELECT viewname from pg_views WHERE schemaname'
diff --git a/program/lib/DB/sqlite.php b/program/lib/DB/sqlite.php
index 42f599e..63fd68b 100644
--- a/program/lib/DB/sqlite.php
+++ b/program/lib/DB/sqlite.php
@@ -19,7 +19,7 @@
  * @author     Urs Gehrig <urs@circle.ch>
  * @author     Mika Tuupola <tuupola@appelsiini.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -45,9 +45,9 @@
  * @author     Urs Gehrig <urs@circle.ch>
  * @author     Mika Tuupola <tuupola@appelsiini.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_sqlite extends DB_common
@@ -182,7 +182,7 @@
      *     'portability' => DB_PORTABILITY_ALL,
      * );
      * 
-     * $db =& DB::connect($dsn, $options);
+     * $db = DB::connect($dsn, $options);
      * if (PEAR::isError($db)) {
      *     die($db->getMessage());
      * }
@@ -204,7 +204,11 @@
             $this->dbsyntax = $dsn['dbsyntax'];
         }
 
-        if ($dsn['database']) {
+        if (!$dsn['database']) {
+            return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
+        }
+
+        if ($dsn['database'] !== ':memory:') {
             if (!file_exists($dsn['database'])) {
                 if (!touch($dsn['database'])) {
                     return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
@@ -229,14 +233,12 @@
             if (!is_readable($dsn['database'])) {
                 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
             }
-        } else {
-            return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
         }
 
         $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
 
         // track_errors must remain on for simpleQuery()
-        ini_set('track_errors', 1);
+        @ini_set('track_errors', 1);
         $php_errormsg = '';
 
         if (!$this->connection = @$connect_function($dsn['database'])) {
@@ -280,7 +282,7 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
         $query = $this->modifyQuery($query);
 
@@ -356,6 +358,16 @@
             $arr = @sqlite_fetch_array($result, SQLITE_ASSOC);
             if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
                 $arr = array_change_key_case($arr, CASE_LOWER);
+            }
+
+            /* Remove extraneous " characters from the fields in the result.
+             * Fixes bug #11716. */
+            if (is_array($arr) && count($arr) > 0) {
+                $strippedArr = array();
+                foreach ($arr as $field => $value) {
+                    $strippedArr[trim($field, '"')] = $value;
+                }
+                $arr = $strippedArr;
             }
         } else {
             $arr = @sqlite_fetch_array($result, SQLITE_NUM);
@@ -727,6 +739,11 @@
     function errorCode($errormsg)
     {
         static $error_regexps;
+        
+        // PHP 5.2+ prepends the function name to $php_errormsg, so we need
+        // this hack to work around it, per bug #9599.
+        $errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg);
+        
         if (!isset($error_regexps)) {
             $error_regexps = array(
                 '/^no such table:/' => DB_ERROR_NOSUCHTABLE,
diff --git a/program/lib/DB/storage.php b/program/lib/DB/storage.php
index 17bffd1..67318a9 100644
--- a/program/lib/DB/storage.php
+++ b/program/lib/DB/storage.php
@@ -16,7 +16,7 @@
  * @category   Database
  * @package    DB
  * @author     Stig Bakken <stig@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -36,9 +36,9 @@
  * @category   Database
  * @package    DB
  * @author     Stig Bakken <stig@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_storage extends PEAR
@@ -293,7 +293,7 @@
     function &create($table, &$data)
     {
         $classname = strtolower(get_class($this));
-        $obj =& new $classname($table);
+        $obj = new $classname($table);
         foreach ($data as $name => $value) {
             $obj->_properties[$name] = true;
             $obj->$name = &$value;
@@ -445,6 +445,8 @@
      */
     function store()
     {
+        $params = array();
+        $vars = array();
         foreach ($this->_changes as $name => $foo) {
             $params[] = &$this->$name;
             $vars[] = $name . ' = ?';
diff --git a/program/lib/DB/sybase.php b/program/lib/DB/sybase.php
index 8931782..3172701 100644
--- a/program/lib/DB/sybase.php
+++ b/program/lib/DB/sybase.php
@@ -19,7 +19,7 @@
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Ant�nio Carlos Ven�ncio J�nior <floripa@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  * @version    CVS: $Id$
  * @link       http://pear.php.net/package/DB
@@ -44,9 +44,9 @@
  * @author     Sterling Hughes <sterling@php.net>
  * @author     Ant�nio Carlos Ven�ncio J�nior <floripa@php.net>
  * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1997-2005 The PHP Group
+ * @copyright  1997-2007 The PHP Group
  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
- * @version    Release: @package_version@
+ * @version    Release: 1.7.13
  * @link       http://pear.php.net/package/DB
  */
 class DB_sybase extends DB_common
@@ -248,9 +248,9 @@
      */
     function simpleQuery($query)
     {
-        $ismanip = DB::isManip($query);
+        $ismanip = $this->_checkManip($query);
         $this->last_query = $query;
-        if (!@sybase_select_db($this->_db, $this->connection)) {
+        if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
             return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
         }
         $query = $this->modifyQuery($query);
@@ -370,7 +370,7 @@
      */
     function freeResult($result)
     {
-        return @sybase_free_result($result);
+        return is_resource($result) ? sybase_free_result($result) : false;
     }
 
     // }}}
@@ -435,7 +435,7 @@
      */
     function affectedRows()
     {
-        if (DB::isManip($this->last_query)) {
+        if ($this->_last_query_manip) {
             $result = @sybase_affected_rows($this->connection);
         } else {
             $result = 0;
@@ -462,7 +462,7 @@
     function nextId($seq_name, $ondemand = true)
     {
         $seqname = $this->getSequenceName($seq_name);
-        if (!@sybase_select_db($this->_db, $this->connection)) {
+        if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
             return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
         }
         $repeat = 0;
@@ -479,7 +479,7 @@
                     return $this->raiseError($result);
                 }
             } elseif (!DB::isError($result)) {
-                $result =& $this->query("SELECT @@IDENTITY FROM $seqname");
+                $result = $this->query("SELECT @@IDENTITY FROM $seqname");
                 $repeat = 0;
             } else {
                 $repeat = false;
@@ -529,6 +529,22 @@
     }
 
     // }}}
+    // {{{ quoteFloat()
+
+    /**
+     * Formats a float value for use within a query in a locale-independent
+     * manner.
+     *
+     * @param float the float value to be quoted.
+     * @return string the quoted string.
+     * @see DB_common::quoteSmart()
+     * @since Method available since release 1.7.8.
+     */
+    function quoteFloat($float) {
+        return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
+    }
+     
+    // }}}
     // {{{ autoCommit()
 
     /**
@@ -558,7 +574,7 @@
     function commit()
     {
         if ($this->transaction_opcount > 0) {
-            if (!@sybase_select_db($this->_db, $this->connection)) {
+            if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
             }
             $result = @sybase_query('COMMIT', $this->connection);
@@ -581,7 +597,7 @@
     function rollback()
     {
         if ($this->transaction_opcount > 0) {
-            if (!@sybase_select_db($this->_db, $this->connection)) {
+            if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
             }
             $result = @sybase_query('ROLLBACK', $this->connection);
@@ -642,6 +658,11 @@
     function errorCode($errormsg)
     {
         static $error_regexps;
+        
+        // PHP 5.2+ prepends the function name to $php_errormsg, so we need
+        // this hack to work around it, per bug #9599.
+        $errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg);
+        
         if (!isset($error_regexps)) {
             $error_regexps = array(
                 '/Incorrect syntax near/'
@@ -674,6 +695,8 @@
                     => DB_ERROR_ALREADY_EXISTS,
                 '/^There are fewer columns in the INSERT statement than values specified/i'
                     => DB_ERROR_VALUE_COUNT_ON_ROW,
+                '/Divide by zero/i'
+                    => DB_ERROR_DIVZERO,
             );
         }
 
@@ -714,7 +737,7 @@
              * Probably received a table name.
              * Create a result resource identifier.
              */
-            if (!@sybase_select_db($this->_db, $this->connection)) {
+            if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
             }
             $id = @sybase_query("SELECT * FROM $result WHERE 1=0",
@@ -811,14 +834,24 @@
             $flags = array();
             $tableName = $table;
 
-            // get unique/primary keys
-            $res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC);
+            /* We're running sp_helpindex directly because it doesn't exist in
+             * older versions of ASE -- unfortunately, we can't just use
+             * DB::isError() because the user may be using callback error
+             * handling. */
+            $res = @sybase_query("sp_helpindex $table", $this->connection);
 
-            if (!isset($res[0]['index_description'])) {
+            if ($res === false || $res === true) {
+                // Fake a valid response for BC reasons.
                 return '';
             }
 
-            foreach ($res as $val) {
+            while (($val = sybase_fetch_assoc($res)) !== false) {
+                if (!isset($val['index_keys'])) {
+                    /* No useful information returned. Break and be done with
+                     * it, which preserves the pre-1.7.9 behaviour. */
+                    break;
+                }
+
                 $keys = explode(', ', trim($val['index_keys']));
 
                 if (sizeof($keys) > 1) {
@@ -834,6 +867,8 @@
                 }
             }
 
+            sybase_free_result($res);
+
         }
 
         if (array_key_exists($column, $flags)) {

--
Gitblit v1.9.1