tarantool16 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/tarantool16/connection/common.rb +10 -4
- data/lib/tarantool16/connection/dumb.rb +120 -7
- data/lib/tarantool16/db.rb +7 -1
- data/lib/tarantool16/dumb_db.rb +23 -28
- data/lib/tarantool16/schema.rb +27 -8
- data/lib/tarantool16/version.rb +1 -1
- data/test/bench_timeout.rb +36 -0
- data/test/config.lua +2 -2
- data/test/helper.rb +32 -3
- data/test/test_dumb.rb +71 -8
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34d90ff491fcf45653aa4038a3c2730f67071cf3
|
4
|
+
data.tar.gz: 3352d2894b63e5db9407fd1c621752babfc08ff9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34046053a18655464b966e9ad50182c3f947de8c29d63fdca3d291ec364c53538697a97845f8d048a546a5bfc543416456d60b8721e24f287af08b73182de1d0
|
7
|
+
data.tar.gz: a6ce2048a5ed0c7d48040015f2485ea295c57b07ba9bd8ca887fe0ac18c8e17dec2f4184e687fb9e196b58f92f0315eb2b9703430757adf353117c19f2569ea6
|
data/README.md
CHANGED
@@ -10,6 +10,7 @@ module Tarantool16
|
|
10
10
|
class ConnectionError < Error; end
|
11
11
|
class CouldNotConnect < ConnectionError; end
|
12
12
|
class Disconnected < ConnectionError; end
|
13
|
+
class Timeout < ConnectionError; end
|
13
14
|
class Retry < ConnectionError; end
|
14
15
|
class UnexpectedResponse < Error; end
|
15
16
|
|
@@ -31,6 +32,7 @@ module Tarantool16
|
|
31
32
|
else
|
32
33
|
@reconnect = false
|
33
34
|
end
|
35
|
+
@timeout = opts[:timeout]
|
34
36
|
@p = MessagePack::Packer.new
|
35
37
|
@u = MessagePack::Unpacker.new
|
36
38
|
@s = 0
|
@@ -127,10 +129,10 @@ module Tarantool16
|
|
127
129
|
elsif code == nil
|
128
130
|
return Option.error(nil, UnexpectedResponse, "Mailformed response: no code for sync=#{sync}")
|
129
131
|
end
|
130
|
-
|
132
|
+
begin
|
131
133
|
bmap = @u.read
|
132
134
|
body = bmap[IPROTO_DATA] || bmap[IPROTO_ERROR]
|
133
|
-
|
135
|
+
rescue EOFError
|
134
136
|
body = nil
|
135
137
|
end
|
136
138
|
Option.ok(sync, code, body)
|
@@ -139,8 +141,12 @@ module Tarantool16
|
|
139
141
|
end
|
140
142
|
|
141
143
|
def host_port
|
142
|
-
|
143
|
-
[
|
144
|
+
@host =~ /^(.*):([^:]+)$/
|
145
|
+
[$1, $2.to_i]
|
146
|
+
end
|
147
|
+
|
148
|
+
def _ipv6?
|
149
|
+
@host.count(':') > 1
|
144
150
|
end
|
145
151
|
|
146
152
|
def _insert(space_no, tuple, cb)
|
@@ -1,4 +1,10 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'io/wait'
|
3
|
+
begin
|
4
|
+
#require 'kgio'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
2
8
|
require_relative 'common'
|
3
9
|
module Tarantool16
|
4
10
|
module Connection
|
@@ -61,17 +67,25 @@ module Tarantool16
|
|
61
67
|
unless could_be_connected?
|
62
68
|
raise Disconnected, "connection is closed"
|
63
69
|
end
|
64
|
-
@socket =
|
70
|
+
@socket = Socket.new((_ipv6? ? Socket::AF_INET6 : Socket::AF_INET), Socket::SOCK_STREAM)
|
65
71
|
@socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
|
72
|
+
@socket.sync = true
|
73
|
+
sockaddr = Socket.pack_sockaddr_in(*host_port.reverse)
|
66
74
|
@retry = @reconnect
|
67
|
-
|
75
|
+
if @timeout
|
76
|
+
_connect_nonblock(sockaddr)
|
77
|
+
else
|
78
|
+
@socket.connect(sockaddr)
|
79
|
+
end
|
80
|
+
greeting = _read(IPROTO_GREETING_SIZE)
|
68
81
|
unless greeting && greeting.bytesize == IPROTO_GREETING_SIZE
|
69
82
|
raise Disconnected, "mailformed greeting #{greeting.inspect}"
|
70
83
|
end
|
71
84
|
@nbuf = "\x00\x00\x00\x00\x00".force_encoding('BINARY')
|
72
85
|
parse_greeting greeting
|
73
86
|
authenticate if @user
|
74
|
-
rescue ::Errno::ECONNREFUSED, ::Errno::EPIPE, Disconnected => e
|
87
|
+
rescue ::Errno::ECONNREFUSED, ::Errno::EPIPE, Disconnected, Timeout => e
|
88
|
+
@socket.close rescue nil
|
75
89
|
@socket = nil
|
76
90
|
if !@reconnect
|
77
91
|
@socket = false
|
@@ -82,9 +96,37 @@ module Tarantool16
|
|
82
96
|
raise CouldNotConnect, e.message
|
83
97
|
end
|
84
98
|
|
99
|
+
def _connect_nonblock(sockaddr)
|
100
|
+
expire = now_f + @timeout
|
101
|
+
begin
|
102
|
+
@socket.connect_nonblock(sockaddr)
|
103
|
+
rescue IO::WaitWritable
|
104
|
+
t = [@socket]
|
105
|
+
IO.select(t, t, nil, expire - now_f)
|
106
|
+
begin
|
107
|
+
@socket.connect_nonblock(sockaddr)
|
108
|
+
rescue Errno::EISCONN
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
85
113
|
def syswrite(req)
|
86
|
-
|
87
|
-
|
114
|
+
unless @timeout
|
115
|
+
if @socket.syswrite(req) != req.bytesize
|
116
|
+
raise Retry, "Could not write message"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
expire = now_f
|
120
|
+
begin
|
121
|
+
until req.empty?
|
122
|
+
n = @socket.write_nonblock(req)
|
123
|
+
req = req[n..-1]
|
124
|
+
end
|
125
|
+
rescue IO::WaitWritable
|
126
|
+
_wait_writable(expire - now_f)
|
127
|
+
rescue Errno::EINTR
|
128
|
+
retry
|
129
|
+
end
|
88
130
|
end
|
89
131
|
end
|
90
132
|
|
@@ -94,7 +136,7 @@ module Tarantool16
|
|
94
136
|
end
|
95
137
|
|
96
138
|
def _read_response
|
97
|
-
str =
|
139
|
+
str = _read(5, @nbuf)
|
98
140
|
unless str && str.bytesize == 5
|
99
141
|
# check if we sent request or not
|
100
142
|
begin
|
@@ -109,7 +151,7 @@ module Tarantool16
|
|
109
151
|
end
|
110
152
|
n = parse_size(str)
|
111
153
|
raise n unless ::Integer === n
|
112
|
-
resp =
|
154
|
+
resp = _read(n)
|
113
155
|
raise Disconnected, "disconnected while read response" unless resp && resp.bytesize == n
|
114
156
|
r = parse_response(resp)
|
115
157
|
if r.ok? && r.sync != @s
|
@@ -117,6 +159,77 @@ module Tarantool16
|
|
117
159
|
end
|
118
160
|
r
|
119
161
|
end
|
162
|
+
|
163
|
+
def _read(n, buf=nil)
|
164
|
+
unless @timeout
|
165
|
+
buf ? @socket.read(n, buf) : @socket.read(n)
|
166
|
+
else
|
167
|
+
expire = now_f + @timeout
|
168
|
+
rbuf = nil
|
169
|
+
while n > 0
|
170
|
+
case tbuf = _read_nonblock(n, buf)
|
171
|
+
when String
|
172
|
+
if rbuf
|
173
|
+
rbuf << tbuf
|
174
|
+
else
|
175
|
+
rbuf = tbuf
|
176
|
+
end
|
177
|
+
buf = nil
|
178
|
+
n -= tbuf.size
|
179
|
+
when :wait_readable
|
180
|
+
nf = now_f
|
181
|
+
if expire <= nf
|
182
|
+
raise Timeout, "response timeouted"
|
183
|
+
else
|
184
|
+
_wait_readable(expire - nf)
|
185
|
+
end
|
186
|
+
when nil
|
187
|
+
raise EOFError
|
188
|
+
end
|
189
|
+
end
|
190
|
+
return rbuf
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
if defined?(Kgio)
|
195
|
+
def _read_nonblock(n, buf)
|
196
|
+
return buf ? Kgio.tryread(@socket, n, buf) : Kgio.tryread(@socket, n)
|
197
|
+
end
|
198
|
+
else
|
199
|
+
def _read_nonblock(n, buf)
|
200
|
+
begin
|
201
|
+
if buf
|
202
|
+
@socket.read_nonblock(n, buf)
|
203
|
+
else
|
204
|
+
@socket.read_nonblock(n)
|
205
|
+
end
|
206
|
+
rescue IO::WaitReadable
|
207
|
+
return :wait_readable
|
208
|
+
rescue Errno::EINTR
|
209
|
+
retry
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
if RUBY_ENGINE == 'jruby'
|
215
|
+
def _wait_readable(timeout)
|
216
|
+
IO.select([@socket], nil, nil, timeout)
|
217
|
+
end
|
218
|
+
else
|
219
|
+
def _wait_readable(timeout)
|
220
|
+
@socket.wait(timeout)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
if IO.instance_methods.include?(:wait_writable)
|
224
|
+
def _wait_writable(timeout)
|
225
|
+
@socket.wait_writable(timeout)
|
226
|
+
end
|
227
|
+
else
|
228
|
+
def _wait_writable(timeout)
|
229
|
+
t = [@socket]
|
230
|
+
IO.select(t, t, nil, expire - now_f)
|
231
|
+
end
|
232
|
+
end
|
120
233
|
end
|
121
234
|
end
|
122
235
|
end
|
data/lib/tarantool16/db.rb
CHANGED
@@ -160,7 +160,13 @@ module Tarantool16
|
|
160
160
|
def _select(sno, ino, key, offset, limit, iterator, need_hash, cb)
|
161
161
|
key = [] if key.nil?
|
162
162
|
ino = 0 if ino.nil? && key.is_a?(Array)
|
163
|
-
|
163
|
+
unless iterator.is_a?(Integer)
|
164
|
+
if key.empty? && (Array === key || Hash === key)
|
165
|
+
iterator = ITERATOR_ALL
|
166
|
+
else
|
167
|
+
iterator = ::Tarantool16.iter(iterator)
|
168
|
+
end
|
169
|
+
end
|
164
170
|
if sno.is_a?(Integer) && ino.is_a?(Integer) && (key.is_a?(Array) || key.nil?)
|
165
171
|
return conn._select(sno, ino, key, offset, limit, iterator, cb)
|
166
172
|
end
|
data/lib/tarantool16/dumb_db.rb
CHANGED
@@ -20,36 +20,16 @@ module Tarantool16
|
|
20
20
|
offset = opts[:offset] || 0
|
21
21
|
limit = opts[:limit] || 2**30
|
22
22
|
iterator = opts[:iterator]
|
23
|
-
need_hash = opts
|
24
|
-
key =
|
25
|
-
when nil
|
26
|
-
[]
|
27
|
-
when Array
|
28
|
-
key
|
29
|
-
when Hash
|
30
|
-
need_hash = true
|
31
|
-
key
|
32
|
-
else
|
33
|
-
[key]
|
34
|
-
end
|
23
|
+
need_hash = opts.fetch(:hash, Hash === key)
|
24
|
+
key = _norm_key(key)
|
35
25
|
_select(sno, ino, key, offset, limit, iterator, need_hash, RETURN_OR_RAISE)
|
36
26
|
end
|
37
27
|
|
38
28
|
def get(sno, key, opts={})
|
39
29
|
ino = opts[:index]
|
40
30
|
iterator = opts[:iterator]
|
41
|
-
need_hash = opts
|
42
|
-
key =
|
43
|
-
when nil
|
44
|
-
[]
|
45
|
-
when Array
|
46
|
-
key
|
47
|
-
when Hash
|
48
|
-
need_hash = true
|
49
|
-
key
|
50
|
-
else
|
51
|
-
[key]
|
52
|
-
end
|
31
|
+
need_hash = opts.fetch(:hash, Hash === key)
|
32
|
+
key = _norm_key(key)
|
53
33
|
_select(sno, ino, key, 0, 1, iterator, need_hash, RETURN_ONE_OR_RAISE)
|
54
34
|
end
|
55
35
|
|
@@ -64,14 +44,18 @@ module Tarantool16
|
|
64
44
|
end
|
65
45
|
|
66
46
|
def delete(sno, key, opts = {})
|
67
|
-
|
68
|
-
|
47
|
+
key_hash = Hash === key
|
48
|
+
ino = opts[:index] || (key_hash ? nil : 0)
|
49
|
+
need_hash = opts.fetch(:hash, key_hash)
|
50
|
+
key = _norm_key(key)
|
69
51
|
_delete(sno, ino, key, need_hash, RETURN_OR_RAISE)
|
70
52
|
end
|
71
53
|
|
72
54
|
def update(sno, key, ops, opts = {})
|
73
|
-
|
74
|
-
|
55
|
+
key_hash = Hash === key
|
56
|
+
ino = opts[:index] || (key_hash ? nil : 0)
|
57
|
+
need_hash = opts.fetch(:hash, key_hash)
|
58
|
+
key = _norm_key(key)
|
75
59
|
_update(sno, ino, key, ops, need_hash, RETURN_OR_RAISE)
|
76
60
|
end
|
77
61
|
|
@@ -83,6 +67,17 @@ module Tarantool16
|
|
83
67
|
yield
|
84
68
|
end
|
85
69
|
|
70
|
+
def _norm_key(key)
|
71
|
+
case key
|
72
|
+
when Array
|
73
|
+
key
|
74
|
+
when Hash
|
75
|
+
key
|
76
|
+
else
|
77
|
+
[key]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
86
81
|
class SchemaFuture
|
87
82
|
UNDEF = Object.new.freeze
|
88
83
|
def initialize
|
data/lib/tarantool16/schema.rb
CHANGED
@@ -70,17 +70,15 @@ module Tarantool16
|
|
70
70
|
@indices && !@indices.empty?
|
71
71
|
end
|
72
72
|
|
73
|
-
def get_ino(ino, key,
|
73
|
+
def get_ino(ino, key, _iter, cb)
|
74
74
|
if ino.nil?
|
75
75
|
unless key.is_a?(Hash)
|
76
76
|
opt = Option.error(SchemaError, "Could not detect index without field names and iterator: #{key.inspect} in #{name_sid}")
|
77
77
|
return cb.call(opt)
|
78
78
|
end
|
79
|
-
unless iter.is_a?(Integer)
|
80
|
-
iter = ::Tarantool16.iter(iter)
|
81
|
-
end
|
82
79
|
# key should be Hash here
|
83
80
|
keys = key.keys
|
81
|
+
keys << _iter
|
84
82
|
_ino = @_fields_2_ino[keys]
|
85
83
|
if _ino
|
86
84
|
ind = @indices[_ino]
|
@@ -89,6 +87,8 @@ module Tarantool16
|
|
89
87
|
opt = Option.error(SchemaError, "Could not detect index for fields #{key.keys} in #{name_sid}")
|
90
88
|
return cb.call(opt)
|
91
89
|
end
|
90
|
+
keys.pop
|
91
|
+
iter = _iter.is_a?(Integer) ? _iter : ::Tarantool16.iter(iter)
|
92
92
|
|
93
93
|
fields = keys.map{|fld|
|
94
94
|
case fld
|
@@ -105,7 +105,7 @@ module Tarantool16
|
|
105
105
|
for ind in @indices
|
106
106
|
next unless ind
|
107
107
|
first_fields = ind.parts[0,fields.size]
|
108
|
-
if ind.can_iterator?(iter)
|
108
|
+
if ind.can_iterator?(iter, fields.size)
|
109
109
|
if fields == first_fields
|
110
110
|
index = ind
|
111
111
|
break
|
@@ -114,6 +114,7 @@ module Tarantool16
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
117
|
+
keys << _iter
|
117
118
|
if index
|
118
119
|
@_fields_2_ino[keys.freeze] = index.pos
|
119
120
|
yield index.pos, index.map_key(key)
|
@@ -189,7 +190,15 @@ module Tarantool16
|
|
189
190
|
_op[1] = @field_names[_1].pos
|
190
191
|
_op
|
191
192
|
when Array
|
192
|
-
|
193
|
+
fld_pos = case op[0]
|
194
|
+
when Integer
|
195
|
+
op[0]
|
196
|
+
when Symbol, String
|
197
|
+
@field_names[op[0]].pos
|
198
|
+
else
|
199
|
+
raise "No field #{op[0].inspect} in #{name_sid}"
|
200
|
+
end
|
201
|
+
_1.dup.insert(1, fld_pos)
|
193
202
|
end
|
194
203
|
end
|
195
204
|
end
|
@@ -236,8 +245,18 @@ module Tarantool16
|
|
236
245
|
}
|
237
246
|
end
|
238
247
|
|
239
|
-
def can_iterator?(iter)
|
240
|
-
@iters.include?(iter)
|
248
|
+
def can_iterator?(iter, flds_cnt)
|
249
|
+
@iters.include?(iter) && begin
|
250
|
+
if iter == ITERATOR_ALL
|
251
|
+
true
|
252
|
+
elsif @type == :hash && flds_cnt == @parts.count
|
253
|
+
true
|
254
|
+
elsif flds_cnt == 1
|
255
|
+
true
|
256
|
+
else
|
257
|
+
false
|
258
|
+
end
|
259
|
+
end
|
241
260
|
end
|
242
261
|
|
243
262
|
def map_key(key)
|
data/lib/tarantool16/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'tarantool16'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
def bench_1000_get(kind, timeout=nil)
|
5
|
+
case kind
|
6
|
+
when :no, :external
|
7
|
+
db = Tarantool16.new host: '127.0.0.1:33013'
|
8
|
+
when :native
|
9
|
+
db = Tarantool16.new host: '127.0.0.1:33013', timeout: timeout
|
10
|
+
end
|
11
|
+
now = Time.now.to_f
|
12
|
+
if kind == :external
|
13
|
+
10000.times do
|
14
|
+
Timeout.timeout(1) do
|
15
|
+
db.get(:test, 1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
else
|
19
|
+
10000.times do
|
20
|
+
db.get(:test, 1)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
r = Time.now.to_f - now
|
24
|
+
db.conn.disconnect
|
25
|
+
r
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "Without timeout: %f" % bench_1000_get(:no, nil)
|
29
|
+
puts "With timeout: %f" % bench_1000_get(:native, 1)
|
30
|
+
puts "With Timeout: %f" % bench_1000_get(:external, 1)
|
31
|
+
puts "Without timeout: %f" % bench_1000_get(:no, nil)
|
32
|
+
puts "With timeout: %f" % bench_1000_get(:native, 1)
|
33
|
+
puts "With Timeout: %f" % bench_1000_get(:external, 1)
|
34
|
+
puts "Without timeout: %f" % bench_1000_get(:no, nil)
|
35
|
+
puts "With timeout: %f" % bench_1000_get(:native, 1)
|
36
|
+
puts "With Timeout: %f" % bench_1000_get(:external, 1)
|
data/test/config.lua
CHANGED
data/test/helper.rb
CHANGED
@@ -62,15 +62,40 @@ class Spawn
|
|
62
62
|
Dir.chdir(@dir) do
|
63
63
|
@pid = spawn(@binary, 'config.lua', {out: log, err: log})
|
64
64
|
end
|
65
|
-
|
65
|
+
100.times do
|
66
|
+
begin
|
67
|
+
TCPSocket.new('127.0.0.1', @admin_port).close
|
68
|
+
return
|
69
|
+
rescue Errno::ECONNREFUSED
|
70
|
+
sleep(0.02)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
raise "NOT CONNECTED"
|
74
|
+
end
|
75
|
+
|
76
|
+
def with_pause
|
77
|
+
Process.kill('STOP', @pid)
|
78
|
+
yield
|
79
|
+
ensure
|
80
|
+
Process.kill('CONT', @pid)
|
66
81
|
end
|
67
82
|
|
68
83
|
def reseed
|
69
84
|
run
|
70
85
|
s = TCPSocket.new '127.0.0.1', @admin_port
|
86
|
+
begin
|
87
|
+
sleep(0.0005)
|
88
|
+
s.read_nonblock(1000)
|
89
|
+
rescue Errno::EWOULDBLOCK
|
90
|
+
retry
|
91
|
+
end
|
71
92
|
s.send("reseed()\n", 0)
|
72
|
-
|
73
|
-
|
93
|
+
begin
|
94
|
+
sleep(0.0005)
|
95
|
+
s.read_nonblock(1000)
|
96
|
+
rescue Errno::EWOULDBLOCK
|
97
|
+
retry
|
98
|
+
end
|
74
99
|
s.close
|
75
100
|
end
|
76
101
|
|
@@ -92,6 +117,10 @@ class Spawn
|
|
92
117
|
inst(what).reseed
|
93
118
|
end
|
94
119
|
|
120
|
+
def self.with_pause(what=:main)
|
121
|
+
inst(what).with_pause{ yield }
|
122
|
+
end
|
123
|
+
|
95
124
|
def self.stop(what=:main)
|
96
125
|
if inst = CONF[what][:inst]
|
97
126
|
inst.stop
|
data/test/test_dumb.rb
CHANGED
@@ -2,9 +2,16 @@ require_relative 'helper'
|
|
2
2
|
|
3
3
|
describe 'DumbConnection' do
|
4
4
|
before { Spawn.reseed }
|
5
|
-
let(:db) { Tarantool16.new host: 'localhost:16788' }
|
6
|
-
let(:r1) { [1, 'hello', [1,2]].deep_freeze }
|
7
|
-
let(:r2) { [2, 'world', [3,4]].deep_freeze }
|
5
|
+
let(:db) { Tarantool16.new host: 'localhost:16788', timeout: 0.1 }
|
6
|
+
let(:r1) { [1, 'hello', [1,2], 100].deep_freeze }
|
7
|
+
let(:r2) { [2, 'world', [3,4], 200].deep_freeze }
|
8
|
+
let(:r3) { [3, 'wicky', [7,10], 300].deep_freeze }
|
9
|
+
|
10
|
+
def rwith(r, fld, val)
|
11
|
+
r=r.dup
|
12
|
+
r[fld]=val
|
13
|
+
r
|
14
|
+
end
|
8
15
|
|
9
16
|
it "should select by pk" do
|
10
17
|
db.select(:test, 1).must_equal [r1]
|
@@ -35,17 +42,41 @@ describe 'DumbConnection' do
|
|
35
42
|
db.select(:test, [[4,4]], index: 2, iterator: "<->").must_equal [r2, r1]
|
36
43
|
end
|
37
44
|
|
45
|
+
it "should iterate with offset and limit" do
|
46
|
+
db.insert(:test, r3)
|
47
|
+
db.select(:test, 1, iterator: :>=, index: 3, limit: 1).must_equal [r1]
|
48
|
+
db.select(:test, 1, iterator: :>=, index: 3, offset: 1).must_equal [r2, r3]
|
49
|
+
db.select(:test, 1, iterator: :>=, index: 3, limit: 1, offset: 1).must_equal [r2]
|
50
|
+
end
|
51
|
+
|
38
52
|
it "should insert" do
|
39
|
-
db.insert(:test,
|
40
|
-
db.select(513,
|
53
|
+
db.insert(:test, r3)
|
54
|
+
db.select(513, 3).must_equal [r3]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should update" do
|
58
|
+
db.update(:test, 1, [[:+, 3, 1]]).must_equal [rwith(r1,3,101)]
|
59
|
+
db.update(:test, "world", {1 => [':', 6, 0, '!']}, index: 1).must_equal [rwith(r2,1,"world!")]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should delete" do
|
63
|
+
db.delete(:test, 1).must_equal [r1]
|
64
|
+
db.delete(:test, "world", index: 1).must_equal [r2]
|
41
65
|
end
|
42
66
|
|
43
67
|
describe "with field names" do
|
44
68
|
before {
|
45
|
-
db.define_fields(:test, [[:id, :int], [:name, :str], [:point, :array]])
|
69
|
+
db.define_fields(:test, [[:id, :int], [:name, :str], [:point, :array], [:count, :int]])
|
46
70
|
}
|
47
|
-
let(:h1){ {id:1, name:'hello', point:[1,2]}.deep_freeze }
|
48
|
-
let(:h2){ {id:2, name:'world', point:[3,4]}.deep_freeze }
|
71
|
+
let(:h1){ {id:1, name:'hello', point:[1,2], count:100}.deep_freeze }
|
72
|
+
let(:h2){ {id:2, name:'world', point:[3,4], count:200}.deep_freeze }
|
73
|
+
let(:h3) { {id:3, name:'wicky', point:[7,10], count:300}.deep_freeze }
|
74
|
+
|
75
|
+
def hwith(h, fld, val)
|
76
|
+
h=h.dup
|
77
|
+
h[fld] = val
|
78
|
+
h
|
79
|
+
end
|
49
80
|
|
50
81
|
it "should select by hash" do
|
51
82
|
db.select(:test, {id: 1}).must_equal [h1]
|
@@ -55,6 +86,38 @@ describe 'DumbConnection' do
|
|
55
86
|
it "should iterate" do
|
56
87
|
db.select(:test, {id: 0}, iterator: :>).must_equal [h1, h2]
|
57
88
|
db.select(:test, {id: 4}, iterator: :<).must_equal [h2, h1]
|
89
|
+
db.select(:test, {name: 'hello'}, iterator: :>).must_equal [h2]
|
90
|
+
db.select(:test, {point: [0,0]}, iterator: "<->").must_equal [h1, h2]
|
91
|
+
db.select(:test, {point: [4,4]}, iterator: "<->").must_equal [h2, h1]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should insert" do
|
95
|
+
db.insert(:test, h3)
|
96
|
+
db.select(513, {id:3}).must_equal [h3]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should update" do
|
100
|
+
db.update(:test, {id: 1}, [[:+, :count, 1]]).must_equal [hwith(h1, :count, 101)]
|
101
|
+
db.update(:test, {name: "world"}, {count: [:+, 1]}).must_equal [hwith(h2, :count, 201)]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "timeouts" do
|
106
|
+
it "should timeout on connect" do
|
107
|
+
Spawn.with_pause do
|
108
|
+
proc {
|
109
|
+
db.get(:test, 1)
|
110
|
+
}.must_raise Tarantool16::Connection::CouldNotConnect
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should timeout on request" do
|
115
|
+
db.get(:test, 1)
|
116
|
+
Spawn.with_pause do
|
117
|
+
proc {
|
118
|
+
db.get(:test, 1)
|
119
|
+
}.must_raise Tarantool16::Connection::Timeout
|
120
|
+
end
|
58
121
|
end
|
59
122
|
end
|
60
123
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tarantool16
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sokolov Yura aka funny_falcon
|
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: bundler
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/tarantool16/schema.rb
|
78
78
|
- lib/tarantool16/version.rb
|
79
79
|
- tarantool16.gemspec
|
80
|
+
- test/bench_timeout.rb
|
80
81
|
- test/config.lua
|
81
82
|
- test/helper.rb
|
82
83
|
- test/test_dumb.rb
|
@@ -100,11 +101,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
101
|
version: '0'
|
101
102
|
requirements: []
|
102
103
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.4.
|
104
|
+
rubygems_version: 2.4.3
|
104
105
|
signing_key:
|
105
106
|
specification_version: 4
|
106
107
|
summary: adapter for Tarantool 1.6
|
107
108
|
test_files:
|
109
|
+
- test/bench_timeout.rb
|
108
110
|
- test/config.lua
|
109
111
|
- test/helper.rb
|
110
112
|
- test/test_dumb.rb
|