sequel 3.21.0 → 3.32.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 +539 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- 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/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +52 -0
- data/lib/sequel/adapters/jdbc/derby.rb +260 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +66 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +339 -0
- data/lib/sequel/adapters/mysql.rb +85 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +355 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +328 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +278 -107
- data/lib/sequel/adapters/shared/mysql.rb +203 -65
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +237 -46
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +200 -50
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- 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 +68 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +163 -59
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +240 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +59 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +676 -267
- 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/named_timezones.rb +5 -0
- data/lib/sequel/extensions/query.rb +1 -1
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1081 -344
- data/lib/sequel/model/base.rb +420 -133
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +20 -10
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +43 -10
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +68 -7
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- data/lib/sequel/plugins/prepared_statements.rb +151 -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/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +135 -30
- data/spec/adapters/mysql_spec.rb +244 -212
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +789 -512
- data/spec/core/dataset_spec.rb +1176 -1061
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +81 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +661 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +500 -67
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +367 -119
- data/spec/integration/prepared_statement_test.rb +222 -125
- data/spec/integration/schema_test.rb +217 -39
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +182 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +955 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +117 -73
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,59 @@ 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
|
|
70
|
+
<tt>Sequel::Model</tt> does support a few additional hooks. One is +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+.
|
|
71
|
+
|
|
72
|
+
== Transaction-related Hooks
|
|
73
|
+
|
|
74
|
+
There are four other model hooks that <tt>Sequel::Model</tt> supports, all related to transactions. These are +after_commit+, +after_rollback+, +after_destroy_commit+, and +after_destroy_rollback+. +after_commit+ is called after the transaction in which you saved the object commits, only if it commits. +after_rollback+ is called after the transaction in which you saved the object rolls back, if it rolls back. +after_destroy_commit+ is called after the transaction in which you destroyed the object commits, if it commits. +after_destroy_rollback+ is called after the transaction in which you destroyed the object rolls back, if it rolls back.
|
|
75
|
+
|
|
76
|
+
If you aren't using transactions when saving or destroying model objects, and there isn't a currently open transaction, +after_commit+ and +after_destroy_commit+ will be called after +after_save+ and +after_destroy+, respectively, and +after_rollback+ and +after_destroy_rollback+ won't be called at all.
|
|
77
|
+
|
|
78
|
+
The purpose of these hooks is dealing with external systems that are interacting with the same database. For example, let's say you have a model that stores a picture, and you have a background job library that makes thumbnails of all of the pictures. So when a model object is created, you want to add a background job that will create the thumbnail for the picture. If you used after_save for this and transactions are being used, you are subject to a race condition where the background job library will check the database table for the record before the transaction that saved the record commits, and it won't be able to see the record's data. Using after_commit, you are guaranteed that the background job library will not get notified of the record until after the transaction commits and the data is viewable.
|
|
61
79
|
|
|
62
80
|
== Running Hooks
|
|
63
81
|
|
|
@@ -98,7 +116,7 @@ If you want to insert a row into the model's table without running the creation
|
|
|
98
116
|
|
|
99
117
|
== Halting Hook Processing
|
|
100
118
|
|
|
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:
|
|
119
|
+
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
120
|
|
|
103
121
|
class Album < Sequel::Model
|
|
104
122
|
def before_save
|
|
@@ -107,9 +125,9 @@ Sequel uses a convention that if any <tt>before_*</tt> hook method returns false
|
|
|
107
125
|
end
|
|
108
126
|
end
|
|
109
127
|
|
|
110
|
-
While returning false is not really recommended, you should be aware of this behavior so that you do not inadvertently return false.
|
|
128
|
+
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
129
|
|
|
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
|
|
130
|
+
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
131
|
|
|
114
132
|
== Conditional Hooks
|
|
115
133
|
|
|
@@ -183,6 +201,7 @@ This allows the following general principles to be true:
|
|
|
183
201
|
|
|
184
202
|
* before hooks are run in reverse order of inclusion
|
|
185
203
|
* after hooks are run in order of inclusion
|
|
204
|
+
* returning false in any before hook will pass the false value down the hook method chain, halting the hook processing.
|
|
186
205
|
|
|
187
206
|
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
207
|
|
|
@@ -193,6 +212,32 @@ So if you define the same before hook in both a model and a plugin that the mode
|
|
|
193
212
|
|
|
194
213
|
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
214
|
|
|
215
|
+
== Around Hooks
|
|
216
|
+
|
|
217
|
+
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:
|
|
218
|
+
|
|
219
|
+
class Album < Sequel::Model
|
|
220
|
+
def around_save
|
|
221
|
+
super
|
|
222
|
+
rescue Sequel::DatabaseError => e
|
|
223
|
+
# parse database error, set error on self, and reraise a Sequel::ValidationFailed
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
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:
|
|
228
|
+
|
|
229
|
+
class Album < Sequel::Model
|
|
230
|
+
def around_save
|
|
231
|
+
super
|
|
232
|
+
ensure
|
|
233
|
+
@file_descriptor.close
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
196
237
|
== +hook_class_methods+
|
|
197
238
|
|
|
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.
|
|
239
|
+
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.
|
|
240
|
+
|
|
241
|
+
== +instance_hooks+
|
|
242
|
+
|
|
243
|
+
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
|
|
@@ -59,24 +66,24 @@ For example:
|
|
|
59
66
|
|
|
60
67
|
These options are shared by all adapters unless otherwise noted.
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
:adapter :: The adapter to use
|
|
70
|
+
:database :: The name of the database to which to connect
|
|
71
|
+
:default_schema :: The database schema to use by default.
|
|
72
|
+
:host :: The hostname of the database server to which to connect
|
|
73
|
+
:logger :: An array of SQL loggers to log to
|
|
74
|
+
:loggers :: An array of SQL loggers to log to
|
|
75
|
+
:password :: The password for the user account
|
|
76
|
+
:servers :: A hash with symbol keys and hash or proc values, used with master/slave/partitioned database configurations
|
|
77
|
+
:single_threaded :: Whether to use a single-threaded (non-thread safe) connection pool
|
|
78
|
+
:test :: Whether to test that a valid database connection can be made (false by default)
|
|
79
|
+
:user :: The user account name to use logging in
|
|
73
80
|
|
|
74
81
|
The following options can be specified and are passed to the the database's internal connection pool.
|
|
75
82
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
:after_connect :: A proc called after a new connection is made, with the connection object (default: nil)
|
|
84
|
+
:max_connections :: The maximum size of the connection pool (default: 4 connections on most databases)
|
|
85
|
+
:pool_sleep_time :: The number of seconds to sleep before trying to acquire a connection again (default: 0.001 seconds)
|
|
86
|
+
:pool_timeout :: The number of seconds to wait if a connection cannot be acquired before raising an error (default: 5 seconds)
|
|
80
87
|
|
|
81
88
|
== Adapter specific connection options
|
|
82
89
|
|
|
@@ -131,8 +138,8 @@ Amalgalite is an ruby extension that provides self contained access to SQLite,
|
|
|
131
138
|
so you don't need to install SQLite separately. As amalgalite is a file backed
|
|
132
139
|
database, the :host, :user, and :password options are not used.
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
|
|
141
|
+
:database :: The name of the database file
|
|
142
|
+
:timeout :: The busy timeout period given in milliseconds
|
|
136
143
|
|
|
137
144
|
Without a database argument, assumes a memory database, so you can do:
|
|
138
145
|
|
|
@@ -145,17 +152,15 @@ 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
|
|
|
155
160
|
Allows access to a multitude of databases via ruby-dbi. Additional options:
|
|
156
161
|
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
:db_type :: Specifying 'mssql' allows Microsoft SQL Server specific syntax to
|
|
163
|
+
be used. Otherwise has no effect.
|
|
159
164
|
|
|
160
165
|
DBI connection strings are a preprocessed a bit, and are specified with a dbi-
|
|
161
166
|
in front of the protocol. Examples:
|
|
@@ -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
|
|
|
@@ -246,37 +258,51 @@ Example connection strings:
|
|
|
246
258
|
jdbc:postgresql://localhost/database?user=username
|
|
247
259
|
jdbc:mysql://localhost/test?user=root&password=root
|
|
248
260
|
jdbc:h2:mem:
|
|
261
|
+
jdbc:hsqldb:mem:mymemdb
|
|
262
|
+
jdbc:derby:memory:myDb;create=true
|
|
249
263
|
jdbc:sqlserver://localhost;database=sequel_test;integratedSecurity=true
|
|
250
264
|
jdbc:jtds:sqlserver://localhost/sequel_test;user=sequel_test;password=sequel_test
|
|
251
|
-
|
|
265
|
+
jdbc:oracle:thin:user/password@localhost:1521:database
|
|
266
|
+
jdbc:db2://localhost:3700/database:user=user;password=password;
|
|
267
|
+
jdbc:firebirdsql:localhost/3050:/path/to/database.fdb
|
|
268
|
+
|
|
252
269
|
You can also use JNDI connection strings:
|
|
253
270
|
|
|
254
271
|
jdbc:jndi:java:comp/env/jndi_resource_name
|
|
255
272
|
|
|
256
273
|
The following additional options are supported:
|
|
257
274
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
275
|
+
:convert_types :: If set to false, does not attempt to convert some Java types to ruby types.
|
|
276
|
+
Setting to false roughly doubles performance when selecting large numbers of rows.
|
|
277
|
+
Note that you can't provide this option inside the connection string (as that is passed
|
|
278
|
+
directly to JDBC), you have to pass it as a separate option.
|
|
279
|
+
:login_timeout :: Set the login timeout on the JDBC connection (in seconds).
|
|
262
280
|
|
|
263
281
|
=== mysql
|
|
264
282
|
|
|
283
|
+
Requires: mysqlplus (or mysql if mysqlplus is not available)
|
|
284
|
+
|
|
265
285
|
The MySQL adapter does not support the pure-ruby MySQL adapter that used to ship with
|
|
266
286
|
ActiveRecord, it requires the native adapter.
|
|
267
287
|
|
|
268
288
|
The following additional options are supported:
|
|
269
289
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
290
|
+
:auto_is_null :: If set to true, makes "WHERE primary_key IS NULL" select the last inserted id.
|
|
291
|
+
:charset :: Same as :encoding, :encoding takes precedence.
|
|
292
|
+
:compress :: Whether to compress data sent/received via the socket connection.
|
|
293
|
+
:config_default_group :: The default group to read from the in the MySQL config file.
|
|
294
|
+
:config_local_infile :: If provided, sets the Mysql::OPT_LOCAL_INFILE option on the connection with the given value.
|
|
295
|
+
:encoding :: Specify the encoding/character set to use for the connection.
|
|
296
|
+
:socket :: Can be used to specify a Unix socket file to connect to instead of a TCP host and port.
|
|
297
|
+
:timeout :: Sets the wait_timeout for the connection, defaults to 1 month.
|
|
298
|
+
:read_timeout :: Set the timeout in seconds for reading back results to a query.
|
|
299
|
+
:connect_timeout :: Set the timeout in seconds before a connection attempt is abandoned.
|
|
300
|
+
|
|
301
|
+
=== mysql2
|
|
302
|
+
|
|
303
|
+
This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
|
|
304
|
+
mysql adapter. Supports the same additional options as the mysql adapter, except for :compress, and uses
|
|
305
|
+
:timeout instead of :read_timeout and :connect_timeout.
|
|
280
306
|
|
|
281
307
|
=== odbc
|
|
282
308
|
|
|
@@ -287,8 +313,8 @@ The :database option given ODBC database should be the DSN (Descriptive Service
|
|
|
287
313
|
|
|
288
314
|
The :host and :port options are not respected. The following additional options are supported:
|
|
289
315
|
|
|
290
|
-
|
|
291
|
-
|
|
316
|
+
:db_type :: Can be specified as 'mssql' or 'progress' to use SQL syntax specific to those databases.
|
|
317
|
+
:driver :: The name of the ODBC driver to utilize.
|
|
292
318
|
|
|
293
319
|
=== openbase
|
|
294
320
|
|
|
@@ -300,7 +326,11 @@ Requires: oci8
|
|
|
300
326
|
|
|
301
327
|
The following additional options are supported:
|
|
302
328
|
|
|
303
|
-
|
|
329
|
+
:autosequence :: Set to true to use Sequel's conventions to guess the sequence to use for datasets. False
|
|
330
|
+
by default.
|
|
331
|
+
:prefetch_rows :: The number of rows to prefetch. Defaults to 1, a larger number can be specified
|
|
332
|
+
and will improve performance when retrieving a large number of rows.
|
|
333
|
+
:privilege :: The Oracle privilege level.
|
|
304
334
|
|
|
305
335
|
=== postgres
|
|
306
336
|
|
|
@@ -311,11 +341,15 @@ The pg library is the best supported, as it supports real bound variables and pr
|
|
|
311
341
|
|
|
312
342
|
The following additional options are supported:
|
|
313
343
|
|
|
314
|
-
|
|
315
|
-
|
|
344
|
+
:charset :: Same as :encoding, :encoding takes precedence
|
|
345
|
+
:encoding :: Set the client_encoding to the given string
|
|
346
|
+
:connect_timeout :: Set the number of seconds to wait for a connection (default 20, only respected
|
|
347
|
+
if using the pg library).
|
|
316
348
|
|
|
317
349
|
=== sqlite
|
|
318
350
|
|
|
351
|
+
Requires: sqlite3
|
|
352
|
+
|
|
319
353
|
As SQLite is a file-based database, the :host and :port options are ignored, and
|
|
320
354
|
the :database option should be a path to the file.
|
|
321
355
|
|
|
@@ -337,7 +371,7 @@ Examples:
|
|
|
337
371
|
|
|
338
372
|
The following additional options are supported:
|
|
339
373
|
|
|
340
|
-
|
|
374
|
+
:timeout :: the busy timeout to use in milliseconds (default: 5000).
|
|
341
375
|
|
|
342
376
|
=== swift
|
|
343
377
|
|
|
@@ -353,16 +387,21 @@ Examples:
|
|
|
353
387
|
|
|
354
388
|
=== tinytds
|
|
355
389
|
|
|
390
|
+
Requires: tiny_tds
|
|
391
|
+
|
|
356
392
|
Because the underscore is not a valid character in a URI schema, the adapter
|
|
357
393
|
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
|
-
:
|
|
394
|
+
to tiny_tds, except that the tiny_tds :username option is set to
|
|
395
|
+
the Sequel :user option. If you want to use an entry in the freetds.conf file, you
|
|
396
|
+
should specify the :dataserver option with that name as the value. Some other
|
|
397
|
+
options that you may want to set are :login_timeout, :timeout, :tds_version, :azure,
|
|
398
|
+
:appname, and :encoding, see the tiny_tds README for details.
|
|
399
|
+
|
|
363
400
|
For highest performance, you should disable any identifier output method when
|
|
364
401
|
using the tinytds adapter, which probably means disabling any identifier input method
|
|
365
402
|
as well. The default for Microsoft SQL Server is to :downcase identifiers on output
|
|
366
403
|
and :upcase them on input, so the highest performance will require changing the setting
|
|
367
404
|
from the default.
|
|
368
405
|
|
|
406
|
+
The Sequel tinytds adapter requires tiny_tds >= 0.4.5, and if you are using FreeTDS
|
|
407
|
+
0.91, you must at least be using 0.91rc2 (0.91rc1 does not work).
|
|
@@ -3,15 +3,22 @@
|
|
|
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
|
+
* oracle (requires type specifiers for nil/NULL values)
|
|
13
|
+
* postgres (when using the pg driver, may require type specifiers)
|
|
14
|
+
* sqlite
|
|
15
|
+
* tinytds
|
|
13
16
|
|
|
14
|
-
Support on other
|
|
17
|
+
Support on other adapters is emulated via string interpolation.
|
|
18
|
+
|
|
19
|
+
You can use the prepared_statements model plugin to automatically use prepared
|
|
20
|
+
statements for some common model actions such as saving or deleting a model
|
|
21
|
+
instance, or looking up a model based on a primary key.
|
|
15
22
|
|
|
16
23
|
== Placeholders
|
|
17
24
|
|
|
@@ -74,20 +81,20 @@ and update queries, the hash to insert/update is passed to +prepare+:
|
|
|
74
81
|
|
|
75
82
|
If you are using the ruby-postgres or postgres-pr driver, PostgreSQL uses the
|
|
76
83
|
default emulated support. If you are using ruby-pg, there is native support,
|
|
77
|
-
but it
|
|
84
|
+
but it may require type specifiers on some old versions (generally not anymore).
|
|
78
85
|
direct control over the SQL string, but since Sequel abstracts that, the types
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
in the SQL). Prepared statements are always server side.
|
|
86
|
+
You can add a __* suffix to the placeholder symbol to specify a type, which
|
|
87
|
+
casts to that type in the SQL (e.g. :$name__text, which will be compiled to
|
|
88
|
+
"$1::text" in the SQL). Prepared statements are always server side.
|
|
82
89
|
|
|
83
90
|
=== SQLite
|
|
84
91
|
|
|
85
92
|
SQLite supports both prepared statements and bound variables. Prepared
|
|
86
93
|
statements are cached per connection.
|
|
87
94
|
|
|
88
|
-
=== MySQL
|
|
95
|
+
=== MySQL/Mysql2
|
|
89
96
|
|
|
90
|
-
The MySQL ruby
|
|
97
|
+
The MySQL/Mysql2 ruby drivers do not support bound variables, so the bound
|
|
91
98
|
variable methods fall back to string interpolation. It uses server side
|
|
92
99
|
prepared statements.
|
|
93
100
|
|
|
@@ -99,6 +106,26 @@ over JDBC, you can add the prepareThreshold=N parameter to the connection
|
|
|
99
106
|
string, which will use a server side prepared statement after N calls to
|
|
100
107
|
the prepared statement.
|
|
101
108
|
|
|
109
|
+
=== TinyTDS
|
|
110
|
+
|
|
111
|
+
Uses the sp_executesql stored procedure with bound variables, since
|
|
112
|
+
Microsoft SQL Server doesn't support true prepared statements.
|
|
113
|
+
|
|
114
|
+
=== IBM_DB
|
|
115
|
+
|
|
116
|
+
DB2 supports both prepared statements and bound variables. Prepared
|
|
117
|
+
statement objects are cached per connection.
|
|
118
|
+
|
|
119
|
+
=== Oracle
|
|
120
|
+
|
|
121
|
+
Oracle supports both prepared statements and bound variables. Prepared
|
|
122
|
+
statements (OCI8::Cursor objects) are cached per connection. If you
|
|
123
|
+
ever plan to use a nil/NULL value as a bound variable/prepared statement
|
|
124
|
+
value, you must specify the type in the placeholder using a __* suffix.
|
|
125
|
+
You can use any of the schema types that Sequel supports, such as
|
|
126
|
+
:$name__string or :$num__integer. Using blobs as bound variables is
|
|
127
|
+
not currently supported.
|
|
128
|
+
|
|
102
129
|
=== All Others
|
|
103
130
|
|
|
104
131
|
Support is emulated using interpolation.
|
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.
|