<?php namespace Majestic\Model;

class SqlResultProvider implements iSqlResultItems
{
    /**
     * @var DbStatement
     */
    private $result;

    /**
     * @var array
     * @desc my be changed in assoc method
     */
    private $result_items;

    /**
     * @var array
     */
    private $result_items_base;

    /**
     * @param $result DbStatement
     */
    public function __construct($result)
    {
        $this->result = $result;
    }

    private function defineResultItems()
    {
        if (is_null($this->result_items_base)) {
            $this->result_items_base = $this->result->fetchAll();
            $this->result_items = $this->result_items_base;
        }
    }

    /**
     * @param $field string
     * @param bool $assoc_as_array
     * @return $this SqlResultProvider
     * @throws \ErrorException
     */
    public function assoc($field, $assoc_as_array = false)
    {
        $this->defineResultItems();
        $result_items_assoc = array();
        foreach ($this->result_items_base as $item) {
            if (!isset($item->{$field})) {
                throw new \ErrorException('Undefined field. ' . $field);
            }
            if ($assoc_as_array) {
                if (!isset($result_items_assoc[$item->{$field}])) {
                    $result_items_assoc[$item->{$field}] = array();
                }
                $result_items_assoc[$item->{$field}][] = $item;
            } else {
                if (isset($result_items_assoc[$item->{$field}])) {
                    throw new \ErrorException('Field not unique. May be use assoc_as_array. ' . $field);
                }
                $result_items_assoc[$item->{$field}] = $item;
            }
        }
        // Ассоциирование внутри каждого элемента массива
        if ($assoc_as_array) {
            foreach ($result_items_assoc as &$value) {
                $value = new SqlResultCollection($value);
            }
        }
        $this->result_items = $result_items_assoc;
        return $this;
    }

    public function getKeys()
    {
        $this->defineResultItems();
        return array_keys($this->result_items);
    }

    /**
     * @param $key
     * @return mixed
     * метод актуален после вызова assoc
     */
    public function fetchKey($key)
    {
        return $this->result_items[$key];
    }

    /**
     * @return DbStatement[]|SqlResultCollection[]
     */
    public function fetchAll()
    {
        $this->defineResultItems();
        return $this->result_items;
    }

    /**
     * @param $field
     * @return mixed
     */
    public function fetchField($field)
    {
        return $this->result->fetchField($field);
    }

    /**
     * @return mixed
     */
    public function fetch()
    {
        return $this->result->fetch(Db::FETCH_OBJ);
    }

    /**
     * @return int
     */
    public function affectedRows()
    {
        return $this->result->affectedRows();
    }
}