sequel 3.21.0 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +294 -0
- data/README.rdoc +20 -6
- data/Rakefile +20 -15
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +64 -27
- data/doc/opening_databases.rdoc +37 -10
- data/doc/prepared_statements.rdoc +16 -10
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/testing.rdoc +106 -0
- data/doc/transactions.rdoc +97 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +12 -1
- data/lib/sequel/adapters/amalgalite.rb +4 -0
- data/lib/sequel/adapters/db2.rb +95 -58
- data/lib/sequel/adapters/do.rb +12 -0
- data/lib/sequel/adapters/firebird.rb +25 -203
- data/lib/sequel/adapters/ibmdb.rb +440 -0
- data/lib/sequel/adapters/informix.rb +4 -19
- data/lib/sequel/adapters/jdbc/as400.rb +0 -7
- data/lib/sequel/adapters/jdbc/db2.rb +49 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +34 -0
- data/lib/sequel/adapters/jdbc/h2.rb +16 -5
- data/lib/sequel/adapters/jdbc/informix.rb +31 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +2 -27
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +46 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +34 -0
- data/lib/sequel/adapters/jdbc.rb +62 -29
- data/lib/sequel/adapters/mysql.rb +22 -139
- data/lib/sequel/adapters/mysql2.rb +9 -14
- data/lib/sequel/adapters/odbc/db2.rb +21 -0
- data/lib/sequel/adapters/odbc.rb +15 -3
- data/lib/sequel/adapters/oracle.rb +17 -1
- data/lib/sequel/adapters/postgres.rb +111 -16
- data/lib/sequel/adapters/shared/access.rb +21 -0
- data/lib/sequel/adapters/shared/db2.rb +290 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +85 -47
- data/lib/sequel/adapters/shared/mysql.rb +50 -7
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +143 -0
- data/lib/sequel/adapters/shared/oracle.rb +0 -4
- data/lib/sequel/adapters/shared/postgres.rb +75 -43
- data/lib/sequel/adapters/shared/sqlite.rb +56 -8
- data/lib/sequel/adapters/sqlite.rb +12 -11
- data/lib/sequel/adapters/swift/mysql.rb +9 -0
- data/lib/sequel/adapters/tinytds.rb +139 -7
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +55 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +6 -5
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +1 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +38 -17
- data/lib/sequel/database/query.rb +50 -19
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +52 -27
- data/lib/sequel/dataset/actions.rb +167 -48
- data/lib/sequel/dataset/features.rb +57 -8
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +39 -20
- data/lib/sequel/dataset/mutation.rb +3 -3
- data/lib/sequel/dataset/prepared_statements.rb +29 -14
- data/lib/sequel/dataset/query.rb +182 -32
- data/lib/sequel/dataset/sql.rb +31 -58
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +893 -309
- data/lib/sequel/model/base.rb +302 -105
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +13 -7
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/identity_map.rb +113 -6
- data/lib/sequel/plugins/many_through_many.rb +67 -5
- data/lib/sequel/plugins/prepared_statements.rb +140 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -20
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -0
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +12 -3
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +36 -0
- data/spec/adapters/mysql_spec.rb +36 -19
- data/spec/adapters/postgres_spec.rb +115 -28
- data/spec/adapters/spec_helper.rb +6 -0
- data/spec/adapters/sqlite_spec.rb +11 -0
- data/spec/core/connection_pool_spec.rb +62 -77
- data/spec/core/database_spec.rb +244 -287
- data/spec/core/dataset_spec.rb +383 -34
- data/spec/core/expression_filters_spec.rb +159 -41
- data/spec/core/schema_spec.rb +326 -3
- data/spec/core/spec_helper.rb +45 -0
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/nested_attributes_spec.rb +1 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +12 -20
- data/spec/extensions/serialization_modification_detection_spec.rb +36 -0
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +3 -1
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +405 -15
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +240 -20
- data/spec/integration/plugin_test.rb +142 -5
- data/spec/integration/prepared_statement_test.rb +174 -95
- data/spec/integration/schema_test.rb +128 -16
- data/spec/integration/spec_helper.rb +15 -0
- data/spec/integration/transaction_test.rb +40 -0
- data/spec/integration/type_test.rb +16 -2
- data/spec/model/association_reflection_spec.rb +91 -0
- data/spec/model/associations_spec.rb +476 -5
- data/spec/model/base_spec.rb +91 -1
- data/spec/model/eager_loading_spec.rb +519 -31
- data/spec/model/hooks_spec.rb +161 -0
- data/spec/model/model_spec.rb +89 -2
- data/spec/model/plugins_spec.rb +17 -0
- data/spec/model/record_spec.rb +184 -12
- data/spec/model/spec_helper.rb +5 -0
- data/spec/model/validations_spec.rb +11 -0
- metadata +85 -34
data/doc/model_hooks.rdoc
CHANGED
|
@@ -4,7 +4,7 @@ This guide is based on http://guides.rubyonrails.org/activerecord_validations_ca
|
|
|
4
4
|
|
|
5
5
|
== Overview
|
|
6
6
|
|
|
7
|
-
Model hooks, also known as model callbacks, are used to specify actions that occur at a given point in a model instance's lifecycle, such as before or after the model object is saved, created, updated, destroyed, or validated.
|
|
7
|
+
Model hooks, also known as model callbacks, are used to specify actions that occur at a given point in a model instance's lifecycle, such as before or after the model object is saved, created, updated, destroyed, or validated. There are also around hooks for all types, which wrap the before hooks, the behavior, and the after hooks.
|
|
8
8
|
|
|
9
9
|
== Basic Usage
|
|
10
10
|
|
|
@@ -23,41 +23,51 @@ The one important thing to note here is the call to +super+ inside the hook. Wh
|
|
|
23
23
|
|
|
24
24
|
Sequel calls hooks in the following order when saving/creating a new object (one that does not already exist in the database):
|
|
25
25
|
|
|
26
|
-
* +
|
|
27
|
-
* +
|
|
28
|
-
* +
|
|
29
|
-
* +
|
|
30
|
-
*
|
|
31
|
-
* +
|
|
32
|
-
* +
|
|
26
|
+
* +around_validation+
|
|
27
|
+
* +before_validation+
|
|
28
|
+
* +validate+ method called
|
|
29
|
+
* +after_validation+
|
|
30
|
+
* +around_save+
|
|
31
|
+
* +before_save+
|
|
32
|
+
* +around_create+
|
|
33
|
+
* +before_create+
|
|
34
|
+
* INSERT QUERY
|
|
35
|
+
* +after_create+
|
|
36
|
+
* +after_save+
|
|
33
37
|
|
|
34
38
|
Sequel calls hooks in the following order when saving an existing object:
|
|
35
39
|
|
|
36
|
-
* +
|
|
37
|
-
* +
|
|
38
|
-
* +
|
|
39
|
-
* +
|
|
40
|
-
*
|
|
41
|
-
* +
|
|
42
|
-
* +
|
|
40
|
+
* +around_validation+
|
|
41
|
+
* +before_validation+
|
|
42
|
+
* +validate+ method called
|
|
43
|
+
* +after_validation+
|
|
44
|
+
* +around_save+
|
|
45
|
+
* +before_save+
|
|
46
|
+
* +around_update+
|
|
47
|
+
* +before_update+
|
|
48
|
+
* INSERT QUERY
|
|
49
|
+
* +after_update+
|
|
50
|
+
* +after_save+
|
|
43
51
|
|
|
44
|
-
Note that all of the hook calls are the same, except that +before_create+ and +after_create+ are used for a new object, and +before_update+ and +after_update+ are used for an existing object. Note that +
|
|
52
|
+
Note that all of the hook calls are the same, except that +around_create+, +before_create+ and +after_create+ are used for a new object, and +around_update+, +before_update+ and +after_update+ are used for an existing object. Note that +around_save+, +before_save+, and +after_save+ are called in both cases.
|
|
45
53
|
|
|
46
54
|
Also note that the validation hooks are not called if the <tt>:validate => false</tt> option is passed to save. However, the validation hooks are called if you call <tt>Model#valid?</tt> manually:
|
|
47
55
|
|
|
48
|
-
* +
|
|
49
|
-
*
|
|
50
|
-
* +
|
|
56
|
+
* +around_validation+
|
|
57
|
+
* +before_validation+
|
|
58
|
+
* +validate+ method called
|
|
59
|
+
* +after_validation+
|
|
51
60
|
|
|
52
61
|
Sequel calls hooks in the following order when destroying an existing object:
|
|
53
62
|
|
|
54
|
-
* +
|
|
55
|
-
*
|
|
56
|
-
*
|
|
63
|
+
* +around_destroy+
|
|
64
|
+
* +before_destroy+
|
|
65
|
+
* DELETE QUERY
|
|
66
|
+
* +after_destroy+
|
|
57
67
|
|
|
58
68
|
Note that these hooks are only called when using <tt>Model#destroy</tt>, they are not called if you use <tt>Model#delete</tt>.
|
|
59
69
|
|
|
60
|
-
<tt>Sequel::Model</tt> does support one additional hook, +after_intialize+, which is called after the model object has been initalized. It can be used to set default attribute values for new objects, since by default new <tt>Sequel::Model</tt> objects have no attributes, and the attributes are not filled in until the model object is saved. You should be careful when you are using +after_initialize+, since it is called for every created record. So if you run a query that returns 1000 model objects, it will be called 1000 times.
|
|
70
|
+
<tt>Sequel::Model</tt> does support one additional hook, +after_intialize+, which is called after the model object has been initalized. It can be used to set default attribute values for new objects, since by default new <tt>Sequel::Model</tt> objects have no attributes, and the attributes are not filled in until the model object is saved. You should be careful when you are using +after_initialize+, since it is called for every created record. So if you run a query that returns 1000 model objects, it will be called 1000 times. If you only want to change the behavior for new records, you can override the +initialize_set+ private method, which is called with the hash passed to +initialize+.
|
|
61
71
|
|
|
62
72
|
== Running Hooks
|
|
63
73
|
|
|
@@ -98,7 +108,7 @@ If you want to insert a row into the model's table without running the creation
|
|
|
98
108
|
|
|
99
109
|
== Halting Hook Processing
|
|
100
110
|
|
|
101
|
-
Sequel uses a convention that if any <tt>before_*</tt> hook method returns false (but not nil), that the action will be canceled. You can use this to implement validation-like behavior, that will run even if validations are skipped. For example:
|
|
111
|
+
Sequel uses a convention that if any <tt>before_*</tt> hook method returns false (but not nil), that the action will be canceled and a <tt>Sequel::HookFailed</tt> raised (or +nil+ to be returned by +save+ if +raise_on_save_failure+ is +false+). You can use this to implement validation-like behavior, that will run even if validations are skipped. For example:
|
|
102
112
|
|
|
103
113
|
class Album < Sequel::Model
|
|
104
114
|
def before_save
|
|
@@ -107,9 +117,9 @@ Sequel uses a convention that if any <tt>before_*</tt> hook method returns false
|
|
|
107
117
|
end
|
|
108
118
|
end
|
|
109
119
|
|
|
110
|
-
While returning false is not really recommended, you should be aware of this behavior so that you do not inadvertently return false.
|
|
120
|
+
While returning false is not really recommended, you should be aware of this behavior so that you do not inadvertently return false. For around hooks, neglecting to call +super+ halts hook processing in the same way as returning +false+ in a before hook. You can't halt hook processing in after hooks, since by then the main processing has already taken place.
|
|
111
121
|
|
|
112
|
-
By default, Sequel runs hooks other than validation hooks inside a transaction, so if you abort the hook by returning false in a before hook or by raising an exception in
|
|
122
|
+
By default, Sequel runs hooks other than validation hooks inside a transaction, so if you abort the hook by returning false in a before hook or by raising an exception in any hook, Sequel will rollback the transaction. However, note that the implicit use of transactions when saving and destroying model objects is conditional (it depends on the model instance's +use_transactions+ setting and the <tt>:transaction</tt> option passed to save).
|
|
113
123
|
|
|
114
124
|
== Conditional Hooks
|
|
115
125
|
|
|
@@ -183,6 +193,7 @@ This allows the following general principles to be true:
|
|
|
183
193
|
|
|
184
194
|
* before hooks are run in reverse order of inclusion
|
|
185
195
|
* after hooks are run in order of inclusion
|
|
196
|
+
* returning false in any before hook will pass the false value down the hook method chain, halting the hook processing.
|
|
186
197
|
|
|
187
198
|
So if you define the same before hook in both a model and a plugin that the model uses, the hooks will be called in this order:
|
|
188
199
|
|
|
@@ -193,6 +204,32 @@ So if you define the same before hook in both a model and a plugin that the mode
|
|
|
193
204
|
|
|
194
205
|
Again, Sequel does not enforce that, and you are free to call +super+ in an order other than the recommended one (just make sure that you call it).
|
|
195
206
|
|
|
207
|
+
== Around Hooks
|
|
208
|
+
|
|
209
|
+
Around hooks should only be used if you cannot accomplish the same results with before and after hooks. For example, if you want to catch database errors caused by the +INSERT+ or +UPDATE+ query when saving a model object and raise them as validation errors, you cannot use a before or after hook. You have use an +around_save+ hook:
|
|
210
|
+
|
|
211
|
+
class Album < Sequel::Model
|
|
212
|
+
def around_save
|
|
213
|
+
super
|
|
214
|
+
rescue Sequel::DatabaseError => e
|
|
215
|
+
# parse database error, set error on self, and reraise a Sequel::ValidationFailed
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
Likewise, let's say that upon retrieval, you associate an object with a file descriptor, and you want to ensure that the file descriptor is closed after the object is saved to the database. Let's assume you are always saving the object and you are not using validations. You could not use an +after_save+ hook safely, since if the database raises an error, the +after_save+ method will not be called. In this case, an +around_save+ hook is also the correct choice:
|
|
220
|
+
|
|
221
|
+
class Album < Sequel::Model
|
|
222
|
+
def around_save
|
|
223
|
+
super
|
|
224
|
+
ensure
|
|
225
|
+
@file_descriptor.close
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
196
229
|
== +hook_class_methods+
|
|
197
230
|
|
|
198
|
-
While it's recommended to write your hooks as instance methods, Sequel ships with a +hook_class_methods+ plugin that allows you to define hooks via class methods. It exists mostly for legacy compatibility, but is still supported.
|
|
231
|
+
While it's recommended to write your hooks as instance methods, Sequel ships with a +hook_class_methods+ plugin that allows you to define hooks via class methods. It exists mostly for legacy compatibility, but is still supported. However, it does not implement around hooks.
|
|
232
|
+
|
|
233
|
+
== +instance_hooks+
|
|
234
|
+
|
|
235
|
+
Sequel also ships with an +instance_hooks+ plugin that allows you to define before and after hooks on a per instance basis. It's very useful as it allows you to delay action on an instance until before or after saving. This can be important if you want to modify a group of related objects together (which is how the +nested_attributes+ plugin uses +instance_hooks+).
|
data/doc/opening_databases.rdoc
CHANGED
|
@@ -46,6 +46,13 @@ unless the first argument is a hash. So the following statements are equivalent
|
|
|
46
46
|
DB = Sequel.postgres('blog', :host=>'localhost', :user=>'user', :password=>'password')
|
|
47
47
|
DB = Sequel.postgres(:host=>'localhost', :user=>'user', :password=>'password', :database=>'blog')
|
|
48
48
|
|
|
49
|
+
Note that using an adapter method forces the use of the specified adapter, not a database type, even
|
|
50
|
+
though some adapters have the same name as the database type. So if you
|
|
51
|
+
want to connect to SQLite, for example, you can do so using the sqlite, do, dbi, jdbc, odbc, and swift adapters.
|
|
52
|
+
If you want to connect to SQLite on JRuby using the jdbc adapter, you should not use <tt>Sequel.sqlite</tt>
|
|
53
|
+
for example, as that uses the C-based sqlite3 gem. Instead, the <tt>Sequel.jdbc</tt> would be appropriate (though
|
|
54
|
+
as mentioned below, using <tt>Sequel.connect</tt> is recommended instead of <tt>Sequel.jdbc</tt>).
|
|
55
|
+
|
|
49
56
|
== Passing a block to either method
|
|
50
57
|
|
|
51
58
|
Both the Sequel.connect method and the specialized adapter methods take a block. If you
|
|
@@ -145,10 +152,8 @@ the sqlite section below for details.
|
|
|
145
152
|
|
|
146
153
|
Requires: db2/db2cli
|
|
147
154
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
get a handle, and respects the :database, :user, and :password options. It doesn't
|
|
151
|
-
appear to respect the :host or :port options.
|
|
155
|
+
This is the older DB2 adapter. It's recommended you try the ibmdb adapter
|
|
156
|
+
instead for new DB2 work, as it is better supported.
|
|
152
157
|
|
|
153
158
|
=== dbi
|
|
154
159
|
|
|
@@ -201,6 +206,13 @@ Requires: fb (using code at http://github.com/wishdev/fb)
|
|
|
201
206
|
|
|
202
207
|
Does not support the :port option.
|
|
203
208
|
|
|
209
|
+
=== ibmdb
|
|
210
|
+
|
|
211
|
+
requires 'ibm_db'
|
|
212
|
+
|
|
213
|
+
This connects to DB2 using IBM_DB. This is the recommended adapter if you are
|
|
214
|
+
using a C-based ruby to connect to DB2.
|
|
215
|
+
|
|
204
216
|
=== informix
|
|
205
217
|
|
|
206
218
|
Does not support the :host or :port options. Depending on the configuration of your server
|
|
@@ -221,7 +233,7 @@ Requires: java
|
|
|
221
233
|
Houses Sequel's JDBC support when running on JRuby.
|
|
222
234
|
Support for individual database types is done using sub adapters.
|
|
223
235
|
There are currently subadapters for PostgreSQL, MySQL, SQLite, H2,
|
|
224
|
-
Oracle, MSSQL, JTDS, and
|
|
236
|
+
Oracle, MSSQL, JTDS, AS400, and DB2. All except Oracle, MSSQL, AS400, and DB2 can load the
|
|
225
237
|
jdbc-* gem, for those you need to have the .jar in your CLASSPATH
|
|
226
238
|
or load the Java class manually before calling Sequel.connect.
|
|
227
239
|
|
|
@@ -262,6 +274,8 @@ The following additional options are supported:
|
|
|
262
274
|
|
|
263
275
|
=== mysql
|
|
264
276
|
|
|
277
|
+
Requires: mysqlplus (or mysql if mysqlplus is not available)
|
|
278
|
+
|
|
265
279
|
The MySQL adapter does not support the pure-ruby MySQL adapter that used to ship with
|
|
266
280
|
ActiveRecord, it requires the native adapter.
|
|
267
281
|
|
|
@@ -278,6 +292,12 @@ The following additional options are supported:
|
|
|
278
292
|
* :read_timeout - Set the timeout in seconds for reading back results to a query.
|
|
279
293
|
* :connect_timeout - Set the timeout in seconds before a connection attempt is abandoned.
|
|
280
294
|
|
|
295
|
+
=== mysql2
|
|
296
|
+
|
|
297
|
+
This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
|
|
298
|
+
mysql adapter. Supports the same additional options as the mysql adapter, except for :compress, and uses
|
|
299
|
+
:timeout instead of :read_timeout and :connect_timeout.
|
|
300
|
+
|
|
281
301
|
=== odbc
|
|
282
302
|
|
|
283
303
|
The ODBC adapter allows you to connect to any database with the appropriate ODBC drivers installed.
|
|
@@ -316,6 +336,8 @@ The following additional options are supported:
|
|
|
316
336
|
|
|
317
337
|
=== sqlite
|
|
318
338
|
|
|
339
|
+
Requires: sqlite3
|
|
340
|
+
|
|
319
341
|
As SQLite is a file-based database, the :host and :port options are ignored, and
|
|
320
342
|
the :database option should be a path to the file.
|
|
321
343
|
|
|
@@ -353,16 +375,21 @@ Examples:
|
|
|
353
375
|
|
|
354
376
|
=== tinytds
|
|
355
377
|
|
|
378
|
+
Requires: tiny_tds
|
|
379
|
+
|
|
356
380
|
Because the underscore is not a valid character in a URI schema, the adapter
|
|
357
381
|
is named tinytds instead of tiny_tds. The connection options are passed directly
|
|
358
|
-
to tiny_tds, except that the tiny_tds :
|
|
359
|
-
the Sequel :
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
:
|
|
382
|
+
to tiny_tds, except that the tiny_tds :username option is set to
|
|
383
|
+
the Sequel :user option. If you want to use an entry in the freetds.conf file, you
|
|
384
|
+
should specify the :dataserver option with that name as the value. Some other
|
|
385
|
+
options that you may want to set are :login_timeout, :timeout, :tds_version, :azure,
|
|
386
|
+
:appname, and :encoding, see the tiny_tds README for details.
|
|
387
|
+
|
|
363
388
|
For highest performance, you should disable any identifier output method when
|
|
364
389
|
using the tinytds adapter, which probably means disabling any identifier input method
|
|
365
390
|
as well. The default for Microsoft SQL Server is to :downcase identifiers on output
|
|
366
391
|
and :upcase them on input, so the highest performance will require changing the setting
|
|
367
392
|
from the default.
|
|
368
393
|
|
|
394
|
+
The Sequel tinytds adapter requires tiny_tds >= 0.4.5, and if you are using FreeTDS
|
|
395
|
+
0.91, you must at least be using 0.91rc2 (0.91rc1 does not work).
|
|
@@ -3,15 +3,21 @@
|
|
|
3
3
|
Sequel has support for prepared statements and bound variables. No matter which
|
|
4
4
|
database you are using, the Sequel prepared statement/bound variable API remains
|
|
5
5
|
the same. There is native support for prepared statements/bound variables on
|
|
6
|
-
the following
|
|
6
|
+
the following adapters:
|
|
7
7
|
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* ibmdb (prepared statements only)
|
|
9
|
+
* jdbc
|
|
10
|
+
* mysql (prepared statements only)
|
|
11
|
+
* mysql2 (prepared statements only)
|
|
12
|
+
* postgres (when using the pg driver, may require type specifiers)
|
|
13
|
+
* sqlite
|
|
14
|
+
* tinytds
|
|
13
15
|
|
|
14
|
-
Support on other
|
|
16
|
+
Support on other adapters is emulated via string interpolation.
|
|
17
|
+
|
|
18
|
+
You can use the prepared_statements model plugin to automatically use prepared
|
|
19
|
+
statements for some common model actions such as saving or deleting a model
|
|
20
|
+
instance, or looking up a model based on a primary key.
|
|
15
21
|
|
|
16
22
|
== Placeholders
|
|
17
23
|
|
|
@@ -74,9 +80,9 @@ and update queries, the hash to insert/update is passed to +prepare+:
|
|
|
74
80
|
|
|
75
81
|
If you are using the ruby-postgres or postgres-pr driver, PostgreSQL uses the
|
|
76
82
|
default emulated support. If you are using ruby-pg, there is native support,
|
|
77
|
-
but it
|
|
83
|
+
but it may require type specifiers. This is easy if you have
|
|
78
84
|
direct control over the SQL string, but since Sequel abstracts that, the types
|
|
79
|
-
|
|
85
|
+
can be specified another way. This is done by adding a __* suffix to the
|
|
80
86
|
placeholder symbol (e.g. :$name__text, which will be compiled to "$1::text"
|
|
81
87
|
in the SQL). Prepared statements are always server side.
|
|
82
88
|
|
|
@@ -87,7 +93,7 @@ statements are cached per connection.
|
|
|
87
93
|
|
|
88
94
|
=== MySQL
|
|
89
95
|
|
|
90
|
-
The MySQL ruby driver does not support bound variables, so the
|
|
96
|
+
The MySQL ruby driver does not support bound variables, so the bound
|
|
91
97
|
variable methods fall back to string interpolation. It uses server side
|
|
92
98
|
prepared statements.
|
|
93
99
|
|
data/doc/reflection.rdoc
CHANGED
|
@@ -16,13 +16,19 @@ In some cases, the adapter scheme will be the same as the database to which you
|
|
|
16
16
|
|
|
17
17
|
== Tables in the Database
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Database#tables gives an array of table name symbols:
|
|
20
|
+
|
|
21
|
+
DB.tables # [:table1, :table2, :table3, ...]
|
|
22
|
+
|
|
23
|
+
== Views in the Database
|
|
24
|
+
|
|
25
|
+
Database#views and gives an array of view name symbols:
|
|
20
26
|
|
|
21
27
|
DB.tables # [:table1, :table2, :table3, ...]
|
|
22
28
|
|
|
23
29
|
== Indexes on a table
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
Database#indexes takes a table name gives a hash of index information. Keys are index names, values are subhashes with the keys :columns and :unique :
|
|
26
32
|
|
|
27
33
|
DB.indexes(:table1) # {:index1=>{:columns=>[:column1], :unique=>false}, :index2=>{:columns=>[:column2, :column3], :unique=>true}}
|
|
28
34
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* Support COLLATE in column definitions. At least MySQL and Microsoft
|
|
4
|
+
SQL Server support them, and PostgreSQL 9.1 should as well.
|
|
5
|
+
|
|
6
|
+
* When connecting to Microsoft SQL Server, you can use the
|
|
7
|
+
mssql_unicode_strings accessor to turn of the default usage
|
|
8
|
+
of unicode strings (N'') and use regular strings (''). This
|
|
9
|
+
can improve performance, but changes the behavior. It's
|
|
10
|
+
set to true by default for backwards compatibility. You can
|
|
11
|
+
change it at both the dataset and database level:
|
|
12
|
+
|
|
13
|
+
DB.mssql_unicode_strings = false # default for datasets
|
|
14
|
+
dataset.mssql_unicode_strings = false # just this dataset
|
|
15
|
+
|
|
16
|
+
* In the oracle adapter, if Sequel.application_timezone is :utc, set
|
|
17
|
+
the timezone for the connection to use the 00:00 timezone.
|
|
18
|
+
|
|
19
|
+
= Other Improvements
|
|
20
|
+
|
|
21
|
+
* In the single_table_inheritance plugin, correctly handle a
|
|
22
|
+
multi-level class hierarchy so that loading instances from a
|
|
23
|
+
middle level of the hierarchy can return instances of subclasses.
|
|
24
|
+
|
|
25
|
+
* Don't use a schema when creating a temporary table, even if
|
|
26
|
+
default_schema is set.
|
|
27
|
+
|
|
28
|
+
* Fix the migrator when a default_schema is used.
|
|
29
|
+
|
|
30
|
+
* In the ado adapter, assume a connection to SQL Server if the
|
|
31
|
+
:conn_string is given and doesn't indicate Access/Jet.
|
|
32
|
+
|
|
33
|
+
* Fix fetching rows in the tinytds adapter when the
|
|
34
|
+
identifier_output_method is nil.
|
|
35
|
+
|
|
36
|
+
* The tinytds adapter now checks for disconnect errors, but it might
|
|
37
|
+
not be reliable until the next release of tiny_tds.
|
|
38
|
+
|
|
39
|
+
* The odbc adapter now handles ODBC::Time instances correctly.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* Sequel now allows dynamic customization for eager loading.
|
|
4
|
+
Previously, the parameters for eager loading were fixed at
|
|
5
|
+
association creation time. Now, they can be modified at query
|
|
6
|
+
time. To dynamically modify an eager load, you use a hash with
|
|
7
|
+
the proc as the value. For example, if you have this code:
|
|
8
|
+
|
|
9
|
+
Artist.eager(:albums)
|
|
10
|
+
|
|
11
|
+
And you only want to eagerly load albums where the id is greater
|
|
12
|
+
than or equal to some number provided by the user, you do:
|
|
13
|
+
|
|
14
|
+
min = params[:min].to_i
|
|
15
|
+
Artist.eager(:albums=>proc{|ds| ds.where{id > min}})
|
|
16
|
+
|
|
17
|
+
This also works when eager loading via eager_graph:
|
|
18
|
+
|
|
19
|
+
Artist.eager_graph(:albums=>proc{|ds| ds.where{id > min}})
|
|
20
|
+
|
|
21
|
+
For eager_graph, the dataset is the dataset to graph into the
|
|
22
|
+
current dataset, and filtering it will result in an SQL query
|
|
23
|
+
that joins to a subquery.
|
|
24
|
+
|
|
25
|
+
You can also use dynamic customization while cascading to also
|
|
26
|
+
eagerly load dependent associations, by making the hash value
|
|
27
|
+
a single entry hash with a proc key and the value being the
|
|
28
|
+
dependent associations to eagerly load. For example, if you want
|
|
29
|
+
to eagerly load tracks for those albums:
|
|
30
|
+
|
|
31
|
+
Artist.eager(:albums=>{proc{|ds| ds.where{id > min}}=>:tracks})
|
|
32
|
+
|
|
33
|
+
* Sequel also now allows dynamic customization for regular
|
|
34
|
+
association loading. Previously, this was possible by using the
|
|
35
|
+
association's dataset:
|
|
36
|
+
|
|
37
|
+
albums = artist.albums_dataset.filter{id > min}
|
|
38
|
+
|
|
39
|
+
However, then there was no handling of caching, callbacks, or
|
|
40
|
+
reciprocals. For example:
|
|
41
|
+
|
|
42
|
+
albums.each{|album| album.artist}
|
|
43
|
+
|
|
44
|
+
Would issue one query per album to get the artist, because the
|
|
45
|
+
reciprocal association was not set. Now you can provide a
|
|
46
|
+
block to the association method:
|
|
47
|
+
|
|
48
|
+
albums = artist.albums{|ds| ds.filter{id > min}}
|
|
49
|
+
|
|
50
|
+
This block is called with the dataset used to retrieve the
|
|
51
|
+
associated objects, and should return a modified version of that
|
|
52
|
+
dataset.
|
|
53
|
+
|
|
54
|
+
Note that ruby 1.8.6 doesn't allow blocks to take block arguments,
|
|
55
|
+
so you have to pass the block as a separate proc argument to the
|
|
56
|
+
association method if you are still using 1.8.6.
|
|
57
|
+
|
|
58
|
+
* Sequel now supports filtering by associations. This wasn't
|
|
59
|
+
previously supported as filtering is a dataset level feature and
|
|
60
|
+
associations are a model level feature, and datasets do not depend
|
|
61
|
+
on models. Now, model datasets have the ability to filter by
|
|
62
|
+
associations. For example, to get all albums for a given artist,
|
|
63
|
+
you could do:
|
|
64
|
+
|
|
65
|
+
artist = Artist[1]
|
|
66
|
+
Album.filter(:artist=>artist)
|
|
67
|
+
|
|
68
|
+
Since the above can also be accomplished with:
|
|
69
|
+
|
|
70
|
+
artist.albums
|
|
71
|
+
|
|
72
|
+
this may not seem like a big improvement, but it allows you to
|
|
73
|
+
filter on multiple associations simultaneously:
|
|
74
|
+
|
|
75
|
+
Album.filter(:artist=>artist, :publisher=>publisher)
|
|
76
|
+
|
|
77
|
+
For simple many_to_one associations, the above is just a simpler
|
|
78
|
+
way to do:
|
|
79
|
+
|
|
80
|
+
Album.filter(:artist_id=>artist.id, :publisher_id=>publisher.id)
|
|
81
|
+
|
|
82
|
+
Sequel supports this for all association types, including
|
|
83
|
+
many_to_many and many_through_many, where a subquery is used, and
|
|
84
|
+
it also works when composite key associations are used:
|
|
85
|
+
|
|
86
|
+
Album.filter(:artist=>artist, :tags=>tag)
|
|
87
|
+
|
|
88
|
+
This will give you the albums for that artist that are also tagged
|
|
89
|
+
with that tag. To provide multiple values for the same
|
|
90
|
+
association, mostly useful for many_to_many associations, you can
|
|
91
|
+
either use separate filter calls or specify the conditions as an
|
|
92
|
+
array:
|
|
93
|
+
|
|
94
|
+
Album.filter(:tags=>tag1).filter(:tags=>tag2)
|
|
95
|
+
Album.filter([[:tags, tag1], [:tags, tag2]])
|
|
96
|
+
|
|
97
|
+
* A columns_introspection extension has been added that makes
|
|
98
|
+
datasets attempt to guess their columns in some cases instead of
|
|
99
|
+
issuing a database query. This can improve performance in cases
|
|
100
|
+
where the columns are needed implicitly, such as graphing. After
|
|
101
|
+
loading the extension, you can enable the support for specific
|
|
102
|
+
datasets by extending them with Sequel::ColumnIntrospection. To
|
|
103
|
+
enable introspection for all datasets, use:
|
|
104
|
+
|
|
105
|
+
Sequel::Dataset.introspect_all_columns
|
|
106
|
+
|
|
107
|
+
* A serialization_modification_detection plugin has been added.
|
|
108
|
+
Previously, Sequel could not detect modifications made to
|
|
109
|
+
serialized objects. It could detect modification if you assigned
|
|
110
|
+
a new value:
|
|
111
|
+
|
|
112
|
+
model.hash_column = model.hash_column.merge(:foo=>:bar)
|
|
113
|
+
|
|
114
|
+
but not if you just modified the object directly:
|
|
115
|
+
|
|
116
|
+
model.hash_columns[:foo] = :bar
|
|
117
|
+
|
|
118
|
+
With this plugin, such modifications can be detected, at a
|
|
119
|
+
potentially significant performance cost.
|
|
120
|
+
|
|
121
|
+
= Other Improvements
|
|
122
|
+
|
|
123
|
+
* When using a migration directory containing both older integer
|
|
124
|
+
migrations and newer timestamp migrations, where some integer
|
|
125
|
+
migrations have not been applied, make sure to apply the remaining
|
|
126
|
+
integer migrations before the timestamp migrations. Previously,
|
|
127
|
+
they could be applied out of order due to a lexicographic sort
|
|
128
|
+
being used instead of a numeric sort.
|
|
129
|
+
|
|
130
|
+
* If a model does not select all columns from its table, the
|
|
131
|
+
insert_select optimization is no longer used. Previously,
|
|
132
|
+
creating a new model object for such a model could result in the
|
|
133
|
+
object containing columns that the model does not select.
|
|
134
|
+
|
|
135
|
+
* You can now use :select=>[] as an option for many_to_many
|
|
136
|
+
associations to select all columns from both the associated
|
|
137
|
+
table and the join table. Previously, this raised an error and
|
|
138
|
+
required you do :select=>'*'.lit as a workaround. The default
|
|
139
|
+
remains to select all columns in the associated table and none
|
|
140
|
+
from the join table.
|
|
141
|
+
|
|
142
|
+
* The xml_serializer plugin now handles namespaced models by
|
|
143
|
+
using __ instead of / as the namespace separator. Previously, /
|
|
144
|
+
was used and caused problems as it is not valid XML.
|
|
145
|
+
|
|
146
|
+
* The :eager_grapher association option can now accept a proc that
|
|
147
|
+
takes a single hash of options instead of a fixed 3 arguments.
|
|
148
|
+
This is the recommended way going forward of writing custom
|
|
149
|
+
:eager_graphers, and all of the internal ones have been converted.
|
|
150
|
+
The previous way of using 3 arguments is still supported.
|
|
151
|
+
|
|
152
|
+
* A bug in the identity_map plugin for many_to_one associations
|
|
153
|
+
without full association reflection information has been fixed.
|
|
154
|
+
|
|
155
|
+
* Sequel is now using GitHub Issues for issue tracking. Old issues
|
|
156
|
+
have been migrated from Google Code.
|
|
157
|
+
|
|
158
|
+
= Backwards Compatibility
|
|
159
|
+
|
|
160
|
+
* The filter by associations support breaks backward compatibilty for
|
|
161
|
+
users who previously added an sql_literal instance method to
|
|
162
|
+
Sequel::Model. Usually, that was done to for reasons similar to
|
|
163
|
+
but inferior than the filter by association support. The following
|
|
164
|
+
code can be used as a temporary workaround until you can modify
|
|
165
|
+
your program to use the new filter by associations support:
|
|
166
|
+
|
|
167
|
+
Sequel::Model::Associations::DatasetMethods.
|
|
168
|
+
send(:remove_method, :complex_expression_sql)
|
|
169
|
+
|
|
170
|
+
* The private Sequel::Model#_load_associated_objects method now takes
|
|
171
|
+
an additional, optional options hash. Plugins that override that
|
|
172
|
+
method need to be modified.
|