sequel 5.73.0 → 5.75.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 +4 -4
 - data/CHANGELOG +22 -0
 - data/doc/migration.rdoc +14 -0
 - data/doc/release_notes/5.74.0.txt +45 -0
 - data/doc/release_notes/5.75.0.txt +35 -0
 - data/lib/sequel/adapters/jdbc/db2.rb +0 -4
 - data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -0
 - data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
 - data/lib/sequel/adapters/jdbc.rb +10 -6
 - data/lib/sequel/adapters/postgres.rb +4 -3
 - data/lib/sequel/adapters/shared/mysql.rb +21 -1
 - data/lib/sequel/adapters/shared/postgres.rb +54 -0
 - data/lib/sequel/adapters/shared/sqlite.rb +0 -1
 - data/lib/sequel/extensions/any_not_empty.rb +2 -2
 - data/lib/sequel/extensions/migration.rb +47 -8
 - data/lib/sequel/extensions/pg_json_ops.rb +52 -0
 - data/lib/sequel/plugins/column_encryption.rb +1 -1
 - data/lib/sequel/version.rb +1 -1
 - metadata +6 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3047129164c9cdffee31414419904329e410db71e7e4243c0549614498a2b0d4
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 9cc84ed8e9dba53aac7175be04699089932566e4015aed7a465c43552808c8b4
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 15ed5c13e4793191546cd452aa5865e65fd7b3bb0458ffdb674d526398b7c9446e2da0f43a339daa3f1dc256eb551f0b773ac9ffc192b4d19f389d0c7e296d98
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 1f25851b50857fbbf8378216794f26d0d8e9baa247f008feac466a218ae6b0777249252b6d05756e075096c5312b9d3b1334b7c4bc1884251e7b892cc17ae7c6
         
     | 
    
        data/CHANGELOG
    CHANGED
    
    | 
         @@ -1,3 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 5.75.0 (2023-12-01)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Make any_not_empty? extension support passing pattern argument to any? (jeremyevans) (#2100)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Respect :skip_transaction option in PostgreSQL Dataset#paged_each (jeremyevans) (#2097)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Add TimestampMigrator.run_single to run a single migration file up or down (opya, jeremyevans) (#2093)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Support INSERT RETURNING on MariaDB 10.5+, and use it when saving new model objects (jeremyevans)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * Add Database#{defer,immediate}_constraints on PostgreSQL for changing handling of deferrable constraints in a transaction (jeremyevans)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            === 5.74.0 (2023-11-01)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * Make generated columns show up in Database#schema when using SQLite 3.37+ (jeremyevans) (#2087)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * Add revert method for Sequel.migration blocks, to revert changes inside the block on up, and apply the changes on down (jeremyevans)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            * Re-add is_json and is_not_json methods to the pg_json_ops extension, as the support was re-added in PostgreSQL 16 (jeremyevans)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            * Avoid infinite loop when handling exceptions with a cause loop in jdbc adapter (jeremyevans)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       1 
23 
     | 
    
         
             
            === 5.73.0 (2023-10-01)
         
     | 
| 
       2 
24 
     | 
    
         | 
| 
       3 
25 
     | 
    
         
             
            * Handle disconnect errors in ibmdb and jdbc/db2 adapters (jeremyevans) (#2083)
         
     | 
    
        data/doc/migration.rdoc
    CHANGED
    
    | 
         @@ -90,6 +90,20 @@ the following methods: 
     | 
|
| 
       90 
90 
     | 
    
         | 
| 
       91 
91 
     | 
    
         
             
            If you use any other methods, you should create your own +down+ block.
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
      
 93 
     | 
    
         
            +
            To revert a migration created with +change+, you can copy the migration to a new file, and
         
     | 
| 
      
 94 
     | 
    
         
            +
            replace +change+ with +revert+. For example, if you no longer need the artists table, you
         
     | 
| 
      
 95 
     | 
    
         
            +
            can use the following migration.  This will drop the artists table when migrating up, and
         
     | 
| 
      
 96 
     | 
    
         
            +
            recreate it when migrating down:
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              Sequel.migration do
         
     | 
| 
      
 99 
     | 
    
         
            +
                revert do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  create_table(:artists) do
         
     | 
| 
      
 101 
     | 
    
         
            +
                    primary_key :id
         
     | 
| 
      
 102 
     | 
    
         
            +
                    String :name, null: false
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
       93 
107 
     | 
    
         
             
            In normal usage, when Sequel's migrator runs, it runs the +up+ blocks for all
         
     | 
| 
       94 
108 
     | 
    
         
             
            migrations that have not yet been applied.  However, you can use the <tt>-M</tt>
         
     | 
| 
       95 
109 
     | 
    
         
             
            switch to specify the version to which to migrate, and if it is lower than the
         
     | 
| 
         @@ -0,0 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = New Features
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Sequel.migration blocks now support a revert method, which reverts
         
     | 
| 
      
 4 
     | 
    
         
            +
              the changes in the block on up, and applies them on down.  So if
         
     | 
| 
      
 5 
     | 
    
         
            +
              you have a migration such as:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                Sequel.migration do
         
     | 
| 
      
 8 
     | 
    
         
            +
                  change do
         
     | 
| 
      
 9 
     | 
    
         
            +
                    create_table :table do
         
     | 
| 
      
 10 
     | 
    
         
            +
                      # ...
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              and you later want to add a migration that drops the table, you
         
     | 
| 
      
 16 
     | 
    
         
            +
              can use:
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                Sequel.migration do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  revert do
         
     | 
| 
      
 20 
     | 
    
         
            +
                    create_table :table do
         
     | 
| 
      
 21 
     | 
    
         
            +
                      # ...
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              This will drop the table when migrating up, and create a table 
         
     | 
| 
      
 27 
     | 
    
         
            +
              with the given schema when migrating down.
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            * is_json and is_not_json methods have been added to the pg_json_ops
         
     | 
| 
      
 30 
     | 
    
         
            +
              extension, for the IS [NOT] JSON operator supported in PostgreSQL
         
     | 
| 
      
 31 
     | 
    
         
            +
              16+.  These were previously added in Sequel 5.59.0, and removed
         
     | 
| 
      
 32 
     | 
    
         
            +
              in Sequel 5.61.0 as support was removed in PostgreSQL 15 beta 4.
         
     | 
| 
      
 33 
     | 
    
         
            +
              PostgreSQL 16 shipped with support for them, so support has been
         
     | 
| 
      
 34 
     | 
    
         
            +
              recommitted to Sequel.
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            = Other Improvements
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            * SQLite generated columns now show up in Database#schema when using
         
     | 
| 
      
 39 
     | 
    
         
            +
              SQLite 3.37+.
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            * Sequel now attempts to avoid an infinite loop in pathlogical cases
         
     | 
| 
      
 42 
     | 
    
         
            +
              in the jdbc adapter, where the exception cause chain has a loop.
         
     | 
| 
      
 43 
     | 
    
         
            +
              Additionally, if an exception is already recognized as a disconnect,
         
     | 
| 
      
 44 
     | 
    
         
            +
              or an exception already responds to a getSQLState method, Sequel no
         
     | 
| 
      
 45 
     | 
    
         
            +
              longer looks at the causes of the exception.
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = New Features
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Database#{defer,immediate}_constraints methods have been added on
         
     | 
| 
      
 4 
     | 
    
         
            +
              PostgreSQL for changing handling of deferrable constraints inside
         
     | 
| 
      
 5 
     | 
    
         
            +
              a transaction. defer_constraints sets deferrable constraints to
         
     | 
| 
      
 6 
     | 
    
         
            +
              be deferred (not checked until transaction commit), and
         
     | 
| 
      
 7 
     | 
    
         
            +
              immediate_constraints sets deferrable constraints to be checked
         
     | 
| 
      
 8 
     | 
    
         
            +
              as part of the related query, and any already deferred constraint
         
     | 
| 
      
 9 
     | 
    
         
            +
              checks to be applied immediately. You can pass the :constraints
         
     | 
| 
      
 10 
     | 
    
         
            +
              option to only apply the changes to specific constraints.
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            * TimestampMigrator.run_single has been added, to migrate a single
         
     | 
| 
      
 13 
     | 
    
         
            +
              migration up or down.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            = Other Improvements
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * INSERT RETURNING is now supported on MariaDB 10.5+, and used
         
     | 
| 
      
 18 
     | 
    
         
            +
              automatically when saving new model objects. Note that this
         
     | 
| 
      
 19 
     | 
    
         
            +
              is not supported when using the jdbc adapter, because the
         
     | 
| 
      
 20 
     | 
    
         
            +
              jdbc-mysql driver doesn't support it.  A jdbc/mariadb adapter
         
     | 
| 
      
 21 
     | 
    
         
            +
              could be added, as it's likely recent versions of the
         
     | 
| 
      
 22 
     | 
    
         
            +
              jdbc-mariadb driver would support it, but the jdbc-mariadb gem 
         
     | 
| 
      
 23 
     | 
    
         
            +
              hasn't been updated in over 4 years.  Talk to the jdbc-mariadb
         
     | 
| 
      
 24 
     | 
    
         
            +
              gem maintainers if you want to use this feature with the jdbc
         
     | 
| 
      
 25 
     | 
    
         
            +
              adapter.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            * The Dataset#paged_each optimization in the postgres adapter
         
     | 
| 
      
 28 
     | 
    
         
            +
              now respects the :skip_transaction option, making it the
         
     | 
| 
      
 29 
     | 
    
         
            +
              same as the :hold option.  Note that this has effects beyond
         
     | 
| 
      
 30 
     | 
    
         
            +
              just skipping the transaction, but non-HOLD cursors are only
         
     | 
| 
      
 31 
     | 
    
         
            +
              supported inside transactions.
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            * The any_not_empty? extension's Dataset#any? method now supports
         
     | 
| 
      
 34 
     | 
    
         
            +
              an argument, passing it to Enumerable#any? (which has supported
         
     | 
| 
      
 35 
     | 
    
         
            +
              an argument since Ruby 2.5).
         
     | 
    
        data/lib/sequel/adapters/jdbc.rb
    CHANGED
    
    | 
         @@ -396,11 +396,16 @@ module Sequel 
     | 
|
| 
       396 
396 
     | 
    
         | 
| 
       397 
397 
     | 
    
         
             
                  def database_exception_sqlstate(exception, opts)
         
     | 
| 
       398 
398 
     | 
    
         
             
                    if database_exception_use_sqlstates?
         
     | 
| 
       399 
     | 
    
         
            -
                       
     | 
| 
       400 
     | 
    
         
            -
                        exception = exception.cause
         
     | 
| 
       401 
     | 
    
         
            -
                        return exception.getSQLState if exception.respond_to?(:getSQLState)
         
     | 
| 
       402 
     | 
    
         
            -
                      end
         
     | 
| 
      
 399 
     | 
    
         
            +
                      _database_exception_sqlstate(exception, opts)
         
     | 
| 
       403 
400 
     | 
    
         
             
                    end
         
     | 
| 
      
 401 
     | 
    
         
            +
                  end
         
     | 
| 
      
 402 
     | 
    
         
            +
             
     | 
| 
      
 403 
     | 
    
         
            +
                  def _database_exception_sqlstate(exception, opts)
         
     | 
| 
      
 404 
     | 
    
         
            +
                    16.times do
         
     | 
| 
      
 405 
     | 
    
         
            +
                      return exception.getSQLState if exception.respond_to?(:getSQLState)
         
     | 
| 
      
 406 
     | 
    
         
            +
                      break unless exception.respond_to?(:cause) && (exception = exception.cause)
         
     | 
| 
      
 407 
     | 
    
         
            +
                    end
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
       404 
409 
     | 
    
         
             
                    nil
         
     | 
| 
       405 
410 
     | 
    
         
             
                  end
         
     | 
| 
       406 
411 
     | 
    
         | 
| 
         @@ -415,8 +420,7 @@ module Sequel 
     | 
|
| 
       415 
420 
     | 
    
         | 
| 
       416 
421 
     | 
    
         
             
                  # Raise a disconnect error if the SQL state of the cause of the exception indicates so.
         
     | 
| 
       417 
422 
     | 
    
         
             
                  def disconnect_error?(exception, opts)
         
     | 
| 
       418 
     | 
    
         
            -
                     
     | 
| 
       419 
     | 
    
         
            -
                    super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
         
     | 
| 
      
 423 
     | 
    
         
            +
                    super || (_database_exception_sqlstate(exception, opts) =~ /^08/)
         
     | 
| 
       420 
424 
     | 
    
         
             
                  end
         
     | 
| 
       421 
425 
     | 
    
         | 
| 
       422 
426 
     | 
    
         
             
                  # Execute the prepared statement.  If the provided name is a
         
     | 
| 
         @@ -672,6 +672,7 @@ module Sequel 
     | 
|
| 
       672 
672 
     | 
    
         
             
                  #          cursor usage.
         
     | 
| 
       673 
673 
     | 
    
         
             
                  # :rows_per_fetch :: The number of rows per fetch (default 1000).  Higher
         
     | 
| 
       674 
674 
     | 
    
         
             
                  #                    numbers result in fewer queries but greater memory use.
         
     | 
| 
      
 675 
     | 
    
         
            +
                  # :skip_transaction :: Same as :hold, but :hold takes priority.
         
     | 
| 
       675 
676 
     | 
    
         
             
                  #
         
     | 
| 
       676 
677 
     | 
    
         
             
                  # Usage:
         
     | 
| 
       677 
678 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -764,13 +765,13 @@ module Sequel 
     | 
|
| 
       764 
765 
     | 
    
         | 
| 
       765 
766 
     | 
    
         
             
                  # Use a cursor to fetch groups of records at a time, yielding them to the block.
         
     | 
| 
       766 
767 
     | 
    
         
             
                  def cursor_fetch_rows(sql)
         
     | 
| 
       767 
     | 
    
         
            -
                    server_opts = {:server=>@opts[:server] || :read_only}
         
     | 
| 
       768 
768 
     | 
    
         
             
                    cursor = @opts[:cursor]
         
     | 
| 
       769 
     | 
    
         
            -
                    hold = cursor[: 
     | 
| 
      
 769 
     | 
    
         
            +
                    hold = cursor.fetch(:hold){cursor[:skip_transaction]}
         
     | 
| 
      
 770 
     | 
    
         
            +
                    server_opts = {:server=>@opts[:server] || :read_only, :skip_transaction=>hold}
         
     | 
| 
       770 
771 
     | 
    
         
             
                    cursor_name = quote_identifier(cursor[:cursor_name] || 'sequel_cursor')
         
     | 
| 
       771 
772 
     | 
    
         
             
                    rows_per_fetch = cursor[:rows_per_fetch].to_i
         
     | 
| 
       772 
773 
     | 
    
         | 
| 
       773 
     | 
    
         
            -
                    db. 
     | 
| 
      
 774 
     | 
    
         
            +
                    db.transaction(server_opts) do 
         
     | 
| 
       774 
775 
     | 
    
         
             
                      begin
         
     | 
| 
       775 
776 
     | 
    
         
             
                        execute_ddl("DECLARE #{cursor_name} NO SCROLL CURSOR WITH#{'OUT' unless hold} HOLD FOR #{sql}", server_opts)
         
     | 
| 
       776 
777 
     | 
    
         
             
                        rows_per_fetch = 1000 if rows_per_fetch <= 0
         
     | 
| 
         @@ -646,7 +646,7 @@ module Sequel 
     | 
|
| 
       646 
646 
     | 
    
         
             
                  MATCH_AGAINST_BOOLEAN = ["MATCH ".freeze, " AGAINST (".freeze, " IN BOOLEAN MODE)".freeze].freeze
         
     | 
| 
       647 
647 
     | 
    
         | 
| 
       648 
648 
     | 
    
         
             
                  Dataset.def_sql_method(self, :delete, %w'with delete from where order limit')
         
     | 
| 
       649 
     | 
    
         
            -
                  Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update')
         
     | 
| 
      
 649 
     | 
    
         
            +
                  Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update returning')
         
     | 
| 
       650 
650 
     | 
    
         
             
                  Dataset.def_sql_method(self, :select, %w'with select distinct calc_found_rows columns from join where group having window compounds order limit lock')
         
     | 
| 
       651 
651 
     | 
    
         
             
                  Dataset.def_sql_method(self, :update, %w'with update ignore table set where order limit')
         
     | 
| 
       652 
652 
     | 
    
         | 
| 
         @@ -774,6 +774,21 @@ module Sequel 
     | 
|
| 
       774 
774 
     | 
    
         
             
                    clone(:insert_ignore=>true)
         
     | 
| 
       775 
775 
     | 
    
         
             
                  end
         
     | 
| 
       776 
776 
     | 
    
         | 
| 
      
 777 
     | 
    
         
            +
                  # Support insert select for associations, so that the model code can use
         
     | 
| 
      
 778 
     | 
    
         
            +
                  # returning instead of a separate query.
         
     | 
| 
      
 779 
     | 
    
         
            +
                  def insert_select(*values)
         
     | 
| 
      
 780 
     | 
    
         
            +
                    return unless supports_insert_select?
         
     | 
| 
      
 781 
     | 
    
         
            +
                    # Handle case where query does not return a row
         
     | 
| 
      
 782 
     | 
    
         
            +
                    server?(:default).with_sql_first(insert_select_sql(*values)) || false
         
     | 
| 
      
 783 
     | 
    
         
            +
                  end
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
      
 785 
     | 
    
         
            +
                  # The SQL to use for an insert_select, adds a RETURNING clause to the insert
         
     | 
| 
      
 786 
     | 
    
         
            +
                  # unless the RETURNING clause is already present.
         
     | 
| 
      
 787 
     | 
    
         
            +
                  def insert_select_sql(*values)
         
     | 
| 
      
 788 
     | 
    
         
            +
                    ds = opts[:returning] ? self : returning
         
     | 
| 
      
 789 
     | 
    
         
            +
                    ds.insert_sql(*values)
         
     | 
| 
      
 790 
     | 
    
         
            +
                  end
         
     | 
| 
      
 791 
     | 
    
         
            +
             
     | 
| 
       777 
792 
     | 
    
         
             
                  # Sets up the insert methods to use ON DUPLICATE KEY UPDATE
         
     | 
| 
       778 
793 
     | 
    
         
             
                  # If you pass no arguments, ALL fields will be
         
     | 
| 
       779 
794 
     | 
    
         
             
                  # updated with the new values.  If you pass the fields you
         
     | 
| 
         @@ -871,6 +886,11 @@ module Sequel 
     | 
|
| 
       871 
886 
     | 
    
         
             
                    true
         
     | 
| 
       872 
887 
     | 
    
         
             
                  end
         
     | 
| 
       873 
888 
     | 
    
         | 
| 
      
 889 
     | 
    
         
            +
                  # MariaDB 10.5.0 supports INSERT RETURNING.
         
     | 
| 
      
 890 
     | 
    
         
            +
                  def supports_returning?(type)
         
     | 
| 
      
 891 
     | 
    
         
            +
                    (type == :insert && db.mariadb? && db.adapter_scheme != :jdbc) ? (db.server_version >= 100500) : false
         
     | 
| 
      
 892 
     | 
    
         
            +
                  end
         
     | 
| 
      
 893 
     | 
    
         
            +
             
     | 
| 
       874 
894 
     | 
    
         
             
                  # MySQL 8+ supports SKIP LOCKED.
         
     | 
| 
       875 
895 
     | 
    
         
             
                  def supports_skip_locked?
         
     | 
| 
       876 
896 
     | 
    
         
             
                    !db.mariadb? && db.server_version >= 80000
         
     | 
| 
         @@ -498,6 +498,25 @@ module Sequel 
     | 
|
| 
       498 
498 
     | 
    
         
             
                    :postgres
         
     | 
| 
       499 
499 
     | 
    
         
             
                  end
         
     | 
| 
       500 
500 
     | 
    
         | 
| 
      
 501 
     | 
    
         
            +
                  # For constraints that are deferrable, defer constraints until 
         
     | 
| 
      
 502 
     | 
    
         
            +
                  # transaction commit. Options:
         
     | 
| 
      
 503 
     | 
    
         
            +
                  #
         
     | 
| 
      
 504 
     | 
    
         
            +
                  # :constraints :: An identifier of the constraint, or an array of
         
     | 
| 
      
 505 
     | 
    
         
            +
                  #                 identifiers for constraints, to apply this
         
     | 
| 
      
 506 
     | 
    
         
            +
                  #                 change to specific constraints.
         
     | 
| 
      
 507 
     | 
    
         
            +
                  # :server :: The server/shard on which to run the query.
         
     | 
| 
      
 508 
     | 
    
         
            +
                  #
         
     | 
| 
      
 509 
     | 
    
         
            +
                  # Examples:
         
     | 
| 
      
 510 
     | 
    
         
            +
                  #
         
     | 
| 
      
 511 
     | 
    
         
            +
                  #   DB.defer_constraints
         
     | 
| 
      
 512 
     | 
    
         
            +
                  #   # SET CONSTRAINTS ALL DEFERRED
         
     | 
| 
      
 513 
     | 
    
         
            +
                  #
         
     | 
| 
      
 514 
     | 
    
         
            +
                  #   DB.defer_constraints(constraints: [:c1, Sequel[:sc][:c2]])
         
     | 
| 
      
 515 
     | 
    
         
            +
                  #   # SET CONSTRAINTS "c1", "sc"."s2" DEFERRED
         
     | 
| 
      
 516 
     | 
    
         
            +
                  def defer_constraints(opts=OPTS)
         
     | 
| 
      
 517 
     | 
    
         
            +
                    _set_constraints(' DEFERRED', opts)
         
     | 
| 
      
 518 
     | 
    
         
            +
                  end
         
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
       501 
520 
     | 
    
         
             
                  # Use PostgreSQL's DO syntax to execute an anonymous code block.  The code should
         
     | 
| 
       502 
521 
     | 
    
         
             
                  # be the literal code string to use in the underlying procedural language.  Options:
         
     | 
| 
       503 
522 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -611,6 +630,24 @@ module Sequel 
     | 
|
| 
       611 
630 
     | 
    
         
             
                    super
         
     | 
| 
       612 
631 
     | 
    
         
             
                  end
         
     | 
| 
       613 
632 
     | 
    
         | 
| 
      
 633 
     | 
    
         
            +
                  # Immediately apply deferrable constraints.
         
     | 
| 
      
 634 
     | 
    
         
            +
                  #
         
     | 
| 
      
 635 
     | 
    
         
            +
                  # :constraints :: An identifier of the constraint, or an array of
         
     | 
| 
      
 636 
     | 
    
         
            +
                  #                 identifiers for constraints, to apply this
         
     | 
| 
      
 637 
     | 
    
         
            +
                  #                 change to specific constraints.
         
     | 
| 
      
 638 
     | 
    
         
            +
                  # :server :: The server/shard on which to run the query.
         
     | 
| 
      
 639 
     | 
    
         
            +
                  #
         
     | 
| 
      
 640 
     | 
    
         
            +
                  # Examples:
         
     | 
| 
      
 641 
     | 
    
         
            +
                  #
         
     | 
| 
      
 642 
     | 
    
         
            +
                  #   DB.immediate_constraints
         
     | 
| 
      
 643 
     | 
    
         
            +
                  #   # SET CONSTRAINTS ALL IMMEDIATE
         
     | 
| 
      
 644 
     | 
    
         
            +
                  #
         
     | 
| 
      
 645 
     | 
    
         
            +
                  #   DB.immediate_constraints(constraints: [:c1, Sequel[:sc][:c2]])
         
     | 
| 
      
 646 
     | 
    
         
            +
                  #   # SET CONSTRAINTS "c1", "sc"."s2" IMMEDIATE
         
     | 
| 
      
 647 
     | 
    
         
            +
                  def immediate_constraints(opts=OPTS)
         
     | 
| 
      
 648 
     | 
    
         
            +
                    _set_constraints(' IMMEDIATE', opts)
         
     | 
| 
      
 649 
     | 
    
         
            +
                  end
         
     | 
| 
      
 650 
     | 
    
         
            +
             
     | 
| 
       614 
651 
     | 
    
         
             
                  # Use the pg_* system tables to determine indexes on a table
         
     | 
| 
       615 
652 
     | 
    
         
             
                  def indexes(table, opts=OPTS)
         
     | 
| 
       616 
653 
     | 
    
         
             
                    m = output_identifier_meth
         
     | 
| 
         @@ -1038,6 +1075,23 @@ module Sequel 
     | 
|
| 
       1038 
1075 
     | 
    
         
             
                    end
         
     | 
| 
       1039 
1076 
     | 
    
         
             
                  end
         
     | 
| 
       1040 
1077 
     | 
    
         | 
| 
      
 1078 
     | 
    
         
            +
                  # Internals of defer_constraints/immediate_constraints
         
     | 
| 
      
 1079 
     | 
    
         
            +
                  def _set_constraints(type, opts)
         
     | 
| 
      
 1080 
     | 
    
         
            +
                    execute_ddl(_set_constraints_sql(type, opts), opts)
         
     | 
| 
      
 1081 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1082 
     | 
    
         
            +
             
     | 
| 
      
 1083 
     | 
    
         
            +
                  # SQL to use for SET CONSTRAINTS
         
     | 
| 
      
 1084 
     | 
    
         
            +
                  def _set_constraints_sql(type, opts)
         
     | 
| 
      
 1085 
     | 
    
         
            +
                    sql = String.new
         
     | 
| 
      
 1086 
     | 
    
         
            +
                    sql << "SET CONSTRAINTS "
         
     | 
| 
      
 1087 
     | 
    
         
            +
                    if constraints = opts[:constraints]
         
     | 
| 
      
 1088 
     | 
    
         
            +
                      dataset.send(:source_list_append, sql, Array(constraints))
         
     | 
| 
      
 1089 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1090 
     | 
    
         
            +
                      sql << "ALL"
         
     | 
| 
      
 1091 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1092 
     | 
    
         
            +
                    sql << type
         
     | 
| 
      
 1093 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1094 
     | 
    
         
            +
             
     | 
| 
       1041 
1095 
     | 
    
         
             
                  def alter_table_add_column_sql(table, op)
         
     | 
| 
       1042 
1096 
     | 
    
         
             
                    "ADD COLUMN#{' IF NOT EXISTS' if op[:if_not_exists]} #{column_definition_sql(op)}"
         
     | 
| 
       1043 
1097 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -504,7 +504,6 @@ module Sequel 
     | 
|
| 
       504 
504 
     | 
    
         
             
                        # table_xinfo PRAGMA used, remove hidden columns
         
     | 
| 
       505 
505 
     | 
    
         
             
                        # that are not generated columns
         
     | 
| 
       506 
506 
     | 
    
         
             
                        if row[:generated] = (row.delete(:hidden) != 0)
         
     | 
| 
       507 
     | 
    
         
            -
                          next unless row[:type].end_with?(' GENERATED ALWAYS')
         
     | 
| 
       508 
507 
     | 
    
         
             
                          row[:type] = row[:type].sub(' GENERATED ALWAYS', '')
         
     | 
| 
       509 
508 
     | 
    
         
             
                        end
         
     | 
| 
       510 
509 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -159,6 +159,19 @@ module Sequel 
     | 
|
| 
       159 
159 
     | 
    
         
             
                  migration.up = block
         
     | 
| 
       160 
160 
     | 
    
         
             
                  migration.down = MigrationReverser.new.reverse(&block)
         
     | 
| 
       161 
161 
     | 
    
         
             
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                # Creates a revert migration.  This is the same as creating
         
     | 
| 
      
 164 
     | 
    
         
            +
                # the same block with +down+, but it also calls the block and attempts
         
     | 
| 
      
 165 
     | 
    
         
            +
                # to create a +up+ block that will reverse the changes made by
         
     | 
| 
      
 166 
     | 
    
         
            +
                # the block.  This is designed to revert the changes in the
         
     | 
| 
      
 167 
     | 
    
         
            +
                # provided block.
         
     | 
| 
      
 168 
     | 
    
         
            +
                #
         
     | 
| 
      
 169 
     | 
    
         
            +
                # There are no guarantees that this will work perfectly
         
     | 
| 
      
 170 
     | 
    
         
            +
                # in all cases, but it works for some simple cases.
         
     | 
| 
      
 171 
     | 
    
         
            +
                def revert(&block)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  migration.down = block
         
     | 
| 
      
 173 
     | 
    
         
            +
                  migration.up = MigrationReverser.new.reverse(&block)
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
       162 
175 
     | 
    
         
             
              end
         
     | 
| 
       163 
176 
     | 
    
         | 
| 
       164 
177 
     | 
    
         
             
              # Handles the reversing of reversible migrations.  Basically records
         
     | 
| 
         @@ -680,6 +693,13 @@ module Sequel 
     | 
|
| 
       680 
693 
     | 
    
         
             
                  @migration_tuples = get_migration_tuples
         
     | 
| 
       681 
694 
     | 
    
         
             
                end
         
     | 
| 
       682 
695 
     | 
    
         | 
| 
      
 696 
     | 
    
         
            +
                # Apply the migration in the given file path.  See Migrator.run for the
         
     | 
| 
      
 697 
     | 
    
         
            +
                # available options.  Additionally, this method supports the :direction
         
     | 
| 
      
 698 
     | 
    
         
            +
                # option for whether to run the migration up (default) or down.
         
     | 
| 
      
 699 
     | 
    
         
            +
                def self.run_single(db, path, opts=OPTS)
         
     | 
| 
      
 700 
     | 
    
         
            +
                  new(db, File.dirname(path), opts).run_single(path, opts[:direction] || :up)
         
     | 
| 
      
 701 
     | 
    
         
            +
                end
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
       683 
703 
     | 
    
         
             
                # The timestamp migrator is current if there are no migrations to apply
         
     | 
| 
       684 
704 
     | 
    
         
             
                # in either direction.
         
     | 
| 
       685 
705 
     | 
    
         
             
                def is_current?
         
     | 
| 
         @@ -689,20 +709,39 @@ module Sequel 
     | 
|
| 
       689 
709 
     | 
    
         
             
                # Apply all migration tuples on the database
         
     | 
| 
       690 
710 
     | 
    
         
             
                def run
         
     | 
| 
       691 
711 
     | 
    
         
             
                  migration_tuples.each do |m, f, direction|
         
     | 
| 
       692 
     | 
    
         
            -
                     
     | 
| 
       693 
     | 
    
         
            -
                    db.log_info("Begin applying migration #{f}, direction: #{direction}")
         
     | 
| 
       694 
     | 
    
         
            -
                    checked_transaction(m) do
         
     | 
| 
       695 
     | 
    
         
            -
                      m.apply(db, direction)
         
     | 
| 
       696 
     | 
    
         
            -
                      fi = f.downcase
         
     | 
| 
       697 
     | 
    
         
            -
                      direction == :up ? ds.insert(column=>fi) : ds.where(column=>fi).delete
         
     | 
| 
       698 
     | 
    
         
            -
                    end
         
     | 
| 
       699 
     | 
    
         
            -
                    db.log_info("Finished applying migration #{f}, direction: #{direction}, took #{sprintf('%0.6f', Time.now - t)} seconds")
         
     | 
| 
      
 712 
     | 
    
         
            +
                    apply_migration(m, f, direction)
         
     | 
| 
       700 
713 
     | 
    
         
             
                  end
         
     | 
| 
       701 
714 
     | 
    
         
             
                  nil
         
     | 
| 
       702 
715 
     | 
    
         
             
                end
         
     | 
| 
       703 
716 
     | 
    
         | 
| 
      
 717 
     | 
    
         
            +
                # Apply single migration tuple at the given path with the given direction
         
     | 
| 
      
 718 
     | 
    
         
            +
                # on the database.
         
     | 
| 
      
 719 
     | 
    
         
            +
                def run_single(path, direction)
         
     | 
| 
      
 720 
     | 
    
         
            +
                  migration = load_migration_file(path)
         
     | 
| 
      
 721 
     | 
    
         
            +
                  file_name = File.basename(path)
         
     | 
| 
      
 722 
     | 
    
         
            +
                  already_applied = applied_migrations.include?(file_name.downcase)
         
     | 
| 
      
 723 
     | 
    
         
            +
             
     | 
| 
      
 724 
     | 
    
         
            +
                  return if direction == :up ? already_applied : !already_applied
         
     | 
| 
      
 725 
     | 
    
         
            +
             
     | 
| 
      
 726 
     | 
    
         
            +
                  apply_migration(migration, file_name, direction)
         
     | 
| 
      
 727 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 728 
     | 
    
         
            +
                end
         
     | 
| 
      
 729 
     | 
    
         
            +
             
     | 
| 
       704 
730 
     | 
    
         
             
                private
         
     | 
| 
       705 
731 
     | 
    
         | 
| 
      
 732 
     | 
    
         
            +
                # Apply a single migration with the given filename in the given direction.
         
     | 
| 
      
 733 
     | 
    
         
            +
                def apply_migration(migration, file_name, direction)
         
     | 
| 
      
 734 
     | 
    
         
            +
                  fi = file_name.downcase
         
     | 
| 
      
 735 
     | 
    
         
            +
                  t = Time.now
         
     | 
| 
      
 736 
     | 
    
         
            +
             
     | 
| 
      
 737 
     | 
    
         
            +
                  db.log_info("Begin applying migration #{file_name}, direction: #{direction}")
         
     | 
| 
      
 738 
     | 
    
         
            +
                  checked_transaction(migration) do
         
     | 
| 
      
 739 
     | 
    
         
            +
                    migration.apply(db, direction)
         
     | 
| 
      
 740 
     | 
    
         
            +
                    direction == :up ? ds.insert(column=>fi) : ds.where(column=>fi).delete
         
     | 
| 
      
 741 
     | 
    
         
            +
                  end
         
     | 
| 
      
 742 
     | 
    
         
            +
                  db.log_info("Finished applying migration #{file_name}, direction: #{direction}, took #{sprintf('%0.6f', Time.now - t)} seconds")
         
     | 
| 
      
 743 
     | 
    
         
            +
                end
         
     | 
| 
      
 744 
     | 
    
         
            +
             
     | 
| 
       706 
745 
     | 
    
         
             
                # Convert the schema_info table to the new schema_migrations table format,
         
     | 
| 
       707 
746 
     | 
    
         
             
                # using the version of the schema_info table and the current migration files.
         
     | 
| 
       708 
747 
     | 
    
         
             
                def convert_from_schema_info
         
     | 
| 
         @@ -123,6 +123,15 @@ 
     | 
|
| 
       123 
123 
     | 
    
         
             
            #   c = Sequel.pg_jsonb_op(:c)
         
     | 
| 
       124 
124 
     | 
    
         
             
            #   DB[:t].update(c['key1'] => 1.to_json, c['key2'] => "a".to_json)
         
     | 
| 
       125 
125 
     | 
    
         
             
            #
         
     | 
| 
      
 126 
     | 
    
         
            +
            # On PostgreSQL 16+, the <tt>IS [NOT] JSON</tt> operator is supported:
         
     | 
| 
      
 127 
     | 
    
         
            +
            #
         
     | 
| 
      
 128 
     | 
    
         
            +
            #   j.is_json                              # j IS JSON
         
     | 
| 
      
 129 
     | 
    
         
            +
            #   j.is_json(type: :object)               # j IS JSON OBJECT
         
     | 
| 
      
 130 
     | 
    
         
            +
            #   j.is_json(type: :object, unique: true) # j IS JSON OBJECT WITH UNIQUE
         
     | 
| 
      
 131 
     | 
    
         
            +
            #   j.is_not_json                          # j IS NOT JSON
         
     | 
| 
      
 132 
     | 
    
         
            +
            #   j.is_not_json(type: :array)                # j IS NOT JSON ARRAY
         
     | 
| 
      
 133 
     | 
    
         
            +
            #   j.is_not_json(unique: true)                # j IS NOT JSON WITH UNIQUE
         
     | 
| 
      
 134 
     | 
    
         
            +
            #
         
     | 
| 
       126 
135 
     | 
    
         
             
            # If you are also using the pg_json extension, you should load it before
         
     | 
| 
       127 
136 
     | 
    
         
             
            # loading this extension.  Doing so will allow you to use the #op method on
         
     | 
| 
       128 
137 
     | 
    
         
             
            # JSONHash, JSONHarray, JSONBHash, and JSONBArray, allowing you to perform json/jsonb operations
         
     | 
| 
         @@ -151,6 +160,18 @@ module Sequel 
     | 
|
| 
       151 
160 
     | 
    
         
             
                  GET_PATH = ["(".freeze, " #> ".freeze, ")".freeze].freeze
         
     | 
| 
       152 
161 
     | 
    
         
             
                  GET_PATH_TEXT = ["(".freeze, " #>> ".freeze, ")".freeze].freeze
         
     | 
| 
       153 
162 
     | 
    
         | 
| 
      
 163 
     | 
    
         
            +
                  IS_JSON = ["(".freeze, " IS JSON".freeze, "".freeze, ")".freeze].freeze
         
     | 
| 
      
 164 
     | 
    
         
            +
                  IS_NOT_JSON = ["(".freeze, " IS NOT JSON".freeze, "".freeze, ")".freeze].freeze
         
     | 
| 
      
 165 
     | 
    
         
            +
                  EMPTY_STRING = Sequel::LiteralString.new('').freeze
         
     | 
| 
      
 166 
     | 
    
         
            +
                  WITH_UNIQUE = Sequel::LiteralString.new(' WITH UNIQUE').freeze
         
     | 
| 
      
 167 
     | 
    
         
            +
                  IS_JSON_MAP = {
         
     | 
| 
      
 168 
     | 
    
         
            +
                    nil => EMPTY_STRING,
         
     | 
| 
      
 169 
     | 
    
         
            +
                    :value => Sequel::LiteralString.new(' VALUE').freeze,
         
     | 
| 
      
 170 
     | 
    
         
            +
                    :scalar => Sequel::LiteralString.new(' SCALAR').freeze,
         
     | 
| 
      
 171 
     | 
    
         
            +
                    :object => Sequel::LiteralString.new(' OBJECT').freeze,
         
     | 
| 
      
 172 
     | 
    
         
            +
                    :array => Sequel::LiteralString.new(' ARRAY').freeze
         
     | 
| 
      
 173 
     | 
    
         
            +
                  }.freeze
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       154 
175 
     | 
    
         
             
                  # Get JSON array element or object field as json.  If an array is given,
         
     | 
| 
       155 
176 
     | 
    
         
             
                  # gets the object at the specified path.
         
     | 
| 
       156 
177 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -233,6 +254,30 @@ module Sequel 
     | 
|
| 
       233 
254 
     | 
    
         
             
                    end
         
     | 
| 
       234 
255 
     | 
    
         
             
                  end
         
     | 
| 
       235 
256 
     | 
    
         | 
| 
      
 257 
     | 
    
         
            +
                  # Return whether the json object can be parsed as JSON.
         
     | 
| 
      
 258 
     | 
    
         
            +
                  #
         
     | 
| 
      
 259 
     | 
    
         
            +
                  # Options:
         
     | 
| 
      
 260 
     | 
    
         
            +
                  # :type :: Check whether the json object can be parsed as a specific type
         
     | 
| 
      
 261 
     | 
    
         
            +
                  #          of JSON (:value, :scalar, :object, :array).
         
     | 
| 
      
 262 
     | 
    
         
            +
                  # :unique :: Check JSON objects for unique keys.
         
     | 
| 
      
 263 
     | 
    
         
            +
                  #
         
     | 
| 
      
 264 
     | 
    
         
            +
                  #   json_op.is_json                 # json IS JSON
         
     | 
| 
      
 265 
     | 
    
         
            +
                  #   json_op.is_json(type: :object)  # json IS JSON OBJECT
         
     | 
| 
      
 266 
     | 
    
         
            +
                  #   json_op.is_json(unique: true)   # json IS JSON WITH UNIQUE
         
     | 
| 
      
 267 
     | 
    
         
            +
                  def is_json(opts=OPTS)
         
     | 
| 
      
 268 
     | 
    
         
            +
                    _is_json(IS_JSON, opts)
         
     | 
| 
      
 269 
     | 
    
         
            +
                  end
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  # Return whether the json object cannot be parsed as JSON. The opposite
         
     | 
| 
      
 272 
     | 
    
         
            +
                  # of #is_json. See #is_json for options.
         
     | 
| 
      
 273 
     | 
    
         
            +
                  #
         
     | 
| 
      
 274 
     | 
    
         
            +
                  #   json_op.is_not_json                 # json IS NOT JSON
         
     | 
| 
      
 275 
     | 
    
         
            +
                  #   json_op.is_not_json(type: :object)  # json IS NOT JSON OBJECT
         
     | 
| 
      
 276 
     | 
    
         
            +
                  #   json_op.is_not_json(unique: true)   # json IS NOT JSON WITH UNIQUE
         
     | 
| 
      
 277 
     | 
    
         
            +
                  def is_not_json(opts=OPTS)
         
     | 
| 
      
 278 
     | 
    
         
            +
                    _is_json(IS_NOT_JSON, opts)
         
     | 
| 
      
 279 
     | 
    
         
            +
                  end
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
       236 
281 
     | 
    
         
             
                  # Returns a set of keys AS text in the json object.
         
     | 
| 
       237 
282 
     | 
    
         
             
                  #
         
     | 
| 
       238 
283 
     | 
    
         
             
                  #   json_op.keys # json_object_keys(json)
         
     | 
| 
         @@ -286,6 +331,13 @@ module Sequel 
     | 
|
| 
       286 
331 
     | 
    
         | 
| 
       287 
332 
     | 
    
         
             
                  private
         
     | 
| 
       288 
333 
     | 
    
         | 
| 
      
 334 
     | 
    
         
            +
                  # Internals of IS [NOT] JSON support
         
     | 
| 
      
 335 
     | 
    
         
            +
                  def _is_json(lit_array, opts)
         
     | 
| 
      
 336 
     | 
    
         
            +
                    raise Error, "invalid is_json :type option: #{opts[:type].inspect}" unless type = IS_JSON_MAP[opts[:type]]
         
     | 
| 
      
 337 
     | 
    
         
            +
                    unique = opts[:unique] ? WITH_UNIQUE : EMPTY_STRING
         
     | 
| 
      
 338 
     | 
    
         
            +
                    Sequel::SQL::BooleanExpression.new(:NOOP, Sequel::SQL::PlaceholderLiteralString.new(lit_array, [self, type, unique]))
         
     | 
| 
      
 339 
     | 
    
         
            +
                  end
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
       289 
341 
     | 
    
         
             
                  # Return a placeholder literal with the given str and args, wrapped
         
     | 
| 
       290 
342 
     | 
    
         
             
                  # in an JSONOp or JSONBOp, used by operators that return json or jsonb.
         
     | 
| 
       291 
343 
     | 
    
         
             
                  def json_op(str, args)
         
     | 
| 
         @@ -325,7 +325,7 @@ module Sequel 
     | 
|
| 
       325 
325 
     | 
    
         
             
                #   DB.alter_table(:ce_test) do
         
     | 
| 
       326 
326 
     | 
    
         
             
                #     c = Sequel[:encrypted_column_name]
         
     | 
| 
       327 
327 
     | 
    
         
             
                #     add_constraint(:enc_base64) do
         
     | 
| 
       328 
     | 
    
         
            -
                #       octet_length(decode(regexp_replace(regexp_replace(c, '_', '/', 'g'), '-', '+', 'g'), 'base64')) >= 65 
     | 
| 
      
 328 
     | 
    
         
            +
                #       octet_length(decode(regexp_replace(regexp_replace(c, '_', '/', 'g'), '-', '+', 'g'), 'base64')) >= 65
         
     | 
| 
       329 
329 
     | 
    
         
             
                #     end
         
     | 
| 
       330 
330 
     | 
    
         
             
                #   end
         
     | 
| 
       331 
331 
     | 
    
         
             
                #
         
     | 
    
        data/lib/sequel/version.rb
    CHANGED
    
    | 
         @@ -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 =  
     | 
| 
      
 9 
     | 
    
         
            +
              MINOR = 75
         
     | 
| 
       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. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.75.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: 2023- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-12-01 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: bigdecimal
         
     | 
| 
         @@ -220,6 +220,8 @@ extra_rdoc_files: 
     | 
|
| 
       220 
220 
     | 
    
         
             
            - doc/release_notes/5.71.0.txt
         
     | 
| 
       221 
221 
     | 
    
         
             
            - doc/release_notes/5.72.0.txt
         
     | 
| 
       222 
222 
     | 
    
         
             
            - doc/release_notes/5.73.0.txt
         
     | 
| 
      
 223 
     | 
    
         
            +
            - doc/release_notes/5.74.0.txt
         
     | 
| 
      
 224 
     | 
    
         
            +
            - doc/release_notes/5.75.0.txt
         
     | 
| 
       223 
225 
     | 
    
         
             
            - doc/release_notes/5.8.0.txt
         
     | 
| 
       224 
226 
     | 
    
         
             
            - doc/release_notes/5.9.0.txt
         
     | 
| 
       225 
227 
     | 
    
         
             
            files:
         
     | 
| 
         @@ -321,6 +323,8 @@ files: 
     | 
|
| 
       321 
323 
     | 
    
         
             
            - doc/release_notes/5.71.0.txt
         
     | 
| 
       322 
324 
     | 
    
         
             
            - doc/release_notes/5.72.0.txt
         
     | 
| 
       323 
325 
     | 
    
         
             
            - doc/release_notes/5.73.0.txt
         
     | 
| 
      
 326 
     | 
    
         
            +
            - doc/release_notes/5.74.0.txt
         
     | 
| 
      
 327 
     | 
    
         
            +
            - doc/release_notes/5.75.0.txt
         
     | 
| 
       324 
328 
     | 
    
         
             
            - doc/release_notes/5.8.0.txt
         
     | 
| 
       325 
329 
     | 
    
         
             
            - doc/release_notes/5.9.0.txt
         
     | 
| 
       326 
330 
     | 
    
         
             
            - doc/schema_modification.rdoc
         
     |