CloudSesame 0.6.8 → 0.7.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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +12 -0
  3. data/.gitignore +1 -1
  4. data/Gemfile.lock +13 -13
  5. data/Guardfile +1 -0
  6. data/cloud_sesame.gemspec +2 -2
  7. data/coverage/.last_run.json +1 -1
  8. data/coverage/.resultset.json +679 -591
  9. data/lib/cloud_sesame/config/credential.rb +6 -6
  10. data/lib/cloud_sesame/context.rb +0 -5
  11. data/lib/cloud_sesame/domain/base.rb +147 -128
  12. data/lib/cloud_sesame/domain/client.rb +25 -25
  13. data/lib/cloud_sesame/domain/client_module/caching/base.rb +19 -23
  14. data/lib/cloud_sesame/domain/client_module/caching/no_cache.rb +11 -11
  15. data/lib/cloud_sesame/domain/client_module/caching/rails_cache.rb +32 -28
  16. data/lib/cloud_sesame/domain/client_module/caching.rb +19 -28
  17. data/lib/cloud_sesame/domain/client_module/retry.rb +6 -6
  18. data/lib/cloud_sesame/domain/config.rb +6 -6
  19. data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +37 -0
  20. data/lib/cloud_sesame/query/ast/abstract/operator.rb +27 -0
  21. data/lib/cloud_sesame/query/ast/abstract/single_expression_operator.rb +39 -0
  22. data/lib/cloud_sesame/query/ast/abstract/value.rb +88 -0
  23. data/lib/cloud_sesame/query/ast/and.rb +1 -1
  24. data/lib/cloud_sesame/query/ast/date_value.rb +19 -3
  25. data/lib/cloud_sesame/query/ast/literal.rb +13 -28
  26. data/lib/cloud_sesame/query/ast/near.rb +4 -4
  27. data/lib/cloud_sesame/query/ast/not.rb +6 -7
  28. data/lib/cloud_sesame/query/ast/numeric_value.rb +20 -12
  29. data/lib/cloud_sesame/query/ast/or.rb +1 -1
  30. data/lib/cloud_sesame/query/ast/phrase.rb +1 -1
  31. data/lib/cloud_sesame/query/ast/prefix.rb +1 -1
  32. data/lib/cloud_sesame/query/ast/range_value.rb +40 -39
  33. data/lib/cloud_sesame/query/ast/root.rb +2 -6
  34. data/lib/cloud_sesame/query/ast/string_value.rb +26 -0
  35. data/lib/cloud_sesame/query/ast/term.rb +1 -1
  36. data/lib/cloud_sesame/query/ast/value.rb +25 -54
  37. data/lib/cloud_sesame/query/builder.rb +83 -54
  38. data/lib/cloud_sesame/query/domain/block.rb +3 -1
  39. data/lib/cloud_sesame/query/dsl/applied_filter_query.rb +14 -23
  40. data/lib/cloud_sesame/query/dsl/field_accessors.rb +25 -22
  41. data/lib/cloud_sesame/query/dsl/field_array_methods.rb +1 -1
  42. data/lib/cloud_sesame/query/dsl/inspect_method.rb +31 -0
  43. data/lib/cloud_sesame/query/dsl/sort_methods.rb +5 -4
  44. data/lib/cloud_sesame/query/node/abstract.rb +1 -2
  45. data/lib/cloud_sesame/query/node/facet.rb +1 -5
  46. data/lib/cloud_sesame/query/node/filter_query.rb +15 -2
  47. data/lib/cloud_sesame/query/node/fuzziness.rb +4 -3
  48. data/lib/cloud_sesame/query/node/page.rb +2 -2
  49. data/lib/cloud_sesame/query/node/query.rb +4 -17
  50. data/lib/cloud_sesame/query/node/query_options.rb +6 -16
  51. data/lib/cloud_sesame/query/node/query_options_field.rb +3 -1
  52. data/lib/cloud_sesame/query/node/query_parser.rb +8 -10
  53. data/lib/cloud_sesame/query/node/request.rb +57 -31
  54. data/lib/cloud_sesame/query/node/sort.rb +25 -11
  55. data/lib/cloud_sesame.rb +15 -12
  56. data/lib/{abstract_object.rb → services/abstract_object.rb} +0 -0
  57. data/lib/services/class_specific.rb +44 -0
  58. data/lib/services/lazy_object.rb +19 -0
  59. data/spec/cloud_sesame/domain/base_spec.rb +26 -11
  60. data/spec/cloud_sesame/domain/client_module/caching/base_spec.rb +2 -1
  61. data/spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb +2 -3
  62. data/spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb +6 -6
  63. data/spec/cloud_sesame/domain/client_module/caching_spec.rb +33 -32
  64. data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +67 -0
  65. data/spec/cloud_sesame/query/ast/abstract/operator_spec.rb +29 -0
  66. data/spec/cloud_sesame/query/ast/abstract/single_expression_operator_spec.rb +70 -0
  67. data/spec/cloud_sesame/query/ast/abstract/value_spec.rb +118 -0
  68. data/spec/cloud_sesame/query/ast/and_spec.rb +1 -1
  69. data/spec/cloud_sesame/query/ast/or_spec.rb +1 -1
  70. data/spec/cloud_sesame/query/ast/range_value_spec.rb +5 -11
  71. data/spec/cloud_sesame/query/builder_spec.rb +10 -4
  72. data/spec/cloud_sesame/query/domain/block_spec.rb +15 -8
  73. data/spec/cloud_sesame/query/dsl/{block_methods_spec.rb → block_styled_operators_spec.rb} +0 -0
  74. data/spec/cloud_sesame/query/dsl/field_accessors_spec.rb +88 -50
  75. data/spec/cloud_sesame/query/dsl/field_array_methods_spec.rb +0 -2
  76. data/spec/cloud_sesame/query/node/facet_spec.rb +1 -15
  77. data/spec/cloud_sesame/query/node/filter_query_spec.rb +16 -2
  78. data/spec/cloud_sesame/query/node/page_spec.rb +3 -2
  79. data/spec/cloud_sesame/query/node/query_options_spec.rb +1 -1
  80. data/spec/cloud_sesame/query/node/query_parser_spec.rb +1 -7
  81. data/spec/cloud_sesame/query/node/query_spec.rb +10 -28
  82. data/spec/cloud_sesame/query/node/sort_spec.rb +19 -28
  83. data/spec/cloud_sesame_spec.rb +2 -156
  84. data/spec/helpers/benchmark_helper.rb +12 -0
  85. data/spec/integration/filter_query_spec.rb +0 -0
  86. data/spec/profiling_spec.rb +155 -0
  87. data/spec/{abstract_object_spec.rb → services/abstract_object_spec.rb} +0 -0
  88. data/spec/services/class_specific_spec.rb +135 -0
  89. data/spec/spec_helper.rb +3 -0
  90. metadata +32 -22
  91. data/lib/active_support/core_ext/object/deep_dup.rb +0 -53
  92. data/lib/active_support/core_ext/object/duplicable.rb +0 -98
  93. data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +0 -35
  94. data/lib/cloud_sesame/query/ast/operator.rb +0 -25
  95. data/lib/cloud_sesame/query/ast/single_expression_operator.rb +0 -35
  96. data/lib/cloud_sesame/query/scope.rb +0 -21
  97. data/profiler.rb +0 -91
  98. data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -76
  99. data/spec/cloud_sesame/query/ast/operator_spec.rb +0 -29
  100. data/spec/cloud_sesame/query/ast/single_expression_operator_spec.rb +0 -78
  101. data/spec/context_spec.rb +0 -17
@@ -1,8 +1,8 @@
1
1
  module CloudSesame
2
- module Config
3
- class Credential < ::AbstractObject
4
- accept :access_key_id, as: [:access_key]
5
- accept :secret_access_key, as: [:secret_key]
6
- end
7
- end
2
+ module Config
3
+ class Credential < ::AbstractObject
4
+ accept :access_key_id, as: [:access_key]
5
+ accept :secret_access_key, as: [:secret_key]
6
+ end
7
+ end
8
8
  end
@@ -23,10 +23,5 @@ module CloudSesame
23
23
  table[key.to_sym] = value
24
24
  end
25
25
 
26
- def duplicate(context)
27
- @table = context.table.deep_dup
28
- self
29
- end
30
-
31
26
  end
32
27
  end
@@ -1,130 +1,149 @@
1
1
  module CloudSesame
2
- module Domain
3
- class Base
4
- extend Forwardable
5
-
6
- def_delegators :client, :config, :caching_with
7
-
8
- attr_reader :searchable
9
-
10
- def self.definitions
11
- @definitions ||= {}
12
- end
13
-
14
- def initialize(searchable)
15
- @searchable = searchable
16
- end
17
-
18
- def builder
19
- Query::Builder.new context, searchable
20
- end
21
-
22
- def client
23
- @client ||= Client.new searchable
24
- end
25
-
26
- def context
27
- @context ||= Context.new
28
- end
29
-
30
- # DEFAULT CONTEXT METHODS
31
- # =========================================
32
-
33
- def default_size(value)
34
- page[:size] = value.to_i
35
- end
36
-
37
- def define_sloppiness(value)
38
- query[:sloppiness] = Query::Node::Sloppiness.new(value)
39
- end
40
-
41
- def define_fuzziness(&block)
42
- query[:fuzziness] = Query::Node::Fuzziness.new(&block)
43
- end
44
-
45
- def field(name, options = {})
46
- field_name = (options[:as] || name)
47
- add_query(field_name, options.delete(:query)) if options[:query]
48
- add_facet(field_name, options.delete(:facet)) if options[:facet]
49
- add_field(name.to_sym, options)
50
- end
51
-
52
- def scope(name, proc = nil, &block)
53
- block = proc unless block_given?
54
- filter_query_scopes[name.to_sym] = block if block
55
- end
56
-
57
- private
58
-
59
- def to_hash(options)
60
- options.is_a?(Hash) ? options : {}
61
- end
62
-
63
- def add_query(name, options)
64
- ((context[:query_options] ||= {})[:fields] ||= {})[name] = to_hash(options)
65
- end
66
-
67
- def add_facet(name, options)
68
- (context[:facet] ||= {})[name] = to_hash(options)
69
- end
70
-
71
- def add_field(name, options)
72
- options = merge_with_as_field options if options[:as]
73
- create_default_literal name, options
74
- create_field_accessor name
75
- filter_query_fields[name] = options
76
- end
77
-
78
- def merge_with_as_field(options)
79
- (existing = filter_query_fields.delete(options[:as])) ? existing.merge(options) : options
80
- end
81
-
82
- def create_default_literal(name, options)
83
- if (block = options.delete(:default))
84
- caller = block.binding.eval "self"
85
- domain = Query::Domain::Literal.new(name, options, caller)
86
- node = domain._eval(&block)
87
- filter_query_defaults << node if node
88
- end
89
- end
90
-
91
- def create_field_accessor(name)
92
- Query::DSL::FieldAccessors.__define_accessor__(name)
93
- end
94
-
95
- def method_missing(name, *args, &block)
96
- if builder.respond_to?(name)
97
- builder.send(name, *args, &block)
98
- elsif searchable.respond_to?(name)
99
- searchable.send(name, *args, &block)
100
- else
101
- super
102
- end
103
- end
104
-
105
- # CONTEXT ACCESSORS
106
- # =========================================
107
-
108
- def page
109
- context[:page] ||= {}
110
- end
111
-
112
- def query
113
- context[:query] ||= {}
114
- end
115
-
116
- def filter_query_fields
117
- (context[:filter_query] ||= {})[:fields] ||= {}
118
- end
119
-
120
- def filter_query_defaults
121
- (context[:filter_query] ||= {})[:defaults] ||= []
122
- end
123
-
124
- def filter_query_scopes
125
- (context[:filter_query] ||= {})[:scopes] ||= {}
126
- end
127
-
128
- end
129
- end
2
+ module Domain
3
+ class Base
4
+ extend Forwardable
5
+
6
+ def_delegators :client, :config, :caching_with
7
+
8
+ attr_reader :searchable
9
+
10
+ def self.definitions
11
+ @definitions ||= {}
12
+ end
13
+
14
+ def initialize(searchable)
15
+ @searchable = searchable
16
+ @builder = Query::Builder.construct_class(searchable)
17
+ end
18
+
19
+ def builder
20
+ @builder.new context, searchable
21
+ end
22
+
23
+ def client
24
+ @client ||= Client.new searchable
25
+ end
26
+
27
+ def context
28
+ @context ||= Context.new
29
+ end
30
+
31
+ # DEFAULT CONTEXT METHODS
32
+ # =========================================
33
+
34
+ def default_size(value)
35
+ context_page[:size] = value.to_i
36
+ end
37
+
38
+ def define_sloppiness(value)
39
+ context_query[:sloppiness] = Query::Node::Sloppiness.new(value)
40
+ end
41
+
42
+ def define_fuzziness(&block)
43
+ context_query[:fuzziness] = Query::Node::Fuzziness.new(&block)
44
+ end
45
+
46
+ def field(name, options = {})
47
+ field_name = (options[:as] || name).to_sym
48
+
49
+ add_sort_alias(name, options) if options[:as]
50
+ add_query_options(field_name, options) if options[:query]
51
+ add_facet(field_name, options) if options[:facet]
52
+ add_field(name, options)
53
+ end
54
+
55
+ def scope(name, proc = nil, &block)
56
+ block = proc unless block_given?
57
+ filter_query_scopes[name.to_sym] = block if block
58
+ end
59
+
60
+ private
61
+
62
+ def add_sort_alias(name, options)
63
+ context_sort_fields[name] = { as: options[:as] }
64
+ end
65
+
66
+ def add_query_options(name, options)
67
+ context_query_options[name] = to_hash(options.delete(:query))
68
+ end
69
+
70
+ def add_facet(name, options)
71
+ context_facet[name] = to_hash(options.delete(:facet))
72
+ end
73
+
74
+ def add_field(name, options)
75
+ options = merge_with_as_field options if options[:as]
76
+ options[:type] = set_type(options[:type])
77
+ create_accessor name
78
+ create_default_literal name, options
79
+ filter_query_fields[name] = options
80
+ end
81
+
82
+ def set_type(type)
83
+ Query::AST::Value.map_type(type)
84
+ end
85
+
86
+ def merge_with_as_field(options)
87
+ (existing = filter_query_fields.delete(options[:as])) ? existing.merge(options) : options
88
+ end
89
+
90
+ def create_accessor(name)
91
+ @builder.field_accessor.__define_accessor__(name)
92
+ end
93
+
94
+ def create_default_literal(name, options)
95
+ if (block = options.delete(:default))
96
+ caller = block.binding.eval "self"
97
+ node = Query::Domain::Literal.new(name, options, caller)._eval(&block)
98
+ filter_query_defaults << node if node
99
+ end
100
+ end
101
+
102
+ def to_hash(options)
103
+ options.is_a?(Hash) ? options : {}
104
+ end
105
+
106
+ def method_missing(name, *args, &block)
107
+ builder.respond_to?(name) ? builder.send(name, *args, &block) :
108
+ searchable.respond_to?(name) ? searchable.send(name, *args, &block) :
109
+ super
110
+ end
111
+
112
+ # CONTEXT INITIALIZERS
113
+ # =========================================
114
+
115
+ def context_page
116
+ context[:page] ||= {}
117
+ end
118
+
119
+ def context_query
120
+ context[:query] ||= {}
121
+ end
122
+
123
+ def context_query_options
124
+ (context[:query_options] ||= {})[:fields] ||= {}
125
+ end
126
+
127
+ def context_facet
128
+ context[:facet] ||= {}
129
+ end
130
+
131
+ def context_sort_fields
132
+ (context[:sort] ||= {})[:fields] ||= {}
133
+ end
134
+
135
+ def filter_query_fields
136
+ (context[:filter_query] ||= {})[:fields] ||= {}
137
+ end
138
+
139
+ def filter_query_defaults
140
+ (context[:filter_query] ||= {})[:defaults] ||= []
141
+ end
142
+
143
+ def filter_query_scopes
144
+ (context[:filter_query] ||= {})[:scopes] ||= {}
145
+ end
146
+
147
+ end
148
+ end
130
149
  end
@@ -1,38 +1,38 @@
1
1
  require 'cloud_sesame/domain/client_module/caching'
2
2
 
3
3
  module CloudSesame
4
- module Domain
5
- class Client
6
- include ClientModule::Caching
4
+ module Domain
5
+ class Client
6
+ include ClientModule::Caching
7
7
 
8
- attr_reader :searchable
8
+ attr_reader :searchable
9
9
 
10
- def self.configure
11
- yield global_config if block_given?
12
- end
10
+ def self.configure
11
+ yield global_config if block_given?
12
+ end
13
13
 
14
- def self.global_config
15
- @global_config ||= Config.new
16
- end
14
+ def self.global_config
15
+ @global_config ||= Config.new
16
+ end
17
17
 
18
- def initialize(searchable)
19
- @searchable = searchable
20
- end
18
+ def initialize(searchable)
19
+ @searchable = searchable
20
+ end
21
21
 
22
- def config
23
- @config ||= Config.new self.class.global_config
24
- end
22
+ def config
23
+ @config ||= Config.new self.class.global_config
24
+ end
25
25
 
26
- def search(params)
27
- executor.fetch params
28
- end
26
+ def search(params)
27
+ executor.fetch params
28
+ end
29
29
 
30
- private
30
+ private
31
31
 
32
- def aws_client
33
- @aws_client ||= ::Aws::CloudSearchDomain::Client.new config.to_hash
34
- end
32
+ def aws_client
33
+ @aws_client ||= LazyObject.new { ::Aws::CloudSearchDomain::Client.new config.to_hash }
34
+ end
35
35
 
36
- end
37
- end
36
+ end
37
+ end
38
38
  end
@@ -1,30 +1,26 @@
1
1
  module CloudSesame
2
- module Domain
3
- module ClientModule
4
- module Caching
5
- class Base
2
+ module Domain
3
+ module ClientModule
4
+ module Caching
5
+ class Base
6
6
 
7
- def initialize(searchable, &lazy_client)
8
- @searchable = searchable
9
- @lazy_client = lazy_client
10
- end
7
+ def initialize(client, searchable)
8
+ @client = client
9
+ @searchable = searchable
10
+ end
11
11
 
12
- def client
13
- @client ||= @lazy_client.call
14
- end
12
+ def fetch(_params)
13
+ raise Error::Caching, "Caching Module needs #fetch method and accepts params"
14
+ end
15
15
 
16
- def fetch(_params)
17
- raise Error::Caching, "Caching Module needs #fetch method and accepts params"
18
- end
16
+ private
19
17
 
20
- private
18
+ def search(params)
19
+ @client.search params
20
+ end
21
21
 
22
- def search(params)
23
- client.search params
24
- end
25
-
26
- end
27
- end
28
- end
29
- end
22
+ end
23
+ end
24
+ end
25
+ end
30
26
  end
@@ -1,15 +1,15 @@
1
1
  module CloudSesame
2
- module Domain
3
- module ClientModule
4
- module Caching
5
- class NoCache < Base
2
+ module Domain
3
+ module ClientModule
4
+ module Caching
5
+ class NoCache < Base
6
6
 
7
- def fetch(params)
8
- search params
9
- end
7
+ def fetch(params)
8
+ search params
9
+ end
10
10
 
11
- end
12
- end
13
- end
14
- end
11
+ end
12
+ end
13
+ end
14
+ end
15
15
  end
@@ -1,38 +1,42 @@
1
1
  require 'ostruct'
2
2
 
3
3
  module CloudSesame
4
- module Domain
5
- module ClientModule
6
- module Caching
7
- class RailsCache < Base
4
+ module Domain
5
+ module ClientModule
6
+ module Caching
7
+ class RailsCache < Base
8
8
 
9
- def initialize(searchable, &lazy_client)
10
- ensure_environment_exists
11
- super
12
- end
9
+ def initialize(client, searchable)
10
+ ensure_environment_exists
11
+ super
12
+ end
13
13
 
14
- def fetch(params)
15
- Rails.cache.fetch(hashify(params)) do
16
- results = search params
17
- OpenStruct.new(status: results.status, hits: results.hits, facets: results.facets)
18
- end
19
- end
14
+ def fetch(params)
15
+ Rails.cache.fetch(hexdigest(params)) do
16
+ results = search params
17
+ OpenStruct.new(
18
+ status: results.status,
19
+ hits: results.hits,
20
+ facets: results.facets
21
+ )
22
+ end
23
+ end
20
24
 
21
- private
25
+ private
22
26
 
23
- def hashify(params)
24
- searchable_params = params.merge(searchable: @searchable)
25
- Digest::MD5.hexdigest Marshal.dump(searchable_params)
26
- end
27
+ def hexdigest(params)
28
+ searchable_params = params.merge(searchable: @searchable)
29
+ Digest::MD5.hexdigest Marshal.dump(searchable_params)
30
+ end
27
31
 
28
- def ensure_environment_exists
29
- unless RailsCache.const_defined?(:Rails)
30
- raise Error::Caching, "Rails environment cannot be found"
31
- end
32
- end
32
+ def ensure_environment_exists
33
+ unless RailsCache.const_defined?(:Rails)
34
+ raise Error::Caching, "Rails environment cannot be found"
35
+ end
36
+ end
33
37
 
34
- end
35
- end
36
- end
37
- end
38
+ end
39
+ end
40
+ end
41
+ end
38
42
  end
@@ -3,38 +3,29 @@ require_relative './caching/no_cache'
3
3
  require_relative './caching/rails_cache'
4
4
 
5
5
  module CloudSesame
6
- module Domain
7
- module ClientModule
8
- module Caching
6
+ module Domain
7
+ module ClientModule
8
+ module Caching
9
9
 
10
- def caching_with(caching_module)
11
- unrecognized_caching_module if !module_defined?(caching_module)
12
- self.executor = module_get(caching_module)
13
- end
10
+ def caching_with(klass)
11
+ self.executor = klass.is_a?(Class) ? klass : module_get(klass)
12
+ end
14
13
 
15
- def executor
16
- @executor ||= Caching::NoCache.new(@searchable) { aws_client }
17
- end
14
+ def executor
15
+ @executor ||= Caching::NoCache.new(aws_client, @searchable)
16
+ end
18
17
 
19
- def executor=(executor)
20
- @executor = executor.new(@searchable) { aws_client }
21
- end
18
+ def executor=(executor)
19
+ @executor = executor.new(aws_client, @searchable)
20
+ end
22
21
 
23
- private
22
+ private
24
23
 
25
- def module_defined?(caching_module)
26
- ClientModule::Caching.const_defined? caching_module
27
- end
24
+ def module_get(klass)
25
+ ClientModule::Caching.const_get klass, false
26
+ end
28
27
 
29
- def module_get(caching_module)
30
- ClientModule::Caching.const_get caching_module
31
- end
32
-
33
- def unrecognized_caching_module
34
- raise Error::Caching, "Unrecognized Caching Module"
35
- end
36
-
37
- end
38
- end
39
- end
28
+ end
29
+ end
30
+ end
40
31
  end
@@ -1,9 +1,9 @@
1
1
  module CloudSesame
2
- module Domain
3
- module ClientModule
4
- module Retry
2
+ module Domain
3
+ module ClientModule
4
+ module Retry
5
5
 
6
- end
7
- end
8
- end
6
+ end
7
+ end
8
+ end
9
9
  end
@@ -1,8 +1,8 @@
1
1
  module CloudSesame
2
- module Domain
3
- class Config < CloudSesame::Config::Credential
4
- accept :sigv4_region, as: [:region]
5
- accept :endpoint, as: [:search_endpoint]
6
- end
7
- end
2
+ module Domain
3
+ class Config < CloudSesame::Config::Credential
4
+ accept :sigv4_region, as: [:region]
5
+ accept :endpoint, as: [:search_endpoint]
6
+ end
7
+ end
8
8
  end
@@ -0,0 +1,37 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ module Abstract
5
+ class MultiExpressionOperator < Operator
6
+
7
+ def <<(object)
8
+ children << object
9
+ end
10
+
11
+ def applied(included = true)
12
+ children.map { |child| child.applied(included) }
13
+ end
14
+
15
+ def children
16
+ @children ||= build_children
17
+ end
18
+
19
+ def compile
20
+ if !children.empty? && (compiled = children.compile) && !compiled.empty?
21
+ "(#{ symbol }#{ boost } #{ compiled })"
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def build_children
28
+ (children = FieldArray.new)._scope = self
29
+ children
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ module Abstract
5
+ class Operator
6
+ SYMBOL = nil
7
+
8
+ attr_reader :context, :options
9
+
10
+ def initialize(context, options = {})
11
+ @context = context
12
+ @options = options
13
+ end
14
+
15
+ def boost
16
+ " boost=#{ options[:boost] }" if options[:boost]
17
+ end
18
+
19
+ def symbol
20
+ self.class::SYMBOL
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end