sequel 5.86.0 → 5.87.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: 2945ab081dad1d3dc6d910e2902247b18750215023e0cfbb5b8f8159811b0d25
4
- data.tar.gz: 6b2933b4ac2023a71526a76f40b949e873460e2a7f8aed1524bef47b71f91e79
3
+ metadata.gz: 8be61078e55201001f1041d09be334411bfaef071e6dbeb3c9082c21b0e70dce
4
+ data.tar.gz: c877f3832d2ef28b14d7037e6bbf7bbe90d2d6f6391736bc3b9e6bdc142b5ba5
5
5
  SHA512:
6
- metadata.gz: 988bfe69b6b4953a7792431e3dd26bcb7ad13f01b8b1dc822fd9d79917608cc2f60bdb7e9a75cfa975bcd297ada83f00a2d80343424f9e4096c029437a9250ad
7
- data.tar.gz: 51c2591400946af23395f0a3f49dfc87d4ce6f536e9cbc045ae7c86915007938c72b90f899dd347d749918218b86edc8dbaa63e8f9430d7075872a431d91b777
6
+ metadata.gz: 7b032d7f8987e0727cc79b98f7f6d5319cd1dc13657c3a2ebc16bff4276d26eb368f1a498d51e27df0aea89184d0b811f6a05355cf3f7a400b45cd8707061f63
7
+ data.tar.gz: f2a1326e3635a7840e220b368459407409391507a3e87cb85ac01f4360d5762a9bdf15ee350032875f9c6d202f03b868fd6c7af43e72bf80cca007edd34cc14e
@@ -567,7 +567,7 @@ module Sequel
567
567
  im = input_identifier_meth(opts[:dataset])
568
568
  table = SQL::Identifier.new(im.call(table_name))
569
569
  table = SQL::QualifiedIdentifier.new(im.call(opts[:schema]), table) if opts[:schema]
570
- metadata_dataset.with_sql("DESCRIBE ?", table).map do |row|
570
+ metadata_dataset.with_sql("SHOW FULL COLUMNS FROM ?", table).map do |row|
571
571
  extra = row.delete(:Extra)
572
572
  if row[:primary_key] = row.delete(:Key) == 'PRI'
573
573
  row[:auto_increment] = !!(extra.to_s =~ /auto_increment/i)
@@ -577,10 +577,14 @@ module Sequel
577
577
  row[:generated] = !!(extra.to_s =~ /VIRTUAL|STORED|PERSISTENT/i)
578
578
  end
579
579
  row[:allow_null] = row.delete(:Null) == 'YES'
580
+ row[:comment] = row.delete(:Comment)
581
+ row[:comment] = nil if row[:comment] == ""
580
582
  row[:default] = row.delete(:Default)
581
583
  row[:db_type] = row.delete(:Type)
582
584
  row[:type] = schema_column_type(row[:db_type])
583
585
  row[:extra] = extra
586
+ row.delete(:Collation)
587
+ row.delete(:Privileges)
584
588
  [m.call(row.delete(:Field)), row]
585
589
  end
586
590
  end
@@ -1075,6 +1075,7 @@ module Sequel
1075
1075
  pg_attribute[:attname].as(:name),
1076
1076
  SQL::Cast.new(pg_attribute[:atttypid], :integer).as(:oid),
1077
1077
  SQL::Cast.new(basetype[:oid], :integer).as(:base_oid),
1078
+ SQL::Function.new(:col_description, pg_class[:oid], pg_attribute[:attnum]).as(:comment),
1078
1079
  SQL::Function.new(:format_type, basetype[:oid], pg_type[:typtypmod]).as(:db_base_type),
1079
1080
  SQL::Function.new(:format_type, pg_type[:oid], pg_attribute[:atttypmod]).as(:db_type),
1080
1081
  SQL::Function.new(:pg_get_expr, pg_attrdef[:adbin], pg_class[:oid]).as(:default),
@@ -62,8 +62,7 @@ module Sequel
62
62
  private
63
63
 
64
64
  def database_specific_error_class(exception, opts)
65
- case exception.message
66
- when /1205 - Lock wait timeout exceeded; try restarting transaction\z/
65
+ if exception.error_code == 1205
67
66
  DatabaseLockTimeout
68
67
  else
69
68
  super
@@ -246,9 +246,13 @@ module Sequel
246
246
  # extension does not have specific support for Database objects, an Error will be raised.
247
247
  # Returns self.
248
248
  def extension(*exts)
249
- Sequel.extension(*exts)
250
249
  exts.each do |ext|
251
- if pr = Sequel.synchronize{EXTENSIONS[ext]}
250
+ unless pr = Sequel.synchronize{EXTENSIONS[ext]}
251
+ Sequel.extension(ext)
252
+ pr = Sequel.synchronize{EXTENSIONS[ext]}
253
+ end
254
+
255
+ if pr
252
256
  if Sequel.synchronize{@loaded_extensions.include?(ext) ? false : (@loaded_extensions << ext)}
253
257
  pr.call(self)
254
258
  end
@@ -204,7 +204,7 @@ module Sequel
204
204
  # If no related extension file exists or the extension does not have
205
205
  # specific support for Dataset objects, an error will be raised.
206
206
  def extension(*exts)
207
- Sequel.extension(*exts)
207
+ exts.each{|ext| Sequel.extension(ext) unless Sequel.synchronize{EXTENSIONS[ext]}}
208
208
  mods = exts.map{|ext| Sequel.synchronize{EXTENSION_MODULES[ext]}}
209
209
  if mods.all?
210
210
  with_extend(*mods)
@@ -1359,9 +1359,13 @@ module Sequel
1359
1359
  unless TRUE_FREEZE
1360
1360
  # Load the extensions into the receiver, without checking if the receiver is frozen.
1361
1361
  def _extension!(exts)
1362
- Sequel.extension(*exts)
1363
1362
  exts.each do |ext|
1364
- if pr = Sequel.synchronize{EXTENSIONS[ext]}
1363
+ unless pr = Sequel.synchronize{EXTENSIONS[ext]}
1364
+ Sequel.extension(ext)
1365
+ pr = Sequel.synchronize{EXTENSIONS[ext]}
1366
+ end
1367
+
1368
+ if pr
1365
1369
  pr.call(self)
1366
1370
  else
1367
1371
  raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
@@ -394,7 +394,7 @@ module Sequel
394
394
  # there can be more than one parameter per column, so this doesn't prevent going
395
395
  # over the limit, though it does make it less likely.
396
396
  def default_import_slice
397
- 40
397
+ @opts[:no_auto_parameterize] ? super : 40
398
398
  end
399
399
 
400
400
  # Handle parameterization of multi_insert_sql
@@ -0,0 +1,90 @@
1
+ # frozen-string-literal: true
2
+ #
3
+ # The pg_schema_caching extension builds on top of the schema_caching
4
+ # extension, and allows it to handle custom PostgreSQL types. On
5
+ # PostgreSQL, column schema hashes include an :oid entry for the OID
6
+ # for the column's type. For custom types, this OID is dependent on
7
+ # the PostgreSQL database, so in most cases, test and development
8
+ # versions of the same database, created with the same migrations,
9
+ # will have different OIDs.
10
+ #
11
+ # To fix this case, the pg_schema_caching extension removes custom
12
+ # OIDs from the schema cache when dumping the schema, replacing them
13
+ # with a placeholder. When loading the cached schema, the Database
14
+ # object makes a single query to get the OIDs for all custom types
15
+ # used by the cached schema, and it updates all related column
16
+ # schema hashes to set the correct :oid entry for the current
17
+ # database.
18
+ #
19
+ # Related module: Sequel::Postgres::SchemaCaching
20
+
21
+ require_relative "schema_caching"
22
+
23
+ module Sequel
24
+ module Postgres
25
+ module SchemaCaching
26
+ include Sequel::SchemaCaching
27
+
28
+ private
29
+
30
+ # Load custom oids from database when loading schema cache file.
31
+ def load_schema_cache_file(file)
32
+ set_custom_oids_for_cached_schema(super)
33
+ end
34
+
35
+ # Find all column schema hashes that use custom types.
36
+ # Load the oids for custom types in a single query, and update
37
+ # each related column schema hash with the correct oid.
38
+ def set_custom_oids_for_cached_schema(schemas)
39
+ custom_oid_rows = {}
40
+
41
+ schemas.each_value do |cols|
42
+ cols.each do |_, h|
43
+ if h[:oid] == :custom
44
+ (custom_oid_rows[h[:db_type]] ||= []) << h
45
+ end
46
+ end
47
+ end
48
+
49
+ unless custom_oid_rows.empty?
50
+ from(:pg_type).where(:typname=>custom_oid_rows.keys).select_hash(:typname, :oid).each do |name, oid|
51
+ custom_oid_rows.delete(name).each do |row|
52
+ row[:oid] = oid
53
+ end
54
+ end
55
+ end
56
+
57
+ unless custom_oid_rows.empty?
58
+ warn "Could not load OIDs for the following custom types: #{custom_oid_rows.keys.sort.join(", ")}", uplevel: 3
59
+
60
+ schemas.keys.each do |k|
61
+ if schemas[k].any?{|_,h| h[:oid] == :custom}
62
+ # Remove schema entry for table, so it will be queried at runtime to get the correct oids
63
+ schemas.delete(k)
64
+ end
65
+ end
66
+ end
67
+
68
+ schemas
69
+ end
70
+
71
+ # Replace :oid entries for custom types with :custom.
72
+ def dumpable_schema_cache
73
+ sch = super
74
+
75
+ sch.each_value do |cols|
76
+ cols.each do |_, h|
77
+ if (oid = h[:oid]) && oid >= 10000
78
+ h[:oid] = :custom
79
+ end
80
+ end
81
+ end
82
+
83
+ sch
84
+ end
85
+ end
86
+ end
87
+
88
+ Database.register_extension(:pg_schema_caching, Postgres::SchemaCaching)
89
+ end
90
+
@@ -51,14 +51,7 @@ module Sequel
51
51
  module SchemaCaching
52
52
  # Dump the cached schema to the filename given in Marshal format.
53
53
  def dump_schema_cache(file)
54
- sch = {}
55
- @schemas.sort.each do |k,v|
56
- sch[k] = v.map do |c, h|
57
- h = Hash[h]
58
- h.delete(:callable_default)
59
- [c, h]
60
- end
61
- end
54
+ sch = dumpable_schema_cache
62
55
  File.open(file, 'wb'){|f| f.write(Marshal.dump(sch))}
63
56
  nil
64
57
  end
@@ -72,7 +65,7 @@ module Sequel
72
65
  # Replace the schema cache with the data from the given file, which
73
66
  # should be in Marshal format.
74
67
  def load_schema_cache(file)
75
- @schemas = Marshal.load(File.read(file))
68
+ @schemas = load_schema_cache_file(file)
76
69
  @schemas.each_value{|v| schema_post_process(v)}
77
70
  nil
78
71
  end
@@ -82,6 +75,28 @@ module Sequel
82
75
  def load_schema_cache?(file)
83
76
  load_schema_cache(file) if File.exist?(file)
84
77
  end
78
+
79
+ private
80
+
81
+ # Return the deserialized schema cache file.
82
+ def load_schema_cache_file(file)
83
+ Marshal.load(File.read(file))
84
+ end
85
+
86
+ # A dumpable version of the schema cache.
87
+ def dumpable_schema_cache
88
+ sch = {}
89
+
90
+ @schemas.sort.each do |k,v|
91
+ sch[k] = v.map do |c, h|
92
+ h = Hash[h]
93
+ h.delete(:callable_default)
94
+ [c, h]
95
+ end
96
+ end
97
+
98
+ sch
99
+ end
85
100
  end
86
101
 
87
102
  Database.register_extension(:schema_caching, SchemaCaching)
@@ -35,7 +35,7 @@
35
35
  #
36
36
  # j[1] # (json_column ->> 1)
37
37
  # j.get(1) # (json_column ->> 1)
38
- # j.get_text(1) # (json_column -> 1)
38
+ # j.get_json(1) # (json_column -> 1)
39
39
  # j.extract('$.a') # json_extract(json_column, '$.a')
40
40
  # jb.extract('$.a') # jsonb_extract(jsonb_column, '$.a')
41
41
  #
@@ -87,7 +87,7 @@ module Sequel
87
87
  attr_reader :simple_pk
88
88
 
89
89
  # Should be the literal table name if this Model's dataset is a simple table (no select, order, join, etc.),
90
- # or nil otherwise. This and simple_pk are used for an optimization in Model.[].
90
+ # or nil otherwise. This and simple_pk are used for an optimization in Model[].
91
91
  attr_reader :simple_table
92
92
 
93
93
  # Whether mass assigning via .create/.new/#set/#update should raise an error
@@ -398,7 +398,7 @@ module Sequel
398
398
  end
399
399
 
400
400
  # Finds a single record according to the supplied filter.
401
- # You are encouraged to use Model.[] or Model.first instead of this method.
401
+ # You are encouraged to use Model[] or Model.first instead of this method.
402
402
  #
403
403
  # Artist.find(name: 'Bob')
404
404
  # # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
@@ -1311,7 +1311,7 @@ module Sequel
1311
1311
  # Returns a string representation of the model instance including
1312
1312
  # the class name and values.
1313
1313
  def inspect
1314
- "#<#{model.name} @values=#{inspect_values}>"
1314
+ "#<#{inspect_prefix} @values=#{inspect_values}>"
1315
1315
  end
1316
1316
 
1317
1317
  # Returns the keys in +values+. May not include all column names.
@@ -1994,7 +1994,12 @@ module Sequel
1994
1994
  set(h) unless h.empty?
1995
1995
  end
1996
1996
 
1997
- # Default inspection output for the values hash, overwrite to change what #inspect displays.
1997
+ # Default inspect output for the inspect, by default, just showing the class.
1998
+ def inspect_prefix
1999
+ model.name
2000
+ end
2001
+
2002
+ # Default inspect output for the values hash, overwrite to change what #inspect displays.
1998
2003
  def inspect_values
1999
2004
  @values.inspect
2000
2005
  end
@@ -0,0 +1,44 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The inspect_pk plugin includes the pk right next to the
6
+ # model name in inspect, allowing for easily copying and
7
+ # pasting to retrieve a copy of the object:
8
+ #
9
+ # Album.with_pk(1).inspect
10
+ # # default: #<Album @values={...}>
11
+ # # with inspect_pk: #<Album[1] @values={...}>
12
+ #
13
+ # Usage:
14
+ #
15
+ # # Make all model instances include pk in inspect output
16
+ # Sequel::Model.plugin :inspect_pk
17
+ #
18
+ # # Make Album instances include pk in inspect output
19
+ # Album.plugin :inspect_pk
20
+ module InspectPk
21
+ module InstanceMethods
22
+ private
23
+
24
+ # The primary key value to include in the inspect output, if any.
25
+ # For composite primary keys, this only includes a value if all
26
+ # fields are present.
27
+ def inspect_pk
28
+ if primary_key && (pk = self.pk) && (!(Array === pk) || pk.all?)
29
+ pk
30
+ end
31
+ end
32
+
33
+ # Include the instance's primary key in the output.
34
+ def inspect_prefix
35
+ if v = inspect_pk
36
+ "#{super}[#{v.inspect}]"
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ 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 = 86
9
+ MINOR = 87
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.86.0
4
+ version: 5.87.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-11-01 00:00:00.000000000 Z
11
+ date: 2024-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -268,6 +268,7 @@ files:
268
268
  - lib/sequel/extensions/pg_range_ops.rb
269
269
  - lib/sequel/extensions/pg_row.rb
270
270
  - lib/sequel/extensions/pg_row_ops.rb
271
+ - lib/sequel/extensions/pg_schema_caching.rb
271
272
  - lib/sequel/extensions/pg_static_cache_updater.rb
272
273
  - lib/sequel/extensions/pg_timestamptz.rb
273
274
  - lib/sequel/extensions/pretty_table.rb
@@ -353,6 +354,7 @@ files:
353
354
  - lib/sequel/plugins/input_transformer.rb
354
355
  - lib/sequel/plugins/insert_conflict.rb
355
356
  - lib/sequel/plugins/insert_returning_select.rb
357
+ - lib/sequel/plugins/inspect_pk.rb
356
358
  - lib/sequel/plugins/instance_filters.rb
357
359
  - lib/sequel/plugins/instance_hooks.rb
358
360
  - lib/sequel/plugins/instance_specific_default.rb
@@ -444,7 +446,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
444
446
  - !ruby/object:Gem::Version
445
447
  version: '0'
446
448
  requirements: []
447
- rubygems_version: 3.5.16
449
+ rubygems_version: 3.5.22
448
450
  signing_key:
449
451
  specification_version: 4
450
452
  summary: The Database Toolkit for Ruby