agnostic_backend 0.9.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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