Sequel version 0.2.1 has just been released. This release includes a
number of major improvements, as well as many bug fixes.
Sequel is a lightweight ORM library for Ruby. Sequel provides thread
safety, connection pooling and a simple and expressive API for
constructing database queries and table schemas.
Following is a discussion of the major changes:
=== Dataset#query
In Sequel, dataset methods can be chained to express a query in a
single line, but complex queries can be hard to read:
ds = DB[:txactions].select(:merchant_id, :COUNT[:id] => :tx_count).
group_by(:merchant_id).order(:tx_count.DESC).limit(5)
Dataset#query is a new method aimed at helping expressing complex
queries:
ds = DB[:txactions].query do
select :merchant_id, :COUNT[:id] => :tx_count
group_by :merchant_id
order :tx_count.DESC
limit 5
end
You can also invoke the #query on databases:
ds = DB.query do
where {:x > 1 && :y < 2}
end
=== Bang methods for mutating datasets
Also new are bang methods for manipulating datasets in place. Instead
of doing this:
ds = DB[:items]
ds = ds.filter(:active => true) if only_active
You can now write:
ds = DB[:items]
ds.filter!(:active => true) if only_active
=== Dataset transforms
You can now specify automatic data transformations when retrieving and
updating / inserting records. This feature is useful if you store
serialized objects in the database. The Dataset#transform method takes
a hash where each value is an array containing two proc objects. The
first proc is used for retrieving records, and the second proc is used
for updating / inserting records. The following example serializes
objects using Marshal.
ds = DB[:items]
ds.transform(:some_column => [
proc {|v| Marshal.load(v)},
proc {|v| Marshal.dump(v)}
])
ds.insert << {:some_column => ['this is a Ruby array']}
ds.first #=> {:some_column => ['this is a Ruby array']}
=== More block filter goodness
Block filter behavior is now improved and more complete, adding
support for strings with embedded Ruby expressions and ternary
operators. You can reference variables, constants and virtually any
Ruby object or expression in order to create parameterized queries.
Here are some examples (from actual working code):
dataset.filter {:parent_id => id}
dataset.filter {:path =~ /^#{path}\/.+/}
dataset.filter {:stamp == ((Time.now - 86400 * 3)..Time.now) && :kind
== ALARM}
dataset.filter do
:session_id == producer ? producer_id : consumer_id
:node_id == Node.root.id
end
You can put column references anywhere in your expressions:
dataset.filter {:price > :AVG[:price]}
#=> "SELECT * FROM items WHERE (price > AVG(price))"
And since Sequel knows how to properly literalize any values you give
it, you get protection from SQL injection for free!
=== Improved model classes
Sequel's model class implementation is still a work in progress, but
it is quite usable and includes the following new features:
* Model.serialize for specifying YAML/Marshal serialization/
deserialization. This method uses Dataset#transform (mentioned above).
Example usage:
class Attribute < Sequel::Model(:attributes)
serialize :value # the value column holds YAML-serialized objects
end
In order to use Marshal serialization write the following:
serialize :value, :format => :marshal
* Support for composite primary keys. Example:
class ProducerRef < Sequel::Model(:producer_refs)
set_primary_key [:session_id, :node_id]
end
You can then find a record by specifying the session_id and node_id
values:
ref = ProducerRef[sid, nid]
=== Bug fixes and miscellanea
* Fixed Dataset#insert_sql to use DEFAULT VALUES clause if argument is
an empty hash.
* Added Model#this method that provides the dataset filtered by the
instance's primary key.
* Added Model.no_primary_key method to allow models without primary
keys.
* Added charset/encoding option to postgres adapter. Changed mysql
adapter to support encoding option as well.
* Added support for case-sensitive regexps to mysql adapter.
* Fixed Symbol#to_field_name to support names with numbers and upper-
case characters (#45).
* Added Dataset#empty? method (#46). This method returns true if the
dataset contains no records.
* Added Dataset#order_by as alias for Dataset#order, Dataset#group_by
as alias for Dataset#group.
* Improved Model#method_missing to deal with invalid attributes.
* Added gem spec for Windows (without ParseTree dependency).
* Partially refactored model class and more model specs. Expect more
in this department in the near future.
=== More info
Sequel project page:
<http://code.google.com/p/ruby-sequel>
Sequel documentation:
<http://sequel.rubyforge.org>
Join the Sequel-talk group:
<http://groups.google.com/group/sequel-talk>
Install the gem:
sudo gem install sequel
Or check out the source and install manually:
svn co http://ruby-sequel.googlecode.com/svn/trunk sequel
cd sequel
rake install
···
from :items