# ANN: Sequel 3.37.0 Released

**URL:** <https://rubytalk.org/t/ann-sequel-3-37-0-released/65805>\
**Category:** ruby-talk\
**Created:** [2 July 2012 20:27 UTC](https://rubytalk.org/t/ann-sequel-3-37-0-released/65805 "2012-07-02T20:27:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [2 July 2012 20:27 UTC](https://rubytalk.org/t/ann-sequel-3-37-0-released/65805/1 "2012-07-02T20:27:11Z")

</div>

Sequel is a lightweight database access toolkit for Ruby.

\* Sequel provides thread safety, connection pooling and a concise  
&nbsp;&nbsp;DSL for constructing SQL queries and table schemas.  
\* Sequel includes a comprehensive ORM layer for mapping records to  
&nbsp;&nbsp;Ruby objects and handling associated records.  
\* Sequel supports advanced database features such as prepared  
&nbsp;&nbsp;statements, bound variables, stored procedures, savepoints,  
&nbsp;&nbsp;two-phase commit, transaction isolation, master/slave  
&nbsp;&nbsp;configurations, and database sharding.  
\* Sequel currently has adapters for ADO, Amalgalite, DataObjects,  
&nbsp;&nbsp;DB2, DBI, Firebird, IBM\_DB, Informix, JDBC, MySQL, Mysql2, ODBC,  
&nbsp;&nbsp;OpenBase, Oracle, PostgreSQL, SQLite3, Swift, and TinyTDS.

Sequel 3.37.0 has been released and should be available on the gem  
mirrors.

= New Features

\* Database#extension and Dataset#extension have been added and  
&nbsp;&nbsp;make it much easier to use extensions that just define modules,  
&nbsp;&nbsp;where you previously had to manually extend a Database or  
&nbsp;&nbsp;Dataset object with the module to get the extension's behavior.  
&nbsp;&nbsp;These methods operate similarly to model plugins, where you just  
&nbsp;&nbsp;specify the extension symbol, except that you can specify multiple  
&nbsp;&nbsp;extensions at once:

&nbsp;&nbsp;&nbsp;&nbsp;DB.extension(:pg\_array, :pg\_hstore)

&nbsp;&nbsp;For databases, these modify the Database itself (and  
&nbsp;&nbsp;potentially all of its datasets). Dataset#extension operates  
&nbsp;&nbsp;like other dataset methods, returning a modified clone of  
&nbsp;&nbsp;the dataset with the extension added:

&nbsp;&nbsp;&nbsp;&nbsp;dataset = dataset.extension(:columns\_introspection)

&nbsp;&nbsp;Dataset#extension! has also been added for modifying the  
&nbsp;&nbsp;receiver instead of returning a clone.

&nbsp;&nbsp;Not all extensions are usable by Database#extension or  
&nbsp;&nbsp;Dataset#extension, the extension has to have specific support  
&nbsp;&nbsp;for it. The following extensions support both  
&nbsp;&nbsp;Database#extension and Dataset#extension:

&nbsp;&nbsp;\* columns\_introspection  
&nbsp;&nbsp;\* query\_literals  
&nbsp;&nbsp;\* split\_array\_nil

&nbsp;&nbsp;The following extensions support just Database#extension:

&nbsp;&nbsp;\* arbitrary\_servers  
&nbsp;&nbsp;\* looser\_typecasting  
&nbsp;&nbsp;\* pg\_array  
&nbsp;&nbsp;\* pg\_auto\_parameterize  
&nbsp;&nbsp;\* pg\_hstore  
&nbsp;&nbsp;\* pg\_inet  
&nbsp;&nbsp;\* pg\_interval  
&nbsp;&nbsp;\* pg\_json  
&nbsp;&nbsp;\* pg\_range  
&nbsp;&nbsp;\* pg\_statement\_cache  
&nbsp;&nbsp;\* server\_block

&nbsp;&nbsp;Any user that was loading these extensions with Sequel.extension  
&nbsp;&nbsp;and then manually extending objects with the extension's module  
&nbsp;&nbsp;is encouraged to switch to Database#extension and/or  
&nbsp;&nbsp;Dataset#extension.

\* Dataset join methods now respect a :qualify=\>:deep option  
&nbsp;&nbsp;to do deep qualification of expressions, allowing qualification  
&nbsp;&nbsp;of subexpressions in the expression tree. This can allow you  
&nbsp;&nbsp;to do things like:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DB[:a].join(:b, {:c.cast(Integer)=\>:d.cast(Integer)},  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:qualify=\>:deep)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# SELECT \* FROM a INNER JOIN b  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ON (CAST(b.c AS INTEGER) = CAST(a.d AS INTEGER))

&nbsp;&nbsp;For backwards compatibility, by default Sequel will only do  
&nbsp;&nbsp;automatic qualification if the arguments are simple symbols.  
&nbsp;&nbsp;This may change in a future version, if automatic qualification  
&nbsp;&nbsp;of only symbols is desired, switch to using :qualify=\>:symbol.

&nbsp;&nbsp;You can also choose to do no automatic qualification using the  
&nbsp;&nbsp;:qualify=\>false option.

\* All of Sequel's model associations now work with key expressions  
&nbsp;&nbsp;that are not simple column references, without creating a fully  
&nbsp;&nbsp;custom association. So you can create associations where the  
&nbsp;&nbsp;primary/foreign key values are stored in PostgreSQL array or  
&nbsp;&nbsp;hstore columns, for example.

\* The pg\_array extension has now been made more generic, so that it  
&nbsp;&nbsp;is easy to support array types for any scalar type that is  
&nbsp;&nbsp;currently supported. All scalar types that Sequel's postgres  
&nbsp;&nbsp;adapter supports now have corresponding array types supported in  
&nbsp;&nbsp;the pg\_array extension. So if you load the pg\_array extension and  
&nbsp;&nbsp;return a date array column, the returned values will be arrays of  
&nbsp;&nbsp;ruby Date objects.

&nbsp;&nbsp;Other pg\_\* extensions that add support for PostgreSQL-specific  
&nbsp;&nbsp;scalar types now support array versions of those types if the  
&nbsp;&nbsp;pg\_array extension is loaded first.

\* A pg\_range extension has been added, making it easy to deal  
&nbsp;&nbsp;with PostgreSQL 9.2+'s range types. As ruby's Range class does  
&nbsp;&nbsp;not support all PostgreSQL range type values (such as empty ranges,  
&nbsp;&nbsp;unbounded ranges, or ranges with an exlusive beginning), range  
&nbsp;&nbsp;types are returned as instances of Sequel::Postgres::PGRange, which  
&nbsp;&nbsp;has an API similar to Range. You can turn a PGRange into a Range  
&nbsp;&nbsp;using PGRange#to\_range, assuming that the range type value does not  
&nbsp;&nbsp;use features that are incompatible with ruby's Range class.

&nbsp;&nbsp;The pg\_range extension supports all range types supported by  
&nbsp;&nbsp;default in PostgreSQL 9.2, and makes it easy to support custom  
&nbsp;&nbsp;range types.

\* A pg\_range\_ops extension has been added, which adds DSL support for  
&nbsp;&nbsp;PostgreSQL range operators and functions, similar to the  
&nbsp;&nbsp;pg\_array\_ops and pg\_hstore\_ops extensions.

\* A pg\_interval extension has been added, which makes Sequel return  
&nbsp;&nbsp;PostgreSQL interval types as instances of ActiveSupport::Duration.  
&nbsp;&nbsp;This is useful if you want to take the interval value and use it in  
&nbsp;&nbsp;calculations in ruby (assuming you load the appropriate parts of  
&nbsp;&nbsp;ActiveSupport).

\* A split\_array\_nil extension has been added, which changes how Sequel  
&nbsp;&nbsp;compiles IN/NOT IN expressions with arrays with nil values.

&nbsp;&nbsp;&nbsp;&nbsp;where(:col=\>[1, nil])  
&nbsp;&nbsp;&nbsp;&nbsp;# Default:  
&nbsp;&nbsp;&nbsp;&nbsp;# WHERE (col IN (1, NULL))  
&nbsp;&nbsp;&nbsp;&nbsp;# with split\_array\_nil extension:  
&nbsp;&nbsp;&nbsp;&nbsp;# WHERE ((col IN (1)) OR (col IS NULL))

&nbsp;&nbsp;&nbsp;&nbsp;exclude(:col=\>[1, nil])  
&nbsp;&nbsp;&nbsp;&nbsp;# Default:  
&nbsp;&nbsp;&nbsp;&nbsp;# WHERE (col NOT IN (1, NULL))  
&nbsp;&nbsp;&nbsp;&nbsp;# with split\_array\_nil extension:  
&nbsp;&nbsp;&nbsp;&nbsp;# WHERE ((col NOT IN (1)) AND (col IS NOT NULL))

\* The nested\_attributes plugin now allows the :fields option to  
&nbsp;&nbsp;be a proc, which is called with the associated object and should  
&nbsp;&nbsp;return an array of allowable fields.

\* You can now specify the graph alias base when using eager\_graph on  
&nbsp;&nbsp;a per-call basis. Previously, it could only be set on a per  
&nbsp;&nbsp;association basis. This is helpful if you have multiple  
&nbsp;&nbsp;associations to the same class, and are cascading the eager graph to  
&nbsp;&nbsp;dependent associations of that class for both of the associations.  
&nbsp;&nbsp;Previously, there was no way to manually give descriptive names to  
&nbsp;&nbsp;the tables in the cascaded associations, but you can now do so  
&nbsp;&nbsp;by passing the association as an Sequel::SQL::AliasedExpression  
&nbsp;&nbsp;instance instead of a plain Symbol. Here's a usage example:

&nbsp;&nbsp;&nbsp;&nbsp;ds = Game.eager\_graph(:winner=\>:players.as(:winning\_players),  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:loser=\>:players.as(:losing\_players)).  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where(:winning\_players\_\_name=\>'A',  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:losing\_players\_\_name=\>'B')

\* many\_through\_many associations now differentiate between column  
&nbsp;&nbsp;references and method references, by supporting the  
&nbsp;&nbsp;:left\_primary\_key\_column and :right\_primary\_key\_method options that  
&nbsp;&nbsp;many\_to\_many associations support.

\* Custom :eager\_loader procs that accept a single hash argument now  
&nbsp;&nbsp;have an additional entry passed in the hash, :id\_map, which is  
&nbsp;&nbsp;easier to use than the :key\_hash entry (which is still present for  
&nbsp;&nbsp;backwards compatibility). Anyone with custom :eager\_loader procs is  
&nbsp;&nbsp;encouraged to switch from using :key\_hash to :id\_map.

\* You can now override the create\_table/alter\_table schema generators  
&nbsp;&nbsp;per database/adapter. This allows for database specific generator  
&nbsp;&nbsp;subclasses, which have methods for unique features for that  
&nbsp;&nbsp;database.

\* You can now setup exclusion constraints on PostgreSQL using the  
&nbsp;&nbsp;create\_table and alter\_table schema generators:

&nbsp;&nbsp;&nbsp;&nbsp;DB.create\_table(:t) do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exclusion\_constraint([[:col1, '&&'], [:col2, '=']])  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# EXCLUDE USING gist (col1 WITH &&, col2 WITH =)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;One common use for exclusion constraints is to make sure that no two  
&nbsp;&nbsp;rows have overlapping values/ranges/circles.

\* When adding foreign key constraints to an existing table on  
&nbsp;&nbsp;PostgreSQL, you can use the :not\_valid option to mark the constraint  
&nbsp;&nbsp;as not yet valid. This will make it so that future changes to the  
&nbsp;&nbsp;table need to respect the foreign key constraint, but existing rows  
&nbsp;&nbsp;do not. After cleaning up the existing data, you can then use the  
&nbsp;&nbsp;alter\_table validate\_constraint method to mark the constraint as  
&nbsp;&nbsp;valid.

\* An eval\_inspect extension has been added that attempts to do  
&nbsp;&nbsp;do the following for Sequel::SQL::Expression instances:

&nbsp;&nbsp;&nbsp;&nbsp;eval(obj.inspect) == obj # =\> true

&nbsp;&nbsp;There are a lot of cases that this extension does not handle, but  
&nbsp;&nbsp;it does a decent job in most cases. This is currently only used  
&nbsp;&nbsp;internally in a specific case in the schema\_dumper extension.

= Other Improvements

\* The filter by associations support now respects the method  
&nbsp;&nbsp;reference vs column reference distinction that other parts of the  
&nbsp;&nbsp;association code have respected since 3.32.0.

\* In the nested\_attributes plugin, new one\_to\_one associated  
&nbsp;&nbsp;values are saved once instead of twice. Previously it attempted to  
&nbsp;&nbsp;save them before they were associated to the current model object,  
&nbsp;&nbsp;which can violate some validations/constraints.

\* When saving an associated object in the one\_to\_one association  
&nbsp;&nbsp;setter method, Sequel no longer adds an unnecessary filter  
&nbsp;&nbsp;condition when nullifying the foreign key for existing rows  
&nbsp;&nbsp;in the associated table.

\* The list plugin's before\_create method now calls super, which  
&nbsp;&nbsp;fixes usage when other plugins that define before\_create are loaded  
&nbsp;&nbsp;before it.

\* In the pg\_array extension, when typecasting an Array to PGArray,  
&nbsp;&nbsp;a recursive map is done on the input array to convert each value  
&nbsp;&nbsp;in the input array to the expected type, using the typecasting  
&nbsp;&nbsp;method that would be used for the scalar value. For example, for  
&nbsp;&nbsp;model objects, where ids is an integer array column:

&nbsp;&nbsp;&nbsp;model.set(:ids=\>['1', '2']).ids.to\_a # =\> [1, 2]

\* The pg\_array extension now correctly handles bytea arrays used  
&nbsp;&nbsp;in bound variables.

\* The pg\_array extension no longer uses the JSON-based parser for  
&nbsp;&nbsp;floating point types, since it doesn't handle NaN and Infinity  
&nbsp;&nbsp;values correctly.

\* When typecasting in the pg\_array extension, PGArray values are  
&nbsp;&nbsp;only returned verbatim if they have a matching database type.  
&nbsp;&nbsp;Otherwise, the underlying array is rewrapped in a new PGArray  
&nbsp;&nbsp;value with the correct database type.

\* H2 clob types are now recognized as strings instead of blobs.  
&nbsp;&nbsp;Previously the code attempted to do this, but it didn't do so  
&nbsp;&nbsp;correctly.

\* The jdbc/postgres adapter now converts scalar values of  
&nbsp;&nbsp;the array to the appropriate type. Previously, if you retrieved  
&nbsp;&nbsp;a date array, you got back a ruby array of JavaSQL::SQL::Date  
&nbsp;&nbsp;instances. Now, you get back a ruby array of ruby Date instances.

\* The schema\_dumper extension now dumps migrations as change  
&nbsp;&nbsp;migrations, instead of separate up/down migrations, resulting in  
&nbsp;&nbsp;simpler code.

\* When dumping non-integer foreign keys in the schema dumper, an  
&nbsp;&nbsp;explicit type is now used. Previously, the column would have been  
&nbsp;&nbsp;dumped as an integer column.

\* When dumping unsigned integer columns in the schema dumper, add a  
&nbsp;&nbsp;column \> 0 constraint in the dumped migration.

\* On Microsoft SQL Server, when updating a dataset with a limit,  
&nbsp;&nbsp;the limit is now respected.

\* When emulating offset using the ROW\_NUMBER window function,  
&nbsp;&nbsp;do not require that the dataset be ordered. If an order is  
&nbsp;&nbsp;not provided, default to ordering on all of the columns in  
&nbsp;&nbsp;the dataset. If you want to override the default order used  
&nbsp;&nbsp;in such a case, you need to override the default\_offset\_order  
&nbsp;&nbsp;method for the dataset.

\* On SQLite, casting to Date/Time/DateTime now calls an SQLite  
&nbsp;&nbsp;date/datetime function instead of using a cast, as SQLite treats  
&nbsp;&nbsp;such a cast as a cast to integer.

\* When using JRuby 1.6 in ruby 1.9 mode and typecasting a time  
&nbsp;&nbsp;column, workaround a bug where Time#nsec is 0 even though  
&nbsp;&nbsp;Time#usec is not.

\* The odbc/mssql adapter now correctly handles the case where  
&nbsp;&nbsp;SCOPE\_IDENTITY returns NULL after an insert.

\* bin/sequel now accepts multiple -l options for logging to multiple  
&nbsp;&nbsp;output files.

\* In addition to Sequel's rigorous pre-push testing, Sequel now  
&nbsp;&nbsp;also uses TravisCI for continuous integration testing across  
&nbsp;&nbsp;a wider range of ruby implementations.

= Backwards Compatibility

\* The keys in the :key\_hash entry passed to the :eager\_loader proc  
&nbsp;&nbsp;are now method references instead of column references. For most  
&nbsp;&nbsp;associations, they are the same thing, but for associations using  
&nbsp;&nbsp;the :key\_column/:primary\_key\_column/:left\_primary\_key\_column  
&nbsp;&nbsp;options, the values could be different. If you were using one  
&nbsp;&nbsp;of those options and had a custom eager\_loader, you should switch  
&nbsp;&nbsp;from indexing into the :key\_hash option to just using the :id\_map  
&nbsp;&nbsp;option.

\* The :key\_hash entry passed to the :eager\_loader proc is now no  
&nbsp;&nbsp;longer guaranteed to contain key maps for associations other than  
&nbsp;&nbsp;the one currently being eagerly loaded. Previously, it contained  
&nbsp;&nbsp;key maps for all associations that were being eagerly loaded. If  
&nbsp;&nbsp;you have a custom :eager\_loader proc that accessed a key map for  
&nbsp;&nbsp;a separate association that was being loaded concurrently, you'll  
&nbsp;&nbsp;now have to build the key map manually if it doesn't exist.

\* If you previously explicitly specified an :eager\_loader\_key option  
&nbsp;&nbsp;when defining an association, you may need to change it so that it  
&nbsp;&nbsp;is a method reference instead of a column reference, or possibly  
&nbsp;&nbsp;just omit the option.

\* If you have a custom :eager\_loader proc for an association where  
&nbsp;&nbsp;the default :eager\_loader\_key option references a method that  
&nbsp;&nbsp;the model does not respond to (or raises an exception), you may  
&nbsp;&nbsp;need to specify the :eager\_loader\_key=\>nil option.

\* In the pg\_auto\_parameterize extension, String values are no longer  
&nbsp;&nbsp;automatically casted to text. This is because the default type of  
&nbsp;&nbsp;a string literal in PostgreSQL is unknown, not text. This makes it  
&nbsp;&nbsp;much less likely to require manual casts, but has the potential to  
&nbsp;&nbsp;break existing code relying on the automatic cast to text. As a  
&nbsp;&nbsp;work around, any query that can no longer be automatically  
&nbsp;&nbsp;parameterized after this query just needs to add manual casting  
&nbsp;&nbsp;to text.

\* Sequel now raises an exception if you attempt to clone associations  
&nbsp;&nbsp;with different types, except if one type is one\_to\_many and the  
&nbsp;&nbsp;other is one\_to\_one. Cloning from other types was usually a bug,  
&nbsp;&nbsp;and raising an exception early will make it much easier to track  
&nbsp;&nbsp;such bugs down.

\* When running the plugin/extension and PostgreSQL adapter specs,  
&nbsp;&nbsp;a json library is now required.

\* The json/postgres adapter array typecasting internals have been  
&nbsp;&nbsp;modified, if you were relying on the internals, you may need to  
&nbsp;&nbsp;update your code.

\* The pg\_array extension internals changed significantly. PGArray  
&nbsp;&nbsp;no longer has any subclasses by default, as parsing is now done  
&nbsp;&nbsp;in separate objects. Anyone relying on the pg\_array internals  
&nbsp;&nbsp;will need to update their code.

\* The postgres adapter no longer sets up type conversion of int2vector  
&nbsp;&nbsp;and money types, since in both cases the conversion was incorrect in  
&nbsp;&nbsp;most cases. These types will now be returned as strings. If you are  
&nbsp;&nbsp;relying on the conversion, you'll need to add your own custom type  
&nbsp;&nbsp;procs.

Thanks,  
Jeremy

\* {Website}[[http://sequel.rubyforge.org](http://sequel.rubyforge.org)]  
\* {Source code}[[http://github.com/jeremyevans/sequel](http://github.com/jeremyevans/sequel)]  
\* {Blog}[[http://sequel.heroku.com](http://sequel.heroku.com)]  
\* {Bug tracking}[[http://github.com/jeremyevans/sequel/issues](http://github.com/jeremyevans/sequel/issues)]  
\* {Google group}[[http://groups.google.com/group/sequel-talk](http://groups.google.com/group/sequel-talk)]  
\* {RDoc}[[http://sequel.rubyforge.org/rdoc](http://sequel.rubyforge.org/rdoc)]

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
