New Features ------------ * Sequel now has support for deleting and updating joined datasets on MySQL and PostgreSQL. Previously, Sequel only supported this to a limited extent on Microsoft SQL Server, and support there has been improved as well. This allows you to do: DB.create_table!(:a){Integer :a; Integer :d} DB.create_table!(:b){Integer :b; Integer :e} DB.create_table!(:c){Integer :c; Integer :f} # Insert some rows ds = DB.from(:a, :b). join(:c, :c=>:e.identifier). where(:d=>:b) ds.where(:f=>6).update(:a => 10) ds.where(:f=>5).delete Which will set the a column to 10 for all rows in table a, where an associated row in table c (through table b) has a value of 6 for column f. It will delete rows from table a where an associated row in table c (through table b) has a value of 5 for column f. Sequel assumes the that first FROM table is the table being updated/deleted. MySQL and Microsoft SQL Server do not require multiple FROM tables, but PostgreSQL does. * Dataset #select_map, #select_order_map, and #select_hash convenience methods were added for quickly creating arrays and hashes from a dataset. select_map and select_order_map both return arrays of values for the column specified. The column can be specified either via an argument or a block, similar to Dataset#get. Both accept any valid objects as arguments. select_hash returns a hash. It requires two symbol arguments, but can handle implicit qualifiers or aliases in the symbols. Neither of these methods offer any new functionality, they just cut down on the number of required key strokes: select_map(:column) # select(:column).map(:column) select_order_map(:column) # select(:column).order(:column). # map(:column) select_hash(:key_column, :value_column) # select(:key_column, :value_column). # to_hash(:key_column, :value_column) * The NULL, NOTNULL, TRUE, SQLTRUE, FALSE, and SQLFALSE constants were added to Sequel::SQL::Constants. This allows you to do: include Sequel::SQL::Constants DB[:table].where(:a=>'1', :b=>NOTNULL) Previously, the shortest way to do this was: DB[:table].where(:a=>'1').exclude(:b=>nil) It may make the code more descriptive: DB[:table].where(:b=>NULL) # compared to DB[:table].where(:b=>nil) This gives the option to use SQL terminology instead of ruby terminology. The other advantage of using the constants it that they handle operators and methods like other Sequel::SQL objects: NULL & SQLFALSE # BooleanExpression => "(NULL AND FALSE)" nil & false # false NULL + :a # NumericExpression => "(NULL + a)" nil + :a # raises NoMethodError NULL.sql_string + :a # StringExpression => "(NULL || a)" NULL.as(:b) # AliasedExpression => "NULL AS b" For complex systems that want to represent SQL boolean objects in ruby (where you don't know exactly how they'll be used), using the constants is recommended. In order not to be too verbose, including Sequel::SQL::Constants is recommended. It's not done by default, but you can still reference the constants under the main Sequel module by default (e.g. Sequel::NULL). * The validates_unique method in the validation_helpers plugin now supports an :only_if_modified option, which should speed up the common case where the unique attribute is not modified for an existing record. It's not on by default, since it's possible the database could be changed between retrieving the model object and updating it. * The Dataest #union, #intersect, and #except methods now accept an :alias option that it used as the alias for the returned dataset. DB[:table].union(DB[:old_table], :alias=>:table) * Model#destroy now supports a :transaction option, similar to Model#save. * The shared Oracle adapter now supports Dataset#sequence for returning autogenerated primary key values on insert from a related sequence. This makes Oracle work correctly when using models, with something like the following: class Album < Sequel::Model set_dataset dataset.sequence(:seq_albums_id) end You currently need to call Dataset#sequence in every model class where the underlying table uses a sequence to generate primary key values. Other Improvements ------------------ * In Model #save and #destroy when using transactions and when raise_on_save_failure is false, ensure that transactions are rolled back if a before hook returns false. * Dataset#group_and_count now handles arguments other than Symbols. A previous change to the method raised an exception if a Symbol was not provided. It also handles AliasedExpressions natively, so the following works correctly: DB[:table].group_and_count(:column.as(:alias)) * Sequel no longer uses native autoreconnection in the mysql adapter. Native autoreconnection has problems with prepared statements, where a new native connection is used behind Sequel's back, so Sequel thinks the prepared statement has already been defined on the connection, when it fact it hasn't. Any other changes that affect the state of the connection will be lost when native autoreconnection is used as well. Sequel's connection pool already handles reconnection if it detects a disconnection. This commit also adds an additional exception message to recognize as a disconnect. If there other exception messages related to disconnects, please post them on the Sequel mailing list. * The schema_dumper plugin now specifies the :type option for primary key if it isn't Integer. * On PostgreSQL, the bigserial type is used if :type=>Bignum is given as an option to primary key. This makes it operate more similarly to other adapters that support autoincrementing 64-bit integer primary keys. * The native mysql adapter will now attempt to load options in the [client] section of the my.cnf file. * The rake spec tasks for the project now work correctly with RSpec 1.2.9. Backwards Compatibility ----------------------- * Dataset::GET_ERROR_MSG and Dataset::MAP_ERROR_MSG constants were removed. Both were replaced with Dataset::ARG_BLOCK_ERROR_MSG. * The behavior of the Model#save_failure private instance method was modified. It now always raises an exception, and validation failures no longer call it. * The internals of how autogenerated primary key metadata is stored when creating tables on PostgreSQL has been modified. * The native MySQL adapter no longer sets the OPT_LOCAL_INFILE option to "client" on the native connection.