# ANN: Sequel 3.1.0 Released

**URL:** <https://www.ruby-forum.com/t/ann-sequel-3-1-0-released/169517>\
**Category:** Ruby\
**Created:** [June 4, 2009, 6:39pm UTC](https://www.ruby-forum.com/t/ann-sequel-3-1-0-released/169517 "2009-06-04T18:39:59Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![nerdmaster](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/c68b51/32.png) [@nerdmaster](https://www.ruby-forum.com/u/nerdmaster)\
**Post date:** [June 4, 2009, 6:39pm UTC](https://www.ruby-forum.com/t/ann-sequel-3-1-0-released/169517/1 "2009-06-04T18:39:59Z")

</div>

Sequel is a lightweight database access toolkit for Ruby.

- Sequel provides thread safety, connection pooling and a concise DSL  
for constructing database queries and table schemas.
- Sequel also includes a lightweight but comprehensive ORM layer for  
mapping records to Ruby objects and handling associated records.
- Sequel supports advanced database features such as prepared  
statements, bound variables, stored procedures, master/slave  
configurations, and database sharding.
- Sequel makes it easy to deal with multiple records without having  
to break your teeth on SQL.
- Sequel currently has adapters for ADO, Amalgalite, DataObjects,  
DB2, DBI, Firebird, Informix, JDBC, MySQL, ODBC, OpenBase, Oracle,  
PostgreSQL and SQLite3.

Sequel 3.1.0 has been released and should be available on the gem  
mirrors. The 3.1.0 release adds numerous improvements:

## New Plugins

3 new plugins were added that implement features supported by  
DataMapper: identity\_map, tactical\_eager\_loading, and  
lazy\_attributes. These plugins don’t add any real new features,  
since you could do everything they allow before simply by being  
a little more explicit in your Sequel code. However, some people  
prefer a less explicit approach that uses a bit more magic, and  
now Sequel can accomodate them.

- The identity\_map plugin allows you to create a 1-1  
correspondence of model objects to database rows via a temporary  
thread-local identity map. It makes the following statment true:

- The tactical\_eager\_loading plugin allows you to eagerly load an  
association for all models retrieved in the same group whenever  
one of the models accesses the association:

- The lazy\_attributes plugin builds on the identity\_map and  
tactical\_eager\_loading plugins and allows you to create  
attributes that are lazily loaded from the database:

- A many\_through\_many plugin was also added. This very powerful  
plugin allows you to create associations to multiple objects through  
multiple join tables. Here are some examples:

## New bin/sequel Features

The bin/sequel command line tool now supports the following options:

- -C: Copies one database to another. You must specify two database  
arguments. Works similar to Taps, copying the table schema, then  
the table data, then creating the indexes.

- -d: Dump the schema of the database in the database-independent  
migration format.

- -D: Dump the schema of the database in the database-specific  
migration format.

- -h: Display the help

- -t: Output the full backtrace if an exception is raised

The bin/sequel tool is now better about checking which options can  
be used together. It also now supports using the -L option multiple  
times and having it load model files from multiple directory trees.

## New Features

- Dataset#qualify\_to and #qualify\_to\_first\_source were added. They  
allow you to qualify unqualified columns in the current dataset  
to the given table or the first source. This can be used to join  
a dataset that has unqualified columns to a new table which has  
columns with the same name.

- Savepoints are now supported using SQLite and MySQL, assuming you  
are using a database version that supports them. You need to  
pass the :savepoint option to Database#transaction to use a  
savepoint.

- Model plugins can now depend on other plugins, simply by calling  
the Model.plugin method inside the plugin’s apply method:

- Model.plugin now takes a block with is passed to the plugin’s  
apply and configure method (see Backwards Compatibility section for  
more information on the configure method).

- You can see which plugins are loaded for a model by using  
Model.plugins.

- You can use Sequel.extension method to load extensions:

- You can now use Database#create\_table? to create the table if it  
doesn’t already exist (a very common need, it seems). The schema  
plugin now supports Model.create\_table? as well.

- #sql\_subscript is now an allowed method on most SQL expression  
objects that Sequel generates. Also, arguments to #sql\_subscript  
can now be other expressions instead of just integers.

- Associations can now take a :cartesian\_product\_number option, which  
can be used to tell Sequel whether to turn on duplicate object  
detection when eagerly loading objects through eager\_graph. This  
number should be 0 if the association can never create multiple  
rows for each row in the current table, 1 if it can create multiple  
rows in the each row in the current table, and 2 if the association  
itself causes a cartesian product.

- On MySQL, Dataset#insert\_ignore now affects #insert as well as  
multi\_insert and import.

- Database#create\_table now supports an :ignore\_index\_errors option,  
and Database#add\_index now supports an :ignore\_errors option.  
These are used by the schema\_dumper when dumping an database  
schema to be restored on another database type, since indexes  
aren’t usually required for proper operation and some indexes  
can’t be transferred.

- The ADO adapter now takes a :provider option, which can be used  
to set the provider.

- The ADO adapter now takes a :command\_timeout option, which tells  
the connection how long to wait before giving up and raising an  
exception.

- The Sequel.amalgalite adapter method was added. Like the  
Sequel.sqlite method, you can call it with no arguments to get  
an in memory database.

## Other Improvements

- MySQL “commands out of sync” errors should no longer occur unless  
you are nesting queries (calling Dataset#each inside Dataset#each).  
A bug dating at least to 2007 and possibly since the initial  
creation of the Sequel MySQL adapter was the cause. Before, SQL  
that caused a result set that was sent using a method where Sequel  
doesn’t yield a result set would cause the “commands out of sync”  
error on the following query. For example, the following code  
would cause the error:

- The schema\_dumper extension is much better about parsing defaults  
from the database. It can now correctly parse most defaults on  
MySQL, SQLite, and PostgreSQL databases. It no longer includes  
defaults that it can’t parse to a ruby object unless a database-  
specific dump is requested.

- The schema\_dumper extension now dumps tables in alphabetical order.

- Ordered and limited datasets are now handled correctly when using  
union, intersect, and except. Also, union, intersect, and except  
now always return a from\_self dataset, so further limiting,  
filtering, and ordering of them now works as expected.

- Dataset#graph now works correctly with a complex dataset without  
having to use from\_self. Before, code like the following didn’t  
do what was expected:

- You can now specify serialization formats per column in the  
serialization plugin, either by calling the plugin multiple  
times or by using the new serialize\_attributes method:

- You can now use eager\_graph to eagerly load associations for models  
that lack primary keys.

- The :eager\_graph association option now works when lazily-loading  
many\_to\_many associations.

- Dataset#add\_graph\_aliases now works correctly even if  
set\_graph\_aliases hasn’t been used.

- The PostgreSQL Database#tables method now assumes the public schema  
if a schema is not given and there is no default\_schema.

- The PostgreSQL Database#indexes method no longer returns partial  
indexes or functional indexes.

- The MySQL Database#indexes method no longer returns indexes on  
partial columns (prefix indexes).

- Default values for String :text=\>true and File columns on MySQL  
are ignored, since MySQL doesn’t support them. They are not  
ignored if you use text and blob, since then you are using the  
database-specific syntax and Sequel doesn’t do translation when  
the database-specific syntax is used.

- On PostgreSQL, attempting the reset the primary key sequence for a  
table without a primary key no longer causes an error.

- Using a placeholder string in an association’s :condition option  
now works correctly (e.g. :conditions=\>[‘n = ?’, 1])

- An error is no longer raised if you attempt to load a plugin that  
has a DatasetMethods module but no public dataset methods.

- The check for dataset[n] where n is an integer was fixed. It now  
raises an error inside of returning a limited dataset.

- On PostgreSQL, Dataset#insert with static SQL now works correctly.

- A reflection.rdoc file was added giving an overview of Sequel’s  
reflection support.

- The Migrator now works correctly with file names like  
001\_12312412\_file\_name.rb.

- The association code now requires the classes match when looking  
for a reciprocal association.

- An unlikely threading bug (race condition) was possible when using  
the validation\_class\_methods plugin. The plugin was refactored and  
now uses a mutex to avoid the issue. One of the refactoring changes  
makes it so that you can no longer use a class level vaildation  
inside a Class.new block (since inherited isn’t called until the  
block finishes).

- The exception messages when Sequel.string\_to\_\* fail have been fixed.

- The String :text=\>true generic database type has been fixed when  
using the Firebird adapter.

## Backwards Compatibility

- A plugin’s apply method is now only called the first time a plugin  
is loaded. Plugins can now have a configure method that is called  
every time the plugin is loaded, and is always called after the  
instance methods, class methods, and dataset method submodules have  
been added to the model. This is different from apply, which is  
called before the submodules are loaded.

- The plugin\_opts methods defined now include multiple args in an  
array if multiple args are given. Before, the plugin\_opts methods  
just returned the first argument.

- Database#table\_exists? no longer checks the cached schema  
information. By default, it will always do a database query  
(unless overridden in an adapter). This shouldn’t affect the  
results, but if were using the method a lot and expecting it to  
use cached information, it doesn’t have the same performance  
characteristics.

- The internal storage of the :select option for datasets have  
changed. You can no longer use a hash as a way of aliasing  
columns. Dataset#select now does the translation from the hash to  
SQL::AliasedExpression instances. Basically, if you were using  
Dataset#clone directly with a :select option with hashes for  
aliasing, you should switch to using Dataset#select or changing  
the hashes to AliasedExpressions yourself.

Thanks,  
Jeremy

- {Website}[[http://sequel.rubyforge.org](http://sequel.rubyforge.org)]
- {Source code}[[GitHub - jeremyevans/sequel: Sequel: The Database Toolkit for Ruby](http://github.com/jeremyevans/sequel)]
- {Bug tracking}[[Google Code Archive - Long-term storage for Google Code Project Hosting.](http://code.google.com/p/ruby-sequel/issues/list)]
- {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)]
