<?php
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage db
 * @since 2010-02-19
 * @version SVN: $Id$
 * @filesource $URL$
 */

abstract class DbStatement
{

    /**
     * @var DbDriver
     */
    protected $driver;

    /**
     * @var string
     */
    protected $request;

    protected $params = array();

    protected $result;

    public function __construct($driver, $request)
    {
        $this->driver = $driver;
        $this->request = $request;
    }

    /**
     * @param array $params
     * @return bool
     */
    public function execute($params = null)
    {
        if (is_array($params)) {
            foreach ($params as $param => &$value) {
                $this->bindParam($param, $value);
            }
        }
        return $this->driverExecute($this->assemble());
    }

    public function __destruct()
    {
        $this->close();
    }

    /**
     * @param mixed $style
     * @return array
     */
    public function fetchAll($style = Db::FETCH_OBJ)
    {
        $data = array();
        while ($row = $this->fetch($style)) {
            $data[] = $row;
        }
        return $data;
    }

    /**
     * @param string $field
     */
    public function fetchColumn($field)
    {
        $data = array();
        while ($row = $this->fetch(Db::FETCH_ASSOC)) {
            $data[] = $row[$field];
        }
        return $data;
    }

    /**
     * @param string $field
     */
    public function fetchField($field)
    {
        $row = $this->fetch(Db::FETCH_ASSOC);
        if (isset($row[$field])) {
            return $row[$field];
        }
        return false;
    }

    /* Abstract methods */

    abstract public function bindParam($param, &$value);

    abstract protected function assemble();

    abstract public function fetch($style = Db::FETCH_OBJ);

    abstract public function fetchObject($class = 'stdClass');

    abstract public function close();

    /**
     * @return int
     */
    abstract public function affectedRows();

    abstract public function numRows();

    /**
     * @return bool
     */
    abstract protected function driverExecute($request);
}