pg_range.rb

lib/sequel/extensions/pg_range.rb
Last Update: 2023-12-06 16:41:40 -0800

The pg_range extension adds support for the PostgreSQL 9.2+ range types to Sequel. PostgreSQL range types are similar to ruby’s Range class, representating an array of values. However, they are more flexible than ruby’s ranges, allowing exclusive beginnings and endings (ruby’s range only allows exclusive endings).

When PostgreSQL range values are retreived, they are parsed and returned as instances of Sequel::Postgres::PGRange. PGRange mostly acts like a Range, but it’s not a Range as not all PostgreSQL range type values would be valid ruby ranges. If the range type value you are using is a valid ruby range, you can call PGRange#to_range to get a Range. However, if you call PGRange#to_range on a range type value uses features that ruby’s Range does not support, an exception will be raised.

In addition to the parser, this extension comes with literalizers for PGRange and Range, so they can be used in queries and as bound variables.

To turn an existing Range into a PGRange, use Sequel.pg_range:

Sequel.pg_range(range)

If you have loaded the core_extensions extension, or you have loaded the core_refinements extension and have activated refinements for the file, you can also use Range#pg_range:

range.pg_range

You may want to specify a specific range type:

Sequel.pg_range(range, :daterange)
range.pg_range(:daterange)

If you specify the range database type, Sequel will automatically cast the value to that type when literalizing.

To use this extension, load it into the Database instance:

DB.extension :pg_range

See the schema modification guide for details on using range type columns in CREATE/ALTER TABLE statements.

This extension makes it easy to add support for other range types. In general, you just need to make sure that the subtype is handled and has the appropriate converter installed. For user defined types, you can do this via:

DB.add_conversion_proc(subtype_oid){|string| }

Then you can call Sequel::Postgres::PGRange::DatabaseMethods#register_range_type to automatically set up a handler for the range type. So if you want to support the timerange type (assuming the time type is already supported):

DB.register_range_type('timerange')

This extension integrates with the pg_array extension. If you plan to use arrays of range types, load the pg_array extension before the pg_range extension:

DB.extension :pg_array, :pg_range

Related module: Sequel::Postgres::PGRange