sequel 5.51.0 → 5.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +28 -0
  3. data/README.rdoc +5 -0
  4. data/doc/opening_databases.rdoc +1 -1
  5. data/doc/release_notes/5.52.0.txt +87 -0
  6. data/doc/testing.rdoc +3 -1
  7. data/lib/sequel/adapters/amalgalite.rb +3 -5
  8. data/lib/sequel/adapters/jdbc.rb +7 -9
  9. data/lib/sequel/adapters/mysql.rb +80 -67
  10. data/lib/sequel/adapters/mysql2.rb +41 -43
  11. data/lib/sequel/adapters/postgres.rb +17 -21
  12. data/lib/sequel/adapters/shared/mysql.rb +3 -2
  13. data/lib/sequel/adapters/shared/postgres.rb +2 -2
  14. data/lib/sequel/adapters/sqlite.rb +16 -18
  15. data/lib/sequel/connection_pool/sharded_single.rb +5 -7
  16. data/lib/sequel/connection_pool/single.rb +6 -8
  17. data/lib/sequel/core.rb +17 -18
  18. data/lib/sequel/database/query.rb +1 -1
  19. data/lib/sequel/extensions/core_refinements.rb +36 -11
  20. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  21. data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
  22. data/lib/sequel/extensions/pg_array_ops.rb +1 -1
  23. data/lib/sequel/extensions/pg_hstore_ops.rb +1 -1
  24. data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
  25. data/lib/sequel/extensions/pg_interval.rb +1 -0
  26. data/lib/sequel/extensions/pg_json.rb +3 -5
  27. data/lib/sequel/extensions/pg_json_ops.rb +1 -1
  28. data/lib/sequel/extensions/pg_range_ops.rb +1 -1
  29. data/lib/sequel/extensions/pg_row_ops.rb +1 -1
  30. data/lib/sequel/extensions/s.rb +2 -1
  31. data/lib/sequel/extensions/server_block.rb +8 -12
  32. data/lib/sequel/extensions/sql_comments.rb +108 -3
  33. data/lib/sequel/extensions/string_date_time.rb +19 -23
  34. data/lib/sequel/model/base.rb +8 -12
  35. data/lib/sequel/plugins/sql_comments.rb +189 -0
  36. data/lib/sequel/plugins/subclasses.rb +28 -11
  37. data/lib/sequel/plugins/unused_associations.rb +2 -2
  38. data/lib/sequel/timezones.rb +12 -14
  39. data/lib/sequel/version.rb +1 -1
  40. metadata +7 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebee8a266be02f6ba3c1d5d340b606336dbb0fb74beb4b4333eb3c930cd59b5c
4
- data.tar.gz: f657a1aaedf3e0ef8f644097ee94760dfb04381730dd0c6f0a53c57e3f2bc742
3
+ metadata.gz: 06302dbd32fc7e13539c83a4cf86fa72d974ffb15d403f30ca13d08af83c0605
4
+ data.tar.gz: ad8cc158183399ac93c5a44e0e33d0693a92599ccb5092f542ff2993f4701d25
5
5
  SHA512:
6
- metadata.gz: 9a0aac448e73636a0c20e5e4d87d65ac648a56bb4267034c5b92fdf2cf297aeeaff408dc4e79c6fe05bdd113e22824a5d7bc7a5b236b44346cda6ed427a377c1
7
- data.tar.gz: d99a2b488a0735ba9012e4dfcaae30bec76fce1e7d3c34a14be9395241432a3d00ec5fa7a22df371810adf734e0c39230d212934f10a7d39c5839e58231d6625
6
+ metadata.gz: 9b0943434af7e097bf7589ec885b6509f40b9677d7e1be56cac17f5093bc2c9a6c1e79918b547a4d04a2623b5562e4e8897247551f1a89ecde5c53339e6c9a48
7
+ data.tar.gz: a82852fa8dd6b598b7463acafab29bd6d1b5e514b639e3d13ee33855c300d9daa662d4ea1af27525d7557644c2eb8bd1ccceec376aa6b1dc26286658db5b63e7
data/CHANGELOG CHANGED
@@ -1,3 +1,31 @@
1
+ === 5.52.0 (2022-01-01)
2
+
3
+ * Use Class#subclasses if available in the subclasses plugin, instead of a custom Model.subclasses accessor (jeremyevans)
4
+
5
+ * Add Model.descendants and .freeze_descendants to subclasses plugin (jeremyevans)
6
+
7
+ * Avoid use of deprecated Refinement#include on Ruby 3.1+ (jeremyevans)
8
+
9
+ * Add date_parse_input_handler extension for custom handling of input to date parsing methods (jeremyevans)
10
+
11
+ * Make postgres adapter respect Database#default_string_column_size (jeremyevans)
12
+
13
+ * Make pg_interval extension work with ActiveSupport 7.0 (jeremyevans)
14
+
15
+ * Make :ruby_default schema entry for type: :datetime respect Sequel.datetime_class (jeremyevans)
16
+
17
+ * Make alter_table drop_constraint have an effect on MySQL 8.0.19+ (jeremyevans)
18
+
19
+ * Make mysql adapter support ruby-mysql 3 API (jeremyevans) (#1795)
20
+
21
+ * Make mysql adapter no longer use connection's server_version, since it isn't accurate when using the ruby-mysql driver (jeremyevans)
22
+
23
+ * Add sql_comments plugin for automatically including comments on queries generated by model class, instance, and dataset methods (jeremyevans)
24
+
25
+ * Make sql_comments Database extension support Database#with_comments, for automatically including comments for queries executed inside the block (jeremyevans)
26
+
27
+ * Fix sql_comments extension to not modify cached SQL for a dataset (jeremyevans)
28
+
1
29
  === 5.51.0 (2021-12-01)
2
30
 
3
31
  * Make eager loading via tactical_eager_loading no longer modify objects who already have a cached value for the association (jeremyevans)
data/README.rdoc CHANGED
@@ -880,6 +880,11 @@ raise an error by default:
880
880
  end
881
881
  end
882
882
 
883
+ == Testing Sequel
884
+
885
+ Please see the {testing guide}[rdoc-ref:doc/testing.rdoc] for recommendations on testing
886
+ applications that use Sequel, as well as the how to run the tests for Sequel itself.
887
+
883
888
  == Sequel Release Policy
884
889
 
885
890
  New major versions of Sequel do not have a defined release policy, but historically have
@@ -249,7 +249,7 @@ jdbc-mysql :: Depending on the configuration of the MySQL server, jdbc-mysql ver
249
249
 
250
250
  Requires: mysql
251
251
 
252
- The MySQL adapter does not support the pure-ruby mysql.rb driver, it requires the C-extension driver.
252
+ This should work with the mysql gem (C extension) and the ruby-mysql gem (pure ruby).
253
253
 
254
254
  The following additional options are supported:
255
255
 
@@ -0,0 +1,87 @@
1
+ = New Features
2
+
3
+ * When the sql_comments Database extension is used,
4
+ Database#with_comments is now added, which can be used for including
5
+ comments for all queries executed inside a given block. This can
6
+ be useful if you want to analyze database query logs, and want to
7
+ group all related queries:
8
+
9
+ DB.with_comments(model: Album, action: :all) do
10
+ DB[:albums].all
11
+ # SELECT * FROM albums -- model:Album,action:all
12
+ end
13
+
14
+ * An sql_comments plugin has been added, which will automatically
15
+ add SQL comments for all queries generated by model class, instance
16
+ and dataset methods:
17
+
18
+ Album.plugin :sql_comments
19
+
20
+ album = Album[1]
21
+ # SELECT * FROM albums WHERE (id = 1) LIMIT 1
22
+ # -- model:Album,method_type:class,method:[]
23
+
24
+ album.update(:name=>'A')
25
+ # UPDATE albums SET name = 'baz' WHERE (id = 1)
26
+ # -- model:Album,method_type:instance,method:update
27
+
28
+ Album.where(id: 1).delete
29
+ # DELETE FROM albums WHERE (id = 1)
30
+ # -- model:Album,method_type:dataset,method:delete
31
+
32
+ This plugin requires you have loaded the sql_comments Database
33
+ extension into the related Database before use.
34
+
35
+ * A date_parse_input_handler extension has been added to support
36
+ custom handling of input to date parsing methods. Among other
37
+ things, you can use this to limit the length of strings that
38
+ will be parsed, which can prevent ArgumentErrors in newer Ruby
39
+ versions:
40
+
41
+ Sequel.extension :date_parse_input_handler
42
+ Sequel.date_parse_input_handler do |string|
43
+ string.b[0, 128]
44
+ end
45
+
46
+ = Other Improvements
47
+
48
+ * On Ruby 3.1, the core_refinements extension now avoids the
49
+ deprecated Refinement#include, switching to
50
+ Refinement#import_methods.
51
+
52
+ * On Ruby 3.1, the subclasses plugin will use Ruby's native support
53
+ for Class#subclasses.
54
+
55
+ * The subclasses plugin has renamed descendents to descendants and
56
+ freeze_descendents to freeze_descendants. The previous method
57
+ names are still available as aliases.
58
+
59
+ * The :ruby_default schema entry for datetime/timestamp columns now
60
+ respects Sequel.datetime_class. Previously, the value for the
61
+ :ruby_default schema entry would always be a DateTime value for
62
+ such columns.
63
+
64
+ * The pg_interval extension now works with ActiveSupport 7.0.
65
+
66
+ * The shared postgres adapter now respects
67
+ Database#default_string_column_size for setting the size of string
68
+ columns that don't use text as the database type.
69
+
70
+ * Database#supports_check_constraints? now returns true on MySQL
71
+ 8.0.19+. This fixes drop_constraint in certain cases when combining
72
+ the constraint dropping with other changes in the same alter_table
73
+ block.
74
+
75
+ * The mysql adapter now supports the ruby-mysql 3 API (ruby-mysql
76
+ is a pure-ruby MySQL driver).
77
+
78
+ * The mysql adapter no longer uses the connection's server_version
79
+ method if it is defined, as the method does not return the
80
+ correct value when using the ruby-mysql driver with MariaDB.
81
+
82
+ * Comments added by the sql_comments extension no longer modify
83
+ cached SQL for a dataset.
84
+
85
+ = Other
86
+
87
+ * This is Sequel's 250th release!
data/doc/testing.rdoc CHANGED
@@ -113,7 +113,7 @@ The order in which you delete/truncate the tables is important if you are using
113
113
 
114
114
  = Testing Sequel Itself
115
115
 
116
- Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-shared_description extensions.
116
+ Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks, minitest-global_expectations, and minitest-shared_description extensions. To install the dependencies necessary to test Sequel, run <tt>gem install --development sequel</tt>.
117
117
 
118
118
  == rake
119
119
 
@@ -145,6 +145,8 @@ The <tt>spec_<i>adapter</i></tt> specs run against a real database connection wi
145
145
 
146
146
  These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use <tt>rake spec_integration</tt> to just run the shared integration tests.
147
147
 
148
+ Each adapter needs a specific gem installed in order to run. Please see the {connecting to a database guide}[rdoc-ref:doc/opening_databases.rdoc] for which gem you need to install for the adapter you are testing.
149
+
148
150
  == Environment variables
149
151
 
150
152
  Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying <tt>spec/spec_config.rb.example</tt> to <tt>spec/spec_config.rb</tt> and modifying it. See that file for details. It may be necessary to use +spec_config.rb+ as opposed to an environment variable if your database connection cannot be specified by a connection string.
@@ -118,11 +118,9 @@ module Sequel
118
118
  # Yield an available connection. Rescue
119
119
  # any Amalgalite::Errors and turn them into DatabaseErrors.
120
120
  def _execute(sql, opts)
121
- begin
122
- synchronize(opts[:server]){|conn| yield conn}
123
- rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
124
- raise_error(e)
125
- end
121
+ synchronize(opts[:server]){|conn| yield conn}
122
+ rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
123
+ raise_error(e)
126
124
  end
127
125
 
128
126
  # The Amagalite adapter does not need the pool to convert exceptions.
@@ -32,15 +32,13 @@ module Sequel
32
32
 
33
33
  # Allow loading the necessary JDBC support via a gem.
34
34
  def self.load_gem(name)
35
- begin
36
- require "jdbc/#{name.to_s.downcase}"
37
- rescue LoadError
38
- # jdbc gem not used, hopefully the user has the .jar in their CLASSPATH
39
- else
40
- if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
41
- jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
42
- jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
43
- end
35
+ require "jdbc/#{name.to_s.downcase}"
36
+ rescue LoadError
37
+ # jdbc gem not used, hopefully the user has the .jar in their CLASSPATH
38
+ else
39
+ if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
40
+ jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
41
+ jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
44
42
  end
45
43
  end
46
44
 
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require 'mysql'
4
- raise(LoadError, "require 'mysql' did not define Mysql::CLIENT_MULTI_RESULTS!\n You are probably using the pure ruby mysql.rb driver,\n which Sequel does not support. You need to install\n the C based adapter, and make sure that the mysql.so\n file is loaded instead of the mysql.rb file.\n") unless defined?(Mysql::CLIENT_MULTI_RESULTS)
4
+ raise(LoadError, "require 'mysql' did not define Mysql::CLIENT_MULTI_RESULTS!, so it not supported. Please install the mysql or ruby-mysql gem.\n") unless defined?(Mysql::CLIENT_MULTI_RESULTS)
5
5
 
6
6
  require_relative 'utils/mysql_mysql2'
7
7
  require_relative 'utils/mysql_prepared_statements'
@@ -71,21 +71,43 @@ module Sequel
71
71
  # disconnect this connection (a.k.a @@wait_timeout).
72
72
  def connect(server)
73
73
  opts = server_opts(server)
74
- conn = Mysql.init
75
- conn.options(Mysql::READ_DEFAULT_GROUP, opts[:config_default_group] || "client")
76
- conn.options(Mysql::OPT_LOCAL_INFILE, opts[:config_local_infile]) if opts.has_key?(:config_local_infile)
77
- conn.ssl_set(opts[:sslkey], opts[:sslcert], opts[:sslca], opts[:sslcapath], opts[:sslcipher]) if opts[:sslca] || opts[:sslkey]
78
- if encoding = opts[:encoding] || opts[:charset]
79
- # Set encoding before connecting so that the mysql driver knows what
80
- # encoding we want to use, but this can be overridden by READ_DEFAULT_GROUP.
81
- conn.options(Mysql::SET_CHARSET_NAME, encoding)
82
- end
83
- if read_timeout = opts[:read_timeout] and defined? Mysql::OPT_READ_TIMEOUT
84
- conn.options(Mysql::OPT_READ_TIMEOUT, read_timeout)
85
- end
86
- if connect_timeout = opts[:connect_timeout] and defined? Mysql::OPT_CONNECT_TIMEOUT
87
- conn.options(Mysql::OPT_CONNECT_TIMEOUT, connect_timeout)
74
+
75
+ if Mysql.respond_to?(:init)
76
+ conn = Mysql.init
77
+ conn.options(Mysql::READ_DEFAULT_GROUP, opts[:config_default_group] || "client")
78
+ conn.options(Mysql::OPT_LOCAL_INFILE, opts[:config_local_infile]) if opts.has_key?(:config_local_infile)
79
+ if encoding = opts[:encoding] || opts[:charset]
80
+ # Set encoding before connecting so that the mysql driver knows what
81
+ # encoding we want to use, but this can be overridden by READ_DEFAULT_GROUP.
82
+ conn.options(Mysql::SET_CHARSET_NAME, encoding)
83
+ end
84
+ if read_timeout = opts[:read_timeout] and defined? Mysql::OPT_READ_TIMEOUT
85
+ conn.options(Mysql::OPT_READ_TIMEOUT, read_timeout)
86
+ end
87
+ if connect_timeout = opts[:connect_timeout] and defined? Mysql::OPT_CONNECT_TIMEOUT
88
+ conn.options(Mysql::OPT_CONNECT_TIMEOUT, connect_timeout)
89
+ end
90
+ else
91
+ # ruby-mysql 3 API
92
+ conn = Mysql.new
93
+ # no support for default group
94
+ conn.local_infile = opts[:config_local_infile] if opts.has_key?(:config_local_infile)
95
+ if encoding = opts[:encoding] || opts[:charset]
96
+ conn.charset = encoding
97
+ end
98
+ if read_timeout = opts[:read_timeout]
99
+ conn.read_timeout = read_timeout
100
+ end
101
+ if connect_timeout = opts[:connect_timeout]
102
+ conn.connect_timeout = connect_timeout
103
+ end
104
+ conn.singleton_class.class_eval do
105
+ alias real_connect connect
106
+ alias use_result store_result
107
+ end
88
108
  end
109
+
110
+ conn.ssl_set(opts[:sslkey], opts[:sslcert], opts[:sslca], opts[:sslcapath], opts[:sslcipher]) if opts[:sslca] || opts[:sslkey]
89
111
  conn.real_connect(
90
112
  opts[:host] || 'localhost',
91
113
  opts[:user],
@@ -152,56 +174,49 @@ module Sequel
152
174
  super
153
175
  end
154
176
 
155
- # Return the version of the MySQL server to which we are connecting.
156
- def server_version(server=nil)
157
- @server_version ||= (synchronize(server){|conn| conn.server_version if conn.respond_to?(:server_version)} || super)
158
- end
159
-
160
177
  private
161
178
 
162
179
  # Execute the given SQL on the given connection. If the :type
163
180
  # option is :select, yield the result of the query, otherwise
164
181
  # yield the connection if a block is given.
165
182
  def _execute(conn, sql, opts)
166
- begin
167
- r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn){conn.query(sql)}
168
- if opts[:type] == :select
169
- yield r if r
170
- elsif defined?(yield)
171
- yield conn
172
- end
173
- if conn.respond_to?(:more_results?)
174
- while conn.more_results? do
175
- if r
176
- r.free
177
- r = nil
178
- end
179
- begin
180
- conn.next_result
181
- r = conn.use_result
182
- rescue Mysql::Error => e
183
- raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
184
- break
185
- end
186
- yield r if opts[:type] == :select
183
+ r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn){conn.query(sql)}
184
+ if opts[:type] == :select
185
+ yield r if r
186
+ elsif defined?(yield)
187
+ yield conn
188
+ end
189
+ if conn.respond_to?(:more_results?)
190
+ while conn.more_results? do
191
+ if r
192
+ r.free
193
+ r = nil
194
+ end
195
+ begin
196
+ conn.next_result
197
+ r = conn.use_result
198
+ rescue Mysql::Error => e
199
+ raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
200
+ break
187
201
  end
202
+ yield r if opts[:type] == :select
188
203
  end
189
- rescue Mysql::Error => e
190
- raise_error(e)
191
- ensure
192
- r.free if r
193
- # Use up all results to avoid a commands out of sync message.
194
- if conn.respond_to?(:more_results?)
195
- while conn.more_results? do
196
- begin
197
- conn.next_result
198
- r = conn.use_result
199
- rescue Mysql::Error => e
200
- raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
201
- break
202
- end
203
- r.free if r
204
+ end
205
+ rescue Mysql::Error => e
206
+ raise_error(e)
207
+ ensure
208
+ r.free if r
209
+ # Use up all results to avoid a commands out of sync message.
210
+ if conn.respond_to?(:more_results?)
211
+ while conn.more_results? do
212
+ begin
213
+ conn.next_result
214
+ r = conn.use_result
215
+ rescue Mysql::Error => e
216
+ raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
217
+ break
204
218
  end
219
+ r.free if r
205
220
  end
206
221
  end
207
222
  end
@@ -233,17 +248,15 @@ module Sequel
233
248
  # the conversion raises an InvalidValue exception, return v
234
249
  # if :string and nil otherwise.
235
250
  def convert_date_time(v)
236
- begin
237
- yield v
238
- rescue InvalidValue
239
- case @convert_invalid_date_time
240
- when nil, :nil
241
- nil
242
- when :string
243
- v
244
- else
245
- raise
246
- end
251
+ yield v
252
+ rescue InvalidValue
253
+ case @convert_invalid_date_time
254
+ when nil, :nil
255
+ nil
256
+ when :string
257
+ v
258
+ else
259
+ raise
247
260
  end
248
261
  end
249
262
 
@@ -111,56 +111,54 @@ module Sequel
111
111
  # option is :select, yield the result of the query, otherwise
112
112
  # yield the connection if a block is given.
113
113
  def _execute(conn, sql, opts)
114
- begin
115
- stream = opts[:stream]
116
- if NativePreparedStatements
117
- if args = opts[:arguments]
118
- args = args.map{|arg| bound_variable_value(arg)}
119
- end
114
+ stream = opts[:stream]
115
+ if NativePreparedStatements
116
+ if args = opts[:arguments]
117
+ args = args.map{|arg| bound_variable_value(arg)}
118
+ end
120
119
 
121
- case sql
122
- when ::Mysql2::Statement
123
- stmt = sql
124
- when Dataset
125
- sql = sql.sql
126
- close_stmt = true
127
- stmt = conn.prepare(sql)
128
- end
120
+ case sql
121
+ when ::Mysql2::Statement
122
+ stmt = sql
123
+ when Dataset
124
+ sql = sql.sql
125
+ close_stmt = true
126
+ stmt = conn.prepare(sql)
129
127
  end
128
+ end
130
129
 
131
- r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn, args) do
132
- if stmt
133
- conn.query_options.merge!(:cache_rows=>true, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream, :cast_booleans=>convert_tinyint_to_bool)
134
- stmt.execute(*args)
135
- else
136
- conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream)
137
- end
130
+ r = log_connection_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql, conn, args) do
131
+ if stmt
132
+ conn.query_options.merge!(:cache_rows=>true, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream, :cast_booleans=>convert_tinyint_to_bool)
133
+ stmt.execute(*args)
134
+ else
135
+ conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream)
138
136
  end
139
- if opts[:type] == :select
140
- if r
141
- if stream
142
- begin
143
- r2 = yield r
144
- ensure
145
- # If r2 is nil, it means the block did not exit normally,
146
- # so the rest of the results must be drained to prevent
147
- # "commands out of sync" errors.
148
- r.each{} unless r2
149
- end
150
- else
151
- yield r
137
+ end
138
+ if opts[:type] == :select
139
+ if r
140
+ if stream
141
+ begin
142
+ r2 = yield r
143
+ ensure
144
+ # If r2 is nil, it means the block did not exit normally,
145
+ # so the rest of the results must be drained to prevent
146
+ # "commands out of sync" errors.
147
+ r.each{} unless r2
152
148
  end
149
+ else
150
+ yield r
153
151
  end
154
- elsif defined?(yield)
155
- yield conn
156
- end
157
- rescue ::Mysql2::Error => e
158
- raise_error(e)
159
- ensure
160
- if stmt
161
- conn.query_options.replace(conn.instance_variable_get(:@sequel_default_query_options))
162
- stmt.close if close_stmt
163
152
  end
153
+ elsif defined?(yield)
154
+ yield conn
155
+ end
156
+ rescue ::Mysql2::Error => e
157
+ raise_error(e)
158
+ ensure
159
+ if stmt
160
+ conn.query_options.replace(conn.instance_variable_get(:@sequel_default_query_options))
161
+ stmt.close if close_stmt
164
162
  end
165
163
  end
166
164
 
@@ -116,25 +116,23 @@ module Sequel
116
116
  # error classes is raised, or a PGError is raised and the connection
117
117
  # status cannot be determined or it is not OK.
118
118
  def check_disconnect_errors
119
+ yield
120
+ rescue *DISCONNECT_ERROR_CLASSES => e
121
+ disconnect = true
122
+ raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError))
123
+ rescue PGError => e
124
+ disconnect = false
119
125
  begin
120
- yield
121
- rescue *DISCONNECT_ERROR_CLASSES => e
126
+ s = status
127
+ rescue PGError
122
128
  disconnect = true
123
- raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError))
124
- rescue PGError => e
125
- disconnect = false
126
- begin
127
- s = status
128
- rescue PGError
129
- disconnect = true
130
- end
131
- status_ok = (s == Adapter::CONNECTION_OK)
132
- disconnect ||= !status_ok
133
- disconnect ||= e.message =~ DISCONNECT_ERROR_RE
134
- disconnect ? raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)) : raise
135
- ensure
136
- block if status_ok && !disconnect
137
129
  end
130
+ status_ok = (s == Adapter::CONNECTION_OK)
131
+ disconnect ||= !status_ok
132
+ disconnect ||= e.message =~ DISCONNECT_ERROR_RE
133
+ disconnect ? raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)) : raise
134
+ ensure
135
+ block if status_ok && !disconnect
138
136
  end
139
137
 
140
138
  # Execute the given SQL with this connection. If a block is given,
@@ -518,11 +516,9 @@ module Sequel
518
516
 
519
517
  # Convert exceptions raised from the block into DatabaseErrors.
520
518
  def check_database_errors
521
- begin
522
- yield
523
- rescue => e
524
- raise_error(e, :classes=>database_error_classes)
525
- end
519
+ yield
520
+ rescue => e
521
+ raise_error(e, :classes=>database_error_classes)
526
522
  end
527
523
 
528
524
  # Set the DateStyle to ISO if configured, for faster date parsing.
@@ -544,9 +544,10 @@ module Sequel
544
544
  server_version >= 50600 && (op[:op] == :drop_index || (op[:op] == :drop_constraint && op[:type] == :unique))
545
545
  end
546
546
 
547
- # Whether the database supports CHECK constraints
547
+ # CHECK constraints only supported on MariaDB 10.2+ and MySQL 8.0.19+
548
+ # (at least MySQL documents DROP CONSTRAINT was supported in 8.0.19+).
548
549
  def supports_check_constraints?
549
- mariadb? && server_version >= 100200
550
+ server_version >= (mariadb? ? 100200 : 80019)
550
551
  end
551
552
 
552
553
  # MySQL can combine multiple alter table ops into a single query.
@@ -1504,9 +1504,9 @@ module Sequel
1504
1504
  if column[:text]
1505
1505
  :text
1506
1506
  elsif column[:fixed]
1507
- "char(#{column[:size]||255})"
1507
+ "char(#{column[:size]||default_string_column_size})"
1508
1508
  elsif column[:text] == false || column[:size]
1509
- "varchar(#{column[:size]||255})"
1509
+ "varchar(#{column[:size]||default_string_column_size})"
1510
1510
  else
1511
1511
  :text
1512
1512
  end
@@ -189,26 +189,24 @@ module Sequel
189
189
  # Yield an available connection. Rescue
190
190
  # any SQLite3::Exceptions and turn them into DatabaseErrors.
191
191
  def _execute(type, sql, opts, &block)
192
- begin
193
- synchronize(opts[:server]) do |conn|
194
- return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
195
- log_args = opts[:arguments]
196
- args = {}
197
- opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v)}
198
- case type
199
- when :select
200
- log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)}
201
- when :insert
202
- log_connection_yield(sql, conn, log_args){conn.execute(sql, args)}
203
- conn.last_insert_row_id
204
- when :update
205
- log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)}
206
- conn.changes
207
- end
192
+ synchronize(opts[:server]) do |conn|
193
+ return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
194
+ log_args = opts[:arguments]
195
+ args = {}
196
+ opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v)}
197
+ case type
198
+ when :select
199
+ log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)}
200
+ when :insert
201
+ log_connection_yield(sql, conn, log_args){conn.execute(sql, args)}
202
+ conn.last_insert_row_id
203
+ when :update
204
+ log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)}
205
+ conn.changes
208
206
  end
209
- rescue SQLite3::Exception => e
210
- raise_error(e)
211
207
  end
208
+ rescue SQLite3::Exception => e
209
+ raise_error(e)
212
210
  end
213
211
 
214
212
  # The SQLite adapter does not need the pool to convert exceptions.
@@ -55,13 +55,11 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
55
55
  # Yields the connection to the supplied block for the given server.
56
56
  # This method simulates the ConnectionPool#hold API.
57
57
  def hold(server=:default)
58
- begin
59
- server = pick_server(server)
60
- yield(@conns[server] ||= make_new(server))
61
- rescue Sequel::DatabaseDisconnectError, *@error_classes => e
62
- disconnect_server(server) if disconnect_error?(e)
63
- raise
64
- end
58
+ server = pick_server(server)
59
+ yield(@conns[server] ||= make_new(server))
60
+ rescue Sequel::DatabaseDisconnectError, *@error_classes => e
61
+ disconnect_server(server) if disconnect_error?(e)
62
+ raise
65
63
  end
66
64
 
67
65
  # The ShardedSingleConnectionPool always has a maximum size of 1.