Module: Sequel::Postgres::PGMultiRange::DatabaseMethods

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(db) ⇒ Object

Add the default multirange conversion procs to the database


113
114
115
116
117
118
119
120
121
122
123
124
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
# File 'lib/sequel/extensions/pg_multirange.rb', line 113

def self.extended(db)
  db.instance_exec do
    raise Error, "multiranges not supported on this database" unless server_version >= 140000

    extension :pg_range
    @pg_multirange_schema_types ||= {}

    register_multirange_type('int4multirange', :range_oid=>3904, :oid=>4451)
    register_multirange_type('nummultirange', :range_oid=>3906, :oid=>4532)
    register_multirange_type('tsmultirange', :range_oid=>3908, :oid=>4533)
    register_multirange_type('tstzmultirange', :range_oid=>3910, :oid=>4534)
    register_multirange_type('datemultirange', :range_oid=>3912, :oid=>4535)
    register_multirange_type('int8multirange', :range_oid=>3926, :oid=>4536)

    if respond_to?(:register_array_type)
      register_array_type('int4multirange', :oid=>6150, :scalar_oid=>4451, :scalar_typecast=>:int4multirange)
      register_array_type('nummultirange', :oid=>6151, :scalar_oid=>4532, :scalar_typecast=>:nummultirange)
      register_array_type('tsmultirange', :oid=>6152, :scalar_oid=>4533, :scalar_typecast=>:tsmultirange)
      register_array_type('tstzmultirange', :oid=>6153, :scalar_oid=>4534, :scalar_typecast=>:tstzmultirange)
      register_array_type('datemultirange', :oid=>6155, :scalar_oid=>4535, :scalar_typecast=>:datemultirange)
      register_array_type('int8multirange', :oid=>6157, :scalar_oid=>4536, :scalar_typecast=>:int8multirange)
    end

    [:int4multirange, :nummultirange, :tsmultirange, :tstzmultirange, :datemultirange, :int8multirange].each do |v|
      @schema_type_classes[v] = PGMultiRange
    end

    procs = conversion_procs
    add_conversion_proc(4533, PGMultiRange::Creator.new("tsmultirange", procs[3908]))
    add_conversion_proc(4534, PGMultiRange::Creator.new("tstzmultirange", procs[3910]))

    if respond_to?(:register_array_type) && defined?(PGArray::Creator)
      add_conversion_proc(6152, PGArray::Creator.new("tsmultirange", procs[4533]))
      add_conversion_proc(6153, PGArray::Creator.new("tstzmultirange", procs[4534]))
    end
  end
end

Instance Method Details

#bound_variable_arg(arg, conn) ⇒ Object

Handle PGMultiRange values in bound variables


152
153
154
155
156
157
158
159
# File 'lib/sequel/extensions/pg_multirange.rb', line 152

def bound_variable_arg(arg, conn)
  case arg
  when PGMultiRange 
    arg.unquoted_literal(schema_utility_dataset)
  else
    super
  end
end

#freezeObject

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


162
163
164
165
# File 'lib/sequel/extensions/pg_multirange.rb', line 162

def freeze
  @pg_multirange_schema_types.freeze
  super
end

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

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

:converter

A callable object (e.g. Proc), that is called with the PostgreSQL range string, and should return a PGRange instance.

:oid

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

:range_oid

Should be the PostgreSQL OID for the multirange subtype (the range type). 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.

Raises:


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
# File 'lib/sequel/extensions/pg_multirange.rb', line 179

def register_multirange_type(db_type, opts=OPTS, &block)
  oid = opts[:oid]
  soid = opts[:range_oid]

  if has_converter = opts.has_key?(:converter)
    raise Error, "can't provide both a block and :converter option to register_multirange_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=>:rngmultitypid).where(:typname=>db_type.to_s).get([:rngmultitypid, :rngtypid])
    soid ||= subtype_oid unless has_converter
    oid ||= range_oid
  end

  db_type = db_type.to_s.dup.freeze

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

  raise Error, "cannot add a multirange type without a convertor (use :converter or :range_oid option or pass block)" unless converter
  creator = Creator.new(db_type, converter)
  add_conversion_proc(oid, creator)

  @pg_multirange_schema_types[db_type] = db_type.to_sym

  singleton_class.class_eval do
    meth = :"typecast_value_#{db_type}"
    scalar_typecast_method = :"typecast_value_#{opts.fetch(:scalar_typecast, db_type.sub('multirange', 'range'))}"
    define_method(meth){|v| typecast_value_pg_multirange(v, creator, scalar_typecast_method)}
    private meth
  end

  @schema_type_classes[db_type] = PGMultiRange
  nil
end