sequel 5.33.0 → 5.34.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/release_notes/5.34.0.txt +40 -0
 - data/lib/sequel/connection_pool/sharded_single.rb +4 -1
 - data/lib/sequel/connection_pool/sharded_threaded.rb +10 -10
 - data/lib/sequel/connection_pool/single.rb +1 -1
 - data/lib/sequel/connection_pool/threaded.rb +1 -1
 - data/lib/sequel/database/connecting.rb +1 -1
 - data/lib/sequel/database/misc.rb +16 -10
 - data/lib/sequel/database/query.rb +2 -0
 - data/lib/sequel/database/schema_generator.rb +0 -1
 - data/lib/sequel/database/schema_methods.rb +15 -16
 - data/lib/sequel/database/transactions.rb +7 -4
 - data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
 - data/lib/sequel/dataset/query.rb +4 -3
 - data/lib/sequel/deprecated.rb +2 -0
 - data/lib/sequel/exceptions.rb +2 -0
 - data/lib/sequel/model.rb +2 -0
 - data/lib/sequel/model/associations.rb +12 -13
 - data/lib/sequel/model/base.rb +5 -3
 - data/lib/sequel/model/plugins.rb +2 -3
 - data/lib/sequel/plugins/association_pks.rb +57 -16
 - data/lib/sequel/plugins/rcte_tree.rb +2 -2
 - data/lib/sequel/version.rb +1 -1
 - metadata +4 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 6c87a14904ac28bee61ed778628cc68f7c7318d6cb2f7c1f8aeeaab0ac2e7f22
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 3fdbda6fce44c6a0d168cc7fe0fe3a2e269ef668397ec1f4289120231006e51f
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 012717171d1b9aded574e16ba2670c95ccb87ef365b68bcee18b1e6730e5ce04425eaeca3be563c5ba416d2691ed83526bcb5254275b6484526856d0cadf14d1
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 02f430fa24d8b61905192a8f387421b28d877978fcd5ce05fdb5f0768b93a6f7771c02ed445c937863b30f24121ad9fae73c8303293bc7475621f077792b3f78
         
     | 
    
        data/CHANGELOG
    CHANGED
    
    | 
         @@ -1,3 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 5.34.0 (2020-07-01)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Make eager_graph work correctly if called with no associations (jeremyevans)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Make :ruby eager limit strategy handle cases where there is no limit or offset (jeremyevans)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Do not keep a reference to a Sequel::Database instance that raises an exception during initialization (jeremyevans)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Make Database#pool.all_connections not yield for a single connection pool in disconnected state (jeremyevans)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * Raise an exception if trying to disconnect a server that doesn't exist in the sharded connection pools (jeremyevans)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * Support :refresh option when calling *_pks getter method in the association_pks plugin (jeremyevans)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * Support caching of repeated calls to *_pks getter method in the association_pks plugin using :cache_pks association option (jeremyevans)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * Add *_pks_dataset methods for one_to_many and many_to_many associations when using the association_pks plugin (jeremyevans)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       1 
19 
     | 
    
         
             
            === 5.33.0 (2020-06-01)
         
     | 
| 
       2 
20 
     | 
    
         | 
| 
       3 
21 
     | 
    
         
             
            * Support custom join types on a per-association basis when using eager_graph/association_join (jeremyevans)
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = New Features
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * The association_pks plugin now creates *_pks_dataset methods for
         
     | 
| 
      
 4 
     | 
    
         
            +
              each association.  These are similar to the existing *_pks getter
         
     | 
| 
      
 5 
     | 
    
         
            +
              methods, but they return a dataset of the keys instead of the keys
         
     | 
| 
      
 6 
     | 
    
         
            +
              themselves.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            * The association_pks plugin now supports a :cache_pks association
         
     | 
| 
      
 9 
     | 
    
         
            +
              option, which will cache calls to the *_pks getter method. The
         
     | 
| 
      
 10 
     | 
    
         
            +
              default behavior remains that the *_pks getter method only returns
         
     | 
| 
      
 11 
     | 
    
         
            +
              cached values if the *_pks= setter method has been used to set the
         
     | 
| 
      
 12 
     | 
    
         
            +
              values.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            * The *_pks getter methods supported by the association_pks plugin
         
     | 
| 
      
 15 
     | 
    
         
            +
              now support a :refresh option to ignore any cached values, similar
         
     | 
| 
      
 16 
     | 
    
         
            +
              to how the association getter methods work.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            = Other Improvements
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            * If trying to disconnect a server that doesn't exist when using a
         
     | 
| 
      
 21 
     | 
    
         
            +
              sharded connection pool, a Sequel::Error is now raised.  Previously,
         
     | 
| 
      
 22 
     | 
    
         
            +
              the sharded threaded pool raised a NoMethodError and the sharded
         
     | 
| 
      
 23 
     | 
    
         
            +
              single connection pool did not raise an error.
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            * If using the :savepoint option when savepoints are not supported,
         
     | 
| 
      
 26 
     | 
    
         
            +
              a Sequel::InvalidOperation exception is now raised, instead of a
         
     | 
| 
      
 27 
     | 
    
         
            +
              NoMethodError.
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            * Calling Dataset#eager_graph with no arguments now returns the
         
     | 
| 
      
 30 
     | 
    
         
            +
              dataset.
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            * If not connected to the database, the single connection pool will
         
     | 
| 
      
 33 
     | 
    
         
            +
              not yield any connections to Database#pool.all_connections.
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            * Forcing a :ruby eager limit strategy for an association without a
         
     | 
| 
      
 36 
     | 
    
         
            +
              limit or offset now works correctly.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            * Multiple unnecessary conditionals have been removed.
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            * Sequel core and model code now have 100% branch coverage.
         
     | 
| 
         @@ -41,7 +41,10 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool 
     | 
|
| 
       41 
41 
     | 
    
         
             
              # :server :: Should be a symbol specifing the server to disconnect from,
         
     | 
| 
       42 
42 
     | 
    
         
             
              #            or an array of symbols to specify multiple servers.
         
     | 
| 
       43 
43 
     | 
    
         
             
              def disconnect(opts=OPTS)
         
     | 
| 
       44 
     | 
    
         
            -
                (opts[:server] ? Array(opts[:server]) : servers).each 
     | 
| 
      
 44 
     | 
    
         
            +
                (opts[:server] ? Array(opts[:server]) : servers).each do |s|
         
     | 
| 
      
 45 
     | 
    
         
            +
                  raise Sequel::Error, "invalid server: #{s}" unless @servers.has_key?(s)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  disconnect_server(s)
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
       45 
48 
     | 
    
         
             
              end
         
     | 
| 
       46 
49 
     | 
    
         | 
| 
       47 
50 
     | 
    
         
             
              def freeze
         
     | 
| 
         @@ -95,9 +95,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool 
     | 
|
| 
       95 
95 
     | 
    
         
             
              #            or an array of symbols to specify multiple servers.
         
     | 
| 
       96 
96 
     | 
    
         
             
              def disconnect(opts=OPTS)
         
     | 
| 
       97 
97 
     | 
    
         
             
                (opts[:server] ? Array(opts[:server]) : sync{@servers.keys}).each do |s|
         
     | 
| 
       98 
     | 
    
         
            -
                   
     | 
| 
       99 
     | 
    
         
            -
                    disconnect_connections(conns)
         
     | 
| 
       100 
     | 
    
         
            -
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  disconnect_connections(sync{disconnect_server_connections(s)})
         
     | 
| 
       101 
99 
     | 
    
         
             
                end
         
     | 
| 
       102 
100 
     | 
    
         
             
              end
         
     | 
| 
       103 
101 
     | 
    
         | 
| 
         @@ -203,9 +201,9 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool 
     | 
|
| 
       203 
201 
     | 
    
         | 
| 
       204 
202 
     | 
    
         
             
                until conn = assign_connection(thread, server)
         
     | 
| 
       205 
203 
     | 
    
         
             
                  elapsed = Sequel.elapsed_seconds_since(timer)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
       206 
205 
     | 
    
         
             
                  raise_pool_timeout(elapsed, server) if elapsed > timeout
         
     | 
| 
       207 
206 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
                  # :nocov:
         
     | 
| 
       209 
207 
     | 
    
         
             
                  # It's difficult to get to this point, it can only happen if there is a race condition
         
     | 
| 
       210 
208 
     | 
    
         
             
                  # where a connection cannot be acquired even after the thread is signalled by the condition variable
         
     | 
| 
       211 
209 
     | 
    
         
             
                  sync do
         
     | 
| 
         @@ -278,13 +276,15 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool 
     | 
|
| 
       278 
276 
     | 
    
         
             
              # Mark any allocated connections to be removed when they are checked back in. The calling
         
     | 
| 
       279 
277 
     | 
    
         
             
              # code should already have the mutex before calling this.
         
     | 
| 
       280 
278 
     | 
    
         
             
              def disconnect_server_connections(server)
         
     | 
| 
       281 
     | 
    
         
            -
                 
     | 
| 
      
 279 
     | 
    
         
            +
                remove_conns = allocated(server)
         
     | 
| 
      
 280 
     | 
    
         
            +
                dis_conns = available_connections(server)
         
     | 
| 
      
 281 
     | 
    
         
            +
                raise Sequel::Error, "invalid server: #{server}" unless remove_conns && dis_conns
         
     | 
| 
       282 
282 
     | 
    
         | 
| 
       283 
     | 
    
         
            -
                 
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
                 
     | 
| 
      
 283 
     | 
    
         
            +
                @connections_to_remove.concat(remove_conns.values)
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                conns = dis_conns.dup
         
     | 
| 
      
 286 
     | 
    
         
            +
                dis_conns.clear
         
     | 
| 
      
 287 
     | 
    
         
            +
                @waiters[server].signal
         
     | 
| 
       288 
288 
     | 
    
         
             
                conns
         
     | 
| 
       289 
289 
     | 
    
         
             
              end
         
     | 
| 
       290 
290 
     | 
    
         | 
| 
         @@ -11,7 +11,7 @@ class Sequel::SingleConnectionPool < Sequel::ConnectionPool 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
              # Yield the connection if one has been made.
         
     | 
| 
       13 
13 
     | 
    
         
             
              def all_connections
         
     | 
| 
       14 
     | 
    
         
            -
                yield @conn.first  
     | 
| 
      
 14 
     | 
    
         
            +
                yield @conn.first unless @conn.empty?
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
              # Disconnect the connection from the database.
         
     | 
| 
         @@ -152,9 +152,9 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool 
     | 
|
| 
       152 
152 
     | 
    
         | 
| 
       153 
153 
     | 
    
         
             
                until conn = assign_connection(thread)
         
     | 
| 
       154 
154 
     | 
    
         
             
                  elapsed = Sequel.elapsed_seconds_since(timer)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
       155 
156 
     | 
    
         
             
                  raise_pool_timeout(elapsed) if elapsed > timeout
         
     | 
| 
       156 
157 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                  # :nocov:
         
     | 
| 
       158 
158 
     | 
    
         
             
                  # It's difficult to get to this point, it can only happen if there is a race condition
         
     | 
| 
       159 
159 
     | 
    
         
             
                  # where a connection cannot be acquired even after the thread is signalled by the condition variable
         
     | 
| 
       160 
160 
     | 
    
         
             
                  sync do
         
     | 
| 
         @@ -36,7 +36,7 @@ module Sequel 
     | 
|
| 
       36 
36 
     | 
    
         
             
                      c = adapter_class(scheme)
         
     | 
| 
       37 
37 
     | 
    
         
             
                      uri_options = c.send(:uri_to_options, uri)
         
     | 
| 
       38 
38 
     | 
    
         
             
                      uri.query.split('&').map{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
         
     | 
| 
       39 
     | 
    
         
            -
                      uri_options.to_a.each{|k,v| uri_options[k] =  
     | 
| 
      
 39 
     | 
    
         
            +
                      uri_options.to_a.each{|k,v| uri_options[k] = URI::DEFAULT_PARSER.unescape(v) if v.is_a?(String)}
         
     | 
| 
       40 
40 
     | 
    
         
             
                      opts = uri_options.merge(opts).merge!(:orig_opts=>opts.dup, :uri=>conn_string, :adapter=>scheme)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    end
         
     | 
| 
       42 
42 
     | 
    
         
             
                  when Hash
         
     | 
    
        data/lib/sequel/database/misc.rb
    CHANGED
    
    | 
         @@ -153,19 +153,23 @@ module Sequel 
     | 
|
| 
       153 
153 
     | 
    
         
             
                  reset_default_dataset
         
     | 
| 
       154 
154 
     | 
    
         
             
                  adapter_initialize
         
     | 
| 
       155 
155 
     | 
    
         | 
| 
       156 
     | 
    
         
            -
                   
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
      
 156 
     | 
    
         
            +
                  keep_reference = typecast_value_boolean(@opts[:keep_reference]) != false
         
     | 
| 
      
 157 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 158 
     | 
    
         
            +
                    Sequel.synchronize{::Sequel::DATABASES.push(self)} if keep_reference
         
     | 
| 
      
 159 
     | 
    
         
            +
                    Sequel::Database.run_after_initialize(self)
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
      
 161 
     | 
    
         
            +
                    initialize_load_extensions(:preconnect_extensions)
         
     | 
| 
       162 
162 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 163 
     | 
    
         
            +
                    if typecast_value_boolean(@opts[:preconnect]) && @pool.respond_to?(:preconnect, true)
         
     | 
| 
      
 164 
     | 
    
         
            +
                      concurrent = typecast_value_string(@opts[:preconnect]) == "concurrently"
         
     | 
| 
      
 165 
     | 
    
         
            +
                      @pool.send(:preconnect, concurrent)
         
     | 
| 
      
 166 
     | 
    
         
            +
                    end
         
     | 
| 
       167 
167 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
      
 168 
     | 
    
         
            +
                    initialize_load_extensions(:extensions)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  rescue
         
     | 
| 
      
 170 
     | 
    
         
            +
                    Sequel.synchronize{::Sequel::DATABASES.delete(self)} if keep_reference
         
     | 
| 
      
 171 
     | 
    
         
            +
                    raise
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
       169 
173 
     | 
    
         
             
                end
         
     | 
| 
       170 
174 
     | 
    
         | 
| 
       171 
175 
     | 
    
         
             
                # Freeze internal data structures for the Database instance.
         
     | 
| 
         @@ -185,7 +189,9 @@ module Sequel 
     | 
|
| 
       185 
189 
     | 
    
         | 
| 
       186 
190 
     | 
    
         
             
                # Disallow dup/clone for Database instances
         
     | 
| 
       187 
191 
     | 
    
         
             
                undef_method :dup, :clone, :initialize_copy
         
     | 
| 
      
 192 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       188 
193 
     | 
    
         
             
                if RUBY_VERSION >= '1.9.3'
         
     | 
| 
      
 194 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       189 
195 
     | 
    
         
             
                  undef_method :initialize_clone, :initialize_dup
         
     | 
| 
       190 
196 
     | 
    
         
             
                end
         
     | 
| 
       191 
197 
     | 
    
         | 
| 
         @@ -38,7 +38,6 @@ module Sequel 
     | 
|
| 
       38 
38 
     | 
    
         
             
                    @constraints = []
         
     | 
| 
       39 
39 
     | 
    
         
             
                    @primary_key = nil
         
     | 
| 
       40 
40 
     | 
    
         
             
                    instance_exec(&block) if block
         
     | 
| 
       41 
     | 
    
         
            -
                    @columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
         
     | 
| 
       42 
41 
     | 
    
         
             
                  end
         
     | 
| 
       43 
42 
     | 
    
         | 
| 
       44 
43 
     | 
    
         
             
                  # Use custom Bignum method to use :Bignum instead of Bignum class, to work
         
     | 
| 
         @@ -494,7 +494,9 @@ module Sequel 
     | 
|
| 
       494 
494 
     | 
    
         
             
                  when :drop_index
         
     | 
| 
       495 
495 
     | 
    
         
             
                    drop_index_sql(table, op)
         
     | 
| 
       496 
496 
     | 
    
         
             
                  else
         
     | 
| 
       497 
     | 
    
         
            -
                     
     | 
| 
      
 497 
     | 
    
         
            +
                    if sql = alter_table_op_sql(table, op)
         
     | 
| 
      
 498 
     | 
    
         
            +
                      "ALTER TABLE #{quote_schema_table(table)} #{sql}"
         
     | 
| 
      
 499 
     | 
    
         
            +
                    end
         
     | 
| 
       498 
500 
     | 
    
         
             
                  end
         
     | 
| 
       499 
501 
     | 
    
         
             
                end
         
     | 
| 
       500 
502 
     | 
    
         | 
| 
         @@ -811,23 +813,20 @@ module Sequel 
     | 
|
| 
       811 
813 
     | 
    
         
             
                # Proxy the filter_expr call to the dataset, used for creating constraints.
         
     | 
| 
       812 
814 
     | 
    
         
             
                # Support passing Proc arguments as blocks, as well as treating plain strings
         
     | 
| 
       813 
815 
     | 
    
         
             
                # as literal strings, so that previous migrations that used this API do not break.
         
     | 
| 
       814 
     | 
    
         
            -
                def filter_expr( 
     | 
| 
       815 
     | 
    
         
            -
                  if  
     | 
| 
       816 
     | 
    
         
            -
                     
     | 
| 
       817 
     | 
    
         
            -
                     
     | 
| 
       818 
     | 
    
         
            -
             
     | 
| 
       819 
     | 
    
         
            -
             
     | 
| 
       820 
     | 
    
         
            -
             
     | 
| 
       821 
     | 
    
         
            -
             
     | 
| 
       822 
     | 
    
         
            -
             
     | 
| 
       823 
     | 
    
         
            -
             
     | 
| 
       824 
     | 
    
         
            -
             
     | 
| 
       825 
     | 
    
         
            -
                      elsif arg.length > 1
         
     | 
| 
       826 
     | 
    
         
            -
                        args = [Sequel.&(*arg)]
         
     | 
| 
       827 
     | 
    
         
            -
                      end
         
     | 
| 
      
 816 
     | 
    
         
            +
                def filter_expr(arg=nil, &block)
         
     | 
| 
      
 817 
     | 
    
         
            +
                  if arg.is_a?(Proc) && !block
         
     | 
| 
      
 818 
     | 
    
         
            +
                    block = arg
         
     | 
| 
      
 819 
     | 
    
         
            +
                    arg = nil
         
     | 
| 
      
 820 
     | 
    
         
            +
                  elsif arg.is_a?(String)
         
     | 
| 
      
 821 
     | 
    
         
            +
                    arg = Sequel.lit(arg)
         
     | 
| 
      
 822 
     | 
    
         
            +
                  elsif arg.is_a?(Array)
         
     | 
| 
      
 823 
     | 
    
         
            +
                    if arg.first.is_a?(String)
         
     | 
| 
      
 824 
     | 
    
         
            +
                      arg = Sequel.lit(*arg)
         
     | 
| 
      
 825 
     | 
    
         
            +
                    elsif arg.length > 1
         
     | 
| 
      
 826 
     | 
    
         
            +
                      arg = Sequel.&(*arg)
         
     | 
| 
       828 
827 
     | 
    
         
             
                    end
         
     | 
| 
       829 
828 
     | 
    
         
             
                  end
         
     | 
| 
       830 
     | 
    
         
            -
                  schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr,  
     | 
| 
      
 829 
     | 
    
         
            +
                  schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, arg, &block))
         
     | 
| 
       831 
830 
     | 
    
         
             
                end
         
     | 
| 
       832 
831 
     | 
    
         | 
| 
       833 
832 
     | 
    
         
             
                # SQL statement for creating an index for the table with the given name
         
     | 
| 
         @@ -205,6 +205,10 @@ module Sequel 
     | 
|
| 
       205 
205 
     | 
    
         
             
                        end
         
     | 
| 
       206 
206 
     | 
    
         
             
                      end
         
     | 
| 
       207 
207 
     | 
    
         | 
| 
      
 208 
     | 
    
         
            +
                      if opts[:savepoint] && !supports_savepoints?
         
     | 
| 
      
 209 
     | 
    
         
            +
                        raise Sequel::InvalidOperation, "savepoints not supported on #{database_type}"
         
     | 
| 
      
 210 
     | 
    
         
            +
                      end
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
       208 
212 
     | 
    
         
             
                      if already_in_transaction?(conn, opts)
         
     | 
| 
       209 
213 
     | 
    
         
             
                        if opts[:rollback] == :always && !opts.has_key?(:savepoint)
         
     | 
| 
       210 
214 
     | 
    
         
             
                          if supports_savepoints? 
         
     | 
| 
         @@ -418,11 +422,10 @@ module Sequel 
     | 
|
| 
       418 
422 
     | 
    
         
             
                end
         
     | 
| 
       419 
423 
     | 
    
         | 
| 
       420 
424 
     | 
    
         
             
                # Retrieve the savepoint hooks that should be run for the given
         
     | 
| 
       421 
     | 
    
         
            -
                # connection and commit status.
         
     | 
| 
      
 425 
     | 
    
         
            +
                # connection and commit status.  This expacts that you are
         
     | 
| 
      
 426 
     | 
    
         
            +
                # already inside a savepoint when calling.
         
     | 
| 
       422 
427 
     | 
    
         
             
                def savepoint_hooks(conn, committed)
         
     | 
| 
       423 
     | 
    
         
            -
                   
     | 
| 
       424 
     | 
    
         
            -
                    _trans(conn)[:savepoints].last[committed ? :after_commit : :after_rollback]
         
     | 
| 
       425 
     | 
    
         
            -
                  end
         
     | 
| 
      
 428 
     | 
    
         
            +
                  _trans(conn)[:savepoints].last[committed ? :after_commit : :after_rollback]
         
     | 
| 
       426 
429 
     | 
    
         
             
                end
         
     | 
| 
       427 
430 
     | 
    
         | 
| 
       428 
431 
     | 
    
         
             
                # Retrieve the transaction hooks that should be run for the given
         
     | 
| 
         @@ -114,10 +114,8 @@ module Sequel 
     | 
|
| 
       114 
114 
     | 
    
         
             
                        prepared_sql << sql
         
     | 
| 
       115 
115 
     | 
    
         
             
                        prepared_sql << "$#{prepared_args[i]}"
         
     | 
| 
       116 
116 
     | 
    
         
             
                      end
         
     | 
| 
       117 
     | 
    
         
            -
                       
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                        prepared_sql << final_sql
         
     | 
| 
       120 
     | 
    
         
            -
                      end
         
     | 
| 
      
 117 
     | 
    
         
            +
                      frags << final_sql
         
     | 
| 
      
 118 
     | 
    
         
            +
                      prepared_sql << final_sql
         
     | 
| 
       121 
119 
     | 
    
         | 
| 
       122 
120 
     | 
    
         
             
                      [prepared_sql, frags]
         
     | 
| 
       123 
121 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -213,9 +211,7 @@ module Sequel 
     | 
|
| 
       213 
211 
     | 
    
         
             
                      end
         
     | 
| 
       214 
212 
     | 
    
         
             
                      ds.literal_append(s, v)
         
     | 
| 
       215 
213 
     | 
    
         
             
                    end
         
     | 
| 
       216 
     | 
    
         
            -
                     
     | 
| 
       217 
     | 
    
         
            -
                      s << sql
         
     | 
| 
       218 
     | 
    
         
            -
                    end
         
     | 
| 
      
 214 
     | 
    
         
            +
                    s << @final_sql
         
     | 
| 
       219 
215 
     | 
    
         
             
                    s
         
     | 
| 
       220 
216 
     | 
    
         
             
                  end
         
     | 
| 
       221 
217 
     | 
    
         
             
                end
         
     | 
    
        data/lib/sequel/dataset/query.rb
    CHANGED
    
    | 
         @@ -330,16 +330,17 @@ module Sequel 
     | 
|
| 
       330 
330 
     | 
    
         
             
                #   # SELECT * FROM a WHERE ((a LIKE '%foo%' ESCAPE '\') AND (b LIKE '%foo%' ESCAPE '\')
         
     | 
| 
       331 
331 
     | 
    
         
             
                #   #   AND (a LIKE '%bar%' ESCAPE '\') AND (b LIKE '%bar%' ESCAPE '\'))
         
     | 
| 
       332 
332 
     | 
    
         
             
                def grep(columns, patterns, opts=OPTS)
         
     | 
| 
      
 333 
     | 
    
         
            +
                  column_op = opts[:all_columns] ? :AND : :OR
         
     | 
| 
       333 
334 
     | 
    
         
             
                  if opts[:all_patterns]
         
     | 
| 
       334 
335 
     | 
    
         
             
                    conds = Array(patterns).map do |pat|
         
     | 
| 
       335 
     | 
    
         
            -
                      SQL::BooleanExpression.new( 
     | 
| 
      
 336 
     | 
    
         
            +
                      SQL::BooleanExpression.new(column_op, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
         
     | 
| 
       336 
337 
     | 
    
         
             
                    end
         
     | 
| 
       337 
     | 
    
         
            -
                    where(SQL::BooleanExpression.new( 
     | 
| 
      
 338 
     | 
    
         
            +
                    where(SQL::BooleanExpression.new(:AND, *conds))
         
     | 
| 
       338 
339 
     | 
    
         
             
                  else
         
     | 
| 
       339 
340 
     | 
    
         
             
                    conds = Array(columns).map do |c|
         
     | 
| 
       340 
341 
     | 
    
         
             
                      SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
         
     | 
| 
       341 
342 
     | 
    
         
             
                    end
         
     | 
| 
       342 
     | 
    
         
            -
                    where(SQL::BooleanExpression.new( 
     | 
| 
      
 343 
     | 
    
         
            +
                    where(SQL::BooleanExpression.new(column_op, *conds))
         
     | 
| 
       343 
344 
     | 
    
         
             
                  end
         
     | 
| 
       344 
345 
     | 
    
         
             
                end
         
     | 
| 
       345 
346 
     | 
    
         | 
    
        data/lib/sequel/deprecated.rb
    CHANGED
    
    | 
         @@ -60,7 +60,9 @@ module Sequel 
     | 
|
| 
       60 
60 
     | 
    
         
             
                # If using ruby 2.3+, use Module#deprecate_constant to deprecate the constant,
         
     | 
| 
       61 
61 
     | 
    
         
             
                # otherwise do nothing as the ruby implementation does not support constant deprecation.
         
     | 
| 
       62 
62 
     | 
    
         
             
                def self.deprecate_constant(mod, constant)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
       63 
64 
     | 
    
         
             
                  if RUBY_VERSION > '2.3'
         
     | 
| 
      
 65 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
       64 
66 
     | 
    
         
             
                    mod.deprecate_constant(constant)
         
     | 
| 
       65 
67 
     | 
    
         
             
                  end
         
     | 
| 
       66 
68 
     | 
    
         
             
                end
         
     | 
    
        data/lib/sequel/exceptions.rb
    CHANGED
    
    
    
        data/lib/sequel/model.rb
    CHANGED
    
    | 
         @@ -69,7 +69,9 @@ module Sequel 
     | 
|
| 
       69 
69 
     | 
    
         
             
                require_relative "model/base"
         
     | 
| 
       70 
70 
     | 
    
         
             
                require_relative "model/exceptions"
         
     | 
| 
       71 
71 
     | 
    
         
             
                require_relative "model/errors"
         
     | 
| 
      
 72 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       72 
73 
     | 
    
         
             
                if !defined?(::SEQUEL_NO_ASSOCIATIONS) && !ENV.has_key?('SEQUEL_NO_ASSOCIATIONS')
         
     | 
| 
      
 74 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       73 
75 
     | 
    
         
             
                  require_relative 'model/associations'
         
     | 
| 
       74 
76 
     | 
    
         
             
                  plugin Model::Associations
         
     | 
| 
       75 
77 
     | 
    
         
             
                end
         
     | 
| 
         @@ -164,11 +164,11 @@ module Sequel 
     | 
|
| 
       164 
164 
     | 
    
         
             
                    # range to return the object(s) at the correct offset/limit.
         
     | 
| 
       165 
165 
     | 
    
         
             
                    def apply_ruby_eager_limit_strategy(rows, limit_and_offset = limit_and_offset())
         
     | 
| 
       166 
166 
     | 
    
         
             
                      name = self[:name]
         
     | 
| 
      
 167 
     | 
    
         
            +
                      return unless range = slice_range(limit_and_offset)
         
     | 
| 
       167 
168 
     | 
    
         
             
                      if returns_array?
         
     | 
| 
       168 
     | 
    
         
            -
                        range = slice_range(limit_and_offset)
         
     | 
| 
       169 
169 
     | 
    
         
             
                        rows.each{|o| o.associations[name] = o.associations[name][range] || []}
         
     | 
| 
       170 
     | 
    
         
            -
                       
     | 
| 
       171 
     | 
    
         
            -
                        offset =  
     | 
| 
      
 170 
     | 
    
         
            +
                      else
         
     | 
| 
      
 171 
     | 
    
         
            +
                        offset = range.begin
         
     | 
| 
       172 
172 
     | 
    
         
             
                        rows.each{|o| o.associations[name] = o.associations[name][offset]}
         
     | 
| 
       173 
173 
     | 
    
         
             
                      end
         
     | 
| 
       174 
174 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1244,7 +1244,9 @@ module Sequel 
     | 
|
| 
       1244 
1244 
     | 
    
         
             
                        else
         
     | 
| 
       1245 
1245 
     | 
    
         
             
                          assoc_record.values.delete(left_key_alias)
         
     | 
| 
       1246 
1246 
     | 
    
         
             
                        end
         
     | 
| 
       1247 
     | 
    
         
            -
             
     | 
| 
      
 1247 
     | 
    
         
            +
             
     | 
| 
      
 1248 
     | 
    
         
            +
                        objects = h[hash_key]
         
     | 
| 
      
 1249 
     | 
    
         
            +
             
     | 
| 
       1248 
1250 
     | 
    
         
             
                        if assign_singular
         
     | 
| 
       1249 
1251 
     | 
    
         
             
                          objects.each do |object| 
         
     | 
| 
       1250 
1252 
     | 
    
         
             
                            object.associations[name] ||= assoc_record
         
     | 
| 
         @@ -1948,10 +1950,8 @@ module Sequel 
     | 
|
| 
       1948 
1950 
     | 
    
         
             
                      if opts[:block]
         
     | 
| 
       1949 
1951 
     | 
    
         
             
                        opts[:block_method] = Plugins.def_sequel_method(association_module(opts), "#{opts[:name]}_block", 1, &opts[:block])
         
     | 
| 
       1950 
1952 
     | 
    
         
             
                      end
         
     | 
| 
       1951 
     | 
    
         
            -
                       
     | 
| 
       1952 
     | 
    
         
            -
             
     | 
| 
       1953 
     | 
    
         
            -
                        opts[:dataset_opt_method] = Plugins.def_sequel_method(association_module(opts), "#{opts[:name]}_dataset_opt", opts[:dataset_opt_arity], &opts[:dataset])
         
     | 
| 
       1954 
     | 
    
         
            -
                      end
         
     | 
| 
      
 1953 
     | 
    
         
            +
                      opts[:dataset_opt_arity] = opts[:dataset].arity == 0 ? 0 : 1
         
     | 
| 
      
 1954 
     | 
    
         
            +
                      opts[:dataset_opt_method] = Plugins.def_sequel_method(association_module(opts), "#{opts[:name]}_dataset_opt", opts[:dataset_opt_arity], &opts[:dataset])
         
     | 
| 
       1955 
1955 
     | 
    
         
             
                      def_association_method(opts)
         
     | 
| 
       1956 
1956 
     | 
    
         | 
| 
       1957 
1957 
     | 
    
         
             
                      return if opts[:read_only]
         
     | 
| 
         @@ -2122,9 +2122,7 @@ module Sequel 
     | 
|
| 
       2122 
2122 
     | 
    
         | 
| 
       2123 
2123 
     | 
    
         
             
                        eager_load_results(opts, eo) do |assoc_record|
         
     | 
| 
       2124 
2124 
     | 
    
         
             
                          hash_key = uses_cks ? pk_meths.map{|k| assoc_record.get_column_value(k)} : assoc_record.get_column_value(opts.primary_key_method)
         
     | 
| 
       2125 
     | 
    
         
            -
                           
     | 
| 
       2126 
     | 
    
         
            -
                            objects.each{|object| object.associations[name] = assoc_record}
         
     | 
| 
       2127 
     | 
    
         
            -
                          end
         
     | 
| 
      
 2125 
     | 
    
         
            +
                          h[hash_key].each{|object| object.associations[name] = assoc_record}
         
     | 
| 
       2128 
2126 
     | 
    
         
             
                        end
         
     | 
| 
       2129 
2127 
     | 
    
         
             
                      end
         
     | 
| 
       2130 
2128 
     | 
    
         | 
| 
         @@ -2171,7 +2169,7 @@ module Sequel 
     | 
|
| 
       2171 
2169 
     | 
    
         
             
                        eager_load_results(opts, eo) do |assoc_record|
         
     | 
| 
       2172 
2170 
     | 
    
         
             
                          assoc_record.values.delete(delete_rn) if delete_rn
         
     | 
| 
       2173 
2171 
     | 
    
         
             
                          hash_key = uses_cks ? km.map{|k| assoc_record.get_column_value(k)} : assoc_record.get_column_value(km)
         
     | 
| 
       2174 
     | 
    
         
            -
                           
     | 
| 
      
 2172 
     | 
    
         
            +
                          objects = h[hash_key]
         
     | 
| 
       2175 
2173 
     | 
    
         
             
                          if assign_singular
         
     | 
| 
       2176 
2174 
     | 
    
         
             
                            objects.each do |object| 
         
     | 
| 
       2177 
2175 
     | 
    
         
             
                              unless object.associations[name]
         
     | 
| 
         @@ -3064,6 +3062,8 @@ module Sequel 
     | 
|
| 
       3064 
3062 
     | 
    
         
             
                    #                    significantly slower in some cases (perhaps even the majority of cases), so you should
         
     | 
| 
       3065 
3063 
     | 
    
         
             
                    #                    only use this if you have benchmarked that it is faster for your use cases.
         
     | 
| 
       3066 
3064 
     | 
    
         
             
                    def eager_graph_with_options(associations, opts=OPTS)
         
     | 
| 
      
 3065 
     | 
    
         
            +
                      return self if associations.empty?
         
     | 
| 
      
 3066 
     | 
    
         
            +
             
     | 
| 
       3067 
3067 
     | 
    
         
             
                      opts = opts.dup unless opts.frozen?
         
     | 
| 
       3068 
3068 
     | 
    
         
             
                      associations = [associations] unless associations.is_a?(Array)
         
     | 
| 
       3069 
3069 
     | 
    
         
             
                      ds = if eg = @opts[:eager_graph]
         
     | 
| 
         @@ -3190,7 +3190,6 @@ module Sequel 
     | 
|
| 
       3190 
3190 
     | 
    
         
             
                    # requirements :: an array, used as a stack for requirements
         
     | 
| 
       3191 
3191 
     | 
    
         
             
                    # *associations :: the associations to add to the graph
         
     | 
| 
       3192 
3192 
     | 
    
         
             
                    def eager_graph_associations(ds, model, ta, requirements, *associations)
         
     | 
| 
       3193 
     | 
    
         
            -
                      return ds if associations.empty?
         
     | 
| 
       3194 
3193 
     | 
    
         
             
                      associations.flatten.each do |association|
         
     | 
| 
       3195 
3194 
     | 
    
         
             
                        ds = case association
         
     | 
| 
       3196 
3195 
     | 
    
         
             
                        when Symbol, SQL::AliasedExpression
         
     | 
    
        data/lib/sequel/model/base.rb
    CHANGED
    
    | 
         @@ -593,7 +593,7 @@ module Sequel 
     | 
|
| 
       593 
593 
     | 
    
         
             
                      @columns = superclass.instance_variable_get(:@columns)
         
     | 
| 
       594 
594 
     | 
    
         
             
                      @db_schema = superclass.instance_variable_get(:@db_schema)
         
     | 
| 
       595 
595 
     | 
    
         
             
                    else
         
     | 
| 
       596 
     | 
    
         
            -
                      @dataset = @dataset.with_extend(*@dataset_method_modules.reverse) 
     | 
| 
      
 596 
     | 
    
         
            +
                      @dataset = @dataset.with_extend(*@dataset_method_modules.reverse)
         
     | 
| 
       597 
597 
     | 
    
         
             
                      @db_schema = get_db_schema
         
     | 
| 
       598 
598 
     | 
    
         
             
                    end
         
     | 
| 
       599 
599 
     | 
    
         | 
| 
         @@ -820,7 +820,6 @@ module Sequel 
     | 
|
| 
       820 
820 
     | 
    
         
             
                    super
         
     | 
| 
       821 
821 
     | 
    
         
             
                    ivs = subclass.instance_variables
         
     | 
| 
       822 
822 
     | 
    
         
             
                    inherited_instance_variables.each do |iv, dup|
         
     | 
| 
       823 
     | 
    
         
            -
                      next if ivs.include?(iv)
         
     | 
| 
       824 
823 
     | 
    
         
             
                      if (sup_class_value = instance_variable_get(iv)) && dup
         
     | 
| 
       825 
824 
     | 
    
         
             
                        sup_class_value = case dup
         
     | 
| 
       826 
825 
     | 
    
         
             
                        when :dup
         
     | 
| 
         @@ -1116,7 +1115,7 @@ module Sequel 
     | 
|
| 
       1116 
1115 
     | 
    
         
             
                    when nil
         
     | 
| 
       1117 
1116 
     | 
    
         
             
                      return false
         
     | 
| 
       1118 
1117 
     | 
    
         
             
                    when Array
         
     | 
| 
       1119 
     | 
    
         
            -
                      return false if  
     | 
| 
      
 1118 
     | 
    
         
            +
                      return false if pkv.any?(&:nil?)
         
     | 
| 
       1120 
1119 
     | 
    
         
             
                    end
         
     | 
| 
       1121 
1120 
     | 
    
         | 
| 
       1122 
1121 
     | 
    
         
             
                    (obj.class == model) && (obj.pk == pkv)
         
     | 
| 
         @@ -1989,6 +1988,7 @@ module Sequel 
     | 
|
| 
       1989 
1988 
     | 
    
         | 
| 
       1990 
1989 
     | 
    
         
             
                  # Get the ruby class or classes related to the given column's type.
         
     | 
| 
       1991 
1990 
     | 
    
         
             
                  def schema_type_class(column)
         
     | 
| 
      
 1991 
     | 
    
         
            +
                    # SEQUEL6: Remove
         
     | 
| 
       1992 
1992 
     | 
    
         
             
                    if (sch = db_schema[column]) && (type = sch[:type])
         
     | 
| 
       1993 
1993 
     | 
    
         
             
                      db.schema_type_class(type)
         
     | 
| 
       1994 
1994 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -2232,7 +2232,9 @@ module Sequel 
     | 
|
| 
       2232 
2232 
     | 
    
         
             
                plugin self
         
     | 
| 
       2233 
2233 
     | 
    
         | 
| 
       2234 
2234 
     | 
    
         
             
                singleton_class.send(:undef_method, :dup, :clone, :initialize_copy)
         
     | 
| 
      
 2235 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       2235 
2236 
     | 
    
         
             
                if RUBY_VERSION >= '1.9.3'
         
     | 
| 
      
 2237 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       2236 
2238 
     | 
    
         
             
                  singleton_class.send(:undef_method, :initialize_clone, :initialize_dup)
         
     | 
| 
       2237 
2239 
     | 
    
         
             
                end
         
     | 
| 
       2238 
2240 
     | 
    
         
             
              end
         
     | 
    
        data/lib/sequel/model/plugins.rb
    CHANGED
    
    | 
         @@ -149,9 +149,8 @@ module Sequel 
     | 
|
| 
       149 
149 
     | 
    
         
             
                  required_args = arity
         
     | 
| 
       150 
150 
     | 
    
         
             
                  arity -= 1 if keyword == :required
         
     | 
| 
       151 
151 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                   
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                  end
         
     | 
| 
      
 152 
     | 
    
         
            +
                  # callable currently is always a non-lambda Proc
         
     | 
| 
      
 153 
     | 
    
         
            +
                  optional_args -= arity
         
     | 
| 
       155 
154 
     | 
    
         | 
| 
       156 
155 
     | 
    
         
             
                  [required_args, optional_args, rest, keyword]
         
     | 
| 
       157 
156 
     | 
    
         
             
                end
         
     | 
| 
         @@ -2,13 +2,17 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Sequel
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Plugins
         
     | 
| 
       5 
     | 
    
         
            -
                # The association_pks plugin adds association_pks and 
     | 
| 
       6 
     | 
    
         
            -
                # instance methods to the model class for each 
     | 
| 
       7 
     | 
    
         
            -
                #  
     | 
| 
       8 
     | 
    
         
            -
                #  
     | 
| 
      
 5 
     | 
    
         
            +
                # The association_pks plugin adds association_pks, association_pks=, and
         
     | 
| 
      
 6 
     | 
    
         
            +
                # association_pks_dataset instance methods to the model class for each
         
     | 
| 
      
 7 
     | 
    
         
            +
                # one_to_many and many_to_many association added.  These methods allow for
         
     | 
| 
      
 8 
     | 
    
         
            +
                # easily returning the primary keys of the associated objects, and easily
         
     | 
| 
      
 9 
     | 
    
         
            +
                # modifying which objects are associated:
         
     | 
| 
       9 
10 
     | 
    
         
             
                #
         
     | 
| 
       10 
11 
     | 
    
         
             
                #   Artist.one_to_many :albums
         
     | 
| 
       11 
12 
     | 
    
         
             
                #   artist = Artist[1]
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   artist.album_pks_dataset
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   # SELECT id FROM albums WHERE (albums.artist_id = 1)
         
     | 
| 
      
 15 
     | 
    
         
            +
                #
         
     | 
| 
       12 
16 
     | 
    
         
             
                #   artist.album_pks # [1, 2, 3]
         
     | 
| 
       13 
17 
     | 
    
         
             
                #   artist.album_pks = [2, 4]
         
     | 
| 
       14 
18 
     | 
    
         
             
                #   artist.album_pks # [2, 4]
         
     | 
| 
         @@ -22,11 +26,18 @@ module Sequel 
     | 
|
| 
       22 
26 
     | 
    
         
             
                # This plugin makes modifications directly to the underlying tables,
         
     | 
| 
       23 
27 
     | 
    
         
             
                # it does not create or return any model objects, and therefore does
         
     | 
| 
       24 
28 
     | 
    
         
             
                # not call any callbacks.  If you have any association callbacks,
         
     | 
| 
       25 
     | 
    
         
            -
                # you probably should not use the setter methods.
         
     | 
| 
      
 29 
     | 
    
         
            +
                # you probably should not use the setter methods this plugin adds.
         
     | 
| 
       26 
30 
     | 
    
         
             
                #
         
     | 
| 
       27 
31 
     | 
    
         
             
                # By default, changes to the association will not happen until the object
         
     | 
| 
       28 
     | 
    
         
            -
                # is saved.  However, using the delay_pks: false option, you can have 
     | 
| 
       29 
     | 
    
         
            -
                # changes made immediately when the association_pks setter method is called.
         
     | 
| 
      
 32 
     | 
    
         
            +
                # is saved.  However, using the delay_pks: false association option, you can have
         
     | 
| 
      
 33 
     | 
    
         
            +
                # the changes made immediately when the association_pks setter method is called.
         
     | 
| 
      
 34 
     | 
    
         
            +
                #
         
     | 
| 
      
 35 
     | 
    
         
            +
                # By default, repeated calls to the association_pks getter method will not be
         
     | 
| 
      
 36 
     | 
    
         
            +
                # cached, unless the setter method has been used and the delay_pks: false
         
     | 
| 
      
 37 
     | 
    
         
            +
                # association option is not used.  You can set caching of repeated calls to the
         
     | 
| 
      
 38 
     | 
    
         
            +
                # association_pks getter method using the :cache_pks association option.  You can
         
     | 
| 
      
 39 
     | 
    
         
            +
                # pass the :refresh option when calling the getter method to ignore any existing
         
     | 
| 
      
 40 
     | 
    
         
            +
                # cached values, similar to how the :refresh option works with associations.
         
     | 
| 
       30 
41 
     | 
    
         
             
                #
         
     | 
| 
       31 
42 
     | 
    
         
             
                # By default, if you pass a nil value to the setter, an exception will be raised.
         
     | 
| 
       32 
43 
     | 
    
         
             
                # You can change this behavior by using the :association_pks_nil association option.
         
     | 
| 
         @@ -60,9 +71,11 @@ module Sequel 
     | 
|
| 
       60 
71 
     | 
    
         | 
| 
       61 
72 
     | 
    
         
             
                    # Define a association_pks method using the block for the association reflection 
         
     | 
| 
       62 
73 
     | 
    
         
             
                    def def_association_pks_methods(opts)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      association_module_def(opts[:pks_dataset_method], &opts[:pks_dataset])
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
       63 
76 
     | 
    
         
             
                      opts[:pks_getter_method] = :"#{singularize(opts[:name])}_pks_getter"
         
     | 
| 
       64 
77 
     | 
    
         
             
                      association_module_def(opts[:pks_getter_method], &opts[:pks_getter])
         
     | 
| 
       65 
     | 
    
         
            -
                      association_module_def(:"#{singularize(opts[:name])}_pks", opts){_association_pks_getter(opts)}
         
     | 
| 
      
 78 
     | 
    
         
            +
                      association_module_def(:"#{singularize(opts[:name])}_pks", opts){|dynamic_opts=OPTS| _association_pks_getter(opts, dynamic_opts)}
         
     | 
| 
       66 
79 
     | 
    
         | 
| 
       67 
80 
     | 
    
         
             
                      if opts[:pks_setter]
         
     | 
| 
       68 
81 
     | 
    
         
             
                        opts[:pks_setter_method] = :"#{singularize(opts[:name])}_pks_setter"
         
     | 
| 
         @@ -84,7 +97,9 @@ module Sequel 
     | 
|
| 
       84 
97 
     | 
    
         
             
                      clpk = lpk.is_a?(Array)
         
     | 
| 
       85 
98 
     | 
    
         
             
                      crk = rk.is_a?(Array)
         
     | 
| 
       86 
99 
     | 
    
         | 
| 
       87 
     | 
    
         
            -
                      opts[: 
     | 
| 
      
 100 
     | 
    
         
            +
                      dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                      opts[:pks_dataset] = if join_associated_table = opts[:association_pks_use_associated_table]
         
     | 
| 
       88 
103 
     | 
    
         
             
                        tname = opts[:join_table]
         
     | 
| 
       89 
104 
     | 
    
         
             
                        lambda do
         
     | 
| 
       90 
105 
     | 
    
         
             
                          cond = if clpk
         
     | 
| 
         @@ -95,16 +110,26 @@ module Sequel 
     | 
|
| 
       95 
110 
     | 
    
         
             
                          rpk = opts.associated_class.primary_key
         
     | 
| 
       96 
111 
     | 
    
         
             
                          opts.associated_dataset.
         
     | 
| 
       97 
112 
     | 
    
         
             
                            naked.where(cond).
         
     | 
| 
       98 
     | 
    
         
            -
                             
     | 
| 
      
 113 
     | 
    
         
            +
                            select(*Sequel.public_send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
         
     | 
| 
       99 
114 
     | 
    
         
             
                        end
         
     | 
| 
       100 
115 
     | 
    
         
             
                      elsif clpk
         
     | 
| 
       101 
116 
     | 
    
         
             
                        lambda do
         
     | 
| 
       102 
117 
     | 
    
         
             
                          cond = lk.zip(lpk).map{|k, pk| [k, get_column_value(pk)]}
         
     | 
| 
       103 
     | 
    
         
            -
                          _join_table_dataset(opts).where(cond). 
     | 
| 
      
 118 
     | 
    
         
            +
                          _join_table_dataset(opts).where(cond).select(*rk)
         
     | 
| 
      
 119 
     | 
    
         
            +
                        end
         
     | 
| 
      
 120 
     | 
    
         
            +
                      else
         
     | 
| 
      
 121 
     | 
    
         
            +
                        lambda do
         
     | 
| 
      
 122 
     | 
    
         
            +
                          _join_table_dataset(opts).where(lk=>get_column_value(lpk)).select(*rk)
         
     | 
| 
      
 123 
     | 
    
         
            +
                        end
         
     | 
| 
      
 124 
     | 
    
         
            +
                      end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                      opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
         
     | 
| 
      
 127 
     | 
    
         
            +
                        lambda do
         
     | 
| 
      
 128 
     | 
    
         
            +
                          public_send(dataset_method).map(opts.associated_class.primary_key)
         
     | 
| 
       104 
129 
     | 
    
         
             
                        end
         
     | 
| 
       105 
130 
     | 
    
         
             
                      else
         
     | 
| 
       106 
131 
     | 
    
         
             
                        lambda do
         
     | 
| 
       107 
     | 
    
         
            -
                           
     | 
| 
      
 132 
     | 
    
         
            +
                          public_send(dataset_method).map(rk)
         
     | 
| 
       108 
133 
     | 
    
         
             
                        end
         
     | 
| 
       109 
134 
     | 
    
         
             
                      end
         
     | 
| 
       110 
135 
     | 
    
         | 
| 
         @@ -145,8 +170,14 @@ module Sequel 
     | 
|
| 
       145 
170 
     | 
    
         | 
| 
       146 
171 
     | 
    
         
             
                      key = opts[:key]
         
     | 
| 
       147 
172 
     | 
    
         | 
| 
      
 173 
     | 
    
         
            +
                      dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                      opts[:pks_dataset] = lambda do
         
     | 
| 
      
 176 
     | 
    
         
            +
                        public_send(opts[:dataset_method]).select(*opts.associated_class.primary_key)
         
     | 
| 
      
 177 
     | 
    
         
            +
                      end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
       148 
179 
     | 
    
         
             
                      opts[:pks_getter] = lambda do
         
     | 
| 
       149 
     | 
    
         
            -
                        public_send( 
     | 
| 
      
 180 
     | 
    
         
            +
                        public_send(dataset_method).map(opts.associated_class.primary_key)
         
     | 
| 
       150 
181 
     | 
    
         
             
                      end
         
     | 
| 
       151 
182 
     | 
    
         | 
| 
       152 
183 
     | 
    
         
             
                      unless opts[:read_only]
         
     | 
| 
         @@ -207,12 +238,22 @@ module Sequel 
     | 
|
| 
       207 
238 
     | 
    
         
             
                    # Return the primary keys of the associated objects.
         
     | 
| 
       208 
239 
     | 
    
         
             
                    # If the receiver is a new object, return any saved
         
     | 
| 
       209 
240 
     | 
    
         
             
                    # pks, or an empty array if no pks have been saved.
         
     | 
| 
       210 
     | 
    
         
            -
                    def _association_pks_getter(opts)
         
     | 
| 
      
 241 
     | 
    
         
            +
                    def _association_pks_getter(opts, dynamic_opts=OPTS)
         
     | 
| 
      
 242 
     | 
    
         
            +
                      do_cache = opts[:cache_pks]
         
     | 
| 
       211 
243 
     | 
    
         
             
                      delay = opts.fetch(:delay_pks, true)
         
     | 
| 
       212 
     | 
    
         
            -
                       
     | 
| 
      
 244 
     | 
    
         
            +
                      cache_or_delay = do_cache || delay
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                      if dynamic_opts[:refresh] && @_association_pks
         
     | 
| 
      
 247 
     | 
    
         
            +
                        @_association_pks.delete(opts[:name])
         
     | 
| 
      
 248 
     | 
    
         
            +
                      end
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                      if new? && cache_or_delay
         
     | 
| 
       213 
251 
     | 
    
         
             
                        (@_association_pks ||= {})[opts[:name]] ||= []
         
     | 
| 
       214 
     | 
    
         
            -
                      elsif  
     | 
| 
      
 252 
     | 
    
         
            +
                      elsif cache_or_delay && @_association_pks && (objs = @_association_pks[opts[:name]])
         
     | 
| 
       215 
253 
     | 
    
         
             
                        objs
         
     | 
| 
      
 254 
     | 
    
         
            +
                      elsif do_cache
         
     | 
| 
      
 255 
     | 
    
         
            +
                       # pks_getter_method is private
         
     | 
| 
      
 256 
     | 
    
         
            +
                        (@_association_pks ||= {})[opts[:name]] = send(opts[:pks_getter_method])
         
     | 
| 
       216 
257 
     | 
    
         
             
                      else
         
     | 
| 
       217 
258 
     | 
    
         
             
                       # pks_getter_method is private
         
     | 
| 
       218 
259 
     | 
    
         
             
                        send(opts[:pks_getter_method])
         
     | 
| 
         @@ -192,7 +192,7 @@ module Sequel 
     | 
|
| 
       192 
192 
     | 
    
         
             
                         :args=>((key_aliases + col_aliases) if col_aliases))
         
     | 
| 
       193 
193 
     | 
    
         
             
                      ds = r.apply_eager_dataset_changes(ds)
         
     | 
| 
       194 
194 
     | 
    
         
             
                      ds = ds.select_append(ka) unless ds.opts[:select] == nil
         
     | 
| 
       195 
     | 
    
         
            -
                      model.eager_load_results(r, eo.merge(:loader=>false, : 
     | 
| 
      
 195 
     | 
    
         
            +
                      model.eager_load_results(r, eo.merge(:loader=>false, :initialize_rows=>false, :dataset=>ds, :id_map=>nil)) do |obj|
         
     | 
| 
       196 
196 
     | 
    
         
             
                        opk = prkey_conv[obj]
         
     | 
| 
       197 
197 
     | 
    
         
             
                        if parent_map.has_key?(opk)
         
     | 
| 
       198 
198 
     | 
    
         
             
                          if idm_obj = parent_map[opk]
         
     | 
| 
         @@ -300,7 +300,7 @@ module Sequel 
     | 
|
| 
       300 
300 
     | 
    
         
             
                          :args=>((key_aliases + col_aliases + (level ? [la] : [])) if col_aliases))
         
     | 
| 
       301 
301 
     | 
    
         
             
                      ds = r.apply_eager_dataset_changes(ds)
         
     | 
| 
       302 
302 
     | 
    
         
             
                      ds = ds.select_append(ka) unless ds.opts[:select] == nil
         
     | 
| 
       303 
     | 
    
         
            -
                      model.eager_load_results(r, eo.merge(:loader=>false, : 
     | 
| 
      
 303 
     | 
    
         
            +
                      model.eager_load_results(r, eo.merge(:loader=>false, :initialize_rows=>false, :dataset=>ds, :id_map=>nil, :associations=>OPTS)) do |obj|
         
     | 
| 
       304 
304 
     | 
    
         
             
                        if level
         
     | 
| 
       305 
305 
     | 
    
         
             
                          no_cache = no_cache_level == obj.values.delete(la)
         
     | 
| 
       306 
306 
     | 
    
         
             
                        end
         
     | 
    
        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 = 34
         
     | 
| 
       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.34.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Jeremy Evans
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2020- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-07-01 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: minitest
         
     | 
| 
         @@ -181,6 +181,7 @@ extra_rdoc_files: 
     | 
|
| 
       181 
181 
     | 
    
         
             
            - doc/release_notes/5.31.0.txt
         
     | 
| 
       182 
182 
     | 
    
         
             
            - doc/release_notes/5.32.0.txt
         
     | 
| 
       183 
183 
     | 
    
         
             
            - doc/release_notes/5.33.0.txt
         
     | 
| 
      
 184 
     | 
    
         
            +
            - doc/release_notes/5.34.0.txt
         
     | 
| 
       184 
185 
     | 
    
         
             
            files:
         
     | 
| 
       185 
186 
     | 
    
         
             
            - CHANGELOG
         
     | 
| 
       186 
187 
     | 
    
         
             
            - MIT-LICENSE
         
     | 
| 
         @@ -235,6 +236,7 @@ files: 
     | 
|
| 
       235 
236 
     | 
    
         
             
            - doc/release_notes/5.31.0.txt
         
     | 
| 
       236 
237 
     | 
    
         
             
            - doc/release_notes/5.32.0.txt
         
     | 
| 
       237 
238 
     | 
    
         
             
            - doc/release_notes/5.33.0.txt
         
     | 
| 
      
 239 
     | 
    
         
            +
            - doc/release_notes/5.34.0.txt
         
     | 
| 
       238 
240 
     | 
    
         
             
            - doc/release_notes/5.4.0.txt
         
     | 
| 
       239 
241 
     | 
    
         
             
            - doc/release_notes/5.5.0.txt
         
     | 
| 
       240 
242 
     | 
    
         
             
            - doc/release_notes/5.6.0.txt
         
     |