Class | DBI::Row |
In: |
lib/dbi/row.rb
|
Parent: | DelegateClass(Array) |
DBI::Row is the representation of a row in a result set returned by the database.
It is responsible for containing and representing the result set, converting it to native Ruby types, and providing methods to sanely move through itself.
The DBI::Row class is a delegate of Array, rather than a subclass, because there are times when it should act like an Array, and others when it should act like a Hash (and still others where it should act like String, Regexp, etc). It also needs to store metadata about the row, such as column data type and index information, that users can then access.
column_names | -> | field_names |
column_names | [R] |
DBI::Row.new(columns, column_types, size_or_array=nil)
Returns a new DBI::Row object using columns. The size_or_array argument may either be an Integer or an Array. If it is not provided, it defaults to the length of columns.
Column types is a corresponding Array of Class/Module objects that conform to the DBI::Type interface. These will be used to convert types as they are returned.
DBI::Row is a delegate of the Array class, so all of the Array instance methods are available to your DBI::Row object (keeping in mind that initialize, [], and []= have been explicitly overridden).
# File lib/dbi/row.rb, line 33 33: def initialize(columns, column_types, size_or_array=nil, convert_types=true) 34: @column_types = column_types 35: @convert_types = convert_types 36: size_or_array ||= columns.size 37: 38: # The '@column_map' is used to map column names to integer values so 39: # that users can reference row values by name or number. 40: 41: @column_map = {} 42: @column_names = columns 43: columns.each_with_index { |c,i| @column_map[c] = i } 44: 45: case size_or_array 46: when Integer 47: super(@arr = Array.new(size_or_array)) 48: when Array 49: super(@arr = size_or_array.dup) 50: set_values(size_or_array.dup) 51: else 52: raise TypeError, "parameter must be either Integer or Array" 53: end 54: end
Row#[]
row[int] row[array] row[regexp] row[arg, arg] row[arg, arg, …]
Sample: Row.new(["first","last","age"], ["Daniel", "Berger", "36"])
Retrieves row elements. Exactly what it retrieves depends on the kind and number of arguments used.
Zero arguments will raise an ArgumentError.
One argument will return a single result. This can be a String, Symbol, Integer, Range or Regexp and the appropriate result will be returned. Strings, Symbols and Regexps act like hash lookups, while Integers and Ranges act like Array index lookups.
Two arguments will act like the second form of Array#[], i.e it takes two integers, with the first number the starting point and the second number the length, and returns an array of values.
If three or more arguments are provided, an array of results is returned. The behavior for each argument is that of a single argument, i.e. Strings, Symbols, and Regexps act like hash lookups, while Integers and Ranges act like Array index lookups.
If no results are found, or an unhandled type is passed, then nil (or a nil element) is returned.
# File lib/dbi/row.rb, line 157 157: def [](*args) 158: begin 159: case args.length 160: when 0 161: err = "wrong # of arguments(#{args.size} for at least 1)" 162: raise ArgumentError, err 163: when 1 164: case args[0] 165: when Array 166: args[0].collect { |e| self[e] } 167: when Regexp 168: self[@column_names.grep(args[0])] 169: else 170: @arr[conv_param(args[0])] 171: end 172: # We explicitly check for a length of 2 in order to properly 173: # simulate the second form of Array#[]. 174: when 2 175: @arr[conv_param(args[0]), conv_param(args[1])] 176: else 177: results = [] 178: args.flatten.each{ |arg| 179: case arg 180: when Integer 181: results.push(@arr[arg]) 182: when Regexp 183: results.push(self[@column_names.grep(arg)]) 184: else 185: results.push(self[conv_param(arg)]) 186: end 187: } 188: results.flatten 189: end 190: rescue TypeError 191: nil 192: end 193: end
Assign a value to a Row object by element. You can assign using a single element reference, or by using a start and length similar to the second form of Array#[]=.
row[0] = "kirk" row[:last] = "haines" row[0, 2] = "test"
# File lib/dbi/row.rb, line 203 203: def []=(key, value_or_length, obj=nil) 204: if obj 205: @arr[conv_param(key), conv_param(value_or_length)] = obj 206: else 207: @arr[conv_param(key)] = value_or_length 208: end 209: end
# File lib/dbi/row.rb, line 217 217: def __setobj__(obj) 218: @delegate_dc_obj = @arr = obj 219: end
Value of the field named field_name or nil if not found.
# File lib/dbi/row.rb, line 117 117: def by_field(field_name) 118: begin 119: @arr[@column_map[field_name.to_s]] 120: rescue TypeError 121: nil 122: end 123: end
converts the types in the array to their specified representation from column types provided at construction time.
# File lib/dbi/row.rb, line 58 58: def convert_types(arr) 59: return arr.dup unless @convert_types 60: 61: if arr.size != @column_types.size 62: raise TypeError, "Type mapping is not consistent with result" 63: end 64: new_arr = [] 65: arr.each_with_index do |item, i| 66: new_arr.push((@column_types[i] || DBI::Type::Varchar).parse(item)) 67: end 68: 69: return new_arr 70: end
Yields a column value by name (rather than index), along with the column name itself.
# File lib/dbi/row.rb, line 80 80: def each_with_name 81: @arr.each_with_index do |v, i| 82: yield v, @column_names[i] 83: end 84: end
Replaces the contents of the internal array with new_values. elements are type converted at this time.
# File lib/dbi/row.rb, line 74 74: def set_values(new_values) 75: @arr.replace(convert_types(new_values)) 76: end
returns the underlying array (duplicated)
# File lib/dbi/row.rb, line 87 87: def to_a 88: @arr.dup 89: end
Returns the Row object as a hash, created by each_with_name.
# File lib/dbi/row.rb, line 92 92: def to_h 93: hash = {} 94: each_with_name{ |v, n| hash[n] = v} 95: hash 96: end