Module: Sequel::Postgres::PGRange::DatabaseMethods

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(db) ⇒ Object

Reset the conversion procs if using the native postgres adapter, and extend the datasets to correctly literalize ruby Range values.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/sequel/extensions/pg_range.rb', line 220

def self.extended(db)
  db.instance_eval do
    @pg_range_schema_types ||= {}
    extend_datasets(DatasetMethods)
    register_range_type('int4range', :oid=>3904, :subtype_oid=>23)
    register_range_type('numrange', :oid=>3906, :subtype_oid=>1700)
    register_range_type('tsrange', :oid=>3908, :subtype_oid=>1114)
    register_range_type('tstzrange', :oid=>3910, :subtype_oid=>1184)
    register_range_type('daterange', :oid=>3912, :subtype_oid=>1082)
    register_range_type('int8range', :oid=>3926, :subtype_oid=>20)
    if respond_to?(:register_array_type)
      register_array_type('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
      register_array_type('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
      register_array_type('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
      register_array_type('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange)
      register_array_type('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange)
      register_array_type('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range)
    end
    [:int4range, :numrange, :tsrange, :tstzrange, :daterange, :int8range].each do |v|
      @schema_type_classes[v] = PGRange
    end

    procs = conversion_procs
    add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
    add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
    if defined?(PGArray::Creator)
      add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
      add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
    end
  end
end

Instance Method Details

#bound_variable_arg(arg, conn) ⇒ Object

Handle Range and PGRange values in bound variables



253
254
255
256
257
258
259
260
261
262
# File 'lib/sequel/extensions/pg_range.rb', line 253

def bound_variable_arg(arg, conn)
  case arg
  when PGRange 
    arg.unquoted_literal(schema_utility_dataset)
  when Range
    PGRange.from_range(arg).unquoted_literal(schema_utility_dataset)
  else
    super
  end
end

#freezeObject

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



265
266
267
268
# File 'lib/sequel/extensions/pg_range.rb', line 265

def freeze
  @pg_range_schema_types.freeze
  super
end

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

Register a database specific range type. This can be used to support different range types per Database. Options:

:converter :: A callable object (e.g. Proc), that is called with the start or end of the range (usually a string), and should return the appropriate typecasted object. :oid :: The PostgreSQL OID for the range type. This is used by the Sequel postgres adapter to set up automatic type conversion on retrieval from the database. :subtype_oid :: Should be the PostgreSQL OID for the range's subtype. If given, automatically sets the :converter option by looking for scalar conversion proc.

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



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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/sequel/extensions/pg_range.rb', line 282

def register_range_type(db_type, opts=OPTS, &block)
  oid = opts[:oid]
  soid = opts[:subtype_oid]

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

  unless (soid || has_converter) && oid
    range_oid, subtype_oid = from(:pg_range).join(:pg_type, :oid=>:rngtypid).where(:typname=>db_type.to_s).get([:rngtypid, :rngsubtype])
    soid ||= subtype_oid unless has_converter
    oid ||= range_oid
  end

  db_type = db_type.to_s.dup.freeze

  if converter = opts[:converter]
    raise Error, "can't provide both a block and :converter option to register" if block
  else
    converter = block
  end

  if soid
    raise Error, "can't provide both a converter and :subtype_oid option to register" if has_converter 
    raise Error, "no conversion proc for :subtype_oid=>#{soid.inspect} in conversion_procs" unless converter = conversion_procs[soid]
  end

  parser = Parser.new(db_type, converter)
  add_conversion_proc(oid, parser)

  @pg_range_schema_types[db_type] = db_type.to_sym

  (class << self; self end).class_eval do
    meth = :"typecast_value_#{db_type}"
    define_method(meth){|v| typecast_value_pg_range(v, parser)}
    private meth
  end

  @schema_type_classes[:"#{opts[:type_symbol] || db_type}"] = PGRange
  conversion_procs_updated # SEQUEL5: Remove
  nil
end