sequel 5.40.0 → 5.41.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: b3391bf9fe9e592892ad8ba6b39f7016fe94524908243e7c85fdf5b1cbf9a62a
4
- data.tar.gz: 3b3c946fefa8c16b8f657c191debf49f8db84cb9cadb5a91ecdb01739c2ec1e9
3
+ metadata.gz: b0886ae2f4e4f4490b56ced6137e2d849cac2458119d6e67d9a756328336ece6
4
+ data.tar.gz: 9c4946c8ca82b2b1c99ee9065bef0aa81175128564cd7ab0c0405bd4e682b339
5
5
  SHA512:
6
- metadata.gz: 1e7812b8851cdcc9e374bcd8439cc4e3dbbedfd550c72b54aa9d6aa16e3bad1e5f59eed824bdef026d784b67450d2f861be8776ddb762be58406cca75f7a0ea9
7
- data.tar.gz: a60bcc72355a1916a0639c5a99ec806f157d60b515112ec24c1757f9a43efc587593a0b11a1e5312d3f40431b313f8f6fc241eee7e7a37c5362565db7c4c8d3c
6
+ metadata.gz: aa61ea3a0cb3d0e3ab021d27589e10250ed9d9d5a0b4bf314729d55661624161cabffe9c87278761890a900949756e185ce1f263bf742d9b317f2621a1f75c09
7
+ data.tar.gz: a8253ea1f6e77b592eb40de7b2544b7b34ff8cd02a79e4dfe5bb26b796dd80d49f052e307590af71fb67b292bc9b9c1def8f400eea0977fdb0d85928a6e9f181
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ === 5.41.0 (2021-02-01)
2
+
3
+ * Have explicit :text option for a String column take priority over :size option on PostgreSQL (jeremyevans) (#1750)
4
+
5
+ * Support a :skip_invalid option in auto_validations plugin for not adding errors to a column that already has an error (jeremyevans)
6
+
7
+ * Support a :skip_invalid option in validation_helpers for not adding an error to a column that already has an error (jeremyevans)
8
+
9
+ * Support :adder, :remover, and :clearer association options that use keyword arguments in Ruby 2.7+ (jeremyevans)
10
+
11
+ * Make pg_interval use the same number of seconds per year and per month as ActiveSupport::Duration when using ActiveSupport 5.1+ (jeremyevans)
12
+
1
13
  === 5.40.0 (2021-01-01)
2
14
 
3
15
  * Support UPDATE FROM syntax in SQLite 3.33.0+ (jeremyevans)
data/MIT-LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2007-2008 Sharon Rosner
2
- Copyright (c) 2008-2020 Jeremy Evans
2
+ Copyright (c) 2008-2021 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,25 @@
1
+ = New Features
2
+
3
+ * The validation methods added by the validation_helpers plugin now
4
+ support the :skip_invalid option, which will not add a validation
5
+ error on a column if it already has a validation error. This can
6
+ be useful if you want to avoid having duplicate errors.
7
+
8
+ * The auto_validations plugin now supports a :skip_invalid plugin
9
+ option, which will pass the :skip_invalid option when calling
10
+ validation methods.
11
+
12
+ = Other Improvements
13
+
14
+ * The :adder, :remover, and :clearer association options now
15
+ support keyword arguments in Ruby 2.7+.
16
+
17
+ * In the pg_interval extension, Sequel now uses the same number of
18
+ seconds per month and seconds per year as active_support. It
19
+ originally used the same number, but active_support changed the
20
+ values in active_support 5.1. Sequel now uses the active_support
21
+ values if they are available.
22
+
23
+ * When adding a String column on PostgreSQL, an explicit text: true
24
+ option now takes precedence over an explicit :size option, as it
25
+ does in Sequel's default behavior.
data/doc/sql.rdoc CHANGED
@@ -544,7 +544,7 @@ On some databases, you can specify null ordering:
544
544
 
545
545
  === All Columns (.*)
546
546
 
547
- To select all columns in a table, Sequel supports the * method on identifiers and qualified without an argument:
547
+ To select all columns in a table, Sequel supports the * method on identifiers and qualified identifiers without an argument:
548
548
 
549
549
  Sequel[:table].* # "table".*
550
550
  Sequel[:schema][:table].* # "schema"."table".*
@@ -1500,9 +1500,11 @@ module Sequel
1500
1500
  # disallowed or there is a size specified, use the varchar type.
1501
1501
  # Otherwise use the text type.
1502
1502
  def type_literal_generic_string(column)
1503
- if column[:fixed]
1503
+ if column[:text]
1504
+ :text
1505
+ elsif column[:fixed]
1504
1506
  "char(#{column[:size]||255})"
1505
- elsif column[:text] == false or column[:size]
1507
+ elsif column[:text] == false || column[:size]
1506
1508
  "varchar(#{column[:size]||255})"
1507
1509
  else
1508
1510
  :text
@@ -7,9 +7,11 @@
7
7
  # Sequel.extension :blank
8
8
 
9
9
  [FalseClass, Object, NilClass, Numeric, String, TrueClass].each do |klass|
10
+ # :nocov:
10
11
  if klass.method_defined?(:blank?)
11
12
  klass.send(:alias_method, :blank?, :blank?)
12
13
  end
14
+ # :nocov:
13
15
  end
14
16
 
15
17
  class FalseClass
@@ -52,14 +52,10 @@ module Sequel
52
52
  if defined?(ActiveSupport::Duration) && interval.is_a?(ActiveSupport::Duration)
53
53
  interval = interval.parts
54
54
  end
55
- interval = if interval.is_a?(Enumerable)
56
- h = {}
57
- interval.each{|k,v| h[k] = -v unless v.nil?}
58
- h
59
- else
60
- -interval
61
- end
62
- DateAdd.new(expr, interval, opts)
55
+ parts = {}
56
+ interval.each{|k,v| parts[k] = -v unless v.nil?}
57
+ parts
58
+ DateAdd.new(expr, parts, opts)
63
59
  end
64
60
  end
65
61
 
@@ -107,9 +107,11 @@ class String
107
107
  end
108
108
 
109
109
  %w'classify constantize dasherize demodulize foreign_key humanize pluralize singularize tableize underscore'.each do |m|
110
+ # :nocov:
110
111
  if method_defined?(m)
111
112
  alias_method(m, m)
112
113
  end
114
+ # :nocov:
113
115
  end
114
116
 
115
117
  # By default, camelize converts the string to UpperCamelCase. If the argument to camelize
@@ -84,9 +84,9 @@ module Sequel
84
84
  def convert_output_time_other(v, output_timezone)
85
85
  Time.at(v.to_i, :in => output_timezone)
86
86
  end
87
- else
88
87
  # :nodoc:
89
88
  # :nocov:
89
+ else
90
90
  def convert_input_time_other(v, input_timezone)
91
91
  local_offset = input_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset
92
92
  Time.new(1970, 1, 1, 0, 0, 0, local_offset) + v.to_i
@@ -105,6 +105,8 @@ module Sequel
105
105
  Time.new(1970, 1, 1, 0, 0, 0, local_offset) + v.to_i
106
106
  end
107
107
  end
108
+ # :nodoc:
109
+ # :nocov:
108
110
  end
109
111
 
110
112
  # Handle both TZInfo 1 and TZInfo 2
@@ -142,6 +144,8 @@ module Sequel
142
144
  # Convert timezone offset from UTC to the offset for the output_timezone
143
145
  (v - local_offset).new_offset(local_offset)
144
146
  end
147
+ # :nodoc:
148
+ # :nocov:
145
149
  end
146
150
 
147
151
  # Returns TZInfo::Timezone instance if given a String.
@@ -71,6 +71,16 @@ module Sequel
71
71
  # Whether ActiveSupport::Duration.new takes parts as array instead of hash
72
72
  USE_PARTS_ARRAY = !defined?(ActiveSupport::VERSION::STRING) || ActiveSupport::VERSION::STRING < '5.1'
73
73
 
74
+ if defined?(ActiveSupport::Duration::SECONDS_PER_MONTH)
75
+ SECONDS_PER_MONTH = ActiveSupport::Duration::SECONDS_PER_MONTH
76
+ SECONDS_PER_YEAR = ActiveSupport::Duration::SECONDS_PER_YEAR
77
+ # :nocov:
78
+ else
79
+ SECONDS_PER_MONTH = 2592000
80
+ SECONDS_PER_YEAR = 31557600
81
+ # :nocov:
82
+ end
83
+
74
84
  # Parse the interval input string into an ActiveSupport::Duration instance.
75
85
  def call(string)
76
86
  raise(InvalidValue, "invalid or unhandled interval format: #{string.inspect}") unless matches = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/.match(string)
@@ -80,12 +90,12 @@ module Sequel
80
90
 
81
91
  if v = matches[1]
82
92
  v = v.to_i
83
- value += 31557600 * v
93
+ value += SECONDS_PER_YEAR * v
84
94
  parts[:years] = v
85
95
  end
86
96
  if v = matches[2]
87
97
  v = v.to_i
88
- value += 2592000 * v
98
+ value += SECONDS_PER_MONTH * v
89
99
  parts[:months] = v
90
100
  end
91
101
  if v = matches[3]
@@ -1929,8 +1929,22 @@ module Sequel
1929
1929
  # can be easily overridden in the class itself while allowing for
1930
1930
  # super to be called.
1931
1931
  def association_module_def(name, opts=OPTS, &block)
1932
- association_module(opts).send(:define_method, name, &block)
1933
- association_module(opts).send(:alias_method, name, name)
1932
+ mod = association_module(opts)
1933
+ mod.send(:define_method, name, &block)
1934
+ mod.send(:alias_method, name, name)
1935
+ end
1936
+
1937
+ # Add a method to the module included in the class, so the method
1938
+ # can be easily overridden in the class itself while allowing for
1939
+ # super to be called. This method allows passing keywords through
1940
+ # the defined methods.
1941
+ def association_module_delegate_def(name, opts, &block)
1942
+ mod = association_module(opts)
1943
+ mod.send(:define_method, name, &block)
1944
+ # :nocov:
1945
+ mod.send(:ruby2_keywords, name) if mod.respond_to?(:ruby2_keywords, true)
1946
+ # :nocov:
1947
+ mod.send(:alias_method, name, name)
1934
1948
  end
1935
1949
 
1936
1950
  # Add a private method to the module included in the class.
@@ -1982,17 +1996,17 @@ module Sequel
1982
1996
 
1983
1997
  if adder = opts[:adder]
1984
1998
  association_module_private_def(opts[:_add_method], opts, &adder)
1985
- association_module_def(opts[:add_method], opts){|o,*args| add_associated_object(opts, o, *args)}
1999
+ association_module_delegate_def(opts[:add_method], opts){|o,*args| add_associated_object(opts, o, *args)}
1986
2000
  end
1987
2001
 
1988
2002
  if remover = opts[:remover]
1989
2003
  association_module_private_def(opts[:_remove_method], opts, &remover)
1990
- association_module_def(opts[:remove_method], opts){|o,*args| remove_associated_object(opts, o, *args)}
2004
+ association_module_delegate_def(opts[:remove_method], opts){|o,*args| remove_associated_object(opts, o, *args)}
1991
2005
  end
1992
2006
 
1993
2007
  if clearer = opts[:clearer]
1994
2008
  association_module_private_def(opts[:_remove_all_method], opts, &clearer)
1995
- association_module_def(opts[:remove_all_method], opts){|*args| remove_all_associated_objects(opts, *args)}
2009
+ association_module_delegate_def(opts[:remove_all_method], opts){|*args| remove_all_associated_objects(opts, *args)}
1996
2010
  end
1997
2011
  end
1998
2012
 
@@ -2424,6 +2438,9 @@ module Sequel
2424
2438
  run_association_callbacks(opts, :after_add, o)
2425
2439
  o
2426
2440
  end
2441
+ # :nocov:
2442
+ ruby2_keywords(:add_associated_object) if respond_to?(:ruby2_keywords, true)
2443
+ # :nocov:
2427
2444
 
2428
2445
  # Add/Set the current object to/as the given object's reciprocal association.
2429
2446
  def add_reciprocal_object(opts, o)
@@ -2566,6 +2583,9 @@ module Sequel
2566
2583
  associations[opts[:name]] = []
2567
2584
  ret
2568
2585
  end
2586
+ # :nocov:
2587
+ ruby2_keywords(:remove_all_associated_objects) if respond_to?(:ruby2_keywords, true)
2588
+ # :nocov:
2569
2589
 
2570
2590
  # Remove the given associated object from the given association
2571
2591
  def remove_associated_object(opts, o, *args)
@@ -2587,6 +2607,9 @@ module Sequel
2587
2607
  run_association_callbacks(opts, :after_remove, o)
2588
2608
  o
2589
2609
  end
2610
+ # :nocov:
2611
+ ruby2_keywords(:remove_associated_object) if respond_to?(:ruby2_keywords, true)
2612
+ # :nocov:
2590
2613
 
2591
2614
  # Check that the object from the associated table specified by the primary key
2592
2615
  # is currently associated to the receiver. If it is associated, return the object, otherwise
@@ -14,7 +14,9 @@ module Sequel
14
14
  # the plugin looks at the database schema for the model's table. To determine
15
15
  # the unique validations, Sequel looks at the indexes on the table. In order
16
16
  # for this plugin to be fully functional, the underlying database adapter needs
17
- # to support both schema and index parsing.
17
+ # to support both schema and index parsing. Additionally, unique validations are
18
+ # only added for models that select from a simple table, they are not added for models
19
+ # that select from a subquery or joined dataset.
18
20
  #
19
21
  # This plugin uses the validation_helpers plugin underneath to implement the
20
22
  # validations. It does not allow for any per-column validation message
@@ -51,6 +53,11 @@ module Sequel
51
53
  # This works for unique_opts, max_length_opts, schema_types_opts,
52
54
  # explicit_not_null_opts, and not_null_opts.
53
55
  #
56
+ # If you only want auto_validations to add validations to columns that do not already
57
+ # have an error associated with them, you can use the skip_invalid option:
58
+ #
59
+ # Model.plugin :auto_validations, skip_invalid: true
60
+ #
54
61
  # Usage:
55
62
  #
56
63
  # # Make all model subclass use auto validations (called before loading subclasses)
@@ -100,6 +107,13 @@ module Sequel
100
107
  h[type] = h[type].merge(type_opts).freeze
101
108
  end
102
109
  end
110
+
111
+ if opts[:skip_invalid]
112
+ [:not_null, :explicit_not_null, :max_length, :schema_types].each do |type|
113
+ h[type] = h[type].merge(:skip_invalid=>true).freeze
114
+ end
115
+ end
116
+
103
117
  @auto_validate_options = h.freeze
104
118
  end
105
119
  end
@@ -36,6 +36,7 @@ module Sequel
36
36
  # :message :: The message to use. Can be a string which is used directly, or a
37
37
  # proc which is called. If the validation method takes a argument before the array of attributes,
38
38
  # that argument is passed as an argument to the proc.
39
+ # :skip_invalid :: Do not try to validate columns that are already invalid.
39
40
  #
40
41
  # The default validation options for all models can be modified by
41
42
  # overridding the Model#default_validation_helpers_options private method.
@@ -281,14 +282,17 @@ module Sequel
281
282
  DEFAULT_OPTIONS[type]
282
283
  end
283
284
 
284
- # Skip validating any attribute that matches one of the allow_* options.
285
+ # Skip validating any attribute that matches one of the allow_* options,
286
+ # or already has an error if the skip_invalid option is given.
287
+ #
285
288
  # Otherwise, yield the attribute, value, and passed option :message to
286
289
  # the block. If the block returns anything except nil or false, add it as
287
290
  # an error message for that attributes.
288
291
  def validatable_attributes(atts, opts)
289
- am, an, ab, m = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message)
292
+ am, an, ab, m, si = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message, :skip_invalid)
290
293
  from_values = opts[:from] == :values
291
294
  Array(atts).each do |a|
295
+ next if si && errors.on(a)
292
296
  next if am && !values.has_key?(a)
293
297
  v = from_values ? values[a] : get_column_value(a)
294
298
  next if an && v.nil?
@@ -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 = 40
9
+ MINOR = 41
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.40.0
4
+ version: 5.41.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: 2021-01-01 00:00:00.000000000 Z
11
+ date: 2021-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -184,6 +184,7 @@ extra_rdoc_files:
184
184
  - doc/release_notes/5.39.0.txt
185
185
  - doc/release_notes/5.4.0.txt
186
186
  - doc/release_notes/5.40.0.txt
187
+ - doc/release_notes/5.41.0.txt
187
188
  - doc/release_notes/5.5.0.txt
188
189
  - doc/release_notes/5.6.0.txt
189
190
  - doc/release_notes/5.7.0.txt
@@ -252,6 +253,7 @@ files:
252
253
  - doc/release_notes/5.39.0.txt
253
254
  - doc/release_notes/5.4.0.txt
254
255
  - doc/release_notes/5.40.0.txt
256
+ - doc/release_notes/5.41.0.txt
255
257
  - doc/release_notes/5.5.0.txt
256
258
  - doc/release_notes/5.6.0.txt
257
259
  - doc/release_notes/5.7.0.txt