sequel 5.58.0 → 5.59.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 +18 -0
- data/doc/opening_databases.rdoc +4 -5
- data/doc/release_notes/5.59.0.txt +73 -0
- data/lib/sequel/adapters/postgres.rb +12 -6
- data/lib/sequel/adapters/shared/postgres.rb +10 -1
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +3 -0
- data/lib/sequel/extensions/pg_json_ops.rb +52 -0
- data/lib/sequel/model/associations.rb +12 -0
- data/lib/sequel/model/base.rb +14 -4
- data/lib/sequel/plugins/list.rb +3 -1
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -0
- data/lib/sequel/version.rb +1 -1
- metadata +5 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 47d7144911d61be13cc600fc3153c8e30eb384476ea7fb94ce61bd0f2f627c36
         | 
| 4 | 
            +
              data.tar.gz: fa763e2f24d5b6b26feecb405b5a43d8bbf30d2b727590e8fd98031640dfef2a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3855f6fbb47f26bfd0e9570ed8b7e908815bc7de3752751b92708c3e88948719f62dafe26cc1ea83b598c73e1ee84e4dbf12f01437dd1b087eed68ca4281b33d
         | 
| 7 | 
            +
              data.tar.gz: 932fa5c97bc8dcf077a50961b2da7ecd59ae0c077409c2b0c3111d875fe468d5fbb4030f155faf17d3ba3ed0392e264d8e5ebaa11ad04db3ab98c209e2199440
         | 
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,21 @@ | |
| 1 | 
            +
            === 5.59.0 (2022-08-01)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Set :allow_eager association option to false for instance specific associations without eager loaders (jeremyevans)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Add require_valid_schema plugin for checking that model classes have schema parsed as expected (jeremyevans)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Model classes created from aliased expressions and literal strings no longer use the simple table optimization (jeremyevans)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Model code that does not swallow connection errors will now also not swallow disconnect errors (jeremyevans) (#1892)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Add is_json and is_not_json methods to the pg_json_ops extension, for the PostgreSQL 15+ IS [NOT] JSON operator (jeremyevans)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Support :security_invoker view option on PostgreSQL 15+, for views where access uses permissions of user instead of owner (jeremyevans)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * Support :nulls_distinct index option on PostgreSQL 15+, for NULLS [NOT] DISTINCT (jeremyevans)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Support sequel-postgres-pr driver in the postgres adapter (jeremyevans)
         | 
| 18 | 
            +
             | 
| 1 19 | 
             
            === 5.58.0 (2022-07-01)
         | 
| 2 20 |  | 
| 3 21 | 
             
            * Support :disable_split_materialized Database option on MySQL to work around optimizer bug in MariaDB 10.5+ affecting association tests (jeremyevans)
         | 
    
        data/doc/opening_databases.rdoc
    CHANGED
    
    | @@ -312,15 +312,14 @@ The following additional options are supported: | |
| 312 312 |  | 
| 313 313 | 
             
            === postgres
         | 
| 314 314 |  | 
| 315 | 
            -
            Requires: pg (or postgres-pr/postgres-compat if pg is not available)
         | 
| 315 | 
            +
            Requires: pg (or sequel/postgres-pr or postgres-pr/postgres-compat if pg is not available)
         | 
| 316 316 |  | 
| 317 | 
            -
            The Sequel postgres adapter works with the pg and postgres-pr ruby libraries.
         | 
| 317 | 
            +
            The Sequel postgres adapter works with the pg, sequel-postgres-pr, jeremyevans-postgres-pr, and postgres-pr ruby libraries.
         | 
| 318 318 | 
             
            The pg library is the best supported, as it supports real bound variables and prepared statements.
         | 
| 319 319 | 
             
            If the pg library is being used, Sequel will also attempt to load the sequel_pg library, which is
         | 
| 320 320 | 
             
            a C extension that optimizes performance when Sequel is used with pg.  All users of Sequel who
         | 
| 321 | 
            -
            use pg are encouraged to install sequel_pg.  For users who want to use postgres-pr | 
| 322 | 
            -
            with C extensions, it is recommended to use  | 
| 323 | 
            -
            the upstream postgres-pr gem, and is regularly tested with Sequel.
         | 
| 321 | 
            +
            use pg are encouraged to install sequel_pg.  For users who want to use one of the postgres-pr
         | 
| 322 | 
            +
            libraries to avoid issues with C extensions, it is recommended to use sequel-postgres-pr.
         | 
| 324 323 |  | 
| 325 324 | 
             
            The following additional options are supported:
         | 
| 326 325 |  | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            = New Features
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * A require_valid_schema plugin has been added, for checking that
         | 
| 4 | 
            +
              model classes have schema parsed as expected.  By default, model
         | 
| 5 | 
            +
              classes are not required to have valid schema, because it is
         | 
| 6 | 
            +
              allowed to have model classes based on arbitrary datasets (such
         | 
| 7 | 
            +
              as those using joins or set-returning functions), and it is not
         | 
| 8 | 
            +
              possible to determine the schema for arbitary datasets.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              Sequel swallows non-connection errors when trying to parse schema
         | 
| 11 | 
            +
              for a model's dataset, but if schema parsing fails when you would
         | 
| 12 | 
            +
              expect it to succeed, it results in a model where typecasting does
         | 
| 13 | 
            +
              not work as expected.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              The require_valid_schema plugin will raise an error when setting
         | 
| 16 | 
            +
              the dataset for a model if schema parsing fails and the dataset
         | 
| 17 | 
            +
              uses a simple table where you would expect schema parsing to
         | 
| 18 | 
            +
              succeed.  You can also provide an argument of :warn when loading
         | 
| 19 | 
            +
              the plugin, to warn instead of raising an error.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              This plugin may not work correctly in all cases for all adapters,
         | 
| 22 | 
            +
              especially external adapters. Adapters are not required to support
         | 
| 23 | 
            +
              schema parsing.  Even if supported, adapters may not support
         | 
| 24 | 
            +
              parsing schema for qualified tables, or parsing schema for views.
         | 
| 25 | 
            +
              You should consider this plugin as a possible safety net.  Users
         | 
| 26 | 
            +
              are encouraged to try using it and report any unexpected breakage,
         | 
| 27 | 
            +
              as that may help improve schema parsing in adapters that Sequel
         | 
| 28 | 
            +
              ships.
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            * is_json and is_not_json methods have been added to the pg_json_ops
         | 
| 31 | 
            +
              extension, for the IS [NOT] JSON operator supported in PostgreSQL
         | 
| 32 | 
            +
              15+.
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            * Index creation methods on PostgreSQL 15+ now support a
         | 
| 35 | 
            +
              :nulls_distinct option, for NULLS [NOT] DISTINCT.  This allows you
         | 
| 36 | 
            +
              to create unique indexes where NULL values are not considered
         | 
| 37 | 
            +
              distinct.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            * View creation methods on PostgreSQL 15+ now support a
         | 
| 40 | 
            +
              :security_invoker option to create a view where access is
         | 
| 41 | 
            +
              determined by the permissions of the role that is accessing the
         | 
| 42 | 
            +
              view, instead of the role that created the view.
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            = Other Improvements
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            * The :allow_eager association option is now set to false by default
         | 
| 47 | 
            +
              for associations explicitly marked as :instance_specific, if the
         | 
| 48 | 
            +
              :eager_loader association is not given.
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
            * The postgres adapter now supports the sequel-postgres-pr driver.
         | 
| 51 | 
            +
              The sequel-postgres-pr driver is a slimmed down fork of the
         | 
| 52 | 
            +
              postgres-pr driver designed specifically for use by Sequel.
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            * Model code that explicitly does not swallow connection errors
         | 
| 55 | 
            +
              will also now not swallow disconnect errors. This can fix issues
         | 
| 56 | 
            +
              where model classes are being loaded at runtime, and the query to
         | 
| 57 | 
            +
              get the columns/schema for the model uses a connection that has
         | 
| 58 | 
            +
              been disconnected.
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            * Model classes created from aliased expressions and literal
         | 
| 61 | 
            +
              strings no longer use the simple_table optimization, as there
         | 
| 62 | 
            +
              are cases where doing so is not safe.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            = Backwards Compatibility
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            * The change to not swallow disconnect errors when not swallowing
         | 
| 67 | 
            +
              connection errors can result in exceptions being raised which
         | 
| 68 | 
            +
              weren't raised previously.  In most cases, this will alert you
         | 
| 69 | 
            +
              to issues in your application that should be fixed, but it
         | 
| 70 | 
            +
              potentially it can result in regressions if you were OK with
         | 
| 71 | 
            +
              the errors being swallowed.  If this does result in regressions
         | 
| 72 | 
            +
              in your application, please file an issue and we can probably
         | 
| 73 | 
            +
              add a setting controlling this feature.
         | 
| @@ -23,16 +23,20 @@ begin | |
| 23 23 | 
             
              end
         | 
| 24 24 | 
             
            rescue LoadError => e 
         | 
| 25 25 | 
             
              begin
         | 
| 26 | 
            -
                require 'postgres-pr | 
| 27 | 
            -
                Sequel::Postgres::USES_PG = false
         | 
| 26 | 
            +
                require 'sequel/postgres-pr'
         | 
| 28 27 | 
             
              rescue LoadError 
         | 
| 29 | 
            -
                 | 
| 28 | 
            +
                begin
         | 
| 29 | 
            +
                  require 'postgres-pr/postgres-compat'
         | 
| 30 | 
            +
                rescue LoadError 
         | 
| 31 | 
            +
                  raise e 
         | 
| 32 | 
            +
                end 
         | 
| 30 33 | 
             
              end 
         | 
| 34 | 
            +
              Sequel::Postgres::USES_PG = false
         | 
| 31 35 | 
             
            end
         | 
| 32 36 |  | 
| 33 37 | 
             
            module Sequel
         | 
| 34 38 | 
             
              module Postgres
         | 
| 35 | 
            -
                if  | 
| 39 | 
            +
                if USES_PG
         | 
| 36 40 | 
             
                  # Whether the given sequel_pg version integer is supported.
         | 
| 37 41 | 
             
                  def self.sequel_pg_version_supported?(version)
         | 
| 38 42 | 
             
                    version >= 10617
         | 
| @@ -74,8 +78,10 @@ module Sequel | |
| 74 78 | 
             
                    unless public_method_defined?(:async_exec_params)
         | 
| 75 79 | 
             
                      alias async_exec_params async_exec
         | 
| 76 80 | 
             
                    end
         | 
| 77 | 
            -
                   | 
| 78 | 
            -
                    #  | 
| 81 | 
            +
                  elsif !const_defined?(:CONNECTION_OK)
         | 
| 82 | 
            +
                    # Handle old postgres-pr
         | 
| 83 | 
            +
                    # sequel-postgres-pr already implements this API
         | 
| 84 | 
            +
             | 
| 79 85 | 
             
                    CONNECTION_OK = -1
         | 
| 80 86 |  | 
| 81 87 | 
             
                    # Escape bytea values.  Uses historical format instead of hex
         | 
| @@ -1247,6 +1247,10 @@ module Sequel | |
| 1247 1247 | 
             
                  def create_view_prefix_sql(name, options)
         | 
| 1248 1248 | 
             
                    sql = create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
         | 
| 1249 1249 |  | 
| 1250 | 
            +
                    if options[:security_invoker]
         | 
| 1251 | 
            +
                      sql += " WITH (security_invoker)"
         | 
| 1252 | 
            +
                    end
         | 
| 1253 | 
            +
             | 
| 1250 1254 | 
             
                    if tablespace = options[:tablespace]
         | 
| 1251 1255 | 
             
                      sql += " TABLESPACE #{quote_identifier(tablespace)}"
         | 
| 1252 1256 | 
             
                    end
         | 
| @@ -1304,16 +1308,20 @@ module Sequel | |
| 1304 1308 | 
             
                  def index_definition_sql(table_name, index)
         | 
| 1305 1309 | 
             
                    cols = index[:columns]
         | 
| 1306 1310 | 
             
                    index_name = index[:name] || default_index_name(table_name, cols)
         | 
| 1311 | 
            +
             | 
| 1307 1312 | 
             
                    expr = if o = index[:opclass]
         | 
| 1308 1313 | 
             
                      "(#{Array(cols).map{|c| "#{literal(c)} #{o}"}.join(', ')})"
         | 
| 1309 1314 | 
             
                    else
         | 
| 1310 1315 | 
             
                      literal(Array(cols))
         | 
| 1311 1316 | 
             
                    end
         | 
| 1317 | 
            +
             | 
| 1312 1318 | 
             
                    if_not_exists = " IF NOT EXISTS" if index[:if_not_exists]
         | 
| 1313 1319 | 
             
                    unique = "UNIQUE " if index[:unique]
         | 
| 1314 1320 | 
             
                    index_type = index[:type]
         | 
| 1315 1321 | 
             
                    filter = index[:where] || index[:filter]
         | 
| 1316 1322 | 
             
                    filter = " WHERE #{filter_expr(filter)}" if filter
         | 
| 1323 | 
            +
                    nulls_distinct = " NULLS#{' NOT' if index[:nulls_distinct] == false} DISTINCT" unless index[:nulls_distinct].nil?
         | 
| 1324 | 
            +
             | 
| 1317 1325 | 
             
                    case index_type
         | 
| 1318 1326 | 
             
                    when :full_text
         | 
| 1319 1327 | 
             
                      expr = "(to_tsvector(#{literal(index[:language] || 'simple')}::regconfig, #{literal(dataset.send(:full_text_string_join, cols))}))"
         | 
| @@ -1321,7 +1329,8 @@ module Sequel | |
| 1321 1329 | 
             
                    when :spatial
         | 
| 1322 1330 | 
             
                      index_type = :gist
         | 
| 1323 1331 | 
             
                    end
         | 
| 1324 | 
            -
             | 
| 1332 | 
            +
             | 
| 1333 | 
            +
                    "CREATE #{unique}INDEX#{' CONCURRENTLY' if index[:concurrently]}#{if_not_exists} #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{"USING #{index_type} " if index_type}#{expr}#{" INCLUDE #{literal(Array(index[:include]))}" if index[:include]}#{nulls_distinct}#{" TABLESPACE #{quote_identifier(index[:tablespace])}" if index[:tablespace]}#{filter}"
         | 
| 1325 1334 | 
             
                  end
         | 
| 1326 1335 |  | 
| 1327 1336 | 
             
                  # Setup datastructures shared by all postgres adapters.
         | 
| @@ -262,6 +262,7 @@ module Sequel | |
| 262 262 | 
             
                  #                  operations on the table while the index is being
         | 
| 263 263 | 
             
                  #                  built.
         | 
| 264 264 | 
             
                  # :if_not_exists :: Only create the index if an index of the same name doesn't already exist.
         | 
| 265 | 
            +
                  # :nulls_distinct :: Set whether separate NULLs should be considered distinct values in unique indexes.
         | 
| 265 266 | 
             
                  # :opclass :: Set an opclass to use for all columns (per-column opclasses require
         | 
| 266 267 | 
             
                  #             custom SQL).
         | 
| 267 268 | 
             
                  # :tablespace :: Specify tablespace for index.
         | 
| @@ -295,6 +295,9 @@ module Sequel | |
| 295 295 | 
             
                #               in a subquery, if you are providing a Dataset as the source
         | 
| 296 296 | 
             
                #               argument, if should probably call the union method with the
         | 
| 297 297 | 
             
                #               all: true and from_self: false options.
         | 
| 298 | 
            +
                # :security_invoker :: Set the security_invoker property on the view, making
         | 
| 299 | 
            +
                #                      the access to the view use the current user's permissions,
         | 
| 300 | 
            +
                #                      instead of the view owner's permissions.
         | 
| 298 301 | 
             
                # :tablespace :: The tablespace to use for materialized views.
         | 
| 299 302 | 
             
                def create_view(name, source, options = OPTS)
         | 
| 300 303 | 
             
                  execute_ddl(create_view_sql(name, source, options))
         | 
| @@ -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 15+, 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_json(type: :array)                # j IS NOT JSON ARRAY
         | 
| 133 | 
            +
            #   j.is_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)
         | 
| @@ -1717,6 +1717,8 @@ module Sequel | |
| 1717 1717 | 
             
                    # :graph_select :: A column or array of columns to select from the associated table
         | 
| 1718 1718 | 
             
                    #                  when eagerly loading the association via +eager_graph+. Defaults to all
         | 
| 1719 1719 | 
             
                    #                  columns in the associated table.
         | 
| 1720 | 
            +
                    # :instance_specific :: Marks the association as instance specific. Should be used if the association block
         | 
| 1721 | 
            +
                    #                       uses instance specific state, or transient state (accessing current date/time, etc.).
         | 
| 1720 1722 | 
             
                    # :limit :: Limit the number of records to the provided value.  Use
         | 
| 1721 1723 | 
             
                    #           an array with two elements for the value to specify a
         | 
| 1722 1724 | 
             
                    #           limit (first element) and an offset (second element).
         | 
| @@ -1856,6 +1858,16 @@ module Sequel | |
| 1856 1858 | 
             
                        # in certain places to disable optimizations.
         | 
| 1857 1859 | 
             
                        opts[:instance_specific] = _association_instance_specific_default(name)
         | 
| 1858 1860 | 
             
                      end
         | 
| 1861 | 
            +
                      if (orig_opts[:instance_specific] || orig_opts[:dataset]) && !opts.has_key?(:allow_eager) && !opts[:eager_loader]
         | 
| 1862 | 
            +
                        # For associations explicitly marked as instance specific, or that use the
         | 
| 1863 | 
            +
                        # :dataset option, where :allow_eager is not set, and no :eager_loader is
         | 
| 1864 | 
            +
                        # provided, disallow eager loading.  In these cases, eager loading is
         | 
| 1865 | 
            +
                        # unlikely to work.  This is not done for implicit setting of :instance_specific,
         | 
| 1866 | 
            +
                        # because implicit use is done by default for all associations with blocks,
         | 
| 1867 | 
            +
                        # and the vast majority of associations with blocks use the block for filtering
         | 
| 1868 | 
            +
                        # in a manner compatible with eager loading.
         | 
| 1869 | 
            +
                        opts[:allow_eager] = false
         | 
| 1870 | 
            +
                      end
         | 
| 1859 1871 | 
             
                      opts = assoc_class.new.merge!(opts)
         | 
| 1860 1872 |  | 
| 1861 1873 | 
             
                      if opts[:clone] && !opts.cloneable?(cloned_assoc)
         | 
    
        data/lib/sequel/model/base.rb
    CHANGED
    
    | @@ -680,10 +680,11 @@ module Sequel | |
| 680 680 |  | 
| 681 681 | 
             
                  private
         | 
| 682 682 |  | 
| 683 | 
            -
                  # Yield to the passed block and if do_raise is false, swallow  | 
| 683 | 
            +
                  # Yield to the passed block and if do_raise is false, swallow Sequel::Errors other than DatabaseConnectionError
         | 
| 684 | 
            +
                  # and DatabaseDisconnectError.
         | 
| 684 685 | 
             
                  def check_non_connection_error(do_raise=require_valid_table)
         | 
| 685 686 | 
             
                    db.transaction(:savepoint=>:only){yield}
         | 
| 686 | 
            -
                  rescue Sequel::DatabaseConnectionError
         | 
| 687 | 
            +
                  rescue Sequel::DatabaseConnectionError, Sequel::DatabaseDisconnectError
         | 
| 687 688 | 
             
                    raise
         | 
| 688 689 | 
             
                  rescue Sequel::Error
         | 
| 689 690 | 
             
                    raise if do_raise
         | 
| @@ -693,9 +694,12 @@ module Sequel | |
| 693 694 | 
             
                  # this model's dataset.
         | 
| 694 695 | 
             
                  def convert_input_dataset(ds)
         | 
| 695 696 | 
             
                    case ds
         | 
| 696 | 
            -
                    when Symbol, SQL::Identifier, SQL::QualifiedIdentifier | 
| 697 | 
            +
                    when Symbol, SQL::Identifier, SQL::QualifiedIdentifier
         | 
| 697 698 | 
             
                      self.simple_table = db.literal(ds).freeze
         | 
| 698 699 | 
             
                      ds = db.from(ds)
         | 
| 700 | 
            +
                    when SQL::AliasedExpression, LiteralString
         | 
| 701 | 
            +
                      self.simple_table = nil
         | 
| 702 | 
            +
                      ds = db.from(ds)
         | 
| 699 703 | 
             
                    when Dataset
         | 
| 700 704 | 
             
                      ds = ds.from_self(:alias=>ds.first_source) if ds.joined_dataset?
         | 
| 701 705 |  | 
| @@ -784,7 +788,7 @@ module Sequel | |
| 784 788 | 
             
                    schema_hash = {}
         | 
| 785 789 | 
             
                    ds_opts = dataset.opts
         | 
| 786 790 | 
             
                    get_columns = proc{check_non_connection_error{columns} || []}
         | 
| 787 | 
            -
                    schema_array =  | 
| 791 | 
            +
                    schema_array = get_db_schema_array(reload) if db.supports_schema_parsing?
         | 
| 788 792 | 
             
                    if schema_array
         | 
| 789 793 | 
             
                      schema_array.each{|k,v| schema_hash[k] = v}
         | 
| 790 794 |  | 
| @@ -821,6 +825,12 @@ module Sequel | |
| 821 825 | 
             
                    schema_hash
         | 
| 822 826 | 
             
                  end
         | 
| 823 827 |  | 
| 828 | 
            +
                  # Get the array of schema information for the dataset.  Returns nil if
         | 
| 829 | 
            +
                  # the schema information cannot be determined.
         | 
| 830 | 
            +
                  def get_db_schema_array(reload)
         | 
| 831 | 
            +
                    check_non_connection_error(false){db.schema(dataset, :reload=>reload)}
         | 
| 832 | 
            +
                  end
         | 
| 833 | 
            +
             | 
| 824 834 | 
             
                  # Uncached version of setter_methods, to be overridden by plugins
         | 
| 825 835 | 
             
                  # that want to modify the methods used.
         | 
| 826 836 | 
             
                  def get_setter_methods
         | 
    
        data/lib/sequel/plugins/list.rb
    CHANGED
    
    | @@ -33,7 +33,9 @@ module Sequel | |
| 33 33 | 
             
                # You can provide a <tt>:scope</tt> option to scope the list.  This option
         | 
| 34 34 | 
             
                # can be a symbol or array of symbols specifying column name(s), or a proc
         | 
| 35 35 | 
             
                # that accepts a model instance and returns a dataset representing the list
         | 
| 36 | 
            -
                # the object is in.
         | 
| 36 | 
            +
                # the object is in.  You will need to provide a <tt>:scope</tt> option if
         | 
| 37 | 
            +
                # the model's dataset uses a subquery (such as when using the class_table_inheritance
         | 
| 38 | 
            +
                # plugin).
         | 
| 37 39 | 
             
                # 
         | 
| 38 40 | 
             
                # For example, if each item has a +user_id+ field, and you want every user
         | 
| 39 41 | 
             
                # to have their own list:
         | 
| @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            # frozen-string-literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Sequel
         | 
| 4 | 
            +
              module Plugins
         | 
| 5 | 
            +
                # The require_valid_schema plugin makes Sequel raise or warn if attempting
         | 
| 6 | 
            +
                # to set the dataset of a model class to a simple table, where the database
         | 
| 7 | 
            +
                # supports schema parsing, but schema parsing does not work for the model's
         | 
| 8 | 
            +
                # table.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # The plugin's default behavior requires that all models that select from a
         | 
| 11 | 
            +
                # single identifier have a valid table schema, if the database supports
         | 
| 12 | 
            +
                # schema parsing. If the schema cannot be determined for such
         | 
| 13 | 
            +
                # a model, an error is raised:
         | 
| 14 | 
            +
                #   
         | 
| 15 | 
            +
                #   Sequel::Model.plugin :require_valid_schema
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                # If you load the plugin with an argument of :warn, Sequel will warn instead
         | 
| 18 | 
            +
                # of raising for such tables:
         | 
| 19 | 
            +
                #
         | 
| 20 | 
            +
                #   Sequel::Model.plugin :require_valid_schema, :warn
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # This can catch bugs where you expect models to have valid schema, but
         | 
| 23 | 
            +
                # they do not. This setting only affects future attempts to set datasets
         | 
| 24 | 
            +
                # in the current class and subclasses created in the future.
         | 
| 25 | 
            +
                #
         | 
| 26 | 
            +
                # If you load the plugin with an argument of false, it will not require valid schema.
         | 
| 27 | 
            +
                # This can be used in subclasses where you do not want to require valid schema,
         | 
| 28 | 
            +
                # but the plugin must be loaded before a dataset with invalid schema is set:
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                #   Sequel::Model.plugin :require_valid_schema
         | 
| 31 | 
            +
                #   InvalidSchemaAllowed = Class.new(Sequel::Model)
         | 
| 32 | 
            +
                #   InvalidSchemaAllowed.plugin :require_valid_schema, false
         | 
| 33 | 
            +
                #   class MyModel < InvalidSchemaAllowed
         | 
| 34 | 
            +
                #   end
         | 
| 35 | 
            +
                module RequireValidSchema
         | 
| 36 | 
            +
                  # Modify the current model's dataset selection, if the model
         | 
| 37 | 
            +
                  # has a dataset.
         | 
| 38 | 
            +
                  def self.configure(model, setting=true)
         | 
| 39 | 
            +
                    model.instance_variable_set(:@require_valid_schema, setting)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  module ClassMethods
         | 
| 43 | 
            +
                    Plugins.inherited_instance_variables(self, :@require_valid_schema=>nil)
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    # If the schema cannot be determined, the model uses a simple table,
         | 
| 48 | 
            +
                    # require_valid_schema is set, and the database supports schema parsing, raise or
         | 
| 49 | 
            +
                    # warn based on the require_valid_schema setting.
         | 
| 50 | 
            +
                    def get_db_schema_array(reload)
         | 
| 51 | 
            +
                      schema_array = super
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      if !schema_array && simple_table && @require_valid_schema
         | 
| 54 | 
            +
                        message = "Not able to parse schema for model: #{inspect}, table: #{simple_table}"
         | 
| 55 | 
            +
                        if @require_valid_schema == :warn
         | 
| 56 | 
            +
                          warn message
         | 
| 57 | 
            +
                        else
         | 
| 58 | 
            +
                          raise Error, message
         | 
| 59 | 
            +
                        end
         | 
| 60 | 
            +
                      end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                      schema_array
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
            end
         | 
| @@ -109,6 +109,13 @@ module Sequel | |
| 109 109 | 
             
                # to eagerly set the associated objects, and having separate threads
         | 
| 110 110 | 
             
                # modify the same model instance is not thread-safe.
         | 
| 111 111 | 
             
                #
         | 
| 112 | 
            +
                # Because this plugin will automatically use eager loading for
         | 
| 113 | 
            +
                # performance, it can break code that defines associations that
         | 
| 114 | 
            +
                # do not support eager loading, without marking that they do not
         | 
| 115 | 
            +
                # support eager loading via the <tt>allow_eager: false</tt> option.
         | 
| 116 | 
            +
                # Make sure to set <tt>allow_eager: false</tt> on any association
         | 
| 117 | 
            +
                # used with this plugin if the association doesn't support eager loading.
         | 
| 118 | 
            +
                #
         | 
| 112 119 | 
             
                # Usage:
         | 
| 113 120 | 
             
                #
         | 
| 114 121 | 
             
                #   # Make all model subclass instances use tactical eager loading (called before loading subclasses)
         | 
    
        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 = 59
         | 
| 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.59.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: 2022- | 
| 11 | 
            +
            date: 2022-08-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: minitest
         | 
| @@ -189,6 +189,7 @@ extra_rdoc_files: | |
| 189 189 | 
             
            - doc/release_notes/5.56.0.txt
         | 
| 190 190 | 
             
            - doc/release_notes/5.57.0.txt
         | 
| 191 191 | 
             
            - doc/release_notes/5.58.0.txt
         | 
| 192 | 
            +
            - doc/release_notes/5.59.0.txt
         | 
| 192 193 | 
             
            - doc/release_notes/5.6.0.txt
         | 
| 193 194 | 
             
            - doc/release_notes/5.7.0.txt
         | 
| 194 195 | 
             
            - doc/release_notes/5.8.0.txt
         | 
| @@ -275,6 +276,7 @@ files: | |
| 275 276 | 
             
            - doc/release_notes/5.56.0.txt
         | 
| 276 277 | 
             
            - doc/release_notes/5.57.0.txt
         | 
| 277 278 | 
             
            - doc/release_notes/5.58.0.txt
         | 
| 279 | 
            +
            - doc/release_notes/5.59.0.txt
         | 
| 278 280 | 
             
            - doc/release_notes/5.6.0.txt
         | 
| 279 281 | 
             
            - doc/release_notes/5.7.0.txt
         | 
| 280 282 | 
             
            - doc/release_notes/5.8.0.txt
         | 
| @@ -527,6 +529,7 @@ files: | |
| 527 529 | 
             
            - lib/sequel/plugins/prepared_statements.rb
         | 
| 528 530 | 
             
            - lib/sequel/plugins/prepared_statements_safe.rb
         | 
| 529 531 | 
             
            - lib/sequel/plugins/rcte_tree.rb
         | 
| 532 | 
            +
            - lib/sequel/plugins/require_valid_schema.rb
         | 
| 530 533 | 
             
            - lib/sequel/plugins/serialization.rb
         | 
| 531 534 | 
             
            - lib/sequel/plugins/serialization_modification_detection.rb
         | 
| 532 535 | 
             
            - lib/sequel/plugins/sharding.rb
         |