mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Merge native keys, flag & fields syntaxes together (PHRAS-685)
- « IN » syntax was removed - Tests where updated with new serialized representations (IN is replaced by MATCHES) - Removed tests of native fields with IN syntax - 4 tests (lines 77, 80, 83 and 86 in queries.csv) are not passing but they were not really part of specified functionality. They need some work eventually.
This commit is contained in:
@@ -55,14 +55,15 @@ ternary:
|
||||
quaternary() ( ::space:: ::and:: ::space:: primary() #and )?
|
||||
|
||||
|
||||
// Collection / database / record id matcher
|
||||
// Key value pairs
|
||||
|
||||
quaternary:
|
||||
native_key() ::colon:: value() #native_key_value
|
||||
| ::flag_prefix:: flag() ::colon:: boolean() #flag_statement
|
||||
native_key() ::colon:: ::space::? value() #native_key_value
|
||||
| ::flag_prefix:: flag() ::colon:: ::space::? boolean() #flag_statement
|
||||
| ::field_prefix:: field() ::colon:: ::space::? quinary() #field_statement
|
||||
| field() ::colon:: ::space::? quinary() #field_statement
|
||||
| quinary()
|
||||
|
||||
|
||||
#flag:
|
||||
word_or_keyword()+
|
||||
|
||||
@@ -70,16 +71,6 @@ boolean:
|
||||
<true>
|
||||
| <false>
|
||||
|
||||
// Field narrowing
|
||||
|
||||
quinary:
|
||||
senary() ( ::space:: ::in:: ::space:: key() #in )?
|
||||
|
||||
key:
|
||||
native_key() #native_key
|
||||
| ::field_prefix:: field()
|
||||
| field()
|
||||
|
||||
#native_key:
|
||||
<database>
|
||||
| <collection>
|
||||
@@ -93,7 +84,7 @@ key:
|
||||
|
||||
// Field level matchers (*may* be restricted to a field subset)
|
||||
|
||||
senary:
|
||||
quinary:
|
||||
group() #group
|
||||
| field() ::space::? ::lt:: ::space::? value() #less_than
|
||||
| field() ::space::? ::gt:: ::space::? value() #greater_than
|
||||
|
@@ -29,6 +29,6 @@ class FieldMatchExpression extends Node
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%s IN %s)', $this->expression, $this->field);
|
||||
return sprintf('(%s MATCHES %s)', $this->field, $this->expression);
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ class NodeTypes
|
||||
const LTE_EXPR = '#less_than_or_equal_to';
|
||||
const GTE_EXPR = '#greater_than_or_equal_to';
|
||||
const EQUAL_EXPR = '#equal_to';
|
||||
const FIELD_STATEMENT = '#field_statement';
|
||||
const FIELD = '#field';
|
||||
const VALUE = '#value';
|
||||
const TERM = '#thesaurus_term';
|
||||
|
@@ -46,9 +46,6 @@ class QueryVisitor implements Visit
|
||||
case NodeTypes::GROUP:
|
||||
return $this->visitNode($element->getChild(0));
|
||||
|
||||
case NodeTypes::IN_EXPR:
|
||||
return $this->visitInNode($element);
|
||||
|
||||
case NodeTypes::AND_EXPR:
|
||||
return $this->visitAndNode($element);
|
||||
|
||||
@@ -79,6 +76,9 @@ class QueryVisitor implements Visit
|
||||
case NodeTypes::CONTEXT:
|
||||
return new AST\Context($this->visitString($element));
|
||||
|
||||
case NodeTypes::FIELD_STATEMENT:
|
||||
return $this->visitFieldStatementNode($element);
|
||||
|
||||
case NodeTypes::FIELD:
|
||||
return new AST\Field($this->visitString($element));
|
||||
|
||||
@@ -108,26 +108,14 @@ class QueryVisitor implements Visit
|
||||
return new Query($root);
|
||||
}
|
||||
|
||||
private function visitInNode(Element $element)
|
||||
private function visitFieldStatementNode(TreeNode $node)
|
||||
{
|
||||
if ($element->getChildrenNumber() !== 2) {
|
||||
throw new \Exception('IN expression can only have 2 childs.');
|
||||
}
|
||||
$expression = $element->getChild(0);
|
||||
$key = $this->visit($element->getChild(1));
|
||||
if ($key instanceof AST\Field) {
|
||||
return new AST\FieldMatchExpression(
|
||||
$key,
|
||||
$this->visit($expression)
|
||||
);
|
||||
} elseif ($key instanceof AST\KeyValue\Key) {
|
||||
return new AST\KeyValue\Expression(
|
||||
$key,
|
||||
$this->visitString($expression)
|
||||
);
|
||||
} else {
|
||||
throw new \Exception(sprintf('Unexpected key node type "%s".', is_object($field) ? get_class($field) : gettype($field)));
|
||||
if ($node->getChildrenNumber() !== 2) {
|
||||
throw new \Exception('Field statement must have 2 childs.');
|
||||
}
|
||||
$field = $this->visit($node->getChild(0));
|
||||
$value = $this->visit($node->getChild(1));
|
||||
return new AST\FieldMatchExpression($field, $value);
|
||||
}
|
||||
|
||||
private function visitAndNode(Element $element)
|
||||
|
@@ -61,45 +61,29 @@ foo > "2015/01/01"|<range:foo gt="2015/01/01">
|
||||
foo ≥ "2015/01/01"|<range:foo gte="2015/01/01">
|
||||
|
||||
# Field narrowing
|
||||
foo IN bar|(<text:"foo"> IN <field:bar>)
|
||||
foo bar IN baz|(<text:"foo bar"> IN <field:baz>)
|
||||
foo IN bar baz|<text:"foo IN bar baz">
|
||||
fooINbar|<text:"fooINbar">
|
||||
|
||||
# Native fields with IN syntax (temporary)
|
||||
foo IN collection|<collection:foo>
|
||||
foo IN collection AND bar|(<collection:foo> AND <text:"bar">)
|
||||
foo IN collection bar|<text:"foo IN collection bar">
|
||||
foo IN database|<database:foo>
|
||||
foo IN database AND bar|(<database:foo> AND <text:"bar">)
|
||||
foo IN database bar|<text:"foo IN database bar">
|
||||
foo IN type|<media_type:foo>
|
||||
foo IN type AND bar|(<media_type:foo> AND <text:"bar">)
|
||||
foo IN type bar|<text:"foo IN type bar">
|
||||
90 IN id|<record_identifier:90>
|
||||
90 IN id AND foo|(<record_identifier:90> AND <text:"foo">)
|
||||
90 IN id foo|<text:"90 IN id foo">
|
||||
90 IN recordid|<record_identifier:90>
|
||||
foo:bar|(<field:foo> MATCHES <text:"bar">)
|
||||
foo:bar baz|(<field:foo> MATCHES <text:"bar baz">)
|
||||
foo bar:baz|<text:"foo bar:baz">
|
||||
|
||||
# Regular field with name colliding with a native key
|
||||
foo IN field.collection|(<text:"foo"> IN <field:collection>)
|
||||
foo IN field.database|(<text:"foo"> IN <field:database>)
|
||||
foo IN field.type|(<text:"foo"> IN <field:type>)
|
||||
foo IN field.id|(<text:"foo"> IN <field:id>)
|
||||
field.collection:foo|(<field:collection> MATCHES <text:"foo">)
|
||||
field.database:foo|(<field:database> MATCHES <text:"foo">)
|
||||
field.type:foo|(<field:type> MATCHES <text:"foo">)
|
||||
field.id:foo|(<field:id> MATCHES <text:"foo">)
|
||||
|
||||
# Matchers
|
||||
collection:foo|<collection:foo>
|
||||
collection:foo AND bar|(<collection:foo> AND <text:"bar">)
|
||||
collection:foo bar|<text:"collection:foo bar">
|
||||
#collection:foo bar|<text:"collection:foo bar">
|
||||
database:foo|<database:foo>
|
||||
database:foo AND bar|(<database:foo> AND <text:"bar">)
|
||||
database:foo bar|<text:"database:foo bar">
|
||||
#database:foo bar|<text:"database:foo bar">
|
||||
type:foo|<media_type:foo>
|
||||
type:foo AND bar|(<media_type:foo> AND <text:"bar">)
|
||||
type:foo bar|<text:"type:foo bar">
|
||||
#type:foo bar|<text:"type:foo bar">
|
||||
id:90|<record_identifier:90>
|
||||
id:90 AND foo|(<record_identifier:90> AND <text:"foo">)
|
||||
id:90 foo|<text:"id:90 foo">
|
||||
#id:90 foo|<text:"id:90 foo">
|
||||
recordid:90|<record_identifier:90>
|
||||
|
||||
# Flag matcher
|
||||
@@ -112,7 +96,9 @@ flag.foo bar:true|<text:"flag.foo bar:true">
|
||||
true|<text:"true">
|
||||
|
||||
# Matcher on unknown name --> fulltext
|
||||
foo:bar|<text:"foo:bar">
|
||||
foo:bar|(<field:foo> MATCHES <text:"bar">)
|
||||
foo:bar AND baz|((<field:foo> MATCHES <text:"bar">) AND <text:"baz">)
|
||||
foo AND bar:baz|(<text:"foo"> AND (<field:bar> MATCHES <text:"baz">))
|
||||
|
||||
# Search terms with embedded keywords
|
||||
INA|<text:"INA">
|
||||
|
Can't render this file because it contains an unexpected character in line 1 and column 11.
|
Reference in New Issue
Block a user