sequel 5.45.0 → 5.77.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +434 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +59 -27
  5. data/bin/sequel +11 -3
  6. data/doc/advanced_associations.rdoc +16 -14
  7. data/doc/association_basics.rdoc +119 -24
  8. data/doc/cheat_sheet.rdoc +11 -3
  9. data/doc/mass_assignment.rdoc +1 -1
  10. data/doc/migration.rdoc +27 -6
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/object_model.rdoc +8 -8
  13. data/doc/opening_databases.rdoc +28 -12
  14. data/doc/postgresql.rdoc +16 -8
  15. data/doc/querying.rdoc +5 -3
  16. data/doc/release_notes/5.46.0.txt +87 -0
  17. data/doc/release_notes/5.47.0.txt +59 -0
  18. data/doc/release_notes/5.48.0.txt +14 -0
  19. data/doc/release_notes/5.49.0.txt +59 -0
  20. data/doc/release_notes/5.50.0.txt +78 -0
  21. data/doc/release_notes/5.51.0.txt +47 -0
  22. data/doc/release_notes/5.52.0.txt +87 -0
  23. data/doc/release_notes/5.53.0.txt +23 -0
  24. data/doc/release_notes/5.54.0.txt +27 -0
  25. data/doc/release_notes/5.55.0.txt +21 -0
  26. data/doc/release_notes/5.56.0.txt +51 -0
  27. data/doc/release_notes/5.57.0.txt +23 -0
  28. data/doc/release_notes/5.58.0.txt +31 -0
  29. data/doc/release_notes/5.59.0.txt +73 -0
  30. data/doc/release_notes/5.60.0.txt +22 -0
  31. data/doc/release_notes/5.61.0.txt +43 -0
  32. data/doc/release_notes/5.62.0.txt +132 -0
  33. data/doc/release_notes/5.63.0.txt +33 -0
  34. data/doc/release_notes/5.64.0.txt +50 -0
  35. data/doc/release_notes/5.65.0.txt +21 -0
  36. data/doc/release_notes/5.66.0.txt +24 -0
  37. data/doc/release_notes/5.67.0.txt +32 -0
  38. data/doc/release_notes/5.68.0.txt +61 -0
  39. data/doc/release_notes/5.69.0.txt +26 -0
  40. data/doc/release_notes/5.70.0.txt +35 -0
  41. data/doc/release_notes/5.71.0.txt +21 -0
  42. data/doc/release_notes/5.72.0.txt +33 -0
  43. data/doc/release_notes/5.73.0.txt +66 -0
  44. data/doc/release_notes/5.74.0.txt +45 -0
  45. data/doc/release_notes/5.75.0.txt +35 -0
  46. data/doc/release_notes/5.76.0.txt +86 -0
  47. data/doc/release_notes/5.77.0.txt +63 -0
  48. data/doc/schema_modification.rdoc +1 -1
  49. data/doc/security.rdoc +9 -9
  50. data/doc/sharding.rdoc +3 -1
  51. data/doc/sql.rdoc +27 -15
  52. data/doc/testing.rdoc +23 -13
  53. data/doc/transactions.rdoc +6 -6
  54. data/doc/virtual_rows.rdoc +1 -1
  55. data/lib/sequel/adapters/ado/access.rb +1 -1
  56. data/lib/sequel/adapters/ado.rb +1 -1
  57. data/lib/sequel/adapters/amalgalite.rb +3 -5
  58. data/lib/sequel/adapters/ibmdb.rb +3 -3
  59. data/lib/sequel/adapters/jdbc/derby.rb +8 -0
  60. data/lib/sequel/adapters/jdbc/h2.rb +63 -10
  61. data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
  62. data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
  63. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
  64. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
  65. data/lib/sequel/adapters/jdbc.rb +24 -22
  66. data/lib/sequel/adapters/mysql.rb +92 -67
  67. data/lib/sequel/adapters/mysql2.rb +56 -51
  68. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  69. data/lib/sequel/adapters/odbc.rb +1 -1
  70. data/lib/sequel/adapters/oracle.rb +4 -3
  71. data/lib/sequel/adapters/postgres.rb +89 -45
  72. data/lib/sequel/adapters/shared/access.rb +11 -1
  73. data/lib/sequel/adapters/shared/db2.rb +42 -0
  74. data/lib/sequel/adapters/shared/mssql.rb +91 -10
  75. data/lib/sequel/adapters/shared/mysql.rb +78 -3
  76. data/lib/sequel/adapters/shared/oracle.rb +86 -7
  77. data/lib/sequel/adapters/shared/postgres.rb +576 -171
  78. data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
  79. data/lib/sequel/adapters/shared/sqlite.rb +92 -8
  80. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  81. data/lib/sequel/adapters/sqlite.rb +99 -18
  82. data/lib/sequel/adapters/tinytds.rb +1 -1
  83. data/lib/sequel/adapters/trilogy.rb +117 -0
  84. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  85. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  86. data/lib/sequel/ast_transformer.rb +6 -0
  87. data/lib/sequel/connection_pool/sharded_single.rb +5 -7
  88. data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
  89. data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
  90. data/lib/sequel/connection_pool/single.rb +6 -8
  91. data/lib/sequel/connection_pool/threaded.rb +14 -8
  92. data/lib/sequel/connection_pool/timed_queue.rb +270 -0
  93. data/lib/sequel/connection_pool.rb +57 -31
  94. data/lib/sequel/core.rb +17 -18
  95. data/lib/sequel/database/connecting.rb +27 -3
  96. data/lib/sequel/database/dataset.rb +16 -6
  97. data/lib/sequel/database/misc.rb +70 -14
  98. data/lib/sequel/database/query.rb +73 -2
  99. data/lib/sequel/database/schema_generator.rb +11 -6
  100. data/lib/sequel/database/schema_methods.rb +23 -4
  101. data/lib/sequel/database/transactions.rb +6 -0
  102. data/lib/sequel/dataset/actions.rb +111 -15
  103. data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
  104. data/lib/sequel/dataset/features.rb +20 -1
  105. data/lib/sequel/dataset/misc.rb +12 -2
  106. data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
  107. data/lib/sequel/dataset/query.rb +170 -41
  108. data/lib/sequel/dataset/sql.rb +190 -71
  109. data/lib/sequel/dataset.rb +4 -0
  110. data/lib/sequel/extensions/_model_pg_row.rb +0 -12
  111. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  112. data/lib/sequel/extensions/any_not_empty.rb +2 -2
  113. data/lib/sequel/extensions/async_thread_pool.rb +14 -13
  114. data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
  115. data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
  116. data/lib/sequel/extensions/connection_expiration.rb +15 -9
  117. data/lib/sequel/extensions/connection_validator.rb +16 -11
  118. data/lib/sequel/extensions/constraint_validations.rb +1 -1
  119. data/lib/sequel/extensions/core_refinements.rb +36 -11
  120. data/lib/sequel/extensions/date_arithmetic.rb +36 -8
  121. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  122. data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
  123. data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
  124. data/lib/sequel/extensions/index_caching.rb +5 -1
  125. data/lib/sequel/extensions/inflector.rb +1 -1
  126. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  127. data/lib/sequel/extensions/looser_typecasting.rb +3 -0
  128. data/lib/sequel/extensions/migration.rb +57 -15
  129. data/lib/sequel/extensions/named_timezones.rb +22 -6
  130. data/lib/sequel/extensions/pagination.rb +1 -1
  131. data/lib/sequel/extensions/pg_array.rb +33 -4
  132. data/lib/sequel/extensions/pg_array_ops.rb +2 -2
  133. data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
  134. data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
  135. data/lib/sequel/extensions/pg_enum.rb +1 -2
  136. data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
  137. data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
  138. data/lib/sequel/extensions/pg_hstore.rb +6 -1
  139. data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
  140. data/lib/sequel/extensions/pg_inet.rb +10 -11
  141. data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
  142. data/lib/sequel/extensions/pg_interval.rb +11 -11
  143. data/lib/sequel/extensions/pg_json.rb +13 -15
  144. data/lib/sequel/extensions/pg_json_ops.rb +125 -2
  145. data/lib/sequel/extensions/pg_multirange.rb +367 -0
  146. data/lib/sequel/extensions/pg_range.rb +13 -26
  147. data/lib/sequel/extensions/pg_range_ops.rb +37 -9
  148. data/lib/sequel/extensions/pg_row.rb +20 -19
  149. data/lib/sequel/extensions/pg_row_ops.rb +1 -1
  150. data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
  151. data/lib/sequel/extensions/round_timestamps.rb +1 -1
  152. data/lib/sequel/extensions/s.rb +2 -1
  153. data/lib/sequel/extensions/schema_caching.rb +1 -1
  154. data/lib/sequel/extensions/schema_dumper.rb +45 -11
  155. data/lib/sequel/extensions/server_block.rb +10 -13
  156. data/lib/sequel/extensions/set_literalizer.rb +58 -0
  157. data/lib/sequel/extensions/sql_comments.rb +110 -3
  158. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  159. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  160. data/lib/sequel/extensions/string_agg.rb +1 -1
  161. data/lib/sequel/extensions/string_date_time.rb +19 -23
  162. data/lib/sequel/extensions/symbol_aref.rb +2 -0
  163. data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
  164. data/lib/sequel/model/associations.rb +286 -92
  165. data/lib/sequel/model/base.rb +53 -33
  166. data/lib/sequel/model/dataset_module.rb +3 -0
  167. data/lib/sequel/model/errors.rb +10 -1
  168. data/lib/sequel/model/exceptions.rb +15 -3
  169. data/lib/sequel/model/inflections.rb +1 -1
  170. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  171. data/lib/sequel/plugins/auto_validations.rb +74 -16
  172. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  173. data/lib/sequel/plugins/column_encryption.rb +29 -8
  174. data/lib/sequel/plugins/composition.rb +3 -2
  175. data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
  176. data/lib/sequel/plugins/constraint_validations.rb +8 -5
  177. data/lib/sequel/plugins/defaults_setter.rb +16 -0
  178. data/lib/sequel/plugins/dirty.rb +1 -1
  179. data/lib/sequel/plugins/enum.rb +124 -0
  180. data/lib/sequel/plugins/finder.rb +4 -2
  181. data/lib/sequel/plugins/insert_conflict.rb +4 -0
  182. data/lib/sequel/plugins/instance_specific_default.rb +1 -1
  183. data/lib/sequel/plugins/json_serializer.rb +2 -2
  184. data/lib/sequel/plugins/lazy_attributes.rb +3 -0
  185. data/lib/sequel/plugins/list.rb +8 -3
  186. data/lib/sequel/plugins/many_through_many.rb +109 -10
  187. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
  188. data/lib/sequel/plugins/nested_attributes.rb +4 -4
  189. data/lib/sequel/plugins/optimistic_locking.rb +9 -42
  190. data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
  191. data/lib/sequel/plugins/paged_operations.rb +181 -0
  192. data/lib/sequel/plugins/pg_array_associations.rb +46 -34
  193. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
  194. data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
  195. data/lib/sequel/plugins/prepared_statements.rb +12 -2
  196. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
  197. data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
  198. data/lib/sequel/plugins/rcte_tree.rb +7 -4
  199. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  200. data/lib/sequel/plugins/serialization.rb +1 -0
  201. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
  202. data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
  203. data/lib/sequel/plugins/sql_comments.rb +189 -0
  204. data/lib/sequel/plugins/static_cache.rb +39 -1
  205. data/lib/sequel/plugins/static_cache_cache.rb +5 -1
  206. data/lib/sequel/plugins/subclasses.rb +28 -11
  207. data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
  208. data/lib/sequel/plugins/timestamps.rb +1 -1
  209. data/lib/sequel/plugins/unused_associations.rb +521 -0
  210. data/lib/sequel/plugins/update_or_create.rb +1 -1
  211. data/lib/sequel/plugins/validate_associated.rb +22 -12
  212. data/lib/sequel/plugins/validation_helpers.rb +41 -11
  213. data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
  214. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  215. data/lib/sequel/sql.rb +1 -1
  216. data/lib/sequel/timezones.rb +12 -14
  217. data/lib/sequel/version.rb +1 -1
  218. metadata +109 -19
@@ -0,0 +1,26 @@
1
+ = New Features
2
+
3
+ * An adapter has been added for the trilogy MySQL driver. One large
4
+ advantage over mysql2 is that trilogy does not require any MySQL
5
+ client libraries installed on the machine. The trilogy adapter
6
+ has basically the same issues/skipped specs as the mysql2 adapter,
7
+ but it also does not support an application_timezone different
8
+ than the database_timezone.
9
+
10
+ * Model dataset modules now have a model accessor, allowing for
11
+ code such as:
12
+
13
+ class Foo < Sequel::Model
14
+ dataset_module do
15
+ where :kept, Sequel[model.table_name][:discarded_at] => nil
16
+ end
17
+ end
18
+
19
+ = Improvements
20
+
21
+ * The mysql adapter now works with ruby-mysql 4 (the pure-ruby
22
+ MySQL driver). Note that multi-results support does not work
23
+ with ruby-mysql 4 (it doesn't work with mysql2, trilogy, or
24
+ other Sequel adapters in general).
25
+
26
+ * Warnings for unsupported flags are now avoided on ruby-mysql 3.
@@ -0,0 +1,35 @@
1
+ = New Features
2
+
3
+ * A sharded_timed_queue connection pool has been added. This offers
4
+ most of the same features as the sharded_threaded connection pool,
5
+ but uses the new Queue#pop :timeout features added in Ruby 3.2 to
6
+ allow for a simpler and possibly faster and more robust
7
+ implementation.
8
+
9
+ * If a :pool_class option is not specified when creating a Database,
10
+ Sequel will now look at the SEQUEL_DEFAULT_CONNECTION_POOL
11
+ environment variable to determine the connection pool class to use.
12
+ This allows you to set SEQUEL_DEFAULT_CONNECTION_POOL=timed_queue
13
+ on Ruby 3.2 to test with the timed_queue connection pool without
14
+ making any code changes. If the :servers Database option is given,
15
+ Sequel will automatically use the sharded version of the connection
16
+ pool specified by SEQUEL_DEFAULT_CONNECTION_POOL.
17
+
18
+ = Other Improvements
19
+
20
+ * The connection_validator, connection_expiration, and
21
+ async_thread_pool extensions now work with the timed_queue and
22
+ sharded_timed_queue connection pools.
23
+
24
+ * The sharded_threaded connection pool now disconnects connections
25
+ for all specified servers instead of just the last specified server
26
+ when using remove_server.
27
+
28
+ * The static_cache plugin now recognizes when the forbid_lazy_load
29
+ plugin is already loaded, and does not return instances that
30
+ forbid lazy load for methods that return a single object, such as
31
+ Database.{[],cache_get_pk,first}.
32
+
33
+ * Sequel now displays an informative error message if attempting to
34
+ load the connection_validator or connection_expiration extensions
35
+ when using the single threaded connection pool.
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * A pg_xmin_optimistic_locking plugin has been added. This plugin
4
+ uses PostgreSQL's xmin system column to implement optimistic
5
+ locking. The xmin system column is automatically updated whenever
6
+ the database row is updated. You can load this plugin into a
7
+ base model and have all models that subclass from it use optimistic
8
+ locking, without needing any user-defined lock columns.
9
+
10
+ = Other Improvements
11
+
12
+ * set_column_allow_null is now a reversible migration method inside
13
+ alter_table blocks.
14
+
15
+ * The use of ILIKE no longer forces the ESCAPE clause on PostgreSQL,
16
+ which allows the use of ILIKE ANY and other constructions. There
17
+ is no need to use the ESCAPE clause with ILIKE, because the value
18
+ Sequel uses is PostgreSQL's default.
19
+
20
+ * The xid PostgreSQL type is now recognized as an integer type in the
21
+ jdbc/postgresql adapter.
@@ -0,0 +1,33 @@
1
+ = New Features
2
+
3
+ * A pg_auto_parameterize_in_array extension has been added, which
4
+ handles conversion of IN/NOT IN to = ANY or != ALL for more types.
5
+ The pg_auto_parameterize extension only handles integer types by
6
+ default, because other types require the pg_array extension. This
7
+ new extension adds handling for Float, BigDecimal, Date, Time,
8
+ DateTime, Sequel::SQLTime, and Sequel::SQL::Blob types. It can
9
+ also handle String types if the :treat_string_list_as_text_array
10
+ Database option is present, using the text type for that. Handling
11
+ String values as text is not the default because that may cause
12
+ issues for some queries.
13
+
14
+ = Other Improvements
15
+
16
+ * The defaults_setter plugin now does a deep copy of database
17
+ default values that are hash/array or delegates to hash/array.
18
+ This fixes cases where the database default values are mutated.
19
+
20
+ * Sequel now correctly handles infinite and NaN float values used
21
+ inside PostgreSQL array bound variables.
22
+
23
+ * The data in the cache files used by the schema_caching and
24
+ index_caching extensions and static_cache_cache and
25
+ pg_auto_constraint_validations plugins are now sorted before the
26
+ cache file is saved, increasing consistency between runs.
27
+
28
+ * bigdecimal has been added as a dependency. bigdecimal is currently
29
+ a default gem in Ruby from 1.9 to 3.2, but it will move to a
30
+ bundled gem in Ruby 3.4, and there will be warnings in Ruby 3.3
31
+ for cases that will break in Ruby 3.4. Adding bigdecimal as a
32
+ dependency should avoid warnings when using bundler in Ruby 3.3,
33
+ and should avoid errors in Ruby 3.4.
@@ -0,0 +1,66 @@
1
+ = New Features
2
+
3
+ * A paged_operations plugin has been added, which adds support for
4
+ paged_datasets, paged_update, and paged_delete dataset methods.
5
+ This methods are designed to be used on large datasets, to split
6
+ a large query into separate smaller queries, to avoid locking the
7
+ related database table for a long period of time.
8
+ paged_update and paged_delete operate the same as update and delete,
9
+ returning the number of rows updated or deleted. paged_datasets yields
10
+ one or more datasets representing subsets of the receiver, with the
11
+ union of all of those datasets comprising all records in the receiver:
12
+
13
+ Album.plugin :paged_operations
14
+
15
+ Album.where{name > 'M'}.paged_datasets{|ds| puts ds.sql}
16
+ # Runs: SELECT id FROM albums WHERE (name <= 'M') ORDER BY id LIMIT 1 OFFSET 1000
17
+ # Prints: SELECT * FROM albums WHERE ((name <= 'M') AND ("id" < 1002))
18
+ # Runs: SELECT id FROM albums WHERE ((name <= 'M') AND (id >= 1002)) ORDER BY id LIMIT 1 OFFSET 1000
19
+ # Prints: SELECT * FROM albums WHERE ((name <= 'M') AND ("id" < 2002) AND (id >= 1002))
20
+ # ...
21
+ # Runs: SELECT id FROM albums WHERE ((name <= 'M') AND (id >= 10002)) ORDER BY id LIMIT 1 OFFSET 1000
22
+ # Prints: SELECT * FROM albums WHERE ((name <= 'M') AND (id >= 10002))
23
+
24
+ Album.where{name <= 'M'}.paged_update(:updated_at=>Sequel::CURRENT_TIMESTAMP)
25
+ # SELECT id FROM albums WHERE (name <= 'M') ORDER BY id LIMIT 1 OFFSET 1000
26
+ # UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE ((name <= 'M') AND ("id" < 1002))
27
+ # SELECT id FROM albums WHERE ((name <= 'M') AND (id >= 1002)) ORDER BY id LIMIT 1 OFFSET 1000
28
+ # UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE ((name <= 'M') AND ("id" < 2002) AND (id >= 1002))
29
+ # ...
30
+ # SELECT id FROM albums WHERE ((name <= 'M') AND (id >= 10002)) ORDER BY id LIMIT 1 OFFSET 1000
31
+ # UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE ((name <= 'M') AND (id >= 10002))
32
+
33
+ Album.where{name > 'M'}.paged_delete
34
+ # SELECT id FROM albums WHERE (name > 'M') ORDER BY id LIMIT 1 OFFSET 1000
35
+ # DELETE FROM albums WHERE ((name > 'M') AND (id < 1002))
36
+ # SELECT id FROM albums WHERE (name > 'M') ORDER BY id LIMIT 1 OFFSET 1000
37
+ # DELETE FROM albums WHERE ((name > 'M') AND (id < 2002))
38
+ # ...
39
+ # SELECT id FROM albums WHERE (name > 'M') ORDER BY id LIMIT 1 OFFSET 1000
40
+ # DELETE FROM albums WHERE (name > 'M')
41
+
42
+ * A Dataset#transaction :skip_transaction option is now support to
43
+ checkout a connection from the pool without opening a transaction. This
44
+ makes it easier to handle cases where a transaction may or not be used
45
+ based on configuration/options. Dataset#import and Dataset#paged_each
46
+ now both support the :skip_transaction option to skip transactions.
47
+
48
+ * Dataset#full_text_search now supports the to_tsquery: :websearch option
49
+ on PostgreSQL 11+, to use the websearch_to_tsquery database function.
50
+
51
+ * The Sequel::MassAssignmentRestriction exception now supports model
52
+ and column methods to get provide additional information about the
53
+ exception. Additionally, the exception message now includes information
54
+ about the model class.
55
+
56
+ = Other Improvements
57
+
58
+ * The ibmdb and jdbc/db2 adapter now both handle disconnect errors
59
+ correctly, removing the related connection from the pool.
60
+
61
+ * Dataset#import no longer uses an explicit transaction if given a dataset
62
+ value, as in that case, only a single query is used.
63
+
64
+ * The column_encryption plugin no longer uses the base64 library. The
65
+ base64 library is moving from the standard library to a bundled gem
66
+ in Ruby 3.4, and this avoids having a dependency on it.
@@ -0,0 +1,45 @@
1
+ = New Features
2
+
3
+ * Sequel.migration blocks now support a revert method, which reverts
4
+ the changes in the block on up, and applies them on down. So if
5
+ you have a migration such as:
6
+
7
+ Sequel.migration do
8
+ change do
9
+ create_table :table do
10
+ # ...
11
+ end
12
+ end
13
+ end
14
+
15
+ and you later want to add a migration that drops the table, you
16
+ can use:
17
+
18
+ Sequel.migration do
19
+ revert do
20
+ create_table :table do
21
+ # ...
22
+ end
23
+ end
24
+ end
25
+
26
+ This will drop the table when migrating up, and create a table
27
+ with the given schema when migrating down.
28
+
29
+ * is_json and is_not_json methods have been added to the pg_json_ops
30
+ extension, for the IS [NOT] JSON operator supported in PostgreSQL
31
+ 16+. These were previously added in Sequel 5.59.0, and removed
32
+ in Sequel 5.61.0 as support was removed in PostgreSQL 15 beta 4.
33
+ PostgreSQL 16 shipped with support for them, so support has been
34
+ recommitted to Sequel.
35
+
36
+ = Other Improvements
37
+
38
+ * SQLite generated columns now show up in Database#schema when using
39
+ SQLite 3.37+.
40
+
41
+ * Sequel now attempts to avoid an infinite loop in pathlogical cases
42
+ in the jdbc adapter, where the exception cause chain has a loop.
43
+ Additionally, if an exception is already recognized as a disconnect,
44
+ or an exception already responds to a getSQLState method, Sequel no
45
+ longer looks at the causes of the exception.
@@ -0,0 +1,35 @@
1
+ = New Features
2
+
3
+ * Database#{defer,immediate}_constraints methods have been added on
4
+ PostgreSQL for changing handling of deferrable constraints inside
5
+ a transaction. defer_constraints sets deferrable constraints to
6
+ be deferred (not checked until transaction commit), and
7
+ immediate_constraints sets deferrable constraints to be checked
8
+ as part of the related query, and any already deferred constraint
9
+ checks to be applied immediately. You can pass the :constraints
10
+ option to only apply the changes to specific constraints.
11
+
12
+ * TimestampMigrator.run_single has been added, to migrate a single
13
+ migration up or down.
14
+
15
+ = Other Improvements
16
+
17
+ * INSERT RETURNING is now supported on MariaDB 10.5+, and used
18
+ automatically when saving new model objects. Note that this
19
+ is not supported when using the jdbc adapter, because the
20
+ jdbc-mysql driver doesn't support it. A jdbc/mariadb adapter
21
+ could be added, as it's likely recent versions of the
22
+ jdbc-mariadb driver would support it, but the jdbc-mariadb gem
23
+ hasn't been updated in over 4 years. Talk to the jdbc-mariadb
24
+ gem maintainers if you want to use this feature with the jdbc
25
+ adapter.
26
+
27
+ * The Dataset#paged_each optimization in the postgres adapter
28
+ now respects the :skip_transaction option, making it the
29
+ same as the :hold option. Note that this has effects beyond
30
+ just skipping the transaction, but non-HOLD cursors are only
31
+ supported inside transactions.
32
+
33
+ * The any_not_empty? extension's Dataset#any? method now supports
34
+ an argument, passing it to Enumerable#any? (which has supported
35
+ an argument since Ruby 2.5).
@@ -0,0 +1,86 @@
1
+ = New Features
2
+
3
+ * An auto_cast_date_and_time extension has been added, which will
4
+ automatically cast date and time values using SQL standard functions.
5
+ This makes sure the database will treat the value as a date, time,
6
+ or timestamp, instead of treating it as a string or unknown type:
7
+
8
+ DB.get(Date.today).class
9
+ # SELECT '2024-01-01' AS v LIMIT 1
10
+ String
11
+
12
+ DB.extension(:auto_cast_date_and_time)
13
+ DB.get(Date.today).class
14
+ # SELECT DATE '2024-01-01' AS v LIMIT 1
15
+ Date
16
+
17
+ This was already Sequel's default behavior on adapters that required
18
+ it. This extension is usable on PostgreSQL and MySQL. It is not
19
+ usable on SQLite (no date/time types) or Microsoft SQL Server (no
20
+ support for the SQL standard conversion syntax).
21
+
22
+ This extension can break code that currently works. If using it on
23
+ PostgreSQL, it will cast the values to TIMESTAMP, not TIMESTAMP
24
+ WITH TIME ZONE, which can break code that depended on an implicit
25
+ conversion to TIMESTAMP WITH TIME ZONE. The pg_timestamptz
26
+ extension integrates with the the auto_cast_date_and_time extension
27
+ and will implicitly cast Time/DateTime to TIMESTAMP WITH TIME ZONE.
28
+
29
+ * The sqlite adapter now supports a :cached value for the
30
+ :setup_regexp_function Database option, which will cache regexp
31
+ values instead of creating a new regexp per value to compare. This
32
+ is much faster when using a regexp comparison on a large dataset,
33
+ but can result in a memory leak if using dynamic regexps. You can
34
+ also provide a Proc value for the :setup_regexp_function option,
35
+ which will be passed both the regexp source string and the database
36
+ string to compare, and should return whether the database string
37
+ matches the regexp string.
38
+
39
+ * The rcte_tree plugin now supports a :union_all option, which can
40
+ be set to false to use UNION instead of UNION ALL in the recursive
41
+ common table expression.
42
+
43
+ = Other Improvements
44
+
45
+ * Time/DateTime/SQLTime literalization speed has more than doubled
46
+ compared to the previous version. The internal code is also much
47
+ simpler, as the speedup resulted from removing multiple abstraction
48
+ layers that mostly existed for Ruby 1.8 support.
49
+
50
+ * Database#table_exists? on PostgreSQL now handles lock or statement
51
+ timeout errors as evidence the table exists.
52
+
53
+ * The round_timestamps extension now correctly rounds SQLTime values
54
+ on Microsoft SQL Server (the only database Sequel supports where
55
+ time precision is different than timestamp precision).
56
+
57
+ * Fractional times and timestamps are now supported on SQLAnywhere,
58
+ except for time values when using the jdbc adapter due to a
59
+ limitation in the JDBC sqlanywhere driver.
60
+
61
+ * Database#tables and #views on PostgreSQL now supports
62
+ SQL::Identifier values for the :schema option.
63
+
64
+ * The named_timezones extension now works around a bug in DateTime.jd
65
+ on JRuby.
66
+
67
+ = Backwards Compatibility
68
+
69
+ * Time/DateTime/SQLTime literalization internals have changed.
70
+ If you are using an external adapter and the external adapter
71
+ overrides or calls any of the following methods:
72
+
73
+ * requires_sql_standard_datetimes?
74
+ * supports_timestamp_usecs?
75
+ * supports_timestamp_timezones?
76
+ * timestamp_precision
77
+ * sqltime_precision
78
+
79
+ then the adapter may need to be updated to support Sequel 5.76.0.
80
+ Additionally, if the adapter uses %N or %z in
81
+ default_timestamp_format, it may need to be updated. Adapters
82
+ should now just override default_timestamp_format and/or
83
+ default_time_format methods as appropriate for the database.
84
+
85
+ * The Dataset#format_timestamp_offset private method has been
86
+ removed.
@@ -0,0 +1,63 @@
1
+ = New Features
2
+
3
+ * A transaction_connection_validator extension has been added. This
4
+ extension allows for transparently switching to a new connection if
5
+ a disconnect error is raised while trying to start a transaction, as
6
+ long as a connection was not already checked out from the pool
7
+ when the transaction method was called. Transparent reconnection
8
+ is safe in this case, since no user code is retried.
9
+
10
+ This extension can have lower overhead than the
11
+ connection_validator extension if that is configured to check for
12
+ validity more often than the default of one hour. However, it
13
+ only handles cases where transactions are used. It can detect
14
+ disconnects that would not be detected by default with the
15
+ connection_validator extension, since that extension defaults to
16
+ only checking validity if the connection has not been used in the
17
+ last hour.
18
+
19
+ * Sequel now supports a create_table :without_rowid option on SQLite,
20
+ to create a table WITHOUT ROWID, for better performance in some
21
+ cases. Users are encouraged to read the SQLite documentation on
22
+ WITHOUT ROWID before using this option.
23
+
24
+ * The sqlite adapter now supports a :regexp_function_cache option, if
25
+ the :setup_regexp_function option is set to :cached. The
26
+ :regexp_function_cache option should be a Proc (returning a cache
27
+ object to use), or a class. It's possible to use
28
+ ObjectSpace::WeakKeyMap as the value of the option on Ruby 3.3+
29
+ to avoid the memory leaks that are possible when using
30
+ :setup_regexp_function option :cached value with dynamic regexps.
31
+
32
+ * The duplicate_columns_handler extension now supports specifying
33
+ the on_duplicate_columns option as a connection string parameter.
34
+
35
+ = Other Improvements
36
+
37
+ * The list plugin now honors the :top option for the position when
38
+ adding the first item to the list, instead of always using 1.
39
+
40
+ * Regexp matches on SQLite are now faster on Ruby 2.4+, using
41
+ Regexp#match?.
42
+
43
+ * The uniqueness validation in the validation_helpers plugin now
44
+ uses empty? instead of count == 0, for better performance.
45
+
46
+ * On Ruby 3.4+, Sequel uses the timed_queue connection pool instead
47
+ of the threaded connection pool by default. This should make it
48
+ so no existing applications are affected by the default switch.
49
+ This should hopefully allow ample testing of the timed_queue
50
+ connection pool. At some point in the future, if no problems
51
+ are repoted, Sequel will likely switch to using the timed_queue
52
+ connection pool by default on Ruby 3.2+.
53
+
54
+ = Backwards Compatibility
55
+
56
+ * Sequel now warns by default if using eager_graph/association_join
57
+ with an association that uses a block, in the cases where the
58
+ block would be ignored and there are no appropriate graph options
59
+ set. In Sequel 6, this warning will be turned into an exception.
60
+ It is recommended that users use the auto_restrict_eager_graph
61
+ plugin to turn this into an exception now, or use the
62
+ :graph_use_association_block option so that the block is not
63
+ ignored when graphing.
@@ -377,7 +377,7 @@ Sequel will not add a column, but will add a composite primary key constraint:
377
377
  It is possible to specify a name for the primary key constraint: via the :name option:
378
378
 
379
379
  alter_table(:albums_artists) do
380
- add_primary_key [:album_id, :artist_id], :name=>:albums_artists_pkey
380
+ add_primary_key [:album_id, :artist_id], name: :albums_artists_pkey
381
381
  end
382
382
 
383
383
  If you just want to take an existing single column and make it a primary key, call
data/doc/security.rdoc CHANGED
@@ -127,8 +127,8 @@ a ruby string as raw SQL. For example:
127
127
  DB.literal(Date.today) # "'2013-03-22'"
128
128
  DB.literal('a') # "'a'"
129
129
  DB.literal(Sequel.lit('a')) # "a"
130
- DB.literal(:a => 'a') # "(\"a\" = 'a')"
131
- DB.literal(:a => Sequel.lit('a')) # "(\"a\" = a)"
130
+ DB.literal(a: 'a') # "(\"a\" = 'a')"
131
+ DB.literal(a: Sequel.lit('a')) # "(\"a\" = a)"
132
132
 
133
133
  ==== SQL Filter Fragments
134
134
 
@@ -178,7 +178,7 @@ user input for function names.
178
178
  For backwards compatibility, Sequel supports regular strings in the
179
179
  window function :frame option, which will be treated as a literal string:
180
180
 
181
- DB[:table].select{fun(arg).over(:frame=>'SQL Here')}
181
+ DB[:table].select{fun(arg).over(frame: 'SQL Here')}
182
182
 
183
183
  You should make sure the frame argument is not derived from user input,
184
184
  or switch to using a hash as the :frame option value.
@@ -237,7 +237,7 @@ or:
237
237
 
238
238
  Instead, you should do:
239
239
 
240
- DB[:table].update(:column => params[:value].to_s) # Safe
240
+ DB[:table].update(column: params[:value].to_s) # Safe
241
241
 
242
242
  Because using the auto_literal_strings extension makes SQL injection
243
243
  so much eaiser, it is recommended to not use it, and instead
@@ -402,29 +402,29 @@ This issue isn't necessarily specific to Sequel, but it is a good general practi
402
402
  If you are using values derived from user input, it is best to be explicit about
403
403
  their type. For example:
404
404
 
405
- Album.where(:id=>params[:id])
405
+ Album.where(id: params[:id])
406
406
 
407
407
  is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
408
408
  be a string, an array, a hash, nil, or potentially something else.
409
409
 
410
410
  Assuming that +id+ is an integer field, you probably want to do:
411
411
 
412
- Album.where(:id=>params[:id].to_i)
412
+ Album.where(id: params[:id].to_i)
413
413
 
414
414
  If you are looking something up by name, you should try to enforce the value to be
415
415
  a string:
416
416
 
417
- Album.where(:name=>params[:name].to_s)
417
+ Album.where(name: params[:name].to_s)
418
418
 
419
419
  If you are trying to use an IN clause with a list of id values based on input provided
420
420
  on a web form:
421
421
 
422
- Album.where(:id=>params[:ids].to_a.map(&:to_i))
422
+ Album.where(id: params[:ids].to_a.map(&:to_i))
423
423
 
424
424
  Basically, be as explicit as possible. While there aren't any known security issues
425
425
  in Sequel when you do:
426
426
 
427
- Album.where(:id=>params[:id])
427
+ Album.where(id: params[:id])
428
428
 
429
429
  It allows the attacker to choose to do any of the following queries:
430
430
 
data/doc/sharding.rdoc CHANGED
@@ -39,7 +39,9 @@ is the simplest configuration:
39
39
  servers: {read_only: {host: 'replica_server'}})
40
40
 
41
41
  This will use the replica_server for SELECT queries and primary_server for
42
- other queries.
42
+ other queries. The :read_only key in the :servers hash is special in that
43
+ it sets the default database for Dataset methods that use SELECT queries
44
+ (which are generally read queries that do not modify the database).
43
45
 
44
46
  If you want to ensure your queries are going to a specific database, you
45
47
  can force this for a given query by using the .server method and passing
data/doc/sql.rdoc CHANGED
@@ -59,7 +59,7 @@ Then, you call the +insert+, +update+, or +delete+ method on the returned datase
59
59
  update_ds.update
60
60
  delete_ds.delete
61
61
 
62
- +update+ and +delete+ should return the number of rows affected, and +insert+ should return the autogenerated primary key integer for the row inserted (if any).
62
+ +update+ and +delete+ generally return the number of rows affected, and +insert+ generally returns the autogenerated primary key integer for the row inserted (if any), but not all adapters/databases support this behavior for datasets using custom SQL (notably it is not supported for +insert+ on PostgreSQL).
63
63
 
64
64
  === Other Queries
65
65
 
@@ -223,22 +223,22 @@ If the database supports window functions, Sequel can handle them by calling the
223
223
  DB[:albums].select{count.function.*.over}
224
224
  # SELECT count(*) OVER () FROM albums
225
225
 
226
- DB[:albums].select{function(:col1).over(:partition=>col2, :order=>col3)}
226
+ DB[:albums].select{function(:col1).over(partition: col2, order: col3)}
227
227
  # SELECT function(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM albums
228
228
 
229
- DB[:albums].select{function(c1, c2).over(:partition=>[c3, c4], :order=>[c5, c6.desc])}
229
+ DB[:albums].select{function(c1, c2).over(partition: [c3, c4], order: [c5, c6.desc])}
230
230
  # SELECT function(c1, c2) OVER (PARTITION BY c3, c4 ORDER BY c5, c6 DESC) FROM albums
231
231
 
232
- DB[:albums].select{function(c1).over(:partition=>c2, :order=>:c3, :frame=>:rows)}
232
+ DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: :rows)}
233
233
  # SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM albums
234
234
 
235
- DB[:albums].select{function(c1).over(:partition=>c2, :order=>:c3, :frame=>{:type=>:range, :start=>1, :end=>1})}
235
+ DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :range, start: 1, end: 1})}
236
236
  # SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM albums
237
237
 
238
- DB[:albums].select{function(c1).over(:partition=>c2, :order=>:c3, :frame=>{:type=>:groups, :start=>[2, :preceding], :end=>[1, :preceding]})}
238
+ DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :groups, start: [2, :preceding], end: [1, :preceding]})}
239
239
  # SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING) FROM albums
240
240
 
241
- DB[:albums].select{function(c1).over(:partition=>c2, :order=>:c3, :frame=>{:type=>:range, :start=>:preceding, :exclude=>:current})}
241
+ DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :range, start: :preceding, exclude: :current})}
242
242
  # SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW) FROM albums
243
243
 
244
244
  === Schema Qualified Functions
@@ -428,6 +428,18 @@ As you can see, these literalize with ANDs by default. You can use the <tt>Sequ
428
428
 
429
429
  Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
430
430
 
431
+ As you can see in the above examples, <tt>Sequel.|</tt> and <tt>Sequel.or</tt> work differently.
432
+ <tt>Sequel.|</tt> is for combining an arbitrary number of expressions using OR. If you pass a single
433
+ argument, <tt>Sequel.|</tt> will just convert it to a Sequel expression, similar to <tt>Sequel.expr</tt>.
434
+ <tt>Sequel.or</tt> is for taking a single hash or array of two element arrays and combining the
435
+ elements of that single argument using OR instead of AND:
436
+
437
+ Sequel.|(column1: 1, column2: 2) # (("column1" = 1) AND ("column2" = 2))
438
+ Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
439
+
440
+ Sequel.|({column1: 1}, {column2: 2}) # (("column1" = 1) OR ("column2" = 2))
441
+ Sequel.or({column1: 1}, {column2: 2}) # ArgumentError
442
+
431
443
  You've already seen the <tt>Sequel.negate</tt> method, which will use ANDs if multiple entries are used:
432
444
 
433
445
  Sequel.negate(column1: 1, column2: 2) # (("column1" != 1) AND ("column2" != 2))
@@ -516,7 +528,7 @@ Inverting the LIKE operator works like other inversions:
516
528
 
517
529
  ~Sequel.like(:name, 'A%') # ("name" NOT LIKE 'A%' ESCAPE '\')
518
530
 
519
- Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
531
+ Sequel also supports SQL regular expressions on MySQL and PostgreSQL (and SQLite when using the sqlite adapter with the :setup_regexp_function Database option). You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
520
532
 
521
533
  Sequel.like(:name, /^A/) # ("name" ~ '^A')
522
534
  ~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
@@ -539,8 +551,8 @@ You can also use the <tt>Sequel.asc</tt> and <tt>Sequel.desc</tt> methods:
539
551
 
540
552
  On some databases, you can specify null ordering:
541
553
 
542
- Sequel.asc(:column, :nulls=>:first) # "column" ASC NULLS FIRST
543
- Sequel.desc(Sequel[:table][:column], :nulls=>:last) # "table"."column" DESC NULLS LAST
554
+ Sequel.asc(:column, nulls: :first) # "column" ASC NULLS FIRST
555
+ Sequel.desc(Sequel[:table][:column], nulls: :last) # "table"."column" DESC NULLS LAST
544
556
 
545
557
  === All Columns (.*)
546
558
 
@@ -617,16 +629,16 @@ Also note that while the SELECT clause is displayed when you look at a dataset,
617
629
 
618
630
  ds = DB[:albums]
619
631
  ds.all # SELECT * FROM albums
620
- ds.insert(:name=>'RF') # INSERT INTO albums (name) VALUES ('RF')
621
- ds.update(:name=>'RF') # UPDATE albums SET name = 'RF'
632
+ ds.insert(name: 'RF') # INSERT INTO albums (name) VALUES ('RF')
633
+ ds.update(name: 'RF') # UPDATE albums SET name = 'RF'
622
634
  ds.delete # DELETE FROM albums
623
635
 
624
636
  In general, the +insert+, +update+, and +delete+ methods use the appropriate clauses you defined on the dataset:
625
637
 
626
- ds = DB[:albums].where(:id=>1)
638
+ ds = DB[:albums].where(id: 1)
627
639
  ds.all # SELECT * FROM albums WHERE (id = 1)
628
- ds.insert(:name=>'RF') # INSERT INTO albums (name) VALUES ('RF')
629
- ds.update(:name=>'RF') # UPDATE albums SET name = 'RF' WHERE (id = 1)
640
+ ds.insert(name: 'RF') # INSERT INTO albums (name) VALUES ('RF')
641
+ ds.update(name: 'RF') # UPDATE albums SET name = 'RF' WHERE (id = 1)
630
642
  ds.delete # DELETE FROM albums WHERE (id = 1)
631
643
 
632
644
  Note how +update+ and +delete+ used the +where+ argument, but +insert+ did not, because INSERT doesn't use a WHERE clause.