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
data/Gemfile CHANGED
@@ -1,14 +1,16 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- gem "activemodel"
3
+ group :development do
4
+ gem "debugger"
5
+ end
4
6
 
5
- gem "rr"
6
- gem "yajl-ruby"
7
- gem "bson"
8
- gem "bson_ext"
9
-
10
- gem "ruby-debug19"
11
-
12
- gem "em-synchrony"
13
-
14
- gemspec
7
+ group :test do
8
+ gem "rr"
9
+ gem "activesupport"
10
+ gem "activemodel"
11
+ gem "yajl-ruby"
12
+ gem "bson"
13
+ gem "bson_ext"
14
+ end
15
+ # Specify your gem's dependencies in em-tarantool.gemspec
16
+ gemspec
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
- /*
2
- * Copyright (C) 2011 Mail.RU
3
- *
1
+ /*
2
+ * Copyright (C) 2011-2012 Mail.RU
3
+ *
4
4
  * Redistribution and use in source and binary forms, with or without
5
5
  * modification, are permitted provided that the following conditions
6
6
  * are met:
@@ -21,4 +21,4 @@
21
21
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
22
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
23
  * SUCH DAMAGE.
24
- */
24
+ */
data/README.md CHANGED
@@ -22,7 +22,13 @@ DB = Tarantool.new host: 'locahost', port: 33013
22
22
  space = DB.space 0
23
23
  ```
24
24
 
25
- The driver internals can work in two modes: block via TCPSocket and non block via EventMachine and fibers. By default it uses block mode.
25
+ The driver internals can work in three modes:
26
+ - blocking via TCPSocket
27
+ - callback style via EventMachine
28
+ - EM::Synchrony like via EventMachine and fibers, so that control flow is visually
29
+ blocked, but eventloop is not (see EM::Synchrony)
30
+
31
+ By default it uses block mode.
26
32
 
27
33
 
28
34
  ```ruby
@@ -49,7 +55,7 @@ EM.synchrony do
49
55
  end
50
56
  ```
51
57
 
52
- The driver itself provides ActiveModel API: Callbacks, Validations, Serialization, Dirty.
58
+ The driver itself provides ActiveModel API: Callbacks, Validations, Serialization, Dirty.
53
59
  Type casting is automatic, based on the index type chosen to process the query.
54
60
  For example:
55
61
 
@@ -59,7 +65,7 @@ require 'tarantool/serializers/bson'
59
65
  class User < Tarantool::Record
60
66
  field :login, :string
61
67
  field :name, :string
62
- field :email, :string
68
+ field :email, :string
63
69
  field :apples_count, :integer, default: 0
64
70
  field :info, :bson
65
71
  index :name, :email
@@ -76,16 +82,16 @@ User.create login: 'prepor', email: 'ceo@prepor.ru', name: 'Andrew'
76
82
  User.create login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'
77
83
 
78
84
  # find by primary key login
79
- User.find 'prepor'
85
+ User.find 'prepor'
80
86
  # first 2 users with name Andrew
81
- User.where(name: 'Andrew').limit(2).all
87
+ User.where(name: 'Andrew').limit(2).all
82
88
  # second user with name Andrew
83
- User.where(name: 'Andrew').offset(1).limit(1).all
89
+ User.where(name: 'Andrew').offset(1).limit(1).all
84
90
  # user with name Andrew and email ceo@prepor.ru
85
91
  User.where(name: 'Andrew', email: 'ceo@prepor.ru').first
86
92
  # raise exception, becouse we can't select query started from not first part of index
87
93
  begin
88
- User.where(email: 'ceo@prepor.ru')
94
+ User.where(email: 'ceo@prepor.ru')
89
95
  rescue Tarantool::ArgumentError => e
90
96
  end
91
97
  # increment field apples_count by one. Its atomic operation via native Tarantool interface
@@ -105,7 +111,7 @@ user.destroy
105
111
  ```
106
112
 
107
113
  When definining a record, field order is important: this is the order of fields
108
- in the tuple stored by Tarantool. By default, the primary key is field 0.
114
+ in the tuple stored by Tarantool. By default, the primary key is field 0.
109
115
 
110
116
  `index` method just mapping to your Tarantool schema, client doesn't modify schema for you.
111
117
 
@@ -117,4 +123,4 @@ in the tuple stored by Tarantool. By default, the primary key is field 0.
117
123
  * admin-socket protocol
118
124
  * safe to add fields to exist model
119
125
  * Hash, Array and lambdas as default values
120
- * timers to response, reconnect strategies
126
+ * timers to response, reconnect strategies
data/Rakefile CHANGED
@@ -1,131 +1,7 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'date'
4
-
5
- #############################################################################
6
- #
7
- # Helper functions
8
- #
9
- #############################################################################
10
-
11
- def name
12
- @name ||= Dir['*.gemspec'].first.split('.').first
13
- end
14
-
15
- def version
16
- line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
- line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
- end
19
-
20
- def date
21
- Date.today.to_s
22
- end
23
-
24
- def rubyforge_project
25
- name
26
- end
27
-
28
- def gemspec_file
29
- "#{name}.gemspec"
30
- end
31
-
32
- def gem_file
33
- "#{name}-#{version}.gem"
34
- end
35
-
36
- def replace_header(head, header_name)
37
- head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
- end
39
-
40
- #############################################################################
41
- #
42
- # Standard tasks
43
- #
44
- #############################################################################
45
-
46
-
47
- task :default => :spec
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
48
3
  require 'rake/testtask'
49
- Rake::TestTask.new(:spec) do |t|
50
- t.libs << 'spec'
51
- t.pattern = 'spec/**/*_spec.rb'
52
- t.verbose = false
53
- end
54
-
55
- desc "Generate RCov test coverage and open in your browser"
56
- task :coverage do
57
- require 'rcov'
58
- sh "rm -fr coverage"
59
- sh "rcov test/test_*.rb"
60
- sh "open coverage/index.html"
61
- end
62
-
63
- desc "Open an irb session preloaded with this library"
64
- task :console do
65
- sh "irb -rubygems -r ./lib/#{name}.rb"
66
- end
67
-
68
-
69
- #############################################################################
70
- #
71
- # Packaging tasks
72
- #
73
- #############################################################################
74
-
75
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
76
- task :release => :build do
77
- unless `git branch` =~ /^\* master$/
78
- puts "You must be on the master branch to release!"
79
- exit!
80
- end
81
- sh "git commit --allow-empty -m 'Release #{version}'"
82
- sh "git tag v#{version}"
83
- sh "git push origin master"
84
- sh "git push origin v#{version}"
85
- sh "gem push pkg/#{name}-#{version}.gem"
86
- end
87
-
88
- desc "Build #{gem_file} into the pkg directory"
89
- task :build => :gemspec do
90
- sh "mkdir -p pkg"
91
- sh "gem build #{gemspec_file}"
92
- sh "mv #{gem_file} pkg"
93
- end
94
-
95
- desc "Generate #{gemspec_file}"
96
- task :gemspec => :validate do
97
- # read spec file and split out manifest section
98
- spec = File.read(gemspec_file)
99
- head, manifest, tail = spec.split(" # = MANIFEST =\n")
100
-
101
- # replace name version and date
102
- replace_header(head, :name)
103
- replace_header(head, :version)
104
- replace_header(head, :date)
105
- #comment this out if your rubyforge_project has a different name
106
- replace_header(head, :rubyforge_project)
107
-
108
- # determine file list from git ls-files
109
- files = `git ls-files`.
110
- split("\n").
111
- sort.
112
- reject { |file| file =~ /^\./ }.
113
- reject { |file| file =~ /^(rdoc|pkg)/ }.
114
- map { |file| " #{file}" }.
115
- join("\n")
116
-
117
- # piece file back together and write
118
- manifest = " s.files = %w[\n#{files}\n ]\n"
119
- spec = [head, manifest, tail].join(" # = MANIFEST =\n")
120
- File.open(gemspec_file, 'w') { |io| io.write(spec) }
121
- puts "Updated #{gemspec_file}"
4
+ Rake::TestTask.new do |i|
5
+ i.options = '-v'
6
+ i.verbose = true
122
7
  end
123
-
124
- desc "Validate #{gemspec_file}"
125
- task :validate do
126
- libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
127
- unless Dir['VERSION*'].empty?
128
- puts "A `VERSION` file at root level violates Gem best practices."
129
- exit!
130
- end
131
- end
@@ -0,0 +1,288 @@
1
+ require 'tarantool'
2
+ require 'tarantool/record/select'
3
+ require 'active_support/core_ext/class/attribute'
4
+
5
+ module Tarantool
6
+ class RecordError < StandardError; end
7
+ class UpdateNewRecord < RecordError; end
8
+
9
+ class BaseRecord
10
+ class_attribute :fields, instance_reader: false, instance_writer: false
11
+ self.fields = {}.freeze
12
+
13
+ class_attribute :default_values, instance_reader: false, instance_writer: false
14
+ self.default_values = {}.freeze
15
+
16
+ class_attribute :indexes, instance_reader: false, instance_writer: false
17
+ self.indexes = [].freeze
18
+
19
+ class_attribute :space_no, instance_reader: false, instance_writer: false
20
+ class_attribute :tarantool, instance_reader: false, instance_writer: false
21
+
22
+ class << self
23
+ alias set_space_no space_no=
24
+ alias set_tarantool tarantool=
25
+ end
26
+
27
+ module ClassMethods
28
+ def field(name, type, params = {})
29
+ type = Serializers.check_type(type)
30
+
31
+ raise ArgumentError, "_tail should be last declaration" if fields.include?(:_tail)
32
+ self.fields = fields.merge(name => type)
33
+ index name if indexes.empty?
34
+
35
+ if params[:default]
36
+ self.default_values = default_values.merge name => params[:default]
37
+ end
38
+
39
+ define_field_accessor(name, type)
40
+ end
41
+
42
+ def _tail(*types)
43
+ types = types.map{|type| Serializers.check_type(type)}
44
+
45
+ raise ArgumentError, "double _tail declaration" if fields.include?(:_tail)
46
+ self.fields = fields.merge(:_tail => types)
47
+
48
+ define_field_accessor(:_tail, types)
49
+ end
50
+
51
+ def index(*fields)
52
+ options = Hash === fields.last ? fields.pop : {}
53
+ if options[:primary]
54
+ self.indexes = indexes.dup.tap{|ind| ind[0] = fields}
55
+ else
56
+ self.indexes += [fields]
57
+ end
58
+ end
59
+
60
+ def primary_index
61
+ indexes[0]
62
+ end
63
+
64
+ def space
65
+ @space ||= begin
66
+ tarantool.space_hash(space_no, fields.dup, keys: indexes)
67
+ end
68
+ end
69
+
70
+ # space that will return records as results for calls
71
+ # it is useful, if you wish to use callback interface
72
+ def auto_space
73
+ @auto_space ||= begin
74
+ space.with_translator(method(:from_fetched))
75
+ end
76
+ end
77
+
78
+ def by_pk(pk)
79
+ if Hash === (res = space.by_pk(pk))
80
+ from_fetched(res)
81
+ end
82
+ end
83
+
84
+ def by_pks(pks)
85
+ space.all_by_pks(pks).map{|hash| from_fetched(hash)}
86
+ end
87
+
88
+ def find(*args)
89
+ if args.size == 1
90
+ by_pk(args[0])
91
+ else
92
+ by_pks(args)
93
+ end
94
+ end
95
+
96
+ def first(cond)
97
+ if Hash === cond
98
+ if Hash === (res = space.first(cond))
99
+ from_fetched(res)
100
+ end
101
+ else
102
+ by_pk(cond)
103
+ end
104
+ end
105
+
106
+ def all(cond, opts={})
107
+ res = space.all(cond, opts)
108
+ res.map!{|hash| from_fetched(hash)}
109
+ res
110
+ end
111
+
112
+ def select(cond=nil, opts={})
113
+ cond.nil? ? Select.new(self) : all(cond, opts)
114
+ end
115
+
116
+ def create(attributes = {})
117
+ r = new(attributes)
118
+ r.save
119
+ r
120
+ end
121
+
122
+ # Call stored procedure without returning tuples. By default, it prepends
123
+ # +space_no+ to arguments. To avoid prepending, set +space_no: nil+ in options.
124
+ #
125
+ # MyRecord.call('box.select_range', offset, limit)
126
+ # MyRecord.call('myfunction', arg1, arg2, space_no: nil)
127
+ #
128
+ def invoke(proc_name, *args)
129
+ opts = Hash === args.last ? args.pop : {}
130
+ space.invoke(proc_name, args, opts)
131
+ end
132
+
133
+ # Call stored procedure. By default, it prepends +space_no+ to arguments.
134
+ # To avoid prepending, set +space_no: nil+ in options.
135
+ #
136
+ # MyRecord.call('box.select_range', offset, limit)
137
+ # MyRecord.call('myfunction', arg1, arg2, space_no: nil)
138
+ #
139
+ # You could recieve arbitarry arrays or hashes instead of instances of
140
+ # record, if you pass +:returns+ argument. See documentation for +SpaceHash+
141
+ # for this.
142
+ def call(proc_name, *args)
143
+ opts = Hash === args.last ? args.pop : {}
144
+ res = space.call(proc_name, args, opts)
145
+ if Array === res && !opts[:returns]
146
+ res.map{|hash| from_fetched(hash) }
147
+ else
148
+ res
149
+ end
150
+ end
151
+
152
+ def from_fetched(hash)
153
+ hash && allocate.__fetched(hash)
154
+ end
155
+
156
+ def insert(hash, ret_tuple = false)
157
+ hash = default_values.merge(hash)
158
+ if ret_tuple
159
+ from_fetched space.insert(hash, return_tuple: true)
160
+ else
161
+ space.insert(hash)
162
+ end
163
+ end
164
+
165
+ def replace(hash, ret_tuple = false)
166
+ hash = default_values.merge(hash)
167
+ if ret_tuple
168
+ from_fetched space.replace(hash, return_tuple: true)
169
+ else
170
+ space.replace(hash)
171
+ end
172
+ end
173
+
174
+ def update(pk, ops, ret_tuple=false)
175
+ if ret_tuple
176
+ from_fetched space.update(pk, ops, return_tuple: true)
177
+ else
178
+ space.update(pk, ops)
179
+ end
180
+ end
181
+
182
+ def delete(pk, ret_tuple=false)
183
+ if ret_tuple
184
+ from_fetched space.delete(pk, return_tuple: true)
185
+ else
186
+ space.delete(pk)
187
+ end
188
+ end
189
+
190
+ %w{where limit offset}.each do |meth|
191
+ class_eval <<-"EOF", __FILE__, __LINE__
192
+ def #{meth}(arg)
193
+ select.#{meth}(arg)
194
+ end
195
+ EOF
196
+ end
197
+ end
198
+ extend ClassMethods
199
+
200
+ module InstanceMethods
201
+ attr_accessor :__new_record
202
+ attr_reader :attributes
203
+ alias new_record __new_record
204
+ alias new_record? new_record
205
+
206
+ def new_record!
207
+ @__new_record = true
208
+ self
209
+ end
210
+
211
+ def old_record!
212
+ @__new_record = false
213
+ self
214
+ end
215
+
216
+ def set_attributes(attributes)
217
+ attributes.each do |k, v|
218
+ send("#{k}=", v)
219
+ end
220
+ end
221
+
222
+ def _tail
223
+ @attributes[:_tail]
224
+ end
225
+
226
+ def _tail=(v)
227
+ @attributes[:_tail] = v
228
+ end
229
+
230
+ def update_attributes(attributes)
231
+ set_attributes(attributes)
232
+ save
233
+ end
234
+
235
+ def id
236
+ (primary = self.class.primary_index).size == 1 ?
237
+ @attributes[primary[0]] :
238
+ @attributes.values_at(*primary)
239
+ end
240
+
241
+ def space
242
+ self.class.space
243
+ end
244
+
245
+ def auto_space
246
+ self.class.space
247
+ end
248
+
249
+ def reload
250
+ if hash = space.by_pk(id)
251
+ @__new_record = false
252
+ @attributes = hash
253
+ self
254
+ else
255
+ _raise_doesnt_exists("reload")
256
+ end
257
+ end
258
+
259
+ def ==(other)
260
+ equal?(other) || (other.class == self.class && id == other.id)
261
+ end
262
+
263
+ # update record in db first, reload it then
264
+ #
265
+ # record.update({:state => 'sleep', :sleep_count => [:+, 1]})
266
+ # record.update([[:state, 'sleep'], [:sleep_count, :+, 1]])
267
+ def update(ops)
268
+ raise UpdateNewRecord, "Could not call update on new record" if @__new_record
269
+ unless new_attrs = space.update(id, ops, return_tuple: true)
270
+ _raise_doesnt_exists
271
+ end
272
+ @attributes = new_attrs
273
+
274
+ self
275
+ end
276
+
277
+ def increment(field, by = 1)
278
+ update([[field.to_sym, :+, by]])
279
+ end
280
+
281
+ def _raise_doesnt_exists(action = "update")
282
+ raise TupleDoesntExists.new(0x3102, "Record which you wish to #{action}, doesn't exists")
283
+ end
284
+ end
285
+ include InstanceMethods
286
+
287
+ end
288
+ end
@@ -0,0 +1,135 @@
1
+ module Tarantool
2
+ class BlockDB < DB
3
+ def establish_connection
4
+ @connection = IProto.get_connection(@host, @port, :block)
5
+ end
6
+
7
+ def close_connection
8
+ @connection.close
9
+ end
10
+
11
+ def _send_request(request_type, body, cb)
12
+ cb.call @connection.send_request(request_type, body)
13
+ end
14
+
15
+ module CommonSpaceBlockingMethods
16
+ def _block_cb
17
+ @_block_cb ||= method(:_raise_or_return)
18
+ end
19
+
20
+ def all_by_pks(pks, opts={})
21
+ all_by_pks_cb(pks, _block_cb, opts)
22
+ end
23
+
24
+ def by_pk(pk)
25
+ by_pk_cb(pk, _block_cb)
26
+ end
27
+
28
+ def insert(tuple, opts={})
29
+ insert_cb(tuple, _block_cb, opts)
30
+ end
31
+
32
+ def replace(tuple, opts={})
33
+ replace_cb(tuple, _block_cb, opts)
34
+ end
35
+
36
+ def update(pk, operations, opts={})
37
+ update_cb(pk, operations, _block_cb, opts)
38
+ end
39
+
40
+ def delete(pk, opts={})
41
+ delete_cb(pk, _block_cb, opts)
42
+ end
43
+
44
+ def invoke(func_name, values = [], opts = {})
45
+ invoke_cb(func_name, values, _block_cb, opts)
46
+ end
47
+
48
+ def call(func_name, values = [], opts = {})
49
+ call_cb(func_name, values, _block_cb, opts)
50
+ end
51
+
52
+ def ping
53
+ ping_cb(_block_cb)
54
+ end
55
+ end
56
+
57
+ class SpaceArray < ::Tarantool::SpaceArray
58
+ include CommonSpaceBlockingMethods
59
+
60
+ def all_by_key(index_no, key, opts={})
61
+ all_by_key_cb(index_no, key, _block_cb, opts)
62
+ end
63
+
64
+ def first_by_key(index_no, key)
65
+ first_by_key_cb(index_no, key, _block_cb)
66
+ end
67
+
68
+ def all_by_keys(index_no, keys, opts={})
69
+ all_by_keys_cb(index_no, keys, _block_cb, opts)
70
+ end
71
+
72
+ def select(index_no, keys, offset=0, limit=-1)
73
+ select_cb(index_no, keys, offset, limit, _block_cb)
74
+ end
75
+ end
76
+
77
+ class SpaceHash < ::Tarantool::SpaceHash
78
+ include CommonSpaceBlockingMethods
79
+
80
+ def all(keys, opts = {})
81
+ all_cb(keys, _block_cb, opts)
82
+ end
83
+
84
+ def first(key)
85
+ first_cb(key, _block_cb)
86
+ end
87
+
88
+ def select(keys, offset=0, limit=-1)
89
+ select_cb(keys, offset, limit, _block_cb)
90
+ end
91
+ end
92
+
93
+ class Query < ::Tarantool::Query
94
+ def select(space_no, index_no, keys, offset, limit, opts={})
95
+ select_cb(space_no, index_no, keys, offset, limit, _block_cb, opts)
96
+ end
97
+
98
+ def all(space_no, index_no, keys, opts={})
99
+ all_cb(space_no, index_no, keys, _block_cb, opts)
100
+ end
101
+
102
+ def first(space_no, index_no, key, opts={})
103
+ first_cb(space_no, index_no, key, _block_cb, opts)
104
+ end
105
+
106
+ def insert(space_no, tuple, opts={})
107
+ insert_cb(space_no, tuple, _block_cb, opts)
108
+ end
109
+
110
+ def replace(space_no, tuple, opts={})
111
+ replace_cb(space_no, tuple, _block_cb, opts)
112
+ end
113
+
114
+ def update(space_no, pk, operation, opts={})
115
+ update_cb(space_no, pk, operation, _block_cb, opts)
116
+ end
117
+
118
+ def delete(space_no, pk, opts={})
119
+ delete_cb(space_no, pk, _block_cb, opts)
120
+ end
121
+
122
+ def invoke(func_name, values, opts={})
123
+ invoke_cb(func_name, values, _block_cb, opts)
124
+ end
125
+
126
+ def call(func_name, values, opts={})
127
+ call_cb(func_name, values, _block_cb, opts)
128
+ end
129
+
130
+ def ping
131
+ ping_cb(_block_cb)
132
+ end
133
+ end
134
+ end
135
+ end