sequel 5.28.0 → 5.29.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: e206de897422ca8260c788bcfc20bcb154c9122dd17a12dc4b45ecdca023eb9a
4
- data.tar.gz: 319df67cbb77d1b93d12cd0a1f429de0b674543ebd62b6407d40e1bd992e2352
3
+ metadata.gz: 014f4b025465c81d313d8ea8d5591d47165d84ee0e15906d3591992f63830e08
4
+ data.tar.gz: f0d19f67d618a2e7cbdf67b198f218cc765507d9de093934edfe1e30aa641e41
5
5
  SHA512:
6
- metadata.gz: a69c5b0bdfdb9c32503204b19d7dc18a7f78f7af7d46c44a7a4413ed4561c3ed3d0a796742045b158714a45f165957a0b9e5d6830bb110e53872a17a1ccb1ed8
7
- data.tar.gz: 73a7df723afa66c70f72218e0327f10ef659a22614e5a4438d8fdc2ba16ec97d6e33213c4fd2ed08e806f2860f968786543015b34f38449093d71194aadb3655
6
+ metadata.gz: c1cda2787c781672dba64847f1524c0ae4120f0ee1eb412a9dbf814336941337b71b4bbc4bb481eb7d9fd847646ca657fcb2309f66030d6d51d28e96f787f073
7
+ data.tar.gz: 64a84a203bb795e586ca50f47d9ff865f9162bffae9d5f36c3d3dfc1baa3696f925bd474b2d4c74fc400f77f550c7fb7f74ea29ff4dfac9322db54a3c42a8732
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ === 5.29.0 (2020-02-01)
2
+
3
+ * Recognize another disconnect error in the tinytds adapter (jeremyevans)
4
+
5
+ * Fix verbose warning in postgres adapter when using prepared statements and recent versions of ruby-pg (jeremyevans)
6
+
7
+ * Work correctly on Ruby 2.8+ by supporting second argument for initialize_clone (jeremyevans)
8
+
9
+ * Add empty_failure_backtraces plugin for empty backtraces for ValidationFailed and HookFailed exceptions, much faster on JRuby (jeremyevans)
10
+
11
+ * Add Dataset#json_serializer_opts to json_serializer plugin, allowing to set json_serializer options on a per-dataset basis (jeremyevans)
12
+
1
13
  === 5.28.0 (2020-01-01)
2
14
 
3
15
  * Warn when calling Sequel::JDBC::Postgres::Dataset#with_fetch_size (jeremyevans) (#1665)
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2007-2008 Sharon Rosner
2
- Copyright (c) 2008-2019 Jeremy Evans
2
+ Copyright (c) 2008-2020 Jeremy Evans
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to
@@ -0,0 +1,22 @@
1
+ = New Features
2
+
3
+ * An empty_failure_backtraces plugin has been added for using empty
4
+ backtraces for ValidationFailed and HookFailed exceptions. In many
5
+ cases, these exceptions are automatically handled (e.g. web form
6
+ submission handling to display appropriate error pages), and using
7
+ empty backtraces is 10-15x faster on JRuby 9.2.7.0+.
8
+
9
+ * Dataset#json_serializer_opts has been added to the json_serializer
10
+ plugin. This allows setting default options on a per-Dataset basis
11
+ for all Dataset#to_json calls.
12
+
13
+ = Other Improvements
14
+
15
+ * Another disconnect error is now recognized in the tinytds adapter.
16
+
17
+ * Using Sequel with the the CRuby master branch (what will be Ruby 3)
18
+ now works by supporting a second argument for
19
+ Dataset#initialize_clone.
20
+
21
+ * Sequel now avoids a warning in verbose mode when using the postgres
22
+ adapter, a recent version of ruby-pg, and bound variables.
@@ -70,6 +70,10 @@ module Sequel
70
70
  # string names of the server side prepared statement, and values
71
71
  # are SQL strings.
72
72
  attr_reader :prepared_statements
73
+
74
+ unless public_method_defined?(:async_exec_params)
75
+ alias async_exec_params async_exec
76
+ end
73
77
  else
74
78
  # Make postgres-pr look like pg
75
79
  CONNECTION_OK = -1
@@ -149,7 +153,7 @@ module Sequel
149
153
 
150
154
  # Return the PGResult containing the query results.
151
155
  def execute_query(sql, args)
152
- @db.log_connection_yield(sql, self, args){args ? async_exec(sql, args) : async_exec(sql)}
156
+ @db.log_connection_yield(sql, self, args){args ? async_exec_params(sql, args) : async_exec(sql)}
153
157
  end
154
158
  end
155
159
 
@@ -691,7 +691,7 @@ module Sequel
691
691
  end
692
692
 
693
693
  # Return the results of an EXPLAIN query as a string. Options:
694
- # :extended :: Use EXPLAIN EXPTENDED instead of EXPLAIN if true.
694
+ # :extended :: Use EXPLAIN EXTENDED instead of EXPLAIN if true.
695
695
  def explain(opts=OPTS)
696
696
  # Load the PrettyTable class, needed for explain output
697
697
  Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
@@ -145,7 +145,7 @@ module Sequel
145
145
 
146
146
  # Return true if the :conn argument is present and not active.
147
147
  def disconnect_error?(e, opts)
148
- super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/.match(e.message)))
148
+ super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out|DBPROCESS is dead or not enabled)/.match(e.message)))
149
149
  end
150
150
 
151
151
  # Dispose of any possible results of execution.
@@ -126,7 +126,7 @@ module Sequel
126
126
  # :on_update :: Specify the behavior of this column when being updated
127
127
  # (:restrict, :cascade, :set_null, :set_default, :no_action).
128
128
  # :primary_key :: Make the column as a single primary key column. This should not
129
- # be used if you have a single, nonautoincrementing primary key column
129
+ # be used if you want a single autoincrementing primary key column
130
130
  # (use the primary_key method in that case).
131
131
  # :primary_key_constraint_name :: The name to give the primary key constraint
132
132
  # :primary_key_deferrable :: Similar to :deferrable, but for the primary key constraint
@@ -439,13 +439,12 @@ module Sequel
439
439
 
440
440
  # Remove the current thread from the list of active transactions
441
441
  def remove_transaction(conn, committed)
442
+ callbacks = transaction_hooks(conn, committed)
442
443
  if in_savepoint?(conn)
443
444
  savepoint_callbacks = savepoint_hooks(conn, committed)
444
445
  if committed
445
446
  savepoint_rollback_callbacks = savepoint_hooks(conn, false)
446
447
  end
447
- else
448
- callbacks = transaction_hooks(conn, committed)
449
448
  end
450
449
 
451
450
  if transaction_finished?(conn)
@@ -453,7 +452,6 @@ module Sequel
453
452
  rolled_back = !committed
454
453
  Sequel.synchronize{h[:rolled_back] = rolled_back}
455
454
  Sequel.synchronize{@transactions.delete(conn)}
456
- callbacks.each(&:call) if callbacks
457
455
  elsif savepoint_callbacks || savepoint_rollback_callbacks
458
456
  if committed
459
457
  meth = in_savepoint?(conn) ? :add_savepoint_hook : :add_transaction_hook
@@ -473,6 +471,8 @@ module Sequel
473
471
  savepoint_callbacks.each(&:call)
474
472
  end
475
473
  end
474
+
475
+ callbacks.each(&:call) if callbacks
476
476
  end
477
477
 
478
478
  # SQL to rollback to a savepoint
@@ -329,7 +329,7 @@ module Sequel
329
329
  end
330
330
 
331
331
  # Set the db, opts, and cache for the copy of the dataset.
332
- def initialize_copy(c)
332
+ def initialize_clone(c, _=nil)
333
333
  @db = c.db
334
334
  @opts = Hash[c.opts]
335
335
  if cols = c.cache_get(:_columns)
@@ -338,7 +338,7 @@ module Sequel
338
338
  @cache = {}
339
339
  end
340
340
  end
341
- alias initialize_clone initialize_copy
341
+ alias initialize_copy initialize_clone
342
342
 
343
343
  # Internal recursive version of unqualified_column_for, handling Strings inside
344
344
  # of other objects.
@@ -0,0 +1,38 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The empty_failure_backtraces plugin uses empty backtraces when raising HookFailed and ValidationFailed
6
+ # exceptions. This can be significantly faster, and if you are using these exceptions for
7
+ # flow control, you do not need the backtraces. This plugin is about 10% faster on CRuby
8
+ # and 10-15x faster on JRuby 9.2.7.0+. This does not have an effect on JRuby <9.2.7.0.
9
+ #
10
+ # Usage:
11
+ #
12
+ # # Make all model subclass instances use empty backtraces for HookFailed
13
+ # # and ValidationFailed exceptions (called before loading subclasses)
14
+ # Sequel::Model.plugin :empty_failure_backtraces
15
+ #
16
+ # # Make the Album class use empty backtraces for HookFailed and ValidationFailed exceptions
17
+ # Album.plugin :empty_failure_backtraces
18
+ module EmptyFailureBacktraces
19
+ module InstanceMethods
20
+ private
21
+
22
+ # Use empty backtrace for HookFailed exceptions.
23
+ def hook_failed_error(msg)
24
+ e = super
25
+ e.set_backtrace([])
26
+ e
27
+ end
28
+
29
+ # Use empty backtrace for ValidationFailed exceptions.
30
+ def validation_failed_error
31
+ e = super
32
+ e.set_backtrace([])
33
+ e
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -369,6 +369,13 @@ module Sequel
369
369
  end
370
370
 
371
371
  module DatasetMethods
372
+ # Store default options used when calling to_json on this dataset.
373
+ # These options take precedence over the class level options,
374
+ # and can be overridden by passing options directly to to_json.
375
+ def json_serializer_opts(opts=OPTS)
376
+ clone(:json_serializer_opts=>opts)
377
+ end
378
+
372
379
  # Return a JSON string representing an array of all objects in
373
380
  # this dataset. Takes the same options as the instance
374
381
  # method, and passes them to every instance. Additionally,
@@ -386,11 +393,15 @@ module Sequel
386
393
  # object. If set to a string, wraps the collection in
387
394
  # a root object using the string as the key.
388
395
  def to_json(*a)
389
- if opts = a.first.is_a?(Hash)
390
- opts = model.json_serializer_opts.merge(a.first)
396
+ opts = model.json_serializer_opts
397
+
398
+ if ds_opts = @opts[:json_serializer_opts]
399
+ opts = opts.merge(ds_opts)
400
+ end
401
+
402
+ if (arg = a.first).is_a?(Hash)
403
+ opts = opts.merge(arg)
391
404
  a = []
392
- else
393
- opts = model.json_serializer_opts
394
405
  end
395
406
 
396
407
  case collection_root = opts[:root]
@@ -48,7 +48,7 @@ module Sequel
48
48
  # nil if there were any.
49
49
  def catch_hook_failures
50
50
  called = ret = nil
51
- caught = catch(HookFailed) do
51
+ catch(HookFailed) do
52
52
  ret = yield
53
53
  called = true
54
54
  end
@@ -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 = 28
9
+ MINOR = 29
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
@@ -3065,7 +3065,6 @@ describe "Dataset#get" do
3065
3065
  end
3066
3066
 
3067
3067
  it "should select the specified column and fetch its value" do
3068
- @d
3069
3068
  5.times do
3070
3069
  @d.get(:name).must_equal "SELECT name FROM test LIMIT 1"
3071
3070
  @d.get(:abc).must_equal "SELECT abc FROM test LIMIT 1"
@@ -3077,14 +3076,12 @@ describe "Dataset#get" do
3077
3076
  end
3078
3077
 
3079
3078
  it "should work with aliased fields" do
3080
- @d
3081
3079
  5.times do
3082
3080
  @d.get(Sequel.expr(Sequel[:x][:b]).as(:name)).must_equal "SELECT x.b AS name FROM test LIMIT 1"
3083
3081
  end
3084
3082
  end
3085
3083
 
3086
3084
  it "should work with plain strings" do
3087
- @d
3088
3085
  5.times do
3089
3086
  @d.get('a').must_equal "SELECT 'a' AS v FROM test LIMIT 1"
3090
3087
  end
@@ -42,7 +42,7 @@ describe "caller_logging extension" do
42
42
 
43
43
  it "should not log caller information if all callers lines are filtered" do
44
44
  @db.caller_logging_ignore = /./
45
- exec_sql("SELECT * FROM items"); line = __LINE__
45
+ exec_sql("SELECT * FROM items")
46
46
  @log_stream.rewind
47
47
  lines = @log_stream.read.split("\n")
48
48
  lines.length.must_equal 1
@@ -0,0 +1,60 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe "empty_failure_backtraces plugin" do
4
+ before do
5
+ @c = Class.new(Sequel::Model(:items)) do
6
+ plugin :empty_failure_backtraces
7
+ columns :x
8
+ set_primary_key :x
9
+ unrestrict_primary_key
10
+ def before_create
11
+ super
12
+ cancel_action 'bc' if x == 2
13
+ end
14
+ def before_destroy
15
+ super
16
+ cancel_action 'bd' if x == 2
17
+ end
18
+ def validate
19
+ super
20
+ errors.add(:x, "3") if x == 3
21
+ end
22
+ end
23
+ DB.reset
24
+ end
25
+
26
+ it "should work normally if no exceptions are thrown/raised" do
27
+ o = @c.create(:x=>1)
28
+ o.must_be_kind_of @c
29
+ o.valid?.must_equal true
30
+ o.destroy.must_equal o
31
+ end
32
+
33
+ it "should work normally when not rescuing exceptions internally when calling save" do
34
+ @c.new.set(:x => 2).save(:raise_on_failure=>false).must_be_nil
35
+ @c.raise_on_save_failure = false
36
+ @c.create(:x => 2).must_be_nil
37
+ @c.load(:x => 2).destroy(:raise_on_failure=>false).must_be_nil
38
+ end
39
+
40
+ it "should work normally when not rescuing exceptions internally when calling valid?" do
41
+ @c.send(:define_method, :before_validation){cancel_action "bv"}
42
+ @c.new(:x => 2).valid?.must_equal false
43
+ end
44
+
45
+ it "should raise exceptions with empty backtraces" do
46
+ begin
47
+ @c.create(:x => 2)
48
+ rescue Sequel::HookFailed => e
49
+ e.backtrace.must_be_empty
50
+ 1
51
+ end.must_equal 1
52
+
53
+ begin
54
+ @c.create(:x => 3)
55
+ rescue Sequel::ValidationFailed => e
56
+ e.backtrace.must_be_empty
57
+ 1
58
+ end.must_equal 1
59
+ end
60
+ end
@@ -187,6 +187,16 @@ describe "Sequel::Plugins::JsonSerializer" do
187
187
  Album.array_from_json(Album.dataset.to_json(:only=>:name)).must_equal [Album.load(:name=>@album.name)]
188
188
  end
189
189
 
190
+ it "should support setting json_serializer_opts for datasets" do
191
+ Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
192
+ Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json).must_equal [Album.load(:name=>@album.name)]
193
+ Album.plugin :json_serializer, :only=>:id
194
+ Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json).must_equal [Album.load(:name=>@album.name)]
195
+ Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json(:only=>:artist_id)).must_equal [Album.load(:artist_id=>2)]
196
+ json = Album.dataset.json_serializer_opts(:only=>:name, :root=>true).to_json(:only=>:artist_id)
197
+ Album.array_from_json(JSON.parse(json)['albums'].to_json).must_equal [Album.load(:artist_id=>2)]
198
+ end
199
+
190
200
  it "should have dataset to_json method work with eager_graph datasets" do
191
201
  ds = Album.dataset.eager_graph(:artist).with_fetch(:id=>1, :name=>'RF', :artist_id=>2, :artist_id_0=>2, :artist_name=>'YM')
192
202
  Sequel.parse_json(ds.to_json(:only=>:name, :include=>{:artist=>{:only=>:name}})).must_equal [{"name"=>"RF", "artist"=>{"name"=>"YM"}}]
@@ -158,12 +158,12 @@ describe "Sequel named_timezones extension with Time class" do
158
158
  dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30-0400')
159
159
  dt.must_be_instance_of Time
160
160
  dt.must_equal Time.new(2009,6,1,3,20,30,-25200)
161
- dt.utc_offset.must_equal -25200
161
+ dt.utc_offset.must_equal(-25200)
162
162
 
163
163
  dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30+0000')
164
164
  dt.must_be_instance_of Time
165
165
  dt.must_equal Time.new(2009,6,1,3,20,30,-25200)
166
- dt.utc_offset.must_equal -25200
166
+ dt.utc_offset.must_equal(-25200)
167
167
  end
168
168
 
169
169
  it "should raise an error for ambiguous timezones by default" do
@@ -175,19 +175,19 @@ describe "Sequel named_timezones extension with Time class" do
175
175
  Sequel.database_to_application_timestamp('2004-10-31T01:30:00').must_equal Time.new(2004, 10, 30, 22, 30, 0, -25200)
176
176
  dt = Sequel.database_to_application_timestamp('2004-10-31T01:30:00')
177
177
  dt.must_equal Time.new(2004, 10, 30, 22, 30, 0, -25200)
178
- dt.utc_offset.must_equal -25200
178
+ dt.utc_offset.must_equal(-25200)
179
179
  end
180
180
 
181
181
  it "should assume datetimes coming out of the database that don't have an offset as coming from database_timezone" do
182
182
  dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30')
183
183
  dt.must_be_instance_of Time
184
184
  dt.must_equal Time.new(2009,6,1,3,20,30, -25200)
185
- dt.utc_offset.must_equal -25200
185
+ dt.utc_offset.must_equal(-25200)
186
186
 
187
187
  dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30')
188
188
  dt.must_be_instance_of Time
189
189
  dt.must_equal Time.new(2009,6,1,7,20,30, -25200)
190
- dt.utc_offset.must_equal -25200
190
+ dt.utc_offset.must_equal(-25200)
191
191
  end
192
192
 
193
193
  it "should work with the thread_local_timezones extension" do
@@ -2131,7 +2131,7 @@ describe "Sequel::Model Simple Associations" do
2131
2131
  a.must_equal [@album, album2]
2132
2132
  a.map(&:artist).must_equal [@artist, @artist]
2133
2133
  a.map(&:artist).map(&:albums).must_equal [[@album, album2], [@album, album2]]
2134
- a.map(&:artist).map{|a| a.associations[:tags]}.must_equal [[], []]
2134
+ a.map(&:artist).map{|artist| artist.associations[:tags]}.must_equal [[], []]
2135
2135
  end
2136
2136
 
2137
2137
  it "should have remove method raise an error for one_to_many records if the object isn't already associated" do
@@ -326,12 +326,12 @@ describe "Sequel::Plugins.def_sequel_method" do
326
326
  it "should define methods using block" do
327
327
  m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0){1}
328
328
  m0.must_be_kind_of Symbol
329
- m0.must_match /\A_sequel_x_\d+\z/
329
+ m0.must_match(/\A_sequel_x_\d+\z/)
330
330
  @scope.send(m0).must_equal 1
331
331
 
332
332
  m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|x| [x, 2]}
333
333
  m1.must_be_kind_of Symbol
334
- m1.must_match /\A_sequel_x_\d+\z/
334
+ m1.must_match(/\A_sequel_x_\d+\z/)
335
335
  @scope.send(m1, 3).must_equal [3, 2]
336
336
  end
337
337
 
@@ -1,4 +1,5 @@
1
1
  if ENV['WARNING']
2
2
  require 'warning'
3
3
  Warning.ignore([:missing_ivar, :method_redefined, :not_reached], File.dirname(File.dirname(__FILE__)))
4
+ Warning.dedup if Warning.respond_to?(:dedup)
4
5
  end
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.28.0
4
+ version: 5.29.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: 2020-01-01 00:00:00.000000000 Z
11
+ date: 2020-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -226,6 +226,7 @@ extra_rdoc_files:
226
226
  - doc/release_notes/5.26.0.txt
227
227
  - doc/release_notes/5.27.0.txt
228
228
  - doc/release_notes/5.28.0.txt
229
+ - doc/release_notes/5.29.0.txt
229
230
  files:
230
231
  - CHANGELOG
231
232
  - MIT-LICENSE
@@ -325,6 +326,7 @@ files:
325
326
  - doc/release_notes/5.26.0.txt
326
327
  - doc/release_notes/5.27.0.txt
327
328
  - doc/release_notes/5.28.0.txt
329
+ - doc/release_notes/5.29.0.txt
328
330
  - doc/release_notes/5.3.0.txt
329
331
  - doc/release_notes/5.4.0.txt
330
332
  - doc/release_notes/5.5.0.txt
@@ -537,6 +539,7 @@ files:
537
539
  - lib/sequel/plugins/dirty.rb
538
540
  - lib/sequel/plugins/eager_each.rb
539
541
  - lib/sequel/plugins/eager_graph_eager.rb
542
+ - lib/sequel/plugins/empty_failure_backtraces.rb
540
543
  - lib/sequel/plugins/error_splitter.rb
541
544
  - lib/sequel/plugins/finder.rb
542
545
  - lib/sequel/plugins/force_encoding.rb
@@ -663,6 +666,7 @@ files:
663
666
  - spec/extensions/eager_each_spec.rb
664
667
  - spec/extensions/eager_graph_eager_spec.rb
665
668
  - spec/extensions/empty_array_consider_nulls_spec.rb
669
+ - spec/extensions/empty_failure_backtraces_spec.rb
666
670
  - spec/extensions/error_splitter_spec.rb
667
671
  - spec/extensions/error_sql_spec.rb
668
672
  - spec/extensions/escaped_like_spec.rb