Class: DBI::DBD::Pg::Type::Array
- Inherits:
-
Object
- Object
- DBI::DBD::Pg::Type::Array
- Defined in:
- lib/dbd/pg/type.rb
Overview
PostgreSQL arrays are simply a specification that sits on top of normal types. They have a specialized string grammar and this class facilitates converting that syntax and the types within those arrays.
Instance Attribute Summary collapse
-
#base_type ⇒ Object
readonly
Returns the value of attribute base_type.
Instance Method Summary collapse
-
#convert_array(str) ⇒ Object
Parse a PostgreSQL-Array output and convert into ruby array.
-
#initialize(base_type) ⇒ Array
constructor
base_type
is a DBI::Type that is used to parse the inner types when a non-array one is found. -
#parse(obj) ⇒ Object
Object method.
Constructor Details
#initialize(base_type) ⇒ Array
base_type
is a DBI::Type that is used to parse the inner types when a non-array one is found.
For instance, if you had an array of integer, one would pass DBI::Type::Integer here.
99 100 101 |
# File 'lib/dbd/pg/type.rb', line 99 def initialize(base_type) @base_type = base_type end |
Instance Attribute Details
#base_type ⇒ Object (readonly)
Returns the value of attribute base_type.
90 91 92 |
# File 'lib/dbd/pg/type.rb', line 90 def base_type @base_type end |
Instance Method Details
#convert_array(str) ⇒ Object
Parse a PostgreSQL-Array output and convert into ruby array. This does the real parsing work.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/dbd/pg/type.rb', line 125 def convert_array(str) array_nesting = 0 # nesting level of the array in_string = false # currently inside a quoted string ? escaped = false # if the character is escaped sbuffer = '' # buffer for the current element result_array = ::Array.new # the resulting Array str.each_byte { |char| # parse character by character char = char.chr # we need the Character, not it's Integer if escaped then # if this character is escaped, just add it to the buffer sbuffer += char escaped = false next end case char # let's see what kind of character we have #------------- {: beginning of an array ----# when '{' if in_string then # ignore inside a string sbuffer += char next end if array_nesting >= 1 then # if it's an nested array, defer for recursion sbuffer += char end array_nesting += 1 # inside another array #------------- ": string deliminator --------# when '"' in_string = !in_string #------------- \: escape character, next is regular character # when "\\" # single \, must be extra escaped in Ruby if array_nesting > 1 sbuffer += char else escaped = true end #------------- ,: element separator ---------# when ',' if in_string or array_nesting > 1 then # don't care if inside string or sbuffer += char # nested array else if !sbuffer.is_a? ::Array then sbuffer = @base_type.parse(sbuffer) end result_array << sbuffer # otherwise, here ends an element sbuffer = '' end #------------- }: End of Array --------------# when '}' if in_string then # ignore if inside quoted string sbuffer += char next end array_nesting -=1 # decrease nesting level if array_nesting == 1 # must be the end of a nested array sbuffer += char sbuffer = convert_array( sbuffer ) # recurse, using the whole nested array elsif array_nesting > 1 # inside nested array, keep it for later sbuffer += char else # array_nesting = 0, must be the last } if !sbuffer.is_a? ::Array then sbuffer = @base_type.parse( sbuffer ) end result_array << sbuffer unless sbuffer.nil? # upto here was the last element end #------------- all other characters ---------# else sbuffer += char # simply append end } return result_array end |
#parse(obj) ⇒ Object
Object method. Please note that this is different than most DBI::Type classes! One must initialize an Array object with an appropriate DBI::Type used to convert the indices of the array before this method can be called.
Returns an appropriately converted array.
111 112 113 114 115 116 117 118 119 |
# File 'lib/dbd/pg/type.rb', line 111 def parse(obj) if obj.nil? nil elsif obj.index('{') == 0 and obj.rindex('}') == (obj.length - 1) convert_array(obj) else raise "Not an array" end end |