archan937/clickhouse

View on GitHub
lib/clickhouse/connection/query/result_set.rb

Summary

Maintainability
A
0 mins
Test Coverage
module Clickhouse
  class Connection
    module Query
      class ResultSet
        include Enumerable
        extend Forwardable

        def_delegators :@rows, :size, :empty?
        def_delegators :to_a, :first, :last, :flatten

        attr_reader :names, :types

        def initialize(rows = [], names = nil, types = nil)
          @rows = rows
          @names = names
          @types = types
        end

        def each
          (0..(size - 1)).collect do |index|
            yield self[index]
            self[index]
          end
        end

        def [](index)
          row = @rows[index]
          row = @rows[index] = parse_row(row) if row.class == Array
          row
        end

        def present?
          !empty?
        end

        def to_hashes(symbolize = false)
          collect{|row| row.to_hash(symbolize)}
        end

      private

        def parse_row(array)
          values = array.each_with_index.to_a.collect do |value, i|
            parse_value(@types[i], value) if @types
          end
          ResultRow.new values, @names
        end

        def parse_value(type, value)
          if value
            case type
            when "UInt8", "UInt16", "UInt32", "UInt64", "Int8", "Int16", "Int32", "Int64"
              parse_int_value value
            when "Float32", "Float64"
              parse_float_value value
            when "String", "Enum8", "Enum16"
              parse_string_value value
            when /FixedString\(\d+\)/
              parse_fixed_string_value value
            when "Date"
              parse_date_value value
            when "DateTime"
              parse_date_time_value value
            when /Array\(/
              parse_array_value value
            else
              raise NotImplementedError, "Cannot parse value of type #{type.inspect}"
            end
          end
        end

        def parse_int_value(value)
          value.to_i
        end

        def parse_float_value(value)
          value.to_f
        end

        def parse_string_value(value)
          value.force_encoding("UTF-8")
        end

        def parse_fixed_string_value(value)
          value.delete("\000").force_encoding("UTF-8")
        end

        def parse_date_value(value)
          Date.parse(value)
        end

        def parse_date_time_value(value)
          Time.parse(value)
        end

        def parse_array_value(value)
          value
        end

      end
    end
  end
end