agnostic_backend 0.9.9 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/agnostic_backend/queryable/cloudsearch/executor.rb +13 -1
- data/lib/agnostic_backend/queryable/cloudsearch/query.rb +9 -2
- data/lib/agnostic_backend/queryable/cloudsearch/query_builder.rb +2 -2
- data/lib/agnostic_backend/queryable/cloudsearch/simple_visitor.rb +130 -0
- data/lib/agnostic_backend/queryable/cloudsearch/visitor.rb +4 -0
- data/lib/agnostic_backend/queryable/criteria/binary.rb +9 -0
- data/lib/agnostic_backend/queryable/criteria_builder.rb +4 -0
- data/lib/agnostic_backend/queryable/elasticsearch/query.rb +1 -1
- data/lib/agnostic_backend/queryable/elasticsearch/query_builder.rb +2 -2
- data/lib/agnostic_backend/queryable/executor.rb +9 -2
- data/lib/agnostic_backend/queryable/expressions/expression.rb +11 -0
- data/lib/agnostic_backend/queryable/query.rb +4 -1
- data/lib/agnostic_backend/queryable/query_builder.rb +13 -3
- data/lib/agnostic_backend/queryable/validator.rb +9 -0
- data/lib/agnostic_backend/queryable/visitor.rb +7 -0
- data/lib/agnostic_backend/version.rb +1 -1
- data/lib/agnostic_backend.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 411f2aeb7e28494accdde867a4e9ada54c1afd10
|
4
|
+
data.tar.gz: 99f6f24769f66ccdc45aa0ba7102f73a6478da3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e89af91cd5444b63a78be5247636c932aaf2faf6de4684196ef03b56167a7625bfe13256d10d5674aa5924e8f1d47e60d6ce72663b4433a72e6f3de7651509b
|
7
|
+
data.tar.gz: fe6ce999953541727dcf2a7cb5c1f14708ec4918deed31c7390d98226eef8b5dcaa4b3ecaa38627513d10b035b3ea5694ac6f70ef517464845822d9dadea43a5
|
@@ -16,11 +16,13 @@ module AgnosticBackend
|
|
16
16
|
def to_s
|
17
17
|
result = ''
|
18
18
|
result += "search?q=#{query_expression}" if query_expression
|
19
|
+
result += " filter=#{filter_query}" if filter_query
|
19
20
|
result += " return=#{return_expression}" if return_expression
|
20
21
|
result += " sort=#{sort}" if sort
|
21
22
|
result += " size=#{size}" if size
|
22
23
|
result += " offset=#{start}" if start
|
23
24
|
result += " cursor=#{scroll_cursor}" if scroll_cursor
|
25
|
+
result += " parser=#{query_parser}"
|
24
26
|
result
|
25
27
|
end
|
26
28
|
|
@@ -44,11 +46,16 @@ module AgnosticBackend
|
|
44
46
|
|
45
47
|
private
|
46
48
|
|
49
|
+
def filter_visitor
|
50
|
+
options[:filter_visitor]
|
51
|
+
end
|
52
|
+
|
47
53
|
def client
|
48
54
|
query.context.index.cloudsearch_domain_client
|
49
55
|
end
|
50
56
|
|
51
57
|
def filter_query
|
58
|
+
filter_expression.accept(filter_visitor) if filter_expression
|
52
59
|
end
|
53
60
|
|
54
61
|
def query_expression
|
@@ -80,7 +87,12 @@ module AgnosticBackend
|
|
80
87
|
end
|
81
88
|
|
82
89
|
def query_parser
|
83
|
-
|
90
|
+
case visitor
|
91
|
+
when SimpleVisitor
|
92
|
+
'simple'
|
93
|
+
else
|
94
|
+
'structured'
|
95
|
+
end
|
84
96
|
end
|
85
97
|
|
86
98
|
def return_expression
|
@@ -3,9 +3,16 @@ module AgnosticBackend
|
|
3
3
|
module Cloudsearch
|
4
4
|
class Query < AgnosticBackend::Queryable::Query
|
5
5
|
|
6
|
-
def initialize(base)
|
6
|
+
def initialize(base, **options)
|
7
7
|
super
|
8
|
-
|
8
|
+
case options[:parser]
|
9
|
+
when :simple
|
10
|
+
@executor = Executor.new(self, SimpleVisitor.new, filter_visitor: Visitor.new)
|
11
|
+
when :structured
|
12
|
+
@executor = Executor.new(self, Visitor.new, filter_visitor: Visitor.new)
|
13
|
+
else
|
14
|
+
@executor = Executor.new(self, Visitor.new, filter_visitor: Visitor.new)
|
15
|
+
end
|
9
16
|
end
|
10
17
|
|
11
18
|
def execute
|
@@ -4,8 +4,8 @@ module AgnosticBackend
|
|
4
4
|
class QueryBuilder < AgnosticBackend::Queryable::QueryBuilder
|
5
5
|
private
|
6
6
|
|
7
|
-
def create_query(context)
|
8
|
-
AgnosticBackend::Queryable::Cloudsearch::Query.new(context)
|
7
|
+
def create_query(context, **options)
|
8
|
+
AgnosticBackend::Queryable::Cloudsearch::Query.new(context, **options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module AgnosticBackend
|
2
|
+
module Queryable
|
3
|
+
module Cloudsearch
|
4
|
+
class SimpleVisitor < AgnosticBackend::Queryable::Visitor
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def visit_criteria_equal(subject)
|
9
|
+
raise UnsupportedNodeError
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_criteria_not_equal(subject)
|
13
|
+
raise UnsupportedNodeError
|
14
|
+
end
|
15
|
+
|
16
|
+
def visit_criteria_greater(subject)
|
17
|
+
raise UnsupportedNodeError
|
18
|
+
end
|
19
|
+
|
20
|
+
def visit_criteria_less(subject)
|
21
|
+
raise UnsupportedNodeError
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit_criteria_greater_equal(subject)
|
25
|
+
raise UnsupportedNodeError
|
26
|
+
end
|
27
|
+
|
28
|
+
def visit_criteria_less_equal(subject)
|
29
|
+
raise UnsupportedNodeError
|
30
|
+
end
|
31
|
+
|
32
|
+
def visit_criteria_greater_and_less(subject)
|
33
|
+
raise UnsupportedNodeError
|
34
|
+
end
|
35
|
+
|
36
|
+
def visit_criteria_greater_equal_and_less(subject)
|
37
|
+
raise UnsupportedNodeError
|
38
|
+
end
|
39
|
+
|
40
|
+
def visit_criteria_greater_and_less_equal(subject)
|
41
|
+
raise UnsupportedNodeError
|
42
|
+
end
|
43
|
+
|
44
|
+
def visit_criteria_greater_equal_and_less_equal(subject)
|
45
|
+
raise UnsupportedNodeError
|
46
|
+
end
|
47
|
+
|
48
|
+
def visit_criteria_contains(subject)
|
49
|
+
raise UnsupportedNodeError
|
50
|
+
end
|
51
|
+
|
52
|
+
def visit_criteria_starts(subject)
|
53
|
+
raise UnsupportedAttributeError unless subject.attribute.any?
|
54
|
+
"#{visit(subject.value)}*"
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_criteria_free_text(subject)
|
58
|
+
raise UnsupportedAttributeError unless subject.attribute.any?
|
59
|
+
"#{visit(subject.value)}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def visit_criteria_fuzzy(subject)
|
63
|
+
raise UnsupportedAttributeError unless subject.attribute.any?
|
64
|
+
"#{visit(subject.value)}~#{subject.fuzziness}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_operations_not(subject)
|
68
|
+
raise UnsupportedNodeError
|
69
|
+
end
|
70
|
+
|
71
|
+
def visit_operations_and(subject)
|
72
|
+
raise UnsupportedNodeError
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_operations_or(subject)
|
76
|
+
raise UnsupportedNodeError
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_operations_ascending(subject)
|
80
|
+
"#{visit(subject.attribute)} asc"
|
81
|
+
end
|
82
|
+
|
83
|
+
def visit_operations_descending(subject)
|
84
|
+
"#{visit(subject.attribute)} desc"
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit_query(subject)
|
88
|
+
"#{subject.children.map{|c| visit(c)}.join(' ')}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def visit_expressions_where(subject)
|
92
|
+
visit(subject.criterion) #search?q=
|
93
|
+
end
|
94
|
+
|
95
|
+
def visit_expressions_select(subject)
|
96
|
+
"#{subject.projections.map{|c| visit(c)}.join(',')}" #return=
|
97
|
+
end
|
98
|
+
|
99
|
+
def visit_expressions_order(subject)
|
100
|
+
"#{subject.qualifiers.map{|c| visit(c)}.join(',')}" #sort=
|
101
|
+
end
|
102
|
+
|
103
|
+
def visit_expressions_limit(subject)
|
104
|
+
visit(subject.limit) #size=
|
105
|
+
end
|
106
|
+
|
107
|
+
def visit_expressions_offset(subject)
|
108
|
+
visit(subject.offset) #offset=
|
109
|
+
end
|
110
|
+
|
111
|
+
def visit_expressions_scroll_cursor(subject)
|
112
|
+
visit(subject.scroll_cursor) #cursor=
|
113
|
+
end
|
114
|
+
|
115
|
+
def visit_attribute(subject)
|
116
|
+
subject.name.split('.').join('__')
|
117
|
+
end
|
118
|
+
|
119
|
+
def visit_value(subject)
|
120
|
+
case subject.type
|
121
|
+
when :string,:string_array,:text,:text_array
|
122
|
+
subject.value
|
123
|
+
else
|
124
|
+
subject.value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -89,6 +89,10 @@ module AgnosticBackend
|
|
89
89
|
visit(subject.criterion) #search?q=
|
90
90
|
end
|
91
91
|
|
92
|
+
def visit_expressions_filter(subject)
|
93
|
+
visit(subject.criterion)
|
94
|
+
end
|
95
|
+
|
92
96
|
def visit_expressions_select(subject)
|
93
97
|
"#{subject.projections.map{|c| visit(c)}.join(',')}" #return=
|
94
98
|
end
|
@@ -45,6 +45,15 @@ module AgnosticBackend
|
|
45
45
|
|
46
46
|
class FreeText < Relational;
|
47
47
|
end
|
48
|
+
|
49
|
+
class Fuzzy < Relational
|
50
|
+
attr_reader :fuzziness
|
51
|
+
|
52
|
+
def initialize(attribute:, value:, context: nil, fuzziness: 1)
|
53
|
+
@fuzziness = fuzziness
|
54
|
+
super(attribute: attribute, value: value, context: context)
|
55
|
+
end
|
56
|
+
end
|
48
57
|
end
|
49
58
|
end
|
50
59
|
end
|
@@ -60,6 +60,10 @@ module AgnosticBackend
|
|
60
60
|
Criteria::FreeText.new(attribute: attribute, value: value, context: context)
|
61
61
|
end
|
62
62
|
|
63
|
+
def fuzzy(attribute, value, fuzziness)
|
64
|
+
Criteria::Fuzzy.new(attribute: attribute, value: value, context: context, fuzziness: fuzziness)
|
65
|
+
end
|
66
|
+
|
63
67
|
def asc(attribute)
|
64
68
|
Operations::Ascending.new(attribute: attribute, context: context)
|
65
69
|
end
|
@@ -4,8 +4,8 @@ module AgnosticBackend
|
|
4
4
|
class QueryBuilder < AgnosticBackend::Queryable::QueryBuilder
|
5
5
|
private
|
6
6
|
|
7
|
-
def create_query(context)
|
8
|
-
AgnosticBackend::Queryable::Elasticsearch::Query.new(context)
|
7
|
+
def create_query(context, **options)
|
8
|
+
AgnosticBackend::Queryable::Elasticsearch::Query.new(context, **options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -4,9 +4,12 @@ module AgnosticBackend
|
|
4
4
|
|
5
5
|
attr_reader :query
|
6
6
|
attr_reader :visitor
|
7
|
+
attr_reader :options
|
7
8
|
|
8
|
-
def initialize(query, visitor)
|
9
|
-
@query
|
9
|
+
def initialize(query, visitor, **options)
|
10
|
+
@query = query
|
11
|
+
@visitor = visitor
|
12
|
+
@options = options
|
10
13
|
end
|
11
14
|
|
12
15
|
def execute
|
@@ -38,6 +41,10 @@ module AgnosticBackend
|
|
38
41
|
def scroll_cursor_expression
|
39
42
|
query.children.find { |e| e.is_a? Expressions::ScrollCursor }
|
40
43
|
end
|
44
|
+
|
45
|
+
def filter_expression
|
46
|
+
query.children.find { |e| e.is_a? Expressions::Filter }
|
47
|
+
end
|
41
48
|
end
|
42
49
|
end
|
43
50
|
end
|
@@ -14,6 +14,17 @@ module AgnosticBackend
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
|
18
|
+
class Filter < Expression
|
19
|
+
def initialize(criterion:, context:)
|
20
|
+
super([criterion], context)
|
21
|
+
end
|
22
|
+
|
23
|
+
def criterion
|
24
|
+
children.first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
class Select < Expression
|
18
29
|
def initialize(attributes:, context:)
|
19
30
|
super(attributes.map { |a| Attribute.new(a, parent: self, context: context) }, context)
|
@@ -3,11 +3,14 @@ module AgnosticBackend
|
|
3
3
|
class Query < TreeNode
|
4
4
|
attr_accessor :errors
|
5
5
|
attr_reader :context
|
6
|
+
attr_reader :executor
|
7
|
+
attr_reader :options
|
6
8
|
|
7
|
-
def initialize(context)
|
9
|
+
def initialize(context, **options)
|
8
10
|
super()
|
9
11
|
@errors ||= Hash.new { |hash, key| hash[key] = Array.new }
|
10
12
|
@context = context
|
13
|
+
@options = options
|
11
14
|
end
|
12
15
|
|
13
16
|
def execute
|
@@ -43,13 +43,19 @@ module AgnosticBackend
|
|
43
43
|
self
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
47
|
-
|
46
|
+
def filter(filter)
|
47
|
+
@filter = filter
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def build(**options)
|
52
|
+
query = create_query(self, **options)
|
48
53
|
query.children << build_where_expression if @criterion
|
49
54
|
query.children << build_select_expression if @projections
|
50
55
|
query.children << build_order_expression if @order_qualifiers
|
51
56
|
query.children << build_limit_expression if @limit
|
52
57
|
query.children << build_offset_expression if @offset
|
58
|
+
query.children << build_filter_expression if @filter
|
53
59
|
query.children << build_scroll_cursor_expression if @scroll_cursor
|
54
60
|
|
55
61
|
@query = query
|
@@ -57,7 +63,7 @@ module AgnosticBackend
|
|
57
63
|
|
58
64
|
private
|
59
65
|
|
60
|
-
def create_query(context)
|
66
|
+
def create_query(context, **options)
|
61
67
|
raise NotImplementedError, 'AbstractMethod'
|
62
68
|
end
|
63
69
|
|
@@ -65,6 +71,10 @@ module AgnosticBackend
|
|
65
71
|
Expressions::Where.new(criterion: @criterion, context: self)
|
66
72
|
end
|
67
73
|
|
74
|
+
def build_filter_expression
|
75
|
+
Expressions::Filter.new(criterion: @filter, context: self)
|
76
|
+
end
|
77
|
+
|
68
78
|
def build_select_expression
|
69
79
|
Expressions::Select.new(attributes: @projections, context: self)
|
70
80
|
end
|
@@ -84,6 +84,11 @@ module AgnosticBackend
|
|
84
84
|
visit(subject.value)
|
85
85
|
end
|
86
86
|
|
87
|
+
def visit_criteria_fuzzy(subject)
|
88
|
+
visit(subject.attribute)
|
89
|
+
visit(subject.value)
|
90
|
+
end
|
91
|
+
|
87
92
|
def visit_operations_not(subject)
|
88
93
|
visit(subject.operand)
|
89
94
|
end
|
@@ -108,6 +113,10 @@ module AgnosticBackend
|
|
108
113
|
visit(subject.criterion)
|
109
114
|
end
|
110
115
|
|
116
|
+
def visit_expressions_filter(subject)
|
117
|
+
visit(subject.criterion)
|
118
|
+
end
|
119
|
+
|
111
120
|
def visit_expressions_select(subject)
|
112
121
|
subject.projections.each { |c| visit(c) }
|
113
122
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module AgnosticBackend
|
2
2
|
module Queryable
|
3
|
+
class UnsupportedNodeError < StandardError; end
|
4
|
+
class UnsupportedAttributeError < StandardError; end
|
5
|
+
|
3
6
|
class Visitor
|
4
7
|
def visit(subject)
|
5
8
|
method_name = class_to_method_name(subject.class)
|
@@ -96,6 +99,10 @@ module AgnosticBackend
|
|
96
99
|
raise NotImplementedError
|
97
100
|
end
|
98
101
|
|
102
|
+
def visit_expressions_filter(subject)
|
103
|
+
raise NotImplementedError
|
104
|
+
end
|
105
|
+
|
99
106
|
def visit_expressions_select(subject)
|
100
107
|
raise NotImplementedError
|
101
108
|
end
|
data/lib/agnostic_backend.rb
CHANGED
@@ -40,6 +40,8 @@ require 'agnostic_backend/queryable/cloudsearch/query'
|
|
40
40
|
require 'agnostic_backend/queryable/cloudsearch/query_builder'
|
41
41
|
require 'agnostic_backend/queryable/cloudsearch/result_set'
|
42
42
|
require 'agnostic_backend/queryable/cloudsearch/visitor'
|
43
|
+
require 'agnostic_backend/queryable/cloudsearch/simple_visitor'
|
44
|
+
|
43
45
|
|
44
46
|
require 'agnostic_backend/cloudsearch/index'
|
45
47
|
require 'agnostic_backend/cloudsearch/index_field'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agnostic_backend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iasonas Gavriilidis
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-10-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -171,6 +171,7 @@ files:
|
|
171
171
|
- lib/agnostic_backend/queryable/cloudsearch/query.rb
|
172
172
|
- lib/agnostic_backend/queryable/cloudsearch/query_builder.rb
|
173
173
|
- lib/agnostic_backend/queryable/cloudsearch/result_set.rb
|
174
|
+
- lib/agnostic_backend/queryable/cloudsearch/simple_visitor.rb
|
174
175
|
- lib/agnostic_backend/queryable/cloudsearch/visitor.rb
|
175
176
|
- lib/agnostic_backend/queryable/criteria/binary.rb
|
176
177
|
- lib/agnostic_backend/queryable/criteria/criterion.rb
|