class Impala::Cursor

Cursors are used to iterate over result sets without loading them all into memory at once. This can be useful if you're dealing with lots of rows. It implements Enumerable, so you can use each/select/map/etc.

Constants

BUFFER_SIZE

Public Class Methods

new(handle, service) click to toggle source
# File lib/impala/cursor.rb, line 9
def initialize(handle, service)
  @handle = handle
  @service = service


  @row_buffer = []
  @done = false
  @open = true

  fetch_more
end

Public Instance Methods

close() click to toggle source

Close the cursor on the remote server. Once a cursor is closed, you can no longer fetch any rows from it.

# File lib/impala/cursor.rb, line 56
def close
  @open = false
  @service.close(@handle)
end
each() { |row| ... } click to toggle source
# File lib/impala/cursor.rb, line 25
def each
  while row = fetch_row
    yield row
  end
end
fetch_all() click to toggle source

Returns all the remaining rows in the result set. @return [Array<Hash>] the remaining rows in the result set @see fetch_one

# File lib/impala/cursor.rb, line 50
def fetch_all
  self.to_a
end
fetch_row() click to toggle source

Returns the next available row as a hash, or nil if there are none left. @return [Hash, nil] the next available row, or nil if there are none

left

@see fetch_all

# File lib/impala/cursor.rb, line 35
def fetch_row
  if @row_buffer.empty?
    if @done
      return nil
    else
      fetch_more
    end
  end

  @row_buffer.shift
end
has_more?() click to toggle source

Returns true if there are any more rows to fetch.

# File lib/impala/cursor.rb, line 67
def has_more?
  !@done || !@row_buffer.empty?
end
inspect() click to toggle source
# File lib/impala/cursor.rb, line 21
def inspect
  "#<#{self.class}#{open? ? '' : ' (CLOSED)'}>"
end
open?() click to toggle source

Returns true if the cursor is still open.

# File lib/impala/cursor.rb, line 62
def open?
  @open
end
runtime_profile() click to toggle source
# File lib/impala/cursor.rb, line 71
def runtime_profile
  @service.GetRuntimeProfile(@handle)
end

Private Instance Methods

convert_raw_value(value, schema) click to toggle source
# File lib/impala/cursor.rb, line 116
def convert_raw_value(value, schema)
  return nil if value == 'NULL'

  case schema.type
  when 'string'
    value
  when 'boolean'
    if value == 'true'
      true
    elsif value == 'false'
      false
    else
      raise ParsingError.new("Invalid value for boolean: #{value}")
    end
  when 'tinyint', 'smallint', 'int', 'bigint'
    value.to_i
  when 'double', 'float', 'decimal'
    value.to_f
  when "timestamp"
    Time.parse(value)
  else
    raise ParsingError.new("Unknown type: #{schema.type}")
  end
end
fetch_batch() click to toggle source
# File lib/impala/cursor.rb, line 85
def fetch_batch
  raise CursorError.new("Cursor has expired or been closed") unless @open

  begin
    res = @service.fetch(@handle, false, BUFFER_SIZE)
  rescue Protocol::Beeswax::BeeswaxException
    @open = false
    raise CursorError.new("Cursor has expired or been closed")
  end

  rows = res.data.map { |raw| parse_row(raw) }
  @row_buffer.concat(rows)

  unless res.has_more
    @done = true
    close
  end
end
fetch_more() click to toggle source
# File lib/impala/cursor.rb, line 81
def fetch_more
  fetch_batch until @done || @row_buffer.count >= BUFFER_SIZE
end
metadata() click to toggle source
# File lib/impala/cursor.rb, line 77
def metadata
  @metadata ||= @service.get_results_metadata(@handle)
end
parse_row(raw) click to toggle source
# File lib/impala/cursor.rb, line 104
def parse_row(raw)
  row = {}
  fields = raw.split(metadata.delim)

  metadata.schema.fieldSchemas.zip(fields).each do |schema, raw_value|
    value = convert_raw_value(raw_value, schema)
    row[schema.name.to_sym] = value
  end

  row
end