Vendoring deprecated composer libs
This commit is contained in:
353
libs/picodb/lib/PicoDb/StatementHandler.php
Normal file
353
libs/picodb/lib/PicoDb/StatementHandler.php
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use PDOStatement;
|
||||
|
||||
/**
|
||||
* Statement Handler
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class StatementHandler
|
||||
{
|
||||
/**
|
||||
* Database instance
|
||||
*
|
||||
* @access protected
|
||||
* @var Database
|
||||
*/
|
||||
protected $db = null;
|
||||
|
||||
/**
|
||||
* Flag to calculate query time
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $stopwatch = false;
|
||||
|
||||
/**
|
||||
* Start time
|
||||
*
|
||||
* @access protected
|
||||
* @var float
|
||||
*/
|
||||
protected $startTime = 0;
|
||||
|
||||
/**
|
||||
* Execution time of all queries
|
||||
*
|
||||
* @access protected
|
||||
* @var float
|
||||
*/
|
||||
protected $executionTime = 0;
|
||||
|
||||
/**
|
||||
* Flag to log generated SQL queries
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $logQueries = false;
|
||||
|
||||
/**
|
||||
* Run explain command on each query
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $explain = false;
|
||||
|
||||
/**
|
||||
* Number of SQL queries executed
|
||||
*
|
||||
* @access protected
|
||||
* @var integer
|
||||
*/
|
||||
protected $nbQueries = 0;
|
||||
|
||||
/**
|
||||
* SQL query
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* Positional SQL parameters
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $positionalParams = array();
|
||||
|
||||
/**
|
||||
* Named SQL parameters
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $namedParams = array();
|
||||
|
||||
/**
|
||||
* Flag to use named params
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $useNamedParams = false;
|
||||
|
||||
/**
|
||||
* LOB params
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $lobParams = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable query logging
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withLogging()
|
||||
{
|
||||
$this->logQueries = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record query execution time
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withStopWatch()
|
||||
{
|
||||
$this->stopwatch = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute explain command on query
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withExplain()
|
||||
{
|
||||
$this->explain = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SQL query
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @return $this
|
||||
*/
|
||||
public function withSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set positional parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function withPositionalParams(array $params)
|
||||
{
|
||||
$this->positionalParams = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set named parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function withNamedParams(array $params)
|
||||
{
|
||||
$this->namedParams = $params;
|
||||
$this->useNamedParams = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind large object parameter
|
||||
*
|
||||
* @access public
|
||||
* @param $name
|
||||
* @param $fp
|
||||
* @return $this
|
||||
*/
|
||||
public function withLobParam($name, &$fp)
|
||||
{
|
||||
$this->lobParams[$name] =& $fp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of queries executed
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getNbQueries()
|
||||
{
|
||||
return $this->nbQueries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a prepared statement
|
||||
*
|
||||
* Note: returns false on duplicate keys instead of SQLException
|
||||
*
|
||||
* @access public
|
||||
* @return PDOStatement|false
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
$this->beforeExecute();
|
||||
|
||||
$pdoStatement = $this->db->getConnection()->prepare($this->sql);
|
||||
$this->bindParams($pdoStatement);
|
||||
$pdoStatement->execute();
|
||||
|
||||
$this->afterExecute();
|
||||
return $pdoStatement;
|
||||
} catch (PDOException $e) {
|
||||
return $this->handleSqlError($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters to PDOStatement
|
||||
*
|
||||
* @access protected
|
||||
* @param PDOStatement $pdoStatement
|
||||
*/
|
||||
protected function bindParams(PDOStatement $pdoStatement)
|
||||
{
|
||||
$i = 1;
|
||||
|
||||
foreach ($this->lobParams as $name => $variable) {
|
||||
if (! $this->useNamedParams) {
|
||||
$parameter = $i;
|
||||
$i++;
|
||||
} else {
|
||||
$parameter = $name;
|
||||
}
|
||||
|
||||
$pdoStatement->bindParam($parameter, $variable, PDO::PARAM_LOB);
|
||||
}
|
||||
|
||||
foreach ($this->positionalParams as $value) {
|
||||
$pdoStatement->bindValue($i, $value, PDO::PARAM_STR);
|
||||
$i++;
|
||||
}
|
||||
|
||||
foreach ($this->namedParams as $name => $value) {
|
||||
$pdoStatement->bindValue($name, $value, PDO::PARAM_STR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed before query execution
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function beforeExecute()
|
||||
{
|
||||
if ($this->logQueries) {
|
||||
$this->db->setLogMessage($this->sql);
|
||||
}
|
||||
|
||||
if ($this->stopwatch) {
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed after query execution
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function afterExecute()
|
||||
{
|
||||
if ($this->stopwatch) {
|
||||
$duration = microtime(true) - $this->startTime;
|
||||
$this->executionTime += $duration;
|
||||
$this->db->setLogMessage('query_duration='.$duration);
|
||||
$this->db->setLogMessage('total_execution_time='.$this->executionTime);
|
||||
}
|
||||
|
||||
if ($this->explain) {
|
||||
$this->db->setLogMessages($this->db->getDriver()->explain($this->sql, $this->positionalParams));
|
||||
}
|
||||
|
||||
$this->nbQueries++;
|
||||
$this->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset internal properties after execution
|
||||
* The same object instance is used
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function cleanup()
|
||||
{
|
||||
$this->sql = '';
|
||||
$this->useNamedParams = false;
|
||||
$this->positionalParams = array();
|
||||
$this->namedParams = array();
|
||||
$this->lobParams = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle PDOException
|
||||
*
|
||||
* @access public
|
||||
* @param PDOException $e
|
||||
* @return bool
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function handleSqlError(PDOException $e)
|
||||
{
|
||||
$this->cleanup();
|
||||
$this->db->cancelTransaction();
|
||||
$this->db->setLogMessage($e->getMessage());
|
||||
|
||||
if ($this->db->getDriver()->isDuplicateKeyError($e->getCode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new SQLException('SQL Error: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user