Mulia A Nst avatar Mulia A Nst committed 5f90a62

Integrate Doctrine 1.2.4

Comments (0)

Files changed (332)

application/config/database.php

-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php  
+if (isset($_SERVER['HTTP_USER_AGENT'])) // Check CLI or not
+if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /*
 | -------------------------------------------------------------------
 | DATABASE CONNECTIVITY SETTINGS
 $db['default']['autoinit'] = TRUE;
 $db['default']['stricton'] = FALSE;
 
+/**
+* Doctrine integration
+*/
+$db['default']['cachedir'] = "";
+// Create dsn from the info above
+$db['default']['dsn'] = $db['default']['dbdriver'] .
+                        '://' . $db['default']['username'] .
+                        ':' . $db['default']['password'].
+                        '@' . $db['default']['hostname'] .
+                        '/' . $db['default']['database'].
+                        '' . '?charset=utf-8';
+ 
+// Require Doctrine.php
+require_once(realpath(dirname(__FILE__) . '/../..') . DIRECTORY_SEPARATOR . 'system/database/Doctrine.php');
+ 
+// Set the autoloader
+spl_autoload_register(array('Doctrine', 'autoload'));
+ 
+// Load the Doctrine connection
+Doctrine_Manager::connection($db['default']['dsn'], $db['default']['database']);
+ 
+// Load the models for the autoloader
+Doctrine::loadModels(realpath(dirname(__FILE__) . '/..') . DIRECTORY_SEPARATOR . 'models');
+
 
 /* End of file database.php */
 /* Location: ./application/config/database.php */

application/doctrine.php

+<?php
+require_once('config/database.php');
+ 
+// Configure Doctrine Cli
+// Normally these are arguments to the cli tasks but if they are set here the arguments will be auto-filled
+$config = array('data_fixtures_path'  =>  dirname(__FILE__) . DIRECTORY_SEPARATOR . '/fixtures',
+                'models_path'         =>  dirname(__FILE__) . DIRECTORY_SEPARATOR . '/models',
+                'migrations_path'     =>  dirname(__FILE__) . DIRECTORY_SEPARATOR . '/migrations',
+                'sql_path'            =>  dirname(__FILE__) . DIRECTORY_SEPARATOR . '/sql',
+                'yaml_schema_path'    =>  dirname(__FILE__) . DIRECTORY_SEPARATOR . '/schema',
+                'generate_models_options' => array(
+                        'generateBaseClasses' => true,
+                        'baseClassPrefix' => 'Base_',
+                        'baseClassesDirectory' => 'Base',
+                        'classPrefixFiles' => false,
+                        'classPrefix' => 'Model_',
+                        'phpDocName' => '',
+                        'phpDocEmail' => ''
+                    ));
+ 
+$cli = new Doctrine_Cli($config);
+$cli->run($_SERVER['argv']);

application/migrations/001_Create_accounts.php

+<?php defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Migration_Create_accounts extends	CI_Migration {
+	
+	function up() 
+	{	
+		if ( ! $this->db->table_exists('accounts'))
+		{
+			// Setup Keys
+			$this->dbforge->add_key('id', TRUE);
+			
+			$this->dbforge->add_field(array(
+				'id' => array('type' => 'INT', 'constraint' => 5, 'unsigned' => TRUE, 'auto_increment' => TRUE),
+				'company_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
+				'first_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
+				'last_name' => array('type' => 'VARCHAR', 'constraint' => '200', 'null' => FALSE),
+				'phone' => array('type' => 'TEXT', 'null' => FALSE),
+				'email' => array('type' => 'TEXT', 'null' => FALSE),
+				'address' => array('type' => 'TEXT', 'null' => FALSE),
+				'Last_Update' => array('type' => 'DATETIME', 'null' => FALSE)
+			));
+			
+			$this->dbforge->add_field("Created_At TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP");
+			$this->dbforge->create_table('accounts', TRUE);
+		}
+	}
+
+	function down() 
+	{
+		$this->dbforge->drop_table('accounts');
+	}
+}
Add a comment to this file

application/schema/schema.yml

Empty file added.

system/database/Doctrine.php

+<?php
+/*
+ *  $Id: Doctrine.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+require_once 'Doctrine/Core.php';
+
+/**
+ * This class only exists for backwards compatability. All code was moved to 
+ * Doctrine_Core and this class extends Doctrine_Core
+ *
+ * @package     Doctrine
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+class Doctrine extends Doctrine_Core
+{
+}

system/database/Doctrine/Access.php

+<?php
+/*
+ *  $Id: Access.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Provides array access and property overload interface for Doctrine subclasses
+ *
+ * @package     Doctrine
+ * @subpackage  Access
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ */
+abstract class Doctrine_Access extends Doctrine_Locator_Injectable implements ArrayAccess
+{
+    /**
+     * Set an entire aray to the data
+     *
+     * @param   array $array An array of key => value pairs
+     * @return  Doctrine_Access
+     */
+    public function setArray(array $array)
+    {
+        foreach ($array as $k => $v) {
+            $this->set($k, $v);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set key and value to data
+     *
+     * @see     set, offsetSet
+     * @param   $name
+     * @param   $value
+     * @return  void
+     */
+    public function __set($name, $value)
+    {
+        $this->set($name, $value);
+    }
+
+    /**
+     * Get key from data
+     *
+     * @see     get, offsetGet
+     * @param   mixed $name
+     * @return  mixed
+     */
+    public function __get($name)
+    {
+        return $this->get($name);
+    }
+
+    /**
+     * Check if key exists in data
+     *
+     * @param   string $name
+     * @return  boolean whether or not this object contains $name
+     */
+    public function __isset($name)
+    {
+        return $this->contains($name);
+    }
+
+    /**
+     * Remove key from data
+     *
+     * @param   string $name
+     * @return  void
+     */
+    public function __unset($name)
+    {
+        return $this->remove($name);
+    }
+
+    /**
+     * Check if an offset axists
+     *
+     * @param   mixed $offset
+     * @return  boolean Whether or not this object contains $offset
+     */
+    public function offsetExists($offset)
+    {
+        return $this->contains($offset);
+    }
+
+    /**
+     * An alias of get()
+     *
+     * @see     get, __get
+     * @param   mixed $offset
+     * @return  mixed
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * Sets $offset to $value
+     *
+     * @see     set, __set
+     * @param   mixed $offset
+     * @param   mixed $value
+     * @return  void
+     */
+    public function offsetSet($offset, $value)
+    {
+        if ( ! isset($offset)) {
+            $this->add($value);
+        } else {
+            $this->set($offset, $value);
+        }
+    }
+
+    /**
+     * Unset a given offset
+     *
+     * @see   set, offsetSet, __set
+     * @param mixed $offset
+     */
+    public function offsetUnset($offset)
+    {
+        return $this->remove($offset);
+    }
+
+    /**
+     * Remove the element with the specified offset
+     *
+     * @param mixed $offset The offset to remove
+     * @return boolean True if removed otherwise false
+     */
+    public function remove($offset)
+    {
+        throw new Doctrine_Exception('Remove is not supported for ' . get_class($this));
+    }
+
+    /**
+     * Return the element with the specified offset
+     *
+     * @param mixed $offset     The offset to return
+     * @return mixed
+     */
+    public function get($offset)
+    {
+        throw new Doctrine_Exception('Get is not supported for ' . get_class($this));
+    }
+
+    /**
+     * Set the offset to the value
+     *
+     * @param mixed $offset The offset to set
+     * @param mixed $value The value to set the offset to
+     *
+     */
+    public function set($offset, $value)
+    {
+        throw new Doctrine_Exception('Set is not supported for ' . get_class($this));
+    }
+
+    /**
+     * Check if the specified offset exists 
+     * 
+     * @param mixed $offset The offset to check
+     * @return boolean True if exists otherwise false
+     */
+    public function contains($offset)
+    {
+        throw new Doctrine_Exception('Contains is not supported for ' . get_class($this));
+    }
+
+    /**
+     * Add the value  
+     * 
+     * @param mixed $value The value to add 
+     * @return void
+     */
+    public function add($value)
+    {
+        throw new Doctrine_Exception('Add is not supported for ' . get_class($this));
+    }
+}

system/database/Doctrine/Adapter/Exception.php

+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Doctrine_Adapter exception class
+ *
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ */
+class Doctrine_Adapter_Exception extends Doctrine_Exception
+{ }

system/database/Doctrine/Adapter/Interface.php

+<?php
+/*
+ *  $Id: Interface.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * This adapter interface should be implemented by all custom adapters
+ *
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+interface Doctrine_Adapter_Interface
+{
+    public function prepare($prepareString);
+    public function query($queryString);
+    public function quote($input);
+    public function exec($statement);
+    public function lastInsertId();
+    public function beginTransaction();
+    public function commit();
+    public function rollBack();
+    public function errorCode();
+    public function errorInfo();
+    public function setAttribute($attribute, $value);
+    public function getAttribute($attribute);
+}

system/database/Doctrine/Adapter/Mock.php

+<?php
+/*
+ *  $Id: Mock.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Doctrine mock connection adapter. This class is used for special testing purposes.
+ *
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface, Countable
+{
+    /**
+     * Name of the dbms to mock
+     *
+     * @var string
+     */
+    private $_name;
+
+    /**
+     * Array of queries executed through this instance of the mock adapter
+     *
+     * @var array $queries
+     */
+    private $_queries = array();
+
+    /**
+     * Array of exceptions thrown
+     *
+     * @var array $exceptions
+     */
+    private $_exception = array();
+
+    /**
+     * Bool true/false variable for whether or not the last insert failed
+     *
+     * @var boolean $lastInsertIdFail
+     */
+    private $_lastInsertIdFail = false;
+
+    /**
+     * Doctrine mock adapter constructor
+     *
+     * <code>
+     * $conn = new Doctrine_Adapter_Mock('mysql');
+     * </code>
+     *
+     * @param string $name 
+     * @return void
+     */
+    public function __construct($name = null)
+    {
+        $this->_name = $name;
+    }
+
+    /**
+     * Get the name of the dbms used in this instance of the mock adapter
+     *
+     * @return string $name Name of the dbms
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Pop the last executed query from the array of executed queries and return it
+     *
+     * @return string $sql Last executed sql string
+     */
+    public function pop()
+    {
+        return array_pop($this->_queries);
+    }
+
+    /**
+     * Force an exception in to the array of exceptions
+     *
+     * @param string $name     Name of exception
+     * @param string $message  Message for the exception
+     * @param integer $code    Code of the exception
+     * @return void
+     */
+    public function forceException($name, $message = '', $code = 0)
+    {
+        $this->_exception = array($name, $message, $code);
+    }
+
+    /**
+     * Prepare a query statement
+     *
+     * @param string $query   Query to prepare
+     * @return Doctrine_Adapter_Statement_Mock $mock Mock prepared statement
+     */
+    public function prepare($query)
+    {
+        $mock = new Doctrine_Adapter_Statement_Mock($this, $query);
+        $mock->queryString = $query;
+
+        return $mock;
+    }
+
+    /**
+     * Add query to the stack of executed queries
+     *
+     * @param string $query 
+     * @return void
+     */
+    public function addQuery($query)
+    {
+        $this->_queries[] = $query;
+    }
+
+    /**
+     * Fake the execution of query and add it to the stack of executed queries
+     *
+     * @param string $query 
+     * @return Doctrine_Adapter_Statement_Mock $stmt
+     */
+    public function query($query)
+    {
+        $this->_queries[] = $query;
+
+        $e    = $this->_exception;
+
+        if ( ! empty($e)) {
+            $name = $e[0];
+
+            $this->_exception = array();
+
+            throw new $name($e[1], $e[2]);
+        }
+
+        $stmt = new Doctrine_Adapter_Statement_Mock($this, $query);
+        $stmt->queryString = $query;
+
+        return $stmt;
+    }
+
+    /**
+     * Get all the executed queries
+     *
+     * @return array $queries Array of all executed queries
+     */
+    public function getAll()
+    {
+        return $this->_queries;
+    }
+
+    /**
+     * Quote a value for the dbms
+     *
+     * @param string $input 
+     * @return string $quoted
+     */
+    public function quote($input)
+    {
+        return "'" . addslashes($input) . "'";
+    }
+
+    /**
+     * Execute a raw sql statement
+     *
+     * @param string $statement 
+     * @return void
+     */
+    public function exec($statement)
+    {
+        $this->_queries[] = $statement;
+
+        $e    = $this->_exception;
+
+        if ( ! empty($e)) {
+            $name = $e[0];
+
+            $this->_exception = array();
+
+            throw new $name($e[1], $e[2]);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Force last insert to be failed
+     *
+     * @param boolean $fail
+     * @return void
+     */
+    public function forceLastInsertIdFail($fail = true)
+    {
+        if ($fail) {
+            $this->_lastInsertIdFail = true;
+        } else {
+            $this->_lastInsertIdFail = false;
+        }
+    }
+
+    /**
+     * Get the id of the last inserted record
+     *
+     * @return integer $id
+     */
+    public function lastInsertId()
+    {
+        $this->_queries[] = 'LAST_INSERT_ID()';
+        if ($this->_lastInsertIdFail) {
+            return null;
+        } else {
+            return 1;
+        }
+    }
+
+    /**
+     * Get the number of queries executed
+     *
+     * @return integer $count
+     */
+    public function count()
+    {
+        return count($this->_queries);
+    }
+
+    /**
+     * Begin a transaction
+     *
+     * @return void
+     */
+    public function beginTransaction()
+    {
+        $this->_queries[] = 'BEGIN TRANSACTION';
+    }
+
+    /**
+     * Commit a transaction
+     *
+     * @return void
+     */
+    public function commit()
+    {
+        $this->_queries[] = 'COMMIT';
+    }
+
+    /**
+     * Rollback a transaction
+     *
+     * @return void
+     */
+    public function rollBack()
+    {
+        $this->_queries[] = 'ROLLBACK';
+    }
+
+    public function getAttribute($attribute)
+    {
+        if ($attribute == Doctrine_Core::ATTR_DRIVER_NAME) {
+            return strtolower($this->_name);
+        }
+    }
+
+    public function errorCode()
+    { }
+
+    public function errorInfo()
+    { }
+
+    public function setAttribute($attribute, $value)
+    { }
+
+    public function sqliteCreateFunction()
+    { }
+}

system/database/Doctrine/Adapter/Oracle.php

+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Custom Doctrine connection adapter for oracle
+ *
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      vadik56
+ * @author      Miloslav Kmet <adrive-nospam@hip-hop.sk>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision$
+ */
+
+class Doctrine_Adapter_Oracle implements Doctrine_Adapter_Interface
+{
+    /**
+     *    execution mode
+     */
+    protected $executeMode = OCI_COMMIT_ON_SUCCESS;
+
+    /**
+     * Resource representing connection to database
+     */
+    protected $connection = false;
+
+
+    protected $attributes = array(Doctrine_Core::ATTR_DRIVER_NAME    => "oci8",
+                                  Doctrine_Core::ATTR_ERRMODE        => Doctrine_Core::ERRMODE_SILENT);
+
+    /**
+     * User-provided configuration.
+     *
+     * Basic keys are:
+     *
+     * username => (string) Connect to the database as this username.
+     * password => (string) Password associated with the username.
+     * dbname   => Either the name of the local Oracle instance, or the
+     *             name of the entry in tnsnames.ora to which you want to connect.
+     *
+     * @var array
+     */
+    protected $config = array(
+        'dbname'     => null,
+        'username'   => null,
+        'password'   => null,
+        'charset'    => null,
+        'persistent' => false
+    );
+
+    /**
+     * Doctrine Oracle adapter constructor
+     *
+     * <code>
+     * $conn = new Doctrine_Adapter_Oracle(array('dbname'=>'db','username'=>'usr','password'=>'pass'));
+     * </code>
+     *
+     * or
+     *
+     * <code>
+     * Doctrine_Manager::connection(array('oracle:dbname=SID;charset=NLS_CHARACTERSET;persistent=true','usr', 'pass'),"doctrine_connection_name")
+     * </code>
+     *
+     * @param string $name
+     * @return void
+     */
+    public function __construct($config = array(), $username = null, $password = null)
+    {
+        if (is_string($config))
+        {
+            $config = str_replace("oracle:","",$config);
+            $parts = explode(";", $config);
+            foreach($parts as $part) {
+                $e = explode("=", $part);
+                $key = array_shift($e);
+                $this->config[$key] = implode('=', $e);
+            }
+
+            if ($username) {
+                $this->config['username'] = $username;
+            }
+            if ($password) {
+                $this->config['password'] = $password;
+            }
+        } else {
+            if ( ! isset($config['password']) || ! isset($config['username'])) {
+                throw new Doctrine_Adapter_Exception('config array must have at least a username and a password');
+            }
+
+            $this->config['username'] = $config['username'];
+            $this->config['password'] = $config['password'];
+            $this->config['dbname']   = $config['dbname'];
+
+            if (isset($config['charset'])) { 
+                $this->config['charset']  = $config['charset']; 
+            } 
+ 
+            if (isset($config['persistent'])) { 
+                $this->config['persistent']  = $config['persistent']; 
+            }
+        }
+
+
+        if ($this->config['persistent'] == 'true'){ 
+            $this->connection = @oci_pconnect($this->config['username'], $this->config['password'], 
+                $this->config['dbname'], $this->config['charset']); 
+        } else { 
+            $this->connection = @oci_new_connect($this->config['username'], $this->config['password'], 
+                $this->config['dbname'], $this->config['charset']); 
+        }
+
+        if ($this->connection === false) {
+            throw new Doctrine_Adapter_Exception(sprintf("Unable to Connect to :'%s' as '%s'", $this->config['dbname'], $this->config['username']));
+        }
+    }
+
+    /**
+     * Prepare a query statement
+     *
+     * @param string $query Query to prepare
+     * @return Doctrine_Adapter_Statement_Oracle $stmt prepared statement
+     */
+    public function prepare($query)
+    {
+        $stmt = new Doctrine_Adapter_Statement_Oracle($this, $query, $this->executeMode);
+
+        return $stmt;
+    }
+
+    /**
+     * Execute query and return results as statement object
+     *
+     * @param string $query
+     * @return Doctrine_Adapter_Statement_Oracle $stmt
+     */
+    public function query($query)
+    {
+        $stmt = new Doctrine_Adapter_Statement_Oracle($this, $query, $this->executeMode);
+        $stmt->execute();
+
+        return $stmt;
+    }
+
+    /**
+     * Quote a value for the dbms
+     *
+     * @param string $input
+     * @return string $quoted
+     */
+    public function quote($input)
+    {
+        return "'" . str_replace("'","''",$input) . "'";
+    }
+
+    /**
+     * Execute a raw sql statement
+     *
+     * @param string $statement
+     * @return void
+     */
+    public function exec($statement)
+    {
+        $stmt = new Doctrine_Adapter_Statement_Oracle($this, $statement, $this->executeMode);
+        $stmt->execute();
+        $count = $stmt->rowCount();
+
+        return $count;
+    }
+
+    /**
+     * Get the id of the last inserted record
+     *
+     * @return integer $id
+     */
+    public function lastInsertId()
+    {
+        throw new Doctrine_Adapter_Exception("unsupported");
+    }
+
+    /**
+     * Begin a transaction
+     *
+     * @return boolean
+     */
+    public function beginTransaction()
+    {
+       $this->executeMode = OCI_DEFAULT;
+       return true;
+    }
+
+    /**
+     * Commit a transaction
+     *
+     * @return void
+     */
+    public function commit()
+    {
+        return @oci_commit($this->connection);
+    }
+
+    /**
+     * Rollback a transaction
+     *
+     * @return boolean
+     */
+    public function rollBack()
+    {
+        return @oci_rollback($this->connection);
+    }
+
+    /**
+     * Set connection attribute
+     *
+     * @param integer $attribute
+     * @param mixed $value                  the value of given attribute
+     * @return boolean                      Returns TRUE on success or FALSE on failure.
+     */
+    public function setAttribute($attribute, $value)
+    {
+        switch ($attribute) {
+            case Doctrine_Core::ATTR_DRIVER_NAME:
+                //TODO throw an error since driver name can not be changed
+            case Doctrine_Core::ATTR_ERRMODE:
+            break;
+            case Doctrine_Core::ATTR_CASE:
+                if ($value == Doctrine_Core::CASE_NATURAL) {
+                    break;
+                } else {
+                    throw new Doctrine_Adapter_Exception("Unsupported Option for ATTR_CASE: $value");
+                }
+            default:
+                throw new Doctrine_Adapter_Exception("Unsupported Attribute: $attribute");
+                return false;
+        }
+        $this->attributes[$attribute] = $value;
+        return true;
+    }
+
+    /**
+     * Retrieve a statement attribute
+     *
+     * @param integer $attribute
+     * @see Doctrine_Core::ATTR_* constants
+     * @return mixed                        the attribute value
+     */
+    public function getAttribute($attribute)
+    {
+        return $this->attributes[$attribute];
+    }
+
+    /**
+     * Returns established OCI connection handler
+     *
+     * @return resource OCI connection handler
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+    
+    /**
+     * Returns current user name
+     * 
+     * @return string current user name
+     */
+    public function getUserName()
+    {
+       return $this->config['username']; 
+    }
+
+    public function errorCode()
+    {
+        if (is_resource($this->connection)) {
+            $error = @oci_error($this->connection);
+        } else {
+            $error = @oci_error();
+        }
+        return $error['code'];
+    }
+
+    public function errorInfo()
+    {
+        if (is_resource($this->connection)) {
+            $error = @oci_error($this->connection);
+        } else {
+            $error = @oci_error();
+        }
+        return $error['message'];
+    }
+
+    public function __destruct() 
+    {  
+        if (is_resource($this->connection)) {  
+            @oci_rollback($this->connection);  
+            @oci_close($this->connection);  
+        } 
+    }
+}

system/database/Doctrine/Adapter/Statement.php

+<?php
+/*
+ *  $Id: Statement.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Doctrine_Adapter_Statement
+ *
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+abstract class Doctrine_Adapter_Statement
+{
+    /**
+     * bindValue
+     *
+     * @param string $no 
+     * @param string $value 
+     * @return void
+     */
+    public function bindValue($no, $value)
+    { }
+
+    /**
+     * fetch
+     *
+     * @see Doctrine_Core::FETCH_* constants
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Doctrine_Core::FETCH_* constants,
+     *                                      defaulting to Doctrine_Core::FETCH_BOTH
+     *
+     * @param integer $cursorOrientation    For a PDOStatement object representing a scrollable cursor, 
+     *                                      this value determines which row will be returned to the caller. 
+     *                                      This value must be one of the Doctrine_Core::FETCH_ORI_* constants, defaulting to
+     *                                      Doctrine_Core::FETCH_ORI_NEXT. To request a scrollable cursor for your 
+     *                                      Doctrine_Adapter_Statement_Interface object,
+     *                                      you must set the Doctrine_Core::ATTR_CURSOR attribute to Doctrine_Core::CURSOR_SCROLL when you
+     *                                      prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
+     *
+     * @param integer $cursorOffset         For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for which the
+     *                                      $cursorOrientation parameter is set to Doctrine_Core::FETCH_ORI_ABS, this value specifies
+     *                                      the absolute number of the row in the result set that shall be fetched.
+     *                                      
+     *                                      For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for 
+     *                                      which the $cursorOrientation parameter is set to Doctrine_Core::FETCH_ORI_REL, this value 
+     *                                      specifies the row to fetch relative to the cursor position before 
+     *                                      Doctrine_Adapter_Statement_Interface->fetch() was called.
+     *
+     * @return mixed
+     */
+    public function fetch()
+    { }
+
+    /**
+     * nextRowSet
+     *
+     * @return void
+     */
+    public function nextRowset()
+    { }
+
+    /**
+     * execute()
+     *
+     * @return void
+     */
+    public function execute()
+    { }
+
+    /**
+     * errorCode
+     *
+     * @return void
+     */
+    public function errorCode()
+    { }
+
+    /**
+     * errorInfo
+     *
+     * @return void
+     */
+    public function errorInfo()
+    { }
+
+    /**
+     * rowCount
+     *
+     * @return void
+     */
+    public function rowCount()
+    { }
+
+    /**
+     * setFetchMode
+     *
+     * @param string $mode 
+     * @return void
+     */
+    public function setFetchMode($mode)
+    { }
+
+    /**
+     * columnCount
+     *
+     * @return void
+     */
+    public function columnCount()
+    { }
+}

system/database/Doctrine/Adapter/Statement/Interface.php

+<?php
+/*
+ *  $Id: Interface.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Interface for Doctrine adapter statements
+ *
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+interface Doctrine_Adapter_Statement_Interface
+{
+    /**
+     * Bind a column to a PHP variable
+     *
+     * @param mixed $column         Number of the column (1-indexed) or name of the column in the result set.
+     *                              If using the column name, be aware that the name should match
+     *                              the case of the column, as returned by the driver.
+     * @param string $param         Name of the PHP variable to which the column will be bound.
+     * @param integer $type         Data type of the parameter, specified by the Doctrine_Core::PARAM_* constants.
+     * @return boolean              Returns TRUE on success or FALSE on failure
+     */
+    public function bindColumn($column, $param, $type = null);
+
+    /**
+     * Binds a value to a corresponding named or question mark 
+     * placeholder in the SQL statement that was use to prepare the statement.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $value          The value to bind to the parameter.
+     * @param integer $type         Explicit data type for the parameter using the Doctrine_Core::PARAM_* constants.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function bindValue($param, $value, $type = null);
+
+    /**
+     * Binds a PHP variable to a corresponding named or question mark placeholder in the 
+     * SQL statement that was use to prepare the statement. Unlike Doctrine_Adapter_Statement_Interface->bindValue(),
+     * the variable is bound as a reference and will only be evaluated at the time 
+     * that Doctrine_Adapter_Statement_Interface->execute() is called.
+     *
+     * Most parameters are input parameters, that is, parameters that are 
+     * used in a read-only fashion to build up the query. Some drivers support the invocation 
+     * of stored procedures that return data as output parameters, and some also as input/output
+     * parameters that both send in data and are updated to receive it.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $variable       Name of the PHP variable to bind to the SQL statement parameter.
+     *
+     * @param integer $type         Explicit data type for the parameter using the Doctrine_Core::PARAM_* constants. To return
+     *                              an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
+     *                              Doctrine_Core::PARAM_INPUT_OUTPUT bits for the data_type parameter.
+     *
+     * @param integer $length       Length of the data type. To indicate that a parameter is an OUT parameter
+     *                              from a stored procedure, you must explicitly set the length.
+     * @param mixed $driverOptions
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function bindParam($column, &$variable, $type = null, $length = null, $driverOptions = array());
+
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function closeCursor();
+
+    /** 
+     * Returns the number of columns in the result set 
+     *
+     * @return integer              Returns the number of columns in the result set represented
+     *                              by the Doctrine_Adapter_Statement_Interface object. If there is no result set,
+     *                              this method should return 0.
+     */
+    public function columnCount();
+
+    /**
+     * Fetch the SQLSTATE associated with the last operation on the statement handle 
+     *
+     * @see Doctrine_Adapter_Interface::errorCode()
+     * @return string       error code string
+     */
+    public function errorCode();
+
+    /**
+     * Fetch extended error information associated with the last operation on the statement handle
+     *
+     * @see Doctrine_Adapter_Interface::errorInfo()
+     * @return array        error info array
+     */
+    public function errorInfo();
+
+    /**
+     * Executes a prepared statement
+     *
+     * If the prepared statement included parameter markers, you must either:
+     * call PDOStatement->bindParam() to bind PHP variables to the parameter markers:
+     * bound variables pass their value as input and receive the output value,
+     * if any, of their associated parameter markers or pass an array of input-only
+     * parameter values
+     *
+     *
+     * @param array $params             An array of values with as many elements as there are
+     *                                  bound parameters in the SQL statement being executed.
+     * @return boolean                  Returns TRUE on success or FALSE on failure.
+     */
+    public function execute($params = null);
+
+    /**
+     * fetch
+     *
+     * @see Doctrine_Core::FETCH_* constants
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Doctrine_Core::FETCH_* constants,
+     *                                      defaulting to Doctrine_Core::FETCH_BOTH
+     *
+     * @param integer $cursorOrientation    For a PDOStatement object representing a scrollable cursor, 
+     *                                      this value determines which row will be returned to the caller. 
+     *                                      This value must be one of the Doctrine_Core::FETCH_ORI_* constants, defaulting to
+     *                                      Doctrine_Core::FETCH_ORI_NEXT. To request a scrollable cursor for your 
+     *                                      Doctrine_Adapter_Statement_Interface object,
+     *                                      you must set the Doctrine_Core::ATTR_CURSOR attribute to Doctrine_Core::CURSOR_SCROLL when you
+     *                                      prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
+     *
+     * @param integer $cursorOffset         For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for which the
+     *                                      $cursorOrientation parameter is set to Doctrine_Core::FETCH_ORI_ABS, this value specifies
+     *                                      the absolute number of the row in the result set that shall be fetched.
+     *                                      
+     *                                      For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for 
+     *                                      which the $cursorOrientation parameter is set to Doctrine_Core::FETCH_ORI_REL, this value 
+     *                                      specifies the row to fetch relative to the cursor position before 
+     *                                      Doctrine_Adapter_Statement_Interface->fetch() was called.
+     *
+     * @return mixed
+     */
+    public function fetch($fetchStyle = Doctrine_Core::FETCH_BOTH,
+                          $cursorOrientation = Doctrine_Core::FETCH_ORI_NEXT,
+                          $cursorOffset = null);
+
+    /**
+     * Returns an array containing all of the result set rows
+     *
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Doctrine_Core::FETCH_* constants,
+     *                                      defaulting to Doctrine_Core::FETCH_BOTH
+     *
+     * @param integer $columnIndex          Returns the indicated 0-indexed column when the value of $fetchStyle is
+     *                                      Doctrine_Core::FETCH_COLUMN. Defaults to 0.
+     *
+     * @return array
+     */
+    public function fetchAll($fetchStyle = Doctrine_Core::FETCH_BOTH);
+
+    /**
+     * Returns a single column from the next row of a
+     * result set or FALSE if there are no more rows.
+     *
+     * @param integer $columnIndex          0-indexed number of the column you wish to retrieve from the row. If no 
+     *                                      value is supplied, Doctrine_Adapter_Statement_Interface->fetchColumn() 
+     *                                      fetches the first column.
+     *
+     * @return string                       returns a single column in the next row of a result set.
+     */
+    public function fetchColumn($columnIndex = 0);
+
+    /**
+     * Fetches the next row and returns it as an object.
+     *
+     * Fetches the next row and returns it as an object. This function is an alternative to 
+     * Doctrine_Adapter_Statement_Interface->fetch() with Doctrine_Core::FETCH_CLASS or Doctrine_Core::FETCH_OBJ style.
+     *
+     * @param string $className             Name of the created class, defaults to stdClass. 
+     * @param array $args                   Elements of this array are passed to the constructor.
+     *
+     * @return mixed                        an instance of the required class with property names that correspond 
+     *                                      to the column names or FALSE in case of an error.
+     */
+    public function fetchObject($className = 'stdClass', $args = array());
+
+    /**
+     * Retrieve a statement attribute 
+     *
+     * @param integer $attribute
+     * @see Doctrine_Core::ATTR_* constants
+     * @return mixed                        the attribute value
+     */
+    public function getAttribute($attribute);
+
+    /**
+     * Returns metadata for a column in a result set
+     *
+     * @param integer $column               The 0-indexed column in the result set.
+     *
+     * @return array                        Associative meta data array with the following structure:
+     *
+     *          native_type                 The PHP native type used to represent the column value.
+     *          driver:decl_                type The SQL type used to represent the column value in the database. If the column in the result set is the result of a function, this value is not returned by PDOStatement->getColumnMeta().
+     *          flags                       Any flags set for this column.
+     *          name                        The name of this column as returned by the database.
+     *          len                         The length of this column. Normally -1 for types other than floating point decimals.
+     *          precision                   The numeric precision of this column. Normally 0 for types other than floating point decimals.
+     *          pdo_type                    The type of this column as represented by the PDO::PARAM_* constants.
+     */
+    public function getColumnMeta($column);
+
+    /**
+     * Advances to the next rowset in a multi-rowset statement handle
+     * 
+     * Some database servers support stored procedures that return more than one rowset 
+     * (also known as a result set). The nextRowset() method enables you to access the second 
+     * and subsequent rowsets associated with a PDOStatement object. Each rowset can have a 
+     * different set of columns from the preceding rowset.
+     *
+     * @return boolean                      Returns TRUE on success or FALSE on failure.
+     */
+    public function nextRowset();
+
+    /**
+     * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement 
+     * executed by the corresponding object.
+     *
+     * If the last SQL statement executed by the associated Statement object was a SELECT statement, 
+     * some databases may return the number of rows returned by that statement. However, 
+     * this behaviour is not guaranteed for all databases and should not be 
+     * relied on for portable applications.
+     *
+     * @return integer                      Returns the number of rows.
+     */
+    public function rowCount();
+
+    /**
+     * Set a statement attribute
+     *
+     * @param integer $attribute
+     * @param mixed $value                  the value of given attribute
+     * @return boolean                      Returns TRUE on success or FALSE on failure.
+     */
+    public function setAttribute($attribute, $value);
+
+    /**
+     * Set the default fetch mode for this statement 
+     *
+     * @param integer $mode                 The fetch mode must be one of the Doctrine_Core::FETCH_* constants.
+     * @return boolean                      Returns 1 on success or FALSE on failure.
+     */
+    public function setFetchMode($mode, $arg1 = null, $arg2 = null);
+}

system/database/Doctrine/Adapter/Statement/Mock.php

+<?php
+/*
+ *  $Id: Mock.php 7490 2010-03-29 19:53:27Z jwage $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+/**
+ * Mock connection adapter statement class. Used for special testing purposes
+ *
+ * @package     Doctrine
+ * @subpackage  Adapter
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 7490 $
+ */
+class Doctrine_Adapter_Statement_Mock implements Doctrine_Adapter_Statement_Interface
+{
+    /**
+     * Variable which stores instance of Doctrine_Adapter_Mock
+     *
+     * @var Doctrine_Adapter_Mock
+     */
+    private $_mock;
+
+    /**
+     * queryString
+     *
+     * @var string
+     */
+    public $queryString;
+
+    /**
+     * Constructor for mock adapter statements. Accepts instance of Doctrine_Adapter_Mock
+     *
+     * @param Doctrine_Adapter_Mock $mock
+     */
+    public function __construct($mock)
+    {
+        $this->_mock  = $mock;
+    }
+
+    /**
+     * bindColumn
+     *
+     * Bind a column to a PHP variable
+     *
+     * @param mixed $column         Number of the column (1-indexed) or name of the column in the result set.
+     *                              If using the column name, be aware that the name should match
+     *                              the case of the column, as returned by the driver.
+     * @param string $param         Name of the PHP variable to which the column will be bound.
+     * @param integer $type         Data type of the parameter, specified by the Doctrine_Core::PARAM_* constants.
+     * @return boolean              Returns TRUE on success or FALSE on failure
+     */
+    public function bindColumn($column, $param, $type = null)
+    { }
+
+    /**
+     * bindValue
+     *
+     * Binds a value to a corresponding named or question mark
+     * placeholder in the SQL statement that was use to prepare the statement.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $value          The value to bind to the parameter.
+     * @param integer $type         Explicit data type for the parameter using the Doctrine_Core::PARAM_* constants.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function bindValue($param, $value, $type = null)
+    { }
+
+    /**
+     * bindParam
+     *
+     * Binds a PHP variable to a corresponding named or question mark placeholder in the
+     * SQL statement that was use to prepare the statement. Unlike Doctrine_Adapter_Statement_Interface->bindValue(),
+     * the variable is bound as a reference and will only be evaluated at the time
+     * that Doctrine_Adapter_Statement_Interface->execute() is called.
+     *
+     * Most parameters are input parameters, that is, parameters that are
+     * used in a read-only fashion to build up the query. Some drivers support the invocation
+     * of stored procedures that return data as output parameters, and some also as input/output
+     * parameters that both send in data and are updated to receive it.
+     *
+     * @param mixed $param          Parameter identifier. For a prepared statement using named placeholders,
+     *                              this will be a parameter name of the form :name. For a prepared statement
+     *                              using question mark placeholders, this will be the 1-indexed position of the parameter
+     *
+     * @param mixed $variable       Name of the PHP variable to bind to the SQL statement parameter.
+     *
+     * @param integer $type         Explicit data type for the parameter using the Doctrine_Core::PARAM_* constants. To return
+     *                              an INOUT parameter from a stored procedure, use the bitwise OR operator to set the
+     *                              Doctrine_Core::PARAM_INPUT_OUTPUT bits for the data_type parameter.
+     *
+     * @param integer $length       Length of the data type. To indicate that a parameter is an OUT parameter
+     *                              from a stored procedure, you must explicitly set the length.
+     * @param mixed $driverOptions
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function bindParam($column, &$variable, $type = null, $length = null, $driverOptions = array())