CloudSesame 0.7.5 → 0.7.7

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +14 -12
  3. data/Guardfile +2 -2
  4. data/cloud_sesame.gemspec +2 -2
  5. data/coverage/.last_run.json +1 -1
  6. data/coverage/.resultset.json +1363 -248
  7. data/lib/cloud_sesame/domain/base.rb +1 -1
  8. data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +3 -4
  9. data/lib/cloud_sesame/query/ast/abstract/value.rb +10 -2
  10. data/lib/cloud_sesame/query/ast/date_value.rb +1 -4
  11. data/lib/cloud_sesame/query/ast/literal.rb +20 -12
  12. data/lib/cloud_sesame/query/ast/{field_array.rb → multi_expression_operator_children.rb} +8 -2
  13. data/lib/cloud_sesame/query/ast/not.rb +1 -7
  14. data/lib/cloud_sesame/query/ast/range_value.rb +43 -28
  15. data/lib/cloud_sesame/query/ast/root.rb +2 -4
  16. data/lib/cloud_sesame/query/ast/value.rb +1 -9
  17. data/lib/cloud_sesame/query/builder.rb +9 -11
  18. data/lib/cloud_sesame/query/domain/block.rb +1 -3
  19. data/lib/cloud_sesame/query/domain/chaining_block.rb +3 -4
  20. data/lib/cloud_sesame/query/domain/literal.rb +1 -3
  21. data/lib/cloud_sesame/query/dsl/bind_caller.rb +13 -6
  22. data/lib/cloud_sesame/query/dsl/{field_array_methods.rb → literal_chaining_methods.rb} +1 -6
  23. data/lib/cloud_sesame/query/dsl/{field_accessors.rb → literal_methods.rb} +1 -1
  24. data/lib/cloud_sesame/query/node/fuzziness.rb +1 -1
  25. data/lib/cloud_sesame.rb +4 -3
  26. data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +5 -1
  27. data/spec/cloud_sesame/query/ast/field_array_spec.rb +57 -0
  28. data/spec/cloud_sesame/query/ast/literal_spec.rb +136 -0
  29. data/spec/cloud_sesame/query/ast/not_spec.rb +30 -0
  30. data/spec/cloud_sesame/query/ast/phrase_spec.rb +20 -0
  31. data/spec/cloud_sesame/query/ast/range_value_spec.rb +245 -30
  32. data/spec/cloud_sesame/query/ast/string_value_spec.rb +39 -0
  33. data/spec/cloud_sesame/query/ast/term_spec.rb +20 -0
  34. data/spec/cloud_sesame/query/ast/value_spec.rb +109 -0
  35. data/spec/cloud_sesame/query/builder_spec.rb +4 -4
  36. data/spec/cloud_sesame/query/domain/block_spec.rb +3 -3
  37. data/spec/cloud_sesame/query/dsl/{field_array_methods_spec.rb → literal_chaining_methods_spec.rb} +1 -1
  38. data/spec/cloud_sesame/query/dsl/{field_accessors_spec.rb → literal_methods_spec.rb} +3 -3
  39. data/spec/cloud_sesame/query/node/query_spec.rb +22 -0
  40. data/spec/profiling_spec.rb +155 -155
  41. metadata +23 -9
@@ -88,7 +88,7 @@ module CloudSesame
88
88
  end
89
89
 
90
90
  def create_accessor(name)
91
- @builder.field_accessor.__define_accessor__(name)
91
+ @builder.literal_methods.__define_accessor__(name)
92
92
  end
93
93
 
94
94
  def create_default_literal(name, options)
@@ -9,14 +9,14 @@ module CloudSesame
9
9
  end
10
10
 
11
11
  def applied(included = true)
12
- children.map { |child| child.applied(included) }
12
+ children.map { |child| child.applied included }
13
13
  end
14
14
 
15
15
  def children
16
16
  @children ||= build_children
17
17
  end
18
18
 
19
- def compile
19
+ def compile(_ = nil)
20
20
  if !children.empty? && (compiled = children.compile) && !compiled.empty?
21
21
  "(#{ symbol }#{ boost } #{ compiled })"
22
22
  end
@@ -25,8 +25,7 @@ module CloudSesame
25
25
  private
26
26
 
27
27
  def build_children
28
- (children = FieldArray.new)._scope = self
29
- children
28
+ MultiExpressionOperatorChildren.build(self)
30
29
  end
31
30
 
32
31
  end
@@ -6,6 +6,8 @@ module CloudSesame
6
6
  module Abstract
7
7
  class Value
8
8
 
9
+ # CONSTANTS
10
+ # =====================================
9
11
  RANGE_FORMAT = Regexp.new(/\A(\[|{)(.*),(.*)(\}|\])\z/).freeze
10
12
  DIGIT_FORMAT = Regexp.new(/\A\d+(.\d+)?\z/).freeze
11
13
  DATETIME_FORMAT = Regexp.new(/\d+{4}-\d+{2}-\d+{2}T\d+{2}:\d+{2}:\d+{2}/).freeze
@@ -13,12 +15,15 @@ module CloudSesame
13
15
 
14
16
  attr_reader :value, :changed, :compiled
15
17
 
18
+ # CLASS METHODS
19
+ # =====================================
20
+
16
21
  def self.range?(value)
17
22
  value.kind_of?(Range)
18
23
  end
19
24
 
20
25
  def self.string_range?(value)
21
- RANGE_FORMAT =~ strip(value)
26
+ value.is_a?(String) && !!(RANGE_FORMAT =~ strip(value))
22
27
  end
23
28
 
24
29
  def self.numeric?(value)
@@ -26,7 +31,7 @@ module CloudSesame
26
31
  end
27
32
 
28
33
  def self.string_numeric?(value)
29
- DIGIT_FORMAT =~ value.to_s
34
+ value.is_a?(String) && !!(DIGIT_FORMAT =~ value)
30
35
  end
31
36
 
32
37
  def self.datetime?(value)
@@ -41,6 +46,9 @@ module CloudSesame
41
46
  value.is_a?(String) && DATE_FORMAT =~ value
42
47
  end
43
48
 
49
+ # INSTANCE METHODS
50
+ # =====================================
51
+
44
52
  def initialize(value, type = nil)
45
53
  self.value = value
46
54
  @type = type
@@ -8,10 +8,7 @@ module CloudSesame
8
8
  DATE_FORMAT = '%F'.freeze
9
9
 
10
10
  def self.parse(value)
11
- if value.kind_of?(RangeValue)
12
- value.type = self
13
- return value
14
- end
11
+ return value.parse self if value.kind_of?(RangeValue)
15
12
 
16
13
  range?(value) || string_range?(value) ? RangeValue.new(value, self) :
17
14
  string_datetime?(value) ? new(parse_datetime(value)) :
@@ -6,45 +6,53 @@ module CloudSesame
6
6
  SINGLE_QUATE = Regexp.new(/\'/).freeze
7
7
  ESCAPE_QUATE = "\\'".freeze
8
8
 
9
- attr_reader :value
9
+ attr_reader :field, :value, :options
10
10
 
11
11
  def initialize(field, value, options = {})
12
12
  @field = field
13
- @options = options
14
- @value = LazyObject.new { (options[:type] || Value).parse(value) } if value
13
+ @options = options || default_options
14
+ @value = parse_value(value) if value
15
15
  end
16
16
 
17
- def is_for(field, options = {})
18
- @field = field
19
- @options.merge! options
17
+ def actual_field_name
18
+ @options[:as] || @field
20
19
  end
21
20
 
22
21
  def applied(included)
23
22
  { field: @field, value: @value, included: included } if @value
24
23
  end
25
24
 
26
- def as_field
27
- @options[:as] || @field
28
- end
29
-
30
25
  def compile(detailed = false)
31
26
  (detailed ? detailed_format : standard_format) if @value
32
27
  end
33
28
 
29
+ def is_for(field, options)
30
+ @field = field
31
+ @options.merge! options if options
32
+ end
33
+
34
34
  private
35
35
 
36
36
  def standard_format
37
- "#{ as_field }:#{ @value.compile }"
37
+ "#{ actual_field_name }:#{ @value.compile }"
38
38
  end
39
39
 
40
40
  def detailed_format
41
- "field=#{ escape as_field.to_s } #{ @value.compile }"
41
+ "field=#{ escape actual_field_name.to_s } #{ @value.compile }"
42
42
  end
43
43
 
44
44
  def escape(data)
45
45
  "'#{ data.gsub(SINGLE_QUATE) { ESCAPE_QUATE } }'"
46
46
  end
47
47
 
48
+ def parse_value(value)
49
+ LazyObject.new { (@options[:type] || Value).parse(value) }
50
+ end
51
+
52
+ def default_options
53
+ { type: Value }
54
+ end
55
+
48
56
  end
49
57
  end
50
58
  end
@@ -1,12 +1,18 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class FieldArray < Array
5
- include DSL::FieldArrayMethods
4
+ class MultiExpressionOperatorChildren < Array
5
+ include DSL::LiteralChainingMethods
6
6
 
7
7
  attr_accessor :_scope, :_return
8
8
  attr_reader :field
9
9
 
10
+ def self.build(scope, children = nil)
11
+ array = new(children || [])
12
+ array._scope = scope
13
+ array
14
+ end
15
+
10
16
  def field=(field)
11
17
  parents.clear
12
18
  @field = field
@@ -4,14 +4,8 @@ module CloudSesame
4
4
  class Not < Abstract::SingleExpressionOperator
5
5
  SYMBOL = :not
6
6
 
7
- def compile
8
- if child && (compiled = child.compile) && !compiled.empty?
9
- "(#{ symbol }#{ boost } #{ compiled })"
10
- end
11
- end
12
-
13
7
  def applied(included = true)
14
- child.applied(!included)
8
+ child.applied !included
15
9
  end
16
10
 
17
11
  end
@@ -4,35 +4,54 @@ module CloudSesame
4
4
  class RangeValue < Abstract::Value
5
5
 
6
6
  def initialize(value = nil, type = nil)
7
- self.value = RangeValue.range?(value) ? range_handler(value) :
8
- RangeValue.string_range?(value) ? string_handler(value) :
9
- empty_value
7
+ self.value = RangeValue.range?(value) ? build_from_range(value) :
8
+ RangeValue.string_range?(value) ? build_from_string(value) :
9
+ initialize_value
10
+ self.parse type
11
+ end
12
+
13
+ def parse(type)
14
+ if type && type.respond_to?(:parse)
15
+ @changed = true
16
+ value[1] = type.parse(self.begin) unless self.begin.to_s.empty?
17
+ value[2] = type.parse(self.end) unless self.end.to_s.empty?
18
+ end
19
+ return self
20
+ end
21
+
22
+ def begin
23
+ value[1]
24
+ end
25
+
26
+ def end
27
+ value[2]
28
+ end
10
29
 
11
- self.type = type if type
30
+ def lower_bound
31
+ value[0]
12
32
  end
13
33
 
14
- def type=(type)
15
- value_type_handler(type) if (@type = type)
16
- type
34
+ def upper_bound
35
+ value[3]
17
36
  end
18
37
 
19
38
  def gt(value)
20
- update_lower_value(value) if value
39
+ set_begin(value) if value
21
40
  return self
22
41
  end
23
42
 
24
43
  def gte(value)
25
- update_lower_value(value, '[') if value
44
+ set_begin(value, '[') if value
26
45
  return self
27
46
  end
28
47
 
29
48
  def lt(value)
30
- update_uppoer_value(value) if value
49
+ set_end(value) if value
31
50
  return self
32
51
  end
33
52
 
34
53
  def lte(value)
35
- update_uppoer_value(value, ']') if value
54
+ set_end(value, ']') if value
36
55
  return self
37
56
  end
38
57
 
@@ -41,7 +60,7 @@ module CloudSesame
41
60
  end
42
61
 
43
62
  def ==(object)
44
- value == RangeValue.new(object, Value).value
63
+ value == (object.is_a?(RangeValue) ? object : RangeValue.new(object, Value)).value
45
64
  end
46
65
 
47
66
  private
@@ -50,30 +69,26 @@ module CloudSesame
50
69
  super "#{ value[0] }#{ value[1] },#{ value[2] }#{ value[3] }"
51
70
  end
52
71
 
53
- def update_lower_value(value, included = '{')
54
- self.value[0] = included
55
- self.value[1] = value
56
- end
57
-
58
- def update_uppoer_value(value, included = '}')
59
- self.value[2] = value
60
- self.value[3] = included
72
+ def set_begin(value, included = '{')
73
+ @changed = true
74
+ self.value[0, 2] = [included, value]
61
75
  end
62
76
 
63
- def range_handler(value)
64
- ['[', value.begin, value.end, value.exclude_end? ? '}' : ']']
77
+ def set_end(value, included = '}')
78
+ @changed = true
79
+ self.value[2, 2] = [value, included]
65
80
  end
66
81
 
67
- def string_handler(value)
68
- RANGE_FORMAT.match(strip(value)).captures
82
+ def build_from_range(range)
83
+ initialize_value('[', range.begin, range.end, range.exclude_end? ? '}' : ']')
69
84
  end
70
85
 
71
- def value_type_handler(type)
72
- self.value[1, 2] = value[1, 2].map { |v| type.parse(v) unless v.to_s.empty? }
86
+ def build_from_string(string)
87
+ initialize_value(*RANGE_FORMAT.match(strip(string)).captures)
73
88
  end
74
89
 
75
- def empty_value
76
- ['{', nil, nil, '}']
90
+ def initialize_value(lb = '[', bv = nil, ev = nil, up = ']')
91
+ [lb, bv, ev, up]
77
92
  end
78
93
 
79
94
  end
@@ -10,10 +10,8 @@ module CloudSesame
10
10
 
11
11
  private
12
12
 
13
- def create_children
14
- array = FieldArray.new(context[:defaults] || [])
15
- array._scope = self
16
- array
13
+ def build_children
14
+ MultiExpressionOperatorChildren.build(self, context[:defaults])
17
15
  end
18
16
 
19
17
  end
@@ -13,21 +13,13 @@ module CloudSesame
13
13
  (klass =TYPES[symbol]) ? klass : self
14
14
  end
15
15
 
16
- # if the value is already a range value object
17
- # set the type to Value and return the value
18
- # else determine the type of value and create it
19
16
  def self.parse(value)
20
- if value.kind_of?(RangeValue)
21
- value.type = self
22
- return value
23
- end
24
-
17
+ return value.parse self if value.kind_of?(RangeValue)
25
18
  (
26
19
  range_value?(value) ? RangeValue :
27
20
  numeric_value?(value) ? NumericValue :
28
21
  datetime?(value) ? DateValue : StringValue
29
22
  ).new(value, self)
30
-
31
23
  end
32
24
 
33
25
  def self.range_value?(value)
@@ -15,16 +15,16 @@ module CloudSesame
15
15
  # ClassSpecific construct class callback
16
16
  #
17
17
  # after construct searchable specific builder,
18
- # construct searchable specific DSL::FieldAccessors,
18
+ # construct searchable specific DSL::LiteralMethods,
19
19
  # and Domain::Block and include the new field accessors
20
20
  # in both builder and domain block
21
21
  # ===================================================
22
22
  after_construct do |searchable|
23
- @field_accessor = DSL::FieldAccessors.construct_module(searchable)
24
- @block_domain = Domain::Block.construct_class(searchable, callback_args: [field_accessor])
23
+ @literal_methods = DSL::LiteralMethods.construct_module(searchable)
24
+ @block_domain = Domain::Block.construct_class(searchable, callback_args: [literal_methods])
25
25
  @request = Node::Request.construct_class(searchable)
26
26
 
27
- include field_accessor
27
+ include literal_methods
28
28
  end
29
29
 
30
30
  # Domain::Block getter
@@ -37,9 +37,9 @@ module CloudSesame
37
37
  @request ||= Node::Request
38
38
  end
39
39
 
40
- # DSL::FieldAccessors getter
41
- def self.field_accessor
42
- @field_accessor ||= DSL::FieldAccessors
40
+ # DSL::LiteralMethods getter
41
+ def self.literal_methods
42
+ @literal_methods ||= DSL::LiteralMethods
43
43
  end
44
44
 
45
45
  # ===================================================
@@ -62,10 +62,8 @@ module CloudSesame
62
62
  private
63
63
 
64
64
  def _block_domain(block)
65
- if block
66
- caller = block.binding.eval("self")
67
- self.class.block_domain.new caller, _context
68
- end
65
+ caller = block ? block.binding.eval("self") : nil
66
+ self.class.block_domain.new caller, _context
69
67
  end
70
68
 
71
69
  def _scope
@@ -15,11 +15,9 @@ module CloudSesame
15
15
  attr_reader :_caller, :_context, :_scopes
16
16
 
17
17
  def initialize(_caller, _context)
18
- @_caller = _caller
18
+ self._caller = _caller
19
19
  @_context = _context
20
20
  @_scopes = []
21
-
22
- _bind_caller_instance_variables
23
21
  end
24
22
 
25
23
  def _eval(node, _scope, _return = _scope, &block)
@@ -28,10 +28,9 @@ module CloudSesame
28
28
  private
29
29
 
30
30
  def _block_domain(block)
31
- @_block_domain ||= (
32
- caller = block.binding.eval("self")
33
- Domain::Block.new caller, _scope.context
34
- )
31
+ caller = block.binding.eval("self")
32
+ @_block_domain._caller = caller
33
+ @_block_domain
35
34
  end
36
35
 
37
36
  def missing_block
@@ -10,9 +10,7 @@ module CloudSesame
10
10
  def initialize(_name, _options, _caller)
11
11
  @_name = _name
12
12
  @_options = _options
13
- @_caller = _caller
14
-
15
- _bind_caller_instance_variables
13
+ self._caller = _caller
16
14
  end
17
15
 
18
16
  def _eval(&block)
@@ -3,11 +3,16 @@ module CloudSesame
3
3
  module DSL
4
4
  module BindCaller
5
5
 
6
+ def _caller=(caller)
7
+ __bind_caller_instance_variables__(caller) if caller
8
+ @_caller = caller
9
+ end
10
+
6
11
  private
7
12
 
8
- def _bind_caller_instance_variables
9
- _caller.instance_variables.each do |name|
10
- value = _caller.instance_variable_get name
13
+ def __bind_caller_instance_variables__(caller)
14
+ caller.instance_variables.each do |name|
15
+ value = caller.instance_variable_get name
11
16
  instance_variable_set name, value
12
17
  end
13
18
  end
@@ -15,9 +20,11 @@ module CloudSesame
15
20
  # ACCESS CALLER'S METHODS
16
21
  # =========================================
17
22
  def method_missing(name, *args, &block)
18
- _caller.send(name, *args, &block)
19
- rescue NoMethodError
20
- super
23
+ if _caller && _caller.respond_to?(name, *args, &block)
24
+ _caller.send(name, *args, &block)
25
+ else
26
+ super
27
+ end
21
28
  end
22
29
 
23
30
  end
@@ -1,12 +1,7 @@
1
- # =========================================================
2
- # field array methods enables field array to chain
3
- # operators after calling the field expression
4
- # accessor
5
- # =========================================================
6
1
  module CloudSesame
7
2
  module Query
8
3
  module DSL
9
- module FieldArrayMethods
4
+ module LiteralChainingMethods
10
5
 
11
6
  # NOT
12
7
  # =======================================
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module DSL
4
- module FieldAccessors
4
+ module LiteralMethods
5
5
  extend ClassSpecific
6
6
 
7
7
  def self.__define_accessor__(name)
@@ -3,7 +3,7 @@ module CloudSesame
3
3
  module Node
4
4
  class Fuzziness
5
5
 
6
- EXCLUDING_TERMS = /^\-/.freeze
6
+ EXCLUDING_TERMS = /(^\-|\*$)/.freeze
7
7
 
8
8
  def initialize(&block)
9
9
 
data/lib/cloud_sesame.rb CHANGED
@@ -25,10 +25,11 @@ require 'cloud_sesame/config/credential'
25
25
  require 'cloud_sesame/query/dsl/applied_filter_query'
26
26
  require 'cloud_sesame/query/dsl/bind_caller'
27
27
  require 'cloud_sesame/query/dsl/block_styled_operators'
28
- require 'cloud_sesame/query/dsl/field_accessors'
28
+ require 'cloud_sesame/query/dsl/literal_methods'
29
+ require 'cloud_sesame/query/dsl/literal_chaining_methods'
29
30
  require 'cloud_sesame/query/dsl/scope_accessors'
30
31
  require 'cloud_sesame/query/dsl/operators'
31
- require 'cloud_sesame/query/dsl/field_array_methods'
32
+
32
33
  require 'cloud_sesame/query/dsl/inspect_method'
33
34
  require 'cloud_sesame/query/dsl/page_methods'
34
35
  require 'cloud_sesame/query/dsl/query_methods'
@@ -49,7 +50,7 @@ require 'cloud_sesame/query/ast/abstract/operator'
49
50
  require 'cloud_sesame/query/ast/abstract/multi_expression_operator'
50
51
  require 'cloud_sesame/query/ast/abstract/single_expression_operator'
51
52
  require 'cloud_sesame/query/ast/abstract/value'
52
- require 'cloud_sesame/query/ast/field_array'
53
+ require 'cloud_sesame/query/ast/multi_expression_operator_children'
53
54
  require 'cloud_sesame/query/ast/and'
54
55
  require 'cloud_sesame/query/ast/or'
55
56
  require 'cloud_sesame/query/ast/not'
@@ -19,11 +19,15 @@ module CloudSesame
19
19
  expect(subject.children).to be_empty
20
20
  end
21
21
  it 'should be an Field Array' do
22
- expect(subject.children).to be_a AST::FieldArray
22
+ expect(subject.children).to be_a AST::MultiExpressionOperatorChildren
23
23
  end
24
24
  end
25
25
 
26
26
  describe '#compile' do
27
+ it 'should accept one optional param' do
28
+ expect{ subject.compile(true) }.to_not raise_error
29
+ end
30
+
27
31
  context 'when theres children' do
28
32
  let(:child) { OpenStruct.new(compile: "compiled") }
29
33
  before { subject.children << child }
@@ -0,0 +1,57 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ describe MultiExpressionOperatorChildren do
5
+
6
+ describe '.build' do
7
+
8
+
9
+
10
+ context 'when children is given' do
11
+
12
+ end
13
+ end
14
+
15
+ describe '#field=' do
16
+
17
+ end
18
+
19
+ describe '#parents' do
20
+
21
+ end
22
+
23
+ describe '#_context' do
24
+
25
+ end
26
+
27
+ describe '#compile' do
28
+
29
+ end
30
+ end
31
+ # class FieldArray < Array
32
+ # include DSL::FieldArrayMethods
33
+
34
+ # attr_accessor :_scope, :_return
35
+ # attr_reader :field
36
+
37
+ # def field=(field)
38
+ # parents.clear
39
+ # @field = field
40
+ # end
41
+
42
+ # def parents
43
+ # @parents ||= []
44
+ # end
45
+
46
+ # def _context
47
+ # _scope && _scope.context
48
+ # end
49
+
50
+ # def compile
51
+ # map(&:compile).join(' ')
52
+ # end
53
+
54
+ # end
55
+ end
56
+ end
57
+ end