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
@@ -1,316 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'spec_helper'
3
- require 'tarantool/record'
4
- require 'yajl'
5
- require 'tarantool/serializers/bson'
6
- describe Tarantool::Record do
7
- include Helpers::Truncate
8
-
9
- def space
10
- @space ||= DB.space 0
11
- end
12
-
13
- let(:user_class) do
14
- Class.new(Tarantool::Record) do
15
- set_tarantool DB
16
- set_space_no 0
17
-
18
- def self.name # For naming
19
- "User"
20
- end
21
-
22
- field :login, :string
23
- field :name, :string
24
- field :email, :string
25
- field :apples_count, :integer, default: 0
26
- index :name, :email
27
- end
28
- end
29
-
30
- let(:user) { user_class.new }
31
- it "should set and get attributes" do
32
- user.name = 'Andrew'
33
- user.name.must_equal 'Andrew'
34
- end
35
-
36
- describe "inheritance" do
37
- let(:author_class) do
38
- Class.new(user_class) do
39
- field :best_book, Integer
40
- end
41
- end
42
- let(:artist_class) do
43
- Class.new(user_class) do
44
- field :imdb_id, Integer
45
- end
46
- end
47
-
48
- describe "Artist from User" do
49
- it "should has only itself field" do
50
- artist_class.fields.keys.must_equal [:login, :name, :email, :apples_count, :imdb_id]
51
- end
52
- end
53
-
54
- it "should has same space no as parent" do
55
- user_class.space_no = 1
56
- artist_class.space_no.must_equal 1
57
- end
58
-
59
- it "should has different space no to parent if setted" do
60
- artist_class.space_no = 1
61
- user_class.space_no.must_equal 0
62
- artist_class.space_no.must_equal 1
63
- end
64
- end
65
-
66
- describe "detect_index_no" do
67
- let(:select) { user_class.select }
68
- it "should return 0 for :login" do
69
- select.detect_index_no([:login]).must_equal 0
70
- end
71
- it "should return 1 for :name" do
72
- select.detect_index_no([:name]).must_equal 1
73
- end
74
- it "should return 1 for :name, :email" do
75
- select.detect_index_no([:name, :email]).must_equal 1
76
- end
77
- it "should return nil for :email" do
78
- select.detect_index_no([:email]).must_be_nil
79
- end
80
- it "should return nil for :login, :name" do
81
- select.detect_index_no([:login, :name]).must_be_nil
82
- end
83
- end
84
-
85
- describe "save" do
86
- it "should save and select record" do
87
- u = user_class.new login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
88
- u.save
89
- u = user_class.find 'prepor'
90
- u.id.must_equal 'prepor'
91
- u.email.must_equal 'ceo@prepor.ru'
92
- u.name.must_equal 'Andrew'
93
- u.apples_count.must_equal 0
94
- end
95
-
96
- it "should update dirty attributes" do
97
- u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
98
- u.name = 'Petr'
99
- u.save
100
- u = user_class.find 'prepor'
101
- u.email.must_equal 'ceo@prepor.ru'
102
- u.name.must_equal 'Petr'
103
- end
104
-
105
- describe "with nils" do
106
- before do
107
- user_class.field :info, :bson
108
- end
109
- it "should work properly with nils values" do
110
- u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru', apples_count: nil
111
- u.info.must_be_nil
112
- u.apples_count.must_be_nil
113
- u.reload
114
- u.info.must_be_nil
115
- u.apples_count.must_be_nil
116
- u.info = {'bio' => 'hi!'}
117
- u.apples_count = 1
118
- u.save
119
- u.reload
120
- u.info.must_equal({ 'bio' => 'hi!' })
121
- u.apples_count.must_equal 1
122
- end
123
- end
124
- end
125
-
126
- describe "reload" do
127
- it "should reload current record" do
128
- u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
129
- u.name = 'Petr'
130
- u.reload.name.must_equal 'Andrew'
131
- end
132
- end
133
-
134
- describe "increment" do
135
- before { @truncate_fields = 2 }
136
- let(:user) { user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
137
- it "should increment apples count by 1" do
138
- user.increment :apples_count
139
- user.reload.apples_count.must_equal 1
140
- end
141
-
142
- it "should increment apples count by 3" do
143
- user.increment :apples_count, 3
144
- user.reload.apples_count.must_equal 3
145
- end
146
- end
147
-
148
- describe "destroy" do
149
- it "should destroy record" do
150
- u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
151
- u.destroy
152
- u.reload.must_equal false
153
- end
154
- end
155
-
156
- describe "validations" do
157
- describe "with validator on login size" do
158
- before do
159
- user_class.validates_length_of(:login, minimum: 3)
160
- end
161
- it "should invalidate all records with login less then 3 chars" do
162
- u = user_class.new login: 'pr', name: 'Andrew', email: 'ceo@prepor.ru'
163
- u.save.must_equal false
164
- u.valid?.must_equal false
165
- u.errors.size.must_equal 1
166
- u.login = 'prepor'
167
- u.save.must_equal true
168
- u.valid?.must_equal true
169
- u.errors.size.must_equal 0
170
- end
171
- end
172
- end
173
-
174
- describe "callbacks" do
175
- let(:u) { user_class.new login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru '}
176
- it "should run before / after create callbackss in right places" do
177
- user_class.before_create :action_before_create
178
- user_class.after_create :action_after_create
179
- mock(u).action_before_create { u.new_record?.must_equal true }
180
- mock(u).action_after_create { u.new_record?.must_equal false }
181
- u.save
182
- end
183
-
184
- describe "initialize" do
185
- it "should run after_initialize after any initialization" do
186
- user_class.after_initialize :action_after_initialize
187
- any_instance_of(user_class) do |u|
188
- mock(u).action_after_initialize.twice
189
- end
190
- u.save
191
- user_class.find u.login
192
- end
193
-
194
- it "should not run after_initialize after reload" do
195
- user_class.after_initialize :action_after_initialize
196
- any_instance_of(user_class) do |u|
197
- mock(u).action_after_initialize.once
198
- end
199
- u.save
200
- u.reload
201
- end
202
-
203
- it "should properly save record inside after_initialize" do
204
- user_class.after_initialize do |u|
205
- u.save
206
- end
207
- u
208
- user_class.find u.login
209
- end
210
- end
211
- end
212
-
213
- describe "serialization" do
214
- it "should support AM serialization API" do
215
- h = { login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
216
- u = user_class.create h
217
- u.as_json.must_equal({ 'user' => h.merge(apples_count: 0) })
218
- end
219
-
220
- describe "fields serilizers" do
221
- before do
222
- user_class.field :info, :bson
223
- end
224
-
225
- it "should serialise and deserialize info field" do
226
- info = { 'bio' => "hi!", 'age' => 23, 'hobbies' => ['mufa', 'tuka'] }
227
- u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru', info: info
228
- u.info['hobbies'].must_equal ['mufa', 'tuka']
229
- u.reload
230
- u.info['hobbies'].must_equal ['mufa', 'tuka']
231
- u = user_class.find u.login
232
- u.info['hobbies'].must_equal ['mufa', 'tuka']
233
- end
234
- end
235
- end
236
-
237
- describe "select" do
238
- describe "by name Andrew" do
239
- let(:select) { user_class.where(name: 'Andrew') }
240
- before do
241
- user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
242
- user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
243
- user_class.create login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'
244
- end
245
- it "should select all records with name == 'Andrew'" do
246
- select.all.map(&:login).must_equal ['prepor', 'ruden']
247
- end
248
-
249
- it "should select first record with name == 'Andrew'" do
250
- select.first.login.must_equal 'prepor'
251
- end
252
-
253
- it "should select 1 record by name and email" do
254
- user_class.where(name: 'Andrew', email: 'rudenkoco@gmail.com').map(&:login).must_equal ['ruden']
255
- end
256
-
257
- it "should select 2 record by name and email" do
258
- user_class.where(name: ['Andrew', 'Andrew'], email: ['ceo@prepor.ru', 'rudenkoco@gmail.com']).map(&:login).must_equal ['prepor', 'ruden']
259
- end
260
-
261
- it "should select 3 record by names" do
262
- user_class.where(name: ['Andrew', 'Petr']).map(&:login).must_equal ['prepor', 'ruden', 'petro']
263
- end
264
-
265
- describe "with limit 1" do
266
- let(:select) { super().limit(1) }
267
- it "should select first record with name == 'Andrew'" do
268
- select.map(&:login).must_equal ['prepor']
269
- end
270
-
271
- describe "with offset 1" do
272
- let(:select) { super().offset(1) }
273
- it "should select last record with name == 'Andrew'" do
274
- select.map(&:login).must_equal ['ruden']
275
- end
276
- end
277
- end
278
- end
279
-
280
- describe "==" do
281
-
282
- before do
283
- user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
284
- user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
285
- end
286
-
287
- it "should return equality as true" do
288
- u1 = user_class.where(login: "prepor").first
289
- u2 = user_class.where(login: "prepor").first
290
- (u1 == u2).must_equal true
291
- end
292
-
293
- it "should not return equality as true" do
294
- u1 = user_class.where(login: "prepor")
295
- u2 = user_class.where(login: "petro")
296
- (u1 == u2).must_equal false
297
- end
298
- end
299
-
300
-
301
- describe "call" do
302
- let(:res) { user.class.select.call('box.select_range', 0, 0, 2)}
303
- before do
304
- user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
305
- user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
306
- user_class.create login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'
307
- end
308
-
309
- it "should select 2 records and return UserClass instances" do
310
- res.size.must_equal 2
311
- res.any? { |v| v.is_a? user_class }
312
- end
313
- end
314
- end
315
-
316
- end
@@ -1,103 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'spec_helper'
3
-
4
- describe Tarantool::Request do
5
- def space
6
- @space ||= DB.space 1
7
- end
8
-
9
- describe "pack method" do
10
- describe "for field" do
11
- it "should pack integer as 32 bit integer" do
12
- size, value = Tarantool::Request.pack_field(5).unpack('wL')
13
- value.must_equal 5
14
- end
15
-
16
- it "should pack string as arbitrary binary string" do
17
- size, value = Tarantool::Request.pack_field("привет").unpack('wa*')
18
- value.force_encoding('utf-8').must_equal 'привет'
19
- end
20
-
21
- it "should raise ArgumentError for other types" do
22
- lambda { Tarantool::Request.pack_field(:foo) }.must_raise Tarantool::ArgumentError
23
- end
24
- end
25
-
26
- describe "for tuple" do
27
- it "should pack to fields with fields count" do
28
- field1, field2 = 1, "привет"
29
- expect = [2, 4, field1, field2.bytesize, field2].pack('LwLwa*')
30
- Tarantool::Request.pack_tuple(field1, field2).must_equal expect
31
- end
32
- end
33
- end
34
-
35
- describe "requests" do
36
- include Helpers::Truncate
37
- describe "insert and select" do
38
- it "should insert tuple and return it" do
39
- space.insert 100, 'привет', return_tuple: true
40
- res = space.select 100
41
- int, string = res.tuple
42
- int.to_i.must_equal 100
43
- string.to_s.must_equal 'привет'
44
- end
45
-
46
- describe "with equal ids" do
47
- it "should raise error" do
48
- space.insert 100, 'lala'
49
- lambda { space.insert 100, 'yo' }.must_raise(Tarantool::BadReturnCode)
50
- end
51
- end
52
- end
53
-
54
- describe "select" do
55
- it "should select multiple tuples" do
56
- space.insert 100, 'привет'
57
- space.insert 101, 'hi'
58
- res = space.select 100, 101
59
- res.tuples.map { |v| v.last.to_s }.must_equal ['привет', 'hi']
60
- end
61
- end
62
-
63
- describe "call" do
64
- it "should call lua proc" do
65
- res = space.call 'box.pack', 'i', '100', return_tuple: true
66
- res.tuple[0].to_i.must_equal 100
67
- end
68
-
69
- it "should return batches via select_range" do
70
- space.insert 100, 'привет'
71
- space.insert 101, 'hi'
72
- res = space.call 'box.select_range', '1', '0', '100', return_tuple: true
73
- res.tuples.size.must_equal 2
74
- end
75
- end
76
-
77
- describe "update" do
78
- it "should update tuple" do
79
- space.insert 100, 'привет'
80
- space.update 100, ops: [[1, :set, 'yo!']]
81
- res = space.select 100
82
- int, string = res.tuple
83
- string.to_s.must_equal 'yo!'
84
- end
85
- end
86
-
87
- describe "delete" do
88
- it "should delete record" do
89
- inserted = space.insert 100, 'привет', return_tuple: true
90
- space.delete inserted.tuple[0], return_tuple: true
91
- res = space.select 100
92
- res.tuple.must_be_nil
93
- end
94
- end
95
-
96
- describe "ping" do
97
- it "should ping without exceptions" do
98
- res = space.ping
99
- res.must_be_kind_of Numeric
100
- end
101
- end
102
- end
103
- end
data/tarantool.gemspec DELETED
@@ -1,69 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.specification_version = 2 if s.respond_to? :specification_version=
3
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
- s.rubygems_version = '1.3.5'
5
-
6
- s.name = 'tarantool'
7
- s.version = '0.2.5'
8
- s.date = '2012-06-02'
9
- s.rubyforge_project = 'tarantool'
10
-
11
- s.summary = "Tarantool KV-storage client."
12
- s.description = "Tarantool KV-storage client."
13
-
14
- s.authors = ["Andrew Rudenko"]
15
- s.email = 'ceo@prepor.ru'
16
- s.homepage = 'http://github.com/mailru/tarantool-ruby'
17
-
18
- s.require_paths = %w[lib]
19
-
20
- s.rdoc_options = ["--charset=UTF-8"]
21
- s.extra_rdoc_files = %w[README.md LICENSE]
22
-
23
- s.add_dependency('iproto', [">= 0.2"])
24
- s.add_dependency('activemodel', [">= 3.1", "< 4.0"])
25
-
26
-
27
- # = MANIFEST =
28
- s.files = %w[
29
- Gemfile
30
- Gemfile.lock
31
- LICENSE
32
- README.md
33
- Rakefile
34
- examples/em_simple.rb
35
- examples/record.rb
36
- examples/simple.rb
37
- lib/tarantool.rb
38
- lib/tarantool/exceptions.rb
39
- lib/tarantool/record.rb
40
- lib/tarantool/request.rb
41
- lib/tarantool/requests.rb
42
- lib/tarantool/requests/call.rb
43
- lib/tarantool/requests/delete.rb
44
- lib/tarantool/requests/insert.rb
45
- lib/tarantool/requests/ping.rb
46
- lib/tarantool/requests/select.rb
47
- lib/tarantool/requests/update.rb
48
- lib/tarantool/response.rb
49
- lib/tarantool/serializers.rb
50
- lib/tarantool/serializers/bson.rb
51
- lib/tarantool/serializers/integer.rb
52
- lib/tarantool/serializers/string.rb
53
- lib/tarantool/space.rb
54
- spec/helpers/let.rb
55
- spec/helpers/truncate.rb
56
- spec/spec_helper.rb
57
- spec/tarantool.cfg
58
- spec/tarantool/composite_primary_key_spec.rb
59
- spec/tarantool/em_spec.rb
60
- spec/tarantool/record_spec.rb
61
- spec/tarantool/request_spec.rb
62
- tarantool.gemspec
63
- ]
64
- # = MANIFEST =
65
-
66
- ## Test files will be grabbed from the file list. Make sure the path glob
67
- ## matches what you actually use.
68
- s.test_files = s.files.select { |path| path =~ /^spec\/.*_spec\.rb/ }
69
- end