class Tarantool16::SchemaSpace

Attributes

sid[RW]

Public Class Methods

new(sid, name, fields) click to toggle source
# File lib/tarantool16/schema.rb, line 6
def initialize(sid, name, fields)
  @sid = sid
  @name = name
  @has_tail = false
  self.fields = fields
end

Public Instance Methods

data() click to toggle source
# File lib/tarantool16/schema.rb, line 15
def data; self; end
fields=(flds) click to toggle source
# File lib/tarantool16/schema.rb, line 17
def fields=(flds)
  @field_names = {}
  @fields = []
  @has_tail = false
  flds.each_with_index do |fld, i; name|
    if @has_tail
      $stderr.puts "no fields allowed after tail: #{flds}"
      break
    end
    case fld
    when String, Symbol
      name = fld.to_s
      type = nil
    when Array
      name, type = fld
    when Hash
      name = fld['name'] || fld[:name]
      type = fld['type'] || fld[:type]
      tail = fld['tail'] || fld[:tail]
    end
    unless name.is_a?(String) || name.is_a?(Symbol)
      $stderr.puts "no field name found for field_#{i} in #{flds}"
      name = "field_#{i}"
    end
    name_s = name.to_sym
    name = name.to_s
    field = Field.new(name_s, i, type)
    @field_names[name] = field
    @field_names[name_s] = field
    @field_names[i] = field
    @fields << field
    @has_tail = true if tail
  end
  # refresh indices ?
  if @index_defs
    self.indices= @index_defs
  end
  flds
end
get_ino(ino, key, _iter, cb) { |_ino, map_key| ... } click to toggle source
# File lib/tarantool16/schema.rb, line 80
def get_ino(ino, key, _iter, cb)
  if ino.nil?
    unless key.is_a?(Hash)
      opt = Option.error(SchemaError, "Could not detect index without field names and iterator: #{key.inspect} in #{name_sid}")
      return cb.call(opt)
    end
    # key should be Hash here
    keys = key.keys
    keys << _iter
    _ino = @_fields_2_ino[keys]
    if _ino
      ind = @indices[_ino]
      return yield(_ino, ind.map_key(key))
    elsif _ino == false
      opt = Option.error(SchemaError, "Could not detect index for fields #{key.keys} in #{name_sid}")
      return cb.call(opt)
    end
    keys.pop
    iter = _iter.is_a?(Integer) ? _iter : ::Tarantool16.iter(iter)

    fields = keys.map{|fld|
      case fld
      when Integer
        fld
      when Symbol, String
        @field_names[fld].pos
      else
        return cb.call(Option.error(SchemaError, "Unknown field #{fld.inspect} in query key #{key.inspect}"))
      end
    }

    index = nil
    for ind in @indices
      next unless ind
      first_fields = ind.parts[0,fields.size]
      if ind.can_iterator?(iter, fields.size)
        if fields == first_fields
          index = ind
          break
        elsif (fields - first_fields).empty?
          index = ind
        end
      end
    end
    keys << _iter
    if index
      @_fields_2_ino[keys.freeze] = index.pos
      yield index.pos, index.map_key(key)
    else
      @_fields_2_ino[keys.freeze] = false
      cb.call(Option.error(SchemaError, "Could not detect index for fields #{key.keys} in #{name_sid}"))
    end
  elsif index = @index_names[ino]
    yield index.pos, index.map_key(key)
  else
    cb.call(Option.error(SchemaError, "Could not find index #{ino} for fields #{Hash===key ? key.keys : key.inspect} in #{name_sid}"))
  end
end
indices=(inds) click to toggle source
# File lib/tarantool16/schema.rb, line 57
def indices=(inds)
  @index_defs = inds
  @index_names = {}
  @indices = []
  @_fields_2_ino = {}
  inds.each do |name, nom, type, parts|
    if @fields && @fields.size > parts.max
      part_names = parts.map{|p| @fields[p].name}
    else
      part_names = []
    end
    index = Index.new(name, nom, type, parts, part_names)
    @index_names[name] = index
    @index_names[name.to_sym] = index
    @index_names[nom] = index
    @indices[nom] = index
  end
end
indices?() click to toggle source
# File lib/tarantool16/schema.rb, line 76
def indices?
  @indices && !@indices.empty?
end
map_ops(ops) click to toggle source
# File lib/tarantool16/schema.rb, line 190
def map_ops(ops)
  ops.map do |op|
    case op1 = op[1]
    when Integer
      op
    when Symbol, String
      _op = op.dup
      _op[1] = @field_names[op1].pos
      _op
    when Array
      fld_pos = case op[0]
            when Integer
              op[0]
            when Symbol, String
              @field_names[op[0]].pos
            else
              raise "No field #{op[0].inspect} in #{name_sid}"
            end
      op1.dup.insert(1, fld_pos)
    end
  end
end
map_tuple(tuple) click to toggle source
# File lib/tarantool16/schema.rb, line 164
def map_tuple(tuple)
  row = []
  unless @has_tail
    tuple.each_key do |k|
      field = @field_names[k]
      row[field.pos] = tuple[k]
    end
  else
    tail = @fields.last
    tuple.each do |k|
      field = @field_names[k]
      val = tuple[k]
      if field.equal? tail
        unless tail.type.is_a?(Array)
          row[field.pos,0] = val
        else
          row[field.pos,0] = val.flatten(1)
        end
      else
        row[field.pos] = tuple[k]
      end
    end
  end
  row
end
name_sid() click to toggle source
# File lib/tarantool16/schema.rb, line 160
def name_sid
  @_np ||= "space #{@name}:#{@sid}"
end
ok?() click to toggle source

imitate Option

# File lib/tarantool16/schema.rb, line 14
def ok?; true; end
tuple2hash(ar) click to toggle source
# File lib/tarantool16/schema.rb, line 139
def tuple2hash(ar)
  raise "No fields defined for #{name_sid}" unless @fields && !@fields.empty?
  res = {}
  i = 0
  flds = @fields
  s = flds.size - (@has_tail ? 1 : 0)
  while i < s
    res[flds[i].name] = ar[i]
    i += 1
  end
  if @has_tail
    tail = flds[s]
    unless tail.type.is_a?(Array)
      res[tail.name] = ar[s..-1]
    else
      res[tail.name] = ar[s..-1].each_slice(tail.type.size).to_a
    end
  end
  res
end
wrap_cb(cb) click to toggle source
# File lib/tarantool16/schema.rb, line 213
def wrap_cb(cb)
  CallbackWrapper.new(self, cb)
end