sequel 5.67.0 → 5.74.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +86 -0
  3. data/README.rdoc +3 -3
  4. data/doc/advanced_associations.rdoc +3 -1
  5. data/doc/mass_assignment.rdoc +1 -1
  6. data/doc/migration.rdoc +15 -0
  7. data/doc/opening_databases.rdoc +8 -1
  8. data/doc/release_notes/5.68.0.txt +61 -0
  9. data/doc/release_notes/5.69.0.txt +26 -0
  10. data/doc/release_notes/5.70.0.txt +35 -0
  11. data/doc/release_notes/5.71.0.txt +21 -0
  12. data/doc/release_notes/5.72.0.txt +33 -0
  13. data/doc/release_notes/5.73.0.txt +66 -0
  14. data/doc/release_notes/5.74.0.txt +45 -0
  15. data/doc/sharding.rdoc +3 -1
  16. data/doc/testing.rdoc +1 -1
  17. data/lib/sequel/adapters/ibmdb.rb +1 -1
  18. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -0
  19. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -0
  20. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
  21. data/lib/sequel/adapters/jdbc.rb +10 -6
  22. data/lib/sequel/adapters/mysql.rb +19 -7
  23. data/lib/sequel/adapters/shared/db2.rb +12 -0
  24. data/lib/sequel/adapters/shared/postgres.rb +70 -6
  25. data/lib/sequel/adapters/shared/sqlite.rb +0 -1
  26. data/lib/sequel/adapters/trilogy.rb +117 -0
  27. data/lib/sequel/connection_pool/sharded_threaded.rb +11 -10
  28. data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
  29. data/lib/sequel/connection_pool/threaded.rb +6 -0
  30. data/lib/sequel/connection_pool/timed_queue.rb +16 -3
  31. data/lib/sequel/connection_pool.rb +8 -1
  32. data/lib/sequel/database/connecting.rb +1 -1
  33. data/lib/sequel/database/schema_methods.rb +4 -3
  34. data/lib/sequel/database/transactions.rb +6 -0
  35. data/lib/sequel/dataset/actions.rb +8 -6
  36. data/lib/sequel/extensions/async_thread_pool.rb +3 -2
  37. data/lib/sequel/extensions/connection_expiration.rb +15 -9
  38. data/lib/sequel/extensions/connection_validator.rb +15 -10
  39. data/lib/sequel/extensions/index_caching.rb +5 -1
  40. data/lib/sequel/extensions/migration.rb +18 -5
  41. data/lib/sequel/extensions/pg_array.rb +9 -1
  42. data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
  43. data/lib/sequel/extensions/pg_enum.rb +1 -2
  44. data/lib/sequel/extensions/pg_extended_date_support.rb +10 -2
  45. data/lib/sequel/extensions/pg_json_ops.rb +52 -0
  46. data/lib/sequel/extensions/pg_multirange.rb +1 -1
  47. data/lib/sequel/extensions/pg_range.rb +1 -1
  48. data/lib/sequel/extensions/pg_row.rb +2 -6
  49. data/lib/sequel/extensions/schema_caching.rb +1 -1
  50. data/lib/sequel/extensions/server_block.rb +2 -1
  51. data/lib/sequel/model/base.rb +20 -10
  52. data/lib/sequel/model/dataset_module.rb +3 -0
  53. data/lib/sequel/model/exceptions.rb +15 -3
  54. data/lib/sequel/plugins/column_encryption.rb +26 -5
  55. data/lib/sequel/plugins/constraint_validations.rb +8 -5
  56. data/lib/sequel/plugins/defaults_setter.rb +16 -0
  57. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
  58. data/lib/sequel/plugins/optimistic_locking.rb +9 -42
  59. data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
  60. data/lib/sequel/plugins/paged_operations.rb +181 -0
  61. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +8 -2
  62. data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
  63. data/lib/sequel/plugins/static_cache.rb +38 -0
  64. data/lib/sequel/plugins/static_cache_cache.rb +5 -1
  65. data/lib/sequel/plugins/validation_helpers.rb +8 -1
  66. data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
  67. data/lib/sequel/version.rb +1 -1
  68. metadata +37 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff5af191af88ca381359503cfd9601ec8f18a9d782b68a3de4a8c9dac080eddc
4
- data.tar.gz: 786d20f7eac9325748c259130951643856e34051e64b02aa17493f6d0283eb52
3
+ metadata.gz: 16c90ef17199e4e48f39edee069981ba0030cf63dc481b136f637b1fe069743e
4
+ data.tar.gz: 52063f32827a04c33173867207290da294878d898d25b80c37666cf66a54b780
5
5
  SHA512:
6
- metadata.gz: db251488ea0739af5ecf6db332a1cff729cffbf31dfabfc7235f3c27f807366bc9feddf147797e4dd5980348fda6a640cc5ceef7e6255cddcd317acb7172be90
7
- data.tar.gz: 45b0e24847ccb365f1d7d06d35c85f05718802375877ab3d0315deb952f72171e26b5676861c25cf1e840f831d216f99eaddcbb717fc752d75077f19ae13980c
6
+ metadata.gz: d808534a13ae702a884524ceae4adcdb8eff9d46681a62d5b2c0d926b46279743350520248311c41f8a385c7fc66d17cbc44c7f1af52f1cffd356fca498d6bb2
7
+ data.tar.gz: 309d0f0c0a7c47a4f1acc90107443e7fd2aa51cb09038082354e822711b11986ae271bb784e710336cebafc83b8b5a99adf088bfd19e2353728d25de86f942c4
data/CHANGELOG CHANGED
@@ -1,3 +1,89 @@
1
+ === 5.74.0 (2023-11-01)
2
+
3
+ * Make generated columns show up in Database#schema when using SQLite 3.37+ (jeremyevans) (#2087)
4
+
5
+ * Add revert method for Sequel.migration blocks, to revert changes inside the block on up, and apply the changes on down (jeremyevans)
6
+
7
+ * Re-add is_json and is_not_json methods to the pg_json_ops extension, as the support was re-added in PostgreSQL 16 (jeremyevans)
8
+
9
+ * Avoid infinite loop when handling exceptions with a cause loop in jdbc adapter (jeremyevans)
10
+
11
+ === 5.73.0 (2023-10-01)
12
+
13
+ * Handle disconnect errors in ibmdb and jdbc/db2 adapters (jeremyevans) (#2083)
14
+
15
+ * Support skipping transactions in Dataset#{import,paged_each} using :skip_transaction option (jeremyevans)
16
+
17
+ * Add Database#transaction :skip_transaction option to skip creating a transaction or savepoint (jeremyevans)
18
+
19
+ * Stop using a transaction for a single query if calling Dataset#import with a dataset (jeremyevans)
20
+
21
+ * Add paged_operations plugin for paged deletes and updates and other custom operations (jeremyevans) (#2080)
22
+
23
+ * Support to_tsquery: :websearch option to Dataset#full_text_search on PostgreSQL 11+ (jeremyevans) (#2075)
24
+
25
+ * Add MassAssignmentRestriction#model and #column for getting the model instance and related column for mass assignment errors (artofhuman, jeremyevans) (#2079)
26
+
27
+ * Stop using base64 library in column_encryption plugin (jeremyevans)
28
+
29
+ === 5.72.0 (2023-09-01)
30
+
31
+ * Sort caches before marshalling when using schema_caching, index_caching, static_cache_cache, and pg_auto_constraint_validations (jeremyevans)
32
+
33
+ * Change the defaults_setter plugin do a deep-copy of database default hash/array values and delegates (jeremyevans) (#2069)
34
+
35
+ * Add pg_auto_parameterize_in_array extension, for converting IN/NOT IN to = ANY or != ALL for more types (jeremyevans)
36
+
37
+ * Fix literalization of infinite and NaN float values in PostgreSQL array bound variables (jeremyevans)
38
+
39
+ === 5.71.0 (2023-08-01)
40
+
41
+ * Support ILIKE ANY on PostgreSQL by not forcing the use of ESCAPE for ILIKE (gilesbowkett) (#2066)
42
+
43
+ * Add pg_xmin_optimistic_locking plugin for optimistic locking for all models without database changes (jeremyevans)
44
+
45
+ * Recognize the xid PostgreSQL type as an integer type in the jdbc/postgresql adapter (jeremyevans)
46
+
47
+ * Make set_column_allow_null method reversible in migrations (enescakir) (#2060)
48
+
49
+ === 5.70.0 (2023-07-01)
50
+
51
+ * Make static_cache plugin better handle cases where forbid_lazy_load plugin is already loaded (jeremyevans)
52
+
53
+ * Fix ShardedThreadedConnectionPool#remove_server to disconnect all connections if removing multiple servers (jeremyevans)
54
+
55
+ * Support SEQUEL_DEFAULT_CONNECTION_POOL environment variable for choosing connection pool when :pool_class Database option is not set (jeremyevans)
56
+
57
+ * Add sharded_timed_queue connection pool (jeremyevans)
58
+
59
+ * Make connection_{validator,expiration} and async_thread_pool extensions work with timed_queue connection pool (jeremyevans)
60
+
61
+ * Make connection_{validator,expiration} extensions raise error when used with single threaded pools (HoneyryderChuck, jeremyevans) (#2049)
62
+
63
+ * Workaround possible resource starvation in threaded connection pool (ioquatix) (#2048)
64
+
65
+ === 5.69.0 (2023-06-01)
66
+
67
+ * Avoid unsupported flag warning when using the mysql adapter with ruby-mysql 3+ (jeremyevans)
68
+
69
+ * Make mysql adapter work with ruby-mysql 4+ (jeremyevans)
70
+
71
+ * Add Model::DatasetModule#model accessor (davekaro) (#2040)
72
+
73
+ * Add trilogy adapter (jeremyevans)
74
+
75
+ === 5.68.0 (2023-05-01)
76
+
77
+ * Add validation_helpers_generic_type_messages plugin for more useful type validation failure messages (jeremyevans) (#2028)
78
+
79
+ * Make constraint_validations plugin not validate missing columns that have a default value (jeremyevans) (#2023)
80
+
81
+ * Skip normal type name parsing for enum/array/composite/range/multirange types on PostgreSQL (jeremyevans) (#2019)
82
+
83
+ * Fix corner case where pg_extended_date_support did not work correctly when using the jdbc/postgresql adapter (jeremyevans)
84
+
85
+ * Include :min_value and :max_value schema entries for date/timestamp/timestamptz columns on PostgreSQL 9.6+ (jeremyevans)
86
+
1
87
  === 5.67.0 (2023-04-01)
2
88
 
3
89
  * Fix dumping of string column sizes in the schema dumper on MSSQL (jeremyevans) (#2013)
data/README.rdoc CHANGED
@@ -13,7 +13,7 @@ toolkit for Ruby.
13
13
  database sharding.
14
14
  * Sequel currently has adapters for ADO, Amalgalite,
15
15
  IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
16
- PostgreSQL, SQLAnywhere, SQLite3, and TinyTDS.
16
+ PostgreSQL, SQLAnywhere, SQLite3, TinyTDS, and Trilogy.
17
17
 
18
18
  == Resources
19
19
 
@@ -825,7 +825,7 @@ You can dynamically customize eager loads for both +eager+ and +eager_graph+ whi
825
825
 
826
826
  === Joining with Associations
827
827
 
828
- You can use the +association_join+ method to add a join to the model's dataset based on the assocation:
828
+ You can use the +association_join+ method to add a join to the model's dataset based on the association:
829
829
 
830
830
  Post.association_join(:author)
831
831
  # SELECT * FROM posts
@@ -927,7 +927,7 @@ Sequel fully supports the currently supported versions of Ruby (MRI) and JRuby.
927
927
  support unsupported versions of Ruby or JRuby, but such support may be dropped in any
928
928
  minor version if keeping it becomes a support issue. The minimum Ruby version
929
929
  required to run the current version of Sequel is 1.9.2, and the minimum JRuby version is
930
- 9.0.0.0.
930
+ 9.2.0.0 (due to the bigdecimal dependency).
931
931
 
932
932
  == Maintainer
933
933
 
@@ -670,8 +670,10 @@ polymorphic associations in Sequel about as easy as it is in ActiveRecord. Howe
670
670
  here's how they can be done using Sequel's custom associations (the sequel_polymorphic
671
671
  external plugin is just a generic version of this code):
672
672
 
673
+ Sequel.extension :inflector # for attachable_type.constantize
674
+
673
675
  class Asset < Sequel::Model
674
- many_to_one :attachable, reciprocal: :assets,
676
+ many_to_one :attachable, reciprocal: :assets, reciprocal_type: :one_to_many,
675
677
  setter: (lambda do |attachable|
676
678
  self[:attachable_id] = (attachable.pk if attachable)
677
679
  self[:attachable_type] = (attachable.class.name if attachable)
@@ -48,7 +48,7 @@ If you want to change mass assignment so it ignores attempts to access restricte
48
48
  Since mass assignment by default allows modification of all column values except for primary key columns, it can be a security risk in some cases.
49
49
  If you are dealing with untrusted input, you are generally going to want to restrict what should be updated.
50
50
 
51
- Sequel has <tt>Model#set_fields</tt> and <tt>Model#update_fields</tt> methods, which are designed to be used with untrused input.
51
+ Sequel has <tt>Model#set_fields</tt> and <tt>Model#update_fields</tt> methods, which are designed to be used with untrusted input.
52
52
  These methods take two arguments, the untrusted hash as the first argument, and a trusted array of field names as the second argument:
53
53
 
54
54
  post.set_fields({title: 'T', body: 'B'}, [:title, :body])
data/doc/migration.rdoc CHANGED
@@ -86,9 +86,24 @@ the following methods:
86
86
  * +add_full_text_index+
87
87
  * +add_spatial_index+
88
88
  * +rename_column+
89
+ * +set_column_allow_null+
89
90
 
90
91
  If you use any other methods, you should create your own +down+ block.
91
92
 
93
+ To revert a migration created with +change+, you can copy the migration to a new file, and
94
+ replace +change+ with +revert+. For example, if you no longer need the artists table, you
95
+ can use the following migration. This will drop the artists table when migrating up, and
96
+ recreate it when migrating down:
97
+
98
+ Sequel.migration do
99
+ revert do
100
+ create_table(:artists) do
101
+ primary_key :id
102
+ String :name, null: false
103
+ end
104
+ end
105
+ end
106
+
92
107
  In normal usage, when Sequel's migrator runs, it runs the +up+ blocks for all
93
108
  migrations that have not yet been applied. However, you can use the <tt>-M</tt>
94
109
  switch to specify the version to which to migrate, and if it is lower than the
@@ -279,7 +279,7 @@ if either the :sslca or :sslkey option is given.
279
279
 
280
280
  === mysql2
281
281
 
282
- This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
282
+ This is a MySQL adapter that does typecasting in C, so it is often faster than the
283
283
  mysql adapter. The options given are passed to Mysql2::Client.new, see the mysql2 documentation
284
284
  for details on what options are supported. The :timeout, :auto_is_null, :sql_mode, and :disable_split_materialized
285
285
  options supported by the mysql adapter are also supported for mysql2 adapter (and any other adapters connecting to
@@ -423,3 +423,10 @@ Other Sequel specific options:
423
423
  This should be specified as an integer. If you plan on setting large
424
424
  text or blob values via tinytds, you should use this option or modify
425
425
  your freetds.conf file.
426
+
427
+ === trilogy
428
+
429
+ This is a MySQL adapter that does typecasting in C, and does not require any mysql client libraries installed.
430
+ The options given are passed to Trilogy.new, see the trilogy documentation for details on what options are
431
+ supported. The :timeout, :auto_is_null, :sql_mode, and :disable_split_materialized
432
+ options supported by the mysql adapter are also supported for trilogy adapter.
@@ -0,0 +1,61 @@
1
+ = New Features
2
+
3
+ * On PostgreSQL 9.6+, date, timestamp, and timestamptz columns now
4
+ have min_value and max_value column schema entries, allowing the
5
+ auto_validations plugin to automatically enforce minimum and
6
+ maximum values for these column types, raising a validation error
7
+ before saving, instead of database error when the query is sent
8
+ to the database.
9
+
10
+ * A validation_helpers_generic_type_messages plugin has been added,
11
+ which improves the default type validation error messages in
12
+ validation_helpers. This change was not made directly to
13
+ validation_helpers for backwards compatibility reasons, but will
14
+ probably become the default behavior in Sequel 6. Some examples
15
+ of the improvements:
16
+
17
+ # :blob type
18
+ # validation_helpers default: "value is not a valid sequel::sql::blob"
19
+ # with this plugin: "value is not a blob"
20
+
21
+ # :boolean type
22
+ # validation_helpers default: "value is not a valid trueclass or falseclass"
23
+ # with this plugin: "value is not true or false"
24
+
25
+ # :datetime type
26
+ # validation_helpers default: "value is not a valid time or datetime"
27
+ # with this plugin: "value is not a valid timestamp"
28
+
29
+ # custom/database-specific types
30
+ # validation_helpers default: "value is not a valid sequel::class_name"
31
+ # with this plugin: "value is not the expected type"
32
+
33
+ = Improvements
34
+
35
+ * The constraint_validations plugin no longer raises validation
36
+ errors for missing columns that have a default value. If a column
37
+ is missing but has a default value, we can assume the default
38
+ value is valid. Additionally, the constraint validations are now
39
+ based on the underlying column value and not any deserialized
40
+ value, so that the validation matches the constraint.
41
+
42
+ * On PostgreSQL, normal type name parsing is skipped for enum,
43
+ array, composite, range, and multirange types, ensuring that
44
+ such types will not be treated incorrectly based on their
45
+ type name.
46
+
47
+ * The pg_extended_date_support extension now works correctly with
48
+ the jdbc/postgresql adapter if there is already an entry in the
49
+ oid_convertor_map for the timestamp and timestamptz types.
50
+
51
+ = Backwards Compatibility
52
+
53
+ * Database#schema_column_type is no longer called for all columns
54
+ on PostgreSQL when parsing schema. Enum, array, composite, range,
55
+ and multirange types each have their own separate type parsing
56
+ method. So if you were overriding Database#schema_column_type to
57
+ implement custom column schema parsing, you may need to adjust
58
+ your code.
59
+
60
+ * The Sequel::Postgres::ExtendedDateSupport::DATE_YEAR_1 constant
61
+ has been removed.
@@ -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.
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/testing.rdoc CHANGED
@@ -176,7 +176,7 @@ SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when runn
176
176
  SEQUEL_MODEL_THROW_FAILURES :: Use the throw_failures plugin when running the specs
177
177
  SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
178
178
  SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
179
- SEQUEL_PG_AUTO_PARAMETERIZE :: Use the pg_auto_parameterize extension when running the postgres specs
179
+ SEQUEL_PG_AUTO_PARAMETERIZE :: Use the pg_auto_parameterize extension when running the postgres specs. Value can be +in_array+ to test the pg_auto_parameterize_in_array extension, and +in_array_string+ to test the pg_auto_parameterize_in_array extension with the +:treat_in_string_list_as_text_array+ Database option set.
180
180
  SEQUEL_PG_TIMESTAMPTZ :: Use the pg_timestamptz extension when running the postgres specs
181
181
  SEQUEL_PRIMARY_KEY_LOOKUP_CHECK_VALUES :: Use the primary_key_lookup_check_values extension when running the adapter or integration specs
182
182
  SEQUEL_QUERY_PER_ASSOCIATION_DB_0_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
@@ -301,7 +301,7 @@ module Sequel
301
301
  end
302
302
 
303
303
  def database_exception_sqlstate(exception, opts)
304
- exception.sqlstate
304
+ exception.sqlstate if exception.respond_to?(:sqlstate)
305
305
  end
306
306
 
307
307
  def dataset_class_default
@@ -199,6 +199,7 @@ module Sequel
199
199
  v.strftime("'%H:%M:%S#{sprintf(".%03d", (v.usec/1000.0).round)}'")
200
200
  end
201
201
 
202
+ INTEGER_TYPE = Java::JavaSQL::Types::INTEGER
202
203
  STRING_TYPE = Java::JavaSQL::Types::VARCHAR
203
204
  ARRAY_TYPE = Java::JavaSQL::Types::ARRAY
204
205
  PG_SPECIFIC_TYPES = [Java::JavaSQL::Types::ARRAY, Java::JavaSQL::Types::OTHER, Java::JavaSQL::Types::STRUCT, Java::JavaSQL::Types::TIME_WITH_TIMEZONE, Java::JavaSQL::Types::TIME].freeze
@@ -219,6 +220,8 @@ module Sequel
219
220
  oid = meta.getField(i).getOID
220
221
  if pr = db.oid_convertor_proc(oid)
221
222
  pr
223
+ elsif oid == 28 # XID (Transaction ID)
224
+ map[INTEGER_TYPE]
222
225
  elsif oid == 2950 # UUID
223
226
  map[STRING_TYPE]
224
227
  elsif meta.getPGType(i) == 'hstore'
@@ -36,6 +36,10 @@ module Sequel
36
36
 
37
37
  private
38
38
 
39
+ def database_exception_use_sqlstates?
40
+ false
41
+ end
42
+
39
43
  # Use @@IDENTITY to get the last inserted id
40
44
  def last_insert_id(conn, opts=OPTS)
41
45
  statement(conn) do |stmt|
@@ -79,6 +79,10 @@ module Sequel
79
79
  super.with_extend(MetadataDatasetMethods)
80
80
  end
81
81
 
82
+ def database_exception_use_sqlstates?
83
+ false
84
+ end
85
+
82
86
  def disconnect_error?(exception, opts)
83
87
  super || (exception.message =~ /connection is closed/)
84
88
  end
@@ -396,11 +396,16 @@ module Sequel
396
396
 
397
397
  def database_exception_sqlstate(exception, opts)
398
398
  if database_exception_use_sqlstates?
399
- while exception.respond_to?(:cause)
400
- exception = exception.cause
401
- return exception.getSQLState if exception.respond_to?(:getSQLState)
402
- end
399
+ _database_exception_sqlstate(exception, opts)
403
400
  end
401
+ end
402
+
403
+ def _database_exception_sqlstate(exception, opts)
404
+ 16.times do
405
+ return exception.getSQLState if exception.respond_to?(:getSQLState)
406
+ break unless exception.respond_to?(:cause) && (exception = exception.cause)
407
+ end
408
+
404
409
  nil
405
410
  end
406
411
 
@@ -415,8 +420,7 @@ module Sequel
415
420
 
416
421
  # Raise a disconnect error if the SQL state of the cause of the exception indicates so.
417
422
  def disconnect_error?(exception, opts)
418
- cause = exception.respond_to?(:cause) ? exception.cause : exception
419
- super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
423
+ super || (_database_exception_sqlstate(exception, opts) =~ /^08/)
420
424
  end
421
425
 
422
426
  # Execute the prepared statement. If the provided name is a
@@ -29,6 +29,21 @@ module Sequel
29
29
  end
30
30
  MYSQL_TYPES.freeze
31
31
 
32
+ RUBY_MYSQL_3 = !Mysql.respond_to?(:init)
33
+ RUBY_MYSQL_4 = RUBY_MYSQL_3 && ::Mysql::VERSION.to_i >= 4
34
+
35
+ if RUBY_MYSQL_3
36
+ class Adapter < ::Mysql
37
+ alias real_connect connect
38
+ alias use_result store_result
39
+ if RUBY_MYSQL_4
40
+ def initialize(**opts)
41
+ super(**opts.merge(:cast=>false))
42
+ end
43
+ end
44
+ end
45
+ end
46
+
32
47
  class Database < Sequel::Database
33
48
  include Sequel::MySQL::DatabaseMethods
34
49
  include Sequel::MySQL::MysqlMysql2::DatabaseMethods
@@ -72,7 +87,7 @@ module Sequel
72
87
  def connect(server)
73
88
  opts = server_opts(server)
74
89
 
75
- if Mysql.respond_to?(:init)
90
+ if !RUBY_MYSQL_3
76
91
  conn = Mysql.init
77
92
  conn.options(Mysql::READ_DEFAULT_GROUP, opts[:config_default_group] || "client")
78
93
  conn.options(Mysql::OPT_LOCAL_INFILE, opts[:config_local_infile]) if opts.has_key?(:config_local_infile)
@@ -88,8 +103,8 @@ module Sequel
88
103
  conn.options(Mysql::OPT_CONNECT_TIMEOUT, connect_timeout)
89
104
  end
90
105
  else
91
- # ruby-mysql 3 API
92
- conn = Mysql.new
106
+ # ruby-mysql 3+ API
107
+ conn = Adapter.new
93
108
  # no support for default group
94
109
  conn.local_infile = opts[:config_local_infile] if opts.has_key?(:config_local_infile)
95
110
  if encoding = opts[:encoding] || opts[:charset]
@@ -101,10 +116,7 @@ module Sequel
101
116
  if connect_timeout = opts[:connect_timeout]
102
117
  conn.connect_timeout = connect_timeout
103
118
  end
104
- conn.singleton_class.class_eval do
105
- alias real_connect connect
106
- alias use_result store_result
107
- end
119
+ opts[:compress] = false
108
120
  end
109
121
 
110
122
  conn.ssl_set(opts[:sslkey], opts[:sslcert], opts[:sslca], opts[:sslcapath], opts[:sslcipher]) if opts[:sslca] || opts[:sslkey]