CloudSesame 0.6.4 → 0.6.5

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -3
  3. data/.rubocop.yml +1158 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile.lock +28 -1
  6. data/Guardfile +6 -1
  7. data/README.md +6 -1
  8. data/cloud_sesame.gemspec +4 -2
  9. data/coverage/.last_run.json +5 -0
  10. data/coverage/.resultset.json +2423 -0
  11. data/coverage/.resultset.json.lock +0 -0
  12. data/lib/cloud_sesame.rb +4 -5
  13. data/lib/cloud_sesame/domain/base.rb +46 -33
  14. data/lib/cloud_sesame/domain/client_module/caching/base.rb +1 -1
  15. data/lib/cloud_sesame/query/ast/near.rb +1 -1
  16. data/lib/cloud_sesame/query/ast/operator.rb +1 -1
  17. data/lib/cloud_sesame/query/ast/range_value.rb +23 -30
  18. data/lib/cloud_sesame/query/ast/single_expression_operator.rb +1 -1
  19. data/lib/cloud_sesame/query/ast/value.rb +18 -4
  20. data/lib/cloud_sesame/query/domain/block.rb +2 -2
  21. data/lib/cloud_sesame/query/domain/literal.rb +1 -1
  22. data/lib/cloud_sesame/query/dsl/applied_filter_query.rb +21 -23
  23. data/lib/cloud_sesame/query/dsl/field_accessors.rb +8 -3
  24. data/lib/cloud_sesame/query/dsl/response_methods.rb +2 -2
  25. data/lib/cloud_sesame/query/dsl/scope_accessors.rb +1 -1
  26. data/lib/cloud_sesame/query/node/fuzziness.rb +11 -13
  27. data/lib/cloud_sesame/query/node/query.rb +9 -10
  28. data/lib/cloud_sesame/query/node/request.rb +2 -2
  29. data/lib/cloud_sesame/query/node/sloppiness.rb +23 -0
  30. data/spec/cloud_sesame/config/credential_spec.rb +76 -0
  31. data/spec/cloud_sesame/domain/base_spec.rb +274 -9
  32. data/spec/cloud_sesame/domain/client_spec.rb +0 -1
  33. data/spec/cloud_sesame/query/domain/block_spec.rb +0 -1
  34. data/spec/cloud_sesame/query/node/query_spec.rb +18 -7
  35. data/spec/cloud_sesame_spec.rb +10 -10
  36. data/spec/spec_helper.rb +3 -0
  37. metadata +38 -3
  38. data/lib/cloud_sesame/domain/context.rb +0 -39
File without changes
data/lib/cloud_sesame.rb CHANGED
@@ -67,6 +67,7 @@ require 'cloud_sesame/query/node/abstract'
67
67
  require 'cloud_sesame/query/node/request'
68
68
  require 'cloud_sesame/query/node/query'
69
69
  require 'cloud_sesame/query/node/fuzziness'
70
+ require 'cloud_sesame/query/node/sloppiness'
70
71
  require 'cloud_sesame/query/node/query_options'
71
72
  require 'cloud_sesame/query/node/query_options_field'
72
73
  require 'cloud_sesame/query/node/query_parser'
@@ -106,15 +107,13 @@ module CloudSesame
106
107
  def define_cloudsearch(&block)
107
108
  if block_given?
108
109
  Domain::Base.definitions[self] = block
109
- cloudsearch._caller = block.binding.eval "self"
110
- cloudsearch.instance_eval &block
111
- cloudsearch._caller = nil
110
+ cloudsearch.instance_eval(&block)
112
111
  end
113
112
  end
114
113
 
115
114
  def load_definition_from(klass)
116
- if (definition = Domain::Base.definitions[self])
117
- cloudsearch.instance_eval &definition
115
+ if (definition = Domain::Base.definitions[klass])
116
+ cloudsearch.instance_eval(&definition)
118
117
  end
119
118
  end
120
119
 
@@ -32,31 +32,27 @@ module CloudSesame
32
32
  # =========================================
33
33
 
34
34
  def default_size(value)
35
- (context[:page] ||= {})[:size] = value
35
+ page[:size] = value.to_i
36
36
  end
37
37
 
38
38
  def define_sloppiness(value)
39
- (context[:query] ||= {})[:sloppiness] = value.to_i
39
+ query[:sloppiness] = Query::Node::Sloppiness.new(value)
40
40
  end
41
41
 
42
42
  def define_fuzziness(&block)
43
- (context[:query] ||= {})[:fuzziness] = Query::Node::Fuzziness.new(&block)
44
- end
45
-
46
- # TODO
47
- def default_scope(proc, &block)
43
+ query[:fuzziness] = Query::Node::Fuzziness.new(&block)
48
44
  end
49
45
 
50
46
  def field(name, options = {})
51
47
  field_name = (options[:as] || name)
52
- add_query field_name, options.delete(:query)
53
- add_facet field_name, options.delete(:facet)
54
- add_field name.to_sym, options
48
+ add_query(field_name, options.delete(:query)) if options[:query]
49
+ add_facet(field_name, options.delete(:facet)) if options[:facet]
50
+ add_field(name.to_sym, options)
55
51
  end
56
52
 
57
53
  def scope(name, proc = nil, &block)
58
54
  block = proc unless block_given?
59
- ((context[:filter_query] ||= {})[:scopes] ||= {})[name.to_sym] = block
55
+ filter_query_scopes[name.to_sym] = block if block
60
56
  end
61
57
 
62
58
  private
@@ -66,51 +62,68 @@ module CloudSesame
66
62
  end
67
63
 
68
64
  def add_query(name, options)
69
- ((context[:query_options] ||= {})[:fields] ||= {})[name] = to_hash(options) if options
65
+ ((context[:query_options] ||= {})[:fields] ||= {})[name] = to_hash(options)
70
66
  end
71
67
 
72
68
  def add_facet(name, options)
73
- (context[:facet] ||= {})[name] = to_hash(options) if options
69
+ (context[:facet] ||= {})[name] = to_hash(options)
74
70
  end
75
71
 
76
72
  def add_field(name, options)
77
- replace_existing_field name, options
73
+ options = merge_with_as_field options if options[:as]
78
74
  create_default_literal name, options
79
75
  create_field_accessor name
80
- (context[:filter_query][:fields] ||= {})[name] = options
76
+ filter_query_fields[name] = options
81
77
  end
82
78
 
83
- def replace_existing_field(name, options)
84
- fields = ((context[:filter_query] ||= {})[:fields] ||= {})
85
- if (as = options[:as]) && (existing = fields.delete(as))
86
- options.merge! existing
87
- end
79
+ def merge_with_as_field(options)
80
+ (existing = filter_query_fields.delete(options[:as])) ? existing.merge(options) : options
88
81
  end
89
82
 
90
83
  def create_default_literal(name, options)
91
84
  if (block = options.delete(:default))
92
85
  caller = block.binding.eval "self"
93
- node = Query::Domain::Literal.new(name, options, caller)._eval(&block)
94
- filter_query_defaults << node
86
+ domain = Query::Domain::Literal.new(name, options, caller)
87
+ node = domain._eval(&block)
88
+ filter_query_defaults << node if node
95
89
  end
96
90
  end
97
91
 
98
- def filter_query_defaults
99
- context[:filter_query][:defaults] ||= []
92
+ def create_field_accessor(name)
93
+ Query::DSL::FieldAccessors.__define_accessor__(name)
100
94
  end
101
95
 
102
- def create_field_accessor(name)
103
- Query::DSL::FieldAccessors.send(:define_method, name) do |*values, &block|
104
- literal name, *values, &block
96
+ def method_missing(name, *args, &block)
97
+ if builder.respond_to?(name)
98
+ builder.send(name, *args, &block)
99
+ elsif searchable.respond_to?(name)
100
+ searchable.send(name, *args, &block)
101
+ else
102
+ super
105
103
  end
106
104
  end
107
105
 
108
- def method_missing(name, *args, &block)
109
- builder.send(name, *args, &block)
110
- rescue NoMethodError => e
111
- _caller.send(name, *args, &block) if _caller
112
- rescue NoMethodError => e
113
- super
106
+ # CONTEXT ACCESSORS
107
+ # =========================================
108
+
109
+ def page
110
+ context[:page] ||= {}
111
+ end
112
+
113
+ def query
114
+ context[:query] ||= {}
115
+ end
116
+
117
+ def filter_query_fields
118
+ (context[:filter_query] ||= {})[:fields] ||= {}
119
+ end
120
+
121
+ def filter_query_defaults
122
+ (context[:filter_query] ||= {})[:defaults] ||= []
123
+ end
124
+
125
+ def filter_query_scopes
126
+ (context[:filter_query] ||= {})[:scopes] ||= {}
114
127
  end
115
128
 
116
129
  end
@@ -9,7 +9,7 @@ module CloudSesame
9
9
  @searchable = searchable
10
10
  end
11
11
 
12
- def fetch(params)
12
+ def fetch(_params)
13
13
  raise Error::Caching, "Caching Module needs #fetch method and accepts params"
14
14
  end
15
15
 
@@ -5,7 +5,7 @@ module CloudSesame
5
5
  DETAILED = true
6
6
  SYMBOL = :near
7
7
 
8
- def compile(detailed = nil)
8
+ def compile(_detailed = nil)
9
9
  if child && (compiled = child.compile operator_detailed) && !compiled.empty?
10
10
  "(#{ symbol }#{ boost }#{ distance } #{ compiled })"
11
11
  end
@@ -6,7 +6,7 @@ module CloudSesame
6
6
 
7
7
  attr_reader :context, :options
8
8
 
9
- def initialize(context, options = {}, &block)
9
+ def initialize(context, options = {})
10
10
  @context = context
11
11
  @options = options
12
12
  end
@@ -6,40 +6,41 @@ module CloudSesame
6
6
  RANGE_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
7
7
 
8
8
  def initialize(value = nil)
9
- @data = if value.kind_of?(Range)
10
- range_to_array(value)
11
- elsif value.is_a?(String) && (match = string_format?(value))
12
- (matches = match.captures)[1, 2] = matches[1, 2].map do |i|
13
- Value.parse(i) unless i.nil? || i.empty?
9
+ @data = (
10
+ if value.kind_of?(Range)
11
+ range_to_array(value)
12
+ elsif value.is_a?(String) && (match = string_format?(value))
13
+ data = match.captures
14
+ data[1, 2] = data[1, 2].map { |i| Value.parse(i) unless i.nil? || i.empty? }
15
+ data
16
+ else
17
+ default_range
14
18
  end
15
- @data = matches
16
- else
17
- default_range
18
- end
19
+ )
19
20
  end
20
21
 
21
22
  def gt(value = nil)
22
- data[0], data[1] = '{', Value.parse(value) if value
23
+ update_lower_value(value) if value
23
24
  return self
24
25
  end
25
26
 
26
27
  def gte(value = nil)
27
- data[0], data[1] = '[', Value.parse(value) if value
28
+ update_lower_value(value, true) if value
28
29
  return self
29
30
  end
30
31
 
31
32
  def lt(value = nil)
32
- data[2], data[3] = Value.parse(value), '}' if value
33
+ update_uppoer_value(value) if value
33
34
  return self
34
35
  end
35
36
 
36
37
  def lte(value = nil)
37
- data[2], data[3] = Value.parse(value), ']' if value
38
+ update_uppoer_value(value, true) if value
38
39
  return self
39
40
  end
40
41
 
41
42
  def compile
42
- "#{ lb }#{ l.to_s },#{ u.to_s }#{ ub }"
43
+ "#{ data[0] }#{ data[1] },#{ data[2] }#{ data[3] }"
43
44
  end
44
45
 
45
46
  def ==(object)
@@ -48,6 +49,14 @@ module CloudSesame
48
49
 
49
50
  private
50
51
 
52
+ def update_lower_value(value, included = false)
53
+ data[0], data[1] = (included ? '[' : '{'), Value.parse(value)
54
+ end
55
+
56
+ def update_uppoer_value(value, included = false)
57
+ data[2], data[3] = Value.parse(value), (included ? ']' : '}')
58
+ end
59
+
51
60
  def string_format?(string)
52
61
  RANGE_FORMAT.match string.tr(' ', '')
53
62
  end
@@ -67,22 +76,6 @@ module CloudSesame
67
76
  ['{', nil, nil, '}']
68
77
  end
69
78
 
70
- def l
71
- data[1]
72
- end
73
-
74
- def u
75
- data[2]
76
- end
77
-
78
- def lb
79
- data[1] ? data[0] : '{'
80
- end
81
-
82
- def ub
83
- data[2] ? data[3] : '}'
84
- end
85
-
86
79
  end
87
80
  end
88
81
  end
@@ -19,7 +19,7 @@ module CloudSesame
19
19
  self.child = object
20
20
  end
21
21
 
22
- def compile(detailed = nil)
22
+ def compile(_detailed = nil)
23
23
  if child && (compiled = child.compile operator_detailed) && !compiled.empty?
24
24
  "(#{ symbol }#{ boost } #{ compiled })"
25
25
  end
@@ -12,10 +12,24 @@ module CloudSesame
12
12
 
13
13
  def self.parse(value)
14
14
  return value if value.kind_of? AST::Value
15
- return AST::NumericValue.new(value) if value.is_a?(Numeric) || (value.is_a?(String) && DIGIT_FORMAT =~ value)
16
- return AST::DateValue.new(value) if value.kind_of?(Date) || value.kind_of?(Time)
17
- return AST::RangeValue.new(value) if value.kind_of?(Range) || (value.is_a?(String) && RANGE_FORMAT =~ value)
18
- AST::Value.new(value)
15
+ (
16
+ is_a_numeric?(value) ? AST::NumericValue :
17
+ is_a_datetime?(value) ? AST::DateValue :
18
+ is_a_range?(value) ? AST::RangeValue :
19
+ AST::Value
20
+ ).new(value)
21
+ end
22
+
23
+ def self.is_a_numeric?(value)
24
+ value.is_a?(Numeric) || (value.is_a?(String) && DIGIT_FORMAT =~ value)
25
+ end
26
+
27
+ def self.is_a_datetime?(value)
28
+ value.kind_of?(Date) || value.kind_of?(Time)
29
+ end
30
+
31
+ def self.is_a_range?(value)
32
+ value.kind_of?(Range) || (value.is_a?(String) && RANGE_FORMAT =~ value)
19
33
  end
20
34
 
21
35
  def initialize(data)
@@ -27,7 +27,7 @@ module CloudSesame
27
27
  # parents (_scope) in order for the parent properly
28
28
  # propagate message down to all the children.
29
29
  # ===============================================
30
- instance_eval &block
30
+ instance_eval(&block)
31
31
  _scope << node
32
32
 
33
33
  _scopes.pop
@@ -42,7 +42,7 @@ module CloudSesame
42
42
  _scope
43
43
  end
44
44
 
45
- def _block_domain(block)
45
+ def _block_domain(_block)
46
46
  self
47
47
  end
48
48
 
@@ -16,7 +16,7 @@ module CloudSesame
16
16
  end
17
17
 
18
18
  def _eval(&block)
19
- if block_given? && (_value = instance_exec &block)
19
+ if block_given? && (_value = instance_exec(&block))
20
20
  AST::Literal.new _name, _value, _options
21
21
  end
22
22
  end
@@ -4,44 +4,42 @@ module CloudSesame
4
4
  module AppliedFilterQuery
5
5
 
6
6
  def included?(field, value = nil)
7
- !!(
8
- (field_options = _context[:fields][field.to_sym]) &&
9
- (applied = field_options[:applied]) &&
10
- (
11
- (!value && applied.values.any?) ||
12
- (
13
- value && (index = applied.keys.index(value)) &&
14
- (field_options[:applied].values[index] != false)
15
- )
16
- )
17
- )
7
+ return false unless (options = field_options_for(field)) && (applied = options[:applied])
8
+ if value
9
+ (index = applied.keys.index(value)) &&
10
+ (applied.values[index] != false)
11
+ else
12
+ applied.values.any?
13
+ end
18
14
  end
19
15
 
20
16
  def excluded?(field, value = nil)
21
- !!(
22
- (field_options = _context[:fields][field.to_sym]) &&
23
- (applied = field_options[:applied]) &&
24
- (
25
- (!value && !applied.values.all?) ||
26
- (
27
- value && (index = applied.keys.index(value)) &&
28
- field_options[:applied].values[index] == false
29
- )
30
- )
31
- )
17
+ return false unless (options = field_options_for(field)) && (applied = options[:applied])
18
+ if value
19
+ (index = applied.keys.index(value)) &&
20
+ (applied.values[index] == false)
21
+ else
22
+ !applied.values.all?
23
+ end
32
24
  end
33
25
 
34
26
  def applied_filters
35
27
  applied = {}
36
28
  _context[:fields].each do |field, options|
37
29
  if options && options[:applied] &&
38
- !(values = options[:applied].select { |k, v| v }.keys).empty?
30
+ !(values = options[:applied].select { |_, v| v }.keys).empty?
39
31
  applied[field] = values
40
32
  end
41
33
  end
42
34
  applied
43
35
  end
44
36
 
37
+ private
38
+
39
+ def field_options_for(field)
40
+ _context[:fields][field.to_sym]
41
+ end
42
+
45
43
  end
46
44
  end
47
45
  end
@@ -3,15 +3,20 @@ module CloudSesame
3
3
  module DSL
4
4
  module FieldAccessors
5
5
 
6
+ def self.__define_accessor__(name)
7
+ define_method(name) { |*values, &block| literal name, *values, &block }
8
+ end
9
+
6
10
  def literal(name, *values, &block)
7
11
  name = name.to_sym
8
12
 
9
13
  if block_given?
10
14
  caller = block.binding.eval "self"
11
15
  options = _scope.context[:fields][name]
12
- node = Domain::Literal.new(name, options, caller)._eval(&block)
13
- values << node
14
- end
16
+ domain = Domain::Literal.new(name, options, caller)
17
+ node = domain._eval(&block)
18
+ values << node
19
+ end
15
20
 
16
21
  _scope.children.field = name
17
22
  _scope.children._return = _return
@@ -19,11 +19,11 @@ module CloudSesame
19
19
  end
20
20
 
21
21
  def each(&block)
22
- results.each &block
22
+ results.each(&block)
23
23
  end
24
24
 
25
25
  def map(&block)
26
- results.map &block
26
+ results.map(&block)
27
27
  end
28
28
 
29
29
  def search