Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (1)
Showing
with 1119 additions and 554 deletions
......@@ -98,9 +98,9 @@ class Storm_Model_PersistenceStrategy_Db
protected function _generateWhereClauseForKeyAndValue(string $key,
$value) : string {
$clause = ($value instanceof Storm_Model_PersistenceStrategy_Clause)
$clause = ($value instanceof Storm_Query_Clause)
? $value
: Storm_Model_PersistenceStrategy_Clause::newWith($key, $value);
: Storm_Query_Clause::newWith($key, $value);
return $clause->getFormatDb($this->getTable());
}
......@@ -172,7 +172,7 @@ class Storm_Model_PersistenceStrategy_Db
*/
public function _generateSelectFor($args) {
if ($args instanceof Storm_Query)
return $args->getSelectAndAssemble();
return $this->_selectForQuery($args);
if (array_key_exists('role', $args) && array_key_exists('model', $args)) {
$model = $args['model'];
......@@ -196,6 +196,14 @@ class Storm_Model_PersistenceStrategy_Db
}
protected function _selectForQuery(Storm_Query $query) {
$select = $this->getTable()->select();
$query->assemble($select);
return $select;
}
protected function _addInSelect($select, string $field, $value_or_clause) : self {
if (in_array($field, ['order', 'limit', 'where'], true)) {
$select->$field($value_or_clause);
......@@ -212,8 +220,8 @@ class Storm_Model_PersistenceStrategy_Db
return $this;
}
if (!($value_or_clause instanceof Storm_Model_PersistenceStrategy_Clause))
$value_or_clause = Storm_Model_PersistenceStrategy_Clause::newWith($field, $value_or_clause);
if (!($value_or_clause instanceof Storm_Query_Clause))
$value_or_clause = Storm_Query_Clause::newWith($field, $value_or_clause);
$select->where($this->_generateWhereClauseForKeyAndValue($field, $value_or_clause));
return $this;
......
......@@ -30,12 +30,9 @@ class Storm_Model_PersistenceStrategy_MatchTerms {
protected array $_values;
protected bool $_exact;
public function __construct($array_or_value, ?bool $exact = false) {
if (!is_array($array_or_value))
$array_or_value = explode(' ', $array_or_value);
$this->_values = $array_or_value;
$this->_exact = $exact ?? false;
public function __construct(array $values, bool $exact) {
$this->_values = $values;
$this->_exact = $exact;
}
......
......@@ -189,16 +189,16 @@ class Storm_Model_PersistenceStrategy_Volatile
public function containsAttribute(array $model, string $key, $value) : bool {
$clause = ($value instanceof Storm_Model_PersistenceStrategy_Clause)
$clause = ($value instanceof Storm_Query_Clause)
? $value
: null;
if (!$clause && preg_match('/left\((.+),(.+)\)/', $key, $matches))
$clause = Storm_Model_PersistenceStrategy_Clause::like(trim($matches[1]),
$clause = Storm_Query_Clause::like(trim($matches[1]),
(substr($value, 0, (int)$matches[2]) . '%'));
if (!$clause)
$clause = Storm_Model_PersistenceStrategy_Clause::newWith($key, $value);
$clause = Storm_Query_Clause::newWith($key, $value);
return $clause->containAttibuteInVolatile($model);
}
......@@ -269,7 +269,7 @@ class Storm_Model_PersistenceStrategy_Volatile
}
protected function _allMatchingInstancesDo(array $clauses, callable $callback) : int {
protected function _allMatchingInstancesDo($clauses, callable $callback) : int {
$matching_instances = array_filter($this->getInstancesArray(),
function ($model) use ($clauses) {
return $this->_modelMatchesClauses($model, $clauses);
......@@ -279,7 +279,10 @@ class Storm_Model_PersistenceStrategy_Volatile
}
protected function _modelMatchesClauses(array $model, array $clauses) : bool {
protected function _modelMatchesClauses(array $model, $clauses) : bool {
if ($clauses instanceof Storm_Query)
return $clauses->containsAllAttributes($model);
return $this->containsAllAttributes($model, $clauses);
}
......
......@@ -75,9 +75,9 @@ class Storm_Model_PersistenceStrategy_Volatile_Filtered {
}
public function getClauses() : array {
public function getClauses() {
return $this->_query
? $this->_query->getClauses()
? $this->_query
: $this->_select;
}
......
......@@ -25,308 +25,268 @@
*/
class Storm_Query {
class Storm_Query implements Storm_Query_CriteriaInterface {
protected array $_clauses;
protected array $_orders;
protected array $_terms;
protected Storm_Model_Loader $_loader;
protected ?Storm_Model_PersistenceStrategy_Clause $_clause_limit;
protected ?Storm_Model_PersistenceStrategy_Clause $_clause_limit_page;
protected ?Storm_Model_PersistenceStrategy_Clause $_clause_group_by;
protected Storm_Query_CriteriaInterface $_criteria;
protected ?Storm_Query_Clause $_clause_limit;
protected ?Storm_Query_Clause $_clause_limit_page;
protected ?Storm_Query_Clause $_clause_group_by;
public function __construct() {
$this->_clauses = [];
protected function __construct(Storm_Model_Loader $loader) {
$this->_loader = $loader;
$this->_orders = [];
$this->_terms = [];
$this->_clause_limit = null;
$this->_clause_limit_page = null;
$this->_clause_group_by = null;
$this->_criteria = new Storm_Query_Criteria;
}
public function __call($method, $args) {
return $this->_callQuery($method, $args);
public static function from(Storm_Model_Loader $loader) : self {
return new static($loader);
}
public static function __callStatic($method, $args) {
return (new static)->_callQuery($method, $args);
public function limit($limit) : self {
$this->_clause_limit = Storm_Query_Clause::limit($limit);
return $this;
}
protected function _callQuery($method, $args) {
if (!method_exists($this , '_' . $method))
throw new Exception('Call undefined method ' . $method);
return $this->{'_' . $method}(...$args);
public function limit_page(array $range) {
$this->_clause_limit_page = Storm_Query_Clause::limit_page($range);
return $this;
}
public function getSelectAndAssemble() {
$select = $this->_loader->getTable()->select();
foreach ($this->getClauses() as $clause)
$clause->assemble($select);
foreach ($this->getOrders() as $order)
$order->assemble($select);
if ($this->_clause_limit)
$this->_clause_limit->assemble($select);
if ($this->_clause_limit_page)
$this->_clause_limit_page->assemble($select);
if ($this->_clause_group_by)
$this->_clause_group_by->assemble($select);
return $select;
public function group(string $value) : self {
$this->_clause_group_by = Storm_Query_Clause::group($value);
return $this;
}
public function orderVolatile(array $models) : array {
return (new Storm_Query_Order(array_reverse($this->getOrders())))
->compareVolatile($models);
public function order(string $key) : self {
$this->_orders [] = Storm_Query_Clause::order($key)
->setOrder(false);
return $this;
}
public function getClauses() : array {
return $this->_clauses;
public function order_desc(string $key) : self {
$this->_orders [] = Storm_Query_Clause::order($key)
->setOrder(true);
return $this;
}
public function getOrders() : array {
return $this->_orders;
}
public function order_match(Storm_Query_MatchRating $match) : self {
$clause_match = Storm_Query_Clause::match($match);
$this->_orders [] =
Storm_Query_Clause::order($match->getKey(),
$clause_match)
->setOrder(false);
public function getTerms() : array {
return $this->_terms;
return $this;
}
public function getLimitValue() {
return $this->_clause_limit ?
$this->_clause_limit->getValueOrArray()
: '';
}
public function order_match_desc(Storm_Query_MatchRating $match) : self {
$clause_match = Storm_Query_Clause::match($match);
$this->_orders [] =
Storm_Query_Clause::order($match->getKey(),
$clause_match)
->setOrder(true);
public function getLimitPageValue() : ?array {
return $this->_clause_limit_page
? $this->_clause_limit_page->getValueOrArray()
: null;
return $this;
}
public function getGroupByValue() : string {
return $this->_clause_group_by
? $this->_clause_group_by->getValueOrArray()
: '';
public function fetchAll() : array {
return $this->_loader->findAllBy($this);
}
protected function _limit($limit) : self {
$this->_clause_limit = Storm_Model_PersistenceStrategy_Clause::limit($limit);
return $this;
public function count() : int {
return $this->_loader->countBy($this);
}
protected function _limit_page(array $range) {
$this->_clause_limit_page = Storm_Model_PersistenceStrategy_Clause::limit_page($range);
return $this;
public function fetchFirst() : ?Storm_Model_Abstract {
return $this->_loader->findFirstBy($this);
}
protected function _group(string $value) : self {
$this->_clause_group_by = Storm_Model_PersistenceStrategy_Clause::group($value);
/** interface Storm_Query_CriteriaInterface */
public function beOr() : self {
$this->_criteria->beOr();
return $this;
}
protected function _eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::equal($key, $value);
public function or(Storm_Query_CriteriaInterface $criteria) : self {
$this->_criteria->or($criteria);
return $this;
}
public function _not_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::equal($key, $value)->setNegated(true);
public function and(Storm_Query_CriteriaInterface $criteria) : self {
$this->_criteria->and($criteria);
return $this;
}
protected function _like(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::like($key, $value);
public function eq(string $key, string $value) : self {
$this->_criteria->eq($key, $value);
return $this;
}
protected function _not_like(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::like($key, $value)->setNegated(true);
public function not_eq(string $key, string $value) : self {
$this->_criteria->not_eq($key, $value);
return $this;
}
protected function _gt(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::greater($key, $value);
public function like(string $key, string $value) : self {
$this->_criteria->like($key, $value);
return $this;
}
protected function _gt_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::greaterEqual($key, $value);
public function not_like(string $key, string $value) : self {
$this->_criteria->not_like($key, $value);
return $this;
}
protected function _lt(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::lesser($key, $value);
public function gt(string $key, string $value) : self {
$this->_criteria->gt($key, $value);
return $this;
}
protected function _lt_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::lesserEqual($key, $value);
public function gt_eq(string $key, string $value) : self {
$this->_criteria->gt_eq($key, $value);
return $this;
}
protected function _is(string $key) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::is($key);
public function lt(string $key, string $value) : self {
$this->_criteria->lt($key, $value);
return $this;
}
protected function _not_is(string $key) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::is($key)->setNegated(true);
public function lt_eq(string $key, string $value) : self {
$this->_criteria->lt_eq($key, $value);
return $this;
}
protected function _in(string $key, array $array) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::in($key, $array);
public function is(string $key) : self {
$this->_criteria->is($key);
return $this;
}
protected function _not_in(string $key, array $array) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::in($key, $array)->setNegated(true);
public function not_is(string $key) : self {
$this->_criteria->not_is($key);
return $this;
}
protected function _start(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::start($key, $value);
public function in(string $key, array $array) : self {
$this->_criteria->in($key, $array);
return $this;
}
protected function _end(string $key, string $value) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::end($key, $value);
public function not_in(string $key, array $array) : self {
$this->_criteria->not_in($key, $array);
return $this;
}
protected function _or(Storm_Query ...$querys) : self {
$clauses = [];
foreach ($querys as $q)
$clauses = [...$clauses, ...$q->getClauses()];
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::or($clauses);
public function start(string $key, string $value) : self {
$this->_criteria->start($key, $value);
return $this;
}
protected function _and(Storm_Query ...$querys) : self {
$clauses = [];
foreach ($querys as $q)
$clauses = [...$clauses, ...$q->getClauses()];
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::and($clauses);
public function end(string $key, string $value) : self {
$this->_criteria->end($key, $value);
return $this;
}
protected function _match(string $key,
Storm_Query $query,
?bool $strict = false,
?bool $boolean_mode = true) : self {
$this->_clauses [] = Storm_Model_PersistenceStrategy_Clause::match($key,
$query->getTerms(),
$strict,
$boolean_mode);
public function match(Storm_Query_MatchRating $match) : self {
$this->_criteria->match($match);
return $this;
}
protected function _terms($value_or_array, ?bool $exact = false) : self {
$this->_terms [] = (new Storm_Model_PersistenceStrategy_MatchTerms($value_or_array, $exact));
return $this;
}
/** DB management */
/**
* @param $select Zend_Db_Table_Select|Storm_Test_ObjectWrapper
*/
public function assemble(object $select) : self {
$sql = new Storm_Query_Sql;
$this->_criteria->assemble($sql);
if ($where = $sql->implode($this->_criteria->separator()))
$select->where($where);
protected function _order(string $key) : self {
$this->_orders [] = Storm_Model_PersistenceStrategy_Clause::order($key)->setOrder(false);
return $this;
}
foreach ($this->_orders as $order)
$order->assemble($select);
if ($this->_clause_limit)
$this->_clause_limit->assemble($select);
protected function _order_desc(string $key) : self {
$this->_orders [] = Storm_Model_PersistenceStrategy_Clause::order($key)->setOrder(true);
return $this;
}
if ($this->_clause_limit_page)
$this->_clause_limit_page->assemble($select);
if ($this->_clause_group_by)
$this->_clause_group_by->assemble($select);
protected function _order_match(string $key,
Storm_Query $query,
?bool $strict = false,
?bool $boolean_mode = true) : self {
$match = Storm_Model_PersistenceStrategy_Clause::match($key,
$query->getTerms(),
$strict,
$boolean_mode);
$this->_orders [] = Storm_Model_PersistenceStrategy_Clause::order($key, $match)->setOrder(false);
return $this;
}
protected function _order_match_desc(string $key,
Storm_Query $query,
?bool $strict = false,
?bool $boolean_mode = true) : self {
$match = Storm_Model_PersistenceStrategy_Clause::match($key,
$query->getTerms(),
$strict,
$boolean_mode);
$this->_orders [] = Storm_Model_PersistenceStrategy_Clause::order($key, $match)->setOrder(true);
return $this;
/** Volatile management */
public function orderVolatile(array $models) : array {
return (new Storm_Query_Order(array_reverse($this->_orders)))
->compareVolatile($models);
}
protected function _from(Storm_Model_Loader $loader) : self {
$this->_loader = $loader;
return $this;
public function containsAllAttributes(array $model) : bool {
return $this->_criteria->containsAllAttributes($model);
}
protected function _fetchAll() : array {
return $this->_loader
? $this->_loader->findAllBy($this)
: [];
public function getLimitValue() {
return $this->_clause_limit ?
$this->_clause_limit->getValueOrArray()
: '';
}
protected function _count() : array {
return $this->_loader
? $this->_loader->countBy($this)
: [];
public function getLimitPageValue() : ?array {
return $this->_clause_limit_page
? $this->_clause_limit_page->getValueOrArray()
: null;
}
protected function _fetchFirst() : ?Storm_Model_Abstract {
return $this->_loader
? $this->_loader->findFirstBy($this)
: null;
public function getGroupByValue() : string {
return $this->_clause_group_by
? $this->_clause_group_by->getValueOrArray()
: '';
}
}
......@@ -336,7 +296,7 @@ class Storm_Query {
class Storm_Query_Order {
protected ?Storm_Query_Order $_next_query;
protected ?Storm_Model_PersistenceStrategy_Clause $_clause;
protected ?Storm_Query_Clause $_clause;
protected int $_position;
public function __construct(array $orders, ?int $position = 0) {
......@@ -359,7 +319,7 @@ class Storm_Query_Order {
}
public function getClause() : ?Storm_Model_PersistenceStrategy_Clause {
public function getClause() : ?Storm_Query_Clause {
return $this->_clause;
}
......
......@@ -25,7 +25,7 @@ THE SOFTWARE.
*/
class Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_Clause {
protected string $_key;
protected string $_operator;
......@@ -33,8 +33,6 @@ class Storm_Model_PersistenceStrategy_Clause {
protected $_value_or_array;
const
CLAUSE_OR = 'or',
CLAUSE_AND = 'and',
CLAUSE_WHERE = 'where',
CLAUSE_LIKE = 'like',
CLAUSE_EQUAL = '=',
......@@ -61,36 +59,34 @@ class Storm_Model_PersistenceStrategy_Clause {
public static function newFor(string $key, string $operator, $value_or_array) : self {
if (static::CLAUSE_OR === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseOr($key, $operator, $value_or_array));
if (static::CLAUSE_AND === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseAnd($key, $operator, $value_or_array));
if (static::CLAUSE_LIKE === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseLike($key, $operator, $value_or_array));
return (new Storm_Query_ClauseLike($key, $operator, $value_or_array));
if (static::CLAUSE_EQUAL === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseEqual($key, $operator, $value_or_array));
return (new Storm_Query_ClauseEqual($key, $operator, $value_or_array));
if (static::CLAUSE_IN === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseIn($key, $operator, $value_or_array));
return (new Storm_Query_ClauseIn($key, $operator, $value_or_array));
if (static::CLAUSE_IS === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseIs($key, $operator, $value_or_array));
return (new Storm_Query_ClauseIs($key, $operator, $value_or_array));
if (static::CLAUSE_GREATER === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseGreater($key, $operator, $value_or_array));
return (new Storm_Query_ClauseGreater($key, $operator, $value_or_array));
if (static::CLAUSE_GREATER_EQUAL === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseGreaterEqual($key, $operator, $value_or_array));
return (new Storm_Query_ClauseGreaterEqual($key, $operator, $value_or_array));
if (static::CLAUSE_LESSER === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseLesser($key, $operator, $value_or_array));
return (new Storm_Query_ClauseLesser($key, $operator, $value_or_array));
if (static::CLAUSE_LESSER_EQUAL === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseLesserEqual($key, $operator, $value_or_array));
return (new Storm_Query_ClauseLesserEqual($key, $operator, $value_or_array));
if (static::CLAUSE_MATCH === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseMatch($key, $operator, $value_or_array));
return (new Storm_Query_Clause_Match($key, $operator, $value_or_array));
if (static::CLAUSE_LIMIT === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseLimit($key, $operator, $value_or_array));
return (new Storm_Query_ClauseLimit($key, $operator, $value_or_array));
if (static::CLAUSE_LIMIT_PAGE === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseLimitPage($key, $operator, $value_or_array));
return (new Storm_Query_ClauseLimitPage($key, $operator, $value_or_array));
if (static::CLAUSE_ORDER_BY === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseOrderBy($key, $operator, $value_or_array));
return (new Storm_Query_Clause_OrderBy($key, $operator, $value_or_array));
if (static::CLAUSE_GROUP_BY === $operator)
return (new Storm_Model_PersistenceStrategy_ClauseGroupBy($key, $operator, $value_or_array));
return (new Storm_Query_ClauseGroupBy($key, $operator, $value_or_array));
if (static::CLAUSE_WHERE === $operator)
return (new Storm_Query_ClauseWhere($key, $operator, $value_or_array));
return (new static($key, $operator, $value_or_array));
}
......@@ -169,23 +165,8 @@ class Storm_Model_PersistenceStrategy_Clause {
}
public static function or(array $array) : self {
return static::newFor(static::CLAUSE_OR, static::CLAUSE_OR, $array);
}
public static function and(array $array) : self {
return static::newFor(static::CLAUSE_AND, static::CLAUSE_AND, $array);
}
public static function match(string $key,
array $array,
?bool $strict = false,
?bool $boolean_mode = true) : self {
return static::newFor($key,
static::CLAUSE_MATCH,
(new Storm_Model_PersistenceStrategy_Match($array, $strict, $boolean_mode)));
public static function match(Storm_Query_MatchRating $match) : self {
return static::newFor($match->getKey(), static::CLAUSE_MATCH, $match);
}
......@@ -204,7 +185,7 @@ class Storm_Model_PersistenceStrategy_Clause {
}
public static function order(string $key, ?Storm_Model_PersistenceStrategy_Clause $clause = null) : self {
public static function order(string $key, ?Storm_Query_Clause $clause = null) : self {
return static::newFor($key, static::CLAUSE_ORDER_BY, $clause);
}
......@@ -221,18 +202,18 @@ class Storm_Model_PersistenceStrategy_Clause {
public function assemble($select) : self {
$select->where($this->getFormatDb($select->getTable()));
$select->where($this->getFormatDb());
return $this;
}
public function getFormatDb($table) : string {
public function getFormatDb() : string {
if (static::CLAUSE_WHERE === $this->_operator)
return '(' . $this->getValueOrArray() . ')';
return $table->getAdapter()
->quoteInto($this->_clauseFormatDb(),
$this->getValueOrArray(), null, null);
return Zend_Db_Table_Abstract::getDefaultAdapter()
->quoteInto($this->_clauseFormatDb(),
$this->getValueOrArray(), null, null);
}
......@@ -262,54 +243,8 @@ class Storm_Model_PersistenceStrategy_Clause {
class Storm_Model_PersistenceStrategy_ClauseOr
extends Storm_Model_PersistenceStrategy_Clause {
public function getValueOrArray() {
return $this->_value_or_array ?? [];
}
public function getFormatDb($table) : string {
$request = '';
$operator = ' ' . $this->_operator . ' ';
foreach ($this->getValueOrArray() as $clause)
$request = implode($operator, array_filter([$request,
$clause->getFormatDb($table)]));
return '(' . $request . ')';
}
public function containAttibuteInVolatile(array $model) : bool {
foreach ($this->getValueOrArray() as $clause)
if ($clause->containAttibuteInVolatile($model))
return true;
return false;
}
}
class Storm_Model_PersistenceStrategy_ClauseAnd
extends Storm_Model_PersistenceStrategy_ClauseOr {
public function containAttibuteInVolatile(array $model) : bool {
foreach ($this->getValueOrArray() as $clause)
if (!$clause->containAttibuteInVolatile($model))
return false;
return true;
}
}
class Storm_Model_PersistenceStrategy_ClauseLike
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseLike
extends Storm_Query_Clause {
protected function _clauseFormatDb() : string {
return $this->_key . ' ' . $this->_getOperator() . ' ?';
......@@ -331,8 +266,8 @@ class Storm_Model_PersistenceStrategy_ClauseLike
class Storm_Model_PersistenceStrategy_ClauseEqual
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseEqual
extends Storm_Query_Clause {
protected function _getOperator() : string {
return ($this->_negated ? '!' : '') . $this->_operator;
......@@ -342,8 +277,8 @@ class Storm_Model_PersistenceStrategy_ClauseEqual
class Storm_Model_PersistenceStrategy_ClauseIn
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseIn
extends Storm_Query_Clause {
public function getValueOrArray() {
return $this->_value_or_array ?? [];
......@@ -372,15 +307,15 @@ class Storm_Model_PersistenceStrategy_ClauseIn
class Storm_Model_PersistenceStrategy_ClauseIs
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseIs
extends Storm_Query_Clause {
public function getValueOrArray() {
return null;
}
public function getFormatDb($table) : string {
public function getFormatDb() : string {
return $this->_key . ' ' . $this->_getOperator() . ' null';
}
......@@ -393,8 +328,8 @@ class Storm_Model_PersistenceStrategy_ClauseIs
class Storm_Model_PersistenceStrategy_ClauseGreater
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseGreater
extends Storm_Query_Clause {
public function containAttibuteInVolatile(array $model) : bool {
if (!$this->_existKeyInModel($model))
......@@ -407,8 +342,8 @@ class Storm_Model_PersistenceStrategy_ClauseGreater
class Storm_Model_PersistenceStrategy_ClauseGreaterEqual
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseGreaterEqual
extends Storm_Query_Clause {
public function containAttibuteInVolatile(array $model) : bool {
if (!$this->_existKeyInModel($model))
......@@ -421,8 +356,8 @@ class Storm_Model_PersistenceStrategy_ClauseGreaterEqual
class Storm_Model_PersistenceStrategy_ClauseLesser
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseLesser
extends Storm_Query_Clause {
public function containAttibuteInVolatile(array $model) : bool {
if (!$this->_existKeyInModel($model))
......@@ -435,8 +370,8 @@ class Storm_Model_PersistenceStrategy_ClauseLesser
class Storm_Model_PersistenceStrategy_ClauseLesserEqual
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseLesserEqual
extends Storm_Query_Clause {
public function containAttibuteInVolatile(array $model) : bool {
if (!$this->_existKeyInModel($model))
......@@ -449,63 +384,8 @@ class Storm_Model_PersistenceStrategy_ClauseLesserEqual
class Storm_Model_PersistenceStrategy_ClauseMatch
extends Storm_Model_PersistenceStrategy_Clause {
public function getValueOrArray() {
return $this->_value_or_array ?? null;
}
public function getFormatDb($table) : string {
return ($value = $this->getValueOrArray())
? ($this->_getOperator() . ' ' . $value->getFormatDb($table))
: '';
}
public function compare(array $a, array $b) : int {
if (!($value = $this->getValueOrArray()))
return 0;
return ($value->getCompareValue($this->_getContents($a))
- $value->getCompareValue($this->_getContents($b)));
}
public function containAttibuteInVolatile(array $model) : bool {
if (!($value = $this->getValueOrArray()))
return false;
return $value->containVolatile($this->_getContents($model));
}
protected function _getOperator() : string {
return $this->_operator . '(' . $this->_key . ')';
}
protected function _clauseFormatDb() : string {
return $this->_getOperator();
}
protected function _getContents(array $model) : string {
$contents = '';
foreach (explode(',', $this->_key) as $key)
if (array_key_exists($key, $model))
$contents = implode(' ', array_filter([$contents, $model[$key]]));
return $contents;
}
}
class Storm_Model_PersistenceStrategy_ClauseLimit
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseLimit
extends Storm_Query_Clause {
public function assemble($select) : self {
$select->limit($this->getValueOrArray());
......@@ -513,7 +393,7 @@ class Storm_Model_PersistenceStrategy_ClauseLimit
}
public function getFormatDb($table) : string {
public function getFormatDb() : string {
return '';
}
......@@ -526,8 +406,8 @@ class Storm_Model_PersistenceStrategy_ClauseLimit
class Storm_Model_PersistenceStrategy_ClauseLimitPage
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseLimitPage
extends Storm_Query_Clause {
public function getValueOrArray() {
return $this->_value_or_array ?? [];
......@@ -543,7 +423,7 @@ class Storm_Model_PersistenceStrategy_ClauseLimitPage
}
public function getFormatDb($table) : string {
public function getFormatDb() : string {
return '';
}
......@@ -556,8 +436,8 @@ class Storm_Model_PersistenceStrategy_ClauseLimitPage
class Storm_Model_PersistenceStrategy_ClauseGroupBy
extends Storm_Model_PersistenceStrategy_Clause {
class Storm_Query_ClauseGroupBy
extends Storm_Query_Clause {
public function assemble($select) : self {
$select->group($this->getValueOrArray());
......@@ -565,7 +445,7 @@ class Storm_Model_PersistenceStrategy_ClauseGroupBy
}
public function getFormatDb($table) : string {
public function getFormatDb() : string {
return '';
}
......@@ -578,65 +458,8 @@ class Storm_Model_PersistenceStrategy_ClauseGroupBy
class Storm_Model_PersistenceStrategy_ClauseOrderBy
extends Storm_Model_PersistenceStrategy_Clause {
const ORDER_DESC = ' desc';
protected ?string $_order_mode = null;
public function getValueOrArray() {
return $this->_value_or_array ?? null;
}
public function assemble($select) : self {
$select->order((($clause = $this->getValueOrArray())
? $clause->getFormatDb($select->getTable())
: $this->_key)
. $this->_order_mode);
return $this;
}
public function getFormatDb($table) : string {
return '';
}
class Storm_Query_ClauseWhere extends Storm_Query_Clause {
public function containAttibuteInVolatile(array $model) : bool {
return true;
}
public function setOrder(bool $mode) : self {
$this->_order_mode = $mode ? static::ORDER_DESC : '';
return $this;
}
public function compare(Storm_Query_Order $query_order, array $a, array $b) : int {
$compare = $this->_compareValues($a, $b)
* $this->_descendant()
* $query_order->getPosition();
return ($next_order = $query_order->getNextQuery())
? ($compare + $next_order->getClause()->compare($next_order, $a, $b))
: $compare;
}
protected function _compareValues(array $a, array $b) : int {
if ($match_clause = $this->getValueOrArray())
return $match_clause->compare($a, $b);
$first = $this->_existKeyInModel($a) ? $a[$this->_key] : '';
$second = $this->_existKeyInModel($b) ? $b[$this->_key] : '';
return ($first <=> $second);
}
protected function _descendant() : int {
return static::ORDER_DESC === $this->_order_mode ? -1 : 1;
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_Clause_Match
extends Storm_Query_Clause {
public function getValueOrArray() {
return $this->_value_or_array ?? null;
}
public function getFormatDb() : string {
if (!$value = $this->getValueOrArray())
return '';
$content = '';
foreach ($value->getTerms() as $key => $term)
$content = implode(' ',
array_filter([$content,
$term->getFormatDb($value->isStrict())]));
$against = sprintf('AGAINST(%s%s)',
Zend_Db_Table_Abstract::getDefaultAdapter()
->quoteInto('?', $content),
($value->isBooleanMode() ? ' IN BOOLEAN MODE' : ''));
return $this->_getOperator() . ' ' . $against;
}
public function compare(array $a, array $b) : int {
return ($this->_compare($this->_getContents($a))
- $this->_compare($this->_getContents($b)));
}
protected function _compare(string $contents) : int {
if (!$value = $this->getValueOrArray())
return 0;
$compare = 0;
foreach ($value->getTerms() as $term) {
$new_compare = $term->getCompareValue($contents);
if ($value->isStrict() && 0 === $new_compare)
return 0;
$compare += $term->getCompareValue($contents);
}
return $value->isBooleanMode()
? min($compare, 1)
: ceil(($compare / count(explode(' ', $contents))) * 10);
}
public function containAttibuteInVolatile(array $model) : bool {
if (!($value = $this->getValueOrArray())
|| !($contents = $this->_getContents($model)))
return false;
foreach ($value->getTerms() as $term) {
if ($value->isStrict() && !$term->containVolatile($contents))
return false;
if (!$value->isStrict() && $term->containVolatile($contents))
return true;
}
return $value->isStrict();
}
protected function _getOperator() : string {
return $this->_operator . '(' . $this->_key . ')';
}
protected function _clauseFormatDb() : string {
return $this->_getOperator();
}
protected function _getContents(array $model) : string {
$contents = '';
foreach (explode(',', $this->_key) as $key)
if (array_key_exists($key, $model))
$contents = implode(' ', array_filter([$contents, $model[$key]]));
return $contents;
}
}
......@@ -5,7 +5,7 @@ STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
gof this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
......@@ -24,59 +24,54 @@ THE SOFTWARE.
*/
class Storm_Model_PersistenceStrategy_Match {
protected array $_terms;
protected bool $_boolean_mode;
protected bool $_strict;
class Storm_Query_Clause_MatchTerms {
public function __construct(array $terms, bool $strict, bool $boolean_mode) {
$this->_terms = $terms;
$this->_strict = $strict;
$this->_boolean_mode = $boolean_mode;
protected array $_values;
protected bool $_exact;
public function __construct(array $values, bool $exact) {
$this->_values = $values;
$this->_exact = $exact;
}
public function getFormatDb($table) : string {
$content = '';
foreach ($this->_terms as $key => $term)
$content = implode(' ', array_filter([$content,
$term->getFormatDb($this->_strict)]));
public function getFormatDb(bool $strict) : string {
$values = implode(' ', $this->_values);
if ($this->_exact)
return $strict ? '+"' . $values . '"' : '"' . $values . '"';
return sprintf('AGAINST(%s%s)',
$table->getAdapter()->quoteInto('?', $content, null, null),
($this->_boolean_mode ? ' IN BOOLEAN MODE' : ''));
return $strict ? '+(' . $values . ')' : $values;
}
public function containVolatile(string $contents) : bool {
if (!$contents)
return false;
if ($this->_exact)
return $this->_containValue($contents, implode(' ', $this->_values));
foreach ($this->_terms as $term) {
if ($this->_strict && !$term->containVolatile($contents))
return false;
if (!$this->_strict && $term->containVolatile($contents))
foreach ($this->_values as $value)
if ($this->_containValue($contents, $value))
return true;
}
return $this->_strict;
return false;
}
public function getCompareValue(string $contents) : int {
if ($this->_exact)
return preg_match_all('/\b' . implode(' ', $this->_values) . '\b/', $contents);
$compare = 0;
foreach ($this->_values as $value)
$compare += ($new_compare = preg_match_all('/\b' . $value . '\b/', $contents))
? $new_compare
: 0;
foreach ($this->_terms as $term) {
$new_compare = $term->getCompareValue($contents);
if ($this->_strict && 0 === $new_compare)
return 0;
return $compare;
}
$compare += $term->getCompareValue($contents);
}
return $this->_boolean_mode
? min($compare, 1)
: ceil(($compare / count(explode(' ', $contents))) * 10);
protected function _containValue(string $contents, string $value) : bool {
return preg_match('/\b' . $value . '\b/', $contents);
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_Clause_OrderBy
extends Storm_Query_Clause {
const ORDER_DESC = ' desc';
protected ?string $_order_mode = null;
public function getValueOrArray() {
return $this->_value_or_array ?? null;
}
public function assemble($select) : self {
$select->order((($clause = $this->getValueOrArray())
? $clause->getFormatDb($select->getTable())
: $this->_key)
. $this->_order_mode);
return $this;
}
public function getFormatDb() : string {
return '';
}
public function containAttibuteInVolatile(array $model) : bool {
return true;
}
public function setOrder(bool $mode) : self {
$this->_order_mode = $mode ? static::ORDER_DESC : '';
return $this;
}
public function compare(Storm_Query_Order $query_order, array $a, array $b) : int {
$compare = $this->_compareValues($a, $b)
* $this->_descendant()
* $query_order->getPosition();
return ($next_order = $query_order->getNextQuery())
? ($compare + $next_order->getClause()->compare($next_order, $a, $b))
: $compare;
}
protected function _compareValues(array $a, array $b) : int {
if ($match_clause = $this->getValueOrArray())
return $match_clause->compare($a, $b);
$first = $this->_existKeyInModel($a) ? $a[$this->_key] : '';
$second = $this->_existKeyInModel($b) ? $b[$this->_key] : '';
return ($first <=> $second);
}
protected function _descendant() : int {
return static::ORDER_DESC === $this->_order_mode ? -1 : 1;
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_Criteria implements Storm_Query_CriteriaInterface {
const
SEPARATOR_AND = 'and',
SEPARATOR_OR = 'or';
protected array $_clauses;
protected string $_separator;
public function __construct() {
$this->_clauses = [];
$this->_separator = static::SEPARATOR_AND;
}
public function beOr() : self {
$this->_separator = static::SEPARATOR_OR;
return $this;
}
public function separator() : string {
return ' ' . $this->_separator . ' ';
}
public function assemble(Storm_Query_Sql $sql) : self {
foreach ($this->_clauses as $clause)
$sql->write($this->_assembleOne($clause));
return $this;
}
/**
* @param $clause Storm_Query_CriteriaInterface|Storm_Query_Clause
*/
protected function _assembleOne(object $clause) : string {
if ($clause instanceof Storm_Query_CriteriaInterface) {
$sql = new Storm_Query_Sql;
$clause->assemble($sql);
return '(' . $sql->implode($clause->separator()) . ')';
}
return $clause->getFormatDb();
}
public function containsAllAttributes(array $model) : bool {
foreach ($this->_clauses as $clause)
if ($this->_isAnd() !== $this->_containsOne($clause, $model))
return !$this->_isAnd();
return $this->_isAnd();
}
protected function _containsOne($clause, array $model) : bool {
if ($clause instanceof Storm_Query_CriteriaInterface)
return $clause->containsAllAttributes($model);
return $clause->containAttibuteInVolatile($model);
}
protected function _isAnd() : bool {
return static::SEPARATOR_AND === $this->_separator;
}
public function eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::equal($key, $value);
return $this;
}
public function not_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::equal($key, $value)
->setNegated(true);
return $this;
}
public function like(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::like($key, $value);
return $this;
}
public function not_like(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::like($key, $value)
->setNegated(true);
return $this;
}
public function gt(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::greater($key, $value);
return $this;
}
public function gt_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::greaterEqual($key,
$value);
return $this;
}
public function lt(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::lesser($key, $value);
return $this;
}
public function lt_eq(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::lesserEqual($key, $value);
return $this;
}
public function is(string $key) : self {
$this->_clauses [] = Storm_Query_Clause::is($key);
return $this;
}
public function not_is(string $key) : self {
$this->_clauses [] = Storm_Query_Clause::is($key)
->setNegated(true);
return $this;
}
public function in(string $key, array $array) : self {
$this->_clauses [] = Storm_Query_Clause::in($key, $array);
return $this;
}
public function not_in(string $key, array $array) : self {
$this->_clauses [] = Storm_Query_Clause::in($key, $array)
->setNegated(true);
return $this;
}
public function start(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::start($key, $value);
return $this;
}
public function end(string $key, string $value) : self {
$this->_clauses [] = Storm_Query_Clause::end($key, $value);
return $this;
}
public function or(Storm_Query_CriteriaInterface $criteria) : self {
$this->_clauses [] = $criteria->beOr();
return $this;
}
public function and(Storm_Query_CriteriaInterface $criteria) : self {
$this->_clauses [] = $criteria;
return $this;
}
public function match(Storm_Query_MatchRating $match) : self {
$this->_clauses [] = Storm_Query_Clause::match($match);
return $this;
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
interface Storm_Query_CriteriaInterface {
public function beOr() : self;
public function eq(string $key, string $value) : self;
public function not_eq(string $key, string $value) : self;
public function like(string $key, string $value) : self;
public function not_like(string $key, string $value) : self;
public function gt(string $key, string $value) : self;
public function gt_eq(string $key, string $value) : self;
public function lt(string $key, string $value) : self;
public function lt_eq(string $key, string $value) : self;
public function is(string $key) : self;
public function not_is(string $key) : self;
public function in(string $key, array $array) : self;
public function not_in(string $key, array $array) : self;
public function start(string $key, string $value) : self;
public function end(string $key, string $value) : self;
public function or(Storm_Query_CriteriaInterface $criteria) : self;
public function and(Storm_Query_CriteriaInterface $criteria) : self;
public function match(Storm_Query_MatchRating $match) : self;
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_MatchBoolean extends Storm_Query_MatchRating {
public function __construct(string $key) {
parent::__construct($key);
$this->_boolean_mode = true;
}
public function exact($array_or_value) : self {
return $this->_addTerm($array_or_value, true);
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_MatchRating {
protected string $_key;
protected array $_terms;
protected bool $_boolean_mode;
protected bool $_strict;
public function __construct(string $key) {
$this->_key = $key;
$this->_terms = [];
$this->_boolean_mode = false;
$this->_strict = false;
}
public function isBooleanMode() : bool {
return $this->_boolean_mode;
}
public function isStrict() : bool {
return $this->_strict;
}
public function getKey() : string {
return $this->_key;
}
public function getTerms() : array {
return $this->_terms;
}
public function beStrict() : self {
$this->_strict = true;
return $this;
}
public function against($array_or_value) : self {
return $this->_addTerm($array_or_value);
}
protected function _addTerm($array_or_value, bool $exact = false) : self {
if (!is_array($array_or_value))
$array_or_value = explode(' ', $array_or_value);
$this->_terms [] = (new Storm_Query_Clause_MatchTerms($array_or_value,
$exact));
return $this;
}
}
<?php
/*
STORM is under the MIT License (MIT)
Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Storm_Query_Sql {
protected array $_sql = [];
public function write(string $sql) : self {
$this->_sql [] = $sql;
return $this;
}
public function implode(string $glue) : string {
return implode($glue, $this->_sql);
}
}
......@@ -27,13 +27,38 @@ THE SOFTWARE.
abstract class Storm_Test_ModelTestCase extends PHPUnit_Framework_TestCase {
use Storm_Test_THelpers;
protected $_old_adapter;
protected function setUp() {
Storm_Model_Abstract::unsetLoaders();
$this->_old_adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
$adapter = new class() extends Zend_Db_Adapter_Mysqli
{
public function __construct($config=[]) { }
public function getConfig() {
return ['dbname' => 'mockdb'];
}
protected function _connect() {
$this->_connection = Storm_Test_ObjectWrapper::mock()
->whenCalled('real_escape_string')
->willDo(fn($value) => $value);
return true;
}
};
Zend_Db_Table_Abstract::setDefaultAdapter($adapter);
}
protected function tearDown() {
Storm_Model_Abstract::unsetLoaders();
Zend_Db_Table_Abstract::setDefaultAdapter($this->_old_adapter);
}
......@@ -44,4 +69,4 @@ abstract class Storm_Test_ModelTestCase extends PHPUnit_Framework_TestCase {
}
}
?>
\ No newline at end of file
?>
......@@ -158,10 +158,10 @@ class Storm_Test_LoaderBasicTest extends Storm_Test_LoaderTestCase {
return
[
[ ['name' => null] , ['name is null'] ],
[ ['name' => ['Harlock', 'Nausicaa']], ['name in (\'Harlock\',\'Nausicaa\')'] ],
[ ['name' => ['Harlock', 'Nausicaa']], ['name in (\'Harlock\', \'Nausicaa\')'] ],
[ ['name not' => 'Harlock'], ['name!=\'Harlock\''] ],
[ ['name not' => ['Harlock', 'Nausicaa']],
['name not in (\'Harlock\',\'Nausicaa\')'] ],
['name not in (\'Harlock\', \'Nausicaa\')'] ],
[ ['name not' => null], ['name is not null'] ],
[ ['login like' => '%aus%'], ['login like \'%aus%\''] ],
[ ['login not like' => '%aus%'], ['login not like \'%aus%\''] ],
......@@ -218,7 +218,7 @@ class Storm_Test_LoaderBasicTest extends Storm_Test_LoaderTestCase {
$this->_table->whenCalled('delete')->answers(2);
$this->_loader->basicDeleteBy(['nom' => ['bond', 'l\'upin']]);
$this->assertEquals("nom in ('bond','l'upin')",
$this->assertEquals("nom in ('bond', 'l'upin')",
$this->_table->getFirstAttributeForLastCallOn('delete'));
}
......@@ -261,7 +261,7 @@ class Storm_Test_LoaderBasicTest extends Storm_Test_LoaderTestCase {
['type' => 'fictive']);
$this->assertEquals([['type' => 'fictive'],
"nom in ('bond','lupin') and type='real'"],
"nom in ('bond', 'lupin') and type='real'"],
$this->_table->getAttributesForLastCallOn('update'));
}
......@@ -292,7 +292,7 @@ class Storm_Test_LoaderSaveWithIdTest extends Storm_Test_LoaderTestCase {
->answers($this->_select = $this->mock());
$this->_select
->whenCalled('where')->with('id=\'4\'')->answers($this->_select)
->whenCalled('where')->with('id=4')->answers($this->_select)
->whenCalled('from')->with($this->_table, ['count(*) as numberof'])->answers($this->_select);
}
......@@ -358,8 +358,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseGreaterThanShouldReturnQuery() {
Storm_Query::gt('id', '30')
->from($this->_loader)
Storm_Query::from($this->_loader)
->gt('id', '30')
->fetchAll();
$this->assertEquals(['id>\'30\''],
......@@ -369,8 +369,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseGreaterThanEqualShouldReturnQuery() {
Storm_Query::gt_eq('id', '30')
->from($this->_loader)
Storm_Query::from($this->_loader)
->gt_eq('id', '30')
->fetchAll();
$this->assertEquals(['id>=\'30\''],
......@@ -380,8 +380,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLesserThanShouldReturnQuery() {
Storm_Query::lt('id', '30')
->from($this->_loader)
Storm_Query::from($this->_loader)
->lt('id', '30')
->fetchAll();
$this->assertEquals(['id<\'30\''],
......@@ -391,8 +391,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLesserThanEqualShouldReturnQuery() {
Storm_Query::lt_eq('id', '30')
->from($this->_loader)
Storm_Query::from($this->_loader)
->lt_eq('id', '30')
->fetchAll();
$this->assertEquals(['id<=\'30\''],
......@@ -402,8 +402,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseIsShouldReturnQuery() {
Storm_Query::is('name')
->from($this->_loader)
Storm_Query::from($this->_loader)
->is('name')
->fetchAll();
$this->assertEquals(['name is null'],
......@@ -413,8 +413,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseIsNotShouldReturnQuery() {
Storm_Query::not_is('name')
->from($this->_loader)
Storm_Query::from($this->_loader)
->not_is('name')
->fetchAll();
$this->assertEquals(['name is not null'],
......@@ -424,30 +424,30 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseInShouldReturnQuery() {
Storm_Query::in('name', ['Harlock', 'Nausicaa'])
->from($this->_loader)
Storm_Query::from($this->_loader)
->in('name', ['Harlock', 'Nausicaa'])
->fetchAll();
$this->assertEquals(['name in (\'Harlock\',\'Nausicaa\')'],
$this->assertEquals(['name in (\'Harlock\', \'Nausicaa\')'],
$this->_select->getAttributesForLastCallOn('where'));
}
/** @test */
public function withClauseNotInShouldReturnQuery() {
Storm_Query::not_in('name', ['Harlock', 'Nausicaa'])
->from($this->_loader)
Storm_Query::from($this->_loader)
->not_in('name', ['Harlock', 'Nausicaa'])
->fetchAll();
$this->assertEquals(['name not in (\'Harlock\',\'Nausicaa\')'],
$this->assertEquals(['name not in (\'Harlock\', \'Nausicaa\')'],
$this->_select->getAttributesForLastCallOn('where'));
}
/** @test */
public function withClauseEqualShouldReturnQuery() {
Storm_Query::eq('left(name, 5)', 'ganda')
->from($this->_loader)
Storm_Query::from($this->_loader)
->eq('left(name, 5)', 'ganda')
->fetchAll();
$this->assertEquals(['left(name, 5)=\'ganda\''],
......@@ -457,8 +457,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseNotEqualShouldReturnQuery() {
Storm_Query::not_eq('name', 'Harlock')
->from($this->_loader)
Storm_Query::from($this->_loader)
->not_eq('name', 'Harlock')
->fetchAll();
$this->assertEquals(['name!=\'Harlock\''],
......@@ -468,8 +468,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLikeShouldReturnQuery() {
Storm_Query::like('login', '%aus%')
->from($this->_loader)
Storm_Query::from($this->_loader)
->like('login', '%aus%')
->fetchAll();
$this->assertEquals(['login like \'%aus%\''],
......@@ -479,8 +479,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseNotLikeShouldReturnQuery() {
Storm_Query::not_like('login', '%aus%')
->from($this->_loader)
Storm_Query::from($this->_loader)
->not_like('login', '%aus%')
->fetchAll();
$this->assertEquals(['login not like \'%aus%\''],
......@@ -490,8 +490,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseStartShouldReturnQuery() {
Storm_Query::start('login', 'aus')
->from($this->_loader)
Storm_Query::from($this->_loader)
->start('login', 'aus')
->fetchAll();
$this->assertEquals(['login like \'aus%\''],
......@@ -501,8 +501,8 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseEndShouldReturnQuery() {
Storm_Query::end('login', 'aus')
->from($this->_loader)
Storm_Query::from($this->_loader)
->end('login', 'aus')
->fetchAll();
$this->assertEquals(['login like \'%aus\''],
......@@ -512,31 +512,35 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseOrShouldReturnQuery() {
Storm_Query::or(Storm_Query::eq('login', 'aus'),
Storm_Query::in('role', ['admin', 'invite']))
->from($this->_loader)
Storm_Query::from($this->_loader)
->or((new Storm_Query_Criteria)
->eq('login', 'aus')
->in('role', ['admin', 'invite']))
->fetchAll();
$this->assertEquals(['(login=\'aus\' or role in (\'admin\',\'invite\'))'],
$this->assertEquals(['(login=\'aus\' or role in (\'admin\', \'invite\'))'],
$this->_select->getAttributesForLastCallOn('where'));
}
/** @test */
public function withClauseAndShouldReturnQuery() {
Storm_Query::and(Storm_Query::eq('login', 'aus')->in('role', ['admin', 'invite']))
->from($this->_loader)
Storm_Query::from($this->_loader)
->and((new Storm_Query_Criteria)
->eq('login', 'aus')
->in('role', ['admin', 'invite']))
->fetchAll();
$this->assertEquals(['(login=\'aus\' and role in (\'admin\',\'invite\'))'],
$this->assertEquals(['(login=\'aus\' and role in (\'admin\', \'invite\'))'],
$this->_select->getAttributesForLastCallOn('where'));
}
/** @test */
public function withClauseMatchShouldReturnQueryInBooleanMode() {
Storm_Query::match('login, role', Storm_Query::terms(['ADMIN', 'INVITE']))
->from($this->_loader)
Storm_Query::from($this->_loader)
->match((new Storm_Query_MatchBoolean('login, role'))
->against(['ADMIN', 'INVITE']))
->fetchAll();
$this->assertEquals(['MATCH(login, role) AGAINST(\'ADMIN INVITE\' IN BOOLEAN MODE)'],
......@@ -546,8 +550,10 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseMatchMultipleTermsShouldReturnQueryInBooleanMode() {
Storm_Query::match('login,role', Storm_Query::terms('ADMIN INVITE')->terms('HUGO ADRIEN'))
->from($this->_loader)
Storm_Query::from($this->_loader)
->match((new Storm_Query_MatchBoolean('login,role'))
->against('ADMIN INVITE')
->against('HUGO ADRIEN'))
->fetchAll();
$this->assertEquals(['MATCH(login,role) AGAINST(\'ADMIN INVITE HUGO ADRIEN\' IN BOOLEAN MODE)'],
......@@ -557,25 +563,28 @@ class Storm_Test_LoaderQueryTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseMatchStrictModeShouldRturnQueryInBooleanMode() {
Storm_Query::match('login,role', Storm_Query::terms('ADMIN INVITE')->terms('HUGO ADRIEN'),
true)
->from($this->_loader)
Storm_Query::from($this->_loader)
->match((new Storm_Query_MatchRating('login,role'))
->beStrict()
->against('ADMIN INVITE')
->against('HUGO ADRIEN'))
->fetchAll();
$this->assertEquals(['MATCH(login,role) AGAINST(\'+(ADMIN INVITE) +(HUGO ADRIEN)\' IN BOOLEAN MODE)'],
$this->assertEquals(['MATCH(login,role) AGAINST(\'+(ADMIN INVITE) +(HUGO ADRIEN)\')'],
$this->_select->getAttributesForLastCallOn('where'));
}
/** @test */
public function withClauseMatchStrictAndOneExactExpressionWithNoBooleanModeShouldReturnQuery() {
Storm_Query::match('login,role', Storm_Query::terms('ADMIN INVITE', true)->terms('HUGO ADRIEN'),
true,
false)
->from($this->_loader)
Storm_Query::from($this->_loader)
->match((new Storm_Query_MatchBoolean('login,role'))
->beStrict()
->exact('ADMIN INVITE')
->against('HUGO ADRIEN'))
->fetchAll();
$this->assertEquals(['MATCH(login,role) AGAINST(\'+"ADMIN INVITE" +(HUGO ADRIEN)\')'],
$this->assertEquals(['MATCH(login,role) AGAINST(\'+"ADMIN INVITE" +(HUGO ADRIEN)\' IN BOOLEAN MODE)'],
$this->_select->getAttributesForLastCallOn('where'));
}
}
......@@ -601,8 +610,8 @@ class Storm_Test_LoaderQueryLimitTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLimit30ShouldReturnQuery() {
Storm_Query::limit(30)
->from($this->_loader)
Storm_Query::from($this->_loader)
->limit(30)
->fetchAll();
$this->assertEquals([30],
......@@ -612,8 +621,8 @@ class Storm_Test_LoaderQueryLimitTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLimit30Offset10ShouldReturnQuery() {
Storm_Query::limit('10, 30')
->from($this->_loader)
Storm_Query::from($this->_loader)
->limit('10, 30')
->fetchAll();
$this->assertEquals(['10, 30'],
......@@ -642,8 +651,8 @@ class Storm_Test_LoaderQueryLimitPageTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseLimitPageShouldReturnQuery() {
Storm_Query::limit_page([1, 100])
->from($this->_loader)
Storm_Query::from($this->_loader)
->limit_page([1, 100])
->fetchAll();
$this->assertEquals([1, 100],
......@@ -673,8 +682,8 @@ class Storm_Test_LoaderQueryOrderTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseOrderIdShouldReturnOrderId() {
Storm_Query::order('id')
->from($this->_loader)
Storm_Query::from($this->_loader)
->order('id')
->fetchAll();
$this->assertEquals(['id'],
......@@ -684,8 +693,8 @@ class Storm_Test_LoaderQueryOrderTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withClauseOrderIdDescShouldReturnOrderIdDesc() {
Storm_Query::order_desc('id')
->from($this->_loader)
Storm_Query::from($this->_loader)
->order_desc('id')
->fetchAll();
$this->assertEquals(['id desc'],
......@@ -695,10 +704,10 @@ class Storm_Test_LoaderQueryOrderTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withMultipleClauseOrderShouldReturnAllOrders() {
Storm_Query::order_desc('id')
Storm_Query::from($this->_loader)
->order_desc('id')
->order('name')
->order_desc('role')
->from($this->_loader)
->fetchAll();
$this->assertEquals(['id desc', 'name', 'role desc'],
......@@ -710,8 +719,9 @@ class Storm_Test_LoaderQueryOrderTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withMatchClauseOrderShouldReturnMatchOrder() {
Storm_Query::order_match('login, role', Storm_Query::terms(['ADMIN', 'INVITE']), false, false)
->from($this->_loader)
Storm_Query::from($this->_loader)
->order_match((new Storm_Query_MatchRating('login, role'))
->against(['ADMIN', 'INVITE']))
->fetchAll();
$this->assertEquals(['MATCH(login, role) AGAINST(\'ADMIN INVITE\')'],
......@@ -721,8 +731,9 @@ class Storm_Test_LoaderQueryOrderTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withMatchClauseOrderDescShouldReturnMatchOrder() {
Storm_Query::order_match_desc('login, role', Storm_Query::terms(['ADMIN', 'INVITE']))
->from($this->_loader)
Storm_Query::from($this->_loader)
->order_match_desc((new Storm_Query_MatchBoolean('login, role'))
->against(['ADMIN', 'INVITE']))
->fetchAll();
$this->assertEquals(['MATCH(login, role) AGAINST(\'ADMIN INVITE\' IN BOOLEAN MODE) desc'],
......@@ -751,8 +762,8 @@ class Storm_Test_LoaderQueryGroupByTest extends Storm_Test_LoaderTestCase {
/** @test */
public function withGroupByLoaderShouldCallGroupOnDbSelect() {
Storm_Query::group('name')
->from($this->_loader)
Storm_Query::from($this->_loader)
->group('name')
->fetchAll();
$this->assertEquals(['name'],
......
This diff is collapsed.