lib/chair/row.rb in chair-1.0.2 vs lib/chair/row.rb in chair-1.1.0

- old
+ new

@@ -1,62 +1,108 @@ -class Row +class Chair::Row + include Comparable # Create a new cell # @param table [Table] the table holding this row - # @param id [Fixnum] the array index of this row in the interal 2D array - def initialize(table, id) + # @param id [Fixnum] the array index of this row in the internal 2D array + def initialize(table, id, data = {}) @row_id = id @table = table - @row = [] + @attributes = data + @attributes.clone. + keep_if{ |col, _| @table.indices.include? col }. + each_pair{ |col, val| add_to_index(col, val) } end # Get a cell based on the column name # @return [Object, nil] the value in the cell, can be nil - def [](col) - idx = @table.send(:get_column_id, col) - @row[idx] + def [](column) + @attributes[column] end # Assign a new value to one of the cells in the row - # @param col [Symbol] the column name to add to + # @param column [Symbol] the column name to add to # @param value [Object] the value to assign # @return [Object] the assigned value - def []=(col, value) - idx = @table.send(:get_column_id, col) - if @table.indices.include? col - if @table.instance_variable_get("@#{col}_index_map".to_sym)[value].nil? - @table.instance_variable_get("@#{col}_index_map".to_sym)[value] = Set.new - end - @table.instance_variable_get("@#{col}_index_map")[value] = - @table.instance_variable_get("@#{col}_index_map")[value] << @row_id + def []=(column, value) + if @table.indices.include? column + add_to_index(column, value) end - @row[idx] = value + @attributes[column] = value end def empty? - @row.empty? + @attributes.empty? end # Create a hash of the data based on the columns # @return [Hash<Symbol, Object>] the data in the row def to_hash - map = {} - @table.columns.each do |col| - idx = @table.send(:get_column_id, col) - map[col] = row[idx] - end - map + @attributes end # Convert the row data to an array # @return [Array<Object>] the data in the row def to_a - @row + @table.columns.map { |col| @attributes[col] } end # Compare Row instances based on internal representation # @param other [Object] the object to compare to # @return [Bool] whether or not the objects are the same - def eql?(other) - @row.eql?(other.instance_variable_get("@row")) + def ==(other) + case other + when Chair::Row + @attributes == other.instance_variable_get('@attributes') + when Array + @attributes.values == other + else false + end + end + + # Compare rows within a table + # @param other [Object] the object to compare to + def <=>(other) + # only be comparable if we're in the same table + if @table.equal?(other.instance_variable_get(@table)) + other_id = other.instance_variable_get('@id') + @id <=> other_id + else + nil + end + end + + # Returns the contents of the record as a nicely formatted string. + def inspect + pairs = [] + # Use the table's column list to order our columns + @table.columns.each { |name| pairs << "#{name}: #{@attributes[name].inspect}"} + inspection = pairs.compact.join(', ') + "#<#{self.class} #{inspection}>" + end + + # Looks to see if we have a attribute + # @param name [Symbol] the column to look at + # @return [Bool] whether or not the value is empty + def has_attribute?(name) + val = @attributes[name] + val.nil? ? false : (not val.empty?) + end + + def method_missing(method_sym, *arguments, &block) + # the first argument is a Symbol, so you need to_s it if you want to pattern match + if method_sym.to_s =~ /^has_(.*)\?$/ + has_attribute?($1.to_sym) + else + super + end + end + + protected + def add_to_index(column, value) + if @table.instance_variable_get("@#{column}_index_map".to_sym)[value].nil? + @table.instance_variable_get("@#{column}_index_map".to_sym)[value] = Set.new + end + @table.instance_variable_get("@#{column}_index_map")[value] = + @table.instance_variable_get("@#{column}_index_map")[value] << @row_id end end