tarantool 0.2.5 → 0.3.0.7

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.
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,284 @@
1
+ require File.expand_path('../helper.rb', __FILE__)
2
+
3
+ shared_examples_for :blocking_array_space do
4
+ before { clear_db }
5
+
6
+ let(:space0) { tarantool.space_array(0, SPACE0[:types], keys: SPACE0[:keys])}
7
+ let(:space1) { tarantool.space_array(1, SPACE1[:types], keys: SPACE1[:keys])}
8
+ let(:space2) { tarantool.space_array(2, SPACE2[:types], keys: SPACE2[:keys])}
9
+ let(:space3) { tarantool.space_array(3, SPACE3[:types], keys: SPACE3[: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 = blockrun { [
17
+ space0.select(0, 'vasya'),
18
+ space0.select(0, ['vasya']),
19
+ space0.select(0, ['vasya', 'ilya']),
20
+ space0.select(0, [['vasya'], ['ilya']]),
21
+ space0.select(0, [['ilya'], ['vasya']]),
22
+ space0.select(0, [['ilya'], ['vasya']], 0, 1),
23
+ space0.select(0, [['ilya'], ['vasya']], 1, 1),
24
+ space0.select(2, 13, 0, 2),
25
+ space0.select(1, [['zimov','il@zi.bot']])
26
+ ] }
27
+ results[0].must_equal [vasya]
28
+ results[1].must_equal [vasya]
29
+ results[2].must_equal [vasya, ilya]
30
+ results[3].must_equal [vasya, ilya]
31
+ results[4].must_equal [ilya, vasya]
32
+ results[5].must_equal [ilya]
33
+ results[6].must_equal [vasya]
34
+ (results[7] - [ilya, fedor]).must_be_empty
35
+ ([ilya, fedor] - results[7]).must_be_empty
36
+ results[8].must_equal [ilya]
37
+ end
38
+
39
+ it "should be able to all_by_keys" do
40
+ results = blockrun { [
41
+ space0.all_by_keys(0, 'vasya'),
42
+ space0.all_by_keys(0, ['vasya']),
43
+ space0.all_by_keys(0, ['vasya', 'ilya']),
44
+ space0.all_by_keys(0, [['vasya'], ['ilya']]),
45
+ space0.all_by_keys(0, [['ilya'], ['vasya']]),
46
+ space0.all_by_keys(0, [['ilya'], ['vasya']], limit: 1),
47
+ space0.all_by_keys(0, [['ilya'], ['vasya']], limit: 1, offset: 1),
48
+ space0.all_by_keys(2, 13),
49
+ space0.all_by_keys(1, [['zimov','il@zi.bot']]),
50
+ ] }
51
+ results[0].must_equal [vasya]
52
+ results[1].must_equal [vasya]
53
+ results[2].must_equal [vasya, ilya]
54
+ results[3].must_equal [vasya, ilya]
55
+ results[4].must_equal [ilya, vasya]
56
+ results[5].must_equal [ilya]
57
+ results[6].must_equal [vasya]
58
+ (results[7] - [ilya, fedor]).must_be_empty
59
+ results[8].must_equal [ilya]
60
+ end
61
+
62
+ it "should be able to all_by_key" do
63
+ results = blockrun { [
64
+ space0.all_by_key(0, 'vasya'),
65
+ space0.all_by_key(0, ['vasya']),
66
+ space0.all_by_key(2, 13),
67
+ space0.all_by_key(1, ['zimov','il@zi.bot']),
68
+ ] }
69
+ results[0].must_equal [vasya]
70
+ results[1].must_equal [vasya]
71
+ (results[2] - [ilya, fedor]).must_be_empty
72
+ results[3].must_equal [ilya]
73
+ end
74
+
75
+ it "should be able to first_by_key" do
76
+ results = blockrun { [
77
+ space0.first_by_key(0, 'vasya'),
78
+ space0.first_by_key(0, ['ilya']),
79
+ space0.first_by_key(2, 13),
80
+ space0.first_by_key(1, ['petrov','eb@lo.com']),
81
+ ] }
82
+ results[0].must_equal vasya
83
+ results[1].must_equal ilya
84
+ [ilya, fedor].must_include results[2]
85
+ results[3].must_equal vasya
86
+ end
87
+
88
+ it "should be able to by_pk" do
89
+ results = blockrun { [
90
+ space0.by_pk('vasya'),
91
+ space0.by_pk(['ilya']),
92
+ space2.by_pk(['hi zo', 'ho zo']),
93
+ ] }
94
+ results[0].must_equal vasya
95
+ results[1].must_equal ilya
96
+ results[2].must_equal ['hi zo', 'ho zo', 1]
97
+ end
98
+
99
+ it "should raise on not matched pk" do
100
+ proc {
101
+ space0.by_pk(['il','ya'])
102
+ }.must_raise Tarantool::ArgumentError
103
+ end
104
+
105
+ it "should fetch longer records" do
106
+ results = blockrun { [
107
+ space2.by_pk(['hi zo', 'pidas']),
108
+ space1.by_pk(2),
109
+ ]}
110
+ results[0].must_equal ['hi zo', 'pidas', 1, 3, 5]
111
+ results[1].must_equal [2, 'medium', 6, 'common', 7]
112
+ end
113
+
114
+ it "should be able to insert" do
115
+ asdf = ['asdf', 'asdf', 'asdf', 4, 5]
116
+ qwer = ['qwer', 'qwer', 'qwer', 4, 20, 19]
117
+ zxcv = [4, 'zxcv', 7, 'zxcv', 8]
118
+ xcvb = [5, 'xcvb', 7, 'xcvb', 8]
119
+ results = blockrun {[
120
+ space0.insert(asdf),
121
+ space0.insert(qwer, return_tuple: true),
122
+ space1.insert(zxcv),
123
+ space1.by_pk(4),
124
+ space1.insert(xcvb, return_tuple: true),
125
+ ]}
126
+ results[0].must_equal 1
127
+ results[1].must_equal qwer
128
+ results[2].must_equal 1
129
+ results[3].must_equal zxcv
130
+ results[4].must_equal xcvb
131
+ end
132
+
133
+ it "should be able to update" do
134
+ results = blockrun {[
135
+ space0.update('vasya', {1 => 'holodov', 3 => [:+, 2]}, return_tuple: true),
136
+ space0.update('ilya', {[2, :set] => 'we@al.hero', 3 => [:&, 7]}, return_tuple: true),
137
+ space1.update(2, [[2, :^, 3], [4, :|, 20]]),
138
+ space1.by_pk(2),
139
+ space1.update(1, [1, :splice, 2, 2, 'nd'], return_tuple: true),
140
+ space2.update(['hi zo', 'pidas'], [[2, :delete], [3, :delete]], return_tuple: true),
141
+ space2.update(['coma', 'peredoma'], [2, :insert, 1]),
142
+ space2.all_by_key(1, 1),
143
+ ]}
144
+ results[0].must_equal ['vasya', 'holodov', 'eb@lo.com', 7]
145
+ results[1].must_equal ['ilya', 'zimov', 'we@al.hero', 5]
146
+ results[2].must_equal 1
147
+ results[3].must_equal [2, 'medium', 5, 'common', 23]
148
+ results[4].must_equal [1, 'condon', 4]
149
+ results[5].must_equal ['hi zo', 'pidas', 5]
150
+ results[6].must_equal 1
151
+ res = [['hi zo', 'ho zo', 1], ['coma', 'peredoma', 1, 2]]
152
+ results[7].sort.must_equal res.sort
153
+ end
154
+
155
+ it "should be able to update (2)" do
156
+ results = blockrun {[
157
+ space2.update(['hi zo', 'pidas'], [[3, [:+, 1]], [4, [:+, -1]]], return_tuple: true)
158
+ ]}
159
+ results[0].must_equal ['hi zo', 'pidas', 1, 4, 4]
160
+ end
161
+
162
+ it "should be able to delete" do
163
+ results = blockrun {[
164
+ space0.delete('vasya', return_tuple: true),
165
+ space1.delete([1], return_tuple: true),
166
+ space2.delete(['hi zo', 'pidas'], return_tuple: true),
167
+ ]}
168
+ results[0].must_equal vasya
169
+ results[1].must_equal [1, 'common', 4]
170
+ results[2].must_equal ['hi zo', 'pidas', 1, 3, 5]
171
+ end
172
+
173
+ it "should be able to choose index by field numbers" do
174
+ results = blockrun {[
175
+ space0.first_by_key([0], 'vasya'),
176
+ space0.first_by_key([1,2], ['zimov', 'il@zi.bot']),
177
+ space0.all_by_key([3], 13),
178
+ space2.first_by_key([1,0], ['peredoma', 'coma']),
179
+ ]}
180
+ results[0].must_equal vasya
181
+ results[1].must_equal ilya
182
+ (results[2] - [ilya, fedor]).must_be_empty
183
+ ([ilya, fedor] - results[2]).must_be_empty
184
+ results[3].must_equal ['coma', 'peredoma', 2]
185
+ end
186
+
187
+ it "should be able to invoke" do
188
+ results = blockrun {[
189
+ space0.invoke('truncate'),
190
+ space0.by_pk('vasya'),
191
+ space0.by_pk('ilya')
192
+ ]}
193
+ results.must_equal [0, nil, nil]
194
+ end
195
+
196
+ it "should be able to call" do
197
+ results = blockrun {[
198
+ space0.call('truncate'),
199
+ space0.by_pk('vasya'),
200
+ space0.by_pk('ilya')
201
+ ]}
202
+ results.must_equal [[], nil, nil]
203
+ end
204
+
205
+ it "should be able to call (1)" do
206
+ results = blockrun {[
207
+ space0.call('func1'),
208
+ space0.call('func1', [1, 2]),
209
+ space0.call('func1', ['1', '2']),
210
+ space0.call('func1', [1, 2], types: [:int, :int]),
211
+ space0.call('func2', [1, 2], types: [:int, :int], returns: [:str, :int])
212
+ ]}
213
+ results.must_equal [
214
+ [['string', '0'], ['nil'], ['nil']],
215
+ [['string', '0'], ['string', '1'], ['string', '2']],
216
+ [['string', '0'], ['string', '1'], ['string', '2']],
217
+ [['string', '0'], ['string', "\x01\x00\x00\x00"], ['string', "\x02\x00\x00\x00"]],
218
+ [['string', 1], ['string', 2]],
219
+ ]
220
+ end
221
+
222
+ it "should be able to call (2)" do
223
+ results = blockrun {[
224
+ space0.call('box.select_range', [0, 2]),
225
+ space0.call('box.select_range', [0, 1000000, 'ilya'])
226
+ ]}
227
+ results[0].must_equal [fedor, ilya]
228
+ results[1].must_equal [ilya, vasya]
229
+ end
230
+
231
+ describe "Array Serializer" do
232
+ it "should be able to save" do
233
+ results = blockrun {[
234
+ space3.insert([1, [1,2,3,4]], return_tuple: true),
235
+ space3.insert([2, []], return_tuple: true),
236
+ space3.insert([3, nil], return_tuple: true),
237
+ space3.all_by_pks([1,2,3])
238
+ ]}
239
+ results[0].must_equal [1, [1,2,3,4]]
240
+ results[1].must_equal [2, nil]
241
+ results[2].must_equal [3, nil]
242
+ results[3].sort.must_equal [[1, [1,2,3,4]], [2, nil], [3, nil]]
243
+ end
244
+
245
+ it "should be able to update" do
246
+ results = blockrun {[
247
+ space3.insert([1, [1,2,3,4]], return_tuple: true),
248
+ space3.update(1, [1, :set, [4,3,2,1]], return_tuple: true)
249
+ ]}
250
+ results.must_equal [[1, [1,2,3,4]], [1,[4,3,2,1]]]
251
+ end
252
+
253
+ it "should be able to save tail with same type" do
254
+ results = blockrun {[
255
+ space3.insert([1, [1,2,3,4], [4,3,2,1], [2,1]], return_tuple: true),
256
+ space3.by_pk(1)
257
+ ]}
258
+ results[0].must_equal [1, [1,2,3,4], [4,3,2,1], [2,1]]
259
+ results[1].must_equal [1, [1,2,3,4], [4,3,2,1], [2,1]]
260
+ end
261
+
262
+ it "should be able to update tail with same type" do
263
+ results = blockrun {[
264
+ space3.insert([1, [1,2,3,4], [4,3,2,1], [2,1]], return_tuple: true),
265
+ space3.update(1, [3, :set, [3,2,1]], return_tuple: true)
266
+ ]}
267
+ results[0].must_equal [1, [1,2,3,4], [4,3,2,1], [2,1]]
268
+ results[1].must_equal [1, [1,2,3,4], [4,3,2,1], [3,2,1]]
269
+ end
270
+
271
+ it "should be able to search by serialized value" do
272
+ results = blockrun {[
273
+ space3.insert([5, [1,2,3]]),
274
+ space3.insert([6, [3,2,1]]),
275
+ space3.first_by_key(1, [[1,2,3]]),
276
+ space3.first_by_key(1, [[3,2,1]]),
277
+ ]}
278
+ results[0..1].must_equal [1,1]
279
+ results[2].must_equal [5, [1,2,3]]
280
+ results[3].must_equal [6, [3,2,1]]
281
+ end
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,239 @@
1
+ require File.expand_path('../helper.rb', __FILE__)
2
+
3
+ shared_examples_for :blocking_hash_space do
4
+ before { clear_db }
5
+
6
+ let(:space0) { tarantool.space_hash(0, HSPACE0[:fields], keys: HSPACE0[:keys])}
7
+ let(:space1) { tarantool.space_hash(1, HSPACE1[:fields], keys: HSPACE1[:keys])}
8
+ let(:space2) { tarantool.space_hash(2, HSPACE2[:fields], keys: HSPACE2[:keys])}
9
+ let(:space3) { tarantool.space_hash(3, HSPACE3[:fields], keys: HSPACE3[:keys])}
10
+
11
+ let(:vasya) { {name: 'vasya', surname: 'petrov', email: 'eb@lo.com', score: 5} }
12
+ let(:ilya) { {name: 'ilya', surname: 'zimov', email: 'il@zi.bot', score: 13} }
13
+ let(:fedor) { {name: 'fedor', surname: 'kuklin', email: 'ku@kl.in', score: 13} }
14
+ let(:hozo) { {first: 'hi zo', second: 'ho zo', third: 1} }
15
+ let(:pidas) { {first: 'hi zo', second: 'pidas', third: 1, _tail: [3, 5]} }
16
+ let(:peredoma) { {first: 'coma', second: 'peredoma', third: 2} }
17
+
18
+ it "should be selectable" do
19
+ results = blockrun { [
20
+ space0.select({name: 'vasya'}, 0, -1),
21
+ space0.select([{name: 'vasya'}], 0, -1),
22
+ space0.select([{name: 'vasya'}, {name: 'ilya'}], 0, -1),
23
+ space0.select([{name: 'ilya'}, {name: 'vasya'}], 0, -1),
24
+ space0.select([{name: 'ilya'}, {name: 'vasya'}], 0, 1),
25
+ space0.select([{name: 'ilya'}, {name: 'vasya'}], 1, 1),
26
+ space0.select({score: 13}, 0, 2),
27
+ space0.select({surname: 'zimov', email: 'il@zi.bot'}, 0, -1),
28
+ ] }
29
+ results[0].must_equal [vasya]
30
+ results[1].must_equal [vasya]
31
+ results[2].must_equal [vasya, ilya]
32
+ results[3].must_equal [ilya, vasya]
33
+ results[4].must_equal [ilya]
34
+ results[5].must_equal [vasya]
35
+ (results[6] - [ilya, fedor]).must_be_empty
36
+ ([ilya, fedor] - results[6]).must_be_empty
37
+ results[7].must_equal [ilya]
38
+ end
39
+
40
+ it "should select tail (and have #all)" do
41
+ results = blockrun{ [
42
+ space1.all({id: 2}),
43
+ space2.all({third: 1})
44
+ ] }
45
+ results[0].must_equal [{id: 2, _tail: [['medium', 6], ['common', 7]]}]
46
+ (results[1] - [hozo, pidas]).must_be_empty
47
+ ([hozo, pidas] - results[1]).must_be_empty
48
+ end
49
+
50
+ it "should react on #by_pk" do
51
+ results = blockrun{ [
52
+ space0.by_pk('vasya'),
53
+ space1.by_pk([1]),
54
+ space1.by_pk({id: 2}),
55
+ space2.by_pk(['hi zo', 'ho zo']),
56
+ space2.by_pk({first: 'hi zo', second: 'pidas'})
57
+ ] }
58
+ results[0].must_equal vasya
59
+ results[1].must_equal({id: 1, _tail: [['common', 4]]})
60
+ results[2].must_equal({id: 2, _tail: [['medium', 6], ['common', 7]]})
61
+ results[3].must_equal hozo
62
+ results[4].must_equal pidas
63
+ end
64
+
65
+ it "should react on #first" do
66
+ results = blockrun{ [
67
+ space0.first({surname: 'petrov', email: 'eb@lo.com'}),
68
+ space2.first({third: 1})
69
+ ] }
70
+ results[0].must_equal vasya
71
+ [hozo, pidas].must_include results[1]
72
+ end
73
+
74
+ it "should insert" do
75
+ petr = {name: 'petr', surname: 'kuprin', email: 'zo@na.ru', score: 1000}
76
+ sp1id3 = {id: 3, _tail: [['no', 8], ['more', 9], ['turtles', 10]]}
77
+ results = blockrun{ [
78
+ space0.insert(petr),
79
+ space0.first(score: 1000),
80
+ space1.insert(sp1id3, return_tuple: true)
81
+ ] }
82
+ results[0].must_equal 1
83
+ results[1].must_equal petr
84
+ results[2].must_equal sp1id3
85
+ end
86
+
87
+ it "should replace" do
88
+ huzo = {first: 'hi zo', second: 'ho zo', third: 6, _tail: [5, 4]}
89
+ results = blockrun{ [
90
+ space2.replace(huzo),
91
+ space2.by_pk(['hi zo', 'ho zo']),
92
+ space1.replace({id: 2, _tail: []}, return_tuple: true)
93
+ ] }
94
+ results[0].must_equal 1
95
+ results[1].must_equal huzo
96
+ results[2].must_equal({id: 2})
97
+ end
98
+
99
+ it "should update" do
100
+ results = blockrun{ [
101
+ space0.update('vasya', {score: 6}),
102
+ space0.by_pk('vasya'),
103
+ space0.update(['ilya'], {email: 'x@y.z', score: [:+, 2]}, return_tuple: true),
104
+ space1.update({id: 1}, {2 => 'more', 3 => 8}, return_tuple: true),
105
+ space1.update(2, [[2, :insert, 'high'], [2, :ins, 20]], return_tuple: true),
106
+ space2.update(['hi zo', 'pidas'], {_tail: [[:+, 1], [:+, -1]]}, return_tuple: true),
107
+ ] }
108
+ results[0].must_equal 1
109
+ results[1].must_equal vasya.merge(score: 6)
110
+ results[2].must_equal ilya.merge(score: 15, email: 'x@y.z')
111
+ results[3].must_equal({id: 1, _tail: [['common', 4], ['more', 8]]})
112
+ results[4].must_equal({id: 2, _tail: [['medium', 6], ['high', 20], ['common', 7]]})
113
+ results[5].must_equal({first: 'hi zo', second: 'pidas', third: 1, _tail: [4, 4]})
114
+ end
115
+
116
+ it "should delete" do
117
+ results = blockrun {[
118
+ space0.delete('vasya', return_tuple: true),
119
+ space0.delete(['ilya'], return_tuple: true),
120
+ space0.delete({name: 'fedor'}, return_tuple: true),
121
+ space1.delete({id: 1}),
122
+ space2.delete(['hi zo', 'ho zo']),
123
+ space2.delete({first: 'hi zo', second: 'pidas'}),
124
+ space2.delete(['unknown', 'man'])
125
+ ]}
126
+ results[0].must_equal vasya
127
+ results[1].must_equal ilya
128
+ results[2].must_equal fedor
129
+ results[3..6].must_equal [1, 1, 1, 0]
130
+ end
131
+
132
+ it "should be able to call" do
133
+ results = blockrun {[
134
+ space0.call('box.select_range', [0, 2]),
135
+ space0.call('box.select_range', [0, 1000000, 'ilya']),
136
+ space0.call('func2', [1,2], types: [:int, :int], returns: [:str, :int]),
137
+ space0.call('func2', [1,2], types: [:int, :int], returns: {type: :str, val: :int})
138
+ ]}
139
+ results[0].must_equal [fedor, ilya]
140
+ results[1].must_equal [ilya, vasya]
141
+ results[2].must_equal [['string', 1], ['string', 2]]
142
+ results[3].must_equal [{type: 'string', val: 1}, {type: 'string', val: 2}]
143
+ end
144
+
145
+ it "should raise error on wrong key" do
146
+ blockrun {
147
+ proc {
148
+ space2.insert(name: 1)
149
+ }.must_raise Tarantool::ArgumentError
150
+ proc {
151
+ space2.by_pk(third: 1)
152
+ }.must_raise Tarantool::ArgumentError
153
+ proc {
154
+ space2.first(name: 1)
155
+ }.must_raise Tarantool::ArgumentError
156
+ proc {
157
+ space2.all(name: 1)
158
+ }.must_raise Tarantool::ArgumentError
159
+ proc {
160
+ space2.select([name: 1], 0, 1)
161
+ }.must_raise Tarantool::ArgumentError
162
+ proc {
163
+ space2.update({third: 1}, {first: 'haha'})
164
+ }.must_raise Tarantool::ArgumentError
165
+ proc {
166
+ space2.update({first: 'haha'}, {first: 'haha'})
167
+ }.must_raise Tarantool::ArgumentError
168
+ proc {
169
+ space2.update({first: 'haha', second: 'hoho'}, {name: 'haha'})
170
+ }.must_raise Tarantool::ArgumentError
171
+ }
172
+ end
173
+
174
+ describe "Array Serializer" do
175
+ it "should be able to save" do
176
+ results = blockrun {[
177
+ space3.insert({id: 1, scores: [1,2,3,4]}, return_tuple: true),
178
+ space3.insert({id: 2, scores: []}, return_tuple: true),
179
+ space3.insert({id: 3}, return_tuple: true),
180
+ space3.all_by_pks([1,2,3])
181
+ ]}
182
+ results[0].must_equal({id: 1, scores: [1,2,3,4]})
183
+ results[1].must_equal({id: 2, scores: nil})
184
+ results[2].must_equal({id: 3, scores: nil})
185
+ results[3].sort_by{|h| h[:id]}.must_equal [
186
+ {id:1, scores:[1,2,3,4]},
187
+ {id:2, scores:nil},
188
+ {id:3, scores:nil}
189
+ ]
190
+ end
191
+
192
+ it "should be able to update" do
193
+ results = blockrun {[
194
+ space3.insert({id:1, scores:[1,2,3,4]}, return_tuple: true),
195
+ space3.update(1, [[:scores, :set, [4,3,2,1]]], return_tuple: true)
196
+ ]}
197
+ results.must_equal [{id:1, scores:[1,2,3,4]}, {id:1, scores:[4,3,2,1]}]
198
+ end
199
+
200
+ it "should be able to save tail with same type" do
201
+ results = blockrun {[
202
+ space3.insert({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]}, return_tuple: true),
203
+ space3.by_pk(1)
204
+ ]}
205
+ results[0].must_equal({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]})
206
+ results[1].must_equal({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]})
207
+ end
208
+
209
+ it "should be able to update tail with same type" do
210
+ results = blockrun {[
211
+ space3.insert({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]}, return_tuple: true),
212
+ space3.update(1, {1 => [:set, [3,2,1]]}, return_tuple: true)
213
+ ]}
214
+ results[0].must_equal({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]})
215
+ results[1].must_equal({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [3,2,1]]})
216
+ end
217
+
218
+ it "should be able to update tail with same type(2)" do
219
+ results = blockrun {[
220
+ space3.insert({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]}, return_tuple: true),
221
+ space3.update(1, {:_tail => [:set, [[1,2,3],[3,2,1]]]}, return_tuple: true)
222
+ ]}
223
+ results[0].must_equal({id:1, scores:[1,2,3,4], _tail:[[4,3,2,1], [2,1]]})
224
+ results[1].must_equal({id:1, scores:[1,2,3,4], _tail:[[1,2,3], [3,2,1]]})
225
+ end
226
+
227
+ it "should be able to search by serialized value" do
228
+ results = blockrun {[
229
+ space3.insert({id:5, scores:[1,2,3]}),
230
+ space3.insert({id:6, scores:[3,2,1]}),
231
+ space3.first(scores: [1,2,3]),
232
+ space3.first(scores: [3,2,1]),
233
+ ]}
234
+ results[0..1].must_equal [1,1]
235
+ results[2].must_equal({id:5, scores:[1,2,3]})
236
+ results[3].must_equal({id:6, scores:[3,2,1]})
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,22 @@
1
+ function truncate(space_no)
2
+ box.space[0+space_no]:truncate()
3
+ end
4
+
5
+ function func1(space_no, arg1, arg2)
6
+ return
7
+ {type(space_no), space_no},
8
+ {type(arg1), arg1},
9
+ {type(arg2), arg2}
10
+ end
11
+
12
+ function func2(space_no, arg1, arg2)
13
+ return
14
+ {type(arg1), arg1},
15
+ {type(arg2), arg2}
16
+ end
17
+
18
+ function func3(arg1, arg2)
19
+ return
20
+ {type(arg1), arg1},
21
+ {type(arg2), arg2}
22
+ end
@@ -0,0 +1,62 @@
1
+ slab_alloc_arena = 0.1
2
+ pid_file = "box.pid"
3
+
4
+ logger="cat - >> tarantool.log"
5
+ work_dir="tarant"
6
+
7
+ primary_port = 33013
8
+ secondary_port = 33014
9
+ admin_port = 33015
10
+
11
+ rows_per_wal = 50000
12
+
13
+ space[0].enabled = 1
14
+
15
+ space[0].index[0].type = "TREE"
16
+ space[0].index[0].unique = 1
17
+ space[0].index[0].key_field[0].fieldno = 0
18
+ space[0].index[0].key_field[0].type = "STR"
19
+
20
+ space[0].index[1].type = "TREE"
21
+ space[0].index[1].unique = 0
22
+ space[0].index[1].key_field[0].fieldno = 1
23
+ space[0].index[1].key_field[0].type = "STR"
24
+ space[0].index[1].key_field[1].fieldno = 2
25
+ space[0].index[1].key_field[1].type = "STR"
26
+
27
+ space[0].index[2].type = "TREE"
28
+ space[0].index[2].unique = 0
29
+ space[0].index[2].key_field[0].fieldno = 3
30
+ space[0].index[2].key_field[0].type = "NUM"
31
+
32
+ space[1].enabled = 1
33
+
34
+ space[1].index[0].type = "HASH"
35
+ space[1].index[0].unique = 1
36
+ space[1].index[0].key_field[0].fieldno = 0
37
+ space[1].index[0].key_field[0].type = "NUM"
38
+
39
+
40
+ space[2].enabled = 1
41
+
42
+ space[2].index[0].type = "TREE"
43
+ space[2].index[0].unique = 1
44
+ space[2].index[0].key_field[0].fieldno = 0
45
+ space[2].index[0].key_field[0].type = "STR"
46
+ space[2].index[0].key_field[1].fieldno = 1
47
+ space[2].index[0].key_field[1].type = "STR"
48
+
49
+ space[2].index[1].type = "TREE"
50
+ space[2].index[1].unique = 0
51
+ space[2].index[1].key_field[0].fieldno = 2
52
+ space[2].index[1].key_field[0].type = "NUM"
53
+
54
+ space[3].enabled = 1
55
+ space[3].index[0].type = "HASH"
56
+ space[3].index[0].unique = 1
57
+ space[3].index[0].key_field[0].fieldno = 0
58
+ space[3].index[0].key_field[0].type = "NUM"
59
+ space[3].index[1].type = "TREE"
60
+ space[3].index[1].unique = 0
61
+ space[3].index[1].key_field[0].fieldno = 1
62
+ space[3].index[1].key_field[0].type = "STR"
@@ -0,0 +1,6 @@
1
+ 1341840795.677 2887 1/sched _ I> space 0 successfully configured
2
+ 1341840795.677 2887 1/sched _ I> space 1 successfully configured
3
+ 1341840795.677 2887 1/sched _ I> space 2 successfully configured
4
+ 1341840795.677 2887 1/sched _ I> recovery start
5
+ 1341840795.677 2887 1/sched _ recovery.m:274 E> can't find snapshot
6
+ 1341840795.677 2887 1/sched _ C> didn't you forget to initialize storage with --init-storage switch?
@@ -2,12 +2,14 @@ slab_alloc_arena = 0.1
2
2
  pid_file = "box.pid"
3
3
 
4
4
  logger="cat - >> tarantool.log"
5
+ work_dir="tarant_repl"
5
6
 
6
- primary_port = 33013
7
- secondary_port = 33014
8
- admin_port = 33015
7
+ primary_port = 34013
8
+ secondary_port = 34014
9
+ admin_port = 34015
10
+ replication_source = "127.0.0.1:33012"
9
11
 
10
- rows_per_wal = 50
12
+ rows_per_wal = 50000
11
13
 
12
14
  space[0].enabled = 1
13
15
 
@@ -23,6 +25,10 @@ space[0].index[1].key_field[0].type = "STR"
23
25
  space[0].index[1].key_field[1].fieldno = 2
24
26
  space[0].index[1].key_field[1].type = "STR"
25
27
 
28
+ space[0].index[2].type = "TREE"
29
+ space[0].index[2].unique = 0
30
+ space[0].index[2].key_field[0].fieldno = 3
31
+ space[0].index[2].key_field[0].type = "NUM"
26
32
 
27
33
  space[1].enabled = 1
28
34
 
@@ -44,4 +50,4 @@ space[2].index[0].key_field[1].type = "STR"
44
50
  space[2].index[1].type = "TREE"
45
51
  space[2].index[1].unique = 0
46
52
  space[2].index[1].key_field[0].fieldno = 2
47
- space[2].index[1].key_field[0].type = "NUM"
53
+ space[2].index[1].key_field[0].type = "NUM"