sequel 3.5.0 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +108 -0
- data/README.rdoc +25 -14
- data/Rakefile +20 -1
- data/doc/advanced_associations.rdoc +61 -64
- data/doc/cheat_sheet.rdoc +16 -7
- data/doc/opening_databases.rdoc +3 -3
- data/doc/prepared_statements.rdoc +1 -1
- data/doc/reflection.rdoc +2 -1
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/schema.rdoc +19 -14
- data/lib/sequel/adapters/amalgalite.rb +5 -27
- data/lib/sequel/adapters/jdbc.rb +13 -3
- data/lib/sequel/adapters/jdbc/h2.rb +17 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +20 -7
- data/lib/sequel/adapters/mysql.rb +4 -3
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +87 -28
- data/lib/sequel/adapters/shared/mssql.rb +47 -6
- data/lib/sequel/adapters/shared/mysql.rb +12 -31
- data/lib/sequel/adapters/shared/postgres.rb +15 -12
- data/lib/sequel/adapters/shared/sqlite.rb +18 -0
- data/lib/sequel/adapters/sqlite.rb +1 -16
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +2 -0
- data/lib/sequel/database/schema_sql.rb +1 -1
- data/lib/sequel/dataset.rb +5 -179
- data/lib/sequel/dataset/actions.rb +123 -0
- data/lib/sequel/dataset/convenience.rb +18 -10
- data/lib/sequel/dataset/features.rb +65 -0
- data/lib/sequel/dataset/prepared_statements.rb +29 -23
- data/lib/sequel/dataset/query.rb +429 -0
- data/lib/sequel/dataset/sql.rb +67 -435
- data/lib/sequel/model/associations.rb +77 -13
- data/lib/sequel/model/base.rb +30 -8
- data/lib/sequel/model/errors.rb +4 -4
- data/lib/sequel/plugins/caching.rb +38 -15
- data/lib/sequel/plugins/force_encoding.rb +18 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -0
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +40 -11
- data/lib/sequel/plugins/serialization.rb +17 -3
- data/lib/sequel/plugins/validation_helpers.rb +65 -18
- data/lib/sequel/sql.rb +23 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +96 -10
- data/spec/adapters/mysql_spec.rb +19 -0
- data/spec/adapters/postgres_spec.rb +65 -2
- data/spec/adapters/sqlite_spec.rb +10 -0
- data/spec/core/core_sql_spec.rb +9 -0
- data/spec/core/database_spec.rb +8 -4
- data/spec/core/dataset_spec.rb +122 -29
- data/spec/core/expression_filters_spec.rb +17 -0
- data/spec/extensions/caching_spec.rb +43 -3
- data/spec/extensions/force_encoding_spec.rb +43 -1
- data/spec/extensions/nested_attributes_spec.rb +55 -2
- data/spec/extensions/validation_helpers_spec.rb +71 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/dataset_test.rb +383 -9
- data/spec/integration/eager_loader_test.rb +0 -65
- data/spec/integration/model_test.rb +110 -0
- data/spec/integration/plugin_test.rb +306 -0
- data/spec/integration/prepared_statement_test.rb +32 -0
- data/spec/integration/schema_test.rb +8 -3
- data/spec/integration/spec_helper.rb +1 -25
- data/spec/model/association_reflection_spec.rb +38 -0
- data/spec/model/associations_spec.rb +184 -8
- data/spec/model/eager_loading_spec.rb +23 -0
- data/spec/model/model_spec.rb +8 -0
- data/spec/model/record_spec.rb +84 -1
- metadata +9 -2
data/doc/cheat_sheet.rdoc
CHANGED
@@ -25,7 +25,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
25
25
|
|
26
26
|
== Using raw SQL
|
27
27
|
|
28
|
-
DB
|
28
|
+
DB.run "CREATE TABLE users (name VARCHAR(255) NOT NULL, age INT(3) NOT NULL)"
|
29
29
|
dataset = DB["SELECT age FROM users WHERE name = ?", name]
|
30
30
|
dataset.map(:age)
|
31
31
|
DB.fetch("SELECT name FROM users") do |row|
|
@@ -79,9 +79,9 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
79
79
|
dataset.where(:value=>[50,75,100])
|
80
80
|
|
81
81
|
dataset.filter(:name => 'abc').first
|
82
|
-
dataset[:name => 'abc']
|
82
|
+
dataset[:name => 'abc']
|
83
83
|
|
84
|
-
|
84
|
+
dataset.where('price > (SELECT avg(price) + 100 FROM table)')
|
85
85
|
dataset.filter{|o| o.price > dataset.select(o.avg(price) + 100)}
|
86
86
|
|
87
87
|
=== Advanced filtering using ruby expressions
|
@@ -198,12 +198,21 @@ Transactions can also be aborted by raising Sequel::Rollback:
|
|
198
198
|
raise(Sequel::Rollback) if something_bad_happened
|
199
199
|
end # ROLLBACK issued and no error raised
|
200
200
|
|
201
|
-
|
201
|
+
Savepoints can be used if the database supports it:
|
202
|
+
|
203
|
+
DB.transaction do
|
204
|
+
dataset << {:first_name => 'Farm', :last_name => 'Boy'} # Inserted
|
205
|
+
DB.transaction(:savepoint=>true) # This savepoint is rolled back
|
206
|
+
dataset << {:first_name => 'Inigo', :last_name => 'Montoya'} # Not inserted
|
207
|
+
raise(Sequel::Rollback) if something_bad_happened
|
208
|
+
end
|
209
|
+
dataset << {:first_name => 'Prince', :last_name => 'Humperdink'} # Inserted
|
210
|
+
end
|
211
|
+
|
212
|
+
== Miscellaneous:
|
202
213
|
|
203
214
|
dataset.sql #=> "SELECT * FROM items"
|
204
215
|
dataset.delete_sql #=> "DELETE FROM items"
|
205
|
-
dataset.where(:name => 'sequel').exists #=> "EXISTS ( SELECT
|
216
|
+
dataset.where(:name => 'sequel').exists #=> "EXISTS ( SELECT * FROM items WHERE name = 'sequel' )"
|
206
217
|
dataset.columns #=> array of columns in the result set, does a SELECT
|
207
|
-
|
208
|
-
# Works on PostgreSQL, MySQL, SQLite, and JDBC
|
209
218
|
DB.schema(:items) => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
|
data/doc/opening_databases.rdoc
CHANGED
@@ -94,9 +94,9 @@ possibly through WINE, but that's fairly unlikely).
|
|
94
94
|
The following options are supported:
|
95
95
|
* :driver - The driver to use. The default if not specified is 'SQL Server'.
|
96
96
|
* :command_timeout - Sets the time in seconds to wait while attempting
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
to execute a command before cancelling the attempt and generating
|
98
|
+
an error. Specifically, it sets the ADO CommandTimeout property.
|
99
|
+
If this property is not set, the default of 30 seconds is used.
|
100
100
|
* :conn_string - The full ADO connection string. If this is provided,
|
101
101
|
the general connection options are ignored.
|
102
102
|
* :provider - Sets the Provider of this ADO connection (for example, "SQLOLEDB")
|
@@ -49,7 +49,7 @@ may itself contain placeholders:
|
|
49
49
|
== Prepared Statements
|
50
50
|
|
51
51
|
Prepared statement support is similar to bound variable support, but you
|
52
|
-
use Dataset#prepare with a name, and Dataset#call later with the values:
|
52
|
+
use Dataset#prepare with a name, and Dataset#call or Database#call later with the values:
|
53
53
|
|
54
54
|
ds = DB[:items].filter(:name=>:$n)
|
55
55
|
ps = ds.prepare(:select, :select_by_name)
|
data/doc/reflection.rdoc
CHANGED
@@ -10,7 +10,7 @@ You can get the adapter in use using Database.adapter_scheme. As this is a clas
|
|
10
10
|
|
11
11
|
== Database Connected To
|
12
12
|
|
13
|
-
In some
|
13
|
+
In some cases, the adapter scheme will be the same as the database to which you are connecting. However, many adapters support multiple databases. You can use the Database#database_type method to get the type of database to which you are connecting:
|
14
14
|
|
15
15
|
DB.database_type # :postgres, :h2, :mssql
|
16
16
|
|
@@ -36,6 +36,7 @@ Database#schema takes a table symbol and returns column information in an array
|
|
36
36
|
* :db_type - The type of column the database provided, as a string. Used by the schema_dumper plugin for a more specific type translation.
|
37
37
|
* :default - The default value of the column, as either a string or nil. Uses a database specific format. Used by the schema_dumper plugin for converting to a ruby value.
|
38
38
|
* :primary_key - Whether this column is one of the primary key columns for the table. Used by the Sequel::Model code to determine primary key columns.
|
39
|
+
* :ruby_default - The default value of the column as a ruby object, or nil if there is no default or the default could not be successfully parsed into a ruby object.
|
39
40
|
* :type - The type of column, as a symbol (e.g. :string). Used by the Sequel::Model typecasting code.
|
40
41
|
|
41
42
|
Example:
|
@@ -0,0 +1,366 @@
|
|
1
|
+
New Features
|
2
|
+
------------
|
3
|
+
|
4
|
+
* Dataset#filter and related methods now accept a string with named
|
5
|
+
placeholders, and a hash with placeholder values:
|
6
|
+
|
7
|
+
ds.filter('copies_sold > :sales', :sales=>500000)
|
8
|
+
|
9
|
+
Sequel's general support for this syntax is nicer:
|
10
|
+
|
11
|
+
ds.filter{copies_sold > 500000}
|
12
|
+
|
13
|
+
But named placeholder support can make it easier to port code
|
14
|
+
from other database libraries. Also, it works much better than
|
15
|
+
the ? placeholder support if you have a long SQL statement:
|
16
|
+
|
17
|
+
DB['SELECT :n FROM t WHERE p > :q AND p < :r', :n=>1,:q=>2,:r=>3]
|
18
|
+
|
19
|
+
Sequel doesn't subsitute values that don't appear in the hash:
|
20
|
+
|
21
|
+
ds.where('price < :p AND id in :ids', :p=>100)
|
22
|
+
# WHERE (price < 100 AND id in :ids)
|
23
|
+
|
24
|
+
This makes it easier to spot missed placeholders, and avoids issues
|
25
|
+
with PostgreSQL's :: casting syntax or : inside string literals.
|
26
|
+
|
27
|
+
* The Model add_ association method now accepts a hash and creates
|
28
|
+
a new associated model object associated to the receiver:
|
29
|
+
|
30
|
+
Artist[:name=>'YJM'].add_album(:name=>'RF')
|
31
|
+
|
32
|
+
* The Model remove_ association method now accepts a primary key
|
33
|
+
and removes the associated model object from the association. For
|
34
|
+
models using composite primary keys, an array of primary key values
|
35
|
+
can be used. Example:
|
36
|
+
|
37
|
+
Artist[:name=>'YJM'].remove_album(1) # regular pk
|
38
|
+
Artist[:name=>'YJM'].remove_album([2, 3]) # composite pk
|
39
|
+
|
40
|
+
* Dataset#bind was added, allowing you to bind values before calling
|
41
|
+
Dataset#call. This is more consistent with Sequel's general
|
42
|
+
approach where queries can be built in any order.
|
43
|
+
|
44
|
+
* The native postgres adapter now has Dataset#use_cursor, which
|
45
|
+
allows you to process huge datasets without keeping all records in
|
46
|
+
memory. The default number of rows per cursor fetch is 1000, but
|
47
|
+
that can be modified:
|
48
|
+
|
49
|
+
DB[:huge_table].use_cursor.each{|r| p r}
|
50
|
+
DB[:huge_table].use_cursor(:rows_per_fetch=>10000).each{|r| p r}
|
51
|
+
|
52
|
+
This probably won't work with prepared statements or
|
53
|
+
bound variables.
|
54
|
+
|
55
|
+
* The nested_attributes plugin now adds newly created objects to the
|
56
|
+
cached association array immediately, even though the changes
|
57
|
+
are not persisted to the database until after the object is saved.
|
58
|
+
The reasoning for this is that otherwise there is no way to access
|
59
|
+
the newly created associated objects before the save, and no way
|
60
|
+
to access them at all if validation fails.
|
61
|
+
|
62
|
+
This makes the nested_attributes plugin much easier to use, since
|
63
|
+
now you can just iterate over the cached association array when
|
64
|
+
building the form. If validation fails, it will have the newly
|
65
|
+
created failed objects in the array, so you can easily display the
|
66
|
+
form as the user entered it for them to make changes.
|
67
|
+
|
68
|
+
This change doesn't affect many_to_one associations, since those
|
69
|
+
don't have a cached association array. This also does not affect
|
70
|
+
updating existing records, since those are already in the cached
|
71
|
+
array.
|
72
|
+
|
73
|
+
* You can now easily override the default options used in the
|
74
|
+
validation_helpers plugin (the recommended validation plugin).
|
75
|
+
Options can be overridden at a global level:
|
76
|
+
|
77
|
+
Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS[:format].
|
78
|
+
merge!(:message=>"incorrect format", :allow_missing=>true)
|
79
|
+
|
80
|
+
Options can also be overridden on a per-class level:
|
81
|
+
|
82
|
+
class Album < Sequel::Model
|
83
|
+
plugin :validation_helpers
|
84
|
+
DEFAULT_VALIDATION_OPTIONS = {
|
85
|
+
:format=>{:message=>"incorrect format", :allow_missing=>true}}
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def default_validation_helpers_options(type)
|
90
|
+
super.merge(DEFAULT_VALIDATION_OPTIONS[type] || {})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
* You can now use a proc instead of a string for the
|
95
|
+
validation_helpers :message option. This should allow much
|
96
|
+
easier internationalization support. If a proc is given, Sequel
|
97
|
+
calls it to get the format string to use. Whether the proc should
|
98
|
+
take an argument depends on whether the associated validation
|
99
|
+
method takes an argument before the array of columns to validate,
|
100
|
+
and the argument provided is what is passed to the proc. The
|
101
|
+
exception to this is the validates_not_string method, which doesn't
|
102
|
+
take an argument, but does pass one to the proc (a symbol with the
|
103
|
+
schema type of the column).
|
104
|
+
|
105
|
+
Combined with the above default option support, full
|
106
|
+
internationalization support for the validation_helpers plugin
|
107
|
+
should be fairly easy.
|
108
|
+
|
109
|
+
* The nested_attributes plugin now accepts a :fields option that
|
110
|
+
specifies the fields that are allowed. If specified, the
|
111
|
+
plugin will use set_only instead of set when mass assigning
|
112
|
+
attributes. Without this, the only way to control which fields
|
113
|
+
are allowed is to set allowed/restricted attributes at a class
|
114
|
+
level in the associated class.
|
115
|
+
|
116
|
+
* Associations now accept a :distinct option which uses the SQL
|
117
|
+
DISTINCT clause. This can be used instead of :uniq for
|
118
|
+
many_to_many and many_through_many associations to handle
|
119
|
+
the uniqueness in the database instead of in ruby. It can
|
120
|
+
also be useful for one_to_many associations to models that
|
121
|
+
don't have primary keys.
|
122
|
+
|
123
|
+
* The caching plugin now accepts an :ignore_exceptions option that
|
124
|
+
allows it to work with memcached (which raises exceptions instead
|
125
|
+
of returning nil for missing records).
|
126
|
+
|
127
|
+
* Sequel now emulates JOIN USING poorly using JOIN ON for databases
|
128
|
+
that don't support JOIN USING (MSSQL and H2). This isn't
|
129
|
+
guaranteed to work for all queries, since USING and ON have
|
130
|
+
different semantics, but should work in most cases.
|
131
|
+
|
132
|
+
* The MSSQL shared adapter now supports insert_select, for faster
|
133
|
+
model object creation. If for some reason you need to disable it,
|
134
|
+
you can use disable_insert_output.
|
135
|
+
|
136
|
+
* Model#modified! has been added which explicitly marks the object
|
137
|
+
as modified. So even if no column values have been modified,
|
138
|
+
calling save_changes/update will still run through the regular
|
139
|
+
save process and call all before and after save/update hooks.
|
140
|
+
|
141
|
+
* Model#marshallable! has been added which removes unmarshallable
|
142
|
+
attributes from the object. Previously, you couldn't marshal
|
143
|
+
a saved model object because it contained a dataset with a
|
144
|
+
singleton class. Custom _dump and _load methods could be used
|
145
|
+
instead, but this approach is easier to implement.
|
146
|
+
|
147
|
+
* Dataset#literal_other now calls sql_literal on the object with
|
148
|
+
the current dataset instance, if the object responds to it.
|
149
|
+
This makes it easier to support the literalization of arbitrary
|
150
|
+
objects.
|
151
|
+
|
152
|
+
Note that if the object is a subclass of a class handled by
|
153
|
+
an existing dataset literalization method, you cannot use this
|
154
|
+
method. You have to override the specific Dataset#literal_* method
|
155
|
+
in that case.
|
156
|
+
|
157
|
+
* Model#save_changes now accepts an option hash that is passed to
|
158
|
+
save:
|
159
|
+
|
160
|
+
album.save_changes(:validate=>false)
|
161
|
+
|
162
|
+
* A bunch of Dataset#*_join methods have been added, for specific
|
163
|
+
join types:
|
164
|
+
|
165
|
+
* cross_join
|
166
|
+
* natural_join
|
167
|
+
* full_join
|
168
|
+
* left_join
|
169
|
+
* right_join
|
170
|
+
* natural_full_join
|
171
|
+
* natural_left_join
|
172
|
+
* natural_right_join
|
173
|
+
|
174
|
+
Previously, you had to use join_table(:cross, ...) to use a CROSS
|
175
|
+
JOIN.
|
176
|
+
|
177
|
+
* You can now create clustered indexes on Microsoft SQL Server using
|
178
|
+
the :clustered option.
|
179
|
+
|
180
|
+
* AssociationReflection#associated_object_keys has been added,
|
181
|
+
specifying the keys in the associated model object that are related
|
182
|
+
to this association.
|
183
|
+
|
184
|
+
* Sequel::SQL::SQLArray#to_a was added.
|
185
|
+
|
186
|
+
Other Improvements
|
187
|
+
------------------
|
188
|
+
|
189
|
+
* Constant lookup in virtual row blocks now works correctly in ruby
|
190
|
+
1.9. Virtual row blocks are based on BasicObject on ruby 1.9,
|
191
|
+
which doesn't allow referencing objects in the top level scope. So
|
192
|
+
the following code would cause an error on 1.9:
|
193
|
+
|
194
|
+
DB[:bonds].filter{maturity_date > Time.now}
|
195
|
+
|
196
|
+
Sequel now uses a Sequel::BasicObject class on 1.9 with a
|
197
|
+
const_missing that looks up constants in Object, which allows the
|
198
|
+
above code to work.
|
199
|
+
|
200
|
+
* Sequel no longer attempts to load associated objects when
|
201
|
+
one of the key fields in the current table is NULL. This fixes
|
202
|
+
the behavior when the :primary_key option for the association
|
203
|
+
is used to point to a non-primary key.
|
204
|
+
|
205
|
+
A consequence of this change is that attempting to load a
|
206
|
+
*_to_many association for a new model object now returns
|
207
|
+
an empty array instead of raising an exception. This has its
|
208
|
+
own advantage of allowing the same association viewing code
|
209
|
+
to work on both new and existing objects. Previously, you had
|
210
|
+
to actively avoid calling the association method on new objects,
|
211
|
+
or Sequel would raise an exception.
|
212
|
+
|
213
|
+
* Dataset aggreate methods (sum/avg/min/max/range/interval) now
|
214
|
+
work correctly with limited, grouped, or compound datasets.
|
215
|
+
Previously, count worked with them, but other aggregate methods
|
216
|
+
did not. These methods now use a subquery if called on a
|
217
|
+
limited, grouped or compound dataset.
|
218
|
+
|
219
|
+
* It is no longer required to have an existing GROUP BY clause
|
220
|
+
to use a HAVING clause (except on SQLite, which doesn't permit
|
221
|
+
it). Sequel has always had this limitation, but it's not required
|
222
|
+
by the SQL standard, and there are valid reasons to use HAVING
|
223
|
+
without GROUP BY.
|
224
|
+
|
225
|
+
* Sequel will now emulate support for databases that don't support
|
226
|
+
multiple column IN/NOT IN syntax, such as MSSQL and SQLite:
|
227
|
+
|
228
|
+
ds.filter([:col1, :col2]=>[[1, 2], [3, 4]].sql_array)
|
229
|
+
# default: WHERE (col1, col2) IN ((1, 2), (3, 4))
|
230
|
+
# emulated: WHERE (((col1 = 1) AND (col2 = 2)) OR
|
231
|
+
# ((col1 = 3) AND (col2 = 4)))
|
232
|
+
|
233
|
+
This is necessary for eager loading associated objects for models
|
234
|
+
with composite primary keys.
|
235
|
+
|
236
|
+
* Sequel now emulates :column.ilike('blah%') for case insensitive
|
237
|
+
searches on MSSQL and H2. MSSQL is case insensitive by default,
|
238
|
+
so it is the same as like. H2 is case sensitive, so Sequel
|
239
|
+
uses a case insensitive cast there.
|
240
|
+
|
241
|
+
* The nested_attributes plugin no longer allows modification of
|
242
|
+
keys related to the association. This fixes a possible security
|
243
|
+
issue with the plugin, where a user could associate the nested
|
244
|
+
record to a different record. For example:
|
245
|
+
|
246
|
+
Artist.one_to_many :albums
|
247
|
+
Artist.plugin :nested_attributes
|
248
|
+
Artist.nested_attributes :albums
|
249
|
+
artist = Artist.create
|
250
|
+
artist2 = Artist.create
|
251
|
+
album = Album.create
|
252
|
+
artist.add_album(album)
|
253
|
+
artist.albums_attributes = [{:id=>album.id,
|
254
|
+
:artist_id=>artist2.id}]
|
255
|
+
artist.save
|
256
|
+
|
257
|
+
* The one_to_many remove_* association method now makes sure that the
|
258
|
+
object to be removed is currently associated to this object.
|
259
|
+
Before, the method could be abused to disassociate the object from
|
260
|
+
whatever object it was associated to.
|
261
|
+
|
262
|
+
* Model add_ and remove_ association methods now check that the passed
|
263
|
+
object is of the correct class.
|
264
|
+
|
265
|
+
* Calling the add_* association method no longer adds the record
|
266
|
+
to the cached association array if the object is already in the
|
267
|
+
array. Previously, Sequel did this for reciprocal associations,
|
268
|
+
but not for regular associations.
|
269
|
+
|
270
|
+
This makes the most sense for one_to_many associations, since
|
271
|
+
those can only be associated to the object once. For many_to_many
|
272
|
+
associations, if you want an option to disable the behavior, please
|
273
|
+
bring it up on the Sequel mailing list.
|
274
|
+
|
275
|
+
* An array with a string and placeholders that is passed to
|
276
|
+
Dataset#filter is no longer modified. Previously:
|
277
|
+
|
278
|
+
options = ["name like ?", "%dog%"]
|
279
|
+
DB[:players].where(options)
|
280
|
+
options # => ["%dog%"]
|
281
|
+
|
282
|
+
* Getting the most recently inserted autoincremented primary key
|
283
|
+
is now optimized when connecting to MySQL via JDBC.
|
284
|
+
|
285
|
+
* Model.inherited now calls Class.inherited.
|
286
|
+
|
287
|
+
* The MSSQL shared adapter once again works on ruby 1.9. It was
|
288
|
+
broken in 3.5.0 due to minor syntax issues.
|
289
|
+
|
290
|
+
* The force_encoding plugin now handles refreshing an existing
|
291
|
+
object, either explicitly or implicitly when new objects are
|
292
|
+
created.
|
293
|
+
|
294
|
+
To use the force_encoding plugin with the identity_map plugin, the
|
295
|
+
identity_map plugin should be loaded first.
|
296
|
+
|
297
|
+
* Using nil as a bound variable now works on PostgreSQL. Before,
|
298
|
+
Sequel would incorrectly use "" instead of NULL, since it
|
299
|
+
transformed all objects to strings before binding them. Sequel
|
300
|
+
now binds the objects directly.
|
301
|
+
|
302
|
+
* The Amalgalite adapter is now significantly faster, especially for
|
303
|
+
code that modifies the schema or submits arbitrary SQL statements
|
304
|
+
using Database <<, run, or execute_ddl.
|
305
|
+
|
306
|
+
* Model#save_changes is now used when updating existing associated
|
307
|
+
objects in the nested_attributes plugin. This should be
|
308
|
+
significantly faster for the common case of submitting a complex
|
309
|
+
form with nested objects without making modifications.
|
310
|
+
|
311
|
+
* You can now prepare insert statements that take multiple arguments,
|
312
|
+
such as insert(1, 2, 3) and insert(columns, values).
|
313
|
+
|
314
|
+
* Dataset#group_and_count now supports aliased columns.
|
315
|
+
|
316
|
+
* Adding indexes to tables outside the default schema now works.
|
317
|
+
|
318
|
+
* Eager graphing now works better with models that use aliased tables.
|
319
|
+
|
320
|
+
* Sequel now correctly parses the column schema information for tables
|
321
|
+
in a non-default schema on Microsoft SQL Server.
|
322
|
+
|
323
|
+
* changed_columns is now cleared for when saving new model objects
|
324
|
+
for adapters that support insert_select, such as PostgreSQL.
|
325
|
+
|
326
|
+
* Dataset#replace on MySQL now works correctly when default values
|
327
|
+
are used.
|
328
|
+
|
329
|
+
* Dataset#lock on PostgreSQL now works correctly.
|
330
|
+
|
331
|
+
* Dataset#explain now works correctly on SQLite, and works using
|
332
|
+
any adapter. It also works correctly on Amalgalite.
|
333
|
+
|
334
|
+
* The JDBC adapter now handles binding Time arguments correctly when
|
335
|
+
using prepared statements.
|
336
|
+
|
337
|
+
* Model add_ and remove_ association methods now have more
|
338
|
+
descriptive exception messages.
|
339
|
+
|
340
|
+
* Dataset#simple_select_all? now ignores options that don't affect
|
341
|
+
the SQL, such as :server.
|
342
|
+
|
343
|
+
* Dataset#window in the PostgreSQL adapter now respects existing
|
344
|
+
named windows.
|
345
|
+
|
346
|
+
* Sequel now better handles a failure to begin a new transaction.
|
347
|
+
|
348
|
+
* The dataset code was split into some additional files for improved
|
349
|
+
readability.
|
350
|
+
|
351
|
+
* Many documentation improvements were made.
|
352
|
+
|
353
|
+
Backwards Compatibility
|
354
|
+
-----------------------
|
355
|
+
|
356
|
+
* Model::Errors no longer uses a default proc, but emulates one in the
|
357
|
+
[] method. This is unlikely to have a negative affect unless you
|
358
|
+
are calling a method on it that doesn't call [] (maybe using it in
|
359
|
+
a C extension?).
|
360
|
+
|
361
|
+
* Model#table_name now only provides the alias if an aliased table is
|
362
|
+
used.
|
363
|
+
|
364
|
+
* The Sequel::Dataset::STOCK_COUNT_OPTS constant has been removed.
|
365
|
+
|
366
|
+
* Dataset#lock on PostgreSQL now returns nil instead of a dataset.
|