Class: DBI::Row
- Inherits:
-
Array
- Object
- Array
- DBI::Row
- Defined in:
- lib/dbi/row.rb
Overview
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.
Instance Attribute Summary collapse
-
#column_names ⇒ Object
(also: #field_names)
readonly
Returns the value of attribute column_names.
Instance Method Summary collapse
-
#[](*args) ⇒ Object
Row#[].
-
#[]=(key, value_or_length, obj = nil) ⇒ Object
Assign a value to a Row object by element.
- #__getobj__ ⇒ Object
- #__setobj__(obj) ⇒ Object
-
#by_field(field_name) ⇒ Object
Value of the field named
field_name
or nil if not found. -
#by_index(index) ⇒ Object
Retrieve a value by index (rather than name).
-
#clone ⇒ Object
See Object#clone.
-
#clone_with(new_values) ⇒ Object
Create a new row with ‘new_values’, reusing the field name hash.
-
#convert_types(arr) ⇒ Object
converts the types in the array to their specified representation from column types provided at construction time.
- #dup ⇒ Object
-
#each_with_name ⇒ Object
Yields a column value by name (rather than index), along with the column name itself.
-
#initialize(columns, column_types, size_or_array = nil, convert_types = true) ⇒ Row
constructor
DBI::Row.new(columns, column_types, size_or_array=nil).
-
#set_values(new_values) ⇒ Object
Replaces the contents of the internal array with
new_values
. -
#to_a ⇒ Object
returns the underlying array (duplicated).
-
#to_h ⇒ Object
Returns the Row object as a hash, created by #each_with_name.
Constructor Details
#initialize(columns, column_types, size_or_array = nil, convert_types = true) ⇒ Row
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).
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/dbi/row.rb', line 33 def initialize(columns, column_types, size_or_array=nil, convert_types=true) @column_types = column_types @convert_types = convert_types size_or_array ||= columns.size # The '@column_map' is used to map column names to integer values so # that users can reference row values by name or number. @column_map = {} @column_names = columns columns.each_with_index { |c,i| @column_map[c] = i } case size_or_array when Integer super(@arr = Array.new(size_or_array)) when Array super(@arr = size_or_array.dup) set_values(size_or_array.dup) else raise TypeError, "parameter must be either Integer or Array" end end |
Instance Attribute Details
#column_names ⇒ Object (readonly) Also known as: field_names
Returns the value of attribute column_names.
17 18 19 |
# File 'lib/dbi/row.rb', line 17 def column_names @column_names end |
Instance Method Details
#[](*args) ⇒ Object
Row#[]
row row row row[arg, arg] row[arg, arg, …]
Sample: Row.new(, [“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.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/dbi/row.rb', line 157 def [](*args) begin case args.length when 0 err = "wrong # of arguments(#{args.size} for at least 1)" raise ArgumentError, err when 1 case args[0] when Array args[0].collect { |e| self[e] } when Regexp self[@column_names.grep(args[0])] else @arr[conv_param(args[0])] end # We explicitly check for a length of 2 in order to properly # simulate the second form of Array#[]. when 2 @arr[conv_param(args[0]), conv_param(args[1])] else results = [] args.flatten.each{ |arg| case arg when Integer results.push(@arr[arg]) when Regexp results.push(self[@column_names.grep(arg)]) else results.push(self[conv_param(arg)]) end } results.flatten end rescue TypeError nil end end |
#[]=(key, value_or_length, obj = nil) ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/dbi/row.rb', line 203 def []=(key, value_or_length, obj=nil) if obj @arr[conv_param(key), conv_param(value_or_length)] = obj else @arr[conv_param(key)] = value_or_length end end |
#__getobj__ ⇒ Object
213 214 215 |
# File 'lib/dbi/row.rb', line 213 def __getobj__ @arr end |
#__setobj__(obj) ⇒ Object
217 218 219 |
# File 'lib/dbi/row.rb', line 217 def __setobj__(obj) @delegate_dc_obj = @arr = obj end |
#by_field(field_name) ⇒ Object
Value of the field named field_name
or nil if not found.
117 118 119 120 121 122 123 |
# File 'lib/dbi/row.rb', line 117 def by_field(field_name) begin @arr[@column_map[field_name.to_s]] rescue TypeError nil end end |
#by_index(index) ⇒ Object
Retrieve a value by index (rather than name).
Deprecated. Since Row delegates to Array, just use Row#at.
112 113 114 |
# File 'lib/dbi/row.rb', line 112 def by_index(index) @arr[index] end |
#clone ⇒ Object
See Object#clone.
#clone and #dup here, however, are both deep copies via Marshal.
226 227 228 |
# File 'lib/dbi/row.rb', line 226 def clone Marshal.load(Marshal.dump(self)) end |
#clone_with(new_values) ⇒ Object
Create a new row with ‘new_values’, reusing the field name hash. Initial cloning is done deeply, via Marshal.
100 101 102 103 104 105 |
# File 'lib/dbi/row.rb', line 100 def clone_with(new_values) obj = clone obj.set_values(new_values) return obj end |
#convert_types(arr) ⇒ Object
converts the types in the array to their specified representation from column types provided at construction time.
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/dbi/row.rb', line 58 def convert_types(arr) return arr.dup unless @convert_types if arr.size != @column_types.size raise TypeError, "Type mapping is not consistent with result" end new_arr = [] arr.each_with_index do |item, i| new_arr.push((@column_types[i] || DBI::Type::Varchar).parse(item)) end return new_arr end |
#dup ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/dbi/row.rb', line 230 def dup row = self.class.allocate row.instance_variable_set :@column_types, @column_types row.instance_variable_set :@convert_types, @convert_types row.instance_variable_set :@column_map, @column_map row.instance_variable_set :@column_names, @column_names # this is the only one we actually dup... row.instance_variable_set :@arr, arr = @arr.dup row.instance_variable_set :@_dc_obj, arr row end |
#each_with_name ⇒ Object
Yields a column value by name (rather than index), along with the column name itself.
80 81 82 83 84 |
# File 'lib/dbi/row.rb', line 80 def each_with_name @arr.each_with_index do |v, i| yield v, @column_names[i] end end |
#set_values(new_values) ⇒ Object
Replaces the contents of the internal array with new_values
. elements are type converted at this time.
74 75 76 |
# File 'lib/dbi/row.rb', line 74 def set_values(new_values) @arr.replace(convert_types(new_values)) end |
#to_a ⇒ Object
returns the underlying array (duplicated)
87 88 89 |
# File 'lib/dbi/row.rb', line 87 def to_a @arr.dup end |
#to_h ⇒ Object
Returns the Row object as a hash, created by #each_with_name.
92 93 94 95 96 |
# File 'lib/dbi/row.rb', line 92 def to_h hash = {} each_with_name{ |v, n| hash[n] = v} hash end |