Commits on Nov 4, 2008
  1. Bump version to 2.7.0

    committed Nov 4, 2008
Commits on Nov 2, 2008
  1. Make sure SQL::SQLArray is handled correctly when used as a hash valu…

    …e, so you get IN instead of =
    committed Nov 2, 2008
Commits on Nov 1, 2008
  1. Transform AssociationReflection from a single class to a class hierarchy

    This commit refactors association reflections from a single class to
    a parent class (still called AssociationReflection), with a subclass
    for each association type.  The AssociationReflection instance
    methods previously had many checks for the association's type in
    order to perform the correct behavior.  Type-specific behavior is one
    of the main benefits of using classes.
    This commit has some small breakage of backwards compatibility. The
    ASSOCIATION_TYPES constant moves from instead AssociationReflection
    to inside Associations, and becomes a hash with symbol keys and class
    values, instead of an array of symbols.  The RECIPROCAL_ASSOCIATIONS
    constant has been eliminated.
    This commit does increase the amount of code, but it also makes the
    code simpler.  In addition, it makes it much easier to add custom
    association classes that are still supported by associate.  You
    just add the type to ASSOCIATION_TYPES, the key being the
    association name symbol, and the value being the custom association
    committed Nov 1, 2008
  2. Optimize Date object creation in PostgreSQL adapter

    This commit changes the PostgreSQL adapter to use instead of
    Date.parse when it encounters a date field. is 3-5 faster
    according to my benchmarking.  Depending on the number of date fields
    you have in your query, this can dramatically speed up fetches.  Note
    that even with this commit, date fields still dramatically slow
    fetches down, because the ruby Date class is slow to instantiate.
    To implement this, add a apply_connection_settings method to
    Postgres::Adapter, and have it run on initial connection as well as
    any time the connection is reset.
    You can turn off this optimization with
    Sequel::Postgres.use_iso_date_format = false, which may be necessary
    if you use a non-ISO date style and changing the date style to ISO
    causes problems.
    committed Nov 1, 2008
  3. Add :eager_grapher option to associations, which the user can use to …

    …override the default eager_graph code
    This commit makes some significant internal changes to the graph code.
    Instead of having a case statement in one of the methods called by
    eager_graph, it now unconditionally calls the :eager_grapher option
    for the association.  Also, the :alias_association_type_map eager
    graph variable now holds only true or false instead of the
    association's type.
    This commit also removes all reliance on the reflection[:type]
    option, users can now define their own associations, which should
    work as long as they have the same API as AssociationReflection.
    There is no explicit support for them, nor did I do any testing to
    make sure that they are allowed, but this definitely removes a couple
    of hurdles.  To remove the reliance on type, #reciprocal_array? and
    is anything standing in the way of custom association types, attempts
    will be made accomodate them.
    committed Nov 1, 2008
  4. Associations are now inherited when a model class is subclassed

    This commit adds the @association_reflections instance variable to
    the list of instance variables to copy when subclassing.  It also
    turns association_reflections from a private class method to a public
    class method.
    committed Nov 1, 2008
  5. Instance methods added by associations are now added to an anonymous …

    …module the class includes, allowing you to override them and use super
    This commit renames the @column_accessors_module to
    @overridable_methods_module, since it is now used for holding
    association methods as well as column accessor methods.  It also adds
    an overridable_methods_module private class method for ease of use.
    committed Nov 1, 2008
Commits on Oct 31, 2008
  1. Add #add_graph_aliases (select_more for graphs), and allow use of arb…

    …itrary expressions when graphing
    Just like select_more adds columns to the already selected columns,
    add_graph_aliases adds columns to the already graphed columns.
    In addition, both set_graph_aliases and add_graph_aliases take an
    optional third argument for each value in the hash, specifying an
    arbitrary expression.  This expression is used in place of the
    combination of the first and second arguments.  For example:
      ds.set_graph_aliases!(:a=>[:b, :c], :d=>[:e, :f, 42])
      # SELECT b.c AS a, 42 AS d FROM ...
      ds.first # => {:b=>{:c=>?}, :e=>{:f=>42}}
    committed Oct 31, 2008
  2. Make Dataset#join_table take an option hash instead of a table_alias …

    …argument, add support for :implicit_qualifier option
    This commit fixes a long standing bug when eager loading via
    eager_graph.  If you are eagerly loading multiple associations for
    the same model and you add any conditions with :graph_conditions or
    :graph_only_conditions, all associations for that model other than
    the first, would implicitly qualify the value conditions with the
    last association table alias instead of the table alias for the
    model.  This is hard to explain, so here's a demonstration:
      Album.many_to_one :band
      # Tracks with the same name as the album
      Album.one_to_many :same_name_tracks, :class=>:Track, \
      Album.eager_graph(:band, :same_name_tracks).sql
      # => ... FROM albums
        LEFT OUTER JOIN bands AS band
          ON ( = albums.band_id)
        LEFT OUTER JOIN tracks AS same_name_tracks ON \
           ((same_name_tracks.album_id = AND \
            ( =
    That's the mistake, as it should use instead of  This commit fixes that, by adding an option to join_table
    that allows explicitly specifying the implicit qualifier for the
    join_table already had a table_alias argument added.  In hindsight,
    that was a mistake.  Change that argument to an option hash, keeping
    backwards compatibility.  Add support for :implicit_qualifier option
    to graph as well, which just passes it to join table.  Have
    eager_graph use the :implicit_qualifer option, and no longer qualify
    the keys manually in eager_graph.
    committed Oct 31, 2008
  3. Add :left_primary_key and :right_primary_key options to many_to_many …

    This is for consistency with the :primary_key options recently added
    to one_to_many and many_to_one associations.
    committed Oct 31, 2008
  4. More specs for :primary_key option, and fix bug in many_to_one eager …

    This commit fixes a bug in many_to_one eager loading when the
    :primary_key option doesn't point to the associated table's
    primary key.
    It also refactors eager_load somewhat, and only runs after_load
    callbacks for all objects eagerly loaded if there are any after_load
    callbacks for the association, which should be a significant speed
    committed Oct 31, 2008
Commits on Oct 30, 2008
  1. Add :primary_key option to one_to_many and many_to_one associations

    This commit allows you to choose which key to use as the primary key
    for one_to_many and many_to_one associations.  Generally, for
    one_to_many associations, this is the primary key in the current
    table, and for many_to_one associations, it is the primary key in the
    associated table.  However, there may be cases where you want to
    associate two models together, with a column in one model pointing to
    a non-primary key column in another model.  This option allows for
    that, and it's also supported when eager loading via eager or
    This commit also adds an eager_loader_key method to
    AssociationReflection, removing some custom code from eager_load.
    This should make adding custom associations easier.
    committed Oct 30, 2008
Commits on Oct 29, 2008
  1. Make after_load association callbacks take effect when eager loading …

    …via eager
    Previously, they did not take affect when eager loading.  They still
    do not take affect when eager loading via eager_graph, but now they
    take affect when eager loading via eager, since support was easy to
    add.  They are supported outside the :eager_loader, so even if you
    define your own eager_loader, they still get run correctly.  This is
    a slight breakage of backwards compatibility, but it's definitely the
    desired behavior in most circumstances.
    committed Oct 29, 2008
  2. Add a :uniq association option to many_to_many associations

    The :uniq option adds a simple after_load callback that removes
    duplicate objects from the association.  This doesn't really make
    sense for one_to_many associations, as all associated objects in a
    one_to_many association should be unique.
    committed Oct 29, 2008
  3. Support using any expression as the argument to Symbol#like

    Before would do "a LIKE 'b'" instead of "a LIKE b". This
    also didn't give the answer one would expect from code such as[:b]).
    This breaks backwards compatibility, as before it would always treat
    the passed object as a string.  However, I believe this is the more
    correct way to handle things.
    committed Oct 29, 2008
  4. Much better support for multiple schemas in PostgreSQL (Fixes #243)

    Sequel already had decent support for selecting data in tables
    outside the default schema, but it's support for schema manipulation
    and introspection for tables outside the default schema was lacking.
    This commit fixes that problem, though the approach could be taken
    further (by inspecting the schema search path and operating on all
    schemas in it).  I have no plans to add that functionality, but I'll
    be happy to apply patches written by others who need it.
    This commit does the following:
    Makes the SQL generators schema-aware, though the default schema for
    every database except PostgreSQL is nil and cannot be changed.
    Explicitly uses the default schema when using PostgreSQL, which is
    set to public by default and can be changed with default_schema=.
    This breaks backwards compatibility for users who use a default
    schema other than public.  If you use PostgreSQL and a schema
    other than public, use DB.default_schema=, and any time you want to
    access a table outside of that schema, make sure to qualify it with
    a schema name.
    Makes the primary key and sequence introspectors for PostgreSQL
    schema aware.  The sequence introspectors now return a quoted,
    qualified sequence.  This makes inserting into a table outside
    a schema in the schema path return the primary key value.
    Makes #table_exists? and #tables schema aware.  #tables now
    accepts a block and yields a dataset if a block is given, instead
    of returning an array of symbols.  #table_exists? uses this new
    The @primary_keys and @primary_key_sequences instance variable
    hashes are keyed on "schema"."table" instead of on table.
    committed Oct 29, 2008
Commits on Oct 28, 2008
  1. Lazy load model instance options such as raise_on_save_failure, for p…

    …erformance reasons
    Before, 6 model instance options were loaded on initialize, which
    slowed things down, as often it wasn't necessary to load them.
    Now, don't load any instance option until it is necessary.
    Add Module#class_attr_overridable to implement this.  It defines
    an instance method which gets it default value from the class
    method, but can be overridden using a standard attr_writer.
    This commit breaks backwards compatibility by removing the
    Model.lazy_load_schema setting.  That setting was necessary when
    loading the schema was very slow and you were reloading code.  It
    shouldn't be necessary now, as you can use DB.schema to get schema
    for all tables at once, and even if you reload the model class, you
    should be able to use the database's cached value (not to mention
    that parsing the schema should be a fairly fast operation now).
    This changes Model#initialize to not call a passed block if from_db
    is true.  That should only be set by Model.load, which doesn't
    use a block.  Also, Model#initialize now defaults to {} for the
    values instead of nil, and passing nil now causes an error (this
    is also a slight breakage of backwards compatibility).
    committed Oct 28, 2008
  2. Make Model::Validiation::Errors more Rails-compatible

    Add a #count method that returns the number of error messages.
    Break backwards compatibility by making #on return nil instead of []
    if there are no error messages for the given attribute.
    committed Oct 28, 2008
  3. Refactor model hooks for increased performance

    This change mainly stemmed from the fact that the call to
    after_initialize in Model.initialize caused about a 20% performance
    hit when fetching records, even if no after_initialize hook was
    defined.  The main performance enhancing change in this commit is
    that hook instance methods are defined to be empty until a hook class
    method is called, which redefines the hook instance method of the
    given type to actually call the hooks.
    Refactor model hooks so they are inherited when the class is created,
    at which point future hooks added to the superclass are not seen
    in the subclass.  This makes sure that the @hooks class instance
    variable is always available, except inside a block passed to (see the spec changes in this commit for a work around).
    It also simplifies Model.has_hooks?.  This breaks backwards
    compatibility slightly, if you were adding hooks to a superclass
    after a subclass had been created and expecting the hooks to appear
    in the subclass.
    This commit removes the Model.hooks and Model.all_hooks private
    class methods.  It adds a Model.hook_blocks public class method that
    yields all hook blocks for the given type of hook.  run_hooks is now
    a private instance method instead of a private class method.
    committed Oct 28, 2008
  4. Major performance enhancement when fetching rows using PostgreSQL

    I did some profiling and found that fetching rows on PostgreSQL was
    a significant bottleneck.  The previous code was decidely suboptimal,
    this new code should be significantly faster.  Basically, the old
    code was doing a hash lookup and calls to fname and ftype for every
    column of every record, when those could be done in advance (since
    they are the same for every record).  I've seen about a 3x
    improvement in speed, and that's on fetches of only 150 records, it
    should be greater on larger fetches.
    Profiling also showed that Postgres.string_to_bool was a bottleneck.
    Doing some research showed that postgresql always gives 't' for true,
    and 'f' for false.  It shouldn't be called for NULL records, so the
    conversation can be reduced to "== 't'", which is simple enough it
    should not require a method, so I inlined it.
    committed Oct 28, 2008
  5. Don't typecast serialized columns in models

    Assigning to a serialized column in a typecasting supported database
    was probably broken after typecasting support was added.  Thankfully,
    the fix is easy.
    committed Oct 27, 2008
Commits on Oct 27, 2008
  1. Add Array#sql_array to handle ruby arrays of all two pairs as SQL arr…

    …ays (Fixes #245)
    Previously, this wasn't possible, as ruby arrays of all two pairs
    were interpreted as conditions (sort of like an ordered hash).
    This allows you to do things like:
      DB[:foo].filter([:a,:b] => [[1,2],[3,4]].sql_array)
      # => SELECT * FROM foo WHERE ((a, b) IN ((1, 2), (3, 4)))
    committed Oct 27, 2008
  2. @vfiodor

    Postgres numeric returns either "numeric" or "numeric(x,y)" where x i…

    …s precision and y is scale. So added support for for last.
    vfiodor committed with Oct 24, 2008
Commits on Oct 23, 2008
  1. Add plugin page to Sequel website

    Currently, only list sequel-notnaughty and sequel-timestamped as
    available plugins.  Others will be added on request.
    committed Oct 23, 2008
  2. @fairchild

    It was not immediately obvious to me how to specify validates_uniquen…

    …ess_of across a combination of columns.
    I figured it could have been
      validates_uniqueness_of(:number, :project_id)
      validates_uniqueness_of([:number, :project_id])
    hopefully this extra sentence makes it blatantly clear
    fairchild committed with Oct 17, 2008
Commits on Oct 17, 2008