php-yaoi/php-yaoi

View on GitHub
src/Database.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php
namespace Yaoi;

use Yaoi\Database\Contract as DatabaseContract;
use Yaoi\Database\Definition\Table;
use Yaoi\Database\Driver\MockProxy;
use Yaoi\Database\Exception;
use Yaoi\Database\Query;
use Yaoi\Database\Settings;
use Yaoi\Mappable\Contract;
use Yaoi\Sql\Batch;
use Yaoi\Sql\DeleteInterface;
use Yaoi\Sql\InsertInterface;
use Yaoi\Sql\SelectInterface;
use Yaoi\Sql\SimpleExpression;
use Yaoi\Sql\Statement;
use Yaoi\Sql\UpdateInterface;

/**
 * TODO catch and repair crashed table
 * TODO reconnect on gone away
 *
 * Class Database
 * @property Settings $settings
 * @method Database\Driver getDriver
 */
class Database extends Service implements DatabaseContract
{
    /**
     * @param string|Settings $settings
     */
    public function __construct($settings = null)
    {
        parent::__construct($settings);
        if ($this->settings->logQueries) {
            $this->log(Log::getInstance($this->settings->logQueries));
        }
    }


    /**
     * @param null $statement
     * @param null $binds
     * @return Query
     */
    public function query($statement = null, $binds = null)
    {
        if ($statement instanceof Batch) {
            $statements = $statement->get();
        }
        else {
            $arguments = func_get_args();
            $statements = array(SimpleExpression::createFromFuncArguments($arguments));
        }

        if (empty($statements) || empty($statement)) {
            throw new Exception('Empty statement', Exception::EMPTY_STATEMENT);
        }
        $query = null;
        foreach ($statements as $expression) {
            if (!$expression->isEmpty()) {
                $query = new Query($expression, $this->getDriver());
                if (null !== $this->log) {
                    $query->log($this->log);
                }
            }
        }

        return $query;
    }


    /**
     * @param Contract $item
     * @return string
     * @deprecated
     */
    public function mappableInsertString(Contract $item)
    {
        $l = array_map(array($this, 'quote'), $item->toArray());
        return "(" . implode(',', array_keys($l)) . ") VALUES (" . implode(",", $l) . ")";
    }


    public function quote($s)
    {
        return $this->getDriver()->quote($s);
    }

    public function symbol($s)
    {
        return $this->getDriver()->quoteSymbol($s);
    }

    /**
     * @return integer
     */
    public function lastInsertId()
    {
        return $this->getDriver()->lastInsertId();
    }


    public function disconnect()
    {
        $this->getDriver()->disconnect();
    }


    protected $originalDriver;

    /**
     * @param Mock $dataSet
     * @return Database
     */
    public function mock(Mock $dataSet = null)
    {
        $driver = $this->getDriver();

        if (null === $dataSet) {
            if ($driver instanceof MockProxy) {
                $this->driver = $driver->driver;
            }
        } else {
            if ($driver instanceof MockProxy) {
                $driver->mock($dataSet);
            } else {
                $mockDriver = new MockProxy($this->settings);
                $mockDriver->mock($dataSet);
                $mockDriver->driver = $driver;
                $this->driver = $mockDriver;
            }
        }

        return $this;
    }

    /**
     * @var Log
     */
    private $log;

    public function log(Log $log = null)
    {
        $this->log = $log;
        return $this;
    }


    /**
     * @param $expression
     * @param null $binds
     * @return SimpleExpression
     * @throws Sql\Exception
     */
    public function expr($expression = null, $binds = null)
    {
        return SimpleExpression::createFromFuncArguments(func_get_args())->bindDatabase($this);
    }


    /**
     * @param null $from
     * @return SelectInterface
     */
    public function select($from = null)
    {
        $select = new Statement();
        $select
            ->bindDatabase($this)
            ->select();

        if (null !== $from) {
            $select->from($from);
        }
        return $select;
    }

    /**
     * @param null $from
     * @return DeleteInterface
     */
    public function delete($from = null)
    {
        $delete = new Statement();
        $delete
            ->bindDatabase($this)
            ->delete($from);

        return $delete;
    }

    /**
     * @param null $table
     * @return UpdateInterface
     */
    public function update($table = null)
    {
        $update = new Statement();
        $update
            ->bindDatabase($this)
            ->update($table);

        return $update;
    }

    /**
     * @param null $table
     * @return InsertInterface
     */
    public function insert($table = null)
    {
        $insert = new Statement();
        $insert
            ->bindDatabase($this)
            ->insert($table);

        return $insert;
    }


    /**
     * @return Statement
     */
    public function statement()
    {
        return Statement::create()->bindDatabase($this);
    }


    /**
     * @param $tableName
     * @return Table
     * @throws Database\Exception
     */
    public function getTableDefinition($tableName)
    {
        return $this->getUtility()->getTableDefinition($tableName);
    }

    const DIALECT_MYSQL = 'Mysql';
    const DIALECT_SQLITE = 'Sqlite';
    const DIALECT_POSTGRESQL = 'Pgsql';

    public function getDialect()
    {
        return $this->getDriver()->getDialect();
    }

    private $utility;

    public function getUtility()
    {
        if (null === $this->utility) {
            $this->utility = $this->getDriver()->getUtility();
            $this->utility->setDatabase($this);
        }
        return $this->utility;
    }

    protected static function getSettingsClassName()
    {
        return Settings::className();
    }

    public function getSchemaName()
    {
        return $this->settings->path;
    }

}