<?php
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage db
 * @since 2010-02-17
 */

/**
 * @property MySQLi $connection
 */
class MySQLiDriver extends SqlDbDriver
{

    public function insert($table, $bind, $on_duplicate = array())
    {
        $columns = array();
        foreach ($bind as $col => $val) {
            $columns[] = $this->quoteIdentifier($col);
        }
        $values = array_values($bind);

        if ($on_duplicate) {
            $update = array();
            foreach ($on_duplicate as $col => $val) {
                $update[] = $this->quoteIdentifier($col) . '=' . $this->quote($val);
            }
            $on_duplicate = ' ON DUPLICATE KEY UPDATE ' . implode(', ', $update);
        }

        $sql = 'INSERT INTO ' . $this->quoteIdentifier($table)
                . ' (' . implode(', ', $columns) . ') VALUES (' . $this->quote($values) . ')'
                . (($on_duplicate) ? $on_duplicate : '');
        return $this->query($sql)->affectedRows();
    }

    /**
     * @param mixed $sql
     * @return MySQLiStatement
     */
    public function prepare($sql)
    {
        return new MySQLiStatement($this, $sql);
    }

    public function getInsertId($table = null, $key = null)
    {
        return $this->connection->insert_id;
    }

    public function isConnected()
    {
        return ($this->connection instanceof MySQLi);
    }

    public function disconnect()
    {
        if ($this->isConnected()) {
            $this->connection->close();
        }
        $this->connection = null;
    }

    protected function connect()
    {
        if ($this->connection) {
            return;
        }

        $port = isset($this->config['port']) ? (int) $this->config['port'] : null;
        $this->connection = mysqli_init();
        @mysqli_real_connect($this->connection,
            $this->config['hostname'],
            $this->config['username'],
            $this->config['password'],
            $this->config['database'],
            $port);
        // Connection errors check
        if (mysqli_connect_error()) {
            throw new GeneralException(mysqli_connect_error(), mysqli_connect_errno());
        }

        $charset = (!empty($this->config['charset'])) ? $this->config['charset'] : 'utf8';
        $this->connection->set_charset($charset);
    }

    protected function driverQuote($value)
    {
        if (is_int($value) || is_float($value)) {
            return $value;
        }

        if (is_bool($value)) {
            return (int) $value;
        }

        if ($value === null) {
            return 'NULL';
        }

        $this->connect();
        return '\'' . $this->connection->real_escape_string($value) . '\'';
    }

    protected function driverBeginTransaction()
    {
        $this->connect();
        $this->connection->autocommit(false);
    }

    protected function driverCommitTransaction()
    {
        $this->connection->commit();
        $this->connection->autocommit(true);
    }

    protected function driverRollbackTransaction()
    {
        $this->connection->rollback();
        $this->connection->autocommit(true);
    }
}