Update version.php to 3.3.0
[isso.git] / Db.php
diff --git a/Db.php b/Db.php
index 549b8a28f10827aaea40e5ab2fb7a3bb6bc8a89e..169893d0d88f8a7b885d7635a638583c8d80ed4f 100644 (file)
--- a/Db.php
+++ b/Db.php
@@ -2,7 +2,7 @@
 /*=====================================================================*\
 || ###################################################################
 || # Blue Static ISSO Framework
-|| # Copyright (c)2002-2007 Blue Static
+|| # Copyright (c)2005-2009 Blue Static
 || #
 || # This program is free software; you can redistribute it and/or modify
 || # it under the terms of the GNU General Public License as published by
 \*=====================================================================*/
 
 /**
-* Abstract Database Layer (Db.php)
-*
-* @package     ISSO
-*/
+ * Abstract Database Layer (Db.php)
+ *
+ * @package    ISSO
+ */
 
 require_once(ISSO . '/Functions.php');
 
 /**
-* Abstract Database Layer
-*
-* This class provides an abstract template for all RDBMS layers. All
-* ISSO abstraction layers should inherit this class. It provides error
-* reporting, SQL analysis, and general connection functionality.
-*
-* Constants:
-             ISSO_SHOW_QUERIES_LIVE - Show queries in page output as they are sent
-*
-* @author              Blue Static
-* @copyright   Copyright (c)2002 - 2007, Blue Static
-* @package             ISSO
-* 
-*/
+ * Abstract Database Layer
+ *
+ * This class provides an abstract template for all RDBMS layers. All
+ * ISSO abstraction layers should inherit this class. It provides error
+ * reporting, SQL analysis, and general connection functionality.
+ *
+ * Constants:
+ *             ISSO_SHOW_QUERIES_LIVE - Show queries in page output as they are sent
+ *
+ * @author             Blue Static
+ * @copyright  Copyright (c)2005 - 2009, Blue Static
+ * @package            ISSO
+ 
+ */
 abstract class BSDb
 {
        /**
-       * Determines whether or not errors should be shown
-       * @var  bool
-       */
+        * Determines whether or not errors should be shown
+        * @var bool
+        */
        public $showerrors = true;
        
        /**
-       * Current error number
-       * @var  integer
-       */
+        * Current error number
+        * @var integer
+        */
        protected $errnum = 0;
        
        /**
-       * Description of current error
-       * @var  string
-       */
+        * Description of current error
+        * @var string
+        */
        protected $errstr = '';
        
        /**
-       * Currend open database connection
-       * @var  integer
-       */
+        * Currend open database connection
+        * @var integer
+        */
        protected $dblink = null;
        
        /**
-       * Current query ID
-       * @var  integer
-       */
+        * Current query ID
+        * @var integer
+        */
        protected $result = null;
        
        /**
-       * Current query string
-       * @var  string
-       */
+        * Current query string
+        * @var string
+        */
        protected $querystr = '';
        
        /**
-       * History of all executed queryies
-       * @var  array
-       */
+        * History of all executed queryies
+        * @var array
+        */
        protected $history = array();
        
-       // ###################################################################
        /**
-       * Returns the history information array
-       *
-       * @return       array   History record
-       */
+        * Returns the history information array
+        *
+        * @return      array   History record
+        */
        public function getHistory()
        {
                return $this->history;
        }
        
-       // ###################################################################
        /**
-       * Connect to a the specified database
-       *
-       * @param        string  Server name
-       * @param        string  User name
-       * @param        string  Password
-       * @param        string  Database name
-       *
-       * @return       bool    Result of connect
-       */
+        * Connect to a the specified database
+        *
+        * @param       string  Server name
+        * @param       string  User name
+        * @param       string  Password
+        * @param       string  Database name
+        *
+        * @return      bool    Result of connect
+        */
        public function connect($server, $user, $password, $database)
        {
                if ($this->dblink == false)
@@ -125,26 +123,25 @@ abstract class BSDb
        }
        
        /**
-       * Abstract function that returns a database link after establishing a connection. This just
-       * calls the function and does not do any checking
-       *
-       * @param        string  Server name
-       * @param        string  User name
-       * @param        string  Password
-       * @param        string  Database name
-       *
-       * @return       integer Database link
-       */
+        * Abstract function that returns a database link after establishing a connection. This just
+        * calls the function and does not do any checking
+        *
+        * @param       string  Server name
+        * @param       string  User name
+        * @param       string  Password
+        * @param       string  Database name
+        *
+        * @return      integer Database link
+        */
        protected abstract function _connect($server, $user, $password, $database);
        
-       // ###################################################################
        /**
-       * Send a query to the open database link
-       *
-       * @param        string  Query string
-       *
-       * @return       BSDbResult      Result object, or NULL
-       */
+        * Send a query to the open database link
+        *
+        * @param       string  Query string
+        *
+        * @return      BSDbResult      Result object, or NULL
+        */
        public function query($string)
        {
                $time = microtime();
@@ -157,7 +154,7 @@ abstract class BSDb
                        throw new BSDbException($this->_errorString(), $this->_errorNumber(), $string);
                }
                
-               $this->history[] = $history = array('query' => $string, 'time' => BSFunctions::FetchMicrotimeDiff($time), 'trace' => BSFunctions::FormatBacktrace(debug_backtrace()));
+               $this->history[] = $history = array('query' => $string, 'time' => BSFunctions::fetch_microtime_diff($time), 'trace' => BSFunctions::format_backtrace(debug_backtrace()));
                
                if (defined('ISSO_SHOW_QUERIES_LIVE'))
                {
@@ -167,7 +164,7 @@ abstract class BSDb
                        }
                }
                
-               if (strtoupper(substr(trim($string), 0, 6)) == 'SELECT')
+               if (preg_match('/^\s*(select|describe|show|explain)/i', $string))
                {
                        $class = get_class($this) . 'Result';
                        return new $class($this->result);
@@ -175,89 +172,85 @@ abstract class BSDb
        }
        
        /**
-       * Abstract function that executes the query command on the database
-       *
-       * @param        string  Query string
-       *
-       * @return       integer Result ID
-       */
+        * Abstract function that executes the query command on the database
+        *
+        * @param       string  Query string
+        *
+        * @return      integer Result ID
+        */
        protected abstract function _query($query);
        
-       // ###################################################################
        /**
-       * Escape a string (depending on character set, if supported)
-       *
-       * @param        string  String to be escaped
-       *
-       * @return       string  Escaped string
-       */
+        * Escape a string (depending on character set, if supported)
+        *
+        * @param       string  String to be escaped
+        *
+        * @return      string  Escaped string
+        */
        public function escapeString($string)
        {
                return $this->_escapeString($string);
        }
        
        /**
-       * Abstract function that calls the escape_string() method
-       *
-       * @param        string  String to escape
-       *
-       * @return       string  Escaped string
-       */
+        * Abstract function that calls the escape_string() method
+        *
+        * @param       string  String to escape
+        *
+        * @return      string  Escaped string
+        */
        protected abstract function _escapeString($string);
        
-       // ###################################################################
        /**
-       * Escapes a binary string for insertion into the database
-       *
-       * @param        string  Unescaped data
-       *
-       * @return       string  Escaped binary data
-       */
+        * Escapes a binary string for insertion into the database
+        *
+        * @param       string  Unescaped data
+        *
+        * @return      string  Escaped binary data
+        */
        public function escapeBinary($binary)
        {
                return $this->_escapeBinary($binary);
        }
        
        /**
-       * Abstract function that calls escape_binary()
-       *
-       * @param        string  Binary to escape
-       *
-       * @return       string  Escaped binary
-       */
+        * Abstract function that calls escape_binary()
+        *
+        * @param       string  Binary to escape
+        *
+        * @return      string  Escaped binary
+        */
        protected abstract function _escapeBinary($string);
        
-       // ###################################################################
        /**
-       * Unescapes a binary string that was fetched from the database
-       *
-       * @param        string  Escaped data
-       *
-       * @return       string  Unescaped binary data
-       */
+        * Unescapes a binary string that was fetched from the database
+        *
+        * @param       string  Escaped data
+        *
+        * @return      string  Unescaped binary data
+        */
        public function unescapeBinary($binary)
        {
                return $this->_unescapeBinary($binary);
        }
        
        /**
-       * Abstract function that calls unescape_binary()
-       *
-       * @param        string  Escaped data
-       *
-       * @return       string  Data that has been unescaped
-       */
+        * Abstract function that calls unescape_binary()
+        *
+        * @param       string  Escaped data
+        *
+        * @return      string  Data that has been unescaped
+        */
        protected abstract function _unescapeBinary($string);
        
-       // ###################################################################
        /**
-       * Send a query and return the first row of the results
-       *
-       * @param        string  Query string
-       * @param        string  Result return function (in the database layer)
-       *
-       * @return       mixed   Results in variable formats
-       */
+        * Send a query and return the first row of the results
+        *
+        * @param       string  Query string
+        * @param       string  Result return function (in the database layer)
+        *
+        * @return      mixed   Results in variable formats
+        */
        public function queryFirst($string, $callback = 'fetchArray')
        {
                $resource = $this->query($string);
@@ -273,79 +266,73 @@ abstract class BSDb
                }
        }
        
-       // ###################################################################
        /**
-       * Returns the errror number
-       */
+        * Returns the errror number
+        */
        public abstract function _errorNumber();
        
        /**
-       * Returns the error string
-       */
+        * Returns the error string
+        */
        public abstract function _errorString();
        
-       // ###################################################################
        /**
-       * Fetch the unique ID of the record just inserted
-       *
-       * @return       integer Insert-ID
-       */
+        * Fetch the unique ID of the record just inserted
+        *
+        * @return      integer Insert-ID
+        */
        public function insertId()
        {
                return $this->_insertID();
        }
        
        /**
-       * Abstract function that returns the ID of the most recently-inserted
-       * record
-       *
-       * @return       integer Insertion ID
-       */
+        * Abstract function that returns the ID of the most recently-inserted
+        * record
+        *
+        * @return      integer Insertion ID
+        */
        protected abstract function _insertId();
        
-       // ###################################################################
        /**
-       * Fetch the number of rows affected by the query
-       *
-       * @param        integer Result
-       *
-       * @return       integer Number of affected rows
-       */
+        * Fetch the number of rows affected by the query
+        *
+        * @param       integer Result
+        *
+        * @return      integer Number of affected rows
+        */
        public function affectedRows()
        {
                return $this->_affectedRows($this->result);
        }
        
        /**
-       * Abstract function that returns the number of affected rows in the result
-       *
-       * @param        integer Result ID
-       *
-       * @return       integer Number of rows
-       */
+        * Abstract function that returns the number of affected rows in the result
+        *
+        * @param       integer Result ID
+        *
+        * @return      integer Number of rows
+        */
        protected abstract function _affectedRows($result);
        
-       // ###################################################################
        /**
-       * Sends the command to start a transaction. This command should never
-       * be reached as it's always overridden
-       */
+        * Sends the command to start a transaction. This command should never
+        * be reached as it's always overridden
+        */
        public abstract function begin();
        
-       // ###################################################################
        /**
-       * Sends the command to rollback to a given savepoint. This command
-       * should never be reached as it's always overridden
-       *
-       * @param        string  Named savepoint
-       */
+        * Sends the command to rollback to a given savepoint. This command
+        * should never be reached as it's always overridden
+        *
+        * @param       string  Named savepoint
+        */
        public abstract function rollback();
        
-       // ###################################################################
        /**
-       * Sends the command to commit the entire transaction. This command
-       * should never be reached as it's always overridden
-       */
+        * Sends the command to commit the entire transaction. This command
+        * should never be reached as it's always overridden
+        */
        public abstract function commit();
 }
 
@@ -355,19 +342,24 @@ abstract class BSDb
  * This class holds result information for a database result
  *
  * @author             rsesek
- * @copyright  Copyright (c)2002 - 2007, Blue Static
+ * @copyright  Copyright (c)2005 - 2009, Blue Static
  * @package            ISSO
  *
  */
-abstract class BSDbResult
+abstract class BSDbResult implements Iterator
 {
        /**
         * The result resource
         * @var resource
         */
-       private $result;
+       protected $result;
+       
+       /**
+        * All the results (as used by the iterator implementation)
+        * @var string
+        */
+       protected $iterator;
        
-       // ###################################################################
        /**
         * Sets the resource and returns a result object
         *
@@ -378,99 +370,169 @@ abstract class BSDbResult
                $this->result = $result;
        }
        
-       // ###################################################################
        /**
-       * Fetch the query result as an array
-       *
-       * @param        integer Result
-       * @param        bool    Return an associative array?
-       *
-       * @return       array   A row of the query result
-       */
+        * Method to call on the result
+        * 
+        * @param       string  Method name
+        *
+        * @return      array   Array of results
+        */
+       public function fetchAll($method = 'fetchArray')
+       {
+               $results = array();
+               while ($result = $this->$method())
+               {
+                       $results[] = $result;
+               }
+               return $results;
+       }
+       
+       /**
+        * Fetch the query result as an array
+        *
+        * @param       integer Result
+        * @param       bool    Return an associative array?
+        *
+        * @return      array   A row of the query result
+        */
        public function fetchArray($assoc = true)
        {
                return $this->{($assoc ? '_fetchAssocArray' : '_fetchRowArray')}($this->result);
        }
        
        /**
-       * Abstract function that returns an associative array of given result
-       *
-       * @param        integer Result
-       *
-       * @return       array   Result array
-       */
+        * Abstract function that returns an associative array of given result
+        *
+        * @param       integer Result
+        *
+        * @return      array   Result array
+        */
        protected abstract function _fetchAssocArray($result);
        
        /**
-       * Abstract function that returns a row array of given result
-       *
-       * @param        integer Result
-       *
-       * @return       array   Result array
-       */
+        * Abstract function that returns a row array of given result
+        *
+        * @param       integer Result
+        *
+        * @return      array   Result array
+        */
        protected abstract function _fetchRowArray($result);
        
-       // ###################################################################
        /**
-       * Fetch the query result as an object
-       *
-       * @param        integer Result
-       *
-       * @return       object  An object with the query result
-       */
+        * Fetch the query result as an object
+        *
+        * @param       integer Result
+        *
+        * @return      object  An object with the query result
+        */
        public function fetchObject()
        {
                return $this->_fetchObject($this->result);
        }
        
        /**
-       * Abstract function that returns an object for a given result
-       *
-       * @param        integer Result
-       *
-       * @return       object  Row object
-       */
+        * Abstract function that returns an object for a given result
+        *
+        * @param       integer Result
+        *
+        * @return      object  Row object
+        */
        public abstract function _fetchObject($result);
        
-       // ###################################################################
        /**
-       * Free the current query result
-       *
-       * @param        integer Result
-       */
+        * Free the current query result
+        *
+        * @param       integer Result
+        */
        public function free()
        {
                $this->_freeResult($this->result);
        }
        
        /**
-       * Abstract function that frees a given result
-       *
-       * @param        integer Result ID
-       */
+        * Abstract function that frees a given result
+        *
+        * @param       integer Result ID
+        */
        protected abstract function _freeResult($result);
        
-       // ###################################################################
        /**
-       * Fetch the number of rows in the result
-       *
-       * @param        integer Result
-       *
-       * @return       integer Number of rows
-       */
+        * Fetch the number of rows in the result
+        *
+        * @param       integer Result
+        *
+        * @return      integer Number of rows
+        */
        public function size()
        {
                return $this->_numRows($this->result);
        }
        
        /**
-       * Abstract function that returns the number of rows in the result
-       *
-       * @param        integer Result ID
-       *
-       * @return       integer Number of rows
-       */
+        * Abstract function that returns the number of rows in the result
+        *
+        * @param       integer Result ID
+        *
+        * @return      integer Number of rows
+        */
        protected abstract function _numRows($result);
+       
+       // ###################################################################
+       // # Iterator implementation
+       // ###################################################################
+       /**
+        * Rewinds the iterator by resetting the result pointer
+        *
+        * @return void
+        */
+       public function rewind()
+       {
+               if ($this->iterator == null)
+               {
+                       $this->iterator = $this->fetchAll();
+               }
+               reset($this->iterator);
+       }
+       
+       /**
+        * Returns the current row
+        *
+        * @return array
+        */
+       public function current()
+       {
+               return current($this->iterator);
+       }
+       
+       /**
+        * Returns the key (result pointer index)
+        *
+        * @return integer
+        */
+       public function key()
+       {
+               return key($this->iterator);
+       }
+       
+       /**
+        * Advances the iterator and returns the row
+        *
+        * @return array
+        */
+       public function next()
+       {
+               return next($this->iterator);
+       }
+       
+       /**
+        * Checks whether the iterator is valid
+        *
+        * @return boolean
+        */
+       public function valid()
+       {
+               return ($this->current() !== false);
+       }
 }
 
 /**
@@ -479,7 +541,7 @@ abstract class BSDbResult
  * Exception handler class for the database classes
  *
  * @author             Blue Static
- * @copyright  Copyright (c)2002 - 2007, Blue Static
+ * @copyright  Copyright (c)2005 - 2009, Blue Static
  * @package            ISSO
  *
  */
@@ -489,9 +551,8 @@ class BSDbException extends Exception
         * The query string that caused the error
         * @var string
         */
-       private $query;
+       protected $query;
        
-       // ###################################################################
        /**
         * Initializes a new database exception
         * 
@@ -505,7 +566,6 @@ class BSDbException extends Exception
                parent::__construct($error, $errorNum);
        }
        
-       // ###################################################################
        /**
         * Returns the query that failed
         *