sequel 5.28.0 → 5.29.0

Sign up to get free protection for your applications and to get access to all the features.
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