Thanks, Jeremy. There is a lot in this release! I will certainly
appreciate the Sequel.mock behavior among other things.

On Nov 1, 1:22 pm, Jeremy Evans <[email protected]> wrote:
> Sequel 3.29.0 has been released and should be available on the gem
> mirrors.
>
> = New Adapter Support
>
> * Sequel now has much better support for Oracle, both in the
>   ruby-oci8-based oracle adapter and in the jdbc/oracle adapter.
>
> * Sequel now has much better support for connecting to HSQLDB
>   using the jdbc adapter.  This support does not work correctly
>   with the jdbc-hsqldb gem, since the version it uses is too
>   old.  You'll need to load the .jar file manually until the
>   gem is updated.
>
> * Sequel now has much better support for connecting to Apache
>   Derby databases using the jdbc adapter.  This works with
>   the jdbc-derby gem, but it's recommend you grab an updated
>   .jar file as the jdbc-derby gem doesn't currently support
>   truncate or booleans.
>
> * The db2 adapter has had most of the remaining issues fixed,
>   and can now run Sequel's test suite cleanly.  It's still
>   recommended that users switch to the ibmdb adapter if they
>   are connecting to DB2.
>
> * A mock adapter has been added which provides a mock Database
>   object that allows you to easily set the returned rows, the
>   number of rows modified by update/delete, and the
>   autogenerating primary key integer for insert.  It also allows
>   you to set specific columns in the dataset when retrieving
>   rows.  The specs were full of partial implementations of
>   mock adapters, this mock adapter is much more complete and
>   offers full support for mocking transactions and database
>   sharding.  Example:
>
>     DB = Sequel.mock(:fetch=>{:id=>1}, :numrows=>2, :autoid=>3)
>     DB[:items].all            # => [{:id => 1}]
>     DB[:items].insert         # => 3
>     DB[:items].insert         # => 4
>     DB[:items].delete         # => 2
>     DB[:items].update(:id=>2) # => 2
>     DB.sqls # => ['SELECT ...', 'INSERT ...', ...]
>
>   In addition to being useful in the specs, the mock adapter is
>   also used if you use bin/sequel without a database argument,
>   which makes it much easier to play around with Sequel on the
>   command line without being tied to a real database.
>
> = New Transaction Features
>
> * Database after_commit and after_rollback hooks have been added,
>   allowing you to set procs that are called after the currently-
>   in-effect transaction commits or rolls back.  If the Database
>   is not currently in a transaction, the after_commit proc is
>   called immediately and the after_rollback proc is ignored.
>
> * Model after_commit, after_rollback, after_destroy_commit, and
>   after_destroy_rollback hooks have been added that use the new
>   Database after_commit/after_rollback hook to execute code after
>   commit or rollback.
>
> * Database#transaction now supports a :rollback => :reraise option
>   to reraise any Sequel::Rollback exceptions raised by the block.
>
> * Database#transaction now supports a :rollback => :always option
>   to always rollback the transaction, which is mostly useful when
>   using transaction-based testing.
>
> * Sequel.transaction has been added, allowing you to run
>   simultaneous transactions on multiple Database objects:
>
>     Sequel.transaction([DB1, DB2]){...}
>     # similar to:
>     DB1.transaction{DB2.transaction{...}}
>
>   You can combine this with the :rollback => :always option to
>   easily use multiple databases in the same test suite and make sure
>   that changes are rolled back on all of them.
>
> * Database#in_transaction? has been added so that users can detect
>   whether the code is currently inside a transaction.
>
> * The generic JDBC transaction support, used by 6 of Sequel's jdbc
>   subapters, now supports savepoints if the underlying JDBC driver
>   supports savepoints.
>
> = Other New Features
>
> * A dataset_associations plugin has been added, allowing datasets
>   to call association methods, which return datasets of rows in
>   the associated table that are associated to rows in the current
>   dataset.
>
>     # Dataset of tracks from albums with name < 'M'
>     # by artists with name > 'M'
>
>     Artist.filter(:name > 'M').albums.filter(:name < 'M').tracks
>
>     # SELECT * FROM tracks
>     # WHERE (tracks.album_id IN (
>     #   SELECT albums.id FROM albums
>     #   WHERE ((albums.artist_id IN (
>     #     SELECT artists.id FROM artists
>     #     WHERE (name > 'M')))
>     #    AND (name < 'M'))))
>
> * Database#extend_datasets has been added, allowing you to do the
>   equivalent of extending all of the database's future datasets
>   with a module.  For performance, it creates an anonymous
>   subclass of the current dataset class and includes a module in
>   it, and uses the subclass to create future datasets.
>
>   Using this feature allows you to override any dataset method
>   and call super, similar to how Sequel::Model plugins work. The
>   method takes either a module:
>
>     Sequel.extension :columns_introspection
>     DB.extend_datasets(Sequel::ColumnsIntrospection)
>
>   or a block that it uses to create an anonymous module:
>
>     DB.extend_datasets do
>       # Always select from table.* instead of *
>       def from(*tables)
>         ds = super
>         if !@opts[:select] || @opts[:select].empty?
>           ds = ds.select_all(*tables)
>         end
>         ds
>       end
>     end
>
> * Database#<< and Dataset#<< now return self, which allow them
>   to be used in chaining:
>
>     DB << "UPADTE foo SET bar_id = NULL" << "DROP TABLE bars"
>     DB[:foo] << {:bar_id=>0} << DB[:bars].select(:id)
>
> * A Database#timezone accessor has been added, allowing you to
>   override Sequel.database_timezone on a per-Database basis, which
>   allows you to use two separate Database objects in the same
>   process that have different timezones.
>
> * You can now modify the type conversion procs on a per-Database
>   basis when using the mysql, sqlite, and ibmdb adapters, by
>   modifying the hash returned by Database#conversion_procs.
>
> * Model.dataset_module now accepts a Module instance as an argument,
>   and extends the model's dataset with that module.
>
> * When using the postgres adapter with the pg driver, you can now
>   use Database#listen to wait for notifications.  All adapters that
>   connect to postgres now support Database#notify to send
>   notifications:
>
>     # process 1
>     DB.listen('foo') do |ev, pid, payload|
>       ev # => 'foo'
>       notify_pid # => some Integer
>       payload # => 'bar'
>     end
>
>     # process 2
>     DB.notify('foo', :payload=>'bar')
>
> * many_to_one associations now have a :qualify option that can be set
>   to false to not qualify the primary key when loading the
>   association.  This shouldn't be necessary to use in most cases, but
>   in some cases qualifying a primary key breaks certain queries (e.g.
>   using JOIN USING on the same column on Oracle).
>
> * Database#schema can now take a dataset as an argument if it just
>   selects from a single table.  If a dataset is provided, the
>   schema parsing will use that dataset's identifier_input_method
>   and identifier_output_method for the parsing, instead of the
>   database's default.  This makes it possible for Model classes
>   to correctly get the table schema if they use a dataset whose
>   identifier_(input|output)_method differs from the database
>   default.
>
> * On databases that support common table expressions (CTEs) but do
>   not support CTE usage in subselects, Sequel now emulates support
>   by moving CTEs from the subselect to the main select when using
>   the Dataset from, from_self, with, with_recursive, union,
>   intersect, and except methods.
>
> * The bitwise compliment operator is now emulated on H2.
>
> * You can now set the convert_tinyint_to_bool setting on a
>   per-Database basis in the mysql and mysql2 adapters.
>
> * You can now set the convert_invalid_date_time setting on a
>   per-Database basis in the mysql adapter.
>
> * Database instances now have a dataset_class accessor that allows
>   you to set which class is used when creating datasets.  This is
>   mostly used to implement the extend_datasets support, but it
>   could be useful for other purposes.
>
> * Dataset#unused_table_alias now accepts an optional 2nd argument,
>   which should be an array of additional symbols that should be
>   considered as already used.
>
> * Dataset#requires_placeholder_type_specifiers? has been added to
>   check if the dataset requires you use type specifiers for
>   bound variable placeholders.
>
>   The prepared_statements plugin now checks this setting and works
>   correctly on adapters that set it to true, such as oracle.
>
> * Dataset#recursive_cte_requires_column_aliases? has been added
>   to check if you must provide a column list for a recursive CTE.
>
>   The rcte_tree plugin now checks this setting an works correctly
>   on databases that set it to true, such as Oracle and HSQLDB.
>
> = Performance Improvements
>
> * Numerous optimizations were made to loading model objects from
>   the database, resulting in a 7-16% speedup.
>
>   Model.call was added, and now .load is just an alias for .call.
>   This allows you to make the model dataset's row_proc the model
>   itself, instead of needing a separate block, which improves
>   performance.
>
>   While Model.load used to call .new (and therefore #initialize),
>   Model.call uses .allocate/#set_values/#after_initialize for speed.
>   This saves a method call or two, and skips setting the @new
>   instance variable.
>
> * Dataset#map, #to_hash, #select_map, #select_order_map, and
>   #select_hash are now faster if any of the provided arguments are
>   an array of symbols.
>
> * The Model.[] optimization is now applied in more cases.
>
> = Other Improvements
>
> * Sequel now creates accessor methods for all columns in a model's
>   table, even if the dataset doesn't select the columns.  This has
>   been the specified behavior for a while, but the spec was broken.
>   This allows you do to:
>
>     Model.dataset = DB[:table].select(:column1, :column2)
>     Model.select_more(:column3).first.column3
>
> * Model.def_dataset_method now correctly handles method names that
>   can't be used directly (such as method names with spaces).  This
>   isn't so the method can be used with arbitrary user input, but
>   it will allow safe creation of dataset methods that are derived
>   from column names, which could contain spaces.
>
> * Model.def_dataset_method no longer overrides private model
>   methods.
>
> * The optimization that Model.[] uses now works correctly if the
>   model's dataset uses a different identifier_input_method than
>   the database.
>
> * Sharding is supported correctly by default for the transactions
>   used by model objects.  Previously, you had to use the sharding
>   plugin to make sure the same shard was used for transactions as
>   for the insert/update/delete statements.
>
> * Sequel now fully supports using an aliased table for the
>   :join_table option of a many_to_many association.  The only real
>   use case for an aliased :join_table option is when the join table
>   is the same as the associated model table.
>
> * A bug when eagerly loading a many_through_many association with
>   composite keys where one of the join tables requires an alias
>   has been fixed.
>
> * Sequel's transaction internals have had substantial improvments.
>   You can now open up simultaneous transactions on two separate
>   shards of the same Database object in the same thread.  The new
>   design allows for future support of connection pools that aren't
>   based on threads.  Sequel no longer abuses thread-local variables
>   to store savepoint state.
>
> * Dataset#select_map and #select_order_map now return an array of
>   single element arrays if given an array with a single entry as
>   an argument.  Previously, they returned an array of values, which
>   wasn't consistent.
>
> * Sequel's emulation of bitwise operators with more than 2 arguments
>   now works on all adapters that use the emulation.  The emulation
>   was broken in 3.28.0 when more than 2 arguments were used on H2,
>   DB2, Microsoft SQL Server, PostgreSQL, and SQLite.
>
> * Dataset#columns now correctly handles the emulated offset support
>   used on DB2, Oracle, and Microsoft SQL Server when using the
>   jdbc, odbc, ado, and dbi adapters.  Previously, Dataet#columns
>   could contain the row number column, which wasn't in the
>   hashes yielded by Dataset#each.
>
> * Sequel can now parse primary key information on Microsoft SQL
>   Server.  Previously, the only adapter that supported this was the
>   jdbc adapter, which uses the generic JDBC support.  The shared
>   mssql adapter now supports parsing the information directly from
>   the database system tables.  This means that if you are using
>   Model objects with a Microsoft SQL Server database using the
>   tinytds, odbc, or ado adapters, the model primary key
>   information will be set automatically.
>
> * Sequel's prepared statement support no longer defines singleton
>   methods on the prepared statement objects.
>
> * StringMethods#like is now case sensitive on SQLite and Microsoft
>   SQL Server, making it more similar to other databases.
>
> * Sequel now works around an SQLite column naming bug if you select
>   columns qualified with the alias of a subselect without providing
>   an alias for the column itself.
>
> * Sequel now handles more bound variable types when using bound
>   variables outside of prepared statements on SQLite.
>
> * Sequel now works around a bug in certain versions of the
>   JDBC/SQLite driver when emulating alter table support for
>   operations such as drop_column.
>
> * Sequel now emulates the add_constraint and drop_constraint
>   alter table operations on SQLite, though the emulation has
>   issues.
>
> * Sequel now correctly handles composite primary keys when
>   emulating alter_table operations on SQLite.
>
> * Sequel now applies the correct PRAGMA statements by default when
>   connecting to SQLite via the amalgalite and swift adapters.
>
> * Sequel now supports using savepoints inside prepared transactions
>   on MySQL.
>
> * Sequel now closes JDBC ResultSet objects as soon as it is done
>   using them, leading to potentially lower memory usage in the JDBC
>   adapter, and fixes issues if you try to drop a table before
>   GC has collected a related ResultSet.
>
> * Sequel can now correctly insert all default values into a table
>   on DB2.  Before, this didn't work correctly if the table had more
>   than one column.
>
> * Another type of disconnection error is now recognized in the
>   mysql2 adapter.
>
> * Sequel now uses better error messages if you attempt to execute a
>   prepared statement without a name using the postgres, mysql, and
>   mysql2 adapters.
>
> * Some small fixes have been made that allow Sequel to run better
>   when $SAFE=1.  However, Sequel is not officially supported using
>   $SAFE > 0, so there could be many issues remaining.
>
> * Sequel's core and model specs were cleaned up by using the mock
>   adapter to eliminate a lot of redundant code.
>
> * Sequel's integration tests were sped up considerably, halving
>   the execution time on some adapters.
>
> = Backwards Compatibility
>
> * Because Model.load is now an alias for .call, plugins should no
>   longer override load.  Instead, they should override .call.
>
> * Loading model objects from the database no longer calls
>   Model#initialize.  Instead, it calls Model.allocate,
>   Model#set_values, and Model#after_initialize.  So if you were
>   overriding #initialize and expecting the changes to affect model
>   objects loaded from the database, you need to change your code.
>
>   Additionally, @new is no longer set to false for objects retieved
>   from the database, since setting it to false hurts performance.
>   Model#new? still returns true or false, so this only affects you
>   if you are checking the instance variables directly.
>
> * Dataset#<< no longer returns the autogenerated primary key for the
>   inserted row.  As mentioned above, it now returns self to allow for
>   chaining.  If you were previously relying on the return value,
>   switch from #<< to #insert.
>
> * Dataset#map no longer calls the row_proc if given an argument, and
>   Dataset#to_hash no longer calls the row_proc if given two arguments.
>   This should only affect your code if you were using a row_proc that
>   modified the content of the hash (e.g. Model#after_initialize). If
>   you were relying on the old behavior, switch:
>
>     dataset.map(:foo)
>     # to
>     dataset.map{|r| r[:foo]}
>
>     dataset.to_hash(:foo, :bar)
>     # to
>     h = {}
>     dataset.each{|r| h[r[:foo]] = r[:bar]}
>     h
>
> * Model classes now need to have a dataset before you can define
>   associations on them.
>
> * Model classes now pass their dataset to Database#schema, instead of
>   their table name.
>
> * The :eager_block association option (which defaults to the
>   association's block argument) is now called before the :eager_graph
>   association option has been applied, instead of after.
>
> * The many_to_many association reflection :qualified_right_key entry
>   is now a method named qualified_right_key.  Switch any
>   code using association_reflection[:qualified_right_key] to use
>   association_reflection.qualified_right_key.
>
> * If you are using like on SQLite and Microsoft SQL Server and want
>   it to be case insensitive, switch to using ilike:
>
>     # Case sensitive
>     DB[:foos].where(:name.like('bar%'))
>     # Case insensitive
>     DB[:foos].where(:name.ilike('bar%'))
>
>   Sequel now sets the case_sensitive_like PRAGMA to true by default
>   on SQLite.  To set it to false instead, pass the
>   :case_sensitive_like=>false option to the database when creating it.
>
> * Sequel's alter table emulation on SQLite now renames the current
>   table then populates the replacement table, instead of
>   populating the replacement table at a temporary name, dropping
>   the current table, and then renaming the replacement table.
>
> * The strings 'n' and 'no' (case insensitive) when typecasted to
>   boolean are now considered false values instead of true.
>
> * The transaction internals had extensive changes, if you have any
>   code that depended on the transaction internals, it will probably
>   require changes.
>
> * Using the Sequel::MySQL module settings for convert_tinyint_to_bool
>   and convert_invalid_date_time now only affects future Database
>   objects.  You should switch to using the per-Database methods
>   if you are currently using the Sequel::MySQL module methods.
>
> * The customized transaction support in the do (DataObjects) adapter
>   was removed.  All three subadapters (postgres, mysql, sqlite) of
>   the do adapter implement their own transaction support, so this
>   should have no effect unless you were using the do adapter with
>   a different database type.
>
> * The oracle support changed dramatically, so if you were relying
>   on the internals of the oracle support, you should take extra
>   care when upgrading.
>
> = Advance Notice
>
> * The next release of Sequel will contain significant changes to
>   how a dataset is literalized into an SQL string.  If you have
>   a custom plugin, extension, or adapter that overrides a
>   method containing "literal", "sql", or "quote", or you make
>   other modifications or extensions to how Sequel currently
>   literalizes datasets to SQL, your code will likely need to
>   be modified to support the next release.
>
> Thanks,
> Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to