Update PicoDb version
This commit is contained in:
parent
920e522c9e
commit
d3fb2bf69d
@ -61,17 +61,13 @@ PicoDb\Database::setInstance('db', function() {
|
||||
else {
|
||||
$errors = $db->getLogMessages();
|
||||
|
||||
$pdo = new \PDO('sqlite::memory:');
|
||||
$result = $pdo->query('select sqlite_version()', PDO::FETCH_COLUMN, 0);
|
||||
$sqlite_version = $result ? $result->fetch() : '?';
|
||||
|
||||
$html = 'Unable to migrate the database schema, <strong>please copy and paste this message and create a bug report:</strong><hr/>';
|
||||
$html .= '<pre><code>';
|
||||
$html .= (isset($errors[0]) ? $errors[0] : 'Unknown SQL error').PHP_EOL.PHP_EOL;
|
||||
$html .= '- PHP version: '.phpversion().PHP_EOL;
|
||||
$html .= '- SAPI: '.php_sapi_name().PHP_EOL;
|
||||
$html .= '- PDO Sqlite version: '.phpversion('pdo_sqlite').PHP_EOL;
|
||||
$html .= '- Sqlite version: '.$sqlite_version.PHP_EOL;
|
||||
$html .= '- Sqlite version: '.$db->getDriver()->getDatabaseVersion().PHP_EOL;
|
||||
$html .= '- OS: '.php_uname();
|
||||
$html .= '</code></pre>';
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
"require": {
|
||||
"fguillot/simple-validator": "v1.0.0",
|
||||
"fguillot/json-rpc": "v1.1.0",
|
||||
"fguillot/picodb": "v1.0.2",
|
||||
"fguillot/picodb": "v1.0.14 ",
|
||||
"fguillot/picofeed": "v0.1.24",
|
||||
"pda/pheanstalk": "v3.1.0"
|
||||
},
|
||||
|
@ -546,7 +546,7 @@ function cleanup($feed_id, array $items_in_feed)
|
||||
$removed_items = $db
|
||||
->table('items')
|
||||
->columns('id')
|
||||
->notin('id', $items_in_feed)
|
||||
->notIn('id', $items_in_feed)
|
||||
->eq('status', 'removed')
|
||||
->eq('feed_id', $feed_id)
|
||||
->desc('updated')
|
||||
|
@ -14,6 +14,8 @@ const EXPIRATION = 5184000;
|
||||
* Get a remember me record
|
||||
*
|
||||
* @access public
|
||||
* @param string $token
|
||||
* @param string $sequence
|
||||
* @return mixed
|
||||
*/
|
||||
function find($token, $sequence)
|
||||
|
11
vendor/composer/autoload_classmap.php
vendored
11
vendor/composer/autoload_classmap.php
vendored
@ -72,16 +72,25 @@ return array(
|
||||
'Pheanstalk\\Socket\\StreamFunctions' => $vendorDir . '/pda/pheanstalk/src/Socket/StreamFunctions.php',
|
||||
'Pheanstalk\\Socket\\WriteHistory' => $vendorDir . '/pda/pheanstalk/src/Socket/WriteHistory.php',
|
||||
'Pheanstalk\\YamlResponseParser' => $vendorDir . '/pda/pheanstalk/src/YamlResponseParser.php',
|
||||
'PicoDb\\Condition' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Condition.php',
|
||||
'PicoDb\\Builder\\BaseBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php',
|
||||
'PicoDb\\Builder\\ConditionBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/ConditionBuilder.php',
|
||||
'PicoDb\\Builder\\InsertBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php',
|
||||
'PicoDb\\Builder\\OrConditionBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php',
|
||||
'PicoDb\\Builder\\UpdateBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php',
|
||||
'PicoDb\\Database' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Database.php',
|
||||
'PicoDb\\DriverFactory' => $vendorDir . '/fguillot/picodb/lib/PicoDb/DriverFactory.php',
|
||||
'PicoDb\\Driver\\Base' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Base.php',
|
||||
'PicoDb\\Driver\\Mssql' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Mssql.php',
|
||||
'PicoDb\\Driver\\Mysql' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Mysql.php',
|
||||
'PicoDb\\Driver\\Postgres' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Postgres.php',
|
||||
'PicoDb\\Driver\\Sqlite' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php',
|
||||
'PicoDb\\Hashtable' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Hashtable.php',
|
||||
'PicoDb\\LargeObject' => $vendorDir . '/fguillot/picodb/lib/PicoDb/LargeObject.php',
|
||||
'PicoDb\\SQLException' => $vendorDir . '/fguillot/picodb/lib/PicoDb/SQLException.php',
|
||||
'PicoDb\\Schema' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Schema.php',
|
||||
'PicoDb\\StatementHandler' => $vendorDir . '/fguillot/picodb/lib/PicoDb/StatementHandler.php',
|
||||
'PicoDb\\Table' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Table.php',
|
||||
'PicoDb\\UrlParser' => $vendorDir . '/fguillot/picodb/lib/PicoDb/UrlParser.php',
|
||||
'PicoFeed\\Base' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Base.php',
|
||||
'PicoFeed\\Client\\Client' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/Client.php',
|
||||
'PicoFeed\\Client\\ClientException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php',
|
||||
|
11
vendor/composer/autoload_static.php
vendored
11
vendor/composer/autoload_static.php
vendored
@ -144,16 +144,25 @@ class ComposerStaticInitfd7e8d436e1dc450edc3153ac8bc31b4
|
||||
'Pheanstalk\\Socket\\StreamFunctions' => __DIR__ . '/..' . '/pda/pheanstalk/src/Socket/StreamFunctions.php',
|
||||
'Pheanstalk\\Socket\\WriteHistory' => __DIR__ . '/..' . '/pda/pheanstalk/src/Socket/WriteHistory.php',
|
||||
'Pheanstalk\\YamlResponseParser' => __DIR__ . '/..' . '/pda/pheanstalk/src/YamlResponseParser.php',
|
||||
'PicoDb\\Condition' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Condition.php',
|
||||
'PicoDb\\Builder\\BaseBuilder' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php',
|
||||
'PicoDb\\Builder\\ConditionBuilder' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Builder/ConditionBuilder.php',
|
||||
'PicoDb\\Builder\\InsertBuilder' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php',
|
||||
'PicoDb\\Builder\\OrConditionBuilder' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php',
|
||||
'PicoDb\\Builder\\UpdateBuilder' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php',
|
||||
'PicoDb\\Database' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Database.php',
|
||||
'PicoDb\\DriverFactory' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/DriverFactory.php',
|
||||
'PicoDb\\Driver\\Base' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Driver/Base.php',
|
||||
'PicoDb\\Driver\\Mssql' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Driver/Mssql.php',
|
||||
'PicoDb\\Driver\\Mysql' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Driver/Mysql.php',
|
||||
'PicoDb\\Driver\\Postgres' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Driver/Postgres.php',
|
||||
'PicoDb\\Driver\\Sqlite' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php',
|
||||
'PicoDb\\Hashtable' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Hashtable.php',
|
||||
'PicoDb\\LargeObject' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/LargeObject.php',
|
||||
'PicoDb\\SQLException' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/SQLException.php',
|
||||
'PicoDb\\Schema' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Schema.php',
|
||||
'PicoDb\\StatementHandler' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/StatementHandler.php',
|
||||
'PicoDb\\Table' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/Table.php',
|
||||
'PicoDb\\UrlParser' => __DIR__ . '/..' . '/fguillot/picodb/lib/PicoDb/UrlParser.php',
|
||||
'PicoFeed\\Base' => __DIR__ . '/..' . '/fguillot/picofeed/lib/PicoFeed/Base.php',
|
||||
'PicoFeed\\Client\\Client' => __DIR__ . '/..' . '/fguillot/picofeed/lib/PicoFeed/Client/Client.php',
|
||||
'PicoFeed\\Client\\ClientException' => __DIR__ . '/..' . '/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php',
|
||||
|
81
vendor/composer/installed.json
vendored
81
vendor/composer/installed.json
vendored
@ -37,45 +37,6 @@
|
||||
"description": "Simple validator library",
|
||||
"homepage": "https://github.com/fguillot/simpleValidator"
|
||||
},
|
||||
{
|
||||
"name": "fguillot/picodb",
|
||||
"version": "v1.0.2",
|
||||
"version_normalized": "1.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fguillot/picoDb.git",
|
||||
"reference": "61f492c125d9195ce869447e2b2450adeb3b01d6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/61f492c125d9195ce869447e2b2450adeb3b01d6",
|
||||
"reference": "61f492c125d9195ce869447e2b2450adeb3b01d6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2015-08-27 23:33:16",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PicoDb": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frédéric Guillot",
|
||||
"homepage": "http://fredericguillot.com"
|
||||
}
|
||||
],
|
||||
"description": "Minimalist database query builder",
|
||||
"homepage": "https://github.com/fguillot/picoDb"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zendxml",
|
||||
"version": "1.0.2",
|
||||
@ -262,5 +223,47 @@
|
||||
],
|
||||
"description": "Modern library to handle RSS/Atom feeds",
|
||||
"homepage": "https://github.com/fguillot/picoFeed"
|
||||
},
|
||||
{
|
||||
"name": "fguillot/picodb",
|
||||
"version": "v1.0.14",
|
||||
"version_normalized": "1.0.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fguillot/picoDb.git",
|
||||
"reference": "86a831302ab10af800c83dbe4b3b01c88d5433f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/86a831302ab10af800c83dbe4b3b01c88d5433f1",
|
||||
"reference": "86a831302ab10af800c83dbe4b3b01c88d5433f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.8.*"
|
||||
},
|
||||
"time": "2016-07-16 22:59:59",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PicoDb": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frédéric Guillot",
|
||||
"homepage": "https://github.com/fguillot/"
|
||||
}
|
||||
],
|
||||
"description": "Minimalist database query builder",
|
||||
"homepage": "https://github.com/fguillot/picoDb"
|
||||
}
|
||||
]
|
||||
|
86
vendor/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php
vendored
Normal file
86
vendor/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
use PicoDb\Database;
|
||||
|
||||
/**
|
||||
* Class InsertBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseBuilder
|
||||
{
|
||||
/**
|
||||
* @var Database
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var ConditionBuilder
|
||||
*/
|
||||
protected $conditionBuilder;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = '';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* InsertBuilder constructor
|
||||
*
|
||||
* @param Database $db
|
||||
* @param ConditionBuilder $condition
|
||||
*/
|
||||
public function __construct(Database $db, ConditionBuilder $condition)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->conditionBuilder = $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param Database $db
|
||||
* @param ConditionBuilder $condition
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance(Database $db, ConditionBuilder $condition)
|
||||
{
|
||||
return new static($db, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table name
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return $this
|
||||
*/
|
||||
public function withTable($table)
|
||||
{
|
||||
$this->table = $table;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set columns name
|
||||
*
|
||||
* @access public
|
||||
* @param string[] $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function withColumns(array $columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,13 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
use PicoDb\Database;
|
||||
use PicoDb\Table;
|
||||
|
||||
/**
|
||||
* Handle SQL conditions
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Condition
|
||||
class ConditionBuilder
|
||||
{
|
||||
/**
|
||||
* Database instance
|
||||
@ -26,10 +30,10 @@ class Condition
|
||||
private $values = array();
|
||||
|
||||
/**
|
||||
* SQL conditions
|
||||
* SQL AND conditions
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
private $conditions = array();
|
||||
|
||||
@ -37,17 +41,17 @@ class Condition
|
||||
* SQL OR conditions
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
* @var OrConditionBuilder[]
|
||||
*/
|
||||
private $or = array();
|
||||
private $orConditions = array();
|
||||
|
||||
/**
|
||||
* OR condition started
|
||||
* SQL condition offset
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
* @var int
|
||||
*/
|
||||
private $beginOr = false;
|
||||
private $orConditionOffset = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -101,8 +105,8 @@ class Condition
|
||||
*/
|
||||
public function addCondition($sql)
|
||||
{
|
||||
if ($this->beginOr) {
|
||||
$this->or[] = $sql;
|
||||
if ($this->orConditionOffset > 0) {
|
||||
$this->orConditions[$this->orConditionOffset]->withCondition($sql);
|
||||
}
|
||||
else {
|
||||
$this->conditions[] = $sql;
|
||||
@ -116,9 +120,10 @@ class Condition
|
||||
*/
|
||||
public function beginOr()
|
||||
{
|
||||
$this->beginOr = true;
|
||||
$this->or = array();
|
||||
$this->orConditionOffset++;
|
||||
$this->orConditions[$this->orConditionOffset] = new OrConditionBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close OR condition
|
||||
*
|
||||
@ -126,10 +131,13 @@ class Condition
|
||||
*/
|
||||
public function closeOr()
|
||||
{
|
||||
$this->beginOr = false;
|
||||
$condition = $this->orConditions[$this->orConditionOffset]->build();
|
||||
$this->orConditionOffset--;
|
||||
|
||||
if (! empty($this->or)) {
|
||||
$this->conditions[] = '('.implode(' OR ', $this->or).')';
|
||||
if ($this->orConditionOffset > 0) {
|
||||
$this->orConditions[$this->orConditionOffset]->withCondition($condition);
|
||||
} else {
|
||||
$this->conditions[] = $condition;
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +182,19 @@ class Condition
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IN condition with a subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function inSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' IN ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT IN condition
|
||||
*
|
||||
@ -181,7 +202,7 @@ class Condition
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
*/
|
||||
public function notin($column, array $values)
|
||||
public function notIn($column, array $values)
|
||||
{
|
||||
if (! empty($values)) {
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' NOT IN ('.implode(', ', array_fill(0, count($values), '?')).')');
|
||||
@ -189,6 +210,19 @@ class Condition
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT IN condition with a subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function notInSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' NOT IN ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* LIKE condition
|
||||
*
|
||||
@ -228,6 +262,19 @@ class Condition
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function gtSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' > ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than condition
|
||||
*
|
||||
@ -241,6 +288,19 @@ class Condition
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function ltSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' < ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equals condition
|
||||
*
|
||||
@ -254,6 +314,19 @@ class Condition
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function gteSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' >= ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than or equals condition
|
||||
*
|
||||
@ -267,6 +340,19 @@ class Condition
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than or equal condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function lteSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' <= ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* IS NULL condition
|
||||
*
|
36
vendor/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php
vendored
Normal file
36
vendor/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class InsertBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class InsertBuilder extends BaseBuilder
|
||||
{
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$columns = array();
|
||||
$placeholders = array();
|
||||
|
||||
foreach ($this->columns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column);
|
||||
$placeholders[] = ':'.$column;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'INSERT INTO %s (%s) VALUES (%s)',
|
||||
$this->db->escapeIdentifier($this->table),
|
||||
implode(', ', $columns),
|
||||
implode(', ', $placeholders)
|
||||
);
|
||||
}
|
||||
}
|
43
vendor/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php
vendored
Normal file
43
vendor/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class OrConditionBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class OrConditionBuilder
|
||||
{
|
||||
/**
|
||||
* List of SQL conditions
|
||||
*
|
||||
* @access protected
|
||||
* @var string[]
|
||||
*/
|
||||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* Add new condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $condition
|
||||
* @return $this
|
||||
*/
|
||||
public function withCondition($condition) {
|
||||
$this->conditions[] = $condition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return '('.implode(' OR ', $this->conditions).')';
|
||||
}
|
||||
}
|
56
vendor/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php
vendored
Normal file
56
vendor/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class UpdateBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UpdateBuilder extends BaseBuilder
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $sumColumns = array();
|
||||
|
||||
/**
|
||||
* Set columns name
|
||||
*
|
||||
* @access public
|
||||
* @param string[] $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function withSumColumns(array $columns)
|
||||
{
|
||||
$this->sumColumns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$columns = array();
|
||||
|
||||
foreach ($this->columns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'=?';
|
||||
}
|
||||
|
||||
foreach ($this->sumColumns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'='.$this->db->escapeIdentifier($column).' + ?';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'UPDATE %s SET %s %s',
|
||||
$this->db->escapeIdentifier($this->table),
|
||||
implode(', ', $columns),
|
||||
$this->conditionBuilder->build()
|
||||
);
|
||||
}
|
||||
}
|
192
vendor/fguillot/picodb/lib/PicoDb/Database.php
vendored
192
vendor/fguillot/picodb/lib/PicoDb/Database.php
vendored
@ -5,6 +5,7 @@ namespace PicoDb;
|
||||
use Closure;
|
||||
use PDOException;
|
||||
use LogicException;
|
||||
use PicoDb\Driver\Mssql;
|
||||
use PicoDb\Driver\Sqlite;
|
||||
use PicoDb\Driver\Mysql;
|
||||
use PicoDb\Driver\Postgres;
|
||||
@ -12,7 +13,8 @@ use PicoDb\Driver\Postgres;
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
@ -25,6 +27,14 @@ class Database
|
||||
*/
|
||||
private static $instances = array();
|
||||
|
||||
/**
|
||||
* Statement object
|
||||
*
|
||||
* @access protected
|
||||
* @var StatementHandler
|
||||
*/
|
||||
protected $statementHandler;
|
||||
|
||||
/**
|
||||
* Queries logs
|
||||
*
|
||||
@ -40,55 +50,16 @@ class Database
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* Flag to calculate query time
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
public $stopwatch = false;
|
||||
|
||||
/**
|
||||
* Flag to log generated SQL queries
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
public $logQueries = false;
|
||||
|
||||
/**
|
||||
* Number of SQL queries executed
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $nbQueries = 0;
|
||||
|
||||
/**
|
||||
* Initialize the driver
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings Connection settings
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct(array $settings)
|
||||
public function __construct(array $settings = array())
|
||||
{
|
||||
if (! isset($settings['driver'])) {
|
||||
throw new LogicException('You must define a database driver');
|
||||
}
|
||||
|
||||
switch ($settings['driver']) {
|
||||
case 'sqlite':
|
||||
$this->driver = new Sqlite($settings);
|
||||
break;
|
||||
case 'mysql':
|
||||
$this->driver = new Mysql($settings);
|
||||
break;
|
||||
case 'postgres':
|
||||
$this->driver = new Postgres($settings);
|
||||
break;
|
||||
default:
|
||||
throw new LogicException('This database driver is not supported');
|
||||
}
|
||||
$this->driver = DriverFactory::getDriver($settings);
|
||||
$this->statementHandler = new StatementHandler($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,11 +110,29 @@ class Database
|
||||
* Add a log message
|
||||
*
|
||||
* @access public
|
||||
* @param string $message Message
|
||||
* @param mixed $message
|
||||
* @return Database
|
||||
*/
|
||||
public function setLogMessage($message)
|
||||
{
|
||||
$this->logs[] = $message;
|
||||
$this->logs[] = is_array($message) ? var_export($message, true) : $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add many log messages
|
||||
*
|
||||
* @access public
|
||||
* @param array $messages
|
||||
* @return Database
|
||||
*/
|
||||
public function setLogMessages(array $messages)
|
||||
{
|
||||
foreach ($messages as $message) {
|
||||
$this->setLogMessage($message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,7 +161,7 @@ class Database
|
||||
* Get the Driver instance
|
||||
*
|
||||
* @access public
|
||||
* @return Sqlite|Postgres|Mysql
|
||||
* @return Mssql|Sqlite|Postgres|Mysql
|
||||
*/
|
||||
public function getDriver()
|
||||
{
|
||||
@ -187,7 +176,18 @@ class Database
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return $this->driver->getLastId();
|
||||
return (int) $this->driver->getLastId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statement object
|
||||
*
|
||||
* @access public
|
||||
* @return StatementHandler
|
||||
*/
|
||||
public function getStatementHandler()
|
||||
{
|
||||
return $this->statementHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,30 +251,10 @@ class Database
|
||||
*/
|
||||
public function execute($sql, array $values = array())
|
||||
{
|
||||
try {
|
||||
|
||||
if ($this->logQueries) {
|
||||
$this->setLogMessage($sql);
|
||||
}
|
||||
|
||||
if ($this->stopwatch) {
|
||||
$start = microtime(true);
|
||||
}
|
||||
|
||||
$rq = $this->getConnection()->prepare($sql);
|
||||
$rq->execute($values);
|
||||
|
||||
if ($this->stopwatch) {
|
||||
$this->setLogMessage('DURATION='.(microtime(true) - $start));
|
||||
}
|
||||
|
||||
$this->nbQueries++;
|
||||
|
||||
return $rq;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
return $this->handleSqlError($e);
|
||||
}
|
||||
return $this->statementHandler
|
||||
->withSql($sql)
|
||||
->withPositionalParams($values)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -293,30 +273,9 @@ class Database
|
||||
$this->closeTransaction();
|
||||
|
||||
return $result === null ? true : $result;
|
||||
} catch (PDOException $e) {
|
||||
return $this->statementHandler->handleSqlError($e);
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
return $this->handleSqlError($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle PDOException
|
||||
*
|
||||
* @access private
|
||||
* @param PDOException $e
|
||||
* @return bool
|
||||
* @throws SQLException
|
||||
*/
|
||||
private function handleSqlError(PDOException $e)
|
||||
{
|
||||
$this->cancelTransaction();
|
||||
$this->setLogMessage($e->getMessage());
|
||||
|
||||
if ($this->driver->isDuplicateKeyError($e->getCode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new SQLException('SQL error'.($this->logQueries ? ': '.$e->getMessage() : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,42 +310,61 @@ class Database
|
||||
public function cancelTransaction()
|
||||
{
|
||||
if ($this->getConnection()->inTransaction()) {
|
||||
$this->getConnection()->rollback();
|
||||
$this->getConnection()->rollBack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a table instance
|
||||
* Get a table object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table_name
|
||||
* @param string $table
|
||||
* @return Table
|
||||
*/
|
||||
public function table($table_name)
|
||||
public function table($table)
|
||||
{
|
||||
return new Table($this, $table_name);
|
||||
return new Table($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hashtable instance
|
||||
* Get a hashtable object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table_name
|
||||
* @param string $table
|
||||
* @return Hashtable
|
||||
*/
|
||||
public function hashtable($table_name)
|
||||
public function hashtable($table)
|
||||
{
|
||||
return new Hashtable($this, $table_name);
|
||||
return new Hashtable($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a schema instance
|
||||
* Get a LOB object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return LargeObject
|
||||
*/
|
||||
public function largeObject($table)
|
||||
{
|
||||
return new LargeObject($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a schema object
|
||||
*
|
||||
* @access public
|
||||
* @param string $namespace
|
||||
* @return Schema
|
||||
*/
|
||||
public function schema()
|
||||
public function schema($namespace = null)
|
||||
{
|
||||
return new Schema($this);
|
||||
$schema = new Schema($this);
|
||||
|
||||
if ($namespace !== null) {
|
||||
$schema->setNamespace($namespace);
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
@ -9,7 +9,8 @@ use PDOException;
|
||||
/**
|
||||
* Base Driver class
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class Base
|
||||
{
|
||||
@ -19,7 +20,7 @@ abstract class Base
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAtttributes = array();
|
||||
protected $requiredAttributes = array();
|
||||
|
||||
/**
|
||||
* PDO connection
|
||||
@ -119,7 +120,7 @@ abstract class Base
|
||||
*/
|
||||
public function __construct(array $settings)
|
||||
{
|
||||
foreach ($this->requiredAtttributes as $attribute) {
|
||||
foreach ($this->requiredAttributes as $attribute) {
|
||||
if (! isset($settings[$attribute])) {
|
||||
throw new LogicException('This configuration parameter is missing: "'.$attribute.'"');
|
||||
}
|
||||
@ -185,8 +186,49 @@ abstract class Base
|
||||
return true;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->pdo->rollback();
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace placeholder with values in prepared statement
|
||||
*
|
||||
* @access protected
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return string
|
||||
*/
|
||||
protected function getSqlFromPreparedStatement($sql, array $values)
|
||||
{
|
||||
foreach ($values as $value) {
|
||||
$sql = substr_replace($sql, "'$value'", strpos($sql, '?'), 1);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SELECT VERSION()')->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
178
vendor/fguillot/picodb/lib/PicoDb/Driver/Mssql.php
vendored
Normal file
178
vendor/fguillot/picodb/lib/PicoDb/Driver/Mssql.php
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Microsoft SQL Server Driver
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Algy Taylor <thomas.taylor@cmft.nhs.uk>
|
||||
*/
|
||||
class Mssql extends Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
'database',
|
||||
);
|
||||
|
||||
/**
|
||||
* Table to store the schema version
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $schemaTable = 'schema_version';
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$dsn = 'sqlsrv:Server=' . $settings['hostname'] . ';Database=' . $settings['database'];
|
||||
|
||||
if (! empty($settings['port'])) {
|
||||
$dsn .= ';port=' . $settings['port'];
|
||||
}
|
||||
|
||||
$this->pdo = new PDO($dsn, $settings['username'], $settings['password']);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('EXEC sp_MSforeachtable @command1="ALTER TABLE ? CHECK CONSTRAINT ALL"; GO;');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('EXEC sp_MSforeachtable @command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"; GO;');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
public function isDuplicateKeyError($code)
|
||||
{
|
||||
return $code == 2601;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/ms175874.aspx
|
||||
*
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function escape($identifier)
|
||||
{
|
||||
return '['.$identifier.']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator($operator)
|
||||
{
|
||||
if ($operator === 'LIKE' || $operator === 'ILIKE') {
|
||||
return 'LIKE';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS [".$this->schemaTable."] ([version] INT DEFAULT '0')");
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT [version] FROM ['.$this->schemaTable.']');
|
||||
$rq->execute();
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
if ($result !== false) {
|
||||
return (int) $result;
|
||||
}
|
||||
else {
|
||||
$this->pdo->exec('INSERT INTO ['.$this->schemaTable.'] VALUES(0)');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
public function setSchemaVersion($version)
|
||||
{
|
||||
$rq = $this->pdo->prepare('UPDATE ['.$this->schemaTable.'] SET [version]=?');
|
||||
$rq->execute(array($version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
$this->getConnection()->exec('SET SHOWPLAN_ALL ON');
|
||||
return $this->getConnection()->query($this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@ use PDOException;
|
||||
/**
|
||||
* Mysql Driver
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Mysql extends Base
|
||||
{
|
||||
@ -18,7 +19,7 @@ class Mysql extends Base
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAtttributes = array(
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
@ -40,6 +41,27 @@ class Mysql extends Base
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$this->pdo = new PDO(
|
||||
$this->buildDsn($settings),
|
||||
$settings['username'],
|
||||
$settings['password'],
|
||||
$this->buildOptions($settings)
|
||||
);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build connection DSN
|
||||
*
|
||||
* @access protected
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
protected function buildDsn(array $settings)
|
||||
{
|
||||
$charset = empty($settings['charset']) ? 'utf8' : $settings['charset'];
|
||||
$dsn = 'mysql:host='.$settings['hostname'].';dbname='.$settings['database'].';charset='.$charset;
|
||||
@ -48,15 +70,35 @@ class Mysql extends Base
|
||||
$dsn .= ';port='.$settings['port'];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build connection options
|
||||
*
|
||||
* @access protected
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function buildOptions(array $settings)
|
||||
{
|
||||
$options = array(
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode = STRICT_ALL_TABLES',
|
||||
);
|
||||
|
||||
$this->pdo = new PDO($dsn, $settings['username'], $settings['password'], $options);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
if (! empty($settings['ssl_key'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_KEY] = $settings['ssl_key'];
|
||||
}
|
||||
|
||||
if (! empty($settings['ssl_cert'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_CERT] = $settings['ssl_cert'];
|
||||
}
|
||||
|
||||
if (! empty($settings['ssl_ca'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_CA] = $settings['ssl_ca'];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +183,7 @@ class Mysql extends Base
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS `".$this->schemaTable."` (`version` INT DEFAULT '0')");
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS `".$this->schemaTable."` (`version` INT DEFAULT '0') ENGINE=InnoDB CHARSET=utf8");
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT `version` FROM `'.$this->schemaTable.'`');
|
||||
$rq->execute();
|
||||
|
@ -8,7 +8,8 @@ use PDOException;
|
||||
/**
|
||||
* Postgres Driver
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Postgres extends Base
|
||||
{
|
||||
@ -18,7 +19,7 @@ class Postgres extends Base
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAtttributes = array(
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
@ -169,4 +170,27 @@ class Postgres extends Base
|
||||
$rq = $this->pdo->prepare('UPDATE '.$this->schemaTable.' SET version=?');
|
||||
$rq->execute(array($version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN (FORMAT YAML) '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SHOW server_version')->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ use PDOException;
|
||||
/**
|
||||
* Sqlite Driver
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Sqlite extends Base
|
||||
{
|
||||
@ -18,7 +19,7 @@ class Sqlite extends Base
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAtttributes = array('filename');
|
||||
protected $requiredAttributes = array('filename');
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
@ -161,8 +162,32 @@ class Sqlite extends Base
|
||||
return true;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->pdo->rollback();
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN QUERY PLAN '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SELECT sqlite_version()')->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
45
vendor/fguillot/picodb/lib/PicoDb/DriverFactory.php
vendored
Normal file
45
vendor/fguillot/picodb/lib/PicoDb/DriverFactory.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use LogicException;
|
||||
use PicoDb\Driver\Mssql;
|
||||
use PicoDb\Driver\Mysql;
|
||||
use PicoDb\Driver\Postgres;
|
||||
use PicoDb\Driver\Sqlite;
|
||||
|
||||
/**
|
||||
* Class DriverFactory
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class DriverFactory
|
||||
{
|
||||
/**
|
||||
* Get database driver from settings or environment URL
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
* @return Mssql|Mysql|Postgres|Sqlite
|
||||
*/
|
||||
public static function getDriver(array $settings)
|
||||
{
|
||||
if (! isset($settings['driver'])) {
|
||||
throw new LogicException('You must define a database driver');
|
||||
}
|
||||
|
||||
switch ($settings['driver']) {
|
||||
case 'sqlite':
|
||||
return new Sqlite($settings);
|
||||
case 'mssql':
|
||||
return new Mssql($settings);
|
||||
case 'mysql':
|
||||
return new Mysql($settings);
|
||||
case 'postgres':
|
||||
return new Postgres($settings);
|
||||
default:
|
||||
throw new LogicException('This database driver is not supported');
|
||||
}
|
||||
}
|
||||
}
|
13
vendor/fguillot/picodb/lib/PicoDb/Hashtable.php
vendored
13
vendor/fguillot/picodb/lib/PicoDb/Hashtable.php
vendored
@ -5,10 +5,11 @@ namespace PicoDb;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Hashtable (key/value)
|
||||
* HashTable (key/value)
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @author Mathias Kresin
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
* @author Mathias Kresin
|
||||
*/
|
||||
class Hashtable extends Table
|
||||
{
|
||||
@ -33,7 +34,7 @@ class Hashtable extends Table
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function columnKey($column)
|
||||
{
|
||||
@ -46,7 +47,7 @@ class Hashtable extends Table
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function columnValue($column)
|
||||
{
|
||||
@ -84,7 +85,7 @@ class Hashtable extends Table
|
||||
// setup to select columns in case that there are more than two
|
||||
$this->columns($this->keyColumn, $this->valueColumn);
|
||||
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->condition->getValues());
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
$rows = $rq->fetchAll(PDO::FETCH_NUM);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
|
167
vendor/fguillot/picodb/lib/PicoDb/LargeObject.php
vendored
Normal file
167
vendor/fguillot/picodb/lib/PicoDb/LargeObject.php
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use PicoDb\Builder\InsertBuilder;
|
||||
use PicoDb\Builder\UpdateBuilder;
|
||||
|
||||
/**
|
||||
* Handle Large Objects (LOBs)
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LargeObject extends Table
|
||||
{
|
||||
/**
|
||||
* Fetch large object as file descriptor
|
||||
*
|
||||
* This method is not compatible with Sqlite and Mysql (return a string instead of resource)
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return resource
|
||||
*/
|
||||
public function findOneColumnAsStream($column)
|
||||
{
|
||||
$this->limit(1);
|
||||
$this->columns($column);
|
||||
|
||||
$rq = $this->db->getStatementHandler()
|
||||
->withSql($this->buildSelectQuery())
|
||||
->withPositionalParams($this->conditionBuilder->getValues())
|
||||
->execute();
|
||||
|
||||
$rq->bindColumn($column, $fd, PDO::PARAM_LOB);
|
||||
$rq->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
return $fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch large object as string
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function findOneColumnAsString($column)
|
||||
{
|
||||
$fd = $this->findOneColumnAsStream($column);
|
||||
|
||||
if (is_string($fd)) {
|
||||
return $fd;
|
||||
}
|
||||
|
||||
return stream_get_contents($fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from stream
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param resource|string $blobDescriptor
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromStream($blobColumn, &$blobDescriptor, array $data = array())
|
||||
{
|
||||
$columns = array_merge(array($blobColumn), array_keys($data));
|
||||
$this->db->startTransaction();
|
||||
|
||||
$result = $this->db->getStatementHandler()
|
||||
->withSql(InsertBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns($columns)
|
||||
->build()
|
||||
)
|
||||
->withNamedParams($data)
|
||||
->withLobParam($blobColumn, $blobDescriptor)
|
||||
->execute();
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from file
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $filename
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromFile($blobColumn, $filename, array $data = array())
|
||||
{
|
||||
$fp = fopen($filename, 'rb');
|
||||
$result = $this->insertFromStream($blobColumn, $fp, $data);
|
||||
fclose($fp);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from string
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $blobData
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromString($blobColumn, &$blobData, array $data = array())
|
||||
{
|
||||
return $this->insertFromStream($blobColumn, $blobData, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update large object from stream
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param resource $blobDescriptor
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function updateFromStream($blobColumn, &$blobDescriptor, array $data = array())
|
||||
{
|
||||
$values = array_merge(array_values($data), $this->conditionBuilder->getValues());
|
||||
$columns = array_merge(array($blobColumn), array_keys($data));
|
||||
|
||||
$this->db->startTransaction();
|
||||
|
||||
$result = $this->db->getStatementHandler()
|
||||
->withSql(UpdateBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns($columns)
|
||||
->build()
|
||||
)
|
||||
->withPositionalParams($values)
|
||||
->withLobParam($blobColumn, $blobDescriptor)
|
||||
->execute();
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update large object from file
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $filename
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function updateFromFile($blobColumn, $filename, array $data = array())
|
||||
{
|
||||
$fp = fopen($filename, 'r');
|
||||
$result = $this->updateFromStream($blobColumn, $fp, $data);
|
||||
fclose($fp);
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -7,7 +7,8 @@ use Exception;
|
||||
/**
|
||||
* SQLException
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SQLException extends Exception
|
||||
{
|
||||
|
57
vendor/fguillot/picodb/lib/PicoDb/Schema.php
vendored
57
vendor/fguillot/picodb/lib/PicoDb/Schema.php
vendored
@ -7,7 +7,8 @@ use PDOException;
|
||||
/**
|
||||
* Schema migration class
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Schema
|
||||
{
|
||||
@ -19,6 +20,14 @@ class Schema
|
||||
*/
|
||||
protected $db = null;
|
||||
|
||||
/**
|
||||
* Schema namespace
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\Schema';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -30,6 +39,30 @@ class Schema
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set another namespace
|
||||
*
|
||||
* @access public
|
||||
* @param string $namespace
|
||||
* @return Schema
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schema namespace
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the schema version and run the migrations
|
||||
*
|
||||
@ -59,25 +92,23 @@ class Schema
|
||||
public function migrateTo($current_version, $next_version)
|
||||
{
|
||||
try {
|
||||
|
||||
$this->db->startTransaction();
|
||||
$this->db->getDriver()->disableForeignKeys();
|
||||
|
||||
for ($i = $current_version + 1; $i <= $next_version; $i++) {
|
||||
$this->db->startTransaction();
|
||||
$this->db->getDriver()->disableForeignKeys();
|
||||
|
||||
$function_name = '\Schema\version_'.$i;
|
||||
$function_name = $this->getNamespace().'\version_'.$i;
|
||||
|
||||
if (function_exists($function_name)) {
|
||||
$this->db->setLogMessage('Running migration '.$function_name);
|
||||
call_user_func($function_name, $this->db->getConnection());
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->getDriver()->setSchemaVersion($i - 1);
|
||||
$this->db->getDriver()->enableForeignKeys();
|
||||
$this->db->closeTransaction();
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->db->setLogMessage($function_name.' => '.$e->getMessage());
|
||||
$this->db->getDriver()->setSchemaVersion($i);
|
||||
$this->db->getDriver()->enableForeignKeys();
|
||||
$this->db->closeTransaction();
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$this->db->setLogMessage($e->getMessage());
|
||||
$this->db->cancelTransaction();
|
||||
$this->db->getDriver()->enableForeignKeys();
|
||||
return false;
|
||||
|
353
vendor/fguillot/picodb/lib/PicoDb/StatementHandler.php
vendored
Normal file
353
vendor/fguillot/picodb/lib/PicoDb/StatementHandler.php
vendored
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'.($this->logQueries ? ': '.$e->getMessage() : ''));
|
||||
}
|
||||
}
|
252
vendor/fguillot/picodb/lib/PicoDb/Table.php
vendored
252
vendor/fguillot/picodb/lib/PicoDb/Table.php
vendored
@ -4,27 +4,37 @@ namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use Closure;
|
||||
use PicoDb\Builder\ConditionBuilder;
|
||||
use PicoDb\Builder\InsertBuilder;
|
||||
use PicoDb\Builder\UpdateBuilder;
|
||||
|
||||
/**
|
||||
* Table
|
||||
*
|
||||
* @author Frederic Guillot
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @method Table addCondition($sql)
|
||||
* @method Table beginOr()
|
||||
* @method Table closeOr()
|
||||
* @method Table eq($column, $value)
|
||||
* @method Table neq($column, $value)
|
||||
* @method Table in($column, array $values)
|
||||
* @method Table notin($column, array $values)
|
||||
* @method Table like($column, $value)
|
||||
* @method Table ilike($column, $value)
|
||||
* @method Table gt($column, $value)
|
||||
* @method Table lt($column, $value)
|
||||
* @method Table gte($column, $value)
|
||||
* @method Table lte($column, $value)
|
||||
* @method Table isNull($column)
|
||||
* @method Table notNull($column)
|
||||
* @method $this addCondition($sql)
|
||||
* @method $this beginOr()
|
||||
* @method $this closeOr()
|
||||
* @method $this eq($column, $value)
|
||||
* @method $this neq($column, $value)
|
||||
* @method $this in($column, array $values)
|
||||
* @method $this inSubquery($column, Table $subquery)
|
||||
* @method $this notIn($column, array $values)
|
||||
* @method $this notInSubquery($column, Table $subquery)
|
||||
* @method $this like($column, $value)
|
||||
* @method $this ilike($column, $value)
|
||||
* @method $this gt($column, $value)
|
||||
* @method $this gtSubquery($column, Table $subquery)
|
||||
* @method $this lt($column, $value)
|
||||
* @method $this ltSubquery($column, Table $subquery)
|
||||
* @method $this gte($column, $value)
|
||||
* @method $this gteSubquery($column, Table $subquery)
|
||||
* @method $this lte($column, $value)
|
||||
* @method $this lteSubquery($column, Table $subquery)
|
||||
* @method $this isNull($column)
|
||||
* @method $this notNull($column)
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
@ -40,10 +50,10 @@ class Table
|
||||
/**
|
||||
* Condition instance
|
||||
*
|
||||
* @access public
|
||||
* @var Condition
|
||||
* @access protected
|
||||
* @var ConditionBuilder
|
||||
*/
|
||||
public $condition;
|
||||
protected $conditionBuilder;
|
||||
|
||||
/**
|
||||
* Database instance
|
||||
@ -152,7 +162,7 @@ class Table
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->name = $name;
|
||||
$this->condition = new Condition($db);
|
||||
$this->conditionBuilder = new ConditionBuilder($db);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,6 +176,17 @@ class Table
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ConditionBuilder object
|
||||
*
|
||||
* @access public
|
||||
* @return ConditionBuilder
|
||||
*/
|
||||
public function getConditionBuilder()
|
||||
{
|
||||
return $this->conditionBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update
|
||||
*
|
||||
@ -175,47 +196,24 @@ class Table
|
||||
*/
|
||||
public function save(array $data)
|
||||
{
|
||||
return $this->condition->hasCondition() ? $this->update($data) : $this->insert($data);
|
||||
return $this->conditionBuilder->hasCondition() ? $this->update($data) : $this->insert($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
*
|
||||
* Note: Do not use `rowCount()` for update the behaviour is different across drivers
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(array $data = array())
|
||||
{
|
||||
$columns = array();
|
||||
$values = array();
|
||||
|
||||
// Split columns and values
|
||||
foreach ($data as $column => $value) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'=?';
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
// Sum columns
|
||||
foreach ($this->sumColumns as $column => $value) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'='.$this->db->escapeIdentifier($column).' + ?';
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
// Append condition values
|
||||
foreach ($this->condition->getValues() as $value) {
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
// Build SQL query
|
||||
$sql = sprintf(
|
||||
'UPDATE %s SET %s %s',
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
implode(', ', $columns),
|
||||
$this->condition->build()
|
||||
);
|
||||
$values = array_merge(array_values($data), array_values($this->sumColumns), $this->conditionBuilder->getValues());
|
||||
$sql = UpdateBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns(array_keys($data))
|
||||
->withSumColumns(array_keys($this->sumColumns))
|
||||
->build();
|
||||
|
||||
return $this->db->execute($sql, $values) !== false;
|
||||
}
|
||||
@ -229,20 +227,30 @@ class Table
|
||||
*/
|
||||
public function insert(array $data)
|
||||
{
|
||||
$columns = array();
|
||||
return $this->db->getStatementHandler()
|
||||
->withSql(InsertBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns(array_keys($data))
|
||||
->build()
|
||||
)
|
||||
->withNamedParams($data)
|
||||
->execute() !== false;
|
||||
}
|
||||
|
||||
foreach ($data as $column => $value) {
|
||||
$columns[] = $this->db->escapeIdentifier($column);
|
||||
/**
|
||||
* Insert a new row and return the ID of the primary key
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return bool|int
|
||||
*/
|
||||
public function persist(array $data)
|
||||
{
|
||||
if ($this->insert($data)) {
|
||||
return $this->db->getLastId();
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'INSERT INTO %s (%s) VALUES (%s)',
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
implode(', ', $columns),
|
||||
implode(', ', array_fill(0, count($data), '?'))
|
||||
);
|
||||
|
||||
return $this->db->execute($sql, array_values($data)) !== false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,10 +264,10 @@ class Table
|
||||
$sql = sprintf(
|
||||
'DELETE FROM %s %s',
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->condition->build()
|
||||
$this->conditionBuilder->build()
|
||||
);
|
||||
|
||||
$result = $this->db->execute($sql, $this->condition->getValues());
|
||||
$result = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
return $result->rowCount() > 0;
|
||||
}
|
||||
|
||||
@ -271,7 +279,7 @@ class Table
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->condition->getValues());
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
$results = $rq->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (is_callable($this->callback) && ! empty($results)) {
|
||||
@ -291,7 +299,7 @@ class Table
|
||||
public function findAllByColumn($column)
|
||||
{
|
||||
$this->columns = array($column);
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->condition->getValues());
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
|
||||
return $rq->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
}
|
||||
@ -322,7 +330,7 @@ class Table
|
||||
$this->limit(1);
|
||||
$this->columns = array($column);
|
||||
|
||||
return $this->db->execute($this->buildSelectQuery(), $this->condition->getValues())->fetchColumn();
|
||||
return $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues())->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -331,7 +339,7 @@ class Table
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param string $alias
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function subquery($sql, $alias)
|
||||
{
|
||||
@ -348,11 +356,11 @@ class Table
|
||||
public function exists()
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT 1 FROM %s '.implode(' ', $this->joins).$this->condition->build(),
|
||||
'SELECT 1 FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->condition->getValues());
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? true : false;
|
||||
@ -367,11 +375,11 @@ class Table
|
||||
public function count()
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT COUNT(*) FROM %s '.implode(' ', $this->joins).$this->condition->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
'SELECT COUNT(*) FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->condition->getValues());
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? (int) $result : 0;
|
||||
@ -387,17 +395,59 @@ class Table
|
||||
public function sum($column)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT SUM(%s) FROM %s '.implode(' ', $this->joins).$this->condition->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
'SELECT SUM(%s) FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->condition->getValues());
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? (float) $result : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment column value
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($column, $value)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'UPDATE %s SET %s=%s+%d '.$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$value
|
||||
);
|
||||
|
||||
return $this->db->execute($sql, $this->conditionBuilder->getValues()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement column value
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($column, $value)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'UPDATE %s SET %s=%s-%d '.$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$value
|
||||
);
|
||||
|
||||
return $this->db->execute($sql, $this->conditionBuilder->getValues()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left join
|
||||
*
|
||||
@ -407,7 +457,7 @@ class Table
|
||||
* @param string $local_column Local column
|
||||
* @param string $local_table Local table
|
||||
* @param string $alias Join table alias
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function join($table, $foreign_column, $local_column, $local_table = '', $alias = '')
|
||||
{
|
||||
@ -430,7 +480,7 @@ class Table
|
||||
* @param string $column1
|
||||
* @param string $table2
|
||||
* @param string $column2
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function left($table1, $alias1, $column1, $table2, $column2)
|
||||
{
|
||||
@ -445,13 +495,37 @@ class Table
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner join
|
||||
*
|
||||
* @access public
|
||||
* @param string $table1
|
||||
* @param string $alias1
|
||||
* @param string $column1
|
||||
* @param string $table2
|
||||
* @param string $column2
|
||||
* @return $this
|
||||
*/
|
||||
public function inner($table1, $alias1, $column1, $table2, $column2)
|
||||
{
|
||||
$this->joins[] = sprintf(
|
||||
'JOIN %s AS %s ON %s=%s',
|
||||
$this->db->escapeIdentifier($table1),
|
||||
$this->db->escapeIdentifier($alias1),
|
||||
$this->db->escapeIdentifier($alias1).'.'.$this->db->escapeIdentifier($column1),
|
||||
$this->db->escapeIdentifier($table2).'.'.$this->db->escapeIdentifier($column2)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order by
|
||||
*
|
||||
* @access public
|
||||
* @param string $column Column name
|
||||
* @param string $order Direction ASC or DESC
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function orderBy($column, $order = self::SORT_ASC)
|
||||
{
|
||||
@ -473,7 +547,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function asc($column)
|
||||
{
|
||||
@ -486,7 +560,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function desc($column)
|
||||
{
|
||||
@ -499,7 +573,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param integer $value
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($value)
|
||||
{
|
||||
@ -515,7 +589,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param integer $value
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function offset($value)
|
||||
{
|
||||
@ -530,7 +604,7 @@ class Table
|
||||
* Group by
|
||||
*
|
||||
* @access public
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function groupBy()
|
||||
{
|
||||
@ -543,7 +617,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param string $select
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function select($select)
|
||||
{
|
||||
@ -555,7 +629,7 @@ class Table
|
||||
* Define the columns for the select
|
||||
*
|
||||
* @access public
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function columns()
|
||||
{
|
||||
@ -569,7 +643,7 @@ class Table
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function sumColumn($column, $value)
|
||||
{
|
||||
@ -581,7 +655,7 @@ class Table
|
||||
* Distinct
|
||||
*
|
||||
* @access public
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function distinct()
|
||||
{
|
||||
@ -595,7 +669,7 @@ class Table
|
||||
*
|
||||
* @access public
|
||||
* @param Closure|array $callback
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function callback($callback)
|
||||
{
|
||||
@ -623,7 +697,7 @@ class Table
|
||||
$this->sqlSelect,
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
implode(' ', $this->joins),
|
||||
$this->condition->build(),
|
||||
$this->conditionBuilder->build(),
|
||||
empty($this->groupBy) ? '' : 'GROUP BY '.implode(', ', $this->groupBy),
|
||||
$this->sqlOrder,
|
||||
$this->sqlLimit,
|
||||
@ -637,11 +711,11 @@ class Table
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return Table
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, array $arguments)
|
||||
{
|
||||
call_user_func_array(array($this->condition, $name), $arguments);
|
||||
call_user_func_array(array($this->conditionBuilder, $name), $arguments);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
93
vendor/fguillot/picodb/lib/PicoDb/UrlParser.php
vendored
Normal file
93
vendor/fguillot/picodb/lib/PicoDb/UrlParser.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
/**
|
||||
* Class UrlParser
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UrlParser
|
||||
{
|
||||
/**
|
||||
* URL
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $environmentVariable
|
||||
*/
|
||||
public function __construct($environmentVariable = 'DATABASE_URL')
|
||||
{
|
||||
$this->url = getenv($environmentVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object instance
|
||||
*
|
||||
* @access public
|
||||
* @param string $environmentVariable
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance($environmentVariable = 'DATABASE_URL')
|
||||
{
|
||||
return new static($environmentVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the variable is defined
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnvironmentVariableDefined()
|
||||
{
|
||||
return ! empty($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings from URL
|
||||
*
|
||||
* @access public
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings($url = '')
|
||||
{
|
||||
$url = $url ?: $this->url;
|
||||
$components = parse_url($url);
|
||||
|
||||
if ($components === false) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array(
|
||||
'driver' => $this->getUrlComponent($components, 'scheme'),
|
||||
'username' => $this->getUrlComponent($components, 'user'),
|
||||
'password' => $this->getUrlComponent($components, 'pass'),
|
||||
'hostname' => $this->getUrlComponent($components, 'host'),
|
||||
'port' => $this->getUrlComponent($components, 'port'),
|
||||
'database' => ltrim($this->getUrlComponent($components, 'path'), '/'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL component
|
||||
*
|
||||
* @access private
|
||||
* @param array $components
|
||||
* @param string $component
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function getUrlComponent(array $components, $component)
|
||||
{
|
||||
return ! empty($components[$component]) ? $components[$component] : null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user