lib/vertica/row_description.rb in vertica-1.0.0.rc1 vs lib/vertica/row_description.rb in vertica-1.0.0.rc2

- old
+ new

@@ -1,12 +1,23 @@ +# Class that describes the shape of a query result. It contains an ordered list +# of {Vertica::Column} instances, which describes the columns that will apear for +# every {Vertica::Row} part of the result of a query. +# +# @see Vertica::Row +# @see Vertica::Result class Vertica::RowDescription include Enumerable + # Builds a new Vertica::RowDescription instance given a list of columns. + # @param columns [Vertica::Protocol::RowDescription, Vertica::RowDescription, Array<Vertica::Column>] + # An object that describes the list of columns. + # @return [Vertica::RowDescription] + # @raise [ArgumentError] If no Vertica::RowDescription could be constructed given the provided argument. def self.build(columns) case columns when Vertica::Protocol::RowDescription - new(columns.fields.map { |fd| Vertica::Column.new(fd) }) + new(columns.fields.map { |fd| Vertica::Column.build(fd) }) when Vertica::RowDescription columns when Array new(columns) when nil @@ -14,53 +25,88 @@ else raise ArgumentError, "Invalid list of columns: #{columns.inspect}" end end + # @param columns [Array<Vertica::Column>] The list of columns as they will + # appear in the rows of a query result. + # @see Vertica::RowDescription.build def initialize(columns) @columns = columns end + # Returns a column in this row description. + # @param name_or_index [String, Symbol, Integer] The name of the column, or + # the index of the column in this row description. + # @return [Vertica::Column] + # @raise [KeyError] if the column could not be found in this row description. def column(name_or_index) column_with_index(name_or_index).first end alias_method :[], :column + # Returns a column, accompanied by the index of that column in this row description. + # @param name_or_index [String, Symbol, Integer] The name of the column, or + # the index of the column in this row description. + # @return [Array<Vertica::Column, Integer>] + # @raise [KeyError] if the column could not be found in this row description. def column_with_index(name_or_index) columns_index.fetch(name_or_index) end + # Iterates over the columns in this row description. + # @yield The provided block will be called with every column. + # @yieldparam column [Vertica::Column] + # @return [void] def each(&block) @columns.each(&block) end + # @return [Integer] Returns the number of columns in this row description. def size @columns.size end alias_method :length, :size + # @return [Array<Vertica::Column>] Returns the columns of this row description as an array. def to_a @columns.clone end + # @param symbolize_keys [Boolean] Whether to use symbols instead of strings as keys. + # @return [Hash] Returns the columns of this row description as a hash, index by the + # column name. + # @raise [Vertica::Error::DuplicateColumnName] If the row description contains multiple + # columns with the same name def to_h(symbolize_keys: false) @columns.inject({}) do |carry, column| key = symbolize_keys ? column.name.to_sym : column.name - carry.merge(key => column) + raise Vertica::Error::DuplicateColumnName, "Column with name #{key} occurs more than once in this row description." if carry.key?(key) + carry[key] = column + carry end end + # Builds a {Vertica::Row} instance given a list of values that conforms to + # this row description. + # @param [Array, Hash, Vertica::Protocol::DataRow] values A list of values. The number + # of values should match the number of columns in the row description. + # @raise [ArgumentError] An ArgumentErrpr is raised if the number of values does not match + # the row description, or if a type is provided that it cannot handle. + # @return [Vertica::Row] The row instance. def build_row(values) case values when Vertica::Row + raise ArgumentError, "Row description of provided row does match this row description" if values.row_description != self values when Vertica::Protocol::DataRow + raise ArgumentError, "Number of values does not match row description" if values.values.size != size converted_values = @columns.map.with_index do |column, index| - column.convert(values.values.fetch(index)) + column.data_type.deserialize(values.values.fetch(index)) end Vertica::Row.new(self, converted_values) when Array raise ArgumentError, "Number of values does not match row description" if values.size != size @@ -74,17 +120,24 @@ else raise ArgumentError, "Don't know how to build a row from a #{values.class.name} instance" end end + # @return [Boolean] Returns true iff this record is equal to the other provided object def eql?(other) self.class === other && other.to_a == self.to_a end alias_method :==, :eql? + # @return [Integer] Returns a hash digtest of this object. def hash @columns.hash + end + + # @return [String] Returns a user-consumable string representation of this row description. + def inspect + "#<#{self.class.name}[#{@columns.map(&:name).join(', ')}]>" end protected def columns_index