== about Sequel

Sequel is an ORM framework for Ruby. Sequel provides thread safety, connection pooling, and a DSL for constructing queries and table schemas.

== Resources

* {Project page}[http://code.google.com/p/ruby-sequel/]
* {Source code}[http://ruby-sequel.googlecode.com/svn/]
* {Bug tracking}[http://code.google.com/p/ruby-sequel/issues/list]
* {RubyForge page}[http://rubyforge.org/projects/sequel/]

To check out the source code:
  
  svn co http://ruby-sequel.googlecode.com/svn/trunk

== Installation

  sudo gem install sequel
  
== Supported Databases

Sequel currently supports:

* Postgresql
* SQLite 3

== A Short Tutorial

=== Connecting to a database

There are two ways to create a connection to a database. The easier way is to provide a connection URL:

  DB = Sequel.connect("sqlite:///blog.db")

You can also specify optional parameters, such as the connection pool size:

  DB = Sequel.connect("postgres://postgres:postgres@localhost/my_db",
    :max_connections => 10)

The second, more verbose, way is to create an instance of a database class:

  DB = Sequel::Postgres::Database.new(:database => 'my_db', :host => 'localhost')

=== Arbitrary SQL queries

  DB.execute("create table t (a text, b text)")
  DB.execute("insert into t values ('a', 'b')")

Or more succintly:

  DB << "create table t (a text, b text)"
  DB << "insert into t values ('a', 'b')"

=== Creating Datasets

Dataset is the primary means through which records are retrieved and manipulated. You can create an blank dataset by using the dataset method:

  dataset = DB.dataset

Or by using the from methods:

  posts = DB.from(:posts)

You can also use the equivalent shorthand:

  posts = DB[:posts]

Note: the dataset will only fetch records when you explicitly ask for them, as will be shown below. Datasets can be manipulated to filter through records, change record order and even join tables, as will also be shown below.

=== Retrieving Records

You can retrieve records by using the all method:

  posts.all

The all method returns an array of hashes, where each hash corresponds to a record.

You can also iterate through records one at a time:

  posts.each {|row| p row}

Or perform more advanced stuff:

  posts.map(:id)
  posts.inject({}) {|h, r| h[r[:id]] = r[:name]}
  
You can also retrieve the first record in a dataset:

  posts.first
  
If the dataset is ordered, you can also ask for the last record:

  posts.order(:stamp).last
  
=== Filtering Records

The simplest way to filter records is to provide a hash of values to match:

  my_posts = posts.filter(:category => 'ruby', :author => 'david')
  
You can also specify ranges:

  my_posts = posts.filter(:stamp => (2.weeks.ago)..(1.week.ago))
  
Or lists of values:

  my_posts = posts.filter(:category => ['ruby', 'postgres', 'linux'])
  
Some adapters (like postgresql) will also let you specify Regexps:

  my_posts = posts.filter(:category => /ruby/i)
  
You can also use an inverse filter:

  my_posts = posts.exclude(:category => /ruby/i)

You can then retrieve the records by using any of the retrieval methods:

  my_posts.each {|row| p row}
  
You can also specify a custom WHERE clause:

  posts.filter('(stamp < ?) AND (author <> ?)', 3.days.ago, author_name)
  
=== Summarizing Records

Counting records is easy:
  posts.filter(:category => /ruby/i).count

And you can also query maximum/minimum values:
  max_value = DB[:history].max(:value)
  
=== Ordering Records

  posts.order(:stamp)
  
You can also specify descending order

  posts.order(:stamp.DESC)

=== Deleting Records

  posts.filter('stamp < ?', 3.days.ago).delete
  
=== Inserting Records

  posts.insert(:category => 'ruby', :author => 'david')
  
Or alternatively:

  posts << {:category => 'ruby', :author => 'david'}
  
=== Updating Records

  posts.filter('stamp < ?', 3.days.ago).update(:state => 'archived')
