# ANN: Sequel 3.5.0 Released

**URL:** <https://www.ruby-forum.com/t/ann-sequel-3-5-0-released/176530>\
**Category:** Ruby\
**Created:** [October 1, 2009, 6:10pm UTC](https://www.ruby-forum.com/t/ann-sequel-3-5-0-released/176530 "2009-10-01T18:10:35Z")\
**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:** [October 1, 2009, 6:10pm UTC](https://www.ruby-forum.com/t/ann-sequel-3-5-0-released/176530/1 "2009-10-01T18:10:35Z")

</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.5.0 has been released and should be available on the gem  
mirrors. The 3.5.0 release adds numerous improvements:

## New Plugins

- A class\_table\_inheritance plugin has been added, supporting model  
inheritance in the database using a table-per-model-class approach.  
Each table stores only attributes unique to that model or subclass  
hierarchy.

- An associations\_dependencies plugin was added for deleting,  
destroying, or nullifying associated objects when destroying a  
model object. This just gives an easy way to add the necessary  
before and after destroy hooks. The following association types  
support the following dependency actions:

- A force\_encoding plugin was added that forces the encoding of  
strings used in model instances. When model instances are loaded  
from the database, all values in the hash that are strings are  
forced to the given encoding. Whenever you update a model column  
attribute, the resulting value is forced to a given encoding if the  
value is a string. There are two ways to specify the encoding.  
You can either do so in the plugin call itself, or via the  
forced\_encoding class accessor:

- A typecast\_on\_load plugin was added, for fixing bad database  
typecasting when loading model objects. Most of Sequel’s database  
adapters don’t have complete control over typecasting, and may  
return columns that aren’t typecast correctly (with correct being  
defined as how the model object would typecast the same column  
values).

- A touch plugin was added, which adds Model#touch for updating an  
instance’s timestamp, as well as touching associations when an  
instance is updated or destroyed.

- A subclasses plugin was added, for recording all of a models  
subclasses and descendent classes. Direct subclasses are available  
via the subclasses method, and all descendent classes are available  
via the descendents method:

- An active\_model plugin was added, giving Sequel::Model an  
ActiveModel complaint API, in so much as it passes the  
ActiveModel::Lint tests.

## New Extensions

- A named\_timezones extension was added, allowing you to use named  
timezones such as “America/Los\_Angeles” (the default Sequel  
timezone support only supports UTC or local time). This extension  
requires TZInfo. It also sets the Sequel.datetime\_class to  
DateTime, so database timestamps will be returned as DateTime  
instances instead of Time instances. This is because ruby’s  
Time class doesn’t support timezones other than UTC and local time.

- A thread\_local\_timezones extension was added. This allows you to  
set a per-thread timezone that will override the default global  
timezone while the thread is executing. The main use case is for  
web applications that execute each request in its own thread, and  
want to set the timezones based on the request. The most common  
example is having the database always store time in UTC, but have  
the application deal with the timezone of the current user. That  
can be done with:

- An sql\_expr extension was added that adds .sql\_expr methods to  
all objects, giving them easy access to Sequel’s DSL:

- A looser\_typecasting extension was added, for using to\_f and to\_i  
instead of the more strict Kernel.Float and Kernel.Integer when  
typecasting floats and integers. To use it, you should extend the  
database with the Sequel::LooserTypecasting module after loading  
the extension:

## Other New Features

- Associations now support composite keys. All of the :\*key options  
options now accept arrays of symbols instead of plain symbols.  
Example:

- Associations now respect a :validate option, which can be set to  
false to not validate when implicitly saving associated objects.

- In addition to the regular association methods, the  
nested\_attributes plugin was also updated to respect the  
:validate\_association option. It was also modified to not validate  
associated objects twice, once when the parent object was validated  
and again when the associated object was saved. Additionally, if  
you pass :validate=\>false to the save method when saving the parent  
object, it will not longer attempt to validate associated objects  
when saving them.

- Dataset#insert and #insert\_sql were refactored and now support the  
following API:

- Graphing now works with previously joined datasets. The main use  
case of this is when eagerly loading (via eager\_graph) model  
associations for models backed by joined datasets, such as those  
created by the class\_table\_inheritance plugin.

- Sequel.virtual\_row was added allowing you to easily use the  
VirtualRow support outside of select, order, and filter calls:

- When Sequel wraps exception in its own classes (to provide database  
independence), it now keeps the wrapped exception available in  
a wrapped\_exception accessor. This allows you to more easily  
determine the wrapped exception class, without resorting to parsing  
the exception message.

- The MySQL adapter now supports a Dataset#split\_multiple\_result\_sets  
method that yields arrays of rows (one per result set), instead of  
rows. This allows you to submit multiple statements at the same  
time (or call a stored procedure that returns multiple result  
sets), and know which rows are related to which result sets.

- The ADO adapter now accepts a :conn\_string option and uses that  
as the full ADO connection string. This can be used to connect to  
any datasource ADO supports, such as Microsoft Excel.

- The Microsoft SQL Server shared adapter now supports a  
Database#server\_version method.

- The Microsoft SQL Server shared adapter now supports updating and  
deleting from joined datasets.

- The Microsoft SQL Server shared adapter now supports a  
Dataset#output method that uses the OUTPUT clause.

- Model#\_save now calls either Model#\_insert or Model#\_update for  
inserting/updating the row in the database. This allows for easier  
overriding when you want to allow creating and updating model  
objects backed by a joined dataset.

- Dataset#graph now takes a :from\_self\_alias option specifying the  
alias to use for the subselect created if the receiver is a joined  
but not yet graphed dataset. It defaults to the first source table  
in the receiver.

## Other Improvements

- Typecasting model attributes is now done before checking existing  
values, instead of after. Before, the code for the model attribute  
setters would compare the given value to the existing entry. If it  
didn’t match, the value was typecasted and then assigned. That led  
to the following situation:

- Model#modified? is now always true if the record is new. modified?  
indicates the instance’s status relative to the database, and since  
a new object is not yet in the database, and saving the object  
would add it, the object is considered modified. A consequence of  
this is that Model#save\_changes now always saves if the object is  
new.

- The DataObjects (do) adpater now supports DataObjects 0.10.

- Dataset#select\_more and Dataset#order\_more no longer affect the  
receiver. They are supposed to just return a modified copy of the  
receiver instead of modifying the receiver itself. For a few  
versions they have been broken in that they modified the receiver  
in addition to returning a modified copy.

- Performance was increased for execution of prepared statements  
with multiple bound variables on MySQL.

- On MySQL, database errors raised when preparing statements or  
setting bound variable values are now caught and raised as  
Sequel::DatabaseErrors.

- On MySQL, more types of disconnection errors are detected.

- When altering columns in MySQL, options such as :unsigned,  
:elements, and :size that are given in the call are now respected.

- MySQL enum defaults are now handled correctly in the schema dumper.

- The schema dumper no longer attempts to use unparseable defaults  
as literals on MySQL, since MySQL does not provide defaults as  
valid literals.

- The emulated offset support in the shared Microsoft SQL Server  
adapter now works better with model classes (or any datasets with  
row\_procs).

- Microsoft SQL Server now supports using the WITH clause in delete,  
update, and insert calls.

- Parsed indexes when connecting to Microsoft SQL Server via JDBC no  
longer include primary key indexes.

- Dataset#insert\_select now returns nil if disable\_insert\_returning  
is used in the shared PostgreSQL adapter. This makes it work as  
expected with model object creation.

- Calling Model.set\_primary\_key with an array of symbols to set  
a composite primary key is now supported. You can also provide  
multiple symbol arguments to do the same thing. Before, specifying  
an array of symbols broke the Model.[] optimization.

- Literalization of timezones in timestamps now works correctly on  
Oracle.

- **FILE** and **LINE** are now used everywhere that eval is called  
with a string, which makes for better backtraces.

- The native MySQL adapter now correctly handles returning before  
yielding all result sets. Previously, this caused a commands out  
of sync error.

- Table names in common table expressions are now quoted.

- The Oracle adapter’s Dataset#except now accepts a hash, giving it  
the same API as the default Dataset#except.

- When connecting to Microsoft SQL Server via ADO, allow  
Dataset#insert to take multiple arguments.

- Fractional timestamps are no longer used on ODBC.

- Schema parsing now works on MSSQL when the database is set to not  
quote identifiers.

- Timezone offsets are no longer used on Microsoft SQL Server, since  
they only work for the datetimeoffset type.

- Only 3 fractional digits in timestamps are used in Microsoft SQL  
Server, since an error is raised if the use the datetime type  
with more than that.

- The integration test suite now has guards for expected failures  
when run on known databases. Expected failures are marked as  
pending.

## Backwards Compatibility

- Graphing to an previously joined (but not graphed) dataset now  
causes the receiver to be wrapped in a subselect, so if you  
graph a dataset to a previously joined dataset, and then filter  
the dataset referring to tables that were in the joined dataset  
(other than the first table), the SQL produced will probably no  
longer be valid. You should either filter the dataset before  
graphing or use the name of the first source of the joined  
dataset (which is what the subselected is aliased to) if filtering  
afterward.

- The DataObjects (do) adpater no longer supports DataObjects 0.9.x.

- The Dataset#virtual\_row\_block\_call private instance method has  
been removed.

- Sequel’s timezone support was significantly refactored, so if you  
had any custom modifications to the timezone support, they might  
need to be refactored as well.

- The SQL generation code was significantly refactored, so if you  
had any custom modifications in that area, you might need to  
refactor as well.

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)]
