CloudSesame 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +14 -11
- data/cloud_sesame.gemspec +13 -4
- data/lib/cloud_sesame.rb +1 -0
- data/lib/cloud_sesame/domain/base.rb +2 -6
- data/lib/cloud_sesame/domain/client.rb +12 -2
- data/lib/cloud_sesame/domain/client_module/caching.rb +40 -0
- data/lib/cloud_sesame/domain/client_module/caching/base.rb +26 -0
- data/lib/cloud_sesame/domain/client_module/caching/no_cache.rb +15 -0
- data/lib/cloud_sesame/domain/client_module/caching/rails_cache.rb +36 -0
- data/lib/cloud_sesame/domain/client_module/retry.rb +9 -0
- data/lib/cloud_sesame/domain/error/caching.rb +8 -0
- data/lib/cloud_sesame/query/ast/range_value.rb +4 -1
- data/lib/cloud_sesame/query/dsl/response_methods.rb +1 -13
- data/spec/cloud_sesame/domain/client_module/caching/base_spec.rb +21 -0
- data/spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb +25 -0
- data/spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb +85 -0
- data/spec/cloud_sesame/domain/client_module/caching_spec.rb +69 -0
- data/spec/cloud_sesame/domain/client_spec.rb +77 -0
- data/spec/cloud_sesame/query/ast/range_value_spec.rb +60 -0
- data/spec/cloud_sesame_spec.rb +95 -105
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3467f2b1e4e4b6ac5a4184c022e9052d9225810
|
4
|
+
data.tar.gz: 1d404cb5f71818b8a9a64942f96b7734ccdbbbe0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39169ff899d4396e439138edb1ba0315d3fcea1768346fa03d339df14cbbba13d8b0d98b58e3ac2283c5be727529a70ea8fb49f327bcd32b0acc5478549d9546
|
7
|
+
data.tar.gz: 18dbe204dcb25aa45664fe394d6d1bb99f7e18acc287bdfced8028447b80b19ba32c5f26e2373e7907e94811c8fdd527d9521d2fdb8056e1ce7deb00acd5e38b
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
CloudSesame (0.6.
|
4
|
+
CloudSesame (0.6.4)
|
5
5
|
aws-sdk (~> 2)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
aws-sdk (2.2.
|
11
|
-
aws-sdk-resources (= 2.2.
|
12
|
-
aws-sdk-core (2.2.
|
10
|
+
aws-sdk (2.2.16)
|
11
|
+
aws-sdk-resources (= 2.2.16)
|
12
|
+
aws-sdk-core (2.2.16)
|
13
13
|
jmespath (~> 1.0)
|
14
|
-
aws-sdk-resources (2.2.
|
15
|
-
aws-sdk-core (= 2.2.
|
14
|
+
aws-sdk-resources (2.2.16)
|
15
|
+
aws-sdk-core (= 2.2.16)
|
16
16
|
coderay (1.1.0)
|
17
17
|
diff-lcs (1.2.5)
|
18
18
|
ffi (1.9.10)
|
@@ -32,12 +32,12 @@ GEM
|
|
32
32
|
guard-compat (~> 1.1)
|
33
33
|
rspec (>= 2.99.0, < 4.0)
|
34
34
|
jmespath (1.1.3)
|
35
|
-
listen (3.0.
|
35
|
+
listen (3.0.6)
|
36
36
|
rb-fsevent (>= 0.9.3)
|
37
|
-
rb-inotify (>= 0.9)
|
37
|
+
rb-inotify (>= 0.9.7)
|
38
38
|
lumberjack (1.0.10)
|
39
39
|
method_source (0.8.2)
|
40
|
-
nenv (0.
|
40
|
+
nenv (0.3.0)
|
41
41
|
notiffany (0.0.8)
|
42
42
|
nenv (~> 0.1)
|
43
43
|
shellany (~> 0.0)
|
@@ -46,13 +46,13 @@ GEM
|
|
46
46
|
method_source (~> 0.8.1)
|
47
47
|
slop (~> 3.4)
|
48
48
|
rb-fsevent (0.9.7)
|
49
|
-
rb-inotify (0.9.
|
49
|
+
rb-inotify (0.9.7)
|
50
50
|
ffi (>= 0.5.0)
|
51
51
|
rspec (3.4.0)
|
52
52
|
rspec-core (~> 3.4.0)
|
53
53
|
rspec-expectations (~> 3.4.0)
|
54
54
|
rspec-mocks (~> 3.4.0)
|
55
|
-
rspec-core (3.4.
|
55
|
+
rspec-core (3.4.2)
|
56
56
|
rspec-support (~> 3.4.0)
|
57
57
|
rspec-expectations (3.4.0)
|
58
58
|
diff-lcs (>= 1.2.0, < 2.0)
|
@@ -76,3 +76,6 @@ DEPENDENCIES
|
|
76
76
|
pry (~> 0)
|
77
77
|
rspec (~> 3)
|
78
78
|
ruby-prof
|
79
|
+
|
80
|
+
BUNDLED WITH
|
81
|
+
1.11.2
|
data/cloud_sesame.gemspec
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'CloudSesame'
|
3
|
-
s.version = '0.6.
|
4
|
-
s.date = '2016-02-
|
3
|
+
s.version = '0.6.4'
|
4
|
+
s.date = '2016-02-14'
|
5
5
|
s.summary = "AWS CloudSearch Query DSL"
|
6
6
|
s.description = "AWS CloudSearch Query DSL"
|
7
|
-
s.authors = [
|
8
|
-
'
|
7
|
+
s.authors = [
|
8
|
+
'Scott Chu',
|
9
|
+
'Emily Fan',
|
10
|
+
'Greg Ward',
|
11
|
+
'David McHoull',
|
12
|
+
'Alishan Ladhani',
|
13
|
+
'Justine Jones',
|
14
|
+
'Gillian Chesnais',
|
15
|
+
'Jeff Li',
|
16
|
+
'Nick Zhu'
|
17
|
+
]
|
9
18
|
s.email = 'dev@retailcommon.com'
|
10
19
|
s.homepage = 'https://github.com/47colborne/cloud-sesame'
|
11
20
|
s.platform = Gem::Platform::RUBY
|
data/lib/cloud_sesame.rb
CHANGED
@@ -87,6 +87,7 @@ require 'cloud_sesame/context'
|
|
87
87
|
require 'cloud_sesame/domain/base'
|
88
88
|
require 'cloud_sesame/domain/client'
|
89
89
|
require 'cloud_sesame/domain/config'
|
90
|
+
require 'cloud_sesame/domain/error/caching'
|
90
91
|
|
91
92
|
# Public Interface
|
92
93
|
# ===============================================
|
@@ -3,7 +3,7 @@ module CloudSesame
|
|
3
3
|
class Base
|
4
4
|
extend Forwardable
|
5
5
|
|
6
|
-
|
6
|
+
def_delegators :client, :config, :caching_with
|
7
7
|
|
8
8
|
attr_accessor :_caller
|
9
9
|
attr_reader :searchable
|
@@ -21,7 +21,7 @@ module CloudSesame
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def client
|
24
|
-
@client ||= Client.new
|
24
|
+
@client ||= Client.new searchable
|
25
25
|
end
|
26
26
|
|
27
27
|
def context
|
@@ -31,10 +31,6 @@ module CloudSesame
|
|
31
31
|
# DEFAULT CONTEXT METHODS
|
32
32
|
# =========================================
|
33
33
|
|
34
|
-
def turn_on_cache
|
35
|
-
context[:cache] = !!(Rails rescue nil)
|
36
|
-
end
|
37
|
-
|
38
34
|
def default_size(value)
|
39
35
|
(context[:page] ||= {})[:size] = value
|
40
36
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
require 'cloud_sesame/domain/client_module/caching'
|
2
|
+
|
1
3
|
module CloudSesame
|
2
4
|
module Domain
|
3
5
|
class Client
|
4
|
-
|
6
|
+
include ClientModule::Caching
|
5
7
|
|
6
|
-
|
8
|
+
attr_reader :searchable
|
7
9
|
|
8
10
|
def self.configure
|
9
11
|
yield global_config if block_given?
|
@@ -13,10 +15,18 @@ module CloudSesame
|
|
13
15
|
@global_config ||= Config.new
|
14
16
|
end
|
15
17
|
|
18
|
+
def initialize(searchable)
|
19
|
+
@searchable = searchable
|
20
|
+
end
|
21
|
+
|
16
22
|
def config
|
17
23
|
@config ||= Config.new self.class.global_config
|
18
24
|
end
|
19
25
|
|
26
|
+
def search(params)
|
27
|
+
executor.fetch params
|
28
|
+
end
|
29
|
+
|
20
30
|
private
|
21
31
|
|
22
32
|
def aws_client
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative './caching/base'
|
2
|
+
require_relative './caching/no_cache'
|
3
|
+
require_relative './caching/rails_cache'
|
4
|
+
|
5
|
+
module CloudSesame
|
6
|
+
module Domain
|
7
|
+
module ClientModule
|
8
|
+
module Caching
|
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
|
14
|
+
|
15
|
+
def executor
|
16
|
+
@executor ||= Caching::NoCache.new(aws_client, @searchable)
|
17
|
+
end
|
18
|
+
|
19
|
+
def executor=(executor)
|
20
|
+
@executor = executor.new(aws_client, @searchable)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def module_defined?(caching_module)
|
26
|
+
ClientModule::Caching.const_defined? caching_module
|
27
|
+
end
|
28
|
+
|
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
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
module Caching
|
5
|
+
class Base
|
6
|
+
|
7
|
+
def initialize(client, searchable)
|
8
|
+
@client = client
|
9
|
+
@searchable = searchable
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(params)
|
13
|
+
raise Error::Caching, "Caching Module needs #fetch method and accepts params"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def search(params)
|
19
|
+
@client.search params
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
module Caching
|
5
|
+
class RailsCache < Base
|
6
|
+
|
7
|
+
def initialize(client, searchable)
|
8
|
+
ensure_environment_exists
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(params)
|
13
|
+
Rails.cache.fetch(hashify(params)) do
|
14
|
+
results = search params
|
15
|
+
OpenStruct.new(status: results.status, hits: results.hits, facets: results.facets)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def hashify(params)
|
22
|
+
searchable_params = params.merge(searchable: @searchable)
|
23
|
+
Digest::MD5.hexdigest Marshal.dump(searchable_params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def ensure_environment_exists
|
27
|
+
unless RailsCache.const_defined?(:Rails)
|
28
|
+
raise Error::Caching, "Rails environment cannot be found"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -26,22 +26,10 @@ module CloudSesame
|
|
26
26
|
results.map &block
|
27
27
|
end
|
28
28
|
|
29
|
-
def hash_key(compiled)
|
30
|
-
Digest::MD5.hexdigest(JSON.generate(compiled.merge(searchable: searchable.to_s)))
|
31
|
-
end
|
32
|
-
|
33
29
|
def search
|
34
30
|
compiled = request.compile
|
35
31
|
raise Error::MissingQuery.new("Query or FilterQuery can not be empty!") if !compiled[:query] || compiled[:query].empty?
|
36
|
-
|
37
|
-
@response = Rails.cache.fetch(hash_key(compiled)) do
|
38
|
-
results = searchable.cloudsearch.client.search compiled
|
39
|
-
OpenStruct.new(status: results.status, hits: results.hits, facets: results.facets)
|
40
|
-
end
|
41
|
-
else
|
42
|
-
@response = searchable.cloudsearch.client.search compiled
|
43
|
-
end
|
44
|
-
@response
|
32
|
+
@response = searchable.cloudsearch.client.search compiled
|
45
33
|
end
|
46
34
|
|
47
35
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
module Caching
|
5
|
+
describe Base do
|
6
|
+
|
7
|
+
class Searchable; end
|
8
|
+
|
9
|
+
subject { Base.new({}, Searchable) }
|
10
|
+
|
11
|
+
describe 'fetch' do
|
12
|
+
it 'should raise an error by default' do
|
13
|
+
expect{ subject.fetch({}) }.to raise_error(Error::Caching, "Caching Module needs #fetch method and accepts params")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
module Caching
|
5
|
+
describe NoCache do
|
6
|
+
|
7
|
+
class Searchable; end
|
8
|
+
|
9
|
+
let(:client) { OpenStruct.new(search: nil) }
|
10
|
+
|
11
|
+
subject { NoCache.new(client, Searchable) }
|
12
|
+
|
13
|
+
describe 'fetch' do
|
14
|
+
let(:params) {{}}
|
15
|
+
it 'should search with params using client' do
|
16
|
+
expect(client).to receive(:search).with(params)
|
17
|
+
subject.fetch(params)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
module Caching
|
5
|
+
describe RailsCache do
|
6
|
+
|
7
|
+
# FAKE RAILS AND RAILS CACHE
|
8
|
+
# =====================================
|
9
|
+
class ::Rails
|
10
|
+
def self.cache
|
11
|
+
@cache ||= FakeCache.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ::FakeCache
|
16
|
+
def table
|
17
|
+
@table ||= {}
|
18
|
+
end
|
19
|
+
def fetch(key, &block)
|
20
|
+
table[key] ||= (block.call if block_given?)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# FAKE SEARCHABLE CLASS
|
25
|
+
# =====================================
|
26
|
+
class Searchable; end
|
27
|
+
|
28
|
+
# HELPERS
|
29
|
+
# =====================================
|
30
|
+
def hashify(params)
|
31
|
+
subject.send(:hashify, params)
|
32
|
+
end
|
33
|
+
|
34
|
+
# TESTS
|
35
|
+
# =====================================
|
36
|
+
|
37
|
+
let(:client) { OpenStruct.new(search: nil) }
|
38
|
+
subject { RailsCache.new(client, Searchable) }
|
39
|
+
|
40
|
+
shared_examples 'cache stored' do
|
41
|
+
it 'should cache the result' do
|
42
|
+
expect{ subject.fetch(params) }.to change{ Rails.cache.table.keys.size }
|
43
|
+
expect(Rails.cache.table[hashify(params)]).to eq results
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'fetch' do
|
48
|
+
let(:params) {{ query: "test" }}
|
49
|
+
let(:results) { OpenStruct.new(status: {}, hits: [], facets: []) }
|
50
|
+
|
51
|
+
before do
|
52
|
+
Rails.cache.table.clear
|
53
|
+
allow(subject).to receive(:search).and_return(results)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should use the hash key generated from params to fetch the cache from Rails' do
|
57
|
+
hash_key = hashify(params)
|
58
|
+
expect(Rails.cache).to receive(:fetch).with(hash_key)
|
59
|
+
subject.fetch(params)
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with non-cached search' do
|
63
|
+
include_examples "cache stored"
|
64
|
+
it 'should trigger search with params' do
|
65
|
+
expect(subject).to receive(:search).with(params)
|
66
|
+
subject.fetch(params)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with cached search' do
|
71
|
+
include_examples "cache stored"
|
72
|
+
it 'should not trigger search with params' do
|
73
|
+
subject.fetch(params)
|
74
|
+
expect(subject).to_not receive(:search)
|
75
|
+
subject.fetch(params)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
module ClientModule
|
4
|
+
describe Caching do
|
5
|
+
|
6
|
+
# SETUP
|
7
|
+
# =======================================
|
8
|
+
|
9
|
+
class Caching::GoodCache < Caching::Base
|
10
|
+
def fetch(params); end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Caching::BadCache < Caching::Base
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestClient
|
17
|
+
include Caching
|
18
|
+
|
19
|
+
def aws_client
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def searchable
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# TESTS
|
29
|
+
# =======================================
|
30
|
+
|
31
|
+
subject { TestClient.new }
|
32
|
+
|
33
|
+
describe '#caching_with' do
|
34
|
+
context 'when giving an existing caching module' do
|
35
|
+
context 'and caching_module respond to fetch' do
|
36
|
+
let(:caching_module) { Caching::GoodCache }
|
37
|
+
before {
|
38
|
+
subject.caching_with(:GoodCache) }
|
39
|
+
it 'should set executor to the caching module' do
|
40
|
+
expect(subject.send(:executor)).to be_kind_of caching_module
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
context 'when giving a non-existing caching module' do
|
45
|
+
it 'should raise Unrecognized Caching Module' do
|
46
|
+
expect{ subject.caching_with(:RedisCache) }.to raise_error(Error::Caching, "Unrecognized Caching Module")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'executor getter' do
|
52
|
+
it 'should default to Caching::NoCache' do
|
53
|
+
expect(Caching::NoCache).to receive(:new).with(subject.aws_client, subject.searchable).and_call_original
|
54
|
+
expect(subject.executor).to be_kind_of Caching::NoCache
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'executor setter' do
|
59
|
+
it 'should accept a caching module' do
|
60
|
+
expect(Caching::GoodCache).to receive(:new).with(subject.aws_client, subject.searchable).and_call_original
|
61
|
+
subject.executor = Caching::GoodCache
|
62
|
+
expect(subject.executor).to be_kind_of Caching::GoodCache
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Domain
|
3
|
+
describe Client do
|
4
|
+
|
5
|
+
class Searchable; end
|
6
|
+
|
7
|
+
subject { Client.new(Searchable) }
|
8
|
+
|
9
|
+
describe '.configure' do
|
10
|
+
context 'when block is given' do
|
11
|
+
it 'should yield back global config' do
|
12
|
+
global_config = Client.global_config
|
13
|
+
expect{ |b| Client.configure(&b) }.to yield_with_args(global_config)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.global_config' do
|
19
|
+
context 'when calling it first time' do
|
20
|
+
before { Client.instance_variable_set(:@global_config, nil) }
|
21
|
+
it 'should initialize an config object on first call' do
|
22
|
+
config = Config.new
|
23
|
+
expect(Config).to receive(:new)
|
24
|
+
Client.global_config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context 'when calling it' do
|
28
|
+
before { Client.global_config }
|
29
|
+
it 'should not re-initialize an config object' do
|
30
|
+
expect(Config).to_not receive(:new)
|
31
|
+
Client.global_config
|
32
|
+
end
|
33
|
+
end
|
34
|
+
it 'should return an config object' do
|
35
|
+
expect(Client.global_config).to be_kind_of(Config)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#config' do
|
40
|
+
context 'when calling it first time' do
|
41
|
+
it 'should initialize an config object from global config' do
|
42
|
+
global_config = Client.global_config
|
43
|
+
expect(Config).to receive(:new).with(global_config)
|
44
|
+
subject.config
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context 'when calling it' do
|
48
|
+
before { subject.config }
|
49
|
+
it 'should no re-initialize an config object' do
|
50
|
+
expect(Config).to_not receive(:new)
|
51
|
+
subject.config
|
52
|
+
end
|
53
|
+
end
|
54
|
+
it 'should return an config object' do
|
55
|
+
expect(Client.global_config).to be_kind_of(Config)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#search' do
|
60
|
+
let(:aws_client) { OpenStruct.new }
|
61
|
+
let(:params) { {} }
|
62
|
+
before { allow(subject).to receive(:aws_client).and_return(aws_client) }
|
63
|
+
it 'should call fetch on executor' do
|
64
|
+
expect(subject.send(:executor)).to receive(:fetch).with(params)
|
65
|
+
subject.search params
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe RangeValue do
|
5
|
+
|
6
|
+
describe 'initialize' do
|
7
|
+
shared_examples 'initialize with initial value' do
|
8
|
+
it 'should be an array' do
|
9
|
+
expect(subject.data).to be_kind_of(Array)
|
10
|
+
end
|
11
|
+
it 'should not be empty' do
|
12
|
+
expect(subject.data).to_not be_empty
|
13
|
+
end
|
14
|
+
it 'should capture the range information' do
|
15
|
+
expect(subject.data).to eq data
|
16
|
+
end
|
17
|
+
context 'when begin and end value exists' do
|
18
|
+
it 'should convert begin and end value to Value' do
|
19
|
+
expect(subject.data[1]).to be_kind_of(Value) if data[1]
|
20
|
+
expect(subject.data[2]).to be_kind_of(Value) if data[2]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when given a range value' do
|
26
|
+
{
|
27
|
+
(0..10) => ['[', 0, 10, ']'],
|
28
|
+
(0...10) => ['[', 0, 10, '}'],
|
29
|
+
(Date.today..(Date.today + 3)) => ['[', Date.today, Date.today + 3, ']']
|
30
|
+
}.each do |before_value, after_value|
|
31
|
+
subject { RangeValue.new(before_value) }
|
32
|
+
let(:data) { after_value }
|
33
|
+
include_examples 'initialize with initial value'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when given a range value in string format' do
|
38
|
+
{
|
39
|
+
"[0, nil}" => ['[', 0, nil, '}'],
|
40
|
+
"{, 100]" => ['{', nil, 100, ']'],
|
41
|
+
}.each do |before_value, after_value|
|
42
|
+
subject { RangeValue.new(before_value) }
|
43
|
+
let(:data) { after_value }
|
44
|
+
include_examples 'initialize with initial value'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when value is not given' do
|
49
|
+
subject { RangeValue.new }
|
50
|
+
let(:data) { [] }
|
51
|
+
it 'should set the data to the default value' do
|
52
|
+
expect(subject.data).to eq ['{', nil, nil, '}']
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/cloud_sesame_spec.rb
CHANGED
@@ -4,6 +4,23 @@
|
|
4
4
|
|
5
5
|
# describe CloudSesame do
|
6
6
|
|
7
|
+
# # FAKE RAILS AND RAILS CACHE
|
8
|
+
# # =====================================
|
9
|
+
# class ::Rails
|
10
|
+
# def self.cache
|
11
|
+
# @cache ||= FakeCache.new
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
|
15
|
+
# class ::FakeCache
|
16
|
+
# def table
|
17
|
+
# @table ||= {}
|
18
|
+
# end
|
19
|
+
# def fetch(key, &block)
|
20
|
+
# table[key] ||= (block.call if block_given?)
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
|
7
24
|
# # AWS initializer
|
8
25
|
# # =======================================================
|
9
26
|
# require 'yaml'
|
@@ -34,7 +51,7 @@
|
|
34
51
|
# config.endpoint = ENV['AWS_ENDPOINT']
|
35
52
|
# config.region = ENV['AWS_REGION']
|
36
53
|
|
37
|
-
#
|
54
|
+
# caching_with :RailsCache
|
38
55
|
|
39
56
|
# default_size 100
|
40
57
|
|
@@ -48,7 +65,7 @@
|
|
48
65
|
|
49
66
|
# field :searchable_text, query: { weight: 2 }
|
50
67
|
# field :description, query: true
|
51
|
-
# field :tags
|
68
|
+
# field :tags
|
52
69
|
|
53
70
|
# field :affiliate_advertiser_ext_id, facet: { size: 50 }
|
54
71
|
# field :currency, facet: true
|
@@ -62,107 +79,80 @@
|
|
62
79
|
|
63
80
|
# end
|
64
81
|
|
65
|
-
#
|
66
|
-
#
|
67
|
-
|
68
|
-
#
|
69
|
-
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
|
74
|
-
#
|
75
|
-
|
76
|
-
#
|
77
|
-
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
|
94
|
-
#
|
95
|
-
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
|
105
|
-
#
|
106
|
-
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
#
|
116
|
-
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
|
121
|
-
#
|
122
|
-
|
123
|
-
#
|
124
|
-
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
131
|
-
#
|
132
|
-
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
|
138
|
-
#
|
139
|
-
|
140
|
-
|
141
|
-
# # end
|
142
|
-
|
143
|
-
# # q = Coupon.cloudsearch.builder
|
144
|
-
|
145
|
-
# # binding.pry
|
146
|
-
|
147
|
-
# # class ProductController
|
148
|
-
|
149
|
-
# # def load_userq
|
150
|
-
# # @name = "scott"
|
151
|
-
# # end
|
152
|
-
|
153
|
-
# # def greeting
|
154
|
-
# # "hello world!"
|
155
|
-
# # end
|
156
|
-
|
157
|
-
# # def search
|
158
|
-
# # load_user
|
159
|
-
# # q = Product.cloudsearch.and {
|
160
|
-
# # binding.pry
|
161
|
-
# # }
|
162
|
-
# # end
|
163
|
-
|
164
|
-
# # end
|
165
|
-
|
166
|
-
# # test = ProductController.new
|
167
|
-
# # test.search
|
82
|
+
# class Coupon
|
83
|
+
# include CloudSesame
|
84
|
+
|
85
|
+
# VALID_COUPON_RANK = 20
|
86
|
+
|
87
|
+
# define_cloudsearch do
|
88
|
+
# config.endpoint = ENV['AWS_ENDPOINT']
|
89
|
+
# config.region = ENV['AWS_REGION']
|
90
|
+
|
91
|
+
# default_size 10
|
92
|
+
|
93
|
+
# define_sloppiness 3
|
94
|
+
|
95
|
+
# define_fuzziness do
|
96
|
+
# max_fuzziness 3
|
97
|
+
# min_char_size 6
|
98
|
+
# fuzzy_percent 0.17
|
99
|
+
# end
|
100
|
+
|
101
|
+
# field :end_date, as: :date1
|
102
|
+
# field :rank, as: :num1, default: -> { gte VALID_COUPON_RANK }
|
103
|
+
# field :searchable_text, query: true
|
104
|
+
# field :affiliate_advertiser_search_ext_id, as: :string1, facet: { size: 50 }
|
105
|
+
# field :countries, as: :string_array1
|
106
|
+
# field :deal_types, as: :string_array2, facet: {}
|
107
|
+
# field :tags, as: :string_array3, facet: {}
|
108
|
+
# field :type, default: -> { 'Catalog::CouponSearchable' }
|
109
|
+
# end
|
110
|
+
|
111
|
+
# end
|
112
|
+
|
113
|
+
# @tags = [1, 2]
|
114
|
+
# n = 10_000
|
115
|
+
# q = nil
|
116
|
+
# result = RubyProf.profile do
|
117
|
+
# n.times do
|
118
|
+
# q = Product.cloudsearch.query("black jacket").sort(price: :asc).page(1).size(1000)
|
119
|
+
# .price { gt 100 }
|
120
|
+
# .and {
|
121
|
+
# or! {
|
122
|
+
# tags *@tags
|
123
|
+
# tags
|
124
|
+
# tags nil
|
125
|
+
# and! {
|
126
|
+
# tags.not "3", "4"
|
127
|
+
# }
|
128
|
+
# and!.not {
|
129
|
+
# tags.start_with "5", "6"
|
130
|
+
# tags.not.start_with("7")
|
131
|
+
# tags.not.near("8", distance: 7)
|
132
|
+
# tags start_with("9"), near("10")
|
133
|
+
# tags term("11", boost: 2)
|
134
|
+
# tags.not phrase "12"
|
135
|
+
# }
|
136
|
+
# or!.not {
|
137
|
+
# price(25..100)
|
138
|
+
# price 100...200
|
139
|
+
# price gte(200).lt(300)
|
140
|
+
# price gte(300)
|
141
|
+
# }
|
142
|
+
# or! {
|
143
|
+
# created_at Date.today - 7
|
144
|
+
# created_at gte(Date.today)
|
145
|
+
# created_at gte(Date.today).lt(Date.today + 3)
|
146
|
+
# }
|
147
|
+
# }
|
148
|
+
# }
|
149
|
+
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
# printer = RubyProf::FlatPrinter.new(result)
|
153
|
+
# printer.print(STDOUT, {})
|
154
|
+
|
155
|
+
# binding.pry
|
156
|
+
|
157
|
+
|
168
158
|
# 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.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chu
|
@@ -12,10 +12,11 @@ authors:
|
|
12
12
|
- Justine Jones
|
13
13
|
- Gillian Chesnais
|
14
14
|
- Jeff Li
|
15
|
+
- Nick Zhu
|
15
16
|
autorequire:
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
|
-
date: 2016-02-
|
19
|
+
date: 2016-02-14 00:00:00.000000000 Z
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: aws-sdk
|
@@ -122,8 +123,14 @@ files:
|
|
122
123
|
- lib/cloud_sesame/context.rb
|
123
124
|
- lib/cloud_sesame/domain/base.rb
|
124
125
|
- lib/cloud_sesame/domain/client.rb
|
126
|
+
- lib/cloud_sesame/domain/client_module/caching.rb
|
127
|
+
- lib/cloud_sesame/domain/client_module/caching/base.rb
|
128
|
+
- lib/cloud_sesame/domain/client_module/caching/no_cache.rb
|
129
|
+
- lib/cloud_sesame/domain/client_module/caching/rails_cache.rb
|
130
|
+
- lib/cloud_sesame/domain/client_module/retry.rb
|
125
131
|
- lib/cloud_sesame/domain/config.rb
|
126
132
|
- lib/cloud_sesame/domain/context.rb
|
133
|
+
- lib/cloud_sesame/domain/error/caching.rb
|
127
134
|
- lib/cloud_sesame/query/ast/and.rb
|
128
135
|
- lib/cloud_sesame/query/ast/date_value.rb
|
129
136
|
- lib/cloud_sesame/query/ast/field_array.rb
|
@@ -178,11 +185,17 @@ files:
|
|
178
185
|
- profiler.rb
|
179
186
|
- spec/abstract_object_spec.rb
|
180
187
|
- spec/cloud_sesame/domain/base_spec.rb
|
188
|
+
- spec/cloud_sesame/domain/client_module/caching/base_spec.rb
|
189
|
+
- spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb
|
190
|
+
- spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb
|
191
|
+
- spec/cloud_sesame/domain/client_module/caching_spec.rb
|
192
|
+
- spec/cloud_sesame/domain/client_spec.rb
|
181
193
|
- spec/cloud_sesame/query/ast/and_spec.rb
|
182
194
|
- spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb
|
183
195
|
- spec/cloud_sesame/query/ast/numeric_value_spec.rb
|
184
196
|
- spec/cloud_sesame/query/ast/operator_spec.rb
|
185
197
|
- spec/cloud_sesame/query/ast/or_spec.rb
|
198
|
+
- spec/cloud_sesame/query/ast/range_value_spec.rb
|
186
199
|
- spec/cloud_sesame/query/ast/root_spec.rb
|
187
200
|
- spec/cloud_sesame/query/ast/single_expression_operator_spec.rb
|
188
201
|
- spec/cloud_sesame/query/builder_spec.rb
|
@@ -229,11 +242,17 @@ summary: AWS CloudSearch Query DSL
|
|
229
242
|
test_files:
|
230
243
|
- spec/abstract_object_spec.rb
|
231
244
|
- spec/cloud_sesame/domain/base_spec.rb
|
245
|
+
- spec/cloud_sesame/domain/client_module/caching/base_spec.rb
|
246
|
+
- spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb
|
247
|
+
- spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb
|
248
|
+
- spec/cloud_sesame/domain/client_module/caching_spec.rb
|
249
|
+
- spec/cloud_sesame/domain/client_spec.rb
|
232
250
|
- spec/cloud_sesame/query/ast/and_spec.rb
|
233
251
|
- spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb
|
234
252
|
- spec/cloud_sesame/query/ast/numeric_value_spec.rb
|
235
253
|
- spec/cloud_sesame/query/ast/operator_spec.rb
|
236
254
|
- spec/cloud_sesame/query/ast/or_spec.rb
|
255
|
+
- spec/cloud_sesame/query/ast/range_value_spec.rb
|
237
256
|
- spec/cloud_sesame/query/ast/root_spec.rb
|
238
257
|
- spec/cloud_sesame/query/ast/single_expression_operator_spec.rb
|
239
258
|
- spec/cloud_sesame/query/builder_spec.rb
|