<?php

require_once 'DB.php';

/**
 * PEAR::DB RDO_Storage implementation.
 *
 * $Horde: framework/RDO/RDO/Storage/peardb.php,v 1.6.2.4 2006/01/18 23:26:58 jan Exp $
 *
 * @package RDO
 */
class RDO_Storage_peardb extends RDO_Storage {

    /**
     * Human-readable name for this Storage driver.
     *
     * @var string $name
     */
    public $name = 'PEAR::DB';

    /**
     * PEAR::DB object.
     *
     * @var DB $db
     */
    private $db = null;

    /**
     */
    public function __construct($params)
    {
        parent::__construct($params);
        $this->connect();
    }

    /**
     * Free any resources that are open.
     */
    public function __destruct()
    {
        if ($this->db) {
            $this->db->disconnect();
            unset($this->db);
        }
    }

    /**
     * Use for SELECT and anything that returns rows.
     */
    public function query($sql)
    {
        return $this->db->query($sql);
    }

    /**
     * Use for INSERT, UPDATE, DELETE. Returns number of affected
     * rows.
     */
    public function execute($sql)
    {
        $result = $this->db->query($sql);
        if ($result instanceof DB_Error) {
            throw new RDO_Exception($result);
        }
        return $this->db->numRows();
    }

    public function begin()
    {
    }

    public function commit()
    {
    }

    public function rollback()
    {
    }

    private function connect()
    {
        $this->db = &DB::connect($this->params);
        if ($this->db == DB_NOT_CONNECTED) {
            throw new RDO_Exception($this->db);
        } elseif ($this->db instanceof DB_Error) {
            throw new RDO_Exception($this->db);
        }

        // Set DB portability options.
        switch ($this->db->phptype) {
        case 'mssql':
            $this->db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
            break;
        default:
            $this->db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
        }

    }

}

class RDO_Results_peardb extends RDO_Results {

    /**
     * Implementation of the rewind() method for iterator.
     */
    public function rewind()
    {
        // Rewind only if never queried before or query was
        // successful.
        if (is_null($this->result) ||
            $this->result instanceof DB_Result) {

            if ($this->result) {
                $this->storage->free($this->result);
            }

            $this->result = null;
            $this->current = null;
            $this->index = null;
            $this->eof = true;

            $this->result = $this->db->query($this->query, $this->params);
            if (!($this->result instanceof DB_Result)) {
                throw new RDO_Exception($this->result);
            }
            $this->next();
        }
    }

    /**
     * Implementation of the next() method for iterator.
     *
     * @return mixed The next row, or null if no more rows.
     */
    public function next()
    {
        if (is_null($this->result)) {
            $this->rewind();
        }

        if ($this->result) {
            $this->current = $this->result->fetchRow();

            if (is_null($this->current)) {
                $this->eof = true;
            } else {
                $this->eof = false;

                if (is_null($this->index)) {
                    $this->index = 0;
                } else {
                    ++$this->index;
                }
            }
        }

        return $this->current;
    }

}
