CloudSesame 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
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