tarantool 0.2.5 → 0.3.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/Gemfile +14 -12
  2. data/LICENSE +4 -4
  3. data/README.md +15 -9
  4. data/Rakefile +5 -129
  5. data/lib/tarantool/base_record.rb +288 -0
  6. data/lib/tarantool/block_db.rb +135 -0
  7. data/lib/tarantool/callback_db.rb +47 -0
  8. data/lib/tarantool/core-ext.rb +12 -0
  9. data/lib/tarantool/em_db.rb +37 -0
  10. data/lib/tarantool/exceptions.rb +52 -7
  11. data/lib/tarantool/fiber_db.rb +152 -0
  12. data/lib/tarantool/light_record.rb +68 -0
  13. data/lib/tarantool/query.rb +127 -0
  14. data/lib/tarantool/record/select.rb +59 -0
  15. data/lib/tarantool/record.rb +93 -282
  16. data/lib/tarantool/request.rb +351 -52
  17. data/lib/tarantool/response.rb +108 -45
  18. data/lib/tarantool/serializers/bson.rb +2 -2
  19. data/lib/tarantool/serializers.rb +32 -4
  20. data/lib/tarantool/space_array.rb +153 -0
  21. data/lib/tarantool/space_hash.rb +262 -0
  22. data/lib/tarantool/util.rb +182 -0
  23. data/lib/tarantool/version.rb +3 -0
  24. data/lib/tarantool.rb +79 -29
  25. data/test/box.pid +1 -0
  26. data/test/helper.rb +164 -0
  27. data/test/run_all.rb +3 -0
  28. data/test/shared_query.rb +73 -0
  29. data/test/shared_record.rb +474 -0
  30. data/test/shared_space_array.rb +284 -0
  31. data/test/shared_space_hash.rb +239 -0
  32. data/test/tarant/init.lua +22 -0
  33. data/test/tarantool.cfg +62 -0
  34. data/test/tarantool.log +6 -0
  35. data/{spec/tarantool.cfg → test/tarantool_repl.cfg} +11 -5
  36. data/test/test_light_record.rb +48 -0
  37. data/test/test_query_block.rb +6 -0
  38. data/test/test_query_fiber.rb +7 -0
  39. data/test/test_record.rb +88 -0
  40. data/{spec/tarantool/composite_primary_key_spec.rb → test/test_record_composite_pk.rb} +5 -7
  41. data/test/test_space_array_block.rb +6 -0
  42. data/test/test_space_array_callback.rb +255 -0
  43. data/test/test_space_array_callback_nodef.rb +190 -0
  44. data/test/test_space_array_fiber.rb +7 -0
  45. data/test/test_space_hash_block.rb +6 -0
  46. data/test/test_space_hash_fiber.rb +7 -0
  47. metadata +78 -55
  48. data/Gemfile.lock +0 -54
  49. data/examples/em_simple.rb +0 -16
  50. data/examples/record.rb +0 -68
  51. data/examples/simple.rb +0 -13
  52. data/lib/tarantool/requests/call.rb +0 -20
  53. data/lib/tarantool/requests/delete.rb +0 -18
  54. data/lib/tarantool/requests/insert.rb +0 -19
  55. data/lib/tarantool/requests/ping.rb +0 -16
  56. data/lib/tarantool/requests/select.rb +0 -22
  57. data/lib/tarantool/requests/update.rb +0 -35
  58. data/lib/tarantool/requests.rb +0 -19
  59. data/lib/tarantool/serializers/integer.rb +0 -14
  60. data/lib/tarantool/serializers/string.rb +0 -14
  61. data/lib/tarantool/space.rb +0 -39
  62. data/spec/helpers/let.rb +0 -11
  63. data/spec/helpers/truncate.rb +0 -12
  64. data/spec/spec_helper.rb +0 -21
  65. data/spec/tarantool/em_spec.rb +0 -22
  66. data/spec/tarantool/record_spec.rb +0 -316
  67. data/spec/tarantool/request_spec.rb +0 -103
  68. data/tarantool.gemspec +0 -69
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path('../shared_record', __FILE__)
3
+ require 'tarantool/light_record'
4
+
5
+ describe 'Tarantool::LightRecord' do
6
+ let(:base_class){ Tarantool::LightRecord }
7
+ it_behaves_like :record
8
+
9
+ describe "update" do
10
+ let(:user) { user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
11
+ it "should reload fields event not reffered in operations" do
12
+ user.name = "Petr"
13
+ user.update(email: "prepor@ceo.ru")
14
+ user.name.must_equal "Andrew"
15
+ user.email.must_equal "prepor@ceo.ru"
16
+
17
+ fetched = user_class.by_pk('prepor')
18
+ fetched.name.must_equal "Andrew"
19
+ fetched.email.must_equal "prepor@ceo.ru"
20
+ end
21
+ end
22
+
23
+ describe "callbacks" do
24
+ let(:u) { user_class.new login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru '}
25
+ it "should run after_init method on creation" do
26
+ any_instance_of(user_class) do |u|
27
+ mock(u).after_init.once
28
+ end
29
+ u.save
30
+ end
31
+
32
+ it "should run after_init method on creation and fetching" do
33
+ any_instance_of(user_class) do |u|
34
+ mock(u).after_init.twice
35
+ end
36
+ u.save
37
+ user_class.find u.login
38
+ end
39
+
40
+ it "should not run after_init on reload" do
41
+ any_instance_of(user_class) do |u|
42
+ mock(u).after_init.once
43
+ end
44
+ u.save
45
+ u.reload
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../shared_space_array.rb', __FILE__)
2
+
3
+ describe 'Tarantool::FiberDB::SpaceArray' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :block)) }
5
+ it_behaves_like :blocking_array_space
6
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared_query.rb', __FILE__)
2
+
3
+ describe 'Tarantool::FiberDB::Query' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :em)) }
5
+ alias blockrun fibrun
6
+ it_behaves_like :blocking_query
7
+ end
@@ -0,0 +1,88 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path('../shared_record', __FILE__)
3
+ require 'tarantool/record'
4
+
5
+ describe 'Tarantool::Record' do
6
+ let(:base_class){ Tarantool::Record }
7
+ it_behaves_like :record
8
+
9
+
10
+ describe "update" do
11
+ let(:user) { user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
12
+ it "should not reload fields not reffered in operations" do
13
+ user.name = "Petr"
14
+ user.update(email: "prepor@ceo.ru")
15
+ user.name.must_equal "Petr"
16
+ user.email.must_equal "prepor@ceo.ru"
17
+
18
+ fetched = user_class.by_pk('prepor')
19
+ fetched.name.must_equal "Andrew"
20
+ fetched.email.must_equal "prepor@ceo.ru"
21
+ end
22
+ end
23
+
24
+ describe "validations" do
25
+ describe "with validator on login size" do
26
+ before do
27
+ user_class.validates_length_of(:login, minimum: 3)
28
+ end
29
+ it "should invalidate all records with login less then 3 chars" do
30
+ u = user_class.new login: 'pr', name: 'Andrew', email: 'ceo@prepor.ru'
31
+ u.save.must_equal false
32
+ u.valid?.must_equal false
33
+ u.errors.size.must_equal 1
34
+ u.login = 'prepor'
35
+ u.save.must_equal true
36
+ u.valid?.must_equal true
37
+ u.errors.size.must_equal 0
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "callbacks" do
43
+ let(:u) { user_class.new login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru '}
44
+ it "should run before / after create callbackss in right places" do
45
+ user_class.before_create :action_before_create
46
+ user_class.after_create :action_after_create
47
+ mock(u).action_before_create { u.new_record?.must_equal true }
48
+ mock(u).action_after_create { u.new_record?.must_equal false }
49
+ u.save
50
+ end
51
+
52
+ describe "initialize" do
53
+ it "should run after_initialize after any initialization" do
54
+ user_class.after_initialize :action_after_initialize
55
+ any_instance_of(user_class) do |u|
56
+ mock(u).action_after_initialize.twice
57
+ end
58
+ u.save
59
+ user_class.find u.login
60
+ end
61
+
62
+ it "should not run after_initialize after reload" do
63
+ user_class.after_initialize :action_after_initialize
64
+ any_instance_of(user_class) do |u|
65
+ mock(u).action_after_initialize.once
66
+ end
67
+ u.save
68
+ u.reload
69
+ end
70
+
71
+ it "should properly save record inside after_initialize" do
72
+ user_class.after_initialize do |u|
73
+ u.save
74
+ end
75
+ u
76
+ user_class.find u.login
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "serialization" do
82
+ it "should support AM serialization API" do
83
+ h = { login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
84
+ u = user_class.create h
85
+ u.as_json.must_equal({ 'user' => h.merge(apples_count: 0) })
86
+ end
87
+ end
88
+ end
@@ -1,16 +1,14 @@
1
1
  # -*- coding: utf-8 -*-
2
- require 'spec_helper'
2
+ require File.expand_path('../helper.rb', __FILE__)
3
3
  require 'tarantool/record'
4
4
  require 'yajl'
5
5
  require 'tarantool/serializers/bson'
6
+
6
7
  describe Tarantool::Record do
7
- include Helpers::Truncate
8
+ DB = Tarantool.new(TCONFIG.merge(type: :block))
9
+ before{ truncate }
8
10
 
9
11
  describe "primary key" do
10
- def space
11
- @space ||= DB.space 2
12
- end
13
-
14
12
  before do
15
13
  @primary_key_size = 2
16
14
  end
@@ -76,4 +74,4 @@ describe Tarantool::Record do
76
74
 
77
75
  end
78
76
  end
79
- end
77
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../shared_space_array.rb', __FILE__)
2
+
3
+ describe 'Tarantool::BlockDB::SpaceArray' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :block)) }
5
+ it_behaves_like :blocking_array_space
6
+ end
@@ -0,0 +1,255 @@
1
+ require File.expand_path('../helper.rb', __FILE__)
2
+
3
+ describe 'Tarantool::CallbackDB::SpaceArray' do
4
+ before { clear_db }
5
+
6
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :em_callback)) }
7
+ let(:space0) { tarantool.space_array(0, SPACE0[:types], keys: SPACE0[:keys])}
8
+ let(:space1) { tarantool.space_array(1, SPACE1[:types], keys: SPACE1[:keys])}
9
+ let(:space2) { tarantool.space_array(2, SPACE2[:types], keys: SPACE2[:keys])}
10
+
11
+ describe "with definition" do
12
+ let(:vasya){ ['vasya', 'petrov', 'eb@lo.com', 5] }
13
+ let(:ilya) { ['ilya', 'zimov', 'il@zi.bot', 13] }
14
+ let(:fedor){ ['fedor', 'kuklin', 'ku@kl.in', 13] }
15
+ it "should be selectable" do
16
+ results = []
17
+ emrun(8) {
18
+ space0.select(0, 'vasya'){|res| results[0] = res; emstop}
19
+ space0.select(0, ['vasya']){|res| results[1] = res; emstop}
20
+ space0.select(0, ['vasya', 'ilya']){|res|
21
+ results[2] = res; emstop
22
+ }
23
+ space0.select(0, [['vasya'], ['ilya']]){|res|
24
+ results[3] = res; emstop
25
+ }
26
+ space0.select(0, [['ilya'], ['vasya']]){|res|
27
+ results[4] = res; emstop
28
+ }
29
+ space0.select(0, [['ilya'], ['vasya']], 0, 1){|res|
30
+ results[5] = res; emstop
31
+ }
32
+ space0.select(0, [['ilya'], ['vasya']], 1, 1){|res|
33
+ results[6] = res; emstop
34
+ }
35
+ space0.select(2, 13, 0, 2){|res|
36
+ results[7] = res; emstop
37
+ }
38
+ space0.select(1, [['zimov','il@zi.bot']]){|res|
39
+ results[8] = res; emstop
40
+ }
41
+ }
42
+ results[0].must_equal [vasya]
43
+ results[1].must_equal [vasya]
44
+ results[2].must_equal [vasya, ilya]
45
+ results[3].must_equal [vasya, ilya]
46
+ results[4].must_equal [ilya, vasya]
47
+ results[5].must_equal [ilya]
48
+ results[6].must_equal [vasya]
49
+ (results[7] - [ilya, fedor]).must_be_empty
50
+ results[8].must_equal [ilya]
51
+ end
52
+
53
+ it "should be able to all_by_keys" do
54
+ results = []
55
+ emrun(8) {
56
+ space0.all_by_keys(0, 'vasya'){|res| results[0] = res; emstop}
57
+ space0.all_by_keys(0, ['vasya']){|res| results[1] = res; emstop}
58
+ space0.all_by_keys(0, ['vasya', 'ilya']){|res|
59
+ results[2] = res; emstop
60
+ }
61
+ space0.all_by_keys(0, [['vasya'], ['ilya']]){|res|
62
+ results[3] = res; emstop
63
+ }
64
+ space0.all_by_keys(0, [['ilya'], ['vasya']]){|res|
65
+ results[4] = res; emstop
66
+ }
67
+ space0.all_by_keys(0, [['ilya'], ['vasya']], limit: 1){|res|
68
+ results[5] = res; emstop
69
+ }
70
+ space0.all_by_keys(0, [['ilya'], ['vasya']], limit: 1, offset: 1){|res|
71
+ results[6] = res; emstop
72
+ }
73
+ space0.all_by_keys(2, 13){|res| results[7] = res; emstop }
74
+ space0.all_by_keys(1, [['zimov','il@zi.bot']]){|res|
75
+ results[8] = res; emstop
76
+ }
77
+ }
78
+ results[0].must_equal [vasya]
79
+ results[1].must_equal [vasya]
80
+ results[2].must_equal [vasya, ilya]
81
+ results[3].must_equal [vasya, ilya]
82
+ results[4].must_equal [ilya, vasya]
83
+ results[5].must_equal [ilya]
84
+ results[6].must_equal [vasya]
85
+ (results[7] - [ilya, fedor]).must_be_empty
86
+ results[8].must_equal [ilya]
87
+ end
88
+
89
+ it "should be able to all_by_key" do
90
+ results = []
91
+ emrun(4) {
92
+ space0.all_by_key(0, 'vasya'){|res| results[0] = res; emstop}
93
+ space0.all_by_key(0, ['vasya']){|res| results[1] = res; emstop}
94
+ space0.all_by_key(2, 13){|res| results[2] = res; emstop }
95
+ space0.all_by_key(1, ['zimov','il@zi.bot']){|res|
96
+ results[3] = res; emstop
97
+ }
98
+ }
99
+ results[0].must_equal [vasya]
100
+ results[1].must_equal [vasya]
101
+ (results[2] - [ilya, fedor]).must_be_empty
102
+ results[3].must_equal [ilya]
103
+ end
104
+
105
+ it "should be able to first_by_key" do
106
+ results = []
107
+ emrun(4) {
108
+ space0.first_by_key(0, 'vasya'){|res| results[0] = res; emstop}
109
+ space0.first_by_key(0, ['ilya']){|res| results[1] = res; emstop}
110
+ space0.first_by_key(2, 13){|res| results[2] = res; emstop }
111
+ space0.first_by_key(1, ['petrov','eb@lo.com']){|res|
112
+ results[3] = res; emstop
113
+ }
114
+ }
115
+ results[0].must_equal vasya
116
+ results[1].must_equal ilya
117
+ [ilya, fedor].must_include results[2]
118
+ results[3].must_equal vasya
119
+ end
120
+
121
+ it "should be able to by_pk" do
122
+ results = []
123
+ emrun(3) {
124
+ space0.by_pk('vasya'){|res| results[0] = res; emstop}
125
+ space0.by_pk(['ilya']){|res| results[1] = res; emstop}
126
+ space2.by_pk(['hi zo', 'ho zo']){|res|
127
+ results[2] = res; emstop
128
+ }
129
+ }
130
+ results[0].must_equal vasya
131
+ results[1].must_equal ilya
132
+ results[2].must_equal ['hi zo', 'ho zo', 1]
133
+ end
134
+
135
+ it "should raise on not matched pk" do
136
+ proc {
137
+ emrun(1) {
138
+ space0.by_pk(['il','ya']){|res| assert false; emstop }
139
+ }
140
+ }.must_raise Tarantool::ArgumentError
141
+ end
142
+
143
+ it "should fetch longer records" do
144
+ results = []
145
+ emrun(2) {
146
+ space2.by_pk(['hi zo', 'pidas']){|res| results[0] = res; emstop}
147
+ space1.by_pk(2){|res| results[1] = res; emstop}
148
+ }
149
+ results[0].must_equal ['hi zo', 'pidas', 1, 3, 5]
150
+ results[1].must_equal [2, 'medium', 6, 'common', 7]
151
+ end
152
+
153
+ it "should be able to insert" do
154
+ results = []
155
+ asdf = ['asdf', 'asdf', 'asdf', 4, 5]
156
+ qwer = ['qwer', 'qwer', 'qwer', 4, 20, 19]
157
+ zxcv = [4, 'zxcv', 7, 'zxcv', 8]
158
+ xcvb = [5, 'xcvb', 7, 'xcvb', 8]
159
+ emrun(4) {
160
+ space0.insert(asdf){|res| results[0] = res; emstop}
161
+ space0.insert(qwer, return_tuple: true){|res| results[1] = res; emstop }
162
+ space1.insert(zxcv){|res|
163
+ results[2] = res
164
+ space1.by_pk(4){|res|
165
+ results[3] = res
166
+ emstop
167
+ }
168
+ }
169
+ space1.insert(xcvb, return_tuple: true){|res| results[4] = res; emstop }
170
+ }
171
+ results[0].must_equal 1
172
+ results[1].must_equal qwer
173
+ results[2].must_equal 1
174
+ results[3].must_equal zxcv
175
+ results[4].must_equal xcvb
176
+ end
177
+
178
+ it "should be able to update" do
179
+ results = []
180
+ emrun(6) {
181
+ space0.update('vasya', {1 => 'holodov', 3 => [:+, 2]}, return_tuple: true){|res|
182
+ results[0] = res; emstop
183
+ }
184
+ space0.update('ilya', {[2, :set] => 'we@al.hero', 3 => [:&, 7]}, return_tuple: true){|res|
185
+ results[1] = res; emstop
186
+ }
187
+ space1.update(2, [[2, :^, 3], [4, :|, 20]]){|res|
188
+ results[2] = res
189
+ space1.by_pk(2){|res|
190
+ results[3] = res; emstop
191
+ }
192
+ }
193
+ space1.update(1, [1, :splice, 2, 2, 'nd'], return_tuple: true){|res|
194
+ results[4] = res
195
+ emstop
196
+ }
197
+ space2.update(['hi zo', 'pidas'], [[2, :delete], [3, :delete]], return_tuple: true){|res|
198
+ results[5] = res
199
+ emstop
200
+ }
201
+ space2.update(['coma', 'peredoma'], [2, :insert, 1]){|res|
202
+ results[6] = res
203
+ space2.all_by_key(1, 1){|res|
204
+ results[7] = res
205
+ emstop
206
+ }
207
+ }
208
+ }
209
+ results[0].must_equal ['vasya', 'holodov', 'eb@lo.com', 7]
210
+ results[1].must_equal ['ilya', 'zimov', 'we@al.hero', 5]
211
+ results[2].must_equal 1
212
+ results[3].must_equal [2, 'medium', 5, 'common', 23]
213
+ results[4].must_equal [1, 'condon', 4]
214
+ end
215
+
216
+ it "should be able to delete" do
217
+ results = []
218
+ emrun(3) {
219
+ space0.delete('vasya', return_tuple: true){|res|
220
+ results[0] = res; emstop
221
+ }
222
+ space1.delete([1], return_tuple: true){|res|
223
+ results[1] = res; emstop
224
+ }
225
+ space2.delete(['hi zo', 'pidas'], return_tuple: true){|res|
226
+ results[2] = res; emstop
227
+ }
228
+ }
229
+ results[0].must_equal vasya
230
+ results[1].must_equal [1, 'common', 4]
231
+ results[2].must_equal ['hi zo', 'pidas', 1, 3, 5]
232
+ end
233
+
234
+ it "should be able to choose index by field numbers" do
235
+ results = []
236
+ emrun(4) {
237
+ space0.first_by_key([0], 'vasya'){|res| results[0] = res; emstop}
238
+ space0.first_by_key([1,2], ['zimov', 'il@zi.bot']){|res|
239
+ results[1] = res; emstop
240
+ }
241
+ space0.all_by_key([3], 13){|res|
242
+ results[2] = res; emstop
243
+ }
244
+ space2.first_by_key([1,0], ['peredoma', 'coma']){|res|
245
+ results[3] = res; emstop
246
+ }
247
+ }
248
+ results[0].must_equal vasya
249
+ results[1].must_equal ilya
250
+ (results[2] - [ilya, fedor]).must_be_empty
251
+ ([ilya, fedor] - results[2]).must_be_empty
252
+ results[3].must_equal ['coma', 'peredoma', 2]
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,190 @@
1
+ require File.expand_path('../helper.rb', __FILE__)
2
+
3
+ describe 'Tarantool::CallbackDB::SpaceArray' do
4
+ before { clear_db }
5
+
6
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :em_callback)) }
7
+ let(:clear_space) { tarantool.space_array(0) }
8
+
9
+ describe "without description" do
10
+ let(:vasya){ %W{vasya petrov eb@lo.com \x05\x00\x00\x00} }
11
+ let(:ilya) { %W{ilya zimov il@zi.bot \x0D\x00\x00\x00} }
12
+ let(:fedor){ %W{fedor kuklin ku@kl.in \x0D\x00\x00\x00} }
13
+ let(:_ilya) { %W{ilya zimov il@zi.bot}+[13] }
14
+ let(:_fedor){ %W{fedor kuklin ku@kl.in}+[13] }
15
+ it "should be selectable" do
16
+ results = []
17
+ emrun(8) {
18
+ clear_space.select(0, 'vasya'){|res| results[0] = res; emstop}
19
+ clear_space.select(0, ['vasya']){|res| results[1] = res; emstop}
20
+ clear_space.select(0, ['vasya', 'ilya']){|res|
21
+ results[2] = res; emstop
22
+ }
23
+ clear_space.select(0, [['vasya'], ['ilya']]){|res|
24
+ results[3] = res; emstop
25
+ }
26
+ clear_space.select(0, [['ilya'], ['vasya']]){|res|
27
+ results[4] = res; emstop
28
+ }
29
+ clear_space.select(0, [['ilya'], ['vasya']], 0, 1){|res|
30
+ results[5] = res; emstop
31
+ }
32
+ clear_space.select(0, [['ilya'], ['vasya']], 1, 1){|res|
33
+ results[6] = res; emstop
34
+ }
35
+ clear_space.select(2, "\x0D\x00\x00\x00", 0, 2){|res|
36
+ results[7] = res; emstop
37
+ }
38
+ clear_space.select(2, 13, 0, 2){|res|
39
+ results[8] = res; emstop
40
+ }
41
+ clear_space.select(1, [['zimov','il@zi.bot']]){|res|
42
+ results[9] = res; emstop
43
+ }
44
+ }
45
+ results[0].must_equal [vasya]
46
+ results[1].must_equal [vasya]
47
+ results[2].must_equal [vasya, ilya]
48
+ results[3].must_equal [vasya, ilya]
49
+ results[4].must_equal [ilya, vasya]
50
+ results[5].must_equal [ilya]
51
+ results[6].must_equal [vasya]
52
+ (results[7] - [fedor, ilya]).empty?
53
+ (results[7] - [_fedor, _ilya]).empty?
54
+ results[7].sort.must_equal [fedor, ilya]
55
+ results[7].sort.must_equal [_fedor, _ilya]
56
+ results[8].sort.must_equal [fedor, ilya]
57
+ results[9].must_equal [ilya]
58
+ end
59
+
60
+ it "should be able to all_by_keys" do
61
+ results = []
62
+ emrun(8) {
63
+ clear_space.all_by_keys(0, 'vasya'){|res| results[0] = res; emstop}
64
+ clear_space.all_by_keys(0, ['vasya']){|res| results[1] = res; emstop}
65
+ clear_space.all_by_keys(0, ['vasya', 'ilya']){|res|
66
+ results[2] = res; emstop
67
+ }
68
+ clear_space.all_by_keys(0, [['vasya'], ['ilya']]){|res|
69
+ results[3] = res; emstop
70
+ }
71
+ clear_space.all_by_keys(0, [['ilya'], ['vasya']]){|res|
72
+ results[4] = res; emstop
73
+ }
74
+ clear_space.all_by_keys(0, [['ilya'], ['vasya']], limit: 1){|res|
75
+ results[5] = res; emstop
76
+ }
77
+ clear_space.all_by_keys(0, [['ilya'], ['vasya']], limit: 1, offset: 1){|res|
78
+ results[6] = res; emstop
79
+ }
80
+ clear_space.all_by_keys(2, "\x0D\x00\x00\x00"){|res|
81
+ results[7] = res; emstop
82
+ }
83
+ clear_space.all_by_keys(2, 13){|res|
84
+ results[8] = res; emstop
85
+ }
86
+ clear_space.all_by_keys(1, [['zimov','il@zi.bot']]){|res|
87
+ results[9] = res; emstop
88
+ }
89
+ }
90
+ results[0].must_equal [vasya]
91
+ results[1].must_equal [vasya]
92
+ results[2].must_equal [vasya, ilya]
93
+ results[3].must_equal [vasya, ilya]
94
+ results[4].must_equal [ilya, vasya]
95
+ results[5].must_equal [ilya]
96
+ results[6].must_equal [vasya]
97
+ results[7].sort.must_equal [fedor, ilya]
98
+ results[8].sort.must_equal [fedor, ilya]
99
+ results[9].must_equal [ilya]
100
+ end
101
+
102
+ it "should be able to all_by_key" do
103
+ results = []
104
+ emrun(4) {
105
+ clear_space.all_by_key(0, 'vasya'){|res| results[0] = res; emstop}
106
+ clear_space.all_by_key(0, ['vasya']){|res| results[1] = res; emstop}
107
+ clear_space.all_by_key(2, "\x0D\x00\x00\x00"){|res|
108
+ results[2] = res; emstop
109
+ }
110
+ clear_space.all_by_key(1, ['zimov','il@zi.bot']){|res|
111
+ results[3] = res; emstop
112
+ }
113
+ }
114
+ results[0].must_equal [vasya]
115
+ results[1].must_equal [vasya]
116
+ results[2].sort.must_equal [fedor, ilya]
117
+ results[3].must_equal [ilya]
118
+ end
119
+
120
+ it "should be able to first_by_key" do
121
+ results = []
122
+ emrun(4) {
123
+ clear_space.first_by_key(0, 'vasya'){|res| results[0] = res; emstop}
124
+ clear_space.first_by_key(0, ['ilya']){|res| results[1] = res; emstop}
125
+ clear_space.first_by_key(2, "\x0D\x00\x00\x00"){|res|
126
+ results[2] = res; emstop
127
+ }
128
+ clear_space.first_by_key(1, ['petrov','eb@lo.com']){|res|
129
+ results[3] = res; emstop
130
+ }
131
+ }
132
+ results[0].must_equal vasya
133
+ results[1].must_equal ilya
134
+ [ilya, fedor].must_include results[2]
135
+ results[3].must_equal vasya
136
+ end
137
+
138
+ it "should be able to by_pk" do
139
+ results = []
140
+ emrun(3) {
141
+ clear_space.by_pk('vasya'){|res| results[0] = res; emstop}
142
+ clear_space.by_pk(['ilya']){|res| results[1] = res; emstop}
143
+ tarantool.space_array(2).by_pk(['hi zo', 'ho zo']){|res|
144
+ results[2] = res; emstop
145
+ }
146
+ }
147
+ results[0].must_equal vasya
148
+ results[1].must_equal ilya
149
+ results[2].must_equal ['hi zo', 'ho zo', "\x01\x00\x00\x00"]
150
+ end
151
+
152
+ it "should be able to insert" do
153
+ results = []
154
+ emrun(2) {
155
+ clear_space.insert(%w{asdf asdf asdf asdf asdf}){|res| results[0] = res; emstop}
156
+ clear_space.insert(%w{qwer qwer qwer qwer qwer}, return_tuple: true){|res|
157
+ results[1] = res; emstop
158
+ }
159
+ clear_space.insert([1,2,3,4,5], return_tuple: true){|res|
160
+ results[2] = res; emstop
161
+ }
162
+ }
163
+ results[0].must_equal 1
164
+ results[1].must_equal %w{qwer qwer qwer qwer qwer}
165
+ results[2].must_equal [1,2,3,4,5].pack("V*").scan(/.{4}/)
166
+ end
167
+
168
+ it "should be able to update" do
169
+ results = []
170
+ emrun(3) {
171
+ clear_space.update('vasya', {
172
+ 1 => 'korkov',
173
+ 2 => ['set', 'no@mo.re'],
174
+ 3 => ['add', 1]}, return_tuple: true){|res|
175
+ results[0] = res; emstop
176
+ }
177
+ clear_space.update('ilya', {'&3' => 12}, return_tuple: true){|res|
178
+ results[1] = res; emstop
179
+ }
180
+ clear_space.update('fedor', {'|3' => 3}, return_tuple: true){|res|
181
+ results[2] = res; emstop
182
+ }
183
+ }
184
+ results[0].must_equal %W{vasya korkov no@mo.re \x06\x00\x00\x00}
185
+ results[1].must_equal %W{ilya zimov il@zi.bot \x0C\x00\x00\x00}
186
+ results[2].must_equal %W{fedor kuklin ku@kl.in \x0F\x00\x00\x00}
187
+ end
188
+ end
189
+
190
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared_space_array.rb', __FILE__)
2
+
3
+ describe 'Tarantool::FiberDB::SpaceArray' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :em)) }
5
+ alias blockrun fibrun
6
+ it_behaves_like :blocking_array_space
7
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../shared_space_hash.rb', __FILE__)
2
+
3
+ describe 'Tarantool::BlockDB::SpaceHash' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :block)) }
5
+ it_behaves_like :blocking_hash_space
6
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared_space_hash.rb', __FILE__)
2
+
3
+ describe 'Tarantool::FiberDB::SpaceHash' do
4
+ let(:tarantool) { Tarantool.new(TCONFIG.merge(type: :em)) }
5
+ alias blockrun fibrun
6
+ it_behaves_like :blocking_hash_space
7
+ end