Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Commits on Sep 2, 2009
  1. Bump version to 3.4.0

    authored
Commits on Aug 31, 2009
  1. @mikegolod

    Oracle database doesn't support SELECT without FROM clause.

    mikegolod authored committed
    This change makes it possible to use DB.get(<something>) against Oracle
    database (before it must be written as DB[:dual].get(<something>)).
    I've noticed, that tests use this to check proper string quoting.
  2. Added #asc, #desc, and #invert for OrderedExpression

    David Lee authored committed
Commits on Aug 29, 2009
  1. Allow validates_unique to take a block used to scope the uniqueness c…

    authored
    …onstraint
    
    This allows you to easily set up uniqueness validations that are only
    necessary in a given scope.  For example, a validation on username,
    but only for active users (as inactive users are soft deleted but
    still in the table).  You just pass a block to validates_unique:
    
      validates_unique(:name){|ds| ds.filter(:active)}
Commits on Aug 27, 2009
Commits on Aug 26, 2009
  1. Merge branch 'nestattr'

    authored
  2. Add a nested_attributes plugin for modifying associated objects direc…

    authored
    …tly through a model object
    
    The nested_attributes plugin allows you to update attributes for
    associated objects directly through the parent object, similar to
    ActiveRecord's Nested Attributes feature.
    
    Nested attributes are created using the nested_attributes method:
    
      Artist.one_to_many :albums
      Artist.nested_attributes :albums
      a = Artist.new(:name=>'YJM',
       :albums_attributes=>[{:name=>'RF'}, {:name=>'MO'}])
      # No database activity yet
    
      a.save # Saves artist and both albums
      a.albums.map{|x| x.name} # ['RF', 'MO']
    
    nested_attributes takes the following options:
    
    * :destroy - Allow destruction of nested records.
    * :limit - For *_to_many associations, a limit on the number of
      records that will be processed, to prevent denial of service
      attacks.
    * :remove - Allow disassociation of nested records (can remove the
      associated object from the parent object, but not destroy the
      associated object).
    * :strict - Set to false to not raise an error message if a primary
      key is provided in a record, but it doesn't match an existing
      associated object.
    
    If a block is provided, it is passed each nested attribute hash.  If
    the hash should be ignored, the block should return anything except
    false or nil.
    
    While hear, change the add_* method for many_to_many associations to
    save the passed associated object if that object is new.  I think this
    makes sense and is better than raising an error, since it now operates
    more similarly to a one_to_many association.
    
    To ease implementation, add a Model#modified? method.  This is called
    by save_changes, instead of assuming that the only possible object
    modifications are through the columns.
Commits on Aug 25, 2009
  1. Add an instance_hooks plugin for adding hooks to specific model insta…

    authored
    …nces
    
    The instance_hooks plugin allows you to add hooks to specific instances,
    by passing a block to a _hook method (e.g. before_save_hook{do_something}).
    The block executed when the hook is called (e.g. before_save).
    
    All of the standard hooks are supported, except for after_initialize.
    Instance level before hooks are executed in reverse order of addition before
    calling super.  Instance level after hooks are executed in order of addition
    after calling super.  If any of the instance level before hook blocks return
    false, no more instance level before hooks are called and false is returned.
    
    Instance level hooks are cleared when the object is saved successfully.
Commits on Aug 24, 2009
Commits on Aug 23, 2009
Commits on Aug 21, 2009
  1. Add a boolean_readers plugin for creating attribute? methods for bool…

    authored
    …ean columns
    
    The BooleaReaders plugin allows for the creation of attribute?
    methods for boolean columns, which provide a nicer API.  By default,
    the accessors are created for all columns of type :boolean.  However,
    you can provide a block to the plugin to change the criteria used to
    determine if a column is boolean:
    
      Sequel::Model.plugin(:boolean_readers) do |c|
        db_schema[c][:db_type] =~ /\Atinyint/
      end
    
    This may be useful if you are using MySQL and have some tinyint
    columns that represent booleans and others that represent integers.
    You can turn the convert_tinyint_to_bool setting off and use the
    attribute methods for the integer value and the attribute? methods
    for the boolean value.
  2. Add Dataset#ungrouped and minor modification to dlee's group patch

    authored
    This makes Dataset#group behave more similarly to order.  It also
    adds ungrouped, which is similar to unordered.
    
    It removes the flattening of the arguments to group, since that
    breaks grouping on a condition specified as an array of two-element
    arrays.
  3. Allow Dataset#group_by to undo grouping by calling with nil, empty, o…

    David Lee authored committed
    …r no arguments
Commits on Aug 20, 2009
  1. Fix using multiple emulated ALTER TABLE statements (e.g. drop_column)…

    authored
    … in a single alter_table block on SQLite
    
    I originally had a much more invasive patch for this, involving
    iterating each operation from the generator as was added, but it
    turns out it wasn't necessary.  Since the operations are just
    abstractions, they can still be generated all together, they just
    need to be literalized and executed in a iterative manner, instead
    of literalizing all operations first, and then executing them all.
    
    I've added an intergration test for removing multiple columns in
    a single alter_table block, which should be able to detect if
    other databases have the same problems.
  2. Don't allow inserting on a grouped dataset or a dataset that selects …

    authored
    …from multiple tables
    
    This renames the private Dataset#check_deletion_allowed! to
    check_modification_allowed!, since it is now used by all of the
    modification methods.
    
    The checks for insert are new, previously it would generate bad
    SQL for the multiple from tables case, and allow and ignore any
    group or join setting.  This breaks backwards compatibility, but
    I believe it is the right thing to do, as now all the modification
    methods (insert, update, delete, and truncate) have the same behavior
    for grouped datasets and datasets that select from multiple tables.
    
    This also fixes the case if you try to update a dataset with no
    table.  Previously you got a NoMethodError, now you get a
    Sequel::InvalidOperation.
Commits on Aug 19, 2009
  1. Allow class Item < Sequel::Model(DB2) to work

    authored
    This allows you to create an anonymous model subclass with a
    non-default database.  This is useful if you have an application
    with multiple databases, with models have the default table names
    but aren't in the default database (Sequel::Model.db or the first
    Sequel::Database object instantiated).
    
    This required a small change to Model.set_dataset to create a new
    dataset if the superclass wasn't Sequel::Model but also didn't
    have an associated dataset.  If it has an associated dataset, that
    dataset is just cloned.
  2. Add Dataset#truncate for truncating tables

    authored
    TRUNCATE is like a faster version of DELETE that cuts some corners.
    I'm not sure if it is standard SQL (it's not in SQL-92), but most
    database support it.  SQLite doesn't support it, but a DELETE
    with no WHERE clause operates like a TRUNCATE on SQLite, so that is
    what is used.
    
    To get this to work, the Dataset#execute_ddl private method was
    added, which operates like the other Dataset#execute* methods,
    except it always returns nil.
  3. Add Database#run method for executing arbitrary SQL on a database

    authored
    This method is just an alias for execute_ddl, except that it
    always returns nil (execute_ddl's return value is adapter
    dependent).
    
    Also, Database#<< is now an alias for run, so it also returns nil.
    That breaks backwards compatibility in exchange for consistency
    across adapters.  I doubt anyone is relying on the return type
    for it anyway, since it's generally used for it's side effects.
    
    I'm not a fan of adding aliases (I believe in having one good way
    do it), but obviously execute_ddl isn't the greatest method name
    for an API.  It's not possible to use execute (depending on the
    adapter), and run seemed like a good name.  It's also easier to
    use run in migrations instead of <<, since << requires an explicit
    self. << also can't specify options to execute_ddl.
  4. JDBC adapter: fix indexes() for tables in non-default schema

    John Firebaugh authored committed
  5. JDBC adapter: properly detect unique indexes on MSSQL

    John Firebaugh authored committed
  6. JDBC adapter: convert byte arrays to/from Sequel::SQL::Blob

    John Firebaugh authored committed
  7. Add support for converting Time/DateTime to local or UTC time upon st…

    authored
    …orage, retrieval, or typecasting
    
    This commit makes Time and DateTime objects being processed by Sequel
    go through a method that allows them to be converted to or from either
    local or UTC time.
    
    There are three different timezone settings:
    
    * Sequel.database_timezone - The timezone that timestamps use in the
      database.  If they database returns a time without an offset, it
      is assumed to be in this timezone.
    
    * Sequel.typecast_timezone - Similar to database_timezone, but used
      for typecasting data from a source other than the database.  This
      is currently only used by the model typecasting code.
    
    * Sequel.application_timezone - The timezone that the application
      wants to deal with.  All Time/DateTime objects are converted into
      this timezone upon retrieval from the database.
    
    Unlike most things in Sequel, these are only global settings, you
    cannot change them per database.  There are only three valid
    timezone settings:
    
    * nil (the default) - Don't do any timezone conversion.  This is the
      historical behavior.
    
    * :local - Convert to local time/Consider time to be in local time.
    
    * :utc - Convert to UTC/Consider time to be in UTC.
    
    So if you want to store times in the database as UTC, but deal with
    them in local time in the application:
    
      Sequel.application_timezone = :local
      Sequel.database_timezone = :utc
    
    If you want to set all three timezones to the same value:
    
      Sequel.default_timezone = :utc
    
    There are three conversion methods that are called:
    
    * Sequel.database_to_application_timestamp - Called on time objects
      coming out of the database.  If the object coming out of the
      database (usually a string) does not have an offset, assume it is
      already in the database_timezone.  Return a Time/DateTime object
      (depending on Sequel.datetime_class), in the application_timzone.
    
    * Sequel.application_to_database_timestamp - Used when literalizing
      Time/DateTime objects into an SQL string.  Converts the object to
      the database_timezone before literalizing them.
    
    * Sequel.typecast_to_application_timestamp - Called when typecasting
      objects for model datetime columns.  If the object being typecasted
      does not already have an offset, assume it is already in the
      typecast_timezone.  Return a Time/DateTime object (depending on
      Sequel.datetime_class), in the application_timzone.
    
    While preparing these changes, the datetime/time literalization code
    was refactored.  The following settings can now be set in adapter
    dataset classes:
    
    * supports_timestamp_timezones? - Whether to include timezone offsets
      in literal timestamp values (false by default, true for MSSQL,
      Oracle, PostgreSQL, and SQLite).
    
    * supports_timestamp_usecs? - Whether to include fractional seconds
      in literal timestamp values (true by default, false for MySQL).
    
    Since the default settings have changed to use fractional seconds
    in timestamps, it's possible that the untested adapters could be
    broken in regards to timestamps.  If that is the case, please let me
    know so I can turn off fractional seconds in timestamps for that
    adapter.  Also, if you know the database supports timezones in
    timestamps, please let me know so I can turn that on.
    
    The internals have been made very easy to modify to support more
    advanced timezone features via extensions.  Two such possible
    extensions are the ability to use arbitrary named timezones (instead
    of just local time and UTC), and the ability to dynamically modify
    the application timezone based on the environment (such as the
    current user).  The following internal functions are used:
    
    * Sequel.convert_input_timestamp - Converts from a String, Array,
      Date, DateTime, or Time object to an object of
      Sequel.datetime_class. For Strings, if no timezone offset is
      included, assumes the string is already in the input_timezone.
    
    * Sequel.convert_output_timestamp - Converts the Time/DateTime object
      to the given output_timezone.
    
    * Sequel.convert_timestamp - Converts the object using
      convert_input_timestamp and the given input_timezone (either
      database_timezone or typecast_timezone) and passes it to
      convert_output_timestamp with the application_timezone.
    
    The following additional changes have been made:
    
    * ODBC::Time values are now converted to DateTimes if the
    Sequel.datetime_class setting is DateTime.  Also, instead of assuming
    UTC time, they will now respect the database_timezone setting.
    
    * The default timestamp literalization format now uses a space
    instead a T to separate the date and time parts.
    
    * The timestamp storage format for SQLite has changed to now
    include the fractional seconds as well as the timezone offset.  Since
    SQLite just stores ASCII text, this can have significant implications
    if you use something other than Sequel to access the SQLite database.
Commits on Aug 13, 2009
  1. JDBC adapter: attempt to bind unknown types using setObject instead o…

    John Firebaugh authored
    …f raising
Something went wrong with that request. Please try again.