Login   Register  
PHP Classes
elePHPant
Icontem

File: phpSweetPDO/Connection.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of FractalizeR2  >  PHP Sweet PDO  >  phpSweetPDO/Connection.php  >  Download  
File: phpSweetPDO/Connection.php
Role: Class source
Content type: text/plain
Description: Main class for connecting to database and executing queries
Class: PHP Sweet PDO
Access databases using PDO
Author: By
Last change:
Date: 2011-05-03 03:08
Size: 12,485 bytes
 

Contents

Class file image Download
<?php
/*
 * ========================================================================
 * Copyright (c) 2011 Vladislav "FractalizeR" Rastrusny
 * Website: http://www.fractalizer.ru
 * Email: FractalizeR@yandex.ru
 * ------------------------------------------------------------------------
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================================
 */

namespace phpSweetPDO;

use phpSweetPDO\Exceptions\DbException;

/**
 * Class, representing dabatase connection
 */
class Connection {

    /**
     * PDO object
     *
     * @var \PDO
     */
    protected $_pdoObject;

    /**
     * Optional event dispatcher used to track various library events
     *
     * @var \sfEventDispatcher
     */
    protected $_eventDispatcher;

    /**
     * Default constructor.
     *
     * If you provide $eventDispatcher to the constructor, most calls to library's methods will generate appropriate event.
     * Events can be used to track SQL statements executed by the library or for profiling purposes.
     *
     * @param string $connectionString PDO connection string ('mysql:dbname=testdb;host=127.0.0.1')
     * @param string $username Username to use when calling PDO
     * @param string $password Password to use when calling PDO
     * @param \sfEventDispatcher $eventDispatcher Event dispatcher to use when reporting library events. Null if no reporting needed
     * @param array $driverOptions Various driver specific options for PDO connection. Empty array if no options
     *
     */
    public function __construct($connectionString, $username, $password, \sfEventDispatcher $eventDispatcher = null,
        $driverOptions = array()) {
        $this->_eventDispatcher = $eventDispatcher;

        $this->_fireEvent('phpsweetpdo.connect.started',
                          array('$connection_string' => &$connectionString, 'username' => &$username,
                               'password' => &$password, 'driver_options' => &$driverOptions));

        $this->_pdoObject = new \PDO($connectionString, $username, $password, $driverOptions);

        $this->_fireEvent('phpsweetpdo.connect.finished',
                          array('$connection_string' => &$connectionString, 'username' => &$username,
                               'password' => &$password, 'driver_options' => &$driverOptions,
                               'result' => $this->_pdoObject));
    }

    /**
     * Execute a statement without returning any data
     *
     * @param string|array $sql SQL statement
     * @param array $params Parameters. A single value or an array of values
     * @param array $driverOptions Specific options to pass to underlying PDO prepare() call. Empty array if no options
     * @return integer A number of rows affected by last operation
     */
    public function execute($sql, $params = array(), array $driverOptions = array()) {
        $this->_modifyParams($sql, $params);

        $this->_fireEvent('phpsweetpdo.execute.started',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions));

        //Preparing and executing
        $statement = $this->_prepareStatement($sql, $params, $driverOptions);
        $this->_executeStatement($statement, $sql, $params);
        $result = $statement->rowCount();

        $this->_fireEvent('phpsweetpdo.execute.finished',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions,
                               'result' => &$result));

        return $result;
    }

    /**
     * Executes a select statement and returns data for it.
     *
     * @param string|array $sql SQL statement to execute.
     * @param array|mixed $params Query parameters to substitute instead of ? marks in query
     * @param array $driverOptions Specific options to pass to underlying PDO prepare() call. Empty array if no options
     * @return Recordset The recordset, containing selection results
     */
    public function select($sql, $params = array(), array $driverOptions = array()) {
        $this->_modifyParams($sql, $params);

        $this->_fireEvent('phpsweetpdo.select.started',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions));

        $statement = $this->_prepareStatement($sql, $params, $driverOptions);

        $result = new Recordset($statement, $params);

        $this->_fireEvent('phpsweetpdo.select.finished',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions,
                               'result' => &$result));

        return $result;
    }

    /**
     * Function returns a single result from a query or false if no
     * rows were selected by query
     *
     * @param string|array $sql SQL statement to execute.
     * @param array|mixed $params Query parameters to substitute instead of ? marks in query
     * @param array $driverOptions Specific options to pass to underlying PDO prepare() call. Empty array if no options
     * @return mixed|boolean A single value from SQL statement execution or boolean false if no result available
     */
    public function getOneValue($sql, $params = array(), array $driverOptions = array()) {
        $this->_modifyParams($sql, $params);

        $this->_fireEvent('phpsweetpdo.get_one_value.started',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions));

        $statement = $this->_prepareStatement($sql, $params, $driverOptions);
        $this->_executeStatement($statement, $sql, $params);
        $result = $statement->fetchColumn(0);

        $this->_fireEvent('phpsweetpdo.get_one_value.finished',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions,
                               'result' => &$result));

        return $result;
    }

    /**
     * Function returns a single row from a query or false if no
     * rows were selected by query
     *
     * @param string|array $sql SQL statement to execute.
     * @param array|mixed $params Query parameters to substitute instead of ? marks in query
     * @param array $driverOptions Specific options to pass to underlying PDO prepare() call. Empty array if no options
     * @return mixed|boolean A single row from SQL statement execution or boolean false if no result available
     */
    public function getOneRow($sql, $params = array(), array $driverOptions = array()) {
        $this->_modifyParams($sql, $params);

        $this->_fireEvent('phpsweetpdo.get_one_row.started',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions));

        $statement = $this->_prepareStatement($sql, $params, $driverOptions);
        $this->_executeStatement($statement, $sql, $params);

        $result = $statement->fetchObject('\phpSweetPDO\RecordsetRow');

        $this->_fireEvent('phpsweetpdo.get_one_row.finished',
                          array('sql' => &$sql, 'params' => &$params, 'driver_options' => &$driverOptions,
                               'result' => &$result));

        return $result;
    }


    /**
     * Function begins a transaction
     *
     * @return boolean
     */
    public function beginTransaction() {
        $this->_fireEvent('phpsweetpdo.begin_transaction.started', array());
        $result = $this->_pdoObject->beginTransaction();
        $this->_fireEvent('phpsweetpdo.begin_transaction.finished', array('result' => $result));
        return $result;
    }

    /**
     * Function commits transaction
     *
     * @return boolean
     */
    public function commitTransaction() {
        $this->_fireEvent('phpsweetpdo.commit_transaction.started', array());
        $result = $this->_pdoObject->commit();
        $this->_fireEvent('phpsweetpdo.commit_transaction.finished', array('result' => &$result));
        return $result;
    }

    /**
     * Function rolls back transaction
     *
     * @return boolean
     */
    public function rollbackTransaction() {
        $this->_fireEvent('phpsweetpdo.rollback_transaction.started', array());
        $result = $this->_pdoObject->rollBack();
        $this->_fireEvent('phpsweetpdo.rollback_transaction.finished', array('result' => &$result));
        return $result;
    }

    /**
     * Returns the last inserted ID into the database
     *
     * @param string $sequenceName The optional name of the sequence to return data for
     *
     */
    public function getLastInsertId($sequenceName = "") {
        $this->_pdoObject->lastInsertId($sequenceName);
    }

    /**
     * Quotes the string to be safely used in queries
     *
     * @param  $str String to quote
     * @return string Quoted string
     */
    public function quote($str) {
        return $this->_pdoObject->quote($str);
    }


    /**
     * Closes connection
     *
     * @return void
     */
    public function close() {
        $this->_pdoObject = null;
    }

    /**
     * Destructor to close connection on object destruction.
     */
    public function __destruct() {
        $this->close();
    }

    /**
     * Function to report events to the dispatcher
     *
     * @param string $name A name of the event to fire
     * @param array $params Event parameters
     * @return void
     */
    protected function _fireEvent($name, $params) {
        if (is_null($this->_eventDispatcher)) {
            return;
        }
        $event = new \sfEvent($this, $name, $params);
        $this->_eventDispatcher->notify($event);
    }

    /**
     * Prepares PDOStatement and checks for errors
     *
     * @throws DbException
     * @param string $sql SQL statement. No array allowed here, string only
     * @param array|mixed $params Query parameters to substitute instead of ? marks in query
     * @param array $driverOptions Specific options to pass to underlying PDO prepare() call. Empty array if no options
     * @return \PDOStatement
     */
    protected function _prepareStatement($sql, $params, $driverOptions) {
        $statement = $this->_pdoObject->prepare($sql, $driverOptions);

        if (!$statement) {
            throw new DbException($statement->errorInfo(), $sql, $params);
        }
        return $statement;
    }

    /**
     * Executes PDOStatement and checks for errors
     *
     * @throws DbException
     * @param  \PDOStatement $statement
     * @param  string $sql
     * @param  array $params
     * @return void
     */
    protected function _executeStatement($statement, $sql, $params) {
        if ((!$statement->execute($params)) and ($statement->errorCode() != '00000')) {
            throw new DbException($statement->errorInfo(), $sql, $params);
        }
    }


    /**
     * Unwraps parameters from $sql if it is array and convert single param into array
     *
     * @throws LogicException
     * @param  $sql
     * @param  $params
     * @return void
     */
    protected function _modifyParams(&$sql, &$params) {
        if (is_array($sql)) {
            if (count($sql) < 2) {
                throw new \InvalidArgumentException('If $sql is array, it needs to have at least 2 elements: (0) sql query, string and (1) parameters (single value or array).');
            }
            if ((count($params) > 0)) {
                throw new \InvalidArgumentException('$sql is array, $params should be empty in this case.');
            }
            $params = $sql[1];
            $sql = $sql[0];
        }
        if (!is_array($params)) {
            $params = array($params);
        }
    }
}