Skip to content

Commit 73fc866

Browse files
committed
QueryEvaluator
1 parent 4e8c47c commit 73fc866

File tree

5 files changed

+86
-20
lines changed

5 files changed

+86
-20
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
## 2.0.1
1+
## 2.1.0
22

3-
- Naming consistency refactor: `FieldScopeQuery` is returned instead of `FieldScope` (kept and deprecated for compatibility for now).
3+
- Naming consistency refactor:
4+
- `ScopeQuery` is returned instead of `FieldScope`.
5+
- `CompareQuery` is returned instead of `FieldCompareQuery`.
6+
- Old classes are kept in compatibility mode and are deprecated.
7+
- Added `QueryEvaluator` to help evaluating queries.
48

59
## 2.0.0
610

lib/src/ast.dart

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ class SourcePosition {
1212
int get length => end - start;
1313
}
1414

15+
/// Provides an interface for generic query evaluation.
16+
abstract class QueryEvaluator<R> {
17+
R evalText(TextQuery query);
18+
R evalPhrase(PhraseQuery query);
19+
R evalScope(ScopeQuery query);
20+
R evalCompare(CompareQuery query);
21+
R evalRange(RangeQuery query);
22+
R evalNot(NotQuery query);
23+
R evalGroup(GroupQuery query);
24+
R evalAnd(AndQuery query);
25+
R evalOr(OrQuery query);
26+
}
27+
1528
/// Base interface for queries.
1629
abstract class Query {
1730
const Query({
@@ -35,6 +48,8 @@ abstract class Query {
3548
///
3649
/// If the [Query] cannot be cast to [R] it will throw an exception.
3750
R cast<R extends Query>() => this as R;
51+
52+
R eval<R>(QueryEvaluator<R> evaluator);
3853
}
3954

4055
/// Text query to match [text].
@@ -45,6 +60,9 @@ class TextQuery extends Query {
4560
required super.position,
4661
});
4762

63+
@override
64+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalText(this);
65+
4866
@override
4967
String toString({bool debug = false}) => _debug(debug, text);
5068
}
@@ -58,13 +76,16 @@ class PhraseQuery extends TextQuery {
5876
required super.position,
5977
});
6078

79+
@override
80+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalPhrase(this);
81+
6182
@override
6283
String toString({bool debug = false}) =>
6384
'"${children.map((n) => n.toString(debug: debug)).join(' ')}"';
6485
}
6586

6687
/// Scopes [child] [Query] to be applied only on the [field].
67-
@Deprecated('Use FieldScopeQuery instead.')
88+
@Deprecated('Use ScopeQuery instead.')
6889
class FieldScope extends Query {
6990
final TextQuery field;
7091
final Query child;
@@ -75,22 +96,30 @@ class FieldScope extends Query {
7596
required super.position,
7697
});
7798

99+
@override
100+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator
101+
.evalScope(ScopeQuery(field: field, child: child, position: position));
102+
78103
@override
79104
String toString({bool debug = false}) =>
80105
'$field:${child.toString(debug: debug)}';
81106
}
82107

83108
/// Scopes [child] [Query] to be applied only on the [field].
84109
// ignore: deprecated_member_use_from_same_package
85-
class FieldScopeQuery extends FieldScope {
86-
const FieldScopeQuery({
110+
class ScopeQuery extends FieldScope {
111+
const ScopeQuery({
87112
required super.field,
88113
required super.child,
89114
required super.position,
90115
});
116+
117+
@override
118+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalScope(this);
91119
}
92120

93121
/// Describes a [field] [operator] [text] tripled (e.g. year < 2000).
122+
@Deprecated('Use CompareQuery instead.')
94123
class FieldCompareQuery extends Query {
95124
final TextQuery field;
96125
final TextQuery operator;
@@ -103,11 +132,29 @@ class FieldCompareQuery extends Query {
103132
required super.position,
104133
});
105134

135+
@override
136+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalCompare(CompareQuery(
137+
field: field, operator: operator, text: text, position: position));
138+
106139
@override
107140
String toString({bool debug = false}) =>
108141
_debug(debug, '$field$operator$text');
109142
}
110143

144+
/// Describes a [field] [operator] [text] tripled (e.g. year < 2000).
145+
// ignore: deprecated_member_use_from_same_package
146+
class CompareQuery extends FieldCompareQuery {
147+
CompareQuery({
148+
required super.field,
149+
required super.operator,
150+
required super.text,
151+
required super.position,
152+
});
153+
154+
@override
155+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalCompare(this);
156+
}
157+
111158
/// Describes a range query between [start] and [end].
112159
class RangeQuery extends Query {
113160
final TextQuery start;
@@ -123,6 +170,9 @@ class RangeQuery extends Query {
123170
this.endInclusive = true,
124171
});
125172

173+
@override
174+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalRange(this);
175+
126176
@override
127177
String toString({bool debug = false}) => _debug(
128178
debug,
@@ -142,6 +192,9 @@ class NotQuery extends Query {
142192
required super.position,
143193
});
144194

195+
@override
196+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalNot(this);
197+
145198
@override
146199
String toString({bool debug = false}) => '-${child.toString(debug: debug)}';
147200
}
@@ -154,6 +207,9 @@ class GroupQuery extends Query {
154207
required super.position,
155208
});
156209

210+
@override
211+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalGroup(this);
212+
157213
@override
158214
String toString({bool debug = false}) => '(${child.toString(debug: debug)})';
159215
}
@@ -167,6 +223,9 @@ class AndQuery extends Query {
167223
required super.position,
168224
});
169225

226+
@override
227+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalAnd(this);
228+
170229
@override
171230
String toString({bool debug = false}) =>
172231
'(${children.map((n) => n.toString(debug: debug)).join(' ')})';
@@ -181,6 +240,9 @@ class OrQuery extends Query {
181240
required super.position,
182241
});
183242

243+
@override
244+
R eval<R>(QueryEvaluator<R> evaluator) => evaluator.evalOr(this);
245+
184246
@override
185247
String toString({bool debug = false}) =>
186248
'(${children.map((n) => n.toString(debug: debug)).join(' OR ')})';

lib/src/grammar.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class QueryGrammarDefinition extends GrammarDefinition {
5959
ref0(exclusion).orEmptyTextQuery();
6060
return g.token().map((list) => list.value.first == null
6161
? list.value.last as Query
62-
: FieldScopeQuery(
62+
: ScopeQuery(
6363
field: list.value.first as TextQuery,
6464
child: list.value.last as Query,
6565
position: SourcePosition(list.start, list.stop)));
@@ -99,13 +99,13 @@ class QueryGrammarDefinition extends GrammarDefinition {
9999
position: SourcePosition(list.start, list.stop)));
100100
}
101101

102-
Parser<FieldCompareQuery> comparison() {
102+
Parser<CompareQuery> comparison() {
103103
final g = ref0(IDENTIFIER).textQuery() &
104104
ref0(EXP_SEP).optional() &
105105
ref0(COMP_OPERATOR).textQuery() &
106106
ref0(EXP_SEP).optional() &
107107
ref0(wordOrExact).orEmptyTextQuery();
108-
return g.token().map((list) => FieldCompareQuery(
108+
return g.token().map((list) => CompareQuery(
109109
field: list.value[0] as TextQuery,
110110
operator: list.value[2] as TextQuery,
111111
text: list.value[4] as TextQuery,

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: query
22
description: >
33
Search query parser to implement customized search.
44
Supports boolean groups, field scopes, ranges, comparisons...
5-
version: 2.0.1
5+
version: 2.1.0
66
homepage: https://github.com/isoos/query
77

88
environment:

test/query_test.dart

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,38 +69,38 @@ void main() {
6969
});
7070

7171
test('scoped', () {
72-
parseQuery('a:abc').expect<FieldScopeQuery>('a:<abc>', 0, 5)
72+
parseQuery('a:abc').expect<ScopeQuery>('a:<abc>', 0, 5)
7373
..field.expect<TextQuery>('<a>', 0, 1)
7474
..child.expect<TextQuery>('<abc>', 2, 5);
75-
parseQuery('a:"abc"').expect<FieldScopeQuery>('a:"<abc>"', 0, 7);
76-
parseQuery('a:"abc 1"').expect<FieldScopeQuery>('a:"<abc> <1>"', 0, 9);
77-
parseQuery('a:-"abc 1"').expect<FieldScopeQuery>('a:-"<abc> <1>"', 0, 10);
75+
parseQuery('a:"abc"').expect<ScopeQuery>('a:"<abc>"', 0, 7);
76+
parseQuery('a:"abc 1"').expect<ScopeQuery>('a:"<abc> <1>"', 0, 9);
77+
parseQuery('a:-"abc 1"').expect<ScopeQuery>('a:-"<abc> <1>"', 0, 10);
7878
parseQuery('NOT field:abc')
7979
.expect<NotQuery>('-field:<abc>', 0, 13)
8080
.child
81-
.expect<FieldScopeQuery>('field:<abc>', 4, 13)
81+
.expect<ScopeQuery>('field:<abc>', 4, 13)
8282
..field.expect<TextQuery>('<field>', 4, 9)
8383
..child.expect<TextQuery>('<abc>', 10, 13);
84-
parseQuery('a:').expect<FieldScopeQuery>('a:<>', 0, 2);
84+
parseQuery('a:').expect<ScopeQuery>('a:<>', 0, 2);
8585
parseQuery('a: AND a').expect<AndQuery>('(a:<> <a>)', 0, 8);
8686
});
8787

8888
test('special scoped', () {
89-
parseQuery('a*:abc').expect<FieldScopeQuery>('a*:<abc>', 0, 6);
90-
parseQuery('a%:"abc"').expect<FieldScopeQuery>('a%:"<abc>"', 0, 8);
89+
parseQuery('a*:abc').expect<ScopeQuery>('a*:<abc>', 0, 6);
90+
parseQuery('a%:"abc"').expect<ScopeQuery>('a%:"<abc>"', 0, 8);
9191
});
9292

9393
test('compare', () {
94-
parseQuery('year < 2000').expect<FieldCompareQuery>('<year<2000>', 0, 11)
94+
parseQuery('year < 2000').expect<CompareQuery>('<year<2000>', 0, 11)
9595
..field.expect<TextQuery>('<year>', 0, 4)
9696
..operator.expect<TextQuery>('<<>', 5, 6)
9797
..text.expect<TextQuery>('<2000>', 7, 11);
9898
parseQuery('field >= "test case"')
99-
.expect<FieldCompareQuery>('<field>="test case">', 0, 20)
99+
.expect<CompareQuery>('<field>="test case">', 0, 20)
100100
..field.expect<TextQuery>('<field>', 0, 5)
101101
..operator.expect<TextQuery>('<>=>', 6, 8)
102102
..text.expect<PhraseQuery>('"<test> <case>"', 9, 20);
103-
parseQuery('year = ').expect<FieldCompareQuery>('<year=>', 0, 7);
103+
parseQuery('year = ').expect<CompareQuery>('<year=>', 0, 7);
104104
});
105105

106106
test('range', () {

0 commit comments

Comments
 (0)