Use State class to simplify management of query builder state
This commit is contained in:
parent
8401cceb0d
commit
e4ca039b3d
@ -6,7 +6,7 @@
|
|||||||
bootstrap="./../tests/bootstrap.php">
|
bootstrap="./../tests/bootstrap.php">
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist>
|
<whitelist>
|
||||||
<directory suffix=".php">./../src/*</directory>
|
<directory suffix=".php">./../src/</directory>
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
|
@ -27,119 +27,6 @@ use Query\Drivers\{
|
|||||||
*/
|
*/
|
||||||
class QueryBuilder implements QueryBuilderInterface {
|
class QueryBuilder implements QueryBuilderInterface {
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Constants
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const KEY = 0;
|
|
||||||
const VALUE = 1;
|
|
||||||
const BOTH = 2;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! SQL Clause Strings
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled 'select' clause
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $selectString = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled 'from' clause
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $fromString = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiled arguments for insert / update
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $setString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Order by clause
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $orderString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group by clause
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $groupString;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! SQL Clause Arrays
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keys for insert/update statement
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $setArrayKeys = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key/val pairs for order by clause
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $orderArray = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key/val pairs for group by clause
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $groupArray = [];
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Other Class vars
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Values to apply to prepared statements
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $values = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Values to apply to where clauses in prepared statements
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $whereValues = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value for limit string
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $limit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value for offset in limit string
|
|
||||||
* @var integer
|
|
||||||
*/
|
|
||||||
protected $offset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query component order mapping
|
|
||||||
* for complex select queries
|
|
||||||
*
|
|
||||||
* Format:
|
|
||||||
* array(
|
|
||||||
* 'type' => 'where',
|
|
||||||
* 'conjunction' => ' AND ',
|
|
||||||
* 'string' => 'k=?'
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $queryMap = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map for having clause
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $havingMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience property for connection management
|
* Convenience property for connection management
|
||||||
* @var string
|
* @var string
|
||||||
@ -156,7 +43,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
* Whether to do only an explain on the query
|
* Whether to do only an explain on the query
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $explain;
|
protected $explain = FALSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current database driver
|
* The current database driver
|
||||||
@ -183,35 +70,10 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
protected $sql;
|
protected $sql;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String class values to be reset
|
* Query Builder state
|
||||||
*
|
* @var State
|
||||||
* @var array
|
|
||||||
*/
|
*/
|
||||||
private $stringVars = [
|
protected $state;
|
||||||
'selectString',
|
|
||||||
'fromString',
|
|
||||||
'setString',
|
|
||||||
'orderString',
|
|
||||||
'groupString',
|
|
||||||
'limit',
|
|
||||||
'offset',
|
|
||||||
'explain',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array class variables to be reset
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $arrayVars = [
|
|
||||||
'setArrayKeys',
|
|
||||||
'orderArray',
|
|
||||||
'groupArray',
|
|
||||||
'values',
|
|
||||||
'whereValues',
|
|
||||||
'queryMap',
|
|
||||||
'havingMap'
|
|
||||||
];
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// ! Methods
|
// ! Methods
|
||||||
@ -229,6 +91,9 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$this->driver = $driver;
|
$this->driver = $driver;
|
||||||
$this->parser = $parser;
|
$this->parser = $parser;
|
||||||
|
|
||||||
|
// Create new State object
|
||||||
|
$this->state = new State();
|
||||||
|
|
||||||
$this->queries['total_time'] = 0;
|
$this->queries['total_time'] = 0;
|
||||||
|
|
||||||
// Alias driver sql and util classes
|
// Alias driver sql and util classes
|
||||||
@ -313,9 +178,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->selectString .= implode(', ', $safeArray);
|
$this->state->appendSelectString(implode(', ', $safeArray));
|
||||||
|
|
||||||
unset($safeArray);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -330,7 +193,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
public function selectMax(string $field, $as=FALSE): QueryBuilderInterface
|
public function selectMax(string $field, $as=FALSE): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->selectString .= ' MAX'.$this->_select($field, $as);
|
$this->state->appendSelectString(' MAX'.$this->_select($field, $as));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +207,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
public function selectMin(string $field, $as=FALSE): QueryBuilderInterface
|
public function selectMin(string $field, $as=FALSE): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->selectString .= ' MIN'.$this->_select($field, $as);
|
$this->state->appendSelectString(' MIN'.$this->_select($field, $as));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +221,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
public function selectAvg(string $field, $as=FALSE): QueryBuilderInterface
|
public function selectAvg(string $field, $as=FALSE): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->selectString .= ' AVG'.$this->_select($field, $as);
|
$this->state->appendSelectString(' AVG'.$this->_select($field, $as));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +235,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
public function selectSum(string $field, $as=FALSE): QueryBuilderInterface
|
public function selectSum(string $field, $as=FALSE): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->selectString .= ' SUM'.$this->_select($field, $as);
|
$this->state->appendSelectString(' SUM'.$this->_select($field, $as));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +247,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
public function distinct(): QueryBuilderInterface
|
public function distinct(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
// Prepend the keyword to the select string
|
// Prepend the keyword to the select string
|
||||||
$this->selectString = ' DISTINCT '.$this->selectString;
|
$this->state->setSelectString(' DISTINCT' . $this->state->getSelectString());
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +279,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$identArray = $this->driver->quoteIdent($identArray);
|
$identArray = $this->driver->quoteIdent($identArray);
|
||||||
|
|
||||||
// Paste it back together
|
// Paste it back together
|
||||||
$this->fromString = implode(' ', $identArray);
|
$this->state->setFromString(implode(' ', $identArray));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -435,7 +298,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function like($field, $val, $pos='both'): QueryBuilderInterface
|
public function like($field, $val, $pos='both'): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
return $this->_like($field, $val, $pos, 'LIKE', 'AND');
|
return $this->_like($field, $val, $pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -521,7 +384,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function where($key, $val=[], $escape=NULL): QueryBuilderInterface
|
public function where($key, $val=[], $escape=NULL): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
return $this->_whereString($key, $val, 'AND');
|
return $this->_whereString($key, $val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -597,16 +460,32 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function set($key, $val = NULL): QueryBuilderInterface
|
public function set($key, $val = NULL): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$this->_mixedSet($this->setArrayKeys, $key, $val, self::KEY);
|
if (is_scalar($key))
|
||||||
$this->_mixedSet($this->values, $key, $val, self::VALUE);
|
{
|
||||||
|
$pairs = [$key => $val];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$pairs = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$keys = array_keys($pairs);
|
||||||
|
$values = array_values($pairs);
|
||||||
|
|
||||||
|
$this->state->appendSetArrayKeys($keys);
|
||||||
|
$this->state->appendValues($values);
|
||||||
|
|
||||||
// Use the keys of the array to make the insert/update string
|
// Use the keys of the array to make the insert/update string
|
||||||
// Escape the field names
|
// Escape the field names
|
||||||
$this->setArrayKeys = array_map([$this->driver, '_quote'], $this->setArrayKeys);
|
$this->state->setSetArrayKeys(
|
||||||
|
array_map([$this->driver, '_quote'], $this->state->getSetArrayKeys())
|
||||||
|
);
|
||||||
|
|
||||||
// Generate the "set" string
|
// Generate the "set" string
|
||||||
$this->setString = implode('=?,', $this->setArrayKeys);
|
$setString = implode('=?,', $this->state->getSetArrayKeys());
|
||||||
$this->setString .= '=?';
|
$setString .= '=?';
|
||||||
|
|
||||||
|
$this->state->setSetString($setString);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -631,7 +510,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$parsedCondition = $this->parser->compileJoin($condition);
|
$parsedCondition = $this->parser->compileJoin($condition);
|
||||||
$condition = $table . ' ON ' . $parsedCondition;
|
$condition = $table . ' ON ' . $parsedCondition;
|
||||||
|
|
||||||
$this->_appendMap("\n" . strtoupper($type) . ' JOIN ', $condition, 'join');
|
$this->state->appendMap("\n" . strtoupper($type) . ' JOIN ', $condition, 'join');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -647,14 +526,16 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
if ( ! is_scalar($field))
|
if ( ! is_scalar($field))
|
||||||
{
|
{
|
||||||
$newGroupArray = array_map([$this->driver, 'quoteIdent'], $field);
|
$newGroupArray = array_map([$this->driver, 'quoteIdent'], $field);
|
||||||
$this->groupArray = array_merge($this->groupArray, $newGroupArray);
|
$this->state->setGroupArray(
|
||||||
|
array_merge($this->state->getGroupArray(), $newGroupArray)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$this->groupArray[] = $this->driver->quoteIdent($field);
|
$this->state->appendGroupArray($this->driver->quoteIdent($field));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->groupString = ' GROUP BY ' . implode(',', $this->groupArray);
|
$this->state->setGroupString(' GROUP BY ' . implode(',', $this->state->getGroupArray()));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -678,21 +559,23 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
|
|
||||||
// Set fields for later manipulation
|
// Set fields for later manipulation
|
||||||
$field = $this->driver->quoteIdent($field);
|
$field = $this->driver->quoteIdent($field);
|
||||||
$this->orderArray[$field] = $type;
|
$this->state->setOrderArray($field, $type);
|
||||||
|
|
||||||
$orderClauses = [];
|
$orderClauses = [];
|
||||||
|
|
||||||
// Flatten key/val pairs into an array of space-separated pairs
|
// Flatten key/val pairs into an array of space-separated pairs
|
||||||
foreach($this->orderArray as $k => $v)
|
foreach($this->state->getOrderArray() as $k => $v)
|
||||||
{
|
{
|
||||||
$orderClauses[] = $k . ' ' . strtoupper($v);
|
$orderClauses[] = $k . ' ' . strtoupper($v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the final string
|
// Set the final string
|
||||||
$this->orderString = ( ! isset($rand))
|
$orderString = ( ! isset($rand))
|
||||||
? "\nORDER BY ".implode(', ', $orderClauses)
|
? "\nORDER BY ".implode(', ', $orderClauses)
|
||||||
: "\nORDER BY".$rand;
|
: "\nORDER BY".$rand;
|
||||||
|
|
||||||
|
$this->state->setOrderString($orderString);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,8 +588,8 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function limit($limit, $offset=FALSE): QueryBuilderInterface
|
public function limit($limit, $offset=FALSE): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$this->limit = (int) $limit;
|
$this->state->setLimit($limit);
|
||||||
$this->offset = $offset;
|
$this->state->setOffset($offset);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -722,9 +605,9 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function groupStart(): QueryBuilderInterface
|
public function groupStart(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$conj = empty($this->queryMap) ? ' WHERE ' : ' ';
|
$conj = empty($this->state->getQueryMap()) ? ' WHERE ' : ' ';
|
||||||
|
|
||||||
$this->_appendMap($conj, '(', 'group_start');
|
$this->state->appendMap($conj, '(', 'group_start');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -737,9 +620,9 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function notGroupStart(): QueryBuilderInterface
|
public function notGroupStart(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$conj = empty($this->queryMap) ? ' WHERE ' : ' AND ';
|
$conj = empty($this->state->getQueryMap()) ? ' WHERE ' : ' AND ';
|
||||||
|
|
||||||
$this->_appendMap($conj, ' NOT (', 'group_start');
|
$this->state->appendMap($conj, ' NOT (', 'group_start');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -752,7 +635,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function orGroupStart(): QueryBuilderInterface
|
public function orGroupStart(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$this->_appendMap('', ' OR (', 'group_start');
|
$this->state->appendMap('', ' OR (', 'group_start');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -765,7 +648,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function orNotGroupStart(): QueryBuilderInterface
|
public function orNotGroupStart(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$this->_appendMap('', ' OR NOT (', 'group_start');
|
$this->state->appendMap('', ' OR NOT (', 'group_start');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -777,7 +660,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function groupEnd(): QueryBuilderInterface
|
public function groupEnd(): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
$this->_appendMap('', ')', 'group_end');
|
$this->state->appendMap('', ')', 'group_end');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -894,7 +777,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
// Get the generated values and sql string
|
// Get the generated values and sql string
|
||||||
list($sql, $data) = $this->driver->insertBatch($table, $data);
|
list($sql, $data) = $this->driver->insertBatch($table, $data);
|
||||||
|
|
||||||
return ( ! is_null($sql))
|
return $sql !== NULL
|
||||||
? $this->_run('', $table, $sql, $data)
|
? $this->_run('', $table, $sql, $data)
|
||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
@ -930,7 +813,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
// Get the generated values and sql string
|
// Get the generated values and sql string
|
||||||
list($sql, $data) = $this->driver->updateBatch($table, $data, $where);
|
list($sql, $data) = $this->driver->updateBatch($table, $data, $where);
|
||||||
|
|
||||||
return ( ! is_null($sql))
|
return $sql !== NULL
|
||||||
? $this->_run('', $table, $sql, $data)
|
? $this->_run('', $table, $sql, $data)
|
||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
@ -1039,50 +922,11 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
public function resetQuery(): void
|
public function resetQuery(): void
|
||||||
{
|
{
|
||||||
// Reset strings and booleans
|
$this->state = new State();
|
||||||
foreach($this->stringVars as $var)
|
$this->explain = FALSE;
|
||||||
{
|
|
||||||
$this->$var = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset arrays
|
|
||||||
foreach($this->arrayVars as $var)
|
|
||||||
{
|
|
||||||
$this->$var = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set values in the class, with either an array or key value pair
|
|
||||||
*
|
|
||||||
* @param array $var
|
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $val
|
|
||||||
* @param int $valType
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function _mixedSet(array &$var, $key, $val=NULL, int $valType=self::BOTH): array
|
|
||||||
{
|
|
||||||
$arg = (is_scalar($key) && is_scalar($val))
|
|
||||||
? [$key => $val]
|
|
||||||
: $key;
|
|
||||||
|
|
||||||
foreach($arg as $k => $v)
|
|
||||||
{
|
|
||||||
if (\in_array($valType, [self::KEY, self::VALUE], TRUE))
|
|
||||||
{
|
|
||||||
$var[] = ($valType === self::KEY)
|
|
||||||
? $k
|
|
||||||
: $v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$var[$k] = $v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $var;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to simplify select_ methods
|
* Method to simplify select_ methods
|
||||||
@ -1156,11 +1000,11 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$val = "%{$val}%";
|
$val = "%{$val}%";
|
||||||
}
|
}
|
||||||
|
|
||||||
$conj = empty($this->queryMap) ? ' WHERE ' : " {$conj} ";
|
$conj = empty($this->state->getQueryMap()) ? ' WHERE ' : " {$conj} ";
|
||||||
$this->_appendMap($conj, $like, 'like');
|
$this->state->appendMap($conj, $like, 'like');
|
||||||
|
|
||||||
// Add to the values array
|
// Add to the values array
|
||||||
$this->whereValues[] = $val;
|
$this->state->appendWhereValues($val);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -1190,10 +1034,12 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$item .= (count($fArray) === 1) ? '=?' : " {$fArray[1]} ?";
|
$item .= (count($fArray) === 1) ? '=?' : " {$fArray[1]} ?";
|
||||||
|
|
||||||
// Put in the having map
|
// Put in the having map
|
||||||
$this->havingMap[] = [
|
$this->state->appendHavingMap([
|
||||||
'conjunction' => ( ! empty($this->havingMap)) ? " {$conj} " : ' HAVING ',
|
'conjunction' => empty($this->state->getHavingMap())
|
||||||
|
? ' HAVING '
|
||||||
|
: " {$conj} ",
|
||||||
'string' => $item
|
'string' => $item
|
||||||
];
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -1209,8 +1055,23 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
protected function _where($key, $val=[]): array
|
protected function _where($key, $val=[]): array
|
||||||
{
|
{
|
||||||
$where = [];
|
$where = [];
|
||||||
$this->_mixedSet($where, $key, $val);
|
$pairs = [];
|
||||||
$this->_mixedSet($this->whereValues, $key, $val, self::VALUE);
|
|
||||||
|
if (is_scalar($key))
|
||||||
|
{
|
||||||
|
$pairs[$key] = $val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$pairs = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($pairs as $k => $v)
|
||||||
|
{
|
||||||
|
$where[$k] = $v;
|
||||||
|
$this->state->appendWhereValues($v);
|
||||||
|
}
|
||||||
|
|
||||||
return $where;
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1227,6 +1088,8 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
// Create key/value placeholders
|
// Create key/value placeholders
|
||||||
foreach($this->_where($key, $values) as $f => $val)
|
foreach($this->_where($key, $values) as $f => $val)
|
||||||
{
|
{
|
||||||
|
$queryMap = $this->state->getQueryMap();
|
||||||
|
|
||||||
// Split each key by spaces, in case there
|
// Split each key by spaces, in case there
|
||||||
// is an operator such as >, <, !=, etc.
|
// is an operator such as >, <, !=, etc.
|
||||||
$fArray = explode(' ', trim($f));
|
$fArray = explode(' ', trim($f));
|
||||||
@ -1235,11 +1098,11 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
|
|
||||||
// Simple key value, or an operator
|
// Simple key value, or an operator
|
||||||
$item .= (count($fArray) === 1) ? '=?' : " {$fArray[1]} ?";
|
$item .= (count($fArray) === 1) ? '=?' : " {$fArray[1]} ?";
|
||||||
$lastItem = end($this->queryMap);
|
$lastItem = end($queryMap);
|
||||||
|
|
||||||
// Determine the correct conjunction
|
// Determine the correct conjunction
|
||||||
$conjunctionList = array_column($this->queryMap, 'conjunction');
|
$conjunctionList = array_column($queryMap, 'conjunction');
|
||||||
if (empty($this->queryMap) || ( ! regex_in_array($conjunctionList, "/^ ?\n?WHERE/i")))
|
if (empty($queryMap) || ( ! regex_in_array($conjunctionList, "/^ ?\n?WHERE/i")))
|
||||||
{
|
{
|
||||||
$conj = "\nWHERE ";
|
$conj = "\nWHERE ";
|
||||||
}
|
}
|
||||||
@ -1252,7 +1115,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
$conj = " {$defaultConj} ";
|
$conj = " {$defaultConj} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_appendMap($conj, $item, 'where');
|
$this->state->appendMap($conj, $item, 'where');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -1271,16 +1134,12 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
{
|
{
|
||||||
$key = $this->driver->quoteIdent($key);
|
$key = $this->driver->quoteIdent($key);
|
||||||
$params = array_fill(0, count($val), '?');
|
$params = array_fill(0, count($val), '?');
|
||||||
|
$this->state->appendWhereValues($val);
|
||||||
|
|
||||||
foreach($val as $v)
|
$conjunction = empty($this->state->getQueryMap()) ? ' WHERE ' : " {$conj} ";
|
||||||
{
|
|
||||||
$this->whereValues[] = $v;
|
|
||||||
}
|
|
||||||
|
|
||||||
$conjunction = ( ! empty($this->queryMap)) ? " {$conj} " : ' WHERE ';
|
|
||||||
$str = $key . " {$in} (".implode(',', $params).') ';
|
$str = $key . " {$in} (".implode(',', $params).') ';
|
||||||
|
|
||||||
$this->_appendMap($conjunction, $str, 'where_in');
|
$this->state->appendMap($conjunction, $str, 'where_in');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -1304,7 +1163,7 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
|
|
||||||
if ($vals === NULL)
|
if ($vals === NULL)
|
||||||
{
|
{
|
||||||
$vals = array_merge($this->values, (array) $this->whereValues);
|
$vals = array_merge($this->state->getValues(), (array) $this->state->getWhereValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
$startTime = microtime(TRUE);
|
$startTime = microtime(TRUE);
|
||||||
@ -1328,23 +1187,6 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an additional set of mapping pairs to a internal map
|
|
||||||
*
|
|
||||||
* @param string $conjunction
|
|
||||||
* @param string $string
|
|
||||||
* @param string $type
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function _appendMap(string $conjunction = '', string $string = '', string $type = '')
|
|
||||||
{
|
|
||||||
$this->queryMap[] = [
|
|
||||||
'type' => $type,
|
|
||||||
'conjunction' => $conjunction,
|
|
||||||
'string' => $string
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the prepared statement into readable sql
|
* Convert the prepared statement into readable sql
|
||||||
*
|
*
|
||||||
@ -1391,18 +1233,20 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
*/
|
*/
|
||||||
protected function _compileType(string $type='', string $table=''): string
|
protected function _compileType(string $type='', string $table=''): string
|
||||||
{
|
{
|
||||||
|
$setArrayKeys = $this->state->getSetArrayKeys();
|
||||||
switch($type)
|
switch($type)
|
||||||
{
|
{
|
||||||
case 'insert':
|
case 'insert':
|
||||||
$paramCount = count($this->setArrayKeys);
|
$paramCount = count($setArrayKeys);
|
||||||
$params = array_fill(0, $paramCount, '?');
|
$params = array_fill(0, $paramCount, '?');
|
||||||
$sql = "INSERT INTO {$table} ("
|
$sql = "INSERT INTO {$table} ("
|
||||||
. implode(',', $this->setArrayKeys)
|
. implode(',', $setArrayKeys)
|
||||||
. ")\nVALUES (".implode(',', $params).')';
|
. ")\nVALUES (".implode(',', $params).')';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'update':
|
case 'update':
|
||||||
$sql = "UPDATE {$table}\nSET {$this->setString}";
|
$setString = $this->state->getSetString();
|
||||||
|
$sql = "UPDATE {$table}\nSET {$setString}";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'replace':
|
case 'replace':
|
||||||
@ -1416,13 +1260,16 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
|
|
||||||
// Get queries
|
// Get queries
|
||||||
default:
|
default:
|
||||||
$sql = "SELECT * \nFROM {$this->fromString}";
|
$fromString = $this->state->getFromString();
|
||||||
|
$selectString = $this->state->getSelectString();
|
||||||
|
|
||||||
|
$sql = "SELECT * \nFROM {$fromString}";
|
||||||
|
|
||||||
// Set the select string
|
// Set the select string
|
||||||
if ( ! empty($this->selectString))
|
if ( ! empty($selectString))
|
||||||
{
|
{
|
||||||
// Replace the star with the selected fields
|
// Replace the star with the selected fields
|
||||||
$sql = str_replace('*', $this->selectString, $sql);
|
$sql = str_replace('*', $selectString, $sql);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1452,7 +1299,8 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
// Set each type of subclause
|
// Set each type of subclause
|
||||||
foreach($clauses as $clause)
|
foreach($clauses as $clause)
|
||||||
{
|
{
|
||||||
$param = $this->$clause;
|
$func = 'get' . ucFirst($clause);
|
||||||
|
$param = $this->state->$func();
|
||||||
if (\is_array($param))
|
if (\is_array($param))
|
||||||
{
|
{
|
||||||
foreach($param as $q)
|
foreach($param as $q)
|
||||||
@ -1467,9 +1315,10 @@ class QueryBuilder implements QueryBuilderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the limit via the class variables
|
// Set the limit via the class variables
|
||||||
if (is_numeric($this->limit))
|
$limit = $this->state->getLimit();
|
||||||
|
if (is_numeric($limit))
|
||||||
{
|
{
|
||||||
$sql = $this->sql->limit($sql, $this->limit, $this->offset);
|
$sql = $this->sql->limit($sql, $limit, $this->state->getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if the query plan, rather than the
|
// See if the query plan, rather than the
|
||||||
|
428
src/State.php
Normal file
428
src/State.php
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Query
|
||||||
|
*
|
||||||
|
* SQL Query Builder / Database Abstraction Layer
|
||||||
|
*
|
||||||
|
* PHP version 7.1
|
||||||
|
*
|
||||||
|
* @package Query
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2012 - 2018 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @link https://git.timshomepage.net/aviat4ion/Query
|
||||||
|
*/
|
||||||
|
namespace Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query builder state
|
||||||
|
*/
|
||||||
|
class State {
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// ! SQL Clause Strings
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiled 'select' clause
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $selectString = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiled 'from' clause
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $fromString = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiled arguments for insert / update
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $setString = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order by clause
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $orderString = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group by clause
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $groupString = '';
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// ! SQL Clause Arrays
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys for insert/update statement
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $setArrayKeys = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key/val pairs for order by clause
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $orderArray = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key/val pairs for group by clause
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $groupArray = [];
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// ! Other Class vars
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values to apply to prepared statements
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $values = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values to apply to where clauses in prepared statements
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $whereValues = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value for limit string
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $limit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value for offset in limit string
|
||||||
|
* @var string|false
|
||||||
|
*/
|
||||||
|
protected $offset = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query component order mapping
|
||||||
|
* for complex select queries
|
||||||
|
*
|
||||||
|
* Format:
|
||||||
|
* array(
|
||||||
|
* 'type' => 'where',
|
||||||
|
* 'conjunction' => ' AND ',
|
||||||
|
* 'string' => 'k=?'
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $queryMap = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map for having clause
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $havingMap = [];
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $str
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setSelectString(string $str): self
|
||||||
|
{
|
||||||
|
$this->selectString = $str;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSelectString(): string
|
||||||
|
{
|
||||||
|
return $this->selectString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $str
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendSelectString(string $str): self
|
||||||
|
{
|
||||||
|
$this->selectString .= $str;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFromString(): string
|
||||||
|
{
|
||||||
|
return $this->fromString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fromString
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setFromString(string $fromString): State
|
||||||
|
{
|
||||||
|
$this->fromString = $fromString;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSetString(): string
|
||||||
|
{
|
||||||
|
return $this->setString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $setString
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setSetString(string $setString): State
|
||||||
|
{
|
||||||
|
$this->setString = $setString;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getOrderString(): string
|
||||||
|
{
|
||||||
|
return $this->orderString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $orderString
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setOrderString(string $orderString): State
|
||||||
|
{
|
||||||
|
$this->orderString = $orderString;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getGroupString(): string
|
||||||
|
{
|
||||||
|
return $this->groupString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $groupString
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setGroupString(string $groupString): State
|
||||||
|
{
|
||||||
|
$this->groupString = $groupString;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSetArrayKeys(): array
|
||||||
|
{
|
||||||
|
return $this->setArrayKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $setArrayKeys
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendSetArrayKeys(array $setArrayKeys): State
|
||||||
|
{
|
||||||
|
$this->setArrayKeys = array_merge($this->setArrayKeys, $setArrayKeys);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $setArrayKeys
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setSetArrayKeys(array $setArrayKeys): State
|
||||||
|
{
|
||||||
|
$this->setArrayKeys = $setArrayKeys;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getOrderArray(): array
|
||||||
|
{
|
||||||
|
return $this->orderArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $orderArray
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setOrderArray(string $key, $orderArray): State
|
||||||
|
{
|
||||||
|
$this->orderArray[$key] = $orderArray;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getGroupArray(): array
|
||||||
|
{
|
||||||
|
return $this->groupArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $groupArray
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setGroupArray(array $groupArray): State
|
||||||
|
{
|
||||||
|
$this->groupArray = $groupArray;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $groupArray
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendGroupArray(string $groupArray): State
|
||||||
|
{
|
||||||
|
$this->groupArray[] = $groupArray;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValues(): array
|
||||||
|
{
|
||||||
|
return $this->values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $values
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendValues(array $values): State
|
||||||
|
{
|
||||||
|
$this->values = array_merge($this->values, $values);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getWhereValues(): array
|
||||||
|
{
|
||||||
|
return $this->whereValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $val
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendWhereValues($val): State
|
||||||
|
{
|
||||||
|
if (\is_array($val))
|
||||||
|
{
|
||||||
|
foreach($val as $v)
|
||||||
|
{
|
||||||
|
$this->whereValues[] = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->whereValues[] = $val;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLimit(): ?int
|
||||||
|
{
|
||||||
|
return $this->limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $limit
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setLimit(int $limit): State
|
||||||
|
{
|
||||||
|
$this->limit = $limit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
public function getOffset()
|
||||||
|
{
|
||||||
|
return $this->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|false $offset
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function setOffset($offset): State
|
||||||
|
{
|
||||||
|
$this->offset = $offset;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getQueryMap(): array
|
||||||
|
{
|
||||||
|
return $this->queryMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an additional set of mapping pairs to a internal map
|
||||||
|
*
|
||||||
|
* @param string $conjunction
|
||||||
|
* @param string $string
|
||||||
|
* @param string $type
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendMap(string $conjunction = '', string $string = '', string $type = ''): self
|
||||||
|
{
|
||||||
|
$this->queryMap[] = [
|
||||||
|
'type' => $type,
|
||||||
|
'conjunction' => $conjunction,
|
||||||
|
'string' => $string
|
||||||
|
];
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getHavingMap(): array
|
||||||
|
{
|
||||||
|
return $this->havingMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $item
|
||||||
|
* @return State
|
||||||
|
*/
|
||||||
|
public function appendHavingMap(array $item): State
|
||||||
|
{
|
||||||
|
$this->havingMap[] = $item;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -31,11 +31,11 @@ namespace Query\Tests {
|
|||||||
*/
|
*/
|
||||||
abstract class TestCase extends \UnitTestCase
|
abstract class TestCase extends \UnitTestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$class = \get_class($this);
|
$class = \get_class($this);
|
||||||
|
|
||||||
|
echo '<pre>';
|
||||||
echo 'Ran test suite: ' . $class . '<br />';
|
echo 'Ran test suite: ' . $class . '<br />';
|
||||||
|
|
||||||
if (method_exists($class, 'setupBeforeClass')) {
|
if (method_exists($class, 'setupBeforeClass')) {
|
||||||
@ -49,6 +49,8 @@ namespace Query\Tests {
|
|||||||
{
|
{
|
||||||
$class = \get_class($this);
|
$class = \get_class($this);
|
||||||
|
|
||||||
|
echo '</pre>';
|
||||||
|
|
||||||
if (method_exists($class, 'tearDownAfterClass')) {
|
if (method_exists($class, 'tearDownAfterClass')) {
|
||||||
$class::tearDownAfterClass();
|
$class::tearDownAfterClass();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user