Initial commit
This commit is contained in:
@@ -0,0 +1,545 @@
|
||||
<?php namespace FluentMail\App\Services\DB\QueryBuilder\Adapters;
|
||||
|
||||
use FluentMail\App\Services\DB\Connection;
|
||||
use FluentMail\App\Services\DB\Exception;
|
||||
use FluentMail\App\Services\DB\QueryBuilder\Raw;
|
||||
|
||||
abstract class BaseAdapter
|
||||
{
|
||||
/**
|
||||
* @var \FluentMail\App\Services\DB\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var \FluentMail\App\Services\DB\Viocon\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->container = $this->connection->getContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build select query string and bindings
|
||||
*
|
||||
* @param $statements
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
public function select($statements)
|
||||
{
|
||||
if (! array_key_exists('tables', $statements)) {
|
||||
throw new Exception('No table specified.', 3);
|
||||
} elseif (! array_key_exists('selects', $statements)) {
|
||||
$statements['selects'][] = '*';
|
||||
}
|
||||
|
||||
// From
|
||||
$tables = $this->arrayStr($statements['tables'], ', ');
|
||||
// Select
|
||||
$selects = $this->arrayStr($statements['selects'], ', ');
|
||||
|
||||
|
||||
// Wheres
|
||||
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
|
||||
// Group bys
|
||||
$groupBys = '';
|
||||
if (isset($statements['groupBys']) && $groupBys = $this->arrayStr($statements['groupBys'], ', ')) {
|
||||
$groupBys = 'GROUP BY ' . $groupBys;
|
||||
}
|
||||
|
||||
// Order bys
|
||||
$orderBys = '';
|
||||
if (isset($statements['orderBys']) && is_array($statements['orderBys'])) {
|
||||
foreach ($statements['orderBys'] as $orderBy) {
|
||||
$orderBys .= $this->wrapSanitizer($orderBy['field']) . ' ' . $orderBy['type'] . ', ';
|
||||
}
|
||||
|
||||
if ($orderBys = trim($orderBys, ', ')) {
|
||||
$orderBys = 'ORDER BY ' . $orderBys;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit and offset
|
||||
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
|
||||
$offset = isset($statements['offset']) ? 'OFFSET ' . $statements['offset'] : '';
|
||||
|
||||
// Having
|
||||
list($havingCriteria, $havingBindings) = $this->buildCriteriaWithType($statements, 'havings', 'HAVING');
|
||||
|
||||
// Joins
|
||||
$joinString = $this->buildJoin($statements);
|
||||
|
||||
$sqlArray = array(
|
||||
'SELECT' . (isset($statements['distinct']) ? ' DISTINCT' : ''),
|
||||
$selects,
|
||||
'FROM',
|
||||
$tables,
|
||||
$joinString,
|
||||
$whereCriteria,
|
||||
$groupBys,
|
||||
$havingCriteria,
|
||||
$orderBys,
|
||||
$limit,
|
||||
$offset
|
||||
);
|
||||
|
||||
$sql = $this->concatenateQuery($sqlArray);
|
||||
|
||||
$bindings = array_merge(
|
||||
$whereBindings,
|
||||
$havingBindings
|
||||
);
|
||||
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build just criteria part of the query
|
||||
*
|
||||
* @param $statements
|
||||
* @param bool $bindValues
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function criteriaOnly($statements, $bindValues = true)
|
||||
{
|
||||
$sql = $bindings = array();
|
||||
|
||||
if (! isset($statements['criteria'])) {
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
list($sql, $bindings) = $this->buildCriteria($statements['criteria'], $bindValues);
|
||||
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a generic insert/ignore/replace query
|
||||
*
|
||||
* @param $statements
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
private function doInsert($statements, array $data, $type)
|
||||
{
|
||||
if (! isset($statements['tables'])) {
|
||||
throw new Exception('No table specified', 3);
|
||||
}
|
||||
|
||||
$table = end($statements['tables']);
|
||||
|
||||
$bindings = $keys = $values = array();
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$keys[] = $key;
|
||||
if ($value instanceof Raw) {
|
||||
$values[] = (string) $value;
|
||||
} else {
|
||||
$values[] = '?';
|
||||
$bindings[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$sqlArray = array(
|
||||
$type . ' INTO',
|
||||
$this->wrapSanitizer($table),
|
||||
'(' . $this->arrayStr($keys, ',') . ')',
|
||||
'VALUES',
|
||||
'(' . $this->arrayStr($values, ',', false) . ')',
|
||||
);
|
||||
|
||||
if (isset($statements['onduplicate'])) {
|
||||
if (count($statements['onduplicate']) < 1) {
|
||||
throw new Exception('No data given.', 4);
|
||||
}
|
||||
list($updateStatement, $updateBindings) = $this->getUpdateStatement($statements['onduplicate']);
|
||||
$sqlArray[] = 'ON DUPLICATE KEY UPDATE ' . $updateStatement;
|
||||
$bindings = array_merge($bindings, $updateBindings);
|
||||
}
|
||||
|
||||
$sql = $this->concatenateQuery($sqlArray);
|
||||
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Insert query
|
||||
*
|
||||
* @param $statements
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
public function insert($statements, array $data)
|
||||
{
|
||||
return $this->doInsert($statements, $data, 'INSERT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Insert Ignore query
|
||||
*
|
||||
* @param $statements
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
public function insertIgnore($statements, array $data)
|
||||
{
|
||||
return $this->doInsert($statements, $data, 'INSERT IGNORE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Insert Ignore query
|
||||
*
|
||||
* @param $statements
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
public function replace($statements, array $data)
|
||||
{
|
||||
return $this->doInsert($statements, $data, 'REPLACE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build fields assignment part of SET ... or ON DUBLICATE KEY UPDATE ... statements
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getUpdateStatement($data)
|
||||
{
|
||||
$bindings = array();
|
||||
$statement = '';
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if ($value instanceof Raw) {
|
||||
$statement .= $this->wrapSanitizer($key) . '=' . $value . ',';
|
||||
} else {
|
||||
$statement .= $this->wrapSanitizer($key) . '=?,';
|
||||
$bindings[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$statement = trim($statement, ',');
|
||||
|
||||
return array($statement, $bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build update query
|
||||
*
|
||||
* @param $statements
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\Exception
|
||||
*/
|
||||
public function update($statements, array $data)
|
||||
{
|
||||
if (! isset($statements['tables'])) {
|
||||
throw new Exception('No table specified', 3);
|
||||
} elseif (count($data) < 1) {
|
||||
throw new Exception('No data given.', 4);
|
||||
}
|
||||
|
||||
$table = end($statements['tables']);
|
||||
|
||||
// Update statement
|
||||
list($updateStatement, $bindings) = $this->getUpdateStatement($data);
|
||||
|
||||
// Wheres
|
||||
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
|
||||
|
||||
// Limit
|
||||
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
|
||||
|
||||
$sqlArray = array(
|
||||
'UPDATE',
|
||||
$this->wrapSanitizer($table),
|
||||
'SET ' . $updateStatement,
|
||||
$whereCriteria,
|
||||
$limit
|
||||
);
|
||||
|
||||
$sql = $this->concatenateQuery($sqlArray);
|
||||
|
||||
$bindings = array_merge($bindings, $whereBindings);
|
||||
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build delete query
|
||||
*
|
||||
* @param $statements
|
||||
*
|
||||
* @return array
|
||||
* @throws \FluentMail\App\Services\DB\src\Exception
|
||||
*/
|
||||
public function delete($statements)
|
||||
{
|
||||
if (! isset($statements['tables'])) {
|
||||
throw new Exception('No table specified', 3);
|
||||
}
|
||||
|
||||
$table = end($statements['tables']);
|
||||
|
||||
// Wheres
|
||||
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
|
||||
|
||||
// Limit
|
||||
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
|
||||
|
||||
$sqlArray = array('DELETE FROM', $this->wrapSanitizer($table), $whereCriteria);
|
||||
$sql = $this->concatenateQuery($sqlArray);
|
||||
$bindings = $whereBindings;
|
||||
|
||||
return compact('sql', 'bindings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Array concatenating method, like implode.
|
||||
* But it does wrap sanitizer and trims last glue
|
||||
*
|
||||
* @param array $pieces
|
||||
* @param $glue
|
||||
* @param bool $wrapSanitizer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function arrayStr(array $pieces, $glue, $wrapSanitizer = true)
|
||||
{
|
||||
$str = '';
|
||||
|
||||
foreach ($pieces as $key => $piece) {
|
||||
if ($wrapSanitizer) {
|
||||
$piece = $this->wrapSanitizer($piece);
|
||||
}
|
||||
|
||||
if (! is_int($key)) {
|
||||
$piece = ($wrapSanitizer ? $this->wrapSanitizer($key) : $key) . ' AS ' . $piece;
|
||||
}
|
||||
|
||||
$str .= $piece . $glue;
|
||||
}
|
||||
|
||||
return trim($str, $glue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join different part of queries with a space.
|
||||
*
|
||||
* @param array $pieces
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function concatenateQuery(array $pieces)
|
||||
{
|
||||
$str = '';
|
||||
|
||||
foreach ($pieces as $piece) {
|
||||
$str = trim($str) . ' ' . trim($piece);
|
||||
}
|
||||
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build generic criteria string and bindings from statements, like "a = b and c = ?"
|
||||
*
|
||||
* @param $statements
|
||||
* @param bool $bindValues
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildCriteria($statements, $bindValues = true)
|
||||
{
|
||||
$criteria = '';
|
||||
$bindings = array();
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
$key = $this->wrapSanitizer($statement['key']);
|
||||
$value = $statement['value'];
|
||||
|
||||
if (is_null($value) && $key instanceof \Closure) {
|
||||
// We have a closure, a nested criteria
|
||||
|
||||
// Build a new NestedCriteria class, keep it by reference so any changes made
|
||||
// in the closure should reflect here
|
||||
$nestedCriteria = $this->container->build(
|
||||
'\\FluentMail\\App\\Services\\DB\\QueryBuilder\\NestedCriteria',
|
||||
array($this->connection)
|
||||
);
|
||||
|
||||
$nestedCriteria = & $nestedCriteria;
|
||||
// Call the closure with our new nestedCriteria object
|
||||
$key($nestedCriteria);
|
||||
// Get the criteria only query from the nestedCriteria object
|
||||
$queryObject = $nestedCriteria->getQuery('criteriaOnly', true);
|
||||
// Merge the bindings we get from nestedCriteria object
|
||||
$bindings = array_merge($bindings, $queryObject->getBindings());
|
||||
// Append the sql we get from the nestedCriteria object
|
||||
$criteria .= $statement['joiner'] . ' (' . $queryObject->getSql() . ') ';
|
||||
} elseif (is_array($value)) {
|
||||
// where_in or between like query
|
||||
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'];
|
||||
|
||||
switch ($statement['operator']) {
|
||||
case 'BETWEEN':
|
||||
$bindings = array_merge($bindings, $statement['value']);
|
||||
$criteria .= ' ? AND ? ';
|
||||
break;
|
||||
default:
|
||||
$valuePlaceholder = '';
|
||||
foreach ($statement['value'] as $subValue) {
|
||||
$valuePlaceholder .= '?, ';
|
||||
$bindings[] = $subValue;
|
||||
}
|
||||
|
||||
$valuePlaceholder = trim($valuePlaceholder, ', ');
|
||||
$criteria .= ' (' . $valuePlaceholder . ') ';
|
||||
break;
|
||||
}
|
||||
} elseif ($value instanceof Raw) {
|
||||
$criteria .= "{$statement['joiner']} {$key} {$statement['operator']} $value ";
|
||||
} else {
|
||||
// Usual where like criteria
|
||||
|
||||
if (! $bindValues) {
|
||||
// Specially for joins
|
||||
|
||||
// We are not binding values, lets sanitize then
|
||||
$value = $this->wrapSanitizer($value);
|
||||
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'] . ' ' . $value . ' ';
|
||||
} elseif ($statement['key'] instanceof Raw) {
|
||||
$criteria .= $statement['joiner'] . ' ' . $key . ' ';
|
||||
$bindings = array_merge($bindings, $statement['key']->getBindings());
|
||||
} else {
|
||||
// For wheres
|
||||
|
||||
$valuePlaceholder = '?';
|
||||
$bindings[] = $value;
|
||||
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'] . ' '
|
||||
. $valuePlaceholder . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all white spaces, and, or from beginning and white spaces from ending
|
||||
$criteria = preg_replace('/^(\s?AND ?|\s?OR ?)|\s$/i', '', $criteria);
|
||||
|
||||
return array($criteria, $bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap values with adapter's sanitizer like, '`'
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function wrapSanitizer($value)
|
||||
{
|
||||
// Its a raw query, just cast as string, object has __toString()
|
||||
if ($value instanceof Raw) {
|
||||
return (string) $value;
|
||||
} elseif ($value instanceof \Closure) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Separate our table and fields which are joined with a ".",
|
||||
// like my_table.id
|
||||
$valueArr = explode('.', $value, 2);
|
||||
|
||||
foreach ($valueArr as $key => $subValue) {
|
||||
// Don't wrap if we have *, which is not a usual field
|
||||
$valueArr[$key] = trim($subValue) == '*' ? $subValue : $this->sanitizer . $subValue . $this->sanitizer;
|
||||
}
|
||||
|
||||
// Join these back with "." and return
|
||||
return implode('.', $valueArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build criteria string and binding with various types added, like WHERE and Having
|
||||
*
|
||||
* @param $statements
|
||||
* @param $key
|
||||
* @param $type
|
||||
* @param bool $bindValues
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildCriteriaWithType($statements, $key, $type, $bindValues = true)
|
||||
{
|
||||
$criteria = '';
|
||||
$bindings = array();
|
||||
|
||||
if (isset($statements[$key])) {
|
||||
// Get the generic/adapter agnostic criteria string from parent
|
||||
list($criteria, $bindings) = $this->buildCriteria($statements[$key], $bindValues);
|
||||
|
||||
if ($criteria) {
|
||||
$criteria = $type . ' ' . $criteria;
|
||||
}
|
||||
}
|
||||
|
||||
return array($criteria, $bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build join string
|
||||
*
|
||||
* @param $statements
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
protected function buildJoin($statements)
|
||||
{
|
||||
$sql = '';
|
||||
|
||||
if (! array_key_exists('joins', $statements) || ! is_array($statements['joins'])) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
foreach ($statements['joins'] as $joinArr) {
|
||||
if (is_array($joinArr['table'])) {
|
||||
$mainTable = $joinArr['table'][0];
|
||||
$aliasTable = $joinArr['table'][1];
|
||||
$table = $this->wrapSanitizer($mainTable) . ' AS ' . $this->wrapSanitizer($aliasTable);
|
||||
} else {
|
||||
$table = $joinArr['table'] instanceof Raw ?
|
||||
(string) $joinArr['table'] :
|
||||
$this->wrapSanitizer($joinArr['table']);
|
||||
}
|
||||
|
||||
$joinBuilder = $joinArr['joinBuilder'];
|
||||
|
||||
$sqlArr = array(
|
||||
$sql,
|
||||
strtoupper($joinArr['type']),
|
||||
'JOIN',
|
||||
$table,
|
||||
'ON',
|
||||
$joinBuilder->getQuery('criteriaOnly', false)->getSql()
|
||||
);
|
||||
|
||||
$sql = $this->concatenateQuery($sqlArr);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace FluentMail\App\Services\DB\QueryBuilder\Adapters;
|
||||
|
||||
class Mysql extends BaseAdapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sanitizer = '`';
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class JoinBuilder extends QueryBuilderHandler
|
||||
{
|
||||
/**
|
||||
* @param $key
|
||||
* @param $operator
|
||||
* @param $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function on($key, $operator, $value)
|
||||
{
|
||||
return $this->joinHandler($key, $operator, $value, 'AND');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $operator
|
||||
* @param $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function orOn($key, $operator, $value)
|
||||
{
|
||||
return $this->joinHandler($key, $operator, $value, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $operator
|
||||
* @param null $value
|
||||
* @param string $joiner
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function joinHandler($key, $operator = null, $value = null, $joiner = 'AND')
|
||||
{
|
||||
$key = $this->addTablePrefix($key);
|
||||
$value = $this->addTablePrefix($value);
|
||||
$this->statements['criteria'][] = compact('key', 'operator', 'value', 'joiner');
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class NestedCriteria extends QueryBuilderHandler
|
||||
{
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $operator
|
||||
* @param null $value
|
||||
* @param string $joiner
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND')
|
||||
{
|
||||
$key = $this->addTablePrefix($key);
|
||||
$this->statements['criteria'][] = compact('key', 'operator', 'value', 'joiner');
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class QueryObject
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql;
|
||||
|
||||
/**
|
||||
* @var \wpdb
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $bindings = array();
|
||||
|
||||
public function __construct($sql, array $bindings)
|
||||
{
|
||||
$this->sql = (string) $sql;
|
||||
|
||||
$this->bindings = $bindings;
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$this->db = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSql()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getBindings()
|
||||
{
|
||||
return $this->bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw/bound sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawSql()
|
||||
{
|
||||
return $this->interpolateQuery($this->sql, $this->bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces any parameter placeholders in a query with the value of that
|
||||
* parameter. Useful for debugging. Assumes anonymous parameters from
|
||||
* $params are are in the same order as specified in $query
|
||||
*
|
||||
* Reference: http://stackoverflow.com/a/1376838/656489
|
||||
*
|
||||
* @param string $query The sql query with parameter placeholders
|
||||
* @param array $params The array of substitution parameters
|
||||
*
|
||||
* @return string The interpolated query
|
||||
*/
|
||||
protected function interpolateQuery($query, $params)
|
||||
{
|
||||
$keys = $placeHolders = [];
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (is_string($key)) {
|
||||
$keys[] = '/:' . $key . '/';
|
||||
} else {
|
||||
$keys[] = '/[?]/';
|
||||
}
|
||||
|
||||
$placeHolders[] = $this->getPlaceHolder($value);
|
||||
}
|
||||
|
||||
$query = preg_replace($keys, $placeHolders, $query, 1, $count);
|
||||
|
||||
return $params ? $this->db->prepare($query, $params) : $query;
|
||||
}
|
||||
|
||||
private function getPlaceHolder($value)
|
||||
{
|
||||
$placeHolder = '%s';
|
||||
|
||||
if (is_int($value)) {
|
||||
$placeHolder = '%d';
|
||||
} elseif (is_float($value)) {
|
||||
$placeHolder = '%f';
|
||||
}
|
||||
|
||||
return $placeHolder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class Raw
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $bindings;
|
||||
|
||||
public function __construct($value, $bindings = array())
|
||||
{
|
||||
$this->value = (string)$value;
|
||||
$this->bindings = (array)$bindings;
|
||||
}
|
||||
|
||||
public function getBindings()
|
||||
{
|
||||
return $this->bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class Transaction extends QueryBuilderHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Commit the database changes
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->db->query('COMMIT');
|
||||
|
||||
throw new TransactionHaltException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the database changes
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->db->query('ROLLBACK');
|
||||
|
||||
throw new TransactionHaltException();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace FluentMail\App\Services\DB\QueryBuilder;
|
||||
|
||||
class TransactionHaltException extends \Exception
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user