- Database#extension and Dataset#extension have been added and make it much
easier to use extensions that just define modules, where you previously had
to manually extend a Database or Dataset object with the module to
get the extension‘s behavior. These methods operate similarly to
model plugins, where you just specify the extension symbol, except that you
can specify multiple extensions at once:
DB.extension(:pg_array, :pg_hstore)
For databases, these modify the Database itself (and potentially all of its
datasets). Dataset#extension operates like other dataset methods, returning
a modified clone of the dataset with the extension added:
dataset = dataset.extension(:columns_introspection)
Dataset#extension! has also been added for modifying the receiver instead
of returning a clone.
Not all extensions are usable by Database#extension or Dataset#extension,
the extension has to have specific support for it. The following extensions
support both Database#extension and Dataset#extension:
- columns_introspection
- query_literals
- split_array_nil
The following extensions support just Database#extension:
- arbitrary_servers
- looser_typecasting
- pg_array
- pg_auto_parameterize
- pg_hstore
- pg_inet
- pg_interval
- pg_json
- pg_range
- pg_statement_cache
- server_block
Any user that was loading these extensions with Sequel.extension and then
manually extending objects with the extension‘s module is encouraged
to switch to Database#extension and/or Dataset#extension.
- Dataset join methods now
respect a :qualify=>:deep option to do deep qualification of
expressions, allowing qualification of subexpressions in the expression
tree. This can allow you to do things like:
DB[:a].join(:b, {:c.cast(Integer)=>:d.cast(Integer)},
:qualify=>:deep)
# SELECT * FROM a INNER JOIN b
# ON (CAST(b.c AS INTEGER) = CAST(a.d AS INTEGER))
For backwards compatibility, by default Sequel will only do automatic
qualification if the arguments are simple symbols. This may change in a
future version, if automatic qualification of only symbols is desired,
switch to using :qualify=>:symbol.
You can also choose to do no automatic qualification using the
:qualify=>false option.
- All of Sequel‘s model
associations now work with key expressions that are not simple column
references, without creating a fully custom association. So you can create
associations where the primary/foreign key values are stored in PostgreSQL
array or hstore columns, for example.
- The pg_array extension has now been made more generic, so that it is easy
to support array types for any scalar type that is currently supported. All
scalar types that Sequel‘s
postgres adapter supports now have corresponding array types supported in
the pg_array extension. So if you load the pg_array extension and return a
date array column, the returned values will be arrays of ruby Date objects.
Other pg_* extensions that add support for PostgreSQL-specific scalar types
now support array versions of those types if the pg_array extension is
loaded first.
- A pg_range extension has been added, making it easy to deal with PostgreSQL
9.2+’s range types. As ruby‘s Range class does not support all
PostgreSQL range type values (such as empty ranges, unbounded ranges, or
ranges with an exlusive beginning), range types are returned as instances
of Sequel::Postgres::PGRange,
which has an API similar to Range. You can turn a PGRange into a
Range using PGRange#to_range,
assuming that the range type value does not use features that are
incompatible with ruby‘s Range class.
The pg_range extension supports all range types supported by default in
PostgreSQL 9.2, and makes it easy to support custom range types.
- A pg_range_ops extension has been added, which adds DSL support for
PostgreSQL range operators and functions, similar to the pg_array_ops and
pg_hstore_ops extensions.
- A pg_interval extension has been added, which makes Sequel return PostgreSQL interval
types as instances of ActiveSupport::Duration. This is useful if you want
to take the interval value and use it in calculations in ruby (assuming you
load the appropriate parts of ActiveSupport).
- A split_array_nil extension has been added, which changes how Sequel compiles IN/NOT IN
expressions with arrays with nil values.
where(:col=>[1, nil])
# Default:
# WHERE (col IN (1, NULL))
# with split_array_nil extension:
# WHERE ((col IN (1)) OR (col IS NULL))
exclude(:col=>[1, nil])
# Default:
# WHERE (col NOT IN (1, NULL))
# with split_array_nil extension:
# WHERE ((col NOT IN (1)) AND (col IS NOT NULL))
- The nested_attributes plugin now allows the :fields option to be a proc,
which is called with the associated object and should return an array of
allowable fields.
- You can now specify the graph alias base when using eager_graph on a
per-call basis. Previously, it could only be set on a per association
basis. This is helpful if you have multiple associations to the same class,
and are cascading the eager graph to dependent associations of that class
for both of the associations. Previously, there was no way to manually give
descriptive names to the tables in the cascaded associations, but you can
now do so by passing the association as an Sequel::SQL::AliasedExpression
instance instead of a plain Symbol. Here‘s a usage
example:
ds = Game.eager_graph(:winner=>:players.as(:winning_players),
:loser=>:players.as(:losing_players)).
where(:winning_players__name=>'A',
:losing_players__name=>'B')
- many_through_many associations now differentiate between column references
and method references, by supporting the :left_primary_key_column and
:right_primary_key_method options that many_to_many associations support.
- Custom :eager_loader procs that accept a single hash argument now have an
additional entry passed in the hash, :id_map, which is easier to use than
the :key_hash entry (which is still present for backwards compatibility).
Anyone with custom :eager_loader procs is encouraged to switch from using
:key_hash to :id_map.
- You can now override the create_table/alter_table schema generators per
database/adapter. This allows for database specific generator subclasses,
which have methods for unique features for that database.
- You can now setup exclusion constraints on PostgreSQL using the
create_table and alter_table schema generators:
DB.create_table(:t) do
...
exclusion_constraint([[:col1, '&&'], [:col2, '=']])
# EXCLUDE USING gist (col1 WITH &&, col2 WITH =)
end
One common use for exclusion constraints is to make sure that no two rows
have overlapping values/ranges/circles.
- When adding foreign key constraints to an existing table on PostgreSQL, you
can use the :not_valid option to mark the constraint as not yet valid. This
will make it so that future changes to the table need to respect the
foreign key constraint, but existing rows do not. After cleaning up the
existing data, you can then use the alter_table validate_constraint method
to mark the constraint as valid.
- An eval_inspect extension has been added that attempts to do do the
following for Sequel::SQL::Expression
instances:
eval(obj.inspect) == obj # => true
There are a lot of cases that this extension does not handle, but it does a
decent job in most cases. This is currently only used internally in a
specific case in the schema_dumper extension.