sqlcached_client 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/lib/sqlcached_client/attachment.rb +54 -0
- data/lib/sqlcached_client/attachments.rb +36 -0
- data/lib/sqlcached_client/entity.rb +32 -8
- data/lib/sqlcached_client/proxy_object.rb +29 -0
- data/lib/sqlcached_client/resultset.rb +32 -3
- data/lib/sqlcached_client/server.rb +36 -22
- data/lib/sqlcached_client/server_responses/query_response.rb +52 -0
- data/lib/sqlcached_client/version.rb +1 -1
- data/spec/sqlcached_client/attachment_spec.rb +68 -0
- data/spec/sqlcached_client/attachments_spec.rb +19 -0
- data/spec/sqlcached_client/entity_spec.rb +7 -1
- data/spec/sqlcached_client/proxy_object_spec.rb +35 -0
- data/spec/sqlcached_client/resultset_spec.rb +39 -2
- data/spec/sqlcached_client/server_responses/query_response_spec.rb +79 -0
- data/spec/sqlcached_client/server_spec.rb +5 -30
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1f725ac30395fee0332b228f2f7afba9a8e3f63
|
4
|
+
data.tar.gz: 6c8f3618babaf1f18b1295d75bb86a89c84007ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7759cc739a2e3d14bc63c294b84cc1096ed7c97f877e4e86210d3e792bfc61e95cab515b7a7a0362e87aaab382cad539305e5caf0eaf0beacdd8aeb860a848b
|
7
|
+
data.tar.gz: 26d535fd6114978514c5b726755bdfd69a30458955a31259ccfc4f86d6baf7dc1dde767f501e392c91cad7e7ffb62077f03e6eaba14e9705fb7998bb2bce9915
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
|
3
|
+
module SqlcachedClient
|
4
|
+
class Attachment
|
5
|
+
|
6
|
+
PREDICATES = ['=', '<=', '>']
|
7
|
+
|
8
|
+
attr_reader :name, :conditions
|
9
|
+
attr_accessor :content
|
10
|
+
|
11
|
+
# @param conditions [Hash] { var_1: 'value 1', var_2: 'value 2' }
|
12
|
+
def initialize(name, conditions, content)
|
13
|
+
@name = name
|
14
|
+
@conditions = conditions.with_indifferent_access
|
15
|
+
@content = content
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
|
20
|
+
attr_reader :variables
|
21
|
+
|
22
|
+
def add_variable(variable_name, predicate)
|
23
|
+
raise "Invalid predicate" if !PREDICATES.include?(predicate)
|
24
|
+
@variables = [] if @variables.nil?
|
25
|
+
@variables << OpenStruct.new(name: variable_name, predicate: predicate)
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :depends_on, :add_variable
|
29
|
+
end # class << self
|
30
|
+
|
31
|
+
def variables
|
32
|
+
self.class.variables
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_query_format
|
36
|
+
{
|
37
|
+
name: name,
|
38
|
+
condition_values: Hash[
|
39
|
+
variables.map { |v| [v.name, conditions[v.name]] }
|
40
|
+
]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_save_format
|
45
|
+
{
|
46
|
+
name: name,
|
47
|
+
attachment: content,
|
48
|
+
conditions: variables.map do |v|
|
49
|
+
"#{v.name} #{v.predicate} #{conditions[v.name]}"
|
50
|
+
end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'sqlcached_client/attachment'
|
2
|
+
|
3
|
+
module SqlcachedClient
|
4
|
+
module Attachments
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def has_attachment(name, &block)
|
9
|
+
@attachment_classes ||= {}
|
10
|
+
@attachment_classes[name] =
|
11
|
+
Class.new(Attachment) do
|
12
|
+
|
13
|
+
@attachment_name = name
|
14
|
+
class << self
|
15
|
+
attr_reader :attachment_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(conditions, content)
|
19
|
+
super(self.class.attachment_name, conditions, content)
|
20
|
+
end
|
21
|
+
|
22
|
+
instance_exec(&block)
|
23
|
+
end
|
24
|
+
attr_accessor(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_attachments(name, conditions, size)
|
28
|
+
size.times.map { @attachment_classes[name].new(conditions, nil) }
|
29
|
+
end
|
30
|
+
end # module ClassMethods
|
31
|
+
|
32
|
+
def self.included(base)
|
33
|
+
base.extend ClassMethods
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -2,6 +2,7 @@ require 'sqlcached_client/resultset'
|
|
2
2
|
require 'sqlcached_client/server'
|
3
3
|
require 'sqlcached_client/arel'
|
4
4
|
require 'sqlcached_client/tree_visitor'
|
5
|
+
require 'sqlcached_client/proxy_object'
|
5
6
|
|
6
7
|
module SqlcachedClient
|
7
8
|
class Entity
|
@@ -85,6 +86,19 @@ module SqlcachedClient
|
|
85
86
|
server.session(&block)
|
86
87
|
end
|
87
88
|
|
89
|
+
|
90
|
+
def transaction(&block)
|
91
|
+
proxy = ProxyObject.new(self)
|
92
|
+
srv_local = server
|
93
|
+
session = server.get_session
|
94
|
+
proxy.plug_method(:server_session) do |server_session_block|
|
95
|
+
instance_exec(srv_local, session, &server_session_block)
|
96
|
+
end
|
97
|
+
result = proxy.execute(srv_local, session, &block)
|
98
|
+
session.finish
|
99
|
+
result
|
100
|
+
end
|
101
|
+
|
88
102
|
# Runs the entity query with the provided parameters
|
89
103
|
# @return [Resultset]
|
90
104
|
def where(params, dry_run = false)
|
@@ -102,14 +116,14 @@ module SqlcachedClient
|
|
102
116
|
if dry_run
|
103
117
|
request
|
104
118
|
else
|
105
|
-
|
106
|
-
|
119
|
+
server_resp =
|
120
|
+
server_session do |server, session|
|
107
121
|
server.run_query(session, server.build_request(
|
108
122
|
request.is_a?(Array) ? request : [request]
|
109
123
|
))
|
110
124
|
end
|
111
|
-
|
112
|
-
Resultset.new(self,
|
125
|
+
server_resp.flatten!(1) if server_resp.is_array?
|
126
|
+
Resultset.new(self, server_resp)
|
113
127
|
end
|
114
128
|
end
|
115
129
|
|
@@ -272,14 +286,24 @@ module SqlcachedClient
|
|
272
286
|
# Like 'where' but loads every associated entity recursively at any level,
|
273
287
|
# with only one interaction with the server
|
274
288
|
# @param root_conditions [Array]
|
275
|
-
def load_tree(root_conditions
|
276
|
-
|
289
|
+
def load_tree(root_conditions, attachment_name = nil,
|
290
|
+
attachment_conditions = nil)
|
291
|
+
attachments =
|
292
|
+
if attachment_name.present?
|
293
|
+
build_attachments(attachment_name, attachment_conditions,
|
294
|
+
root_conditions.size)
|
295
|
+
else
|
296
|
+
nil
|
297
|
+
end
|
298
|
+
server_session do |server, session|
|
277
299
|
Resultset.new(
|
278
300
|
self,
|
279
301
|
server.run_query(
|
280
302
|
session,
|
281
|
-
server.build_tree_request(build_query_tree, root_conditions
|
282
|
-
|
303
|
+
server.build_tree_request(build_query_tree, root_conditions,
|
304
|
+
attachments)
|
305
|
+
),
|
306
|
+
attachments
|
283
307
|
)
|
284
308
|
end
|
285
309
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SqlcachedClient
|
2
|
+
class ProxyObject < BasicObject
|
3
|
+
|
4
|
+
def initialize(context)
|
5
|
+
@context = context
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(symbol, *args)
|
9
|
+
@context.send(symbol, *args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(*args, &block)
|
13
|
+
instance_exec(*args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def plug_method(method_name, &method_body)
|
17
|
+
memoize_var = "@m_#{method_name}"
|
18
|
+
instance_variable_set(memoize_var, method_body)
|
19
|
+
eval(
|
20
|
+
<<-RUBY
|
21
|
+
def self.#{method_name}(*args, &block)
|
22
|
+
instance_exec(*args, block, &#{memoize_var})
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
)
|
26
|
+
method_name.to_sym
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -5,10 +5,13 @@ module SqlcachedClient
|
|
5
5
|
attr_reader :entity_class, :entities, :count
|
6
6
|
|
7
7
|
# @param entity_class [Class]
|
8
|
-
# @param
|
9
|
-
def initialize(entity_class,
|
8
|
+
# @param data [Array] or [ServerResponse]
|
9
|
+
def initialize(entity_class, data, attachments = nil)
|
10
|
+
# set entity class
|
10
11
|
@entity_class = entity_class
|
11
|
-
|
12
|
+
# build the entities
|
13
|
+
ents = data.respond_to?(:entities) ? data.entities : data
|
14
|
+
@entities = (ents || []).map do |item|
|
12
15
|
if item.is_a?(Hash)
|
13
16
|
entity_class.new(item)
|
14
17
|
elsif item.is_a?(entity_class)
|
@@ -17,7 +20,10 @@ module SqlcachedClient
|
|
17
20
|
raise "Cannot handle: #{item.inspect}"
|
18
21
|
end
|
19
22
|
end
|
23
|
+
# record collection size
|
20
24
|
@count = @entities.size
|
25
|
+
# set up attachments
|
26
|
+
set_entities_attachments(@entities, attachments, data.try(:attachments))
|
21
27
|
end
|
22
28
|
|
23
29
|
class << self
|
@@ -69,5 +75,28 @@ module SqlcachedClient
|
|
69
75
|
entity.get_association_requests
|
70
76
|
end
|
71
77
|
end
|
78
|
+
|
79
|
+
def set_entities_attachments(entities, attachments, contents)
|
80
|
+
if attachments.is_a?(Array) && contents.is_a?(Array)
|
81
|
+
entities.each_with_index do |entity, i|
|
82
|
+
attachment = attachments[i]
|
83
|
+
entity.send("#{attachment.name}=", attachment)
|
84
|
+
attachment.content = contents[i] if attachment.respond_to?(:content=)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def store_attachments(attachment_name, server, session)
|
90
|
+
entities_with_a = entities.select do |entity|
|
91
|
+
!entity.send(attachment_name).nil?
|
92
|
+
end
|
93
|
+
server.store_attachments(
|
94
|
+
session,
|
95
|
+
server.build_store_attachments_request(
|
96
|
+
entities_with_a.map { |e| e.attributes },
|
97
|
+
entities_with_a.map { |e| e.send(attachment_name).to_save_format }
|
98
|
+
)
|
99
|
+
)
|
100
|
+
end
|
72
101
|
end
|
73
102
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'net/http'
|
3
3
|
require 'json'
|
4
|
+
require 'sqlcached_client/server_responses/query_response'
|
4
5
|
|
5
6
|
module SqlcachedClient
|
6
7
|
class Server
|
@@ -12,37 +13,32 @@ module SqlcachedClient
|
|
12
13
|
@port = config[:port]
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
+
# @return [ServerResponses::QueryResponse]
|
16
17
|
def run_query(session, http_req_body)
|
17
18
|
req = Net::HTTP::Post.new(data_batch_url)
|
18
19
|
req.set_content_type('application/json')
|
19
20
|
req.body = http_req_body.to_json
|
20
21
|
resp = session.request(req)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
resp_body =
|
23
|
+
if (resp['Content-Type'] || '') =~ /application\/json/
|
24
|
+
JSON.parse(resp.body)
|
25
|
+
else
|
26
|
+
resp.body
|
27
|
+
end
|
26
28
|
if 200 == resp.code.to_i
|
27
|
-
resp_body
|
29
|
+
ServerResponses::QueryResponse.new(resp_body)
|
28
30
|
else
|
29
31
|
raise "Got HTTP response #{resp.code} from server - #{resp_body.inspect}"
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
35
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
else
|
41
|
-
resultset
|
42
|
-
end
|
43
|
-
else
|
44
|
-
body
|
45
|
-
end
|
36
|
+
def store_attachments(session, http_req_body)
|
37
|
+
req = Net::HTTP::Post.new(store_attachments_url)
|
38
|
+
req.set_content_type('application/json')
|
39
|
+
req.body = http_req_body.to_json
|
40
|
+
resp = session.request(req)
|
41
|
+
201 == resp.code.to_i || raise("Failed to save attachments - server answered with #{resp.body.inspect}")
|
46
42
|
end
|
47
43
|
|
48
44
|
# Builds a 'standard' request body
|
@@ -56,8 +52,12 @@ module SqlcachedClient
|
|
56
52
|
# @param tree [Hash]
|
57
53
|
# @param root_parameters [Array] a vector of actual condition parameters
|
58
54
|
# for the root query
|
59
|
-
def build_tree_request(tree, root_parameters)
|
60
|
-
{ tree: tree, root_parameters: root_parameters }
|
55
|
+
def build_tree_request(tree, root_parameters, attachments = nil)
|
56
|
+
h = { tree: tree, root_parameters: root_parameters }
|
57
|
+
if !attachments.nil?
|
58
|
+
h[:attachments] = attachments.map(&:to_query_format)
|
59
|
+
end
|
60
|
+
h
|
61
61
|
end
|
62
62
|
|
63
63
|
# Formats the parameters passed in the way the server expects
|
@@ -75,6 +75,14 @@ module SqlcachedClient
|
|
75
75
|
}
|
76
76
|
end
|
77
77
|
|
78
|
+
|
79
|
+
def build_store_attachments_request(entities, attachments)
|
80
|
+
{
|
81
|
+
resultset: entities,
|
82
|
+
attachments: attachments
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
78
86
|
# @return [Net::HTTP] an http session on the server
|
79
87
|
def get_session
|
80
88
|
url = server_url
|
@@ -99,7 +107,13 @@ module SqlcachedClient
|
|
99
107
|
|
100
108
|
def data_batch_url
|
101
109
|
url = server_url
|
102
|
-
url.path =
|
110
|
+
url.path = '/data-batch'
|
111
|
+
url
|
112
|
+
end
|
113
|
+
|
114
|
+
def store_attachments_url
|
115
|
+
url = server_url
|
116
|
+
url.path = '/resultset-attachments'
|
103
117
|
url
|
104
118
|
end
|
105
119
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module SqlcachedClient
|
2
|
+
module ServerResponses
|
3
|
+
|
4
|
+
class QueryResponse
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :body
|
8
|
+
|
9
|
+
# @param body [Hash]
|
10
|
+
def initialize(body)
|
11
|
+
@body = body
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&block)
|
15
|
+
block ? entities.each(&block) : entities.each
|
16
|
+
end
|
17
|
+
|
18
|
+
def attachments
|
19
|
+
body.is_a?(Hash) ? body['attachments'] : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def entities
|
23
|
+
@entities ||= get_entities(body)
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_array?
|
27
|
+
entities.is_a?(Array)
|
28
|
+
end
|
29
|
+
|
30
|
+
def flatten!(level = nil)
|
31
|
+
entities if @entities.nil?
|
32
|
+
@entities.flatten!(level)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def get_entities(data)
|
38
|
+
if data.is_a?(Array)
|
39
|
+
data.map { |item| get_entities(item) }
|
40
|
+
elsif data.is_a?(Hash)
|
41
|
+
if (resultset = data['resultset']).is_a?(String)
|
42
|
+
JSON.parse(resultset)
|
43
|
+
else
|
44
|
+
resultset
|
45
|
+
end
|
46
|
+
else
|
47
|
+
data
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end # class QueryResponse
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'sqlcached_client/attachment'
|
2
|
+
|
3
|
+
describe SqlcachedClient::Attachment do
|
4
|
+
|
5
|
+
let(:described_class) { SqlcachedClient::Attachment }
|
6
|
+
|
7
|
+
describe :initialize do
|
8
|
+
it "accepts name, conditions and content" do
|
9
|
+
attachment = described_class.new('name', { 'foo' => 'bar'}, 'content')
|
10
|
+
expect(attachment.name).to eq('name')
|
11
|
+
expect(attachment.conditions).to eq({ 'foo' => 'bar' })
|
12
|
+
expect(attachment.content).to eq('content')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe :variables do
|
17
|
+
it "returns the variables added to the class" do
|
18
|
+
attachment = described_class.new(nil, {}, nil)
|
19
|
+
allow(described_class).to receive(:variables).and_return('foo')
|
20
|
+
expect(attachment.variables).to eq('foo')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe :to_query_format do
|
25
|
+
it "is an hash with name and condition values" do
|
26
|
+
attachment = described_class.new('foo', { v1: 'bar', v2: 'baz'}, nil)
|
27
|
+
allow(attachment).to receive(:variables).and_return([
|
28
|
+
double(name: 'v1'), double(name: 'v2')
|
29
|
+
])
|
30
|
+
expect(attachment.to_query_format).to eq({
|
31
|
+
name: 'foo',
|
32
|
+
condition_values: {
|
33
|
+
'v1' => 'bar', 'v2' => 'baz'
|
34
|
+
}
|
35
|
+
})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe :to_save_format do
|
40
|
+
it "is an hash with name, attachment and conditions" do
|
41
|
+
attachment = described_class.new('foo', { v1: 'bar', v2: 'baz'},
|
42
|
+
'content')
|
43
|
+
allow(attachment).to receive(:variables).and_return([
|
44
|
+
double(name: 'v1', predicate: '='), double(name: 'v2', predicate: '<=')
|
45
|
+
])
|
46
|
+
expect(attachment.to_save_format).to eq({
|
47
|
+
name: 'foo',
|
48
|
+
attachment: 'content',
|
49
|
+
conditions: ['v1 = bar', 'v2 <= baz']
|
50
|
+
})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :add_variable do
|
55
|
+
it "adds a new variable in the class list" do
|
56
|
+
described_class.add_variable('foo', '=')
|
57
|
+
v = described_class.variables.first
|
58
|
+
expect(v.name).to eq('foo')
|
59
|
+
expect(v.predicate).to eq('=')
|
60
|
+
end
|
61
|
+
|
62
|
+
context "if predicate symbol is not allowed" do
|
63
|
+
it "raises an exception" do
|
64
|
+
expect { described_class.add_variable('foo', 'X') }.to raise_exception
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'sqlcached_client/attachments'
|
2
|
+
|
3
|
+
describe SqlcachedClient::Attachments do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new do
|
6
|
+
include SqlcachedClient::Attachments
|
7
|
+
|
8
|
+
has_attachment :foo do
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "after including the module" do
|
14
|
+
it "add methods 'has_attachment' and 'build_attachments' to the class" do
|
15
|
+
expect(klass.respond_to?(:has_attachment)).to eq(true)
|
16
|
+
expect(klass.respond_to?(:build_attachments)).to eq(true)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -154,7 +154,8 @@ describe SqlcachedClient::Entity do
|
|
154
154
|
entity_class.server(double(
|
155
155
|
build_request_item: "this is the request",
|
156
156
|
build_request: "request body",
|
157
|
-
session:
|
157
|
+
session: double(is_array?: false,
|
158
|
+
entities: [{ key: "value" }, { key: "value" }])
|
158
159
|
))
|
159
160
|
expect(entity_class.server).to receive(:build_request_item).with(
|
160
161
|
"foo", "bar", { baz: "biz" }, true)
|
@@ -224,4 +225,9 @@ describe SqlcachedClient::Entity do
|
|
224
225
|
describe :build_query_tree do
|
225
226
|
pending
|
226
227
|
end
|
228
|
+
|
229
|
+
|
230
|
+
describe :transaction do
|
231
|
+
pending
|
232
|
+
end
|
227
233
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'sqlcached_client/proxy_object'
|
2
|
+
|
3
|
+
describe SqlcachedClient::ProxyObject do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new do
|
6
|
+
def foo
|
7
|
+
'bar'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "forwards method calls to the proxied object" do
|
13
|
+
f = klass.new
|
14
|
+
p = SqlcachedClient::ProxyObject.new(f)
|
15
|
+
expect(p.foo).to eq('bar')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe :execute do
|
19
|
+
it "executes the block provided in the context of the instance" do
|
20
|
+
f = klass.new
|
21
|
+
p = SqlcachedClient::ProxyObject.new(f)
|
22
|
+
expect(p.execute { foo }).to eq('bar')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe :plug_method do
|
27
|
+
it "defines a singleton method on the proxy object" do
|
28
|
+
p = SqlcachedClient::ProxyObject.new(Object.new)
|
29
|
+
p.plug_method(:sum) do |a, b|
|
30
|
+
a + b
|
31
|
+
end
|
32
|
+
expect(p.sum(2, 3)).to eq(5)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -26,12 +26,10 @@ describe SqlcachedClient::Resultset do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
29
|
describe :build_associations do
|
31
30
|
pending
|
32
31
|
end
|
33
32
|
|
34
|
-
|
35
33
|
describe :[] do
|
36
34
|
it "should be entities[i]" do
|
37
35
|
entities = [Object.new] * 3
|
@@ -39,4 +37,43 @@ describe SqlcachedClient::Resultset do
|
|
39
37
|
3.times { |i| expect(r[i]).to eq(entities[i]) }
|
40
38
|
end
|
41
39
|
end
|
40
|
+
|
41
|
+
describe :set_entities_attachments do
|
42
|
+
let(:resultset) { SqlcachedClient::Resultset.new(nil, nil) }
|
43
|
+
|
44
|
+
let(:entities) do
|
45
|
+
[double(:attach1=)]
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:attachment) { double(:content=, name: 'attach1') }
|
49
|
+
|
50
|
+
it "sets each attachment to the corresponding entity and saves the content" do
|
51
|
+
expect(entities.first).to receive(:attach1=).with(attachment)
|
52
|
+
expect(attachment).to receive(:content=).with('content')
|
53
|
+
resultset.set_entities_attachments(entities, [attachment], ['content'])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe :store_attachments do
|
58
|
+
let(:resultset) { SqlcachedClient::Resultset.new(nil, nil) }
|
59
|
+
|
60
|
+
let(:entities) do
|
61
|
+
[
|
62
|
+
double(att1: double(to_save_format: 'value a'), attributes: 'attrs a'),
|
63
|
+
double(att1: double(to_save_format: 'value b'), attributes: 'attrs b')
|
64
|
+
]
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:server) { double }
|
68
|
+
|
69
|
+
it "calls server.store_attachments" do
|
70
|
+
expect(server).to receive(:build_store_attachments_request).with(
|
71
|
+
['attrs a', 'attrs b'], ['value a', 'value b']
|
72
|
+
).and_return('attachment request')
|
73
|
+
expect(server).to receive(:store_attachments).with('session',
|
74
|
+
'attachment request')
|
75
|
+
allow(resultset).to receive(:entities).and_return(entities)
|
76
|
+
resultset.store_attachments(:att1, server, 'session')
|
77
|
+
end
|
78
|
+
end
|
42
79
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sqlcached_client/server_responses/query_response'
|
2
|
+
|
3
|
+
describe SqlcachedClient::ServerResponses::QueryResponse do
|
4
|
+
let(:described_class) { SqlcachedClient::ServerResponses::QueryResponse }
|
5
|
+
|
6
|
+
describe :entities do
|
7
|
+
context "if body is an array" do
|
8
|
+
it "parses each item recoursively" do
|
9
|
+
query_response = described_class.new([[1, 2, [3, 4]], 5])
|
10
|
+
expect(query_response.entities).to eq(
|
11
|
+
[[1, 2, [3, 4]], 5])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "if body is an hash" do
|
16
|
+
it "returns the value corresponding to the key 'resultset'" do
|
17
|
+
query_response = described_class.new({ 'resultset' => 1 })
|
18
|
+
expect(query_response.entities).to eq(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "if key 'resultset' is not present" do
|
22
|
+
it "is nil" do
|
23
|
+
query_response = described_class.new({ foo: 'bar' })
|
24
|
+
expect(query_response.entities).to be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "if resultset is a string" do
|
29
|
+
it "is parsed as json" do
|
30
|
+
query_response = described_class.new({
|
31
|
+
'resultset' => "{ \"foo\": \"bar\", \"baz\": 1 }"
|
32
|
+
})
|
33
|
+
expect(query_response.entities).to eq({
|
34
|
+
"foo" => "bar", "baz" => 1 })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe :attachments do
|
41
|
+
context "when body is an Hash" do
|
42
|
+
it "is body.attachments" do
|
43
|
+
query_response = described_class.new({ 'attachments' => 'foo' })
|
44
|
+
expect(query_response.attachments).to eq('foo')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when body is not an Hash" do
|
49
|
+
it "is nil" do
|
50
|
+
query_response = described_class.new(['foo', 'bar'])
|
51
|
+
expect(query_response.attachments).to be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe :is_array? do
|
57
|
+
context "when entities is an Array" do
|
58
|
+
it "is true" do
|
59
|
+
query_response = described_class.new(['foo'])
|
60
|
+
expect(query_response.is_array?).to eq(true)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when entities is not an Array" do
|
65
|
+
it "is false" do
|
66
|
+
query_response = described_class.new({})
|
67
|
+
expect(query_response.is_array?).to eq(false)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe :flatten! do
|
73
|
+
it "flattens the entities in place" do
|
74
|
+
query_response = described_class.new([[1, [2]], [3]])
|
75
|
+
query_response.flatten!
|
76
|
+
expect(query_response.entities).to eq([1, 2, 3])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -12,14 +12,12 @@ describe SqlcachedClient::Server do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
15
|
describe :build_request do
|
17
16
|
it "should put the passed value into an hash" do
|
18
17
|
expect(server.build_request("foo")).to eq({ batch: "foo" })
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
21
|
describe :build_tree_request do
|
24
22
|
it "should be an Hash with 'tree' and 'root_parameters' keys" do
|
25
23
|
expect(server.build_tree_request('tree', 'root')).to eq({
|
@@ -28,7 +26,6 @@ describe SqlcachedClient::Server do
|
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
31
|
-
|
32
29
|
describe :build_request_item do
|
33
30
|
it "should be an hash with id, template, params keys" do
|
34
31
|
expect(server.build_request_item("foo", "bar", "baz", "cache")).to eq({
|
@@ -40,33 +37,11 @@ describe SqlcachedClient::Server do
|
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
[[1, 2, [3, 4]], 5])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context "if body is an hash" do
|
53
|
-
it "should return the value corresponding to the key 'resultset'" do
|
54
|
-
expect(server.parse_response_body({ 'resultset' => 1 })).to eq(1)
|
55
|
-
end
|
56
|
-
|
57
|
-
context "if key 'resultset' is not present" do
|
58
|
-
it "should be nil" do
|
59
|
-
expect(server.parse_response_body({ foo: 'bar' })).to be_nil
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context "if resultset is a string" do
|
64
|
-
it "should be parsed as json" do
|
65
|
-
expect(server.parse_response_body({
|
66
|
-
'resultset' => "{ \"foo\": \"bar\", \"baz\": 1 }" })).to eq({
|
67
|
-
"foo" => "bar", "baz" => 1 })
|
68
|
-
end
|
69
|
-
end
|
40
|
+
describe :build_store_attachments_request do
|
41
|
+
it "contains keys resultset and attachments" do
|
42
|
+
expect(server.build_store_attachments_request('e', 'a')).to eq({
|
43
|
+
resultset: 'e', attachments: 'a'
|
44
|
+
})
|
70
45
|
end
|
71
46
|
end
|
72
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlcached_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Maestroni
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -122,13 +122,21 @@ files:
|
|
122
122
|
- Rakefile
|
123
123
|
- lib/sqlcached_client.rb
|
124
124
|
- lib/sqlcached_client/arel.rb
|
125
|
+
- lib/sqlcached_client/attachment.rb
|
126
|
+
- lib/sqlcached_client/attachments.rb
|
125
127
|
- lib/sqlcached_client/entity.rb
|
128
|
+
- lib/sqlcached_client/proxy_object.rb
|
126
129
|
- lib/sqlcached_client/resultset.rb
|
127
130
|
- lib/sqlcached_client/server.rb
|
131
|
+
- lib/sqlcached_client/server_responses/query_response.rb
|
128
132
|
- lib/sqlcached_client/tree_visitor.rb
|
129
133
|
- lib/sqlcached_client/version.rb
|
134
|
+
- spec/sqlcached_client/attachment_spec.rb
|
135
|
+
- spec/sqlcached_client/attachments_spec.rb
|
130
136
|
- spec/sqlcached_client/entity_spec.rb
|
137
|
+
- spec/sqlcached_client/proxy_object_spec.rb
|
131
138
|
- spec/sqlcached_client/resultset_spec.rb
|
139
|
+
- spec/sqlcached_client/server_responses/query_response_spec.rb
|
132
140
|
- spec/sqlcached_client/server_spec.rb
|
133
141
|
- spec/sqlcached_client/tree_visitor_spec.rb
|
134
142
|
- sqlcached_client.gemspec
|
@@ -157,7 +165,11 @@ signing_key:
|
|
157
165
|
specification_version: 4
|
158
166
|
summary: A Ruby client for sqlcached
|
159
167
|
test_files:
|
168
|
+
- spec/sqlcached_client/attachment_spec.rb
|
169
|
+
- spec/sqlcached_client/attachments_spec.rb
|
160
170
|
- spec/sqlcached_client/entity_spec.rb
|
171
|
+
- spec/sqlcached_client/proxy_object_spec.rb
|
161
172
|
- spec/sqlcached_client/resultset_spec.rb
|
173
|
+
- spec/sqlcached_client/server_responses/query_response_spec.rb
|
162
174
|
- spec/sqlcached_client/server_spec.rb
|
163
175
|
- spec/sqlcached_client/tree_visitor_spec.rb
|