Module: Tarantool::Request

Includes:
Serializers, Util::Packer, Util::TailGetter
Included in:
Query, SpaceArray, SpaceHash
Defined in:
lib/tarantool/request.rb,
lib/tarantool/shards_support.rb

Defined Under Namespace

Classes: DefaultShardProc, IndexIndexError, ModuloShardProc, SumburMurmur32, SumburMurmurFmix, SumburMurmurInt64, SumburMurmurStr, WrapPing

Constant Summary collapse

SELECT_HEADER =
'VVVVV'.freeze
INSERT_HEADER =
'VV'.freeze
UPDATE_HEADER =
'VV'.freeze
DELETE_HEADER =
'VV'.freeze
CALL_HEADER =
'Vwa*'.freeze
INT32_0 =
"\x00\x00\x00\x00".freeze
INT32_1 =
"\x01\x00\x00\x00".freeze
ZERO =
"\x00".freeze
ONE =
"\x01".freeze
EMPTY =
"".freeze
PACK_STRING =
'wa*'.freeze
LEST_INT32 =
-(2**31)
TYPES_AUTO =
[:auto].freeze
TYPES_FALLBACK =
[:string].freeze
TYPES_STR_STR =
[:string, :string].freeze
TYPES_STR_AUTO =
[:string, :auto].freeze
REQUEST_SELECT =
17
REQUEST_INSERT =
13
REQUEST_UPDATE =
19
REQUEST_DELETE =
21
REQUEST_CALL =
22
REQUEST_PING =
65280
BOX_RETURN_TUPLE =
0x01
BOX_ADD =
0x02
BOX_REPLACE =
0x04
UPDATE_OPS =
{
  :"=" => 0, :+   => 1, :&   => 2, :^   => 3, :|  => 4, :[]     => 5,
  :set => 0, :add => 1, :and => 2, :xor => 3, :or => 4, :splice => 5,
  :delete => 6, :insert => 7,
  :del    => 6, :ins    => 7,
   '=' => 0, '+'  => 1, '&'  => 2, '^'  => 3, '|' => 4, '[]'    => 5,
                                                        ':'     => 5,
  'set'=> 0, 'add'=> 1, 'and'=> 2, 'xor'=> 3, 'or'=> 4, 'splice'=> 5,
  '#'     => 6, '!'     => 7,
  'delete'=> 6, 'insert'=> 7,
  'del'   => 6, 'ins'   => 7,
   0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7
}
UPDATE_FIELDNO_OP =
'VC'.freeze
BINARY =
::Encoding::BINARY
MAX_BYTE_SIZE =
1024 * 1024

Constants included from Serializers

Serializers::MAP

Constants included from Util::Packer

Util::Packer::INT16, Util::Packer::INT32, Util::Packer::INT64, Util::Packer::INT8, Util::Packer::MAX_INT16, Util::Packer::MAX_INT32, Util::Packer::MAX_INT64, Util::Packer::MAX_INT8, Util::Packer::MAX_SINT16, Util::Packer::MAX_SINT32, Util::Packer::MAX_SINT64, Util::Packer::MAX_SINT8, Util::Packer::MIN_INT, Util::Packer::MIN_SINT16, Util::Packer::MIN_SINT32, Util::Packer::MIN_SINT64, Util::Packer::MIN_SINT8, Util::Packer::SINT16, Util::Packer::SINT32, Util::Packer::SINT64, Util::Packer::SINT8

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Serializers

#check_type, #get_serializer

Instance Attribute Details

#insert_with_shards_countObject (readonly)

Returns the value of attribute insert_with_shards_count.



59
60
61
# File 'lib/tarantool/shards_support.rb', line 59

def insert_with_shards_count
  @insert_with_shards_count
end

#previous_shards_countObject (readonly)

Returns the value of attribute previous_shards_count.



58
59
60
# File 'lib/tarantool/shards_support.rb', line 58

def previous_shards_count
  @previous_shards_count
end

#shard_procObject (readonly)

Returns the value of attribute shard_proc.



58
59
60
# File 'lib/tarantool/shards_support.rb', line 58

def shard_proc
  @shard_proc
end

#shards_countObject (readonly)

Returns the value of attribute shards_count.



58
59
60
# File 'lib/tarantool/shards_support.rb', line 58

def shards_count
  @shards_count
end

Instance Method Details

#_all_shardsObject



157
158
159
# File 'lib/tarantool/shards_support.rb', line 157

def _all_shards
  (0...@shards_count).to_a
end

#_call(func_name, values, cb, opts = {}) ⇒ Object



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/tarantool/request.rb', line 352

def _call(func_name, values, cb, opts={})
  return_tuple = opts[:return_tuple] && :all
  flags = return_tuple ? BOX_RETURN_TUPLE : 0
  
  values = [*values]
  value_types = opts[:types] ? [*opts[:types]] :
                              _detect_types(values)
  return_types = [*opts[:returns] || TYPES_AUTO]

  func_name = func_name.to_s
  body = ::BinUtils.append_int32_le!(nil, flags)
  ::BinUtils.append_bersize_string!(body, func_name)
  pack_tuple(body, values, value_types, :func_call)

  shard_nums = opts[:shards] || all_shards
  read_write = case opts[:readonly]
               when nil, false, :write
                 :write
               when true, :read
                 :read
               when :replace
                 :replace
               else
                 raise ArgumentError, "space#call :readonly options accepts nil, false, :write, true, :read and :replace, but #{opts[:readonly].inspect} were sent"
               end

  _modify_request(REQUEST_CALL, body, return_types, return_tuple, cb, shard_nums, read_write, opts[:translators] || [])
end

#_delete(space_no, pk, fields, pk_fields, cb, ret_tuple, shard_nums, translators = []) ⇒ Object



316
317
318
319
320
321
322
323
# File 'lib/tarantool/request.rb', line 316

def _delete(space_no, pk, fields, pk_fields, cb, ret_tuple, shard_nums, translators = [])
  flags = ret_tuple ? BOX_RETURN_TUPLE : 0

  body = ::BinUtils.append_int32_le!(nil, space_no, flags)
  pack_tuple(body, pk, pk_fields, 0)

  _modify_request(REQUEST_DELETE, body, fields, ret_tuple, cb, shard_nums, :write, translators)
end

#_detect_shard(shard_values) ⇒ Object



143
144
145
146
147
148
149
150
151
# File 'lib/tarantool/shards_support.rb', line 143

def _detect_shard(shard_values)
  shard_values = [shard_values]  unless Array === shard_values
  shards = @shard_proc.call(shard_values, @shards_count, self) || _all_shards
  if @previous_shards_count
    prev_shards = @shard_proc.call(shard_values, @previous_shards_count, self) || _all_shards
    shards = [*shards, *prev_shards].uniq
  end
  shards
end

#_detect_shard_for_insert(shard_values) ⇒ Object



138
139
140
141
# File 'lib/tarantool/shards_support.rb', line 138

def _detect_shard_for_insert(shard_values)
  shard_values = [shard_values]  unless Array === shard_values
  @shard_proc.call(shard_values, @insert_with_shards_count, self) || _all_shards
end

#_detect_shards(keys) ⇒ Object



118
119
120
# File 'lib/tarantool/shards_support.rb', line 118

def _detect_shards(keys)
  _flat_uniq keys.map{|key| _detect_shard(key)}
end

#_detect_shards_for_insert(keys) ⇒ Object



122
123
124
# File 'lib/tarantool/shards_support.rb', line 122

def _detect_shards_for_insert(keys)
  _flat_uniq keys.map{|key| _detect_shard_for_insert(key)}
end

#_detect_shards_for_key(key, index_no) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/tarantool/shards_support.rb', line 108

def _detect_shards_for_key(key, index_no)
  if index_no == @shard_by_index
    _detect_shard(key)
  elsif pos = @shard_for_index[index_no]
    _detect_shard(key.values_at(*pos))
  else
    _all_shards
  end
end

#_detect_shards_for_keys(keys, index_no) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/tarantool/shards_support.rb', line 94

def _detect_shards_for_keys(keys, index_no)
  return _detect_shards_for_key(keys, index_no)  unless Array === keys
  if index_no == @shard_by_index && (
        @index_fields.size == 1 ||
        keys.all?{|key| Array === key && key.size == @index_fields.size}
      )
    _flat_uniq keys.map{|key| _detect_shard(key)}
  elsif pos = @shard_for_index[index_no]
    _flat_uniq keys.map{|key| _detect_shard([*key].values_at(*pos)) }
  else
    _all_shards
  end
end

#_detect_type(value) ⇒ Object



404
405
406
407
408
# File 'lib/tarantool/request.rb', line 404

def _detect_type(value)
  Integer === v ? :varint :
  Util::AutoType === v ? :auto :
  :string
end

#_detect_types(values) ⇒ Object



400
401
402
# File 'lib/tarantool/request.rb', line 400

def _detect_types(values)
  values.map{|v| Integer === v ? :varint : :string}
end

#_flat_uniq(array) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/tarantool/shards_support.rb', line 126

def _flat_uniq(array)
  hsh = {}
  array.each do |v|
    if v.respond_to?(:each)
      v.each{|vv| hsh[vv] = true}
    else
      hsh[v] = true
    end
  end
  hsh.keys
end

#_get_shard_numsObject



153
154
155
# File 'lib/tarantool/shards_support.rb', line 153

def _get_shard_nums
  @shards_count == 1 ? @default_shard : yield
end

#_init_shard_vars(shard_proc, init_shard_for_index = true) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/tarantool/shards_support.rb', line 61

def _init_shard_vars(shard_proc, init_shard_for_index = true)
  if init_shard_for_index
    @shard_by_index = @index_fields.index{|index| index == @shard_fields}
    @shard_for_index = @index_fields.map{|index|
        if (pos = @shard_fields.map{|name| index.index(name)}).any?
          pos.map{|i| i || 2**30}
        end
    }
    @shard_proc = case shard_proc
                  when nil, :default
                    DefaultShardProc.new
                  when :sumbur_murmur_fmix
                    SumburMurmurFmix.new
                  when :sumbur_murmur_int64
                    SumburMurmurInt64.new
                  when :sumbur_murmur_str
                    SumburMurmurStr.new
                  when :modulo, :module
                    ModuloShardProc.new
                  else
                    unless shard_proc.respond_to?(:call)
                      raise ArgumentError, "Wrong sharding proc object #{shard_proc.inspect}"
                    end
                    shard_proc
                  end
  end

  @shards_count = @tarantool.shards_count
  @previous_shards_count = @tarantool.previous_shards_count
  @insert_with_shards_count = @tarantool.insert_with_shards_count
  @default_shard = 0
end

#_insert(space_no, flags, tuple, fields, cb, ret_tuple, shard_nums, in_any_shard = nil, translators = []) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/tarantool/request.rb', line 190

def _insert(space_no, flags, tuple, fields, cb, ret_tuple, shard_nums, in_any_shard = nil, translators = [])
  flags |= BOX_RETURN_TUPLE  if ret_tuple
  fields = [*fields]

  tuple = [*tuple]
  body = ::BinUtils.append_int32_le!(nil, space_no, flags)
  pack_tuple(body, tuple, fields, :space)

  _modify_request(REQUEST_INSERT, body, fields, ret_tuple, cb, shard_nums,
                  in_any_shard ? :replace : :write, translators)
end

#_modify_request(type, body, fields, ret_tuple, cb, shard_nums, read_write, translators) ⇒ Object



183
184
185
186
187
# File 'lib/tarantool/request.rb', line 183

def _modify_request(type, body, fields, ret_tuple, cb, shard_nums, read_write, translators)
  response = Response.new(cb, type, body, ret_tuple && (ret_tuple != :all ? :first : :all),
                        fields, translators)
  _send_request(shard_nums, read_write, response)
end

#_pack_operations(body, operations, fields) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/tarantool/request.rb', line 218

def _pack_operations(body, operations, fields)
  if Integer === fields.last
    *fields, tail = fields
  else
    tail = 1
  end
  for operation in operations
    if Array === operation[0]
      operation = operation[0] + operation.drop(1)
    elsif Array === operation[1]
      if operation.size == 2
        operation = [operation[0]] + operation[1]
      else
        raise ArgumentError, "Could not understand operation #{operation}"
      end
    end

    field_no = operation[0]
    if operation.size == 2
      if (Integer === field_no || field_no =~ /\A\d/)
        unless Symbol === operation[1] && UPDATE_OPS[operation[1]] == 6
          ::BinUtils.append_int32_int8_le!(body, field_no, 0)
          type = fields[field_no] || get_tail_item(fields, field_no, tail) ||
            _detect_type(operation[1])
          pack_field(body, type, operation[1])
          next
        end
      elsif String === field_no
        operation.insert(1, field_no.slice(0, 1))
        field_no = field_no.slice(1..-1).to_i
      else
        raise ArgumentError, "Could not understand field number #{field_no.inspect}"
      end
    end

    op = operation[1]
    op = UPDATE_OPS[op]  unless Integer === op
    raise ArgumentError, "Unknown operation #{operation[1]}" unless op
    case op
    when 0
      ::BinUtils.append_int32_int8_le!(body, field_no, op)
      if (type = fields[field_no]).nil?
        if operation.size == 4 && Symbol === operation.last
          *operation, type = operation
        else
          type = get_tail_item(fields, field_no, tail) || _detect_type(operation[2])
        end
      end
      unless operation.size == 3
        raise ArgumentError, "wrong arguments for set or insert operation #{operation.inspect}"
      end
      pack_field(body, type, operation[2])
    when 1, 2, 3, 4
      ::BinUtils.append_int32_int8_le!(body, field_no, op)
      unless operation.size == 3 && !operation[2].nil?
        raise ArgumentError, "wrong arguments for integer operation #{operation.inspect}"
      end
      pack_field(body, :sint, operation[2])
    when 5
      ::BinUtils.append_int32_int8_le!(body, field_no, op)
      unless operation.size == 5 && !operation[2].nil? && !operation[3].nil?
        raise ArgumentError, "wrong arguments for slice operation #{operation.inspect}"
      end

      str = operation[4].to_s
      ::BinUtils.append_ber!(body, 10 + ber_size(str.bytesize) + str.bytesize)
      ::BinUtils.append_bersize_int32_le!(body, operation[2].to_i)
      ::BinUtils.append_bersize_int32_le!(body, operation[3].to_i)
      ::BinUtils.append_bersize_string!(body, str.to_s)
    when 7
      old_field_no = field_no +
        (inserted ||= []).count{|i| i <= field_no} -
        (deleted ||= []).count{|i| i <= field_no}
      ::BinUtils.append_int32_int8_le!(body, old_field_no, op)
      inserted << field_no
      if (type = fields[old_field_no]).nil?
        if operation.size == 4 && Symbol === operation.last
          *operation, type = operation
        else
          type = get_tail_item(fields, old_field_no, tail)
        end
      end
      unless operation.size == 3
        raise ArgumentError, "wrong arguments for set or insert operation #{operation.inspect}"
      end
      pack_field(body, type, operation[2])
    when 6
      old_field_no = field_no +
        (inserted ||= []).count{|i| i <= field_no} -
        (deleted ||= []).count{|i| i <= field_no}
      ::BinUtils.append_int32_int8_le!(body, old_field_no, op)
      deleted << field_no
      body << ZERO
      # pass
    end
  end
end

#_parse_hash_definition(returns) ⇒ Object



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/tarantool/request.rb', line 410

def _parse_hash_definition(returns)
  field_names = []
  field_types = []
  returns.each{|name, type|
    field_names << name
    field_types << type
  }
  field_types << if field_names.include?(:_tail)
      unless field_names.last == :_tail
        raise ArgumentError, "_tail should be de declared last"
      end
      field_names.pop
      [*field_types.last].size
    else
      1
    end
  field_types.flatten!
  [field_types, TranslateToHash.new(field_names, field_types.last)]
end

#_ping(cb) ⇒ Object Also known as: ping_cb



395
396
397
# File 'lib/tarantool/request.rb', line 395

def _ping(cb)
  _send_request(all_shards, :write, REQUEST_PING, EMPTY, WrapPing.new(cb))
end

#_raise_integer_overflow(value, min, max) ⇒ Object



179
180
181
# File 'lib/tarantool/request.rb', line 179

def _raise_integer_overflow(value, min, max)
    raise IntegerFieldOverflow, "#{value} not in (#{min}..#{max})"
end

#_raise_or_return(res) ⇒ Object



430
431
432
433
# File 'lib/tarantool/request.rb', line 430

def _raise_or_return(res)
  raise res  if Exception === res
  res
end

#_select(space_no, index_no, offset, limit, keys, cb, fields, index_fields, shard_nums, translators = []) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/tarantool/request.rb', line 63

def _select(space_no, index_no, offset, limit, keys, cb, fields, index_fields, shard_nums, translators = [])
  get_tuples = limit == :first ? (limit = 1; :first) : :all
  keys = [*keys]
  body = ::BinUtils.append_int32_le!(nil, space_no, index_no, offset, limit, keys.size)

  for key in keys
    pack_tuple(body, key, index_fields, index_no)
  end
  response = Response.new(cb, REQUEST_SELECT, body, get_tuples, fields, translators)
  _send_request(shard_nums, :read, response)
end

#_send_request(shard_numbers, read_write, cb) ⇒ Object



58
59
60
# File 'lib/tarantool/request.rb', line 58

def _send_request(shard_numbers, read_write, cb)
  @tarantool._send_request(shard_numbers, read_write, cb)
end

#_space_call_fix_values(values, space_no, opts) ⇒ Object



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/tarantool/request.rb', line 325

def _space_call_fix_values(values, space_no, opts)
  opts = opts.dup
  space_no = opts[:space_no]  if opts.has_key?(:space_no)
  if space_no
    values = [space_no].concat([*values])
    if opts[:types]
      opts[:types] = [:string].concat([*opts[:types]]) # cause lua could convert it to integer by itself
    else
      opts[:types] = TYPES_STR_STR
    end
  end

  # scheck for shards hints
  opts[:shards] ||= _get_shard_nums do
      if opts[:shard_for_insert]
        opts[:shard_keys] ? _detect_shards_for_insert(opts[:shard_keys]) :
        opts[:shard_key]  ? _detect_shard_for_insert( opts[:shard_key]) :
                             _all_shards
      else
        opts[:shard_keys] ? _detect_shards(opts[:shard_keys]) :
        opts[:shard_key]  ? _detect_shard( opts[:shard_key]) :
                             _all_shards
      end
    end
  [values, opts]
end

#_update(space_no, pk, operations, fields, pk_fields, cb, ret_tuple, shard_nums, translators = []) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/tarantool/request.rb', line 202

def _update(space_no, pk, operations, fields, pk_fields, cb, ret_tuple, shard_nums, translators = [])
  flags = ret_tuple ? BOX_RETURN_TUPLE : 0

  if Array === operations && !(Array === operations.first)
    operations = [operations]
  end

  body = ::BinUtils.append_int32_le!(nil, space_no, flags)
  pack_tuple(body, pk, pk_fields, 0)
  ::BinUtils.append_int32_le!(body, operations.size)

  _pack_operations(body, operations, fields)

  _modify_request(REQUEST_UPDATE, body, fields, ret_tuple, cb, shard_nums, :write, translators)
end

#all_shardsObject



177
178
179
# File 'lib/tarantool/shards_support.rb', line 177

def all_shards
  @shards_count == 1 ? @default_shard : (0...@shards_count).to_a
end

#detect_shard(shard_values) ⇒ Object



161
162
163
# File 'lib/tarantool/shards_support.rb', line 161

def detect_shard(shard_values)
  @shards_count == 1 ? @default_shard : _detect_shard(shard_values)
end

#detect_shard_for_insert(shard_values) ⇒ Object



165
166
167
# File 'lib/tarantool/shards_support.rb', line 165

def detect_shard_for_insert(shard_values)
  @shards_count == 1 ? @default_shard : _detect_shard_for_insert(shard_values)
end

#detect_shards(shard_values) ⇒ Object



169
170
171
# File 'lib/tarantool/shards_support.rb', line 169

def detect_shards(shard_values)
  @shards_count == 1 ? @default_shard : _detect_shards(shard_values)
end

#detect_shards_for_insert(shard_values) ⇒ Object



173
174
175
# File 'lib/tarantool/shards_support.rb', line 173

def detect_shards_for_insert(shard_values)
  @shards_count == 1 ? @default_shard : _detect_shards_for_insert(shard_values)
end

#pack_field(body, field_kind, value) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/tarantool/request.rb', line 105

def pack_field(body, field_kind, value)
  if value.nil?
    body << ZERO
    return
  end
  case field_kind
  when :int, :integer
    value = value.to_i
    _raise_integer_overflow(value, MIN_INT, MAX_INT32)  if value > MAX_INT32 or value < 0
    ::BinUtils.append_bersize_int32_le!(body, value)
  when :string, :bytes, :str
    value = value.to_s
    value = ZERO + value  if value < ONE
    raise StringTooLong  if value.bytesize >= MAX_BYTE_SIZE
    ::BinUtils.append_bersize_string!(body, value)
  when :bytes
    value = value.to_s
    raise StringTooLong  if value.bytesize >= MAX_BYTE_SIZE
    ::BinUtils.append_bersize_string!(body, value)
  when :int64
    value = value.to_i
    _raise_integer_overflow(value, MIN_INT, MAX_INT64)  if value > MAX_INT64 or value < 0
    ::BinUtils.append_bersize_int64_le!(body, value)
  when :int16
    value = value.to_i
    _raise_integer_overflow(value, MIN_INT, MAX_INT16)  if value > MAX_INT16 or value < 0
    ::BinUtils.append_bersize_int16_le!(body, value)
  when :int8
    value = value.to_i
    _raise_integer_overflow(value, MIN_INT, MAX_INT8)  if value > MAX_INT8 or value < 0
    ::BinUtils.append_bersize_int8!(body, value)
  when :sint
    value = value.to_i
    _raise_integer_overflow(value, MIN_SINT32, MAX_SINT32)  if value > MAX_SINT32 or value < MIN_SINT32
    ::BinUtils.append_bersize_int32_le!(body, value)
  when :sint64
    value = value.to_i
    _raise_integer_overflow(value, MIN_SINT64, MAX_SINT64)  if value > MAX_SINT64 or value < MIN_SINT64
    ::BinUtils.append_bersize_int64_le!(body, value)
  when :sint16
    value = value.to_i
    _raise_integer_overflow(value, MIN_SINT16, MAX_SINT16)  if value > MAX_SINT16 or value < MIN_SINT16
    ::BinUtils.append_bersize_int16_le!(body, value)
  when :sint8
    value = value.to_i
    _raise_integer_overflow(value, MIN_SINT8, MAX_SINT8)  if value > MAX_SINT8 or value < MIN_SINT8
    ::BinUtils.append_bersize_int8!(body, value)
  when :varint
    value = value.to_i
    if 0 <= value && value < MAX_INT32
      ::BinUtils.append_bersize_int32_le!(body, value)
    else
      ::BinUtils.append_bersize_int64_le!(body, value)
    end
  when :error
    raise IndexIndexError
  when :auto
    case value
    when Integer
      pack_field(body, :varint, value)
    when String
      pack_field(body, :bytes, value)
    when Util::AutoType
      pack_field(body, :bytes, value.data)
    else
      raise ArgumentError, "Could auto detect only Integer and String"
    end
  else
    value = get_serializer(field_kind).encode(value).to_s
    raise StringTooLong  if value.bytesize > MAX_BYTE_SIZE
    ::BinUtils.append_bersize_string!(body, value)
  end
end

#pack_tuple(body, key, types, index_no = 0) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/tarantool/request.rb', line 76

def pack_tuple(body, key, types, index_no = 0)
  if Integer === types.last
    *types, tail = types
  else
    tail = 1
  end
  case key
  when Array
    if index_no != :space && nili = key.index(nil)
      key = key.slice(0, nili)
    end
    ::BinUtils.append_int32_le!(body, key_size = key.size)
    i = 0
    while i < key_size
      field = types[i] || get_tail_item(types, i, tail)
      pack_field(body, field, key[i])
      i += 1
    end
  when nil
    body << INT32_0
  else
    body << INT32_1
    pack_field(body, types[0], key)
  end
rescue IndexIndexError
  raise ArgumentError, "tuple #{key} has more entries than index #{index_no}"
end

#shard(shard_number) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/tarantool/shards_support.rb', line 181

def shard(shard_number)
  case shard_number
  when Integer
    if shard_number >= @shards_count
      raise ArgumentError, "There is no shard #{shard_number}, amount of shards is #{@shards_count}"
    end
  when Array
    shard_number.each do|i|
      if i >= @shards_count
        raise ArgumentError, "There is no shard #{i}, amount of shards is #{@shards_count}"
      end
    end
  else
    raise ArgumentError, "Shard number should be integer or array of integers"
  end
  (@_fixed_shards ||= {})[shard_number] ||=
      clone.instance_exec do
        @shards_count = 1
        @default_shard = shard_number
        self
      end
end