sqlcached_client 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sqlcached_client/entity.rb +31 -1
- data/lib/sqlcached_client/resultset.rb +7 -3
- data/lib/sqlcached_client/server.rb +28 -17
- data/lib/sqlcached_client/version.rb +1 -1
- data/spec/sqlcached_client/entity_spec.rb +150 -0
- data/spec/sqlcached_client/resultset_spec.rb +43 -0
- data/spec/sqlcached_client/server_spec.rb +62 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76ca46c57afc585a8a3ba673e64992b765534fde
|
4
|
+
data.tar.gz: 2be70c7d54517dd4a3d3bedb833572592b3bfea0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f797a555a1f56561da3a56c535ddd8f0822e6636cfa5d3b2bc648cff9e99f51cc0d8e215c1aca398ba381e5ed87b5f24f64b5cebd59ddec6b688fa475aef895
|
7
|
+
data.tar.gz: cfa1fa922a25c58a327361e0561b7fd5d4391562f4f125ac32cd16bb1a7de6252b2db9655767843847ae448f6550567152f74fea1000e498b6dba11776bae0a1
|
@@ -17,14 +17,19 @@ module SqlcachedClient
|
|
17
17
|
class << self
|
18
18
|
attr_reader :query_id
|
19
19
|
|
20
|
+
# Sets the name of this entity
|
20
21
|
def entity_name(value)
|
21
22
|
@query_id = value
|
22
23
|
end
|
23
24
|
|
25
|
+
# Sets the query of this entity if a parameter is provided, otherwise
|
26
|
+
# returns the value previously set.
|
24
27
|
def query(sql_string = nil)
|
25
28
|
sql_string.nil? ? @query : @query = sql_string.strip
|
26
29
|
end
|
27
30
|
|
31
|
+
# Configures the server of this entity if a parameter is provided,
|
32
|
+
# otherwise returns the server object previously set.
|
28
33
|
def server(config = nil)
|
29
34
|
if config.nil?
|
30
35
|
@server ||
|
@@ -43,17 +48,40 @@ module SqlcachedClient
|
|
43
48
|
end
|
44
49
|
end
|
45
50
|
|
51
|
+
# Gets a session from the server and yields the passed block
|
52
|
+
def server_session(&block)
|
53
|
+
server.session(&block)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Runs the entity query with the provided parameters
|
57
|
+
# @return [Resultset]
|
46
58
|
def where(params, dry_run = false)
|
47
59
|
request = server.format_request(query_id, query, params)
|
48
60
|
if dry_run
|
49
61
|
request
|
50
62
|
else
|
51
|
-
data =
|
63
|
+
data =
|
64
|
+
server.session do |server, session|
|
65
|
+
server.run_query(session, server.build_request_body([request]))
|
66
|
+
end
|
52
67
|
data = data[0] if data.is_a?(Array)
|
53
68
|
Resultset.new(self, data)
|
54
69
|
end
|
55
70
|
end
|
56
71
|
|
72
|
+
# Defines a 'has_many' relationship. Available options are
|
73
|
+
# [class_name]
|
74
|
+
# Specifies the class of the associated objects, if not given it's
|
75
|
+
# inferred from the accessor_name (singularized + camelized).
|
76
|
+
# [where]
|
77
|
+
# Specifies how to fill the query template for the associated objects.
|
78
|
+
# It's an hash where each key is a foreign parameter that will be
|
79
|
+
# set to the value provided. A special case occours when the value is
|
80
|
+
# a Symbol, in this case it represents the value of the attribute named
|
81
|
+
# as the symbol.
|
82
|
+
# For example, <tt>where: { id: :user_id }</tt> fills the parameter
|
83
|
+
# <tt>id</tt> of the foreign entity with the value of
|
84
|
+
# <tt>self.user_id</tt>.
|
57
85
|
def has_many(accessor_name, options)
|
58
86
|
foreign_class_name =
|
59
87
|
if options[:class_name].present?
|
@@ -100,6 +128,8 @@ module SqlcachedClient
|
|
100
128
|
register_association(accessor_name)
|
101
129
|
end
|
102
130
|
|
131
|
+
# Defines a 'has_one' relationship. See 'has_many' for the available
|
132
|
+
# options
|
103
133
|
def has_one(accessor_name, options)
|
104
134
|
plural_accessor_name = "s_#{accessor_name}".to_s.pluralize
|
105
135
|
class_name = accessor_name.to_s.camelize
|
@@ -22,12 +22,13 @@ module SqlcachedClient
|
|
22
22
|
|
23
23
|
class << self
|
24
24
|
|
25
|
-
def build_associations(resultsets, server, max_depth, current_depth = 0)
|
25
|
+
def build_associations(resultsets, server, session, max_depth, current_depth = 0)
|
26
26
|
if resultsets.any?
|
27
27
|
batch = resultsets.map { |r| r._get_entities_association_requests }
|
28
28
|
if batch.flatten.any?
|
29
29
|
next_batch =
|
30
30
|
server.run_query(
|
31
|
+
session,
|
31
32
|
server.build_request_body(
|
32
33
|
batch
|
33
34
|
)
|
@@ -35,7 +36,8 @@ module SqlcachedClient
|
|
35
36
|
resultsets[i]._fill_associations(resultset_data)
|
36
37
|
end.flatten!
|
37
38
|
if !max_depth || current_depth < max_depth
|
38
|
-
build_associations(next_batch, server, max_depth,
|
39
|
+
build_associations(next_batch, server, session, max_depth,
|
40
|
+
current_depth + 1)
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -55,7 +57,9 @@ module SqlcachedClient
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def build_associations(max_depth = false)
|
58
|
-
|
60
|
+
entity_class.server_session do |server, session|
|
61
|
+
self.class.build_associations([self], server, session, max_depth)
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
def _fill_associations(data)
|
@@ -12,23 +12,20 @@ module SqlcachedClient
|
|
12
12
|
end
|
13
13
|
|
14
14
|
|
15
|
-
def run_query(http_req_body)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
raise "Got http response #{resp.code} from server - #{resp_body.inspect}"
|
31
|
-
end
|
15
|
+
def run_query(session, http_req_body)
|
16
|
+
req = Net::HTTP::Post.new(data_batch_url)
|
17
|
+
req.set_content_type('application/json')
|
18
|
+
req.body = http_req_body.to_json
|
19
|
+
resp = session.request(req)
|
20
|
+
if 'application/json' == resp['Content-Type']
|
21
|
+
resp_body = parse_response_body(JSON.parse(resp.body))
|
22
|
+
else
|
23
|
+
resp_body = resp.body
|
24
|
+
end
|
25
|
+
if 200 == resp.code.to_i
|
26
|
+
resp_body
|
27
|
+
else
|
28
|
+
raise "Got http response #{resp.code} from server - #{resp_body.inspect}"
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
@@ -61,6 +58,20 @@ module SqlcachedClient
|
|
61
58
|
}
|
62
59
|
end
|
63
60
|
|
61
|
+
|
62
|
+
def get_session
|
63
|
+
url = server_url
|
64
|
+
Net::HTTP.start(url.host, url.port)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def session
|
69
|
+
s = get_session
|
70
|
+
ret_value = yield(self, s) if block_given?
|
71
|
+
s.finish
|
72
|
+
ret_value
|
73
|
+
end
|
74
|
+
|
64
75
|
private
|
65
76
|
|
66
77
|
def server_url
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'sqlcached_client/entity'
|
2
|
+
require 'sqlcached_client/server'
|
3
|
+
|
4
|
+
describe SqlcachedClient::Entity do
|
5
|
+
|
6
|
+
describe :initialize do
|
7
|
+
it "should record the attribute names" do
|
8
|
+
e = SqlcachedClient::Entity.new({ foo: 'bar', baz: 'biz' })
|
9
|
+
expect(e.attribute_names).to eq([:foo, :baz])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
describe :entity_name do
|
15
|
+
it "should set query_id" do
|
16
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
17
|
+
entity_name("foo")
|
18
|
+
end
|
19
|
+
expect(entity_class.query_id).to eq("foo")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe :query do
|
25
|
+
context "if a parameter is provided" do
|
26
|
+
it "should set @query and strip spaces" do
|
27
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
28
|
+
query(" foo \n ")
|
29
|
+
end
|
30
|
+
expect(entity_class.instance_variable_get(:@query)).to eq("foo")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "if no parameter is provided" do
|
35
|
+
it "should return the value previously stored" do
|
36
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
37
|
+
query(" foo \n ")
|
38
|
+
end
|
39
|
+
expect(entity_class.query).to eq("foo")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
describe :server do
|
46
|
+
context "if a parameter is provided" do
|
47
|
+
it "should set @server" do
|
48
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
49
|
+
server("foo")
|
50
|
+
end
|
51
|
+
expect(entity_class.instance_variable_get(:@server)).to eq("foo")
|
52
|
+
end
|
53
|
+
|
54
|
+
context "if the parameter is an hash" do
|
55
|
+
it "should instantiate a new Server" do
|
56
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
57
|
+
server(foo: "bar")
|
58
|
+
end
|
59
|
+
expect(entity_class.server).to be_instance_of(SqlcachedClient::Server)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "if no parameter is provided" do
|
65
|
+
it "should return the value previously stored" do
|
66
|
+
entity_class = Class.new(SqlcachedClient::Entity) do
|
67
|
+
server("foo")
|
68
|
+
end
|
69
|
+
expect(entity_class.server).to eq("foo")
|
70
|
+
end
|
71
|
+
|
72
|
+
context "if no server was configured for the class" do
|
73
|
+
it "should use the value from the first ancestor" do
|
74
|
+
entity_class0 = Class.new(SqlcachedClient::Entity) do
|
75
|
+
server("foo")
|
76
|
+
end
|
77
|
+
entity_class1 = Class.new(entity_class0)
|
78
|
+
expect(entity_class1.server).to eq("foo")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
describe :where do
|
86
|
+
let(:entity_class) do
|
87
|
+
Class.new(SqlcachedClient::Entity) do
|
88
|
+
entity_name 'foo'
|
89
|
+
query 'bar'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "if dry_run" do
|
94
|
+
it "should return the request that would be sent to the server" do
|
95
|
+
entity_class.server(double(format_request: "this is the request"))
|
96
|
+
expect(entity_class.server).to receive(:format_request).with("foo", "bar", { baz: "biz" })
|
97
|
+
expect(entity_class.where({ baz: "biz" }, true)).to eq("this is the request")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "if not dry_run" do
|
102
|
+
it "should create a new ResultSet" do
|
103
|
+
entity_class.server(double(
|
104
|
+
format_request: "this is the request",
|
105
|
+
build_request_body: "request body",
|
106
|
+
session: [[{ key: "value" }], 2, 3]
|
107
|
+
))
|
108
|
+
expect(entity_class.server).to receive(:format_request).with(
|
109
|
+
"foo", "bar", { baz: "biz" })
|
110
|
+
expect(entity_class.where({ baz: "biz" })).to be_instance_of(
|
111
|
+
SqlcachedClient::Resultset)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
describe :has_many do
|
118
|
+
pending
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
describe :has_one do
|
123
|
+
pending
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
describe :get_association_requests do
|
128
|
+
pending
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
describe :set_associations_data do
|
133
|
+
pending
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
describe :get_associations do
|
138
|
+
pending
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
describe :build_associations do
|
143
|
+
pending
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
describe :to_h do
|
148
|
+
pending
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'sqlcached_client/resultset'
|
2
|
+
require 'sqlcached_client/hash_struct'
|
3
|
+
|
4
|
+
describe SqlcachedClient::Resultset do
|
5
|
+
|
6
|
+
describe :initialize do
|
7
|
+
|
8
|
+
it "should set count" do
|
9
|
+
r = SqlcachedClient::Resultset.new(Object, [Object.new] * 3)
|
10
|
+
expect(r.count).to eq(3)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when passed entities are hashes" do
|
14
|
+
it "should map them to instances of the entity class provided" do
|
15
|
+
r = SqlcachedClient::Resultset.new(SqlcachedClient::HashStruct,
|
16
|
+
[{ foo: 'bar' }] * 3)
|
17
|
+
expect(r.entities[0]).to be_instance_of(SqlcachedClient::HashStruct)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when passing entities that are instances of the class" do
|
22
|
+
it "should set them without do anything" do
|
23
|
+
entities = [Object.new] * 3
|
24
|
+
r = SqlcachedClient::Resultset.new(Object, entities)
|
25
|
+
expect(r.entities).to eq(entities)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe :build_associations do
|
32
|
+
pending
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe :[] do
|
37
|
+
it "should be entities[i]" do
|
38
|
+
entities = [Object.new] * 3
|
39
|
+
r = SqlcachedClient::Resultset.new(Object, entities)
|
40
|
+
3.times { |i| expect(r[i]).to eq(entities[i]) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'sqlcached_client/server'
|
2
|
+
|
3
|
+
describe SqlcachedClient::Server do
|
4
|
+
|
5
|
+
let(:server) { SqlcachedClient::Server.new({}) }
|
6
|
+
|
7
|
+
describe :initialize do
|
8
|
+
it "should set host and port" do
|
9
|
+
server = SqlcachedClient::Server.new(host: "localhost", port: 80)
|
10
|
+
expect(server.host).to eq("localhost")
|
11
|
+
expect(server.port).to eq(80)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe :build_request_body do
|
17
|
+
it "should put the passed value into an hash" do
|
18
|
+
expect(server.build_request_body("foo")).to eq({ batch: "foo" })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
describe :format_request do
|
24
|
+
it "should be an hash with id, template, params keys" do
|
25
|
+
expect(server.format_request("foo", "bar", "baz")).to eq({
|
26
|
+
queryId: "foo",
|
27
|
+
queryTemplate: "bar",
|
28
|
+
queryParams: "baz"
|
29
|
+
})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe :parse_response_body do
|
35
|
+
context "if body is an array" do
|
36
|
+
it "should parse each item recoursively" do
|
37
|
+
expect(server.parse_response_body([[1, 2, [3, 4]], 5])).to eq(
|
38
|
+
[[1, 2, [3, 4]], 5])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "if body is an hash" do
|
43
|
+
it "should return the value corresponding to the key 'resultset'" do
|
44
|
+
expect(server.parse_response_body({ 'resultset' => 1 })).to eq(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
context "if key 'resultset' is not present" do
|
48
|
+
it "should be nil" do
|
49
|
+
expect(server.parse_response_body({ foo: 'bar' })).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "if resultset is a string" do
|
54
|
+
it "should be parsed as json" do
|
55
|
+
expect(server.parse_response_body({
|
56
|
+
'resultset' => "{ \"foo\": \"bar\", \"baz\": 1 }" })).to eq({
|
57
|
+
"foo" => "bar", "baz" => 1 })
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
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: 0.0.
|
4
|
+
version: 0.0.2
|
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-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -84,7 +84,10 @@ files:
|
|
84
84
|
- lib/sqlcached_client/resultset.rb
|
85
85
|
- lib/sqlcached_client/server.rb
|
86
86
|
- lib/sqlcached_client/version.rb
|
87
|
+
- spec/sqlcached_client/entity_spec.rb
|
87
88
|
- spec/sqlcached_client/hash_struct_spec.rb
|
89
|
+
- spec/sqlcached_client/resultset_spec.rb
|
90
|
+
- spec/sqlcached_client/server_spec.rb
|
88
91
|
- sqlcached_client.gemspec
|
89
92
|
homepage: https://github.com/rmaestroni/sqlcached_client
|
90
93
|
licenses:
|
@@ -111,4 +114,7 @@ signing_key:
|
|
111
114
|
specification_version: 4
|
112
115
|
summary: A Ruby client for sqlcached
|
113
116
|
test_files:
|
117
|
+
- spec/sqlcached_client/entity_spec.rb
|
114
118
|
- spec/sqlcached_client/hash_struct_spec.rb
|
119
|
+
- spec/sqlcached_client/resultset_spec.rb
|
120
|
+
- spec/sqlcached_client/server_spec.rb
|