sequel 5.80.0 → 5.81.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddf0e8e9009f39ca7f6dffca8aef10ef4fbdf22a8c5002def5ecea4042f38763
4
- data.tar.gz: b9f3cb97273dd9885e8002a64e17bddd0a6db2f932d1c68ce97844e2ac843096
3
+ metadata.gz: a23afa1510b7bd1ba6918319eedce156450672520ab4798e6de56461a59660e1
4
+ data.tar.gz: bb6bbfbf0f1f82fe117fa8c725e9cf4fde49644a74b463ab8682018744a8a1de
5
5
  SHA512:
6
- metadata.gz: 7387d403f32cb492abe6fad35d6a87a4ac274fc3602aee0f8afba38d9feb30578ee774de2b168a88d86ab740a41fa2a62333f695c0d2fa507fde775943917daa
7
- data.tar.gz: 11b1c1e9daf92153585f158358ee85078b83decfca8bcf4569fa90e59335dfd123a0d8fddf8f6e58e166801029de23937279dc3aa746d0d3878a34dac90ce636
6
+ metadata.gz: 9e26620f8f1df2715205e9019c2012ec2e9f392d14ed427d66c76f488bccc3e5d3f27e4d626a47d54903d611695db0487f987d99191602024a1864d6c10f7bde
7
+ data.tar.gz: cd070d8c35960949039d226b5eaf8c90ebec8d0cef3f09b5dae533551bb35170ca6e2503d88f1b1512110b6617ff9c03d9cb2afb62395c4d953314aa5a5ca87c
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 5.81.0 (2024-06-01)
2
+
3
+ * Fix ignored block warnings in a couple plugin apply methods on Ruby 3.4 (jeremyevans)
4
+
5
+ * Skip Ruby internal caller locations when searching for caller locations in caller_logging and provenance extensions (jeremyevans)
6
+
7
+ * Add temporarily_release_connection Database extension for multithreaded transactional testing (jeremyevans)
8
+
1
9
  === 5.80.0 (2024-05-01)
2
10
 
3
11
  * Support Dataset#skip_locked on MariaDB 10.6+ (simi) (#2150)
data/doc/code_order.rdoc CHANGED
@@ -91,9 +91,11 @@ unsafe runtime modification of the configuration:
91
91
  model_classes.each(&:freeze)
92
92
  DB.freeze
93
93
 
94
- The `subclasses` plugin can be used to keep track of all model classes
95
- that have been setup in your application. Finalizing their associations
96
- and freezing them can easily be achieved through the plugin:
94
+ `model_classes` is not a Sequel method, it indicates an array of model
95
+ classes you defined. Instead of listing them manually, the `subclasses`
96
+ plugin can be used to keep track of all model classes that have been
97
+ setup in your application. Finalizing their associations and freezing
98
+ them can easily be achieved through the plugin:
97
99
 
98
100
  # Register the plugin before setting up the models
99
101
  Sequel::Model.plugin :subclasses
@@ -0,0 +1,31 @@
1
+ = New Features
2
+
3
+ * A temporarily_release_connection Database extension has been added,
4
+ designed for multithreaded transactional testing.
5
+
6
+ This allows one thread to start a transaction, and then release
7
+ the connection back for usage by the connection pool, so that
8
+ other threads can operate on the connection object safely inside
9
+ the transaction. This requires the connection pool be limited
10
+ to a single connection, to ensure that the released connection
11
+ can be reacquired. It's not perfect, because if the connection
12
+ is disconnected and removed from the pool while temporarily
13
+ released, there is no way to handle that situation correctly.
14
+ Example:
15
+
16
+ DB.transaction(rollback: :always, auto_savepoint: true) do |conn|
17
+ DB.temporarily_release_connection(conn) do
18
+ # Other threads can operate on connection safely inside
19
+ # the transaction
20
+ yield
21
+ end
22
+ end
23
+
24
+ = Other Improvements
25
+
26
+ * In the caller_logging and provenance extensions, Ruby internal
27
+ caller locations are skipped when trying to locate the appropriate
28
+ caller line to include.
29
+
30
+ * A couple ignored block warnings in plugin apply methods have been
31
+ fixed on Ruby 3.4.
@@ -37,6 +37,7 @@ module Sequel
37
37
  module CallerLogging
38
38
  SEQUEL_LIB_PATH = (File.expand_path('../../..', __FILE__) + '/').freeze
39
39
  RUBY_STDLIB = RbConfig::CONFIG["rubylibdir"]
40
+ INTERNAL = '<internal'
40
41
 
41
42
  # A regexp of caller lines to ignore, in addition to internal Sequel and Ruby code.
42
43
  attr_accessor :caller_logging_ignore
@@ -61,6 +62,7 @@ module Sequel
61
62
  c = caller.find do |line|
62
63
  !(line.start_with?(SEQUEL_LIB_PATH) ||
63
64
  line.start_with?(RUBY_STDLIB) ||
65
+ line.start_with?(INTERNAL) ||
64
66
  (ignore && line =~ ignore))
65
67
  end
66
68
 
@@ -38,6 +38,7 @@ module Sequel
38
38
  module Provenance
39
39
  SEQUEL_LIB_PATH = (File.expand_path('../../..', __FILE__) + '/').freeze
40
40
  RUBY_STDLIB = RbConfig::CONFIG["rubylibdir"]
41
+ INTERNAL = '<internal'
41
42
 
42
43
  if TRUE_FREEZE
43
44
  # Include provenance information when cloning datasets.
@@ -98,6 +99,7 @@ module Sequel
98
99
  caller.find do |line|
99
100
  !(line.start_with?(SEQUEL_LIB_PATH) ||
100
101
  line.start_with?(RUBY_STDLIB) ||
102
+ line.start_with?(INTERNAL) ||
101
103
  (ignore && line =~ ignore))
102
104
  end
103
105
  end
@@ -0,0 +1,178 @@
1
+ # frozen-string-literal: true
2
+ #
3
+ # The temporarily_release_connection extension adds support for temporarily
4
+ # releasing a checked out connection back to the connection pool. It is
5
+ # designed for use in multithreaded transactional integration tests, allowing
6
+ # a connection to start a transaction in one thread, but be temporarily
7
+ # released back to the connection pool, so it can be operated on safely
8
+ # by multiple threads inside a block. For example, the main thread could be
9
+ # running tests that send web requests, and a separate thread running a web
10
+ # server that is responding to those requests, and the same connection and
11
+ # transaction would be used for both.
12
+ #
13
+ # To load the extension into the database:
14
+ #
15
+ # DB.extension :temporarily_release_connection
16
+ #
17
+ # After the extension is loaded, call the +temporarily_release_connection+
18
+ # method with the connection object to temporarily release the connection
19
+ # back to the pool. Example:
20
+ #
21
+ # DB.transaction(rollback: :always, auto_savepoint: true) do |conn|
22
+ # DB.temporarily_release_connection(conn) do
23
+ # # Other threads can operate on connection safely inside the transaction
24
+ # yield
25
+ # end
26
+ # end
27
+ #
28
+ # For sharded connection pools, the second argument to +temporarily_release_connection+
29
+ # is respected, and specifies the server on which to temporarily release the connection.
30
+ #
31
+ # The temporarily_release_connection extension is only supported with the
32
+ # threaded and timed_queue connection pools that ship with Sequel (and the sharded
33
+ # versions of each). To make sure that same connection object can be reacquired, it
34
+ # is only supported if the maximum connection pool size is 1, so set the Database
35
+ # :max_connections option to 1 if you plan to use this extension.
36
+ #
37
+ # If the +temporarily_release_connection+ method cannot reacquire the same connection
38
+ # it released to the pool, it will raise a Sequel::UnableToReacquireConnectionError
39
+ # exception. This should only happen if the connection has been disconnected
40
+ # while it was temporarily released. If this error is raised, Database#transaction
41
+ # will not rollback the transaction, since the connection object is likely no longer
42
+ # valid, and on poorly written database drivers, that could cause the process to crash.
43
+ #
44
+ # Related modules: Sequel::TemporarilyReleaseConnection,
45
+ # Sequel::UnableToReacquireConnectionError
46
+
47
+ #
48
+ module Sequel
49
+ # Error class raised if the connection pool does not provide the same connection
50
+ # object when checking a temporarily released connection out.
51
+ class UnableToReacquireConnectionError < Error
52
+ end
53
+
54
+ module TemporarilyReleaseConnection
55
+ module DatabaseMethods
56
+ # Temporarily release the connection back to the connection pool for the
57
+ # duration of the block.
58
+ def temporarily_release_connection(conn, server=:default, &block)
59
+ pool.temporarily_release_connection(conn, server, &block)
60
+ end
61
+
62
+ private
63
+
64
+ # Do nothing if UnableToReacquireConnectionError is raised, as it is
65
+ # likely the connection is not in a usable state.
66
+ def rollback_transaction(conn, opts)
67
+ return if UnableToReacquireConnectionError === $!
68
+ super
69
+ end
70
+ end
71
+
72
+ module PoolMethods
73
+ # Temporarily release a currently checked out connection, then yield to the block. Reacquire the same
74
+ # connection upon the exit of the block.
75
+ def temporarily_release_connection(conn, server)
76
+ t = Sequel.current
77
+ raise Error, "connection not currently checked out" unless conn.equal?(trc_owned_connection(t, server))
78
+
79
+ begin
80
+ trc_release(t, conn, server)
81
+ yield
82
+ ensure
83
+ c = trc_acquire(t, server)
84
+ unless conn.equal?(c)
85
+ raise UnableToReacquireConnectionError, "reacquired connection not the same as initial connection"
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ module TimedQueue
92
+ private
93
+
94
+ def trc_owned_connection(t, server)
95
+ owned_connection(t)
96
+ end
97
+
98
+ def trc_release(t, conn, server)
99
+ release(t)
100
+ end
101
+
102
+ def trc_acquire(t, server)
103
+ acquire(t)
104
+ end
105
+ end
106
+
107
+ module ShardedTimedQueue
108
+ # Normalize the server name for sharded connection pools
109
+ def temporarily_release_connection(conn, server)
110
+ server = pick_server(server)
111
+ super
112
+ end
113
+
114
+ private
115
+
116
+ def trc_owned_connection(t, server)
117
+ owned_connection(t, server)
118
+ end
119
+
120
+ def trc_release(t, conn, server)
121
+ release(t, conn, server)
122
+ end
123
+
124
+ def trc_acquire(t, server)
125
+ acquire(t, server)
126
+ end
127
+ end
128
+
129
+ module ThreadedBase
130
+ private
131
+
132
+ def trc_release(t, conn, server)
133
+ sync{super}
134
+ end
135
+ end
136
+
137
+ module Threaded
138
+ include TimedQueue
139
+ include ThreadedBase
140
+ end
141
+
142
+ module ShardedThreaded
143
+ include ShardedTimedQueue
144
+ include ThreadedBase
145
+ end
146
+ end
147
+
148
+ trc = TemporarilyReleaseConnection
149
+ trc_map = {
150
+ :threaded => trc::Threaded,
151
+ :sharded_threaded => trc::ShardedThreaded,
152
+ :timed_queue => trc::TimedQueue,
153
+ :sharded_timed_queue => trc::ShardedTimedQueue,
154
+ }.freeze
155
+
156
+ Database.register_extension(:temporarily_release_connection) do |db|
157
+ unless pool_mod = trc_map[db.pool.pool_type]
158
+ raise(Error, "temporarily_release_connection extension not supported for connection pool type #{db.pool.pool_type}")
159
+ end
160
+
161
+ case db.pool.pool_type
162
+ when :threaded, :sharded_threaded
163
+ if db.opts[:connection_handling] == :disconnect
164
+ raise Error, "temporarily_release_connection extension not supported with connection_handling: :disconnect option"
165
+ end
166
+ end
167
+
168
+ unless db.pool.max_size == 1
169
+ raise Error, "temporarily_release_connection extension not supported unless :max_connections option is 1"
170
+ end
171
+
172
+ db.extend(trc::DatabaseMethods)
173
+ db.pool.extend(trc::PoolMethods)
174
+ db.pool.extend(pool_mod)
175
+ end
176
+
177
+ private_constant :TemporarilyReleaseConnection
178
+ end
@@ -586,7 +586,7 @@ module Sequel
586
586
  end
587
587
  end
588
588
 
589
- def self.apply(model, opts=OPTS)
589
+ def self.apply(model, opts=OPTS, &_)
590
590
  model.plugin :serialization
591
591
  end
592
592
 
@@ -24,7 +24,7 @@ module Sequel
24
24
  # # Make the Album class support input transformers
25
25
  # Album.plugin :input_transformer
26
26
  module InputTransformer
27
- def self.apply(model, *)
27
+ def self.apply(model, *, &_)
28
28
  model.instance_exec do
29
29
  @input_transformers = {}
30
30
  @skip_input_transformer_columns = {}
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 80
9
+ MINOR = 81
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.80.0
4
+ version: 5.81.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-01 00:00:00.000000000 Z
11
+ date: 2024-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -228,6 +228,7 @@ extra_rdoc_files:
228
228
  - doc/release_notes/5.79.0.txt
229
229
  - doc/release_notes/5.8.0.txt
230
230
  - doc/release_notes/5.80.0.txt
231
+ - doc/release_notes/5.81.0.txt
231
232
  - doc/release_notes/5.9.0.txt
232
233
  files:
233
234
  - CHANGELOG
@@ -336,6 +337,7 @@ files:
336
337
  - doc/release_notes/5.79.0.txt
337
338
  - doc/release_notes/5.8.0.txt
338
339
  - doc/release_notes/5.80.0.txt
340
+ - doc/release_notes/5.81.0.txt
339
341
  - doc/release_notes/5.9.0.txt
340
342
  - doc/schema_modification.rdoc
341
343
  - doc/security.rdoc
@@ -522,6 +524,7 @@ files:
522
524
  - lib/sequel/extensions/symbol_as.rb
523
525
  - lib/sequel/extensions/symbol_as_refinement.rb
524
526
  - lib/sequel/extensions/synchronize_sql.rb
527
+ - lib/sequel/extensions/temporarily_release_connection.rb
525
528
  - lib/sequel/extensions/thread_local_timezones.rb
526
529
  - lib/sequel/extensions/to_dot.rb
527
530
  - lib/sequel/extensions/transaction_connection_validator.rb