File: /home/cafsindia/snap.cafsinfotech.in/vendor/itsgoingd/clockwork/Clockwork/Storage/SqlSearch.php
<?php namespace Clockwork\Storage;
use Clockwork\Request\Request;
use PDO;
// Rules for searching requests using SQL storage, builds the SQL query conditions
class SqlSearch extends Search
{
// Generated SQL query and bindings
public $query;
public $bindings;
// Internal representation of the SQL where conditions
protected $conditions;
// PDO instance
protected $pdo;
// Create a new instance, takes search parameters
public function __construct($search = [], PDO $pdo = null)
{
parent::__construct($search);
$this->pdo = $pdo;
list($this->conditions, $this->bindings) = $this->resolveConditions();
$this->buildQuery();
}
// Creates a new instance from a base Search class instance
public static function fromBase(Search $search = null, PDO $pdo = null)
{
return new static((array) $search, $pdo);
}
// Add an additional where condition, takes the SQL condition and array of bindings
public function addCondition($condition, $bindings = [])
{
$this->conditions = array_merge([ $condition ], $this->conditions);
$this->bindings = array_merge($bindings, $this->bindings);
$this->buildQuery();
return $this;
}
// Resolve SQL conditions and bindings based on the search parameters
protected function resolveConditions()
{
if ($this->isEmpty()) return [ [], [] ];
$conditions = array_filter([
$this->resolveStringCondition([ 'type' ], $this->type),
$this->resolveStringCondition([ 'uri', 'commandName', 'jobName', 'testName' ], array_merge($this->uri, $this->name)),
$this->resolveStringCondition([ 'controller' ], $this->controller),
$this->resolveExactCondition([ 'method' ], $this->method),
$this->resolveNumberCondition([ 'responseStatus', 'commandExitCode', 'jobStatus', 'testStatus' ], $this->status),
$this->resolveNumberCondition([ 'responseDuration' ], $this->time),
$this->resolveDateCondition([ 'time' ], $this->received)
]);
$sql = array_map(function ($condition) { return $condition[0]; }, $conditions);
$bindings = array_reduce($conditions, function ($bindings, $condition) {
return array_merge($bindings, $condition[1]);
}, []);
return [ $sql, $bindings ];
}
// Resolve a date type condition and bindings
protected function resolveDateCondition($fields, $inputs)
{
if (! count($inputs)) return null;
$bindings = [];
$conditions = implode(' OR ', array_map(function ($field) use ($inputs, &$bindings) {
return implode(' OR ', array_map(function ($input, $index) use ($field, &$bindings) {
if (preg_match('/^<(.+)$/', $input, $match)) {
$bindings["{$field}{$index}"] = $match[1];
return $this->quote($field) . " < :{$field}{$index}";
} elseif (preg_match('/^>(.+)$/', $input, $match)) {
$bindings["{$field}{$index}"] = $match[1];
return $this->quote($field). " > :{$field}{$index}";
}
}, $inputs, array_keys($inputs)));
}, $fields));
return [ "({$conditions})", $bindings ];
}
// Resolve an exact type condition and bindings
protected function resolveExactCondition($fields, $inputs)
{
if (! count($inputs)) return null;
$bindings = [];
$values = implode(' OR ', array_map(function ($field) use ($inputs, &$bindings) {
return implode(', ', array_map(function ($input, $index) use ($field, &$bindings) {
$bindings["{$field}{$index}"] = $input;
return ":{$field}{$index}";
}, $inputs, array_keys($inputs)));
}, $fields));
return [ $this->quote($field) . " IN ({$values})", $bindings ];
}
// Resolve a number type condition and bindings
protected function resolveNumberCondition($fields, $inputs)
{
if (! count($inputs)) return null;
$bindings = [];
$conditions = implode(' OR ', array_map(function ($field) use ($inputs, &$bindings) {
return implode(' OR ', array_map(function ($input, $index) use ($field, &$bindings) {
if (preg_match('/^<(\d+(?:\.\d+)?)$/', $input, $match)) {
$bindings["{$field}{$index}"] = $match[1];
return $this->quote($field) . " < :{$field}{$index}";
} elseif (preg_match('/^>(\d+(?:\.\d+)?)$/', $input, $match)) {
$bindings["{$field}{$index}"] = $match[1];
return $this->quote($field) . " > :{$field}{$index}";
} elseif (preg_match('/^(\d+(?:\.\d+)?)-(\d+(?:\.\d+)?)$/', $input, $match)) {
$bindings["{$field}{$index}from"] = $match[1];
$bindings["{$field}{$index}to"] = $match[2];
$quotedField = $this->quote($field);
return "({$quotedField} > :{$field}{$index}from AND {$quotedField} < :{$field}{$index}to)";
} else {
$bindings["{$field}{$index}"] = $input;
return $this->quote($field) . " = :{$field}{$index}";
}
}, $inputs, array_keys($inputs)));
}, $fields));
return [ "({$conditions})", $bindings ];
}
// Resolve a string type condition and bindings
protected function resolveStringCondition($fields, $inputs)
{
if (! count($inputs)) return null;
$bindings = [];
$conditions = implode(' OR ', array_map(function ($field) use ($inputs, &$bindings) {
return implode(' OR ', array_map(function ($input, $index) use ($field, &$bindings) {
$bindings["{$field}{$index}"] = $input;
return $this->quote($field) . " LIKE :{$field}{$index}";
}, $inputs, array_keys($inputs)));
}, $fields));
return [ "({$conditions})", $bindings ];
}
// Build the where part of the SQL query
protected function buildQuery()
{
$this->query = count($this->conditions) ? 'WHERE ' . implode(' AND ', $this->conditions) : '';
}
// Quotes SQL identifier name properly for the current database
protected function quote($identifier)
{
return $this->pdo && $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql' ? "`{$identifier}`" : "\"{$identifier}\"";
}
}