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,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"