CloudSesame 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37c4c9374c039f8cdab3da4ec22d17706baa23a4
4
- data.tar.gz: 9600876e639d302f4138da57c116e947087afd43
3
+ metadata.gz: a97ed18065996a1ded5cc2b8719d43e668383f4f
4
+ data.tar.gz: 94b4b851f28cbe7b50cd7f3b7d0ce45373e07e87
5
5
  SHA512:
6
- metadata.gz: bc23ba7626029370ac200ddac02a57b0731cdb695d7023f8388774f116cff99a583a6c930240f12d95ac3c702b71ecc5598d0ee82304d96c958b883ec7476383
7
- data.tar.gz: 7316b4b97c6bebe8beba9320df8e2e2fde31a797ec788b2257b2922e566ac17dedc61bc576417d00a5b131d73514c2d5144e63a53ffb996277e4a23404029216
6
+ metadata.gz: 2f62458643e0f3e95e404b326317016c07b94657a7f17ce471601d9f603667077affd7cf4319d7dd34553818f1e85f9a6e099973f701e5cc2c4e599e0893c08d
7
+ data.tar.gz: 756f7b2e14460b142b8ed59d5ac63dbd3f66deff02f4af71f57b4e9213e5b8ac3c5655e42796d2a20a399c0e9eedf26c88fe00d4bf295e6ddc4a1978eb242652
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- CloudSesame (0.3.6)
4
+ CloudSesame (0.4.0)
5
5
  aws-sdk (~> 2)
6
6
 
7
7
  GEM
data/cloud_sesame.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'CloudSesame'
3
- s.version = '0.3.6'
3
+ s.version = '0.4.0'
4
4
  s.date = '2016-01-20'
5
5
  s.summary = "AWS CloudSearch Query DSL"
6
6
  s.description = "AWS CloudSearch Query DSL"
@@ -11,12 +11,10 @@ module CloudSesame
11
11
 
12
12
  def initialize(field = nil, value = nil, options = {}, &block)
13
13
  @field = field
14
-
15
14
  @value = Value.parse value if value
16
15
  @value = Value.parse ValueEvaluator.new.instance_exec &block if block_given?
17
-
18
16
  @options = options || {}
19
- (@options[:included] ||= []) << @value
17
+ applied[@value] = true
20
18
  end
21
19
 
22
20
  def is_for(field, options)
@@ -25,27 +23,21 @@ module CloudSesame
25
23
  end
26
24
 
27
25
  def is_excluded
28
- options[:included].delete value
29
- (options[:excluded] ||= []) << value
26
+ applied[value] = applied[value] == false ? true : false
30
27
  end
31
28
 
32
29
  def as_field
33
- @as_field ||= (options[:as] || field).to_s
30
+ options[:as] || field
34
31
  end
35
32
 
36
33
  def compile(detailed = false)
37
- updated? ? recompile(detailed) : @compiled
34
+ detailed ? detailed_format : standard_format
38
35
  end
39
36
 
40
37
  private
41
38
 
42
- def updated?
43
- @compiled_value != value
44
- end
45
-
46
- def recompile(detailed)
47
- @compiled_value = value
48
- @compiled = detailed ? detailed_format : standard_format
39
+ def applied
40
+ options[:applied] ||= {}
49
41
  end
50
42
 
51
43
  def standard_format
@@ -53,7 +45,7 @@ module CloudSesame
53
45
  end
54
46
 
55
47
  def detailed_format
56
- "field=#{ escape as_field } #{ value.compile }"
48
+ "field=#{ escape as_field.to_s } #{ value.compile }"
57
49
  end
58
50
 
59
51
  def escape(data)
@@ -5,8 +5,8 @@ module CloudSesame
5
5
  DETAILED = true
6
6
  SYMBOL = :near
7
7
 
8
- def compile
9
- "(#{ symbol }#{ boost }#{ distance } #{ child.compile detailed })" if child
8
+ def compile(detailed = nil)
9
+ "(#{ symbol }#{ boost }#{ distance } #{ child.compile operator_detailed })" if child
10
10
  end
11
11
 
12
12
  def distance
@@ -6,10 +6,10 @@ module CloudSesame
6
6
 
7
7
  def <<(object)
8
8
  object.is_excluded
9
- super
9
+ self.child = object
10
10
  end
11
11
 
12
- def compile(detailed = nil)
12
+ def compile
13
13
  "(#{ symbol }#{ boost } #{ child.compile })" if child
14
14
  end
15
15
 
@@ -9,7 +9,6 @@ module CloudSesame
9
9
  def initialize(context, options = {}, &block)
10
10
  @context = context
11
11
  @options = options
12
- instance_eval &block if block_given?
13
12
  end
14
13
 
15
14
  def boost
@@ -3,22 +3,18 @@ module CloudSesame
3
3
  module AST
4
4
  class RangeValue < Value
5
5
 
6
- STRING_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
6
+ RANGE_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
7
7
 
8
8
  def initialize(value = nil)
9
9
  @data = if value.kind_of?(Range)
10
10
  range_to_array(value)
11
- elsif value.is_a?(String) && (match = STRING_FORMAT.match value)
11
+ elsif value.is_a?(String) && (match = string_format?(value))
12
12
  @data = match.captures
13
13
  else
14
14
  default_range
15
15
  end
16
16
  end
17
17
 
18
- def compile
19
- "#{ lb }#{ l.to_s },#{ u.to_s }#{ ub }"
20
- end
21
-
22
18
  def gt(value = nil)
23
19
  data[0], data[1] = '{', Value.parse(value) if value
24
20
  return self
@@ -39,18 +35,22 @@ module CloudSesame
39
35
  return self
40
36
  end
41
37
 
42
- def l
43
- data[1]
38
+ def compile
39
+ "#{ lb }#{ l.to_s },#{ u.to_s }#{ ub }"
44
40
  end
45
41
 
46
- def u
47
- data[2]
42
+ def ==(object)
43
+ data == Value.parse(object).data
48
44
  end
49
45
 
50
46
  private
51
47
 
52
- def range_to_array(r)
53
- ['[', r.begin, r.end, end_symbol(r)]
48
+ def string_format?(string)
49
+ RANGE_FORMAT.match string.tr(' ', '')
50
+ end
51
+
52
+ def range_to_array(range)
53
+ ['[', range.begin, range.end, end_symbol(range)]
54
54
  end
55
55
 
56
56
  def end_symbol(value)
@@ -61,6 +61,14 @@ module CloudSesame
61
61
  ['{', nil, nil, '}']
62
62
  end
63
63
 
64
+ def l
65
+ data[1]
66
+ end
67
+
68
+ def u
69
+ data[2]
70
+ end
71
+
64
72
  def lb
65
73
  data[1] ? data[0] : '{'
66
74
  end
@@ -21,11 +21,11 @@ module CloudSesame
21
21
  self.child = object
22
22
  end
23
23
 
24
- def compile
25
- "(#{ symbol }#{ boost } #{ child.compile detailed })" if child
24
+ def compile(detailed = nil)
25
+ "(#{ symbol }#{ boost } #{ child.compile operator_detailed })" if child
26
26
  end
27
27
 
28
- def detailed
28
+ def operator_detailed
29
29
  self.class::DETAILED
30
30
  end
31
31
 
@@ -3,7 +3,7 @@ module CloudSesame
3
3
  module AST
4
4
  class Value
5
5
 
6
- RANGE_FORMAT = /\A[\[\{].*[\]\}]\z/
6
+ RANGE_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
7
7
  DIGIT_FORMAT = /\A\d+(.\d+)?\z/
8
8
  SINGLE_QUATE = /\'/
9
9
  ESCAPE_QUATE = "\\'"
@@ -12,15 +12,14 @@ 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)
15
16
  return AST::DateValue.new(value) if value.kind_of?(Date) || value.kind_of?(Time)
16
17
  return AST::RangeValue.new(value) if value.kind_of?(Range) || (value.is_a?(String) && RANGE_FORMAT =~ value)
17
- return AST::NumericValue.new(value) if value.is_a?(Numeric) || (value.is_a?(String) && DIGIT_FORMAT =~ value)
18
18
  AST::Value.new(value)
19
19
  end
20
20
 
21
21
  def initialize(data)
22
22
  @data = data
23
- @compiled = compile
24
23
  end
25
24
 
26
25
  def compile
@@ -46,7 +45,7 @@ module CloudSesame
46
45
  @compiled = escape @compiled_data
47
46
  end
48
47
 
49
- def escape(data = "")
48
+ def escape(data)
50
49
  "'#{ data.gsub(SINGLE_QUATE) { ESCAPE_QUATE } }'"
51
50
  end
52
51
 
@@ -58,7 +58,7 @@ module CloudSesame
58
58
  def search
59
59
  compiled = request.compile
60
60
  raise Error::MissingQuery.new("Query or FilterQuery can not be empty!") if !compiled[:query] || compiled[:query].empty?
61
- @response = client.search compiled
61
+ @response = searchable.cloudsearch.client.search compiled
62
62
  end
63
63
 
64
64
  private
@@ -13,6 +13,10 @@ module CloudSesame
13
13
  dsl_scope.context
14
14
  end
15
15
 
16
+ def dsl_caller
17
+ dsl_context[:caller]
18
+ end
19
+
16
20
  def dsl_return(node = nil)
17
21
  node || dsl_scope
18
22
  end
@@ -26,19 +26,33 @@ module CloudSesame
26
26
  private
27
27
 
28
28
  def block_style_dsl(klass, options, &block)
29
- node = klass.new dsl_context, options, &block
29
+ node = klass.new dsl_context, options
30
30
  if block_given?
31
+ extract_caller_from block if on_root_level?
32
+ node.instance_eval &block
31
33
  dsl_scope << node
32
34
  dsl_return node
33
35
  else
34
- return_chaining_relation(node)
36
+ chaining_relation_for(node)
35
37
  end
36
38
  end
37
39
 
38
- def return_chaining_relation(node)
40
+ def chaining_relation_for(node)
39
41
  AST::BlockChainingRelation.new(dsl_scope, dsl_return, node)
40
42
  end
41
43
 
44
+ def on_root_level?
45
+ dsl_scope.is_a?(AST::Root)
46
+ end
47
+
48
+ def extract_caller_from(block)
49
+ dsl_context[:caller] = block.binding.eval "self"
50
+ end
51
+
52
+ def method_missing(name, *args, &block)
53
+ dsl_caller ? dsl_caller.send(name, *args, &block) : super
54
+ end
55
+
42
56
  end
43
57
  end
44
58
  end
@@ -4,27 +4,42 @@ module CloudSesame
4
4
  module FilterQueryMethods
5
5
 
6
6
  def included?(field, value = nil)
7
- (field_options = dsl_context[:fields][field]) && (
8
- (value && field_options_is(:included, field_options, value)) ||
9
- (!value && field_options_not_empty_in(:included, field_options))
7
+ !!(
8
+ (field_options = dsl_context[:fields][field]) &&
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
+ )
10
17
  )
11
18
  end
12
19
 
13
20
  def excluded?(field, value = nil)
14
- (field_options = dsl_context[:fields][field]) && (
15
- (value && field_options_is(:excluded, field_options, value)) ||
16
- (!value && field_options_not_empty_in(:excluded, field_options))
21
+ !!(
22
+ (field_options = dsl_context[:fields][field]) &&
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
+ )
17
31
  )
18
32
  end
19
33
 
20
- private
21
-
22
- def field_options_is(type, field_options, value)
23
- (values = field_options[type]) && values.include?(value)
24
- end
25
-
26
- def field_options_not_empty_in(type, field_options)
27
- field_options[type] && !field_options[type].empty?
34
+ def applied_filters
35
+ applied = {}
36
+ dsl_context[:fields].each do |field, options|
37
+ if options && options[:applied] &&
38
+ !(values = options[:applied].select { |k, v| v }.keys).empty?
39
+ applied[field] = values
40
+ end
41
+ end
42
+ applied
28
43
  end
29
44
 
30
45
  end
@@ -9,15 +9,6 @@ module CloudSesame
9
9
  let(:block) { Proc.new {} }
10
10
  subject { Operator.new(context, options, &block) }
11
11
 
12
- describe '#initialize' do
13
- context 'given a block' do
14
- let(:block) { Proc.new { context[:name] = :test } }
15
- it 'should evalute the block' do
16
- expect(subject.context[:name]).to eq :test
17
- end
18
- end
19
- end
20
-
21
12
  describe '#boost' do
22
13
  context 'given boost option' do
23
14
  let(:options) {{ boost: 2 }}
@@ -62,22 +62,23 @@
62
62
  # end
63
63
 
64
64
 
65
- # # n = 500
66
- # # result = RubyProf.profile do
67
- # # n.times do
65
+ # n = 10_000
66
+ # q = nil
67
+ # result = RubyProf.profile do
68
+ # n.times do
68
69
  # q = Product.cloudsearch.query("black jacket").sort(price: :asc).page(1).size(1000).and {
69
70
  # or! {
70
- # tags "men", "women"
71
+ # tags "1", "2"
71
72
  # and! {
72
- # tags.not "child", "home"
73
+ # tags.not "3", "4"
73
74
  # }
74
75
  # and!.not {
75
- # tags.start_with "great", "nice"
76
- # tags.not.start_with "super"
77
- # tags.not.near "hello world"
78
- # tags start_with("wifi"), near("electronic")
79
- # tags term "cool"
80
- # tags phrase "flash_deal"
76
+ # tags.start_with "5", "6"
77
+ # tags.not.start_with "7"
78
+ # tags.not.near "8"
79
+ # tags start_with("9"), near("10")
80
+ # tags term "11"
81
+ # tags phrase "12"
81
82
  # }
82
83
  # or!.not {
83
84
  # price 25..100
@@ -91,15 +92,31 @@
91
92
  # created_at gte(Date.today).lt(Date.today + 3)
92
93
  # }
93
94
  # }
94
- # }.compile
95
-
96
- # # end
97
- # # end
98
- # # printer = RubyProf::FlatPrinter.new(result)
99
- # # printer.print(STDOUT, {})
100
-
101
- # # q = Product.cloudsearch.and {
102
- # binding.pry
103
- # # }
95
+ # }
96
+ # a = q.applied_filters
104
97
 
98
+ # end
99
+ # end
100
+ # printer = RubyProf::FlatPrinter.new(result)
101
+ # printer.print(STDOUT, {})
102
+
103
+ # binding.pry
104
+
105
+ # # class TestClass
106
+ # # def initialize
107
+ # # @name = "scott"
108
+ # # end
109
+ # # def greeting
110
+ # # "hello world!"
111
+ # # end
112
+ # # def test_method
113
+ # # local = :test
114
+ # # q = Product.cloudsearch.and {
115
+ # # binding.pry
116
+ # # }
117
+ # # end
118
+ # # end
119
+
120
+ # # test = TestClass.new
121
+ # # test.test_method
105
122
  # end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: CloudSesame
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chu