Module: Sequel::Postgres::PGArray::DatabaseMethods

Defined in:
lib/sequel/extensions/pg_array.rb

Constant Summary collapse

APOS =
"'".freeze
DOUBLE_APOS =
"''".freeze
ESCAPE_RE =
/("|\\)/.freeze
ESCAPE_REPLACEMENT =
'\\\\\1'.freeze
BLOB_RANGE =
1...-1

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(db) ⇒ Object

Create the local hash of database type strings to schema type symbols, used for array types local to this database.



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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/sequel/extensions/pg_array.rb', line 178

def self.extended(db)
  db.instance_eval do
    @pg_array_schema_types ||= {}
    procs = conversion_procs
    add_conversion_proc(1115, Creator.new("timestamp without time zone", procs[1114]))
    add_conversion_proc(1185, Creator.new("timestamp with time zone", procs[1184]))

    register_array_type('text', :oid=>1009, :scalar_oid=>25, :type_symbol=>:string)
    register_array_type('integer', :oid=>1007, :scalar_oid=>23)
    register_array_type('bigint', :oid=>1016, :scalar_oid=>20, :scalar_typecast=>:integer)
    register_array_type('numeric', :oid=>1231, :scalar_oid=>1700, :type_symbol=>:decimal)
    register_array_type('double precision', :oid=>1022, :scalar_oid=>701, :type_symbol=>:float)

    register_array_type('boolean', :oid=>1000, :scalar_oid=>16)
    register_array_type('bytea', :oid=>1001, :scalar_oid=>17, :type_symbol=>:blob)
    register_array_type('date', :oid=>1182, :scalar_oid=>1082)
    register_array_type('time without time zone', :oid=>1183, :scalar_oid=>1083, :type_symbol=>:time)
    register_array_type('time with time zone', :oid=>1270, :scalar_oid=>1083, :type_symbol=>:time_timezone, :scalar_typecast=>:time)

    register_array_type('smallint', :oid=>1005, :scalar_oid=>21, :scalar_typecast=>:integer)
    register_array_type('oid', :oid=>1028, :scalar_oid=>26, :scalar_typecast=>:integer)
    register_array_type('real', :oid=>1021, :scalar_oid=>700, :scalar_typecast=>:float)
    register_array_type('character', :oid=>1014, :converter=>nil, :array_type=>:text, :scalar_typecast=>:string)
    register_array_type('character varying', :oid=>1015, :converter=>nil, :scalar_typecast=>:string, :type_symbol=>:varchar)

    register_array_type('xml', :oid=>143, :scalar_oid=>142)
    register_array_type('money', :oid=>791, :scalar_oid=>790)
    register_array_type('bit', :oid=>1561, :scalar_oid=>1560)
    register_array_type('bit varying', :oid=>1563, :scalar_oid=>1562, :type_symbol=>:varbit)
    register_array_type('uuid', :oid=>2951, :scalar_oid=>2950)

    register_array_type('xid', :oid=>1011, :scalar_oid=>28)
    register_array_type('cid', :oid=>1012, :scalar_oid=>29)

    register_array_type('name', :oid=>1003, :scalar_oid=>19)
    register_array_type('tid', :oid=>1010, :scalar_oid=>27)
    register_array_type('int2vector', :oid=>1006, :scalar_oid=>22)
    register_array_type('oidvector', :oid=>1013, :scalar_oid=>30)

    [:string_array, :integer_array, :decimal_array, :float_array, :boolean_array, :blob_array, :date_array, :time_array, :datetime_array].each do |v|
      @schema_type_classes[v] = PGArray
    end
  end
end

Instance Method Details

#bound_variable_arg(arg, conn) ⇒ Object

Handle arrays in bound variables



224
225
226
227
228
229
230
231
232
233
# File 'lib/sequel/extensions/pg_array.rb', line 224

def bound_variable_arg(arg, conn)
  case arg
  when PGArray
    bound_variable_array(arg.to_a)
  when Array
    bound_variable_array(arg)
  else
    super
  end
end

#freezeObject

Freeze the pg array schema types to prevent adding new ones.



236
237
238
239
# File 'lib/sequel/extensions/pg_array.rb', line 236

def freeze
  @pg_array_schema_types.freeze
  super
end

#register_array_type(db_type, opts = OPTS, &block) ⇒ Object

Register a database specific array type. Options:

:array_type

The type to automatically cast the array to when literalizing the array. Usually the same as db_type.

:converter

A callable object (e.g. Proc), that is called with each element of the array (usually a string), and should return the appropriate typecasted object.

:oid

The PostgreSQL OID for the array type. This is used by the Sequel postgres adapter to set up automatic type conversion on retrieval from the database.

:scalar_oid

Should be the PostgreSQL OID for the scalar version of this array type. If given, automatically sets the :converter option by looking for scalar conversion proc.

:scalar_typecast

Should be a symbol indicating the typecast method that should be called on each element of the array, when a plain array is passed into a database typecast method. For example, for an array of integers, this could be set to :integer, so that the typecast_value_integer method is called on all of the array elements. Defaults to :type_symbol option.

:type_symbol

The base of the schema type symbol for this type. For example, if you provide :integer, Sequel will recognize this type as :integer_array during schema parsing. Defaults to the db_type argument.

If a block is given, it is treated as the :converter option.



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/sequel/extensions/pg_array.rb', line 262

def register_array_type(db_type, opts=OPTS, &block)
  # Only for convert_named_procs_to_procs usage
  type_procs = opts[:type_procs] || conversion_procs # SEQUEL5: Remove

  oid = opts[:oid]
  soid = opts[:scalar_oid]

  if has_converter = opts.has_key?(:converter)
    raise Error, "can't provide both a block and :converter option to register_array_type" if block
    converter = opts[:converter]
  else
    has_converter = true if block
    converter = block
  end

  unless (soid || has_converter) && oid
    array_oid, scalar_oid = from(:pg_type).where(:typname=>db_type.to_s).get([:typarray, :oid])
    soid ||= scalar_oid unless has_converter
    oid ||= array_oid
  end

  db_type = db_type.to_s
  type = (opts[:type_symbol] || db_type).to_sym
  typecast_method_map = @pg_array_schema_types

  if soid
    raise Error, "can't provide both a converter and :scalar_oid option to register" if has_converter 
    converter = type_procs[soid] # SEQUEL5: conversion_procs[soid]
  end

  array_type = (opts[:array_type] || db_type).to_s.dup.freeze
  creator = Creator.new(array_type, converter)
  type_procs[oid] = creator # SEQUEL5: Remove
  #add_conversion_proc(oid, creator) # SEQUEL5

  typecast_method_map[db_type] = :"#{type}_array"

  (class << self; self end).class_eval do # singleton_class.class_eval do # SEQUEL5
    meth = :"typecast_value_#{type}_array"
    scalar_typecast_method = :"typecast_value_#{opts.fetch(:scalar_typecast, type)}"
    define_method(meth){|v| typecast_value_pg_array(v, creator, scalar_typecast_method)}
    private meth
  end

  @schema_type_classes[:"#{type}_array"] = PGArray
  conversion_procs_updated # SEQUEL5: Remove
  nil
end

#schema_type_class(type) ⇒ Object

SEQUEL5: Remove



312
313
314
# File 'lib/sequel/extensions/pg_array.rb', line 312

def schema_type_class(type)
  super || (ARRAY_TYPES.each_value{|v| return PGArray if type == v}; nil)
end