sequel 5.45.0 → 5.77.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 +434 -0
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +59 -27
 - data/bin/sequel +11 -3
 - data/doc/advanced_associations.rdoc +16 -14
 - data/doc/association_basics.rdoc +119 -24
 - data/doc/cheat_sheet.rdoc +11 -3
 - data/doc/mass_assignment.rdoc +1 -1
 - data/doc/migration.rdoc +27 -6
 - data/doc/model_hooks.rdoc +1 -1
 - data/doc/object_model.rdoc +8 -8
 - data/doc/opening_databases.rdoc +28 -12
 - data/doc/postgresql.rdoc +16 -8
 - data/doc/querying.rdoc +5 -3
 - data/doc/release_notes/5.46.0.txt +87 -0
 - data/doc/release_notes/5.47.0.txt +59 -0
 - data/doc/release_notes/5.48.0.txt +14 -0
 - data/doc/release_notes/5.49.0.txt +59 -0
 - data/doc/release_notes/5.50.0.txt +78 -0
 - data/doc/release_notes/5.51.0.txt +47 -0
 - data/doc/release_notes/5.52.0.txt +87 -0
 - data/doc/release_notes/5.53.0.txt +23 -0
 - data/doc/release_notes/5.54.0.txt +27 -0
 - data/doc/release_notes/5.55.0.txt +21 -0
 - data/doc/release_notes/5.56.0.txt +51 -0
 - data/doc/release_notes/5.57.0.txt +23 -0
 - data/doc/release_notes/5.58.0.txt +31 -0
 - data/doc/release_notes/5.59.0.txt +73 -0
 - data/doc/release_notes/5.60.0.txt +22 -0
 - data/doc/release_notes/5.61.0.txt +43 -0
 - data/doc/release_notes/5.62.0.txt +132 -0
 - data/doc/release_notes/5.63.0.txt +33 -0
 - data/doc/release_notes/5.64.0.txt +50 -0
 - data/doc/release_notes/5.65.0.txt +21 -0
 - data/doc/release_notes/5.66.0.txt +24 -0
 - data/doc/release_notes/5.67.0.txt +32 -0
 - data/doc/release_notes/5.68.0.txt +61 -0
 - data/doc/release_notes/5.69.0.txt +26 -0
 - data/doc/release_notes/5.70.0.txt +35 -0
 - data/doc/release_notes/5.71.0.txt +21 -0
 - data/doc/release_notes/5.72.0.txt +33 -0
 - data/doc/release_notes/5.73.0.txt +66 -0
 - data/doc/release_notes/5.74.0.txt +45 -0
 - data/doc/release_notes/5.75.0.txt +35 -0
 - data/doc/release_notes/5.76.0.txt +86 -0
 - data/doc/release_notes/5.77.0.txt +63 -0
 - data/doc/schema_modification.rdoc +1 -1
 - data/doc/security.rdoc +9 -9
 - data/doc/sharding.rdoc +3 -1
 - data/doc/sql.rdoc +27 -15
 - data/doc/testing.rdoc +23 -13
 - data/doc/transactions.rdoc +6 -6
 - data/doc/virtual_rows.rdoc +1 -1
 - data/lib/sequel/adapters/ado/access.rb +1 -1
 - data/lib/sequel/adapters/ado.rb +1 -1
 - data/lib/sequel/adapters/amalgalite.rb +3 -5
 - data/lib/sequel/adapters/ibmdb.rb +3 -3
 - data/lib/sequel/adapters/jdbc/derby.rb +8 -0
 - data/lib/sequel/adapters/jdbc/h2.rb +63 -10
 - data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
 - data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
 - data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
 - data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
 - data/lib/sequel/adapters/jdbc.rb +24 -22
 - data/lib/sequel/adapters/mysql.rb +92 -67
 - data/lib/sequel/adapters/mysql2.rb +56 -51
 - data/lib/sequel/adapters/odbc/mssql.rb +1 -1
 - data/lib/sequel/adapters/odbc.rb +1 -1
 - data/lib/sequel/adapters/oracle.rb +4 -3
 - data/lib/sequel/adapters/postgres.rb +89 -45
 - data/lib/sequel/adapters/shared/access.rb +11 -1
 - data/lib/sequel/adapters/shared/db2.rb +42 -0
 - data/lib/sequel/adapters/shared/mssql.rb +91 -10
 - data/lib/sequel/adapters/shared/mysql.rb +78 -3
 - data/lib/sequel/adapters/shared/oracle.rb +86 -7
 - data/lib/sequel/adapters/shared/postgres.rb +576 -171
 - data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
 - data/lib/sequel/adapters/shared/sqlite.rb +92 -8
 - data/lib/sequel/adapters/sqlanywhere.rb +1 -1
 - data/lib/sequel/adapters/sqlite.rb +99 -18
 - data/lib/sequel/adapters/tinytds.rb +1 -1
 - data/lib/sequel/adapters/trilogy.rb +117 -0
 - data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
 - data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
 - data/lib/sequel/ast_transformer.rb +6 -0
 - data/lib/sequel/connection_pool/sharded_single.rb +5 -7
 - data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
 - data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
 - data/lib/sequel/connection_pool/single.rb +6 -8
 - data/lib/sequel/connection_pool/threaded.rb +14 -8
 - data/lib/sequel/connection_pool/timed_queue.rb +270 -0
 - data/lib/sequel/connection_pool.rb +57 -31
 - data/lib/sequel/core.rb +17 -18
 - data/lib/sequel/database/connecting.rb +27 -3
 - data/lib/sequel/database/dataset.rb +16 -6
 - data/lib/sequel/database/misc.rb +70 -14
 - data/lib/sequel/database/query.rb +73 -2
 - data/lib/sequel/database/schema_generator.rb +11 -6
 - data/lib/sequel/database/schema_methods.rb +23 -4
 - data/lib/sequel/database/transactions.rb +6 -0
 - data/lib/sequel/dataset/actions.rb +111 -15
 - data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
 - data/lib/sequel/dataset/features.rb +20 -1
 - data/lib/sequel/dataset/misc.rb +12 -2
 - data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
 - data/lib/sequel/dataset/query.rb +170 -41
 - data/lib/sequel/dataset/sql.rb +190 -71
 - data/lib/sequel/dataset.rb +4 -0
 - data/lib/sequel/extensions/_model_pg_row.rb +0 -12
 - data/lib/sequel/extensions/_pretty_table.rb +1 -1
 - data/lib/sequel/extensions/any_not_empty.rb +2 -2
 - data/lib/sequel/extensions/async_thread_pool.rb +14 -13
 - data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
 - data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
 - data/lib/sequel/extensions/connection_expiration.rb +15 -9
 - data/lib/sequel/extensions/connection_validator.rb +16 -11
 - data/lib/sequel/extensions/constraint_validations.rb +1 -1
 - data/lib/sequel/extensions/core_refinements.rb +36 -11
 - data/lib/sequel/extensions/date_arithmetic.rb +36 -8
 - data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
 - data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
 - data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
 - data/lib/sequel/extensions/index_caching.rb +5 -1
 - data/lib/sequel/extensions/inflector.rb +1 -1
 - data/lib/sequel/extensions/is_distinct_from.rb +141 -0
 - data/lib/sequel/extensions/looser_typecasting.rb +3 -0
 - data/lib/sequel/extensions/migration.rb +57 -15
 - data/lib/sequel/extensions/named_timezones.rb +22 -6
 - data/lib/sequel/extensions/pagination.rb +1 -1
 - data/lib/sequel/extensions/pg_array.rb +33 -4
 - data/lib/sequel/extensions/pg_array_ops.rb +2 -2
 - data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
 - data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
 - data/lib/sequel/extensions/pg_enum.rb +1 -2
 - data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
 - data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
 - data/lib/sequel/extensions/pg_hstore.rb +6 -1
 - data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
 - data/lib/sequel/extensions/pg_inet.rb +10 -11
 - data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_interval.rb +11 -11
 - data/lib/sequel/extensions/pg_json.rb +13 -15
 - data/lib/sequel/extensions/pg_json_ops.rb +125 -2
 - data/lib/sequel/extensions/pg_multirange.rb +367 -0
 - data/lib/sequel/extensions/pg_range.rb +13 -26
 - data/lib/sequel/extensions/pg_range_ops.rb +37 -9
 - data/lib/sequel/extensions/pg_row.rb +20 -19
 - data/lib/sequel/extensions/pg_row_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
 - data/lib/sequel/extensions/round_timestamps.rb +1 -1
 - data/lib/sequel/extensions/s.rb +2 -1
 - data/lib/sequel/extensions/schema_caching.rb +1 -1
 - data/lib/sequel/extensions/schema_dumper.rb +45 -11
 - data/lib/sequel/extensions/server_block.rb +10 -13
 - data/lib/sequel/extensions/set_literalizer.rb +58 -0
 - data/lib/sequel/extensions/sql_comments.rb +110 -3
 - data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
 - data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
 - data/lib/sequel/extensions/string_agg.rb +1 -1
 - data/lib/sequel/extensions/string_date_time.rb +19 -23
 - data/lib/sequel/extensions/symbol_aref.rb +2 -0
 - data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
 - data/lib/sequel/model/associations.rb +286 -92
 - data/lib/sequel/model/base.rb +53 -33
 - data/lib/sequel/model/dataset_module.rb +3 -0
 - data/lib/sequel/model/errors.rb +10 -1
 - data/lib/sequel/model/exceptions.rb +15 -3
 - data/lib/sequel/model/inflections.rb +1 -1
 - data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
 - data/lib/sequel/plugins/auto_validations.rb +74 -16
 - data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
 - data/lib/sequel/plugins/column_encryption.rb +29 -8
 - data/lib/sequel/plugins/composition.rb +3 -2
 - data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
 - data/lib/sequel/plugins/constraint_validations.rb +8 -5
 - data/lib/sequel/plugins/defaults_setter.rb +16 -0
 - data/lib/sequel/plugins/dirty.rb +1 -1
 - data/lib/sequel/plugins/enum.rb +124 -0
 - data/lib/sequel/plugins/finder.rb +4 -2
 - data/lib/sequel/plugins/insert_conflict.rb +4 -0
 - data/lib/sequel/plugins/instance_specific_default.rb +1 -1
 - data/lib/sequel/plugins/json_serializer.rb +2 -2
 - data/lib/sequel/plugins/lazy_attributes.rb +3 -0
 - data/lib/sequel/plugins/list.rb +8 -3
 - data/lib/sequel/plugins/many_through_many.rb +109 -10
 - data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
 - data/lib/sequel/plugins/nested_attributes.rb +4 -4
 - data/lib/sequel/plugins/optimistic_locking.rb +9 -42
 - data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
 - data/lib/sequel/plugins/paged_operations.rb +181 -0
 - data/lib/sequel/plugins/pg_array_associations.rb +46 -34
 - data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
 - data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
 - data/lib/sequel/plugins/prepared_statements.rb +12 -2
 - data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
 - data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
 - data/lib/sequel/plugins/rcte_tree.rb +7 -4
 - data/lib/sequel/plugins/require_valid_schema.rb +67 -0
 - data/lib/sequel/plugins/serialization.rb +1 -0
 - data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
 - data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
 - data/lib/sequel/plugins/sql_comments.rb +189 -0
 - data/lib/sequel/plugins/static_cache.rb +39 -1
 - data/lib/sequel/plugins/static_cache_cache.rb +5 -1
 - data/lib/sequel/plugins/subclasses.rb +28 -11
 - data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
 - data/lib/sequel/plugins/timestamps.rb +1 -1
 - data/lib/sequel/plugins/unused_associations.rb +521 -0
 - data/lib/sequel/plugins/update_or_create.rb +1 -1
 - data/lib/sequel/plugins/validate_associated.rb +22 -12
 - data/lib/sequel/plugins/validation_helpers.rb +41 -11
 - data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
 - data/lib/sequel/plugins/xml_serializer.rb +1 -1
 - data/lib/sequel/sql.rb +1 -1
 - data/lib/sequel/timezones.rb +12 -14
 - data/lib/sequel/version.rb +1 -1
 - metadata +109 -19
 
| 
         @@ -274,7 +274,9 @@ module Sequel 
     | 
|
| 
       274 
274 
     | 
    
         
             
                      cascade = eo[:associations]
         
     | 
| 
       275 
275 
     | 
    
         
             
                      eager_limit = nil
         
     | 
| 
       276 
276 
     | 
    
         | 
| 
       277 
     | 
    
         
            -
                      if eo[: 
     | 
| 
      
 277 
     | 
    
         
            +
                      if eo[:no_results]
         
     | 
| 
      
 278 
     | 
    
         
            +
                        no_results = true
         
     | 
| 
      
 279 
     | 
    
         
            +
                      elsif eo[:eager_block] || eo[:loader] == false || !use_placeholder_loader?
         
     | 
| 
       278 
280 
     | 
    
         
             
                        ds = eager_loading_dataset(eo)
         
     | 
| 
       279 
281 
     | 
    
         | 
| 
       280 
282 
     | 
    
         
             
                        strategy = ds.opts[:eager_limit_strategy] || strategy
         
     | 
| 
         @@ -297,13 +299,28 @@ module Sequel 
     | 
|
| 
       297 
299 
     | 
    
         
             
                        strategy = :ruby if strategy == :correlated_subquery
         
     | 
| 
       298 
300 
     | 
    
         
             
                        strategy = nil if strategy == :ruby && assign_singular?
         
     | 
| 
       299 
301 
     | 
    
         
             
                        objects = apply_eager_limit_strategy(ds, strategy, eager_limit).all
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                        if strategy == :window_function
         
     | 
| 
      
 304 
     | 
    
         
            +
                          delete_rn = ds.row_number_column 
         
     | 
| 
      
 305 
     | 
    
         
            +
                          objects.each{|obj| obj.values.delete(delete_rn)}
         
     | 
| 
      
 306 
     | 
    
         
            +
                        end
         
     | 
| 
       300 
307 
     | 
    
         
             
                      elsif strategy == :union
         
     | 
| 
       301 
308 
     | 
    
         
             
                        objects = []
         
     | 
| 
       302 
309 
     | 
    
         
             
                        ds = associated_dataset
         
     | 
| 
       303 
310 
     | 
    
         
             
                        loader = union_eager_loader
         
     | 
| 
       304 
311 
     | 
    
         
             
                        joiner = " UNION ALL "
         
     | 
| 
       305 
312 
     | 
    
         
             
                        ids.each_slice(subqueries_per_union).each do |slice|
         
     | 
| 
       306 
     | 
    
         
            -
                           
     | 
| 
      
 313 
     | 
    
         
            +
                          sql = loader.send(:sql_origin)
         
     | 
| 
      
 314 
     | 
    
         
            +
                          join = false
         
     | 
| 
      
 315 
     | 
    
         
            +
                          slice.each do |k|
         
     | 
| 
      
 316 
     | 
    
         
            +
                            if join
         
     | 
| 
      
 317 
     | 
    
         
            +
                              sql << joiner
         
     | 
| 
      
 318 
     | 
    
         
            +
                            else
         
     | 
| 
      
 319 
     | 
    
         
            +
                              join = true
         
     | 
| 
      
 320 
     | 
    
         
            +
                            end
         
     | 
| 
      
 321 
     | 
    
         
            +
                            loader.append_sql(sql, *k)
         
     | 
| 
      
 322 
     | 
    
         
            +
                          end
         
     | 
| 
      
 323 
     | 
    
         
            +
                          objects.concat(ds.with_sql(sql).to_a)
         
     | 
| 
       307 
324 
     | 
    
         
             
                        end
         
     | 
| 
       308 
325 
     | 
    
         
             
                        ds = ds.eager(cascade) if cascade
         
     | 
| 
       309 
326 
     | 
    
         
             
                        ds.send(:post_load, objects)
         
     | 
| 
         @@ -313,7 +330,7 @@ module Sequel 
     | 
|
| 
       313 
330 
     | 
    
         
             
                        objects = loader.all(ids)
         
     | 
| 
       314 
331 
     | 
    
         
             
                      end
         
     | 
| 
       315 
332 
     | 
    
         | 
| 
       316 
     | 
    
         
            -
                      Sequel.synchronize_with(eo[:mutex]){objects.each(&block)}
         
     | 
| 
      
 333 
     | 
    
         
            +
                      Sequel.synchronize_with(eo[:mutex]){objects.each(&block)} unless no_results
         
     | 
| 
       317 
334 
     | 
    
         | 
| 
       318 
335 
     | 
    
         
             
                      if strategy == :ruby
         
     | 
| 
       319 
336 
     | 
    
         
             
                        apply_ruby_eager_limit_strategy(rows, eager_limit || limit_and_offset)
         
     | 
| 
         @@ -439,7 +456,7 @@ module Sequel 
     | 
|
| 
       439 
456 
     | 
    
         
             
                    def placeholder_loader
         
     | 
| 
       440 
457 
     | 
    
         
             
                      if use_placeholder_loader?
         
     | 
| 
       441 
458 
     | 
    
         
             
                        cached_fetch(:placeholder_loader) do
         
     | 
| 
       442 
     | 
    
         
            -
                           
     | 
| 
      
 459 
     | 
    
         
            +
                          associated_dataset.placeholder_literalizer_loader do |pl, ds|
         
     | 
| 
       443 
460 
     | 
    
         
             
                            ds = ds.where(Sequel.&(*predicate_keys.map{|k| SQL::BooleanExpression.new(:'=', k, pl.arg)}))
         
     | 
| 
       444 
461 
     | 
    
         
             
                            if self[:block]
         
     | 
| 
       445 
462 
     | 
    
         
             
                              ds = self[:block].call(ds)
         
     | 
| 
         @@ -638,9 +655,7 @@ module Sequel 
     | 
|
| 
       638 
655 
     | 
    
         
             
                    # given the hash passed to the eager loader.
         
     | 
| 
       639 
656 
     | 
    
         
             
                    def eager_loading_dataset(eo=OPTS)
         
     | 
| 
       640 
657 
     | 
    
         
             
                      ds = eo[:dataset] || associated_eager_dataset
         
     | 
| 
       641 
     | 
    
         
            -
                       
     | 
| 
       642 
     | 
    
         
            -
                        ds = ds.where(eager_loading_predicate_condition(id_map.keys))
         
     | 
| 
       643 
     | 
    
         
            -
                      end
         
     | 
| 
      
 658 
     | 
    
         
            +
                      ds = eager_loading_set_predicate_condition(ds, eo)
         
     | 
| 
       644 
659 
     | 
    
         
             
                      if associations = eo[:associations]
         
     | 
| 
       645 
660 
     | 
    
         
             
                        ds = ds.eager(associations)
         
     | 
| 
       646 
661 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -667,6 +682,15 @@ module Sequel 
     | 
|
| 
       667 
682 
     | 
    
         
             
                      self[:model].default_eager_limit_strategy || :ruby
         
     | 
| 
       668 
683 
     | 
    
         
             
                    end
         
     | 
| 
       669 
684 
     | 
    
         | 
| 
      
 685 
     | 
    
         
            +
                    # Set the predicate condition for the eager loading dataset based on the id map
         
     | 
| 
      
 686 
     | 
    
         
            +
                    # in the eager loading options.
         
     | 
| 
      
 687 
     | 
    
         
            +
                    def eager_loading_set_predicate_condition(ds, eo)
         
     | 
| 
      
 688 
     | 
    
         
            +
                      if id_map = eo[:id_map]
         
     | 
| 
      
 689 
     | 
    
         
            +
                        ds = ds.where(eager_loading_predicate_condition(id_map.keys))
         
     | 
| 
      
 690 
     | 
    
         
            +
                      end
         
     | 
| 
      
 691 
     | 
    
         
            +
                      ds
         
     | 
| 
      
 692 
     | 
    
         
            +
                    end
         
     | 
| 
      
 693 
     | 
    
         
            +
             
     | 
| 
       670 
694 
     | 
    
         
             
                    # The predicate condition to use for the eager_loader.
         
     | 
| 
       671 
695 
     | 
    
         
             
                    def eager_loading_predicate_condition(keys)
         
     | 
| 
       672 
696 
     | 
    
         
             
                      {predicate_key=>keys}
         
     | 
| 
         @@ -734,8 +758,8 @@ module Sequel 
     | 
|
| 
       734 
758 
     | 
    
         
             
                    # A placeholder literalizer used to speed up eager loading.
         
     | 
| 
       735 
759 
     | 
    
         
             
                    def placeholder_eager_loader
         
     | 
| 
       736 
760 
     | 
    
         
             
                      cached_fetch(:placeholder_eager_loader) do
         
     | 
| 
       737 
     | 
    
         
            -
                         
     | 
| 
       738 
     | 
    
         
            -
                          apply_eager_limit_strategy( 
     | 
| 
      
 761 
     | 
    
         
            +
                        eager_loading_dataset.placeholder_literalizer_loader do |pl, ds|
         
     | 
| 
      
 762 
     | 
    
         
            +
                          apply_eager_limit_strategy(ds.where(predicate_key=>pl.arg), eager_limit_strategy)
         
     | 
| 
       739 
763 
     | 
    
         
             
                        end
         
     | 
| 
       740 
764 
     | 
    
         
             
                      end
         
     | 
| 
       741 
765 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -794,7 +818,7 @@ module Sequel 
     | 
|
| 
       794 
818 
     | 
    
         
             
                    # loading a limited association.
         
     | 
| 
       795 
819 
     | 
    
         
             
                    def union_eager_loader
         
     | 
| 
       796 
820 
     | 
    
         
             
                      cached_fetch(:union_eager_loader) do
         
     | 
| 
       797 
     | 
    
         
            -
                         
     | 
| 
      
 821 
     | 
    
         
            +
                        associated_dataset.placeholder_literalizer_loader do |pl, ds|
         
     | 
| 
       798 
822 
     | 
    
         
             
                          ds = self[:eager_block].call(ds) if self[:eager_block]
         
     | 
| 
       799 
823 
     | 
    
         
             
                          keys = predicate_keys
         
     | 
| 
       800 
824 
     | 
    
         
             
                          ds = ds.where(keys.map{pl.arg}.zip(keys))
         
     | 
| 
         @@ -808,7 +832,7 @@ module Sequel 
     | 
|
| 
       808 
832 
     | 
    
         | 
| 
       809 
833 
     | 
    
         
             
                    # Whether the placeholder loader can be used to load the association.
         
     | 
| 
       810 
834 
     | 
    
         
             
                    def use_placeholder_loader?
         
     | 
| 
       811 
     | 
    
         
            -
                      self[:use_placeholder_loader]
         
     | 
| 
      
 835 
     | 
    
         
            +
                      self[:use_placeholder_loader] && _associated_dataset.supports_placeholder_literalizer?
         
     | 
| 
       812 
836 
     | 
    
         
             
                    end
         
     | 
| 
       813 
837 
     | 
    
         
             
                  end
         
     | 
| 
       814 
838 
     | 
    
         | 
| 
         @@ -1318,7 +1342,7 @@ module Sequel 
     | 
|
| 
       1318 
1342 
     | 
    
         | 
| 
       1319 
1343 
     | 
    
         
             
                    # many_to_many associations need to select a key in an associated table to eagerly load
         
     | 
| 
       1320 
1344 
     | 
    
         
             
                    def eager_loading_use_associated_key?
         
     | 
| 
       1321 
     | 
    
         
            -
                       
     | 
| 
      
 1345 
     | 
    
         
            +
                      !separate_query_per_table?
         
     | 
| 
       1322 
1346 
     | 
    
         
             
                    end
         
     | 
| 
       1323 
1347 
     | 
    
         | 
| 
       1324 
1348 
     | 
    
         
             
                    # The source of the join table.  This is the join table itself, unless it
         
     | 
| 
         @@ -1375,10 +1399,30 @@ module Sequel 
     | 
|
| 
       1375 
1399 
     | 
    
         
             
                      cached_fetch(:select){default_select}
         
     | 
| 
       1376 
1400 
     | 
    
         
             
                    end
         
     | 
| 
       1377 
1401 
     | 
    
         | 
| 
      
 1402 
     | 
    
         
            +
                    # Whether a separate query should be used for the join table.
         
     | 
| 
      
 1403 
     | 
    
         
            +
                    def separate_query_per_table?
         
     | 
| 
      
 1404 
     | 
    
         
            +
                      self[:join_table_db]
         
     | 
| 
      
 1405 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1406 
     | 
    
         
            +
             
     | 
| 
       1378 
1407 
     | 
    
         
             
                    private
         
     | 
| 
       1379 
1408 
     | 
    
         | 
| 
      
 1409 
     | 
    
         
            +
                    # Join to the the join table, unless using a separate query per table.
         
     | 
| 
       1380 
1410 
     | 
    
         
             
                    def _associated_dataset
         
     | 
| 
       1381 
     | 
    
         
            -
                       
     | 
| 
      
 1411 
     | 
    
         
            +
                      if separate_query_per_table?
         
     | 
| 
      
 1412 
     | 
    
         
            +
                        super
         
     | 
| 
      
 1413 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1414 
     | 
    
         
            +
                        super.inner_join(self[:join_table], self[:right_keys].zip(right_primary_keys), :qualify=>:deep)
         
     | 
| 
      
 1415 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1416 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1417 
     | 
    
         
            +
             
     | 
| 
      
 1418 
     | 
    
         
            +
                    # Use the right_keys from the eager loading options if
         
     | 
| 
      
 1419 
     | 
    
         
            +
                    # using a separate query per table.
         
     | 
| 
      
 1420 
     | 
    
         
            +
                    def eager_loading_set_predicate_condition(ds, eo)
         
     | 
| 
      
 1421 
     | 
    
         
            +
                      if separate_query_per_table?
         
     | 
| 
      
 1422 
     | 
    
         
            +
                        ds.where(right_primary_key=>eo[:right_keys])
         
     | 
| 
      
 1423 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1424 
     | 
    
         
            +
                        super
         
     | 
| 
      
 1425 
     | 
    
         
            +
                      end
         
     | 
| 
       1382 
1426 
     | 
    
         
             
                    end
         
     | 
| 
       1383 
1427 
     | 
    
         | 
| 
       1384 
1428 
     | 
    
         
             
                    # The default selection for associations that require joins.  These do not use the default
         
     | 
| 
         @@ -1595,6 +1639,7 @@ module Sequel 
     | 
|
| 
       1595 
1639 
     | 
    
         
             
                    # === Multiple Types
         
     | 
| 
       1596 
1640 
     | 
    
         
             
                    # :adder :: Proc used to define the private _add_* method for doing the database work
         
     | 
| 
       1597 
1641 
     | 
    
         
             
                    #           to associate the given object to the current object (*_to_many assocations).
         
     | 
| 
      
 1642 
     | 
    
         
            +
                    #           Set to nil to not define a add_* method for the association.
         
     | 
| 
       1598 
1643 
     | 
    
         
             
                    # :after_add :: Symbol, Proc, or array of both/either specifying a callback to call
         
     | 
| 
       1599 
1644 
     | 
    
         
             
                    #               after a new item is added to the association.
         
     | 
| 
       1600 
1645 
     | 
    
         
             
                    # :after_load :: Symbol, Proc, or array of both/either specifying a callback to call
         
     | 
| 
         @@ -1605,6 +1650,8 @@ module Sequel 
     | 
|
| 
       1605 
1650 
     | 
    
         
             
                    #               after an item is set using the association setter method.
         
     | 
| 
       1606 
1651 
     | 
    
         
             
                    # :allow_eager :: If set to false, you cannot load the association eagerly
         
     | 
| 
       1607 
1652 
     | 
    
         
             
                    #                 via eager or eager_graph
         
     | 
| 
      
 1653 
     | 
    
         
            +
                    # :allow_eager_graph :: If set to false, you cannot load the association eagerly via eager_graph.
         
     | 
| 
      
 1654 
     | 
    
         
            +
                    # :allow_filtering_by :: If set to false, you cannot use the association when filtering
         
     | 
| 
       1608 
1655 
     | 
    
         
             
                    # :before_add :: Symbol, Proc, or array of both/either specifying a callback to call
         
     | 
| 
       1609 
1656 
     | 
    
         
             
                    #                before a new item is added to the association.
         
     | 
| 
       1610 
1657 
     | 
    
         
             
                    # :before_remove :: Symbol, Proc, or array of both/either specifying a callback to call
         
     | 
| 
         @@ -1623,6 +1670,7 @@ module Sequel 
     | 
|
| 
       1623 
1670 
     | 
    
         
             
                    #                     the class.  <tt>class: 'Foo', class_namespace: 'Bar'</tt> looks for <tt>::Bar::Foo</tt>.)
         
     | 
| 
       1624 
1671 
     | 
    
         
             
                    # :clearer :: Proc used to define the private _remove_all_* method for doing the database work
         
     | 
| 
       1625 
1672 
     | 
    
         
             
                    #             to remove all objects associated to the current object (*_to_many assocations).
         
     | 
| 
      
 1673 
     | 
    
         
            +
                    #             Set to nil to not define a remove_all_* method for the association.
         
     | 
| 
       1626 
1674 
     | 
    
         
             
                    # :clone :: Merge the current options and block into the options and block used in defining
         
     | 
| 
       1627 
1675 
     | 
    
         
             
                    #           the given association.  Can be used to DRY up a bunch of similar associations that
         
     | 
| 
       1628 
1676 
     | 
    
         
             
                    #           all share the same options such as :class and :key, while changing the order and block used.
         
     | 
| 
         @@ -1677,18 +1725,26 @@ module Sequel 
     | 
|
| 
       1677 
1725 
     | 
    
         
             
                    # :graph_only_conditions :: The conditions to use on the SQL join when eagerly loading
         
     | 
| 
       1678 
1726 
     | 
    
         
             
                    #                           the association via +eager_graph+, instead of the default conditions specified by the
         
     | 
| 
       1679 
1727 
     | 
    
         
             
                    #                           foreign/primary keys.  This option causes the :graph_conditions option to be ignored.
         
     | 
| 
       1680 
     | 
    
         
            -
                    # :graph_order ::  
     | 
| 
      
 1728 
     | 
    
         
            +
                    # :graph_order :: the order to use when using eager_graph, instead of the default order.  This should be used
         
     | 
| 
       1681 
1729 
     | 
    
         
             
                    #                 in the case where :order contains an identifier qualified by the table's name, which may not match
         
     | 
| 
       1682 
1730 
     | 
    
         
             
                    #                 the alias used when eager graphing.  By setting this to the unqualified identifier, it will be
         
     | 
| 
       1683 
1731 
     | 
    
         
             
                    #                 automatically qualified when using eager_graph.
         
     | 
| 
       1684 
1732 
     | 
    
         
             
                    # :graph_select :: A column or array of columns to select from the associated table
         
     | 
| 
       1685 
1733 
     | 
    
         
             
                    #                  when eagerly loading the association via +eager_graph+. Defaults to all
         
     | 
| 
       1686 
1734 
     | 
    
         
             
                    #                  columns in the associated table.
         
     | 
| 
      
 1735 
     | 
    
         
            +
                    # :graph_use_association_block :: Makes eager_graph consider the association block. Without this, eager_graph
         
     | 
| 
      
 1736 
     | 
    
         
            +
                    #                                 ignores the bock and only use the :graph_* options.
         
     | 
| 
      
 1737 
     | 
    
         
            +
                    # :instance_specific :: Marks the association as instance specific. Should be used if the association block
         
     | 
| 
      
 1738 
     | 
    
         
            +
                    #                       uses instance specific state, or transient state (accessing current date/time, etc.).
         
     | 
| 
       1687 
1739 
     | 
    
         
             
                    # :limit :: Limit the number of records to the provided value.  Use
         
     | 
| 
       1688 
1740 
     | 
    
         
             
                    #           an array with two elements for the value to specify a
         
     | 
| 
       1689 
1741 
     | 
    
         
             
                    #           limit (first element) and an offset (second element).
         
     | 
| 
       1690 
1742 
     | 
    
         
             
                    # :methods_module :: The module that methods the association creates will be placed into. Defaults
         
     | 
| 
       1691 
1743 
     | 
    
         
             
                    #                    to the module containing the model's columns.
         
     | 
| 
      
 1744 
     | 
    
         
            +
                    # :no_association_method :: Do not add a method for the association. This can save memory if the association
         
     | 
| 
      
 1745 
     | 
    
         
            +
                    #                           method is never used.
         
     | 
| 
      
 1746 
     | 
    
         
            +
                    # :no_dataset_method :: Do not add a method for the association dataset. This can save memory if the dataset
         
     | 
| 
      
 1747 
     | 
    
         
            +
                    #                       method is never used.
         
     | 
| 
       1692 
1748 
     | 
    
         
             
                    # :order :: the column(s) by which to order the association dataset.  Can be a
         
     | 
| 
       1693 
1749 
     | 
    
         
             
                    #           singular column symbol or an array of column symbols.
         
     | 
| 
       1694 
1750 
     | 
    
         
             
                    # :order_eager_graph :: Whether to add the association's order to the graphed dataset's order when graphing
         
     | 
| 
         @@ -1701,6 +1757,7 @@ module Sequel 
     | 
|
| 
       1701 
1757 
     | 
    
         
             
                    #                the current association's key(s).  Set to nil to not use a reciprocal.
         
     | 
| 
       1702 
1758 
     | 
    
         
             
                    # :remover :: Proc used to define the private _remove_* method for doing the database work
         
     | 
| 
       1703 
1759 
     | 
    
         
             
                    #             to remove the association between the given object and the current object (*_to_many assocations).
         
     | 
| 
      
 1760 
     | 
    
         
            +
                    #             Set to nil to not define a remove_* method for the association.
         
     | 
| 
       1704 
1761 
     | 
    
         
             
                    # :select :: the columns to select.  Defaults to the associated class's table_name.* in an association
         
     | 
| 
       1705 
1762 
     | 
    
         
             
                    #            that uses joins, which means it doesn't include the attributes from the
         
     | 
| 
       1706 
1763 
     | 
    
         
             
                    #            join table.  If you want to include the join table attributes, you can
         
     | 
| 
         @@ -1709,6 +1766,7 @@ module Sequel 
     | 
|
| 
       1709 
1766 
     | 
    
         
             
                    #            the same name in both the join table and the associated table.
         
     | 
| 
       1710 
1767 
     | 
    
         
             
                    # :setter :: Proc used to define the private _*= method for doing the work to setup the assocation
         
     | 
| 
       1711 
1768 
     | 
    
         
             
                    #            between the given object and the current object (*_to_one associations).
         
     | 
| 
      
 1769 
     | 
    
         
            +
                    #            Set to nil to not define a setter method for the association.
         
     | 
| 
       1712 
1770 
     | 
    
         
             
                    # :subqueries_per_union :: The number of subqueries to use in each UNION query, for eager
         
     | 
| 
       1713 
1771 
     | 
    
         
             
                    #                          loading limited associations using the default :union strategy.
         
     | 
| 
       1714 
1772 
     | 
    
         
             
                    # :validate :: Set to false to not validate when implicitly saving any associated object.
         
     | 
| 
         @@ -1765,6 +1823,9 @@ module Sequel 
     | 
|
| 
       1765 
1823 
     | 
    
         
             
                    #                underscored, sorted, and joined with '_'.
         
     | 
| 
       1766 
1824 
     | 
    
         
             
                    # :join_table_block :: proc that can be used to modify the dataset used in the add/remove/remove_all
         
     | 
| 
       1767 
1825 
     | 
    
         
             
                    #                      methods.  Should accept a dataset argument and return a modified dataset if present.
         
     | 
| 
      
 1826 
     | 
    
         
            +
                    # :join_table_db :: When retrieving records when using lazy loading or eager loading via +eager+, instead of
         
     | 
| 
      
 1827 
     | 
    
         
            +
                    #                   a join between to the join table and the associated table, use a separate query for the
         
     | 
| 
      
 1828 
     | 
    
         
            +
                    #                   join table using the given Database object.
         
     | 
| 
       1768 
1829 
     | 
    
         
             
                    # :left_key :: foreign key in join table that points to current model's
         
     | 
| 
       1769 
1830 
     | 
    
         
             
                    #              primary key, as a symbol. Defaults to :"#{self.name.underscore}_id".
         
     | 
| 
       1770 
1831 
     | 
    
         
             
                    #              Can use an array of symbols for a composite key association.
         
     | 
| 
         @@ -1794,7 +1855,9 @@ module Sequel 
     | 
|
| 
       1794 
1855 
     | 
    
         | 
| 
       1795 
1856 
     | 
    
         
             
                      if opts[:clone]
         
     | 
| 
       1796 
1857 
     | 
    
         
             
                        cloned_assoc = association_reflection(opts[:clone])
         
     | 
| 
      
 1858 
     | 
    
         
            +
                        remove_class_name = orig_opts[:class] && !orig_opts[:class_name]
         
     | 
| 
       1797 
1859 
     | 
    
         
             
                        orig_opts = cloned_assoc[:orig_opts].merge(orig_opts)
         
     | 
| 
      
 1860 
     | 
    
         
            +
                        orig_opts.delete(:class_name) if remove_class_name
         
     | 
| 
       1798 
1861 
     | 
    
         
             
                      end
         
     | 
| 
       1799 
1862 
     | 
    
         | 
| 
       1800 
1863 
     | 
    
         
             
                      opts = Hash[default_association_options]
         
     | 
| 
         @@ -1812,6 +1875,16 @@ module Sequel 
     | 
|
| 
       1812 
1875 
     | 
    
         
             
                        # in certain places to disable optimizations.
         
     | 
| 
       1813 
1876 
     | 
    
         
             
                        opts[:instance_specific] = _association_instance_specific_default(name)
         
     | 
| 
       1814 
1877 
     | 
    
         
             
                      end
         
     | 
| 
      
 1878 
     | 
    
         
            +
                      if (orig_opts[:instance_specific] || orig_opts[:dataset]) && !opts.has_key?(:allow_eager) && !opts[:eager_loader]
         
     | 
| 
      
 1879 
     | 
    
         
            +
                        # For associations explicitly marked as instance specific, or that use the
         
     | 
| 
      
 1880 
     | 
    
         
            +
                        # :dataset option, where :allow_eager is not set, and no :eager_loader is
         
     | 
| 
      
 1881 
     | 
    
         
            +
                        # provided, disallow eager loading.  In these cases, eager loading is
         
     | 
| 
      
 1882 
     | 
    
         
            +
                        # unlikely to work.  This is not done for implicit setting of :instance_specific,
         
     | 
| 
      
 1883 
     | 
    
         
            +
                        # because implicit use is done by default for all associations with blocks,
         
     | 
| 
      
 1884 
     | 
    
         
            +
                        # and the vast majority of associations with blocks use the block for filtering
         
     | 
| 
      
 1885 
     | 
    
         
            +
                        # in a manner compatible with eager loading.
         
     | 
| 
      
 1886 
     | 
    
         
            +
                        opts[:allow_eager] = false
         
     | 
| 
      
 1887 
     | 
    
         
            +
                      end
         
     | 
| 
       1815 
1888 
     | 
    
         
             
                      opts = assoc_class.new.merge!(opts)
         
     | 
| 
       1816 
1889 
     | 
    
         | 
| 
       1817 
1890 
     | 
    
         
             
                      if opts[:clone] && !opts.cloneable?(cloned_assoc)
         
     | 
| 
         @@ -1841,8 +1914,7 @@ module Sequel 
     | 
|
| 
       1841 
1914 
     | 
    
         
             
                      # Remove :class entry if it exists and is nil, to work with cached_fetch
         
     | 
| 
       1842 
1915 
     | 
    
         
             
                      opts.delete(:class) unless opts[:class]
         
     | 
| 
       1843 
1916 
     | 
    
         | 
| 
       1844 
     | 
    
         
            -
                       
     | 
| 
       1845 
     | 
    
         
            -
                      def_association_instance_methods(opts)
         
     | 
| 
      
 1917 
     | 
    
         
            +
                      def_association(opts)
         
     | 
| 
       1846 
1918 
     | 
    
         | 
| 
       1847 
1919 
     | 
    
         
             
                      orig_opts.delete(:clone)
         
     | 
| 
       1848 
1920 
     | 
    
         
             
                      opts[:orig_class] = orig_opts[:class] || orig_opts[:class_name]
         
     | 
| 
         @@ -1956,6 +2028,13 @@ module Sequel 
     | 
|
| 
       1956 
2028 
     | 
    
         
             
                      association_module(opts).send(:private, name)
         
     | 
| 
       1957 
2029 
     | 
    
         
             
                    end
         
     | 
| 
       1958 
2030 
     | 
    
         | 
| 
      
 2031 
     | 
    
         
            +
                    # Delegate to the type-specific association method to setup the
         
     | 
| 
      
 2032 
     | 
    
         
            +
                    # association, and define the association instance methods.
         
     | 
| 
      
 2033 
     | 
    
         
            +
                    def def_association(opts)
         
     | 
| 
      
 2034 
     | 
    
         
            +
                      send(:"def_#{opts[:type]}", opts)
         
     | 
| 
      
 2035 
     | 
    
         
            +
                      def_association_instance_methods(opts)
         
     | 
| 
      
 2036 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2037 
     | 
    
         
            +
                    
         
     | 
| 
       1959 
2038 
     | 
    
         
             
                    # Adds the association method to the association methods module.
         
     | 
| 
       1960 
2039 
     | 
    
         
             
                    def def_association_method(opts)
         
     | 
| 
       1961 
2040 
     | 
    
         
             
                      association_module_def(opts.association_method, opts) do |dynamic_opts=OPTS, &block|
         
     | 
| 
         @@ -1981,13 +2060,13 @@ module Sequel 
     | 
|
| 
       1981 
2060 
     | 
    
         
             
                        opts[:setter_method] = :"#{opts[:name]}="
         
     | 
| 
       1982 
2061 
     | 
    
         
             
                      end
         
     | 
| 
       1983 
2062 
     | 
    
         | 
| 
       1984 
     | 
    
         
            -
                      association_module_def(opts.dataset_method, opts){_dataset(opts)}
         
     | 
| 
      
 2063 
     | 
    
         
            +
                      association_module_def(opts.dataset_method, opts){_dataset(opts)} unless opts[:no_dataset_method]
         
     | 
| 
       1985 
2064 
     | 
    
         
             
                      if opts[:block]
         
     | 
| 
       1986 
2065 
     | 
    
         
             
                        opts[:block_method] = Plugins.def_sequel_method(association_module(opts), "#{opts[:name]}_block", 1, &opts[:block])
         
     | 
| 
       1987 
2066 
     | 
    
         
             
                      end
         
     | 
| 
       1988 
2067 
     | 
    
         
             
                      opts[:dataset_opt_arity] = opts[:dataset].arity == 0 ? 0 : 1
         
     | 
| 
       1989 
2068 
     | 
    
         
             
                      opts[:dataset_opt_method] = Plugins.def_sequel_method(association_module(opts), "#{opts[:name]}_dataset_opt", opts[:dataset_opt_arity], &opts[:dataset])
         
     | 
| 
       1990 
     | 
    
         
            -
                      def_association_method(opts)
         
     | 
| 
      
 2069 
     | 
    
         
            +
                      def_association_method(opts) unless opts[:no_association_method]
         
     | 
| 
       1991 
2070 
     | 
    
         | 
| 
       1992 
2071 
     | 
    
         
             
                      return if opts[:read_only]
         
     | 
| 
       1993 
2072 
     | 
    
         | 
| 
         @@ -2031,7 +2110,7 @@ module Sequel 
     | 
|
| 
       2031 
2110 
     | 
    
         
             
                        raise(Error, "mismatched number of right keys: #{rcks.inspect} vs #{rcpks.inspect}") unless rcks.length == rcpks.length
         
     | 
| 
       2032 
2111 
     | 
    
         
             
                      end
         
     | 
| 
       2033 
2112 
     | 
    
         
             
                      opts[:uses_left_composite_keys] = lcks.length > 1
         
     | 
| 
       2034 
     | 
    
         
            -
                      opts[:uses_right_composite_keys] = rcks.length > 1
         
     | 
| 
      
 2113 
     | 
    
         
            +
                      uses_rcks = opts[:uses_right_composite_keys] = rcks.length > 1
         
     | 
| 
       2035 
2114 
     | 
    
         
             
                      opts[:cartesian_product_number] ||= one_through_one ? 0 : 1
         
     | 
| 
       2036 
2115 
     | 
    
         
             
                      join_table = (opts[:join_table] ||= opts.default_join_table)
         
     | 
| 
       2037 
2116 
     | 
    
         
             
                      opts[:left_key_alias] ||= opts.default_associated_key_alias
         
     | 
| 
         @@ -2040,8 +2119,75 @@ module Sequel 
     | 
|
| 
       2040 
2119 
     | 
    
         
             
                        opts[:after_load] ||= []
         
     | 
| 
       2041 
2120 
     | 
    
         
             
                        opts[:after_load].unshift(:array_uniq!)
         
     | 
| 
       2042 
2121 
     | 
    
         
             
                      end
         
     | 
| 
       2043 
     | 
    
         
            -
                      opts[: 
     | 
| 
       2044 
     | 
    
         
            -
             
     | 
| 
      
 2122 
     | 
    
         
            +
                      if join_table_db = opts[:join_table_db]
         
     | 
| 
      
 2123 
     | 
    
         
            +
                        opts[:use_placeholder_loader] = false
         
     | 
| 
      
 2124 
     | 
    
         
            +
                        opts[:allow_eager_graph] = false
         
     | 
| 
      
 2125 
     | 
    
         
            +
                        opts[:allow_filtering_by] = false
         
     | 
| 
      
 2126 
     | 
    
         
            +
                        opts[:eager_limit_strategy] = nil
         
     | 
| 
      
 2127 
     | 
    
         
            +
                        join_table_ds = join_table_db.from(join_table)
         
     | 
| 
      
 2128 
     | 
    
         
            +
                        opts[:dataset] ||= proc do |r|
         
     | 
| 
      
 2129 
     | 
    
         
            +
                          vals = join_table_ds.where(lcks.zip(lcpks.map{|k| get_column_value(k)})).select_map(right)
         
     | 
| 
      
 2130 
     | 
    
         
            +
                          ds = r.associated_dataset.where(opts.right_primary_key => vals)
         
     | 
| 
      
 2131 
     | 
    
         
            +
                          if uses_rcks
         
     | 
| 
      
 2132 
     | 
    
         
            +
                            vals.delete_if{|v| v.any?(&:nil?)}
         
     | 
| 
      
 2133 
     | 
    
         
            +
                          else
         
     | 
| 
      
 2134 
     | 
    
         
            +
                            vals.delete(nil)
         
     | 
| 
      
 2135 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2136 
     | 
    
         
            +
                          ds = ds.clone(:no_results=>true) if vals.empty?
         
     | 
| 
      
 2137 
     | 
    
         
            +
                          ds
         
     | 
| 
      
 2138 
     | 
    
         
            +
                        end
         
     | 
| 
      
 2139 
     | 
    
         
            +
                        opts[:eager_loader] ||= proc do |eo|
         
     | 
| 
      
 2140 
     | 
    
         
            +
                          h = eo[:id_map]
         
     | 
| 
      
 2141 
     | 
    
         
            +
                          assign_singular = opts.assign_singular?
         
     | 
| 
      
 2142 
     | 
    
         
            +
                          rpk = opts.right_primary_key
         
     | 
| 
      
 2143 
     | 
    
         
            +
                          name = opts[:name]
         
     | 
| 
      
 2144 
     | 
    
         
            +
             
     | 
| 
      
 2145 
     | 
    
         
            +
                          join_map = join_table_ds.where(left=>h.keys).select_hash_groups(right, left)
         
     | 
| 
      
 2146 
     | 
    
         
            +
             
     | 
| 
      
 2147 
     | 
    
         
            +
                          if uses_rcks
         
     | 
| 
      
 2148 
     | 
    
         
            +
                            join_map.delete_if{|v,| v.any?(&:nil?)}
         
     | 
| 
      
 2149 
     | 
    
         
            +
                          else
         
     | 
| 
      
 2150 
     | 
    
         
            +
                            join_map.delete(nil)
         
     | 
| 
      
 2151 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2152 
     | 
    
         
            +
             
     | 
| 
      
 2153 
     | 
    
         
            +
                          eo = Hash[eo]
         
     | 
| 
      
 2154 
     | 
    
         
            +
             
     | 
| 
      
 2155 
     | 
    
         
            +
                          if join_map.empty?
         
     | 
| 
      
 2156 
     | 
    
         
            +
                            eo[:no_results] = true
         
     | 
| 
      
 2157 
     | 
    
         
            +
                          else
         
     | 
| 
      
 2158 
     | 
    
         
            +
                            join_map.each_value do |vs|
         
     | 
| 
      
 2159 
     | 
    
         
            +
                              vs.replace(vs.flat_map{|v| h[v]})
         
     | 
| 
      
 2160 
     | 
    
         
            +
                              vs.uniq!
         
     | 
| 
      
 2161 
     | 
    
         
            +
                            end
         
     | 
| 
      
 2162 
     | 
    
         
            +
             
     | 
| 
      
 2163 
     | 
    
         
            +
                            eo[:loader] = false
         
     | 
| 
      
 2164 
     | 
    
         
            +
                            eo[:right_keys] = join_map.keys
         
     | 
| 
      
 2165 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2166 
     | 
    
         
            +
             
     | 
| 
      
 2167 
     | 
    
         
            +
                          opts[:model].eager_load_results(opts, eo) do |assoc_record|
         
     | 
| 
      
 2168 
     | 
    
         
            +
                            rpkv = if uses_rcks
         
     | 
| 
      
 2169 
     | 
    
         
            +
                              assoc_record.values.values_at(*rpk)
         
     | 
| 
      
 2170 
     | 
    
         
            +
                            else
         
     | 
| 
      
 2171 
     | 
    
         
            +
                              assoc_record.values[rpk]
         
     | 
| 
      
 2172 
     | 
    
         
            +
                            end
         
     | 
| 
      
 2173 
     | 
    
         
            +
             
     | 
| 
      
 2174 
     | 
    
         
            +
                            objects = join_map[rpkv]
         
     | 
| 
      
 2175 
     | 
    
         
            +
             
     | 
| 
      
 2176 
     | 
    
         
            +
                            if assign_singular
         
     | 
| 
      
 2177 
     | 
    
         
            +
                              objects.each do |object|
         
     | 
| 
      
 2178 
     | 
    
         
            +
                                object.associations[name] ||= assoc_record
         
     | 
| 
      
 2179 
     | 
    
         
            +
                              end
         
     | 
| 
      
 2180 
     | 
    
         
            +
                            else
         
     | 
| 
      
 2181 
     | 
    
         
            +
                              objects.each do |object|
         
     | 
| 
      
 2182 
     | 
    
         
            +
                                object.associations[name].push(assoc_record)
         
     | 
| 
      
 2183 
     | 
    
         
            +
                              end
         
     | 
| 
      
 2184 
     | 
    
         
            +
                            end
         
     | 
| 
      
 2185 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2186 
     | 
    
         
            +
                        end
         
     | 
| 
      
 2187 
     | 
    
         
            +
                      else
         
     | 
| 
      
 2188 
     | 
    
         
            +
                        opts[:dataset] ||= opts.association_dataset_proc
         
     | 
| 
      
 2189 
     | 
    
         
            +
                        opts[:eager_loader] ||= opts.method(:default_eager_loader)
         
     | 
| 
      
 2190 
     | 
    
         
            +
                      end
         
     | 
| 
       2045 
2191 
     | 
    
         | 
| 
       2046 
2192 
     | 
    
         
             
                      join_type = opts[:graph_join_type]
         
     | 
| 
       2047 
2193 
     | 
    
         
             
                      select = opts[:graph_select]
         
     | 
| 
         @@ -2075,50 +2221,60 @@ module Sequel 
     | 
|
| 
       2075 
2221 
     | 
    
         
             
                      return if opts[:read_only]
         
     | 
| 
       2076 
2222 
     | 
    
         | 
| 
       2077 
2223 
     | 
    
         
             
                      if one_through_one
         
     | 
| 
       2078 
     | 
    
         
            -
                        opts 
     | 
| 
       2079 
     | 
    
         
            -
                           
     | 
| 
       2080 
     | 
    
         
            -
             
     | 
| 
       2081 
     | 
    
         
            -
             
     | 
| 
      
 2224 
     | 
    
         
            +
                        unless opts.has_key?(:setter)
         
     | 
| 
      
 2225 
     | 
    
         
            +
                          opts[:setter] = proc do |o|
         
     | 
| 
      
 2226 
     | 
    
         
            +
                            h = {}
         
     | 
| 
      
 2227 
     | 
    
         
            +
                            lh = lcks.zip(lcpks.map{|k| get_column_value(k)})
         
     | 
| 
      
 2228 
     | 
    
         
            +
                            jtds = _join_table_dataset(opts).where(lh)
         
     | 
| 
       2082 
2229 
     | 
    
         | 
| 
       2083 
     | 
    
         
            -
             
     | 
| 
       2084 
     | 
    
         
            -
             
     | 
| 
       2085 
     | 
    
         
            -
             
     | 
| 
       2086 
     | 
    
         
            -
                            if o
         
     | 
| 
       2087 
     | 
    
         
            -
                              new_values = []
         
     | 
| 
       2088 
     | 
    
         
            -
                              rcks.zip(opts.right_primary_key_methods).each{|k, pk| new_values << (h[k] = o.get_column_value(pk))}
         
     | 
| 
       2089 
     | 
    
         
            -
                            end
         
     | 
| 
      
 2230 
     | 
    
         
            +
                            checked_transaction do
         
     | 
| 
      
 2231 
     | 
    
         
            +
                              current = jtds.first
         
     | 
| 
       2090 
2232 
     | 
    
         | 
| 
       2091 
     | 
    
         
            -
                            if current
         
     | 
| 
       2092 
     | 
    
         
            -
                              current_values = rcks.map{|k| current[k]}
         
     | 
| 
       2093 
     | 
    
         
            -
                              jtds = jtds.where(rcks.zip(current_values))
         
     | 
| 
       2094 
2233 
     | 
    
         
             
                              if o
         
     | 
| 
       2095 
     | 
    
         
            -
                                 
     | 
| 
       2096 
     | 
    
         
            -
             
     | 
| 
      
 2234 
     | 
    
         
            +
                                new_values = []
         
     | 
| 
      
 2235 
     | 
    
         
            +
                                rcks.zip(opts.right_primary_key_methods).each{|k, pk| new_values << (h[k] = o.get_column_value(pk))}
         
     | 
| 
      
 2236 
     | 
    
         
            +
                              end
         
     | 
| 
      
 2237 
     | 
    
         
            +
             
     | 
| 
      
 2238 
     | 
    
         
            +
                              if current
         
     | 
| 
      
 2239 
     | 
    
         
            +
                                current_values = rcks.map{|k| current[k]}
         
     | 
| 
      
 2240 
     | 
    
         
            +
                                jtds = jtds.where(rcks.zip(current_values))
         
     | 
| 
      
 2241 
     | 
    
         
            +
                                if o
         
     | 
| 
      
 2242 
     | 
    
         
            +
                                  if current_values != new_values
         
     | 
| 
      
 2243 
     | 
    
         
            +
                                    jtds.update(h)
         
     | 
| 
      
 2244 
     | 
    
         
            +
                                  end
         
     | 
| 
      
 2245 
     | 
    
         
            +
                                else
         
     | 
| 
      
 2246 
     | 
    
         
            +
                                  jtds.delete
         
     | 
| 
       2097 
2247 
     | 
    
         
             
                                end
         
     | 
| 
       2098 
     | 
    
         
            -
                               
     | 
| 
       2099 
     | 
    
         
            -
                                 
     | 
| 
      
 2248 
     | 
    
         
            +
                              elsif o
         
     | 
| 
      
 2249 
     | 
    
         
            +
                                lh.each{|k,v| h[k] = v}
         
     | 
| 
      
 2250 
     | 
    
         
            +
                                jtds.insert(h)
         
     | 
| 
       2100 
2251 
     | 
    
         
             
                              end
         
     | 
| 
       2101 
     | 
    
         
            -
                            elsif o
         
     | 
| 
       2102 
     | 
    
         
            -
                              lh.each{|k,v| h[k] = v}
         
     | 
| 
       2103 
     | 
    
         
            -
                              jtds.insert(h)
         
     | 
| 
       2104 
2252 
     | 
    
         
             
                            end
         
     | 
| 
       2105 
2253 
     | 
    
         
             
                          end
         
     | 
| 
       2106 
2254 
     | 
    
         
             
                        end
         
     | 
| 
       2107 
     | 
    
         
            -
                        opts 
     | 
| 
      
 2255 
     | 
    
         
            +
                        if opts.fetch(:setter, true)
         
     | 
| 
      
 2256 
     | 
    
         
            +
                          opts[:_setter] = proc{|o| set_one_through_one_associated_object(opts, o)}
         
     | 
| 
      
 2257 
     | 
    
         
            +
                        end
         
     | 
| 
       2108 
2258 
     | 
    
         
             
                      else 
         
     | 
| 
       2109 
     | 
    
         
            -
                        opts 
     | 
| 
       2110 
     | 
    
         
            -
                           
     | 
| 
       2111 
     | 
    
         
            -
             
     | 
| 
       2112 
     | 
    
         
            -
             
     | 
| 
       2113 
     | 
    
         
            -
             
     | 
| 
      
 2259 
     | 
    
         
            +
                        unless opts.has_key?(:adder)
         
     | 
| 
      
 2260 
     | 
    
         
            +
                          opts[:adder] = proc do |o|
         
     | 
| 
      
 2261 
     | 
    
         
            +
                            h = {}
         
     | 
| 
      
 2262 
     | 
    
         
            +
                            lcks.zip(lcpks).each{|k, pk| h[k] = get_column_value(pk)}
         
     | 
| 
      
 2263 
     | 
    
         
            +
                            rcks.zip(opts.right_primary_key_methods).each{|k, pk| h[k] = o.get_column_value(pk)}
         
     | 
| 
      
 2264 
     | 
    
         
            +
                            _join_table_dataset(opts).insert(h)
         
     | 
| 
      
 2265 
     | 
    
         
            +
                          end
         
     | 
| 
       2114 
2266 
     | 
    
         
             
                        end
         
     | 
| 
       2115 
2267 
     | 
    
         | 
| 
       2116 
     | 
    
         
            -
                        opts 
     | 
| 
       2117 
     | 
    
         
            -
                           
     | 
| 
      
 2268 
     | 
    
         
            +
                        unless opts.has_key?(:remover)
         
     | 
| 
      
 2269 
     | 
    
         
            +
                          opts[:remover] = proc do |o|
         
     | 
| 
      
 2270 
     | 
    
         
            +
                            _join_table_dataset(opts).where(lcks.zip(lcpks.map{|k| get_column_value(k)}) + rcks.zip(opts.right_primary_key_methods.map{|k| o.get_column_value(k)})).delete
         
     | 
| 
      
 2271 
     | 
    
         
            +
                          end
         
     | 
| 
       2118 
2272 
     | 
    
         
             
                        end
         
     | 
| 
       2119 
2273 
     | 
    
         | 
| 
       2120 
     | 
    
         
            -
                        opts 
     | 
| 
       2121 
     | 
    
         
            -
                           
     | 
| 
      
 2274 
     | 
    
         
            +
                        unless opts.has_key?(:clearer)
         
     | 
| 
      
 2275 
     | 
    
         
            +
                          opts[:clearer] = proc do
         
     | 
| 
      
 2276 
     | 
    
         
            +
                            _join_table_dataset(opts).where(lcks.zip(lcpks.map{|k| get_column_value(k)})).delete
         
     | 
| 
      
 2277 
     | 
    
         
            +
                          end
         
     | 
| 
       2122 
2278 
     | 
    
         
             
                        end
         
     | 
| 
       2123 
2279 
     | 
    
         
             
                      end
         
     | 
| 
       2124 
2280 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -2175,8 +2331,12 @@ module Sequel 
     | 
|
| 
       2175 
2331 
     | 
    
         | 
| 
       2176 
2332 
     | 
    
         
             
                      return if opts[:read_only]
         
     | 
| 
       2177 
2333 
     | 
    
         | 
| 
       2178 
     | 
    
         
            -
                       
     | 
| 
       2179 
     | 
    
         
            -
             
     | 
| 
      
 2334 
     | 
    
         
            +
                      unless opts.has_key?(:setter)
         
     | 
| 
      
 2335 
     | 
    
         
            +
                        opts[:setter] = proc{|o| cks.zip(opts.primary_key_methods).each{|k, pk| set_column_value(:"#{k}=", (o.get_column_value(pk) if o))}}
         
     | 
| 
      
 2336 
     | 
    
         
            +
                      end
         
     | 
| 
      
 2337 
     | 
    
         
            +
                      if opts.fetch(:setter, true)
         
     | 
| 
      
 2338 
     | 
    
         
            +
                        opts[:_setter] = proc{|o| set_associated_object(opts, o)}
         
     | 
| 
      
 2339 
     | 
    
         
            +
                      end
         
     | 
| 
       2180 
2340 
     | 
    
         
             
                    end
         
     | 
| 
       2181 
2341 
     | 
    
         | 
| 
       2182 
2342 
     | 
    
         
             
                    # Configures one_to_many and one_to_one association reflections and adds the related association methods
         
     | 
| 
         @@ -2243,49 +2403,59 @@ module Sequel 
     | 
|
| 
       2243 
2403 
     | 
    
         
             
                      cks.each{|k| ck_nil_hash[k] = nil}
         
     | 
| 
       2244 
2404 
     | 
    
         | 
| 
       2245 
2405 
     | 
    
         
             
                      if one_to_one
         
     | 
| 
       2246 
     | 
    
         
            -
                        opts 
     | 
| 
       2247 
     | 
    
         
            -
                           
     | 
| 
      
 2406 
     | 
    
         
            +
                        unless opts.has_key?(:setter)
         
     | 
| 
      
 2407 
     | 
    
         
            +
                          opts[:setter] = proc do |o|
         
     | 
| 
      
 2408 
     | 
    
         
            +
                            up_ds = _apply_association_options(opts, opts.associated_dataset.where(cks.zip(cpks.map{|k| get_column_value(k)})))
         
     | 
| 
       2248 
2409 
     | 
    
         | 
| 
       2249 
     | 
    
         
            -
             
     | 
| 
       2250 
     | 
    
         
            -
             
     | 
| 
       2251 
     | 
    
         
            -
             
     | 
| 
      
 2410 
     | 
    
         
            +
                            if (froms = up_ds.opts[:from]) && (from = froms[0]) && (from.is_a?(Sequel::Dataset) || (from.is_a?(Sequel::SQL::AliasedExpression) && from.expression.is_a?(Sequel::Dataset)))
         
     | 
| 
      
 2411 
     | 
    
         
            +
                              if old = up_ds.first
         
     | 
| 
      
 2412 
     | 
    
         
            +
                                cks.each{|k| old.set_column_value(:"#{k}=", nil)}
         
     | 
| 
      
 2413 
     | 
    
         
            +
                              end
         
     | 
| 
      
 2414 
     | 
    
         
            +
                              save_old = true
         
     | 
| 
       2252 
2415 
     | 
    
         
             
                            end
         
     | 
| 
       2253 
     | 
    
         
            -
                            save_old = true
         
     | 
| 
       2254 
     | 
    
         
            -
                          end
         
     | 
| 
       2255 
2416 
     | 
    
         | 
| 
       2256 
     | 
    
         
            -
             
     | 
| 
       2257 
     | 
    
         
            -
             
     | 
| 
       2258 
     | 
    
         
            -
             
     | 
| 
      
 2417 
     | 
    
         
            +
                            if o
         
     | 
| 
      
 2418 
     | 
    
         
            +
                              if !o.new? && !save_old
         
     | 
| 
      
 2419 
     | 
    
         
            +
                                up_ds = up_ds.exclude(o.pk_hash)
         
     | 
| 
      
 2420 
     | 
    
         
            +
                              end
         
     | 
| 
      
 2421 
     | 
    
         
            +
                              cks.zip(cpks).each{|k, pk| o.set_column_value(:"#{k}=", get_column_value(pk))}
         
     | 
| 
       2259 
2422 
     | 
    
         
             
                            end
         
     | 
| 
       2260 
     | 
    
         
            -
                            cks.zip(cpks).each{|k, pk| o.set_column_value(:"#{k}=", get_column_value(pk))}
         
     | 
| 
       2261 
     | 
    
         
            -
                          end
         
     | 
| 
       2262 
2423 
     | 
    
         | 
| 
       2263 
     | 
    
         
            -
             
     | 
| 
       2264 
     | 
    
         
            -
             
     | 
| 
       2265 
     | 
    
         
            -
             
     | 
| 
       2266 
     | 
    
         
            -
             
     | 
| 
       2267 
     | 
    
         
            -
             
     | 
| 
       2268 
     | 
    
         
            -
             
     | 
| 
      
 2424 
     | 
    
         
            +
                            checked_transaction do
         
     | 
| 
      
 2425 
     | 
    
         
            +
                              if save_old
         
     | 
| 
      
 2426 
     | 
    
         
            +
                                old.save(save_opts) || raise(Sequel::Error, "invalid previously associated object, cannot save") if old
         
     | 
| 
      
 2427 
     | 
    
         
            +
                              else
         
     | 
| 
      
 2428 
     | 
    
         
            +
                                up_ds.skip_limit_check.update(ck_nil_hash)
         
     | 
| 
      
 2429 
     | 
    
         
            +
                              end
         
     | 
| 
       2269 
2430 
     | 
    
         | 
| 
       2270 
     | 
    
         
            -
             
     | 
| 
      
 2431 
     | 
    
         
            +
                              o.save(save_opts) || raise(Sequel::Error, "invalid associated object, cannot save") if o
         
     | 
| 
      
 2432 
     | 
    
         
            +
                            end
         
     | 
| 
       2271 
2433 
     | 
    
         
             
                          end
         
     | 
| 
       2272 
2434 
     | 
    
         
             
                        end
         
     | 
| 
       2273 
     | 
    
         
            -
                        opts 
     | 
| 
      
 2435 
     | 
    
         
            +
                        if opts.fetch(:setter, true)
         
     | 
| 
      
 2436 
     | 
    
         
            +
                          opts[:_setter] = proc{|o| set_one_to_one_associated_object(opts, o)}
         
     | 
| 
      
 2437 
     | 
    
         
            +
                        end
         
     | 
| 
       2274 
2438 
     | 
    
         
             
                      else 
         
     | 
| 
       2275 
2439 
     | 
    
         
             
                        save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false
         
     | 
| 
       2276 
2440 
     | 
    
         | 
| 
       2277 
     | 
    
         
            -
                        opts 
     | 
| 
       2278 
     | 
    
         
            -
                           
     | 
| 
       2279 
     | 
    
         
            -
             
     | 
| 
      
 2441 
     | 
    
         
            +
                        unless opts.has_key?(:adder)
         
     | 
| 
      
 2442 
     | 
    
         
            +
                          opts[:adder] = proc do |o|
         
     | 
| 
      
 2443 
     | 
    
         
            +
                            cks.zip(cpks).each{|k, pk| o.set_column_value(:"#{k}=", get_column_value(pk))}
         
     | 
| 
      
 2444 
     | 
    
         
            +
                            o.save(save_opts)
         
     | 
| 
      
 2445 
     | 
    
         
            +
                          end
         
     | 
| 
       2280 
2446 
     | 
    
         
             
                        end
         
     | 
| 
       2281 
2447 
     | 
    
         | 
| 
       2282 
     | 
    
         
            -
                        opts 
     | 
| 
       2283 
     | 
    
         
            -
                           
     | 
| 
       2284 
     | 
    
         
            -
             
     | 
| 
      
 2448 
     | 
    
         
            +
                        unless opts.has_key?(:remover)
         
     | 
| 
      
 2449 
     | 
    
         
            +
                          opts[:remover] = proc do |o|
         
     | 
| 
      
 2450 
     | 
    
         
            +
                            cks.each{|k| o.set_column_value(:"#{k}=", nil)}
         
     | 
| 
      
 2451 
     | 
    
         
            +
                            o.save(save_opts)
         
     | 
| 
      
 2452 
     | 
    
         
            +
                          end
         
     | 
| 
       2285 
2453 
     | 
    
         
             
                        end
         
     | 
| 
       2286 
2454 
     | 
    
         | 
| 
       2287 
     | 
    
         
            -
                        opts 
     | 
| 
       2288 
     | 
    
         
            -
                           
     | 
| 
      
 2455 
     | 
    
         
            +
                        unless opts.has_key?(:clearer)
         
     | 
| 
      
 2456 
     | 
    
         
            +
                          opts[:clearer] = proc do
         
     | 
| 
      
 2457 
     | 
    
         
            +
                            _apply_association_options(opts, opts.associated_dataset.where(cks.zip(cpks.map{|k| get_column_value(k)}))).update(ck_nil_hash)
         
     | 
| 
      
 2458 
     | 
    
         
            +
                          end
         
     | 
| 
       2289 
2459 
     | 
    
         
             
                        end
         
     | 
| 
       2290 
2460 
     | 
    
         
             
                      end
         
     | 
| 
       2291 
2461 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -2303,6 +2473,9 @@ module Sequel 
     | 
|
| 
       2303 
2473 
     | 
    
         
             
                    # Return dataset to graph into given the association reflection, applying the :callback option if set.
         
     | 
| 
       2304 
2474 
     | 
    
         
             
                    def eager_graph_dataset(opts, eager_options)
         
     | 
| 
       2305 
2475 
     | 
    
         
             
                      ds = opts.associated_class.dataset
         
     | 
| 
      
 2476 
     | 
    
         
            +
                      if opts[:graph_use_association_block] && (b = opts[:block])
         
     | 
| 
      
 2477 
     | 
    
         
            +
                        ds = b.call(ds)
         
     | 
| 
      
 2478 
     | 
    
         
            +
                      end
         
     | 
| 
       2306 
2479 
     | 
    
         
             
                      if cb = eager_options[:callback]
         
     | 
| 
       2307 
2480 
     | 
    
         
             
                        ds = cb.call(ds)
         
     | 
| 
       2308 
2481 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -2379,7 +2552,7 @@ module Sequel 
     | 
|
| 
       2379 
2552 
     | 
    
         | 
| 
       2380 
2553 
     | 
    
         
             
                    # Dataset for the join table of the given many to many association reflection
         
     | 
| 
       2381 
2554 
     | 
    
         
             
                    def _join_table_dataset(opts)
         
     | 
| 
       2382 
     | 
    
         
            -
                      ds = model.db.from(opts.join_table_source)
         
     | 
| 
      
 2555 
     | 
    
         
            +
                      ds = (opts[:join_table_db] || model.db).from(opts.join_table_source)
         
     | 
| 
       2383 
2556 
     | 
    
         
             
                      opts[:join_table_block] ? opts[:join_table_block].call(ds) : ds
         
     | 
| 
       2384 
2557 
     | 
    
         
             
                    end
         
     | 
| 
       2385 
2558 
     | 
    
         | 
| 
         @@ -2400,7 +2573,12 @@ module Sequel 
     | 
|
| 
       2400 
2573 
     | 
    
         
             
                      if loader = _associated_object_loader(opts, dynamic_opts)
         
     | 
| 
       2401 
2574 
     | 
    
         
             
                        loader.all(*opts.predicate_key_values(self))
         
     | 
| 
       2402 
2575 
     | 
    
         
             
                      else
         
     | 
| 
       2403 
     | 
    
         
            -
                        _associated_dataset(opts, dynamic_opts) 
     | 
| 
      
 2576 
     | 
    
         
            +
                        ds = _associated_dataset(opts, dynamic_opts)
         
     | 
| 
      
 2577 
     | 
    
         
            +
                        if ds.opts[:no_results]
         
     | 
| 
      
 2578 
     | 
    
         
            +
                          []
         
     | 
| 
      
 2579 
     | 
    
         
            +
                        else
         
     | 
| 
      
 2580 
     | 
    
         
            +
                          ds.all
         
     | 
| 
      
 2581 
     | 
    
         
            +
                        end
         
     | 
| 
       2404 
2582 
     | 
    
         
             
                      end
         
     | 
| 
       2405 
2583 
     | 
    
         
             
                    end
         
     | 
| 
       2406 
2584 
     | 
    
         | 
| 
         @@ -2861,6 +3039,8 @@ module Sequel 
     | 
|
| 
       2861 
3039 
     | 
    
         
             
                          (multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (r.respond_to?(:all?) && r.all?{|x| x.is_a?(Sequel::Model)})))))
         
     | 
| 
       2862 
3040 
     | 
    
         
             
                        l = args[0]
         
     | 
| 
       2863 
3041 
     | 
    
         
             
                        if ar = model.association_reflections[l]
         
     | 
| 
      
 3042 
     | 
    
         
            +
                          raise Error, "filtering by associations is not allowed for #{ar.inspect}" if ar[:allow_filtering_by] == false
         
     | 
| 
      
 3043 
     | 
    
         
            +
             
     | 
| 
       2864 
3044 
     | 
    
         
             
                          if multiple
         
     | 
| 
       2865 
3045 
     | 
    
         
             
                            klass = ar.associated_class
         
     | 
| 
       2866 
3046 
     | 
    
         
             
                            if is_ds
         
     | 
| 
         @@ -2982,7 +3162,7 @@ module Sequel 
     | 
|
| 
       2982 
3162 
     | 
    
         | 
| 
       2983 
3163 
     | 
    
         
             
                    # The secondary eager loading method.  Loads all associations in a single query. This
         
     | 
| 
       2984 
3164 
     | 
    
         
             
                    # method should only be used if you need to filter or order based on columns in associated tables,
         
     | 
| 
       2985 
     | 
    
         
            -
                    # or if you have done comparative benchmarking  
     | 
| 
      
 3165 
     | 
    
         
            +
                    # or if you have done comparative benchmarking and determined it is faster.
         
     | 
| 
       2986 
3166 
     | 
    
         
             
                    #
         
     | 
| 
       2987 
3167 
     | 
    
         
             
                    # This method uses <tt>Dataset#graph</tt> to create appropriate aliases for columns in all the
         
     | 
| 
       2988 
3168 
     | 
    
         
             
                    # tables.  Then it uses the graph's metadata to build the associations from the single hash, and
         
     | 
| 
         @@ -3207,8 +3387,15 @@ module Sequel 
     | 
|
| 
       3207 
3387 
     | 
    
         
             
                      local_opts = ds.opts[:eager_graph][:local]
         
     | 
| 
       3208 
3388 
     | 
    
         
             
                      limit_strategy = r.eager_graph_limit_strategy(local_opts[:limit_strategy])
         
     | 
| 
       3209 
3389 
     | 
    
         | 
| 
       3210 
     | 
    
         
            -
                       
     | 
| 
       3211 
     | 
    
         
            -
             
     | 
| 
      
 3390 
     | 
    
         
            +
                      # SEQUEL6: remove and integrate the auto_restrict_eager_graph plugin
         
     | 
| 
      
 3391 
     | 
    
         
            +
                      if !r[:orig_opts].has_key?(:graph_conditions) && !r[:orig_opts].has_key?(:graph_only_conditions) && !r.has_key?(:graph_block) && !r[:allow_eager_graph]
         
     | 
| 
      
 3392 
     | 
    
         
            +
                        if r[:conditions] && !Sequel.condition_specifier?(r[:conditions])
         
     | 
| 
      
 3393 
     | 
    
         
            +
                          raise Error, "Cannot eager_graph association when :conditions specified and not a hash or an array of pairs.  Specify :graph_conditions, :graph_only_conditions, or :graph_block for the association.  Model: #{r[:model]}, association: #{r[:name]}"
         
     | 
| 
      
 3394 
     | 
    
         
            +
                        end
         
     | 
| 
      
 3395 
     | 
    
         
            +
             
     | 
| 
      
 3396 
     | 
    
         
            +
                        if r[:block] && !r[:graph_use_association_block]
         
     | 
| 
      
 3397 
     | 
    
         
            +
                          warn "eager_graph used for association when association given a block without graph options.  The block is ignored in this case.  This will result in an exception starting in Sequel 6.  Model: #{r[:model]}, association: #{r[:name]}"
         
     | 
| 
      
 3398 
     | 
    
         
            +
                        end
         
     | 
| 
       3212 
3399 
     | 
    
         
             
                      end
         
     | 
| 
       3213 
3400 
     | 
    
         | 
| 
       3214 
3401 
     | 
    
         
             
                      ds = loader.call(:self=>ds, :table_alias=>assoc_table_alias, :implicit_qualifier=>(ta == ds.opts[:eager_graph][:master]) ? first_source : qualifier_from_alias_symbol(ta, first_source), :callback=>callback, :join_type=>join_type || local_opts[:join_type], :join_only=>local_opts[:join_only], :limit_strategy=>limit_strategy, :from_self_alias=>ds.opts[:eager_graph][:master])
         
     | 
| 
         @@ -3356,7 +3543,7 @@ module Sequel 
     | 
|
| 
       3356 
3543 
     | 
    
         
             
                    # Allow associations that are eagerly graphed to be specified as an SQL::AliasedExpression, for
         
     | 
| 
       3357 
3544 
     | 
    
         
             
                    # per-call determining of the alias base.
         
     | 
| 
       3358 
3545 
     | 
    
         
             
                    def eager_graph_check_association(model, association)
         
     | 
| 
       3359 
     | 
    
         
            -
                      if association.is_a?(SQL::AliasedExpression)
         
     | 
| 
      
 3546 
     | 
    
         
            +
                      reflection = if association.is_a?(SQL::AliasedExpression)
         
     | 
| 
       3360 
3547 
     | 
    
         
             
                        expr = association.expression
         
     | 
| 
       3361 
3548 
     | 
    
         
             
                        if expr.is_a?(SQL::Identifier)
         
     | 
| 
       3362 
3549 
     | 
    
         
             
                          expr = expr.value
         
     | 
| 
         @@ -3365,10 +3552,17 @@ module Sequel 
     | 
|
| 
       3365 
3552 
     | 
    
         
             
                          end
         
     | 
| 
       3366 
3553 
     | 
    
         
             
                        end
         
     | 
| 
       3367 
3554 
     | 
    
         | 
| 
       3368 
     | 
    
         
            -
                         
     | 
| 
      
 3555 
     | 
    
         
            +
                        check_reflection = check_association(model, expr)
         
     | 
| 
      
 3556 
     | 
    
         
            +
                        SQL::AliasedExpression.new(check_reflection, association.alias || expr, association.columns)
         
     | 
| 
       3369 
3557 
     | 
    
         
             
                      else
         
     | 
| 
       3370 
     | 
    
         
            -
                        check_association(model, association)
         
     | 
| 
      
 3558 
     | 
    
         
            +
                        check_reflection = check_association(model, association)
         
     | 
| 
      
 3559 
     | 
    
         
            +
                      end
         
     | 
| 
      
 3560 
     | 
    
         
            +
             
     | 
| 
      
 3561 
     | 
    
         
            +
                      if check_reflection && check_reflection[:allow_eager_graph] == false
         
     | 
| 
      
 3562 
     | 
    
         
            +
                        raise Error, "eager_graph not allowed for #{reflection.inspect}"
         
     | 
| 
       3371 
3563 
     | 
    
         
             
                      end
         
     | 
| 
      
 3564 
     | 
    
         
            +
             
     | 
| 
      
 3565 
     | 
    
         
            +
                      reflection
         
     | 
| 
       3372 
3566 
     | 
    
         
             
                    end
         
     | 
| 
       3373 
3567 
     | 
    
         | 
| 
       3374 
3568 
     | 
    
         
             
                    # The EagerGraphLoader instance used for converting eager_graph results.
         
     | 
| 
         @@ -3380,11 +3574,11 @@ module Sequel 
     | 
|
| 
       3380 
3574 
     | 
    
         
             
                    end
         
     | 
| 
       3381 
3575 
     | 
    
         | 
| 
       3382 
3576 
     | 
    
         
             
                    # Eagerly load all specified associations.
         
     | 
| 
       3383 
     | 
    
         
            -
                    def eager_load(a, eager_assoc=@opts[:eager])
         
     | 
| 
      
 3577 
     | 
    
         
            +
                    def eager_load(a, eager_assoc=@opts[:eager], m=model)
         
     | 
| 
       3384 
3578 
     | 
    
         
             
                      return if a.empty?
         
     | 
| 
       3385 
3579 
     | 
    
         | 
| 
       3386 
3580 
     | 
    
         
             
                      # Reflections for all associations to eager load
         
     | 
| 
       3387 
     | 
    
         
            -
                      reflections = eager_assoc.keys.map{|assoc|  
     | 
| 
      
 3581 
     | 
    
         
            +
                      reflections = eager_assoc.keys.map{|assoc| m.association_reflection(assoc) || (raise Sequel::UndefinedAssociation, "Model: #{self}, Association: #{assoc}")}
         
     | 
| 
       3388 
3582 
     | 
    
         | 
| 
       3389 
3583 
     | 
    
         
             
                      perform_eager_loads(prepare_eager_load(a, reflections, eager_assoc))
         
     | 
| 
       3390 
3584 
     | 
    
         |