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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ed2f8294a4e610eb4603d376fb93a6e6d2e96e4
4
- data.tar.gz: f6e47ceafa6f3777bbcddd2f019e514ebbd01330
3
+ metadata.gz: 411f2aeb7e28494accdde867a4e9ada54c1afd10
4
+ data.tar.gz: 99f6f24769f66ccdc45aa0ba7102f73a6478da3f
5
5
  SHA512:
6
- metadata.gz: aad2c7bb9671be7eb720a4aabf1e067ed1ac51df44d7a86e4fee5ccfb75750891c878d6f184327a84337493b720f966a7b36cbe4ef746b4dd561c7118fabd005
7
- data.tar.gz: 67837152d83201cc3c509826a00372123735885d72b7b17a441d61ad8544f2b45267f54215344a16acde1f1dfb7c8adc0f3f5ac37cae0c4b038d6e075af4c630
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
- 'structured'
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
- @executor = Executor.new(self, Visitor.new)
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
@@ -3,7 +3,7 @@ module AgnosticBackend
3
3
  module Elasticsearch
4
4
  class Query < AgnosticBackend::Queryable::Query
5
5
 
6
- def initialize(base)
6
+ def initialize(base, **options)
7
7
  super
8
8
  @executor = Executor.new(self, Visitor.new)
9
9
  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, @visitor = query, visitor
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 build
47
- query = create_query(self)
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
@@ -1,3 +1,3 @@
1
1
  module AgnosticBackend
2
- VERSION = "0.9.9"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -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.9.9
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-09-07 00:00:00.000000000 Z
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