PHP Classes

File: src/Db.php

Recommend this page to a friend!
  Classes of Vitaly   Queasy DB   src/Db.php   Download  
File: src/Db.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Queasy DB
Execute queries by accessing class variables
Author: By
Last change: #48 fixed
Date: 2 years ago
Size: 5,640 bytes
 

Contents

Class file image Download
<?php

namespace queasy\db;

use
Exception;
use
BadMethodCallException;
use
InvalidArgumentException;
use
PDOException;

use
PDO;

use
ArrayAccess;

use
Psr\Log\NullLogger;
use
Psr\Log\LoggerInterface;
use
Psr\Log\LoggerAwareInterface;

use
queasy\db\query\Query;
use
queasy\db\query\CustomQuery;

class
Db extends PDO implements ArrayAccess, LoggerAwareInterface
{
    const
DEFAULT_FETCH_MODE = PDO::FETCH_ASSOC;

    const
RETURN_STATEMENT = 1;
    const
RETURN_ONE = 2;
    const
RETURN_ALL = 3;
    const
RETURN_VALUE = 4;

    private
$tables = array();

    private
$queries = array();

   
/**
     * @var array|ArrayAccess Database config
     */
   
protected $config;

   
/**
     * @var LoggerInterface Logger instance
     */
   
protected $logger;

   
/**
     * Create Db instance
     *
     * @param string|array|ArrayAccess $configOrDsn DSN string or config array
     * @param string $user Database user name
     * @param string $password Database user password
     * @param array $options Key-value array of driver-specific options
     *
     */
   
public function __construct($configOrDsn = null, $user = null, $password = null, array $options = null)
    {
       
$this->logger = new NullLogger();

       
$config = array();
        if (
null === $configOrDsn) {
           
$connectionConfig = null;
        } elseif (
is_string($configOrDsn)) {
           
$connectionConfig = array(
               
'dsn' => $configOrDsn,
               
'user' => $user,
               
'password' => $password,
               
'options' => $options
           
);
        } elseif (
is_array($configOrDsn) || ($configOrDsn instanceof ArrayAccess)) {
           
$config = $configOrDsn;
           
$connectionConfig = isset($config['connection'])? $config['connection']: null;
        } else {
            throw new
InvalidArgumentException('Wrong constructor arguments.');
        }

       
$this->config = $config;

       
$connectionString = new Connection($connectionConfig);

       
parent::__construct(
           
$connectionString(),
            isset(
$connectionConfig['user'])? $connectionConfig['user']: $user,
            isset(
$connectionConfig['password'])? $connectionConfig['password']: $password,
            isset(
$connectionConfig['options'])? $connectionConfig['options']: $options
       
);

        if (isset(
$config['queries'])) {
           
$this->queries = $config['queries'];
        }

       
$errorMode = isset($config['errorMode'])? $config['errorMode']: self::ERRMODE_EXCEPTION;
        if (!
$this->setAttribute(self::ATTR_ERRMODE, $errorMode)) {
            throw new
DbException('Cannot set error mode.');
        }

        if (isset(
$config['fetchMode'])) {
            if (!
$this->setAttribute(self::ATTR_DEFAULT_FETCH_MODE, $config['fetchMode'])) {
                throw new
DbException('Cannot set fetch mode.');
            }
        }
    }

   
/**
     * Set a logger.
     *
     * @param LoggerInterface $logger
     */
   
public function setLogger(LoggerInterface $logger)
    {
       
$this->logger = $logger;
    }

    public function
__get($name)
    {
        return
$this->table($name);
    }

    public function
__call($name, array $args = array())
    {
        if (!isset(
$this->queries[$name])) {
            throw new
BadMethodCallException(sprintf('No method "%s" found.', $name));
        }

       
$query = new CustomQuery($this, $this->queries[$name]);
       
$query->setLogger($this->logger);

       
$params = array_shift($args);
       
$options = array_shift($args);

        return
$query(
            empty(
$params)? array(): $params,
            empty(
$options)? array(): $options
       
);
    }

    public function
__invoke($sql, array $params = array(), array $options = array())
    {
        return
$this->run($sql, $params, $options);
    }

    public function
offsetGet($name)
    {
        return
$this->table($name);
    }

    public function
offsetSet($offset, $value)
    {
        throw new
BadMethodCallException(sprintf('Not implemented.', $offset, $value));
    }

    public function
offsetExists($offset)
    {
        throw new
BadMethodCallException(sprintf('Not implemented.', $offset));
    }

    public function
offsetUnset($offset)
    {
        throw new
BadMethodCallException(sprintf('Not implemented.', $offset));
    }

    public function
table($name)
    {
        if (!isset(
$this->tables[$name])) {
           
$tablesConfig = isset($this->config['tables'])
                ?
$this->config['tables']
                : array();

           
$tableConfig = isset($tablesConfig[$name])
                ?
$tablesConfig[$name]
                : array();

           
$this->tables[$name] = new Table($this, $name, $tableConfig);
           
$this->tables[$name]->setLogger($this->logger);
        }

        return
$this->tables[$name];
    }

    public function
run($sql, array $params = array(), array $options = array())
    {
       
$query = new Query($this, $sql);
       
$query->setLogger($this->logger);

        return
$query($params, $options);
    }

    public function
id($sequence = null)
    {
        return
$this->lastInsertId($sequence);
    }

    public function
trans($func)
    {
        if (!
is_callable($func)) {
            throw new
InvalidArgumentException('Argument is not callable.');
        }

       
$this->beginTransaction();

        try {
           
$func($this);

           
$this->commit();
        } catch (
Exception $e) {
           
$this->rollBack();

            throw
$e;
        }
    }

    protected function
logger()
    {
        return
$this->logger;
    }
}