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
    from :items
    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