sequel 3.48.0 → 4.0.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 +114 -0
- data/Rakefile +10 -7
- data/doc/association_basics.rdoc +25 -23
- data/doc/code_order.rdoc +7 -0
- data/doc/core_extensions.rdoc +0 -10
- data/doc/object_model.rdoc +4 -1
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.0.0.txt +262 -0
- data/doc/security.rdoc +0 -28
- data/doc/testing.rdoc +8 -14
- data/lib/sequel/adapters/ado.rb +7 -11
- data/lib/sequel/adapters/ado/access.rb +8 -8
- data/lib/sequel/adapters/ado/mssql.rb +4 -4
- data/lib/sequel/adapters/amalgalite.rb +6 -6
- data/lib/sequel/adapters/cubrid.rb +7 -7
- data/lib/sequel/adapters/db2.rb +5 -9
- data/lib/sequel/adapters/dbi.rb +2 -6
- data/lib/sequel/adapters/do.rb +4 -4
- data/lib/sequel/adapters/firebird.rb +4 -4
- data/lib/sequel/adapters/ibmdb.rb +8 -8
- data/lib/sequel/adapters/informix.rb +2 -10
- data/lib/sequel/adapters/jdbc.rb +17 -17
- data/lib/sequel/adapters/jdbc/as400.rb +2 -2
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +2 -2
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
- data/lib/sequel/adapters/jdbc/informix.rb +1 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
- data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
- data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
- data/lib/sequel/adapters/mock.rb +7 -7
- data/lib/sequel/adapters/mysql.rb +3 -3
- data/lib/sequel/adapters/mysql2.rb +4 -4
- data/lib/sequel/adapters/odbc.rb +2 -6
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/openbase.rb +1 -5
- data/lib/sequel/adapters/oracle.rb +13 -17
- data/lib/sequel/adapters/postgres.rb +20 -25
- data/lib/sequel/adapters/shared/cubrid.rb +3 -3
- data/lib/sequel/adapters/shared/db2.rb +2 -2
- data/lib/sequel/adapters/shared/firebird.rb +7 -7
- data/lib/sequel/adapters/shared/mssql.rb +9 -9
- data/lib/sequel/adapters/shared/mysql.rb +29 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
- data/lib/sequel/adapters/shared/oracle.rb +22 -13
- data/lib/sequel/adapters/shared/postgres.rb +61 -46
- data/lib/sequel/adapters/shared/sqlite.rb +9 -9
- data/lib/sequel/adapters/sqlite.rb +17 -11
- data/lib/sequel/adapters/swift.rb +3 -3
- data/lib/sequel/adapters/swift/mysql.rb +1 -1
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +8 -8
- data/lib/sequel/ast_transformer.rb +3 -1
- data/lib/sequel/connection_pool.rb +4 -2
- data/lib/sequel/connection_pool/sharded_single.rb +2 -2
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
- data/lib/sequel/connection_pool/threaded.rb +7 -7
- data/lib/sequel/core.rb +4 -67
- data/lib/sequel/database.rb +1 -0
- data/lib/sequel/database/connecting.rb +2 -8
- data/lib/sequel/database/dataset.rb +2 -7
- data/lib/sequel/database/dataset_defaults.rb +0 -18
- data/lib/sequel/database/features.rb +4 -4
- data/lib/sequel/database/misc.rb +6 -8
- data/lib/sequel/database/query.rb +5 -61
- data/lib/sequel/database/schema_generator.rb +22 -20
- data/lib/sequel/database/schema_methods.rb +48 -20
- data/lib/sequel/database/transactions.rb +7 -17
- data/lib/sequel/dataset.rb +2 -0
- data/lib/sequel/dataset/actions.rb +23 -91
- data/lib/sequel/dataset/features.rb +1 -4
- data/lib/sequel/dataset/graph.rb +3 -47
- data/lib/sequel/dataset/misc.rb +4 -33
- data/lib/sequel/dataset/prepared_statements.rb +3 -1
- data/lib/sequel/dataset/query.rb +116 -240
- data/lib/sequel/dataset/sql.rb +19 -97
- data/lib/sequel/deprecated.rb +0 -16
- data/lib/sequel/exceptions.rb +0 -3
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/columns_introspection.rb +1 -12
- data/lib/sequel/extensions/constraint_validations.rb +3 -3
- data/lib/sequel/extensions/core_extensions.rb +0 -9
- data/lib/sequel/extensions/date_arithmetic.rb +1 -2
- data/lib/sequel/extensions/graph_each.rb +11 -0
- data/lib/sequel/extensions/migration.rb +5 -5
- data/lib/sequel/extensions/null_dataset.rb +11 -13
- data/lib/sequel/extensions/pagination.rb +3 -6
- data/lib/sequel/extensions/pg_array.rb +6 -4
- data/lib/sequel/extensions/pg_array_ops.rb +35 -1
- data/lib/sequel/extensions/pg_json.rb +12 -2
- data/lib/sequel/extensions/pg_json_ops.rb +266 -0
- data/lib/sequel/extensions/pg_range.rb +2 -2
- data/lib/sequel/extensions/pg_range_ops.rb +0 -8
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/pretty_table.rb +0 -4
- data/lib/sequel/extensions/query.rb +3 -8
- data/lib/sequel/extensions/schema_caching.rb +0 -7
- data/lib/sequel/extensions/schema_dumper.rb +10 -17
- data/lib/sequel/extensions/select_remove.rb +0 -4
- data/lib/sequel/extensions/set_overrides.rb +28 -0
- data/lib/sequel/extensions/to_dot.rb +6 -10
- data/lib/sequel/model.rb +6 -7
- data/lib/sequel/model/associations.rb +127 -182
- data/lib/sequel/model/base.rb +88 -211
- data/lib/sequel/model/errors.rb +0 -13
- data/lib/sequel/model/plugins.rb +2 -2
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/after_initialize.rb +11 -17
- data/lib/sequel/plugins/association_autoreloading.rb +1 -47
- data/lib/sequel/plugins/association_dependencies.rb +2 -2
- data/lib/sequel/plugins/auto_validations.rb +2 -8
- data/lib/sequel/plugins/blacklist_security.rb +32 -2
- data/lib/sequel/plugins/caching.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/composition.rb +10 -8
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +4 -0
- data/lib/sequel/plugins/defaults_setter.rb +8 -6
- data/lib/sequel/plugins/dirty.rb +6 -6
- data/lib/sequel/plugins/force_encoding.rb +13 -8
- data/lib/sequel/plugins/hook_class_methods.rb +1 -7
- data/lib/sequel/plugins/json_serializer.rb +13 -74
- data/lib/sequel/plugins/lazy_attributes.rb +2 -4
- data/lib/sequel/plugins/list.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +4 -11
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/optimistic_locking.rb +3 -5
- data/lib/sequel/plugins/pg_array_associations.rb +453 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +5 -4
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +7 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -2
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +19 -4
- data/lib/sequel/plugins/validation_class_methods.rb +0 -30
- data/lib/sequel/plugins/validation_helpers.rb +13 -31
- data/lib/sequel/plugins/xml_serializer.rb +18 -57
- data/lib/sequel/sql.rb +20 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/db2_spec.rb +14 -23
- data/spec/adapters/firebird_spec.rb +25 -29
- data/spec/adapters/informix_spec.rb +11 -14
- data/spec/adapters/mssql_spec.rb +71 -77
- data/spec/adapters/mysql_spec.rb +165 -172
- data/spec/adapters/oracle_spec.rb +36 -39
- data/spec/adapters/postgres_spec.rb +175 -100
- data/spec/adapters/spec_helper.rb +13 -11
- data/spec/adapters/sqlite_spec.rb +36 -44
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +55 -55
- data/spec/core/dataset_spec.rb +45 -249
- data/spec/core/deprecated_spec.rb +0 -8
- data/spec/core/expression_filters_spec.rb +23 -5
- data/spec/core/object_graph_spec.rb +4 -66
- data/spec/core/schema_spec.rb +35 -12
- data/spec/core/spec_helper.rb +3 -2
- data/spec/core_extensions_spec.rb +17 -19
- data/spec/extensions/arbitrary_servers_spec.rb +2 -3
- data/spec/extensions/association_dependencies_spec.rb +14 -14
- data/spec/extensions/auto_validations_spec.rb +7 -0
- data/spec/extensions/blacklist_security_spec.rb +5 -5
- data/spec/extensions/blank_spec.rb +2 -0
- data/spec/extensions/class_table_inheritance_spec.rb +2 -2
- data/spec/extensions/columns_introspection_spec.rb +2 -29
- data/spec/extensions/composition_spec.rb +10 -17
- data/spec/extensions/core_refinements_spec.rb +5 -1
- data/spec/extensions/dataset_associations_spec.rb +18 -0
- data/spec/extensions/date_arithmetic_spec.rb +2 -2
- data/spec/extensions/defaults_setter_spec.rb +9 -9
- data/spec/extensions/dirty_spec.rb +0 -5
- data/spec/extensions/eval_inspect_spec.rb +2 -0
- data/spec/extensions/force_encoding_spec.rb +2 -18
- data/spec/extensions/hash_aliases_spec.rb +8 -0
- data/spec/extensions/hook_class_methods_spec.rb +39 -58
- data/spec/extensions/inflector_spec.rb +2 -0
- data/spec/extensions/instance_filters_spec.rb +8 -8
- data/spec/extensions/json_serializer_spec.rb +1 -41
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +106 -109
- data/spec/extensions/migration_spec.rb +2 -0
- data/spec/extensions/named_timezones_spec.rb +1 -0
- data/spec/extensions/pg_array_associations_spec.rb +603 -0
- data/spec/extensions/pg_array_ops_spec.rb +25 -0
- data/spec/extensions/pg_array_spec.rb +9 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
- data/spec/extensions/pg_hstore_spec.rb +1 -0
- data/spec/extensions/pg_json_ops_spec.rb +131 -0
- data/spec/extensions/pg_json_spec.rb +10 -4
- data/spec/extensions/pg_range_ops_spec.rb +2 -5
- data/spec/extensions/pg_range_spec.rb +6 -2
- data/spec/extensions/pg_row_ops_spec.rb +2 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
- data/spec/extensions/rcte_tree_spec.rb +15 -15
- data/spec/extensions/schema_dumper_spec.rb +0 -1
- data/spec/extensions/schema_spec.rb +9 -9
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +18 -29
- data/spec/extensions/set_overrides_spec.rb +4 -0
- data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
- data/spec/extensions/single_table_inheritance_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +8 -9
- data/spec/extensions/sql_expr_spec.rb +2 -0
- data/spec/extensions/string_date_time_spec.rb +2 -0
- data/spec/extensions/string_stripper_spec.rb +2 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
- data/spec/extensions/thread_local_timezones_spec.rb +2 -0
- data/spec/extensions/timestamps_spec.rb +1 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +24 -24
- data/spec/extensions/tree_spec.rb +7 -7
- data/spec/extensions/typecast_on_load_spec.rb +8 -1
- data/spec/extensions/update_primary_key_spec.rb +10 -10
- data/spec/extensions/validation_class_methods_spec.rb +10 -39
- data/spec/extensions/validation_helpers_spec.rb +29 -47
- data/spec/extensions/xml_serializer_spec.rb +1 -23
- data/spec/integration/associations_test.rb +231 -40
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +64 -64
- data/spec/integration/eager_loader_test.rb +28 -28
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +21 -21
- data/spec/integration/prepared_statement_test.rb +7 -7
- data/spec/integration/schema_test.rb +115 -110
- data/spec/integration/spec_helper.rb +17 -27
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/integration/transaction_test.rb +10 -10
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/association_reflection_spec.rb +2 -28
- data/spec/model/associations_spec.rb +239 -188
- data/spec/model/base_spec.rb +27 -68
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +160 -172
- data/spec/model/hooks_spec.rb +62 -79
- data/spec/model/model_spec.rb +36 -51
- data/spec/model/plugins_spec.rb +5 -19
- data/spec/model/record_spec.rb +125 -151
- data/spec/model/spec_helper.rb +8 -6
- data/spec/model/validations_spec.rb +4 -17
- data/spec/spec_config.rb +2 -10
- metadata +50 -56
- data/lib/sequel/deprecated_core_extensions.rb +0 -135
- data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
- data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
- data/lib/sequel/plugins/identity_map.rb +0 -260
- data/lib/sequel_core.rb +0 -2
- data/lib/sequel_model.rb +0 -2
- data/spec/extensions/association_autoreloading_spec.rb +0 -102
- data/spec/extensions/identity_map_spec.rb +0 -337
- data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
- data/spec/extensions/pg_statement_cache_spec.rb +0 -208
- data/spec/rcov.opts +0 -8
- data/spec/spec_config.rb.example +0 -10
data/spec/model/base_spec.rb
CHANGED
|
@@ -6,7 +6,7 @@ describe "Model attribute setters" do
|
|
|
6
6
|
columns :id, :x, :y, :"x y"
|
|
7
7
|
end
|
|
8
8
|
@o = @c.new
|
|
9
|
-
|
|
9
|
+
DB.reset
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
specify "refresh should return self" do
|
|
@@ -47,7 +47,7 @@ describe "Model.def_column_alias" do
|
|
|
47
47
|
columns :id
|
|
48
48
|
def_column_alias(:id2, :id)
|
|
49
49
|
end.load(:id=>1)
|
|
50
|
-
|
|
50
|
+
DB.reset
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it "should create an getter alias for the column" do
|
|
@@ -412,6 +412,8 @@ describe "Model.db" do
|
|
|
412
412
|
class ModelTest2 < Sequel::Model(@db[:foo])
|
|
413
413
|
db.should == @db
|
|
414
414
|
end
|
|
415
|
+
ModelTest.instance_variable_set(:@db, nil)
|
|
416
|
+
ModelTest.db.should == @db
|
|
415
417
|
ensure
|
|
416
418
|
Object.send(:remove_const, :ModelTest)
|
|
417
419
|
Object.send(:remove_const, :ModelTest2)
|
|
@@ -462,14 +464,6 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
462
464
|
@c.allowed_columns.should == [:x, :y]
|
|
463
465
|
end
|
|
464
466
|
|
|
465
|
-
qspecify "should set the restricted columns correctly" do
|
|
466
|
-
@c.restricted_columns.should == nil
|
|
467
|
-
@c.set_restricted_columns :x
|
|
468
|
-
@c.restricted_columns.should == [:x]
|
|
469
|
-
@c.set_restricted_columns :x, :y
|
|
470
|
-
@c.restricted_columns.should == [:x, :y]
|
|
471
|
-
end
|
|
472
|
-
|
|
473
467
|
it "should only set allowed columns by default" do
|
|
474
468
|
@c.set_allowed_columns :x, :y
|
|
475
469
|
i = @c.new(:x => 1, :y => 2, :z => 3)
|
|
@@ -481,36 +475,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
481
475
|
i = @c.new
|
|
482
476
|
i.update(:x => 7, :z => 9)
|
|
483
477
|
i.values.should == {:x => 7}
|
|
484
|
-
|
|
485
|
-
end
|
|
486
|
-
|
|
487
|
-
qspecify "should not set restricted columns by default" do
|
|
488
|
-
@c.set_restricted_columns :z
|
|
489
|
-
i = @c.new(:x => 1, :y => 2, :z => 3)
|
|
490
|
-
i.values.should == {:x => 1, :y => 2}
|
|
491
|
-
i.set(:x => 4, :y => 5, :z => 6)
|
|
492
|
-
i.values.should == {:x => 4, :y => 5}
|
|
493
|
-
|
|
494
|
-
@c.instance_dataset._fetch = @c.dataset._fetch = {:x => 7}
|
|
495
|
-
i = @c.new
|
|
496
|
-
i.update(:x => 7, :z => 9)
|
|
497
|
-
i.values.should == {:x => 7}
|
|
498
|
-
MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
499
|
-
end
|
|
500
|
-
|
|
501
|
-
qspecify "should have allowed take precedence over restricted" do
|
|
502
|
-
@c.set_allowed_columns :x, :y
|
|
503
|
-
@c.set_restricted_columns :y, :z
|
|
504
|
-
i = @c.new(:x => 1, :y => 2, :z => 3)
|
|
505
|
-
i.values.should == {:x => 1, :y => 2}
|
|
506
|
-
i.set(:x => 4, :y => 5, :z => 6)
|
|
507
|
-
i.values.should == {:x => 4, :y => 5}
|
|
508
|
-
|
|
509
|
-
@c.instance_dataset._fetch = @c.dataset._fetch = {:y => 7}
|
|
510
|
-
i = @c.new
|
|
511
|
-
i.update(:y => 7, :z => 9)
|
|
512
|
-
i.values.should == {:y => 7}
|
|
513
|
-
MODEL_DB.sqls.should == ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
478
|
+
DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
514
479
|
end
|
|
515
480
|
end
|
|
516
481
|
|
|
@@ -569,19 +534,13 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
|
569
534
|
proc{@c.create(:z=>1)}.should raise_error(Sequel::Error)
|
|
570
535
|
c = @c.new
|
|
571
536
|
proc{c.set(:z=>1)}.should raise_error(Sequel::Error)
|
|
572
|
-
proc{c.set_all(:
|
|
537
|
+
proc{c.set_all(:use_after_commit_rollback => false)}.should raise_error(Sequel::Error)
|
|
573
538
|
proc{c.set_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
|
|
574
539
|
proc{c.update(:z=>1)}.should raise_error(Sequel::Error)
|
|
575
|
-
proc{c.update_all(:
|
|
540
|
+
proc{c.update_all(:use_after_commit_rollback=>false)}.should raise_error(Sequel::Error)
|
|
576
541
|
proc{c.update_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
|
|
577
542
|
end
|
|
578
543
|
|
|
579
|
-
qspecify "should raise an error if a missing/restricted column/method is accessed by *_except" do
|
|
580
|
-
c = @c.new
|
|
581
|
-
proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
|
|
582
|
-
proc{c.update_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
|
|
583
|
-
end
|
|
584
|
-
|
|
585
544
|
it "should be disabled by strict_param_setting = false" do
|
|
586
545
|
@c.strict_param_setting = false
|
|
587
546
|
@c.strict_param_setting.should == false
|
|
@@ -591,9 +550,9 @@ end
|
|
|
591
550
|
|
|
592
551
|
describe Sequel::Model, ".require_modification" do
|
|
593
552
|
before do
|
|
594
|
-
@ds1 =
|
|
553
|
+
@ds1 = DB[:items]
|
|
595
554
|
def @ds1.provides_accurate_rows_matched?() false end
|
|
596
|
-
@ds2 =
|
|
555
|
+
@ds2 = DB[:items]
|
|
597
556
|
def @ds2.provides_accurate_rows_matched?() true end
|
|
598
557
|
end
|
|
599
558
|
after do
|
|
@@ -618,7 +577,7 @@ end
|
|
|
618
577
|
|
|
619
578
|
describe Sequel::Model, ".[] optimization" do
|
|
620
579
|
before do
|
|
621
|
-
@db =
|
|
580
|
+
@db = DB.clone
|
|
622
581
|
@db.quote_identifiers = true
|
|
623
582
|
@c = Class.new(Sequel::Model(@db))
|
|
624
583
|
end
|
|
@@ -700,47 +659,47 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
|
700
659
|
@c = Class.new(Sequel::Model(:a))
|
|
701
660
|
@ds = @c.dataset
|
|
702
661
|
@ds._fetch = {:id=>1}
|
|
703
|
-
|
|
662
|
+
DB.reset
|
|
704
663
|
end
|
|
705
664
|
|
|
706
665
|
it "should be callable on the model class with optimized SQL" do
|
|
707
666
|
@c.with_pk(1).should == @c.load(:id=>1)
|
|
708
|
-
|
|
667
|
+
DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
|
709
668
|
@c.with_pk!(1).should == @c.load(:id=>1)
|
|
710
|
-
|
|
669
|
+
DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
|
711
670
|
end
|
|
712
671
|
|
|
713
672
|
it "should return the first record where the primary key matches" do
|
|
714
673
|
@ds.with_pk(1).should == @c.load(:id=>1)
|
|
715
|
-
|
|
674
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
716
675
|
@ds.with_pk!(1).should == @c.load(:id=>1)
|
|
717
|
-
|
|
676
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
718
677
|
end
|
|
719
678
|
|
|
720
679
|
it "should handle existing filters" do
|
|
721
680
|
@ds.filter(:a=>2).with_pk(1)
|
|
722
|
-
|
|
681
|
+
DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
|
|
723
682
|
@ds.filter(:a=>2).with_pk!(1)
|
|
724
|
-
|
|
683
|
+
DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
|
|
725
684
|
end
|
|
726
685
|
|
|
727
686
|
it "should work with string values" do
|
|
728
687
|
@ds.with_pk("foo")
|
|
729
|
-
|
|
688
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
|
|
730
689
|
@ds.with_pk!("foo")
|
|
731
|
-
|
|
690
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
|
|
732
691
|
end
|
|
733
692
|
|
|
734
693
|
it "should handle an array for composite primary keys" do
|
|
735
694
|
@c.set_primary_key [:id1, :id2]
|
|
736
695
|
@ds.with_pk([1, 2])
|
|
737
|
-
sqls =
|
|
696
|
+
sqls = DB.sqls
|
|
738
697
|
["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
|
|
739
698
|
"SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
|
|
740
699
|
sqls.should == []
|
|
741
700
|
|
|
742
701
|
@ds.with_pk!([1, 2])
|
|
743
|
-
sqls =
|
|
702
|
+
sqls = DB.sqls
|
|
744
703
|
["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
|
|
745
704
|
"SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
|
|
746
705
|
sqls.should == []
|
|
@@ -749,26 +708,26 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
|
749
708
|
it "should have with_pk return nil and with_pk! raise if no rows match" do
|
|
750
709
|
@ds._fetch = []
|
|
751
710
|
@ds.with_pk(1).should == nil
|
|
752
|
-
|
|
711
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
753
712
|
proc{@ds.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
|
|
754
|
-
|
|
713
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
755
714
|
end
|
|
756
715
|
|
|
757
716
|
it "should have with_pk return nil and with_pk! raise if no rows match when calling the class method" do
|
|
758
717
|
@ds._fetch = []
|
|
759
718
|
@c.with_pk(1).should == nil
|
|
760
|
-
|
|
719
|
+
DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
|
761
720
|
proc{@c.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
|
|
762
|
-
|
|
721
|
+
DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
|
763
722
|
end
|
|
764
723
|
|
|
765
724
|
it "should have #[] consider an integer as a primary key lookup" do
|
|
766
725
|
@ds[1].should == @c.load(:id=>1)
|
|
767
|
-
|
|
726
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
768
727
|
end
|
|
769
728
|
|
|
770
729
|
it "should not have #[] consider a string as a primary key lookup" do
|
|
771
730
|
@ds['foo'].should == @c.load(:id=>1)
|
|
772
|
-
|
|
731
|
+
DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
|
773
732
|
end
|
|
774
733
|
end
|
|
@@ -10,7 +10,7 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
|
|
|
10
10
|
end
|
|
11
11
|
@d = @c.dataset
|
|
12
12
|
@d._fetch = [{:id=>1}, {:id=>2}]
|
|
13
|
-
|
|
13
|
+
DB.reset
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "should instantiate objects in the dataset and call destroy on each" do
|
|
@@ -28,13 +28,13 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
|
|
|
28
28
|
it "should use a transaction if use_transactions is true for the model" do
|
|
29
29
|
@c.use_transactions = true
|
|
30
30
|
@d.destroy
|
|
31
|
-
|
|
31
|
+
DB.sqls.should == ["BEGIN", "SELECT * FROM items", "COMMIT"]
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
it "should not use a transaction if use_transactions is false for the model" do
|
|
35
35
|
@c.use_transactions = false
|
|
36
36
|
@d.destroy
|
|
37
|
-
|
|
37
|
+
DB.sqls.should == ["SELECT * FROM items"]
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -82,7 +82,7 @@ describe Sequel::Model::DatasetMethods do
|
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
specify "#join_table should handle model classes that aren't simple selects using a subselect" do
|
|
85
|
-
@c.join(Class.new(Sequel::Model(
|
|
85
|
+
@c.join(Class.new(Sequel::Model(DB[:categories].where(:foo=>1))), :item_id => :id).sql.should == 'SELECT * FROM items INNER JOIN (SELECT * FROM categories WHERE (foo = 1)) AS t1 ON (t1.item_id = items.id)'
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
specify "#graph should allow use to use a model class when joining" do
|
|
@@ -92,7 +92,7 @@ describe Sequel::Model, "#eager" do
|
|
|
92
92
|
h
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
DB.reset
|
|
96
96
|
end
|
|
97
97
|
after do
|
|
98
98
|
[:EagerAlbum, :EagerBand, :EagerTrack, :EagerGenre, :EagerBandMember].each{|x| Object.send(:remove_const, x)}
|
|
@@ -124,29 +124,39 @@ describe Sequel::Model, "#eager" do
|
|
|
124
124
|
|
|
125
125
|
it "should eagerly load a single many_to_one association" do
|
|
126
126
|
a = EagerAlbum.eager(:band).all
|
|
127
|
-
|
|
127
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
128
128
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
129
129
|
a.first.band.should == EagerBand.load(:id=>2)
|
|
130
|
-
|
|
130
|
+
DB.sqls.should == []
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
it "should eagerly load a single many_to_one association with the same name as the column" do
|
|
134
134
|
EagerAlbum.def_column_alias(:band_id_id, :band_id)
|
|
135
135
|
EagerAlbum.many_to_one :band_id, :key_column=>:band_id, :class=>EagerBand
|
|
136
136
|
a = EagerAlbum.eager(:band_id).all
|
|
137
|
-
|
|
137
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
138
138
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
139
139
|
a.first.band_id.should == EagerBand.load(:id=>2)
|
|
140
|
-
|
|
140
|
+
DB.sqls.should == []
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should eagerly load a single one_to_one association" do
|
|
144
144
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
145
145
|
a = EagerAlbum.eager(:track).all
|
|
146
146
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
147
|
-
|
|
147
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
148
148
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
149
|
-
|
|
149
|
+
DB.sqls.should == []
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should use first matching entry when eager loading one_to_one association" do
|
|
153
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
154
|
+
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
|
155
|
+
a = EagerAlbum.eager(:track).all
|
|
156
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
157
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
158
|
+
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
159
|
+
DB.sqls.should == []
|
|
150
160
|
end
|
|
151
161
|
|
|
152
162
|
it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
|
|
@@ -154,87 +164,76 @@ describe Sequel::Model, "#eager" do
|
|
|
154
164
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true
|
|
155
165
|
a = EagerAlbum.eager(:track).all
|
|
156
166
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
157
|
-
|
|
167
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT DISTINCT ON (tracks.album_id) * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY tracks.album_id']
|
|
158
168
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
159
|
-
|
|
169
|
+
DB.sqls.should == []
|
|
160
170
|
end
|
|
161
171
|
|
|
162
172
|
it "should eagerly load a single one_to_one association using the :window_function strategy" do
|
|
163
173
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
164
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true
|
|
174
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy=>true
|
|
165
175
|
a = EagerAlbum.eager(:track).all
|
|
166
176
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
167
|
-
|
|
177
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)']
|
|
168
178
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
169
|
-
|
|
179
|
+
DB.sqls.should == []
|
|
170
180
|
end
|
|
171
181
|
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
it "should not use distinct on eager limit strategy if the association has an offset" do
|
|
183
|
+
def (EagerTrack.dataset).supports_distinct_on?() true end
|
|
184
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
185
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :order=>:name
|
|
174
186
|
a = EagerAlbum.eager(:track).all
|
|
175
187
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
176
|
-
|
|
188
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 2)']
|
|
177
189
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
178
|
-
|
|
190
|
+
DB.sqls.should == []
|
|
179
191
|
end
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :
|
|
193
|
+
it "should automatically use an eager limit stategy if the association has an offset" do
|
|
194
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
|
|
195
|
+
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
|
183
196
|
a = EagerAlbum.eager(:track).all
|
|
184
197
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
185
|
-
|
|
186
|
-
a.first.track.should == EagerTrack.load(:id =>
|
|
187
|
-
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
qspecify "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
|
|
191
|
-
c1 = Class.new(EagerAlbum)
|
|
192
|
-
c2 = Class.new(EagerTrack)
|
|
193
|
-
c1.set_primary_key [:id, :band_id]
|
|
194
|
-
c2.set_primary_key [:id, :album_id]
|
|
195
|
-
c1.one_to_one :track, :class=>c2, :key=>[:album_id, :id], :eager_limit_strategy=>:correlated_subquery
|
|
196
|
-
c2.dataset._fetch = {:id => 2, :album_id=>1}
|
|
197
|
-
a = c1.eager(:track).all
|
|
198
|
-
a.should == [c1.load(:id => 1, :band_id => 2)]
|
|
199
|
-
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (((tracks.album_id, tracks.id) IN ((1, 2))) AND ((tracks.id, tracks.album_id) IN (SELECT t1.id, t1.album_id FROM tracks AS t1 WHERE ((t1.album_id = tracks.album_id) AND (t1.id = tracks.id)) LIMIT 1)))']
|
|
200
|
-
a.first.track.should == c2.load(:id => 2, :album_id=>1)
|
|
201
|
-
MODEL_DB.sqls.should == []
|
|
198
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
199
|
+
a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
|
|
200
|
+
DB.sqls.should == []
|
|
202
201
|
end
|
|
203
202
|
|
|
204
203
|
it "should eagerly load a single one_to_many association" do
|
|
205
204
|
a = EagerAlbum.eager(:tracks).all
|
|
206
205
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
207
|
-
|
|
206
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
208
207
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
209
|
-
|
|
208
|
+
DB.sqls.should == []
|
|
210
209
|
end
|
|
211
210
|
|
|
212
211
|
it "should eagerly load a single many_to_many association" do
|
|
213
212
|
a = EagerAlbum.eager(:genres).all
|
|
214
213
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
215
|
-
|
|
214
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
216
215
|
a.first.genres.should == [EagerGenre.load(:id=>4)]
|
|
217
|
-
|
|
216
|
+
DB.sqls.should == []
|
|
218
217
|
end
|
|
219
218
|
|
|
220
219
|
it "should support using a custom :key option when eager loading many_to_one associations" do
|
|
221
220
|
EagerAlbum.many_to_one :sband, :clone=>:band, :key=>:band_id3
|
|
222
221
|
EagerBand.dataset._fetch = {:id=>6}
|
|
223
222
|
a = EagerAlbum.eager(:sband).all
|
|
224
|
-
|
|
223
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (6))']
|
|
225
224
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
226
225
|
a.first.sband.should == EagerBand.load(:id=>6)
|
|
227
|
-
|
|
226
|
+
DB.sqls.should == []
|
|
228
227
|
end
|
|
229
228
|
|
|
230
229
|
it "should support using a custom :primary_key option when eager loading one_to_many associations" do
|
|
231
230
|
EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
|
|
232
231
|
EagerBand.dataset._fetch = {:id=>6}
|
|
233
232
|
a = EagerBand.eager(:salbums).all
|
|
234
|
-
|
|
233
|
+
DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
|
|
235
234
|
a.should == [EagerBand.load(:id => 6)]
|
|
236
235
|
a.first.salbums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
237
|
-
|
|
236
|
+
DB.sqls.should == []
|
|
238
237
|
end
|
|
239
238
|
|
|
240
239
|
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
|
@@ -242,38 +241,38 @@ describe Sequel::Model, "#eager" do
|
|
|
242
241
|
EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
|
|
243
242
|
a = EagerAlbum.eager(:sgenres).all
|
|
244
243
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
245
|
-
|
|
244
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (6)))"]
|
|
246
245
|
a.first.sgenres.should == [EagerGenre.load(:id=>4)]
|
|
247
|
-
|
|
246
|
+
DB.sqls.should == []
|
|
248
247
|
end
|
|
249
248
|
|
|
250
249
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_one associations" do
|
|
251
250
|
EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>Sequel./(:bands__id, 3), :primary_key_method=>:id3
|
|
252
251
|
EagerBand.dataset._fetch = {:id=>6}
|
|
253
252
|
a = EagerAlbum.eager(:sband).all
|
|
254
|
-
|
|
253
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
|
|
255
254
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
256
255
|
a.first.sband.should == EagerBand.load(:id=>6)
|
|
257
|
-
|
|
256
|
+
DB.sqls.should == []
|
|
258
257
|
end
|
|
259
258
|
|
|
260
259
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
|
|
261
260
|
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
|
|
262
261
|
EagerBand.dataset._fetch = {:id=>6}
|
|
263
262
|
a = EagerBand.eager(:salbums).all
|
|
264
|
-
|
|
263
|
+
DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
|
|
265
264
|
a.should == [EagerBand.load(:id => 6)]
|
|
266
265
|
a.first.salbums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
267
|
-
|
|
266
|
+
DB.sqls.should == []
|
|
268
267
|
end
|
|
269
268
|
|
|
270
269
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_many associations" do
|
|
271
270
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
|
|
272
271
|
a = EagerAlbum.eager(:sgenres).all
|
|
273
272
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
274
|
-
|
|
273
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND ((ag.album_id * 1) IN (1)))"]
|
|
275
274
|
a.first.sgenres.should == [EagerGenre.load(:id=>4)]
|
|
276
|
-
|
|
275
|
+
DB.sqls.should == []
|
|
277
276
|
end
|
|
278
277
|
|
|
279
278
|
it "should raise an error for an unhandled :eager_loader_key option" do
|
|
@@ -294,19 +293,19 @@ describe Sequel::Model, "#eager" do
|
|
|
294
293
|
it "should correctly handle a :select=>[] option to many_to_many" do
|
|
295
294
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :select=>[]
|
|
296
295
|
EagerAlbum.eager(:sgenres).all
|
|
297
|
-
|
|
296
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
298
297
|
end
|
|
299
298
|
|
|
300
299
|
it "should correctly handle an aliased join table in many_to_many" do
|
|
301
300
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
|
302
301
|
EagerAlbum.eager(:sgenres).all
|
|
303
|
-
|
|
302
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON ((ga.genre_id = genres.id) AND (ga.album_id IN (1)))"]
|
|
304
303
|
end
|
|
305
304
|
|
|
306
305
|
it "should eagerly load multiple associations in a single call" do
|
|
307
306
|
a = EagerAlbum.eager(:genres, :tracks, :band).all
|
|
308
307
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
309
|
-
sqls =
|
|
308
|
+
sqls = DB.sqls
|
|
310
309
|
sqls.shift.should == 'SELECT * FROM albums'
|
|
311
310
|
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
312
311
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
@@ -315,13 +314,13 @@ describe Sequel::Model, "#eager" do
|
|
|
315
314
|
a.band.should == EagerBand.load(:id=>2)
|
|
316
315
|
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
317
316
|
a.genres.should == [EagerGenre.load(:id => 4)]
|
|
318
|
-
|
|
317
|
+
DB.sqls.should == []
|
|
319
318
|
end
|
|
320
319
|
|
|
321
320
|
it "should eagerly load multiple associations in separate calls" do
|
|
322
321
|
a = EagerAlbum.eager(:genres).eager(:tracks).eager(:band).all
|
|
323
322
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
324
|
-
sqls =
|
|
323
|
+
sqls = DB.sqls
|
|
325
324
|
sqls.shift.should == 'SELECT * FROM albums'
|
|
326
325
|
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
327
326
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
@@ -330,13 +329,13 @@ describe Sequel::Model, "#eager" do
|
|
|
330
329
|
a.band.should == EagerBand.load(:id=>2)
|
|
331
330
|
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
332
331
|
a.genres.should == [EagerGenre.load(:id => 4)]
|
|
333
|
-
|
|
332
|
+
DB.sqls.should == []
|
|
334
333
|
end
|
|
335
334
|
|
|
336
335
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
337
336
|
a = EagerTrack.eager(:album=>{:band=>:members}).all
|
|
338
337
|
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
339
|
-
|
|
338
|
+
DB.sqls.should == ['SELECT * FROM tracks',
|
|
340
339
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
341
340
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
342
341
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
@@ -344,41 +343,41 @@ describe Sequel::Model, "#eager" do
|
|
|
344
343
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
345
344
|
a.album.band.should == EagerBand.load(:id => 2)
|
|
346
345
|
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
347
|
-
|
|
346
|
+
DB.sqls.should == []
|
|
348
347
|
end
|
|
349
348
|
|
|
350
349
|
it "should cascade eagerly loading when the :eager association option is used" do
|
|
351
350
|
a = EagerBand.eager(:albums).all
|
|
352
351
|
a.should == [EagerBand.load(:id=>2)]
|
|
353
|
-
|
|
352
|
+
DB.sqls.should == ['SELECT * FROM bands',
|
|
354
353
|
'SELECT * FROM albums WHERE (albums.band_id IN (2))',
|
|
355
354
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
356
355
|
a.first.albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
357
356
|
a.first.albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
358
|
-
|
|
357
|
+
DB.sqls.should == []
|
|
359
358
|
end
|
|
360
359
|
|
|
361
360
|
it "should respect :eager when lazily loading an association" do
|
|
362
361
|
a = EagerBand.all
|
|
363
362
|
a.should == [EagerBand.load(:id=>2)]
|
|
364
|
-
|
|
363
|
+
DB.sqls.should == ['SELECT * FROM bands']
|
|
365
364
|
a = a.first.albums
|
|
366
|
-
|
|
365
|
+
DB.sqls.should == ['SELECT * FROM albums WHERE (albums.band_id = 2)',
|
|
367
366
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
368
367
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
369
368
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
370
|
-
|
|
369
|
+
DB.sqls.should == []
|
|
371
370
|
end
|
|
372
371
|
|
|
373
372
|
it "should cascade eagerly loading when the :eager_graph association option is used" do
|
|
374
373
|
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
375
374
|
a = EagerBand.eager(:graph_albums).all
|
|
376
375
|
a.should == [EagerBand.load(:id=>2)]
|
|
377
|
-
|
|
376
|
+
DB.sqls.should == ['SELECT * FROM bands',
|
|
378
377
|
'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id IN (2))']
|
|
379
378
|
a.first.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
380
379
|
a.first.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
381
|
-
|
|
380
|
+
DB.sqls.should == []
|
|
382
381
|
end
|
|
383
382
|
|
|
384
383
|
it "should raise an Error when eager loading a many_to_many association with the :eager_graph option" do
|
|
@@ -388,14 +387,14 @@ describe Sequel::Model, "#eager" do
|
|
|
388
387
|
it "should respect :eager_graph when lazily loading an association" do
|
|
389
388
|
a = EagerBand.all
|
|
390
389
|
a.should == [EagerBand.load(:id=>2)]
|
|
391
|
-
|
|
390
|
+
DB.sqls.should == ['SELECT * FROM bands']
|
|
392
391
|
a = a.first
|
|
393
392
|
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
394
393
|
a.graph_albums
|
|
395
|
-
|
|
394
|
+
DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id = 2)']
|
|
396
395
|
a.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
397
396
|
a.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
398
|
-
|
|
397
|
+
DB.sqls.should == []
|
|
399
398
|
end
|
|
400
399
|
|
|
401
400
|
it "should respect :eager_graph when lazily loading a many_to_many association" do
|
|
@@ -404,70 +403,70 @@ describe Sequel::Model, "#eager" do
|
|
|
404
403
|
ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
|
|
405
404
|
a = EagerBand.load(:id=>2)
|
|
406
405
|
a.graph_members.should == [EagerBandMember.load(:id=>5)]
|
|
407
|
-
|
|
406
|
+
DB.sqls.should == ['SELECT members.id, bands.id AS bands_id, bands.p_k FROM (SELECT members.* FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id = 2))) AS members LEFT OUTER JOIN bm AS bm_0 ON (bm_0.member_id = members.id) LEFT OUTER JOIN bands ON (bands.id = bm_0.band_id) ORDER BY bands.id']
|
|
408
407
|
a.graph_members.first.bands.should == [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
|
|
409
|
-
|
|
408
|
+
DB.sqls.should == []
|
|
410
409
|
end
|
|
411
410
|
|
|
412
411
|
it "should respect :conditions when eagerly loading" do
|
|
413
412
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
|
|
414
413
|
a = EagerBandMember.eager(:good_bands).all
|
|
415
414
|
a.should == [EagerBandMember.load(:id => 5)]
|
|
416
|
-
|
|
415
|
+
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (a = 32) ORDER BY id']
|
|
417
416
|
a.first.good_bands.should == [EagerBand.load(:id => 2)]
|
|
418
|
-
|
|
417
|
+
DB.sqls.should == []
|
|
419
418
|
|
|
420
419
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
|
421
420
|
a = EagerBandMember.eager(:good_bands).all
|
|
422
|
-
|
|
421
|
+
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (x = 1) ORDER BY id']
|
|
423
422
|
end
|
|
424
423
|
|
|
425
424
|
it "should respect :order when eagerly loading" do
|
|
426
425
|
a = EagerBandMember.eager(:bands).all
|
|
427
426
|
a.should == [EagerBandMember.load(:id => 5)]
|
|
428
|
-
|
|
427
|
+
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) ORDER BY id']
|
|
429
428
|
a.first.bands.should == [EagerBand.load(:id => 2)]
|
|
430
|
-
|
|
429
|
+
DB.sqls.should == []
|
|
431
430
|
end
|
|
432
431
|
|
|
433
432
|
it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
|
|
434
433
|
a = EagerAlbum.eager(:tracks).all
|
|
435
434
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
436
|
-
|
|
435
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
437
436
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
438
437
|
a.first.tracks.first.album.should == a.first
|
|
439
|
-
|
|
438
|
+
DB.sqls.should == []
|
|
440
439
|
end
|
|
441
440
|
|
|
442
441
|
it "should cache the negative lookup when eagerly loading a many_to_one association" do
|
|
443
442
|
a = EagerAlbum.eager(:band).filter(:id=>101).all
|
|
444
443
|
a.should == [EagerAlbum.load(:id => 101, :band_id => 101)]
|
|
445
|
-
|
|
444
|
+
DB.sqls.should == ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
|
|
446
445
|
a.first.associations.fetch(:band, 2).should be_nil
|
|
447
446
|
a.first.band.should be_nil
|
|
448
|
-
|
|
447
|
+
DB.sqls.should == []
|
|
449
448
|
end
|
|
450
449
|
|
|
451
450
|
it "should cache the negative lookup when eagerly loading a *_to_many associations" do
|
|
452
451
|
a = EagerBand.eager(:albums).filter('id > 100').all
|
|
453
452
|
a.should == [EagerBand.load(:id => 101), EagerBand.load(:id =>102)]
|
|
454
|
-
sqls =
|
|
453
|
+
sqls = DB.sqls
|
|
455
454
|
['SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', 'SELECT * FROM albums WHERE (albums.band_id IN (102, 101))'].should include(sqls.delete_at(1))
|
|
456
455
|
sqls.should == ['SELECT * FROM bands WHERE (id > 100)', "SELECT * FROM tracks WHERE (tracks.album_id IN (101))"]
|
|
457
456
|
a.map{|b| b.associations[:albums]}.should == [[EagerAlbum.load({:band_id=>101, :id=>101})], []]
|
|
458
|
-
|
|
457
|
+
DB.sqls.should == []
|
|
459
458
|
end
|
|
460
459
|
|
|
461
460
|
it "should use the association's block when eager loading by default" do
|
|
462
461
|
EagerAlbum.eager(:good_tracks).all
|
|
463
|
-
|
|
462
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
|
|
464
463
|
end
|
|
465
464
|
|
|
466
465
|
it "should use the eager_block option when eager loading if given" do
|
|
467
466
|
EagerBand.eager(:good_albums).all
|
|
468
|
-
|
|
467
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
|
|
469
468
|
EagerBand.eager(:good_albums=>:good_tracks).all
|
|
470
|
-
|
|
469
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))", "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
|
|
471
470
|
end
|
|
472
471
|
|
|
473
472
|
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
|
@@ -477,34 +476,34 @@ describe Sequel::Model, "#eager" do
|
|
|
477
476
|
|
|
478
477
|
it "should respect the association's :select option" do
|
|
479
478
|
EagerAlbum.eager(:band_name).all
|
|
480
|
-
|
|
479
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM bands WHERE (bands.id IN (2))"]
|
|
481
480
|
EagerAlbum.eager(:track_names).all
|
|
482
|
-
|
|
481
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
483
482
|
EagerAlbum.eager(:genre_names).all
|
|
484
|
-
|
|
483
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
485
484
|
end
|
|
486
485
|
|
|
487
486
|
it "should respect many_to_one association's :qualify option" do
|
|
488
487
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :qualify=>false, :key=>:band_id
|
|
489
488
|
EagerBand.dataset._fetch = {:id=>2}
|
|
490
489
|
as = EagerAlbum.eager(:special_band).all
|
|
491
|
-
|
|
490
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
|
|
492
491
|
as.map{|a| a.special_band}.should == [EagerBand.load(:id=>2)]
|
|
493
|
-
|
|
492
|
+
DB.sqls.should == []
|
|
494
493
|
end
|
|
495
494
|
|
|
496
495
|
it "should respect the association's :primary_key option" do
|
|
497
496
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>:p_k, :key=>:band_id
|
|
498
497
|
EagerBand.dataset._fetch = {:p_k=>2, :id=>1}
|
|
499
498
|
as = EagerAlbum.eager(:special_band).all
|
|
500
|
-
|
|
499
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
|
|
501
500
|
as.length.should == 1
|
|
502
501
|
as.first.special_band.should == EagerBand.load(:p_k=>2, :id=>1)
|
|
503
502
|
|
|
504
503
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
|
|
505
504
|
EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
|
|
506
505
|
as = EagerAlbum.eager(:special_tracks).all
|
|
507
|
-
|
|
506
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
|
|
508
507
|
as.length.should == 1
|
|
509
508
|
as.first.special_tracks.should == [EagerTrack.load(:album_id=>2, :id=>1)]
|
|
510
509
|
end
|
|
@@ -513,7 +512,7 @@ describe Sequel::Model, "#eager" do
|
|
|
513
512
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>[:id, :p_k], :key=>[:band_id, :id]
|
|
514
513
|
EagerBand.dataset._fetch = {:p_k=>1, :id=>2}
|
|
515
514
|
as = EagerAlbum.eager(:special_band).all
|
|
516
|
-
|
|
515
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
|
|
517
516
|
as.length.should == 1
|
|
518
517
|
as.first.special_band.should == EagerBand.load(:p_k=>1, :id=>2)
|
|
519
518
|
end
|
|
@@ -522,7 +521,7 @@ describe Sequel::Model, "#eager" do
|
|
|
522
521
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>[:band_id, :id], :key=>[:id, :album_id]
|
|
523
522
|
EagerTrack.dataset._fetch = {:album_id=>1, :id=>2}
|
|
524
523
|
as = EagerAlbum.eager(:special_tracks).all
|
|
525
|
-
|
|
524
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
|
|
526
525
|
as.length.should == 1
|
|
527
526
|
as.first.special_tracks.should == [EagerTrack.load(:album_id=>1, :id=>2)]
|
|
528
527
|
end
|
|
@@ -531,7 +530,7 @@ describe Sequel::Model, "#eager" do
|
|
|
531
530
|
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>[:band_id, :id], :left_key=>[:l1, :l2], :right_primary_key=>[:xxx, :id], :right_key=>[:r1, :r2], :join_table=>:ag
|
|
532
531
|
EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}, {:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>6}]
|
|
533
532
|
as = EagerAlbum.eager(:special_genres).all
|
|
534
|
-
|
|
533
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.l1 AS x_foreign_key_0_x, ag.l2 AS x_foreign_key_1_x FROM genres INNER JOIN ag ON ((ag.r1 = genres.xxx) AND (ag.r2 = genres.id) AND ((ag.l1, ag.l2) IN ((2, 1))))"]
|
|
535
534
|
as.length.should == 1
|
|
536
535
|
as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
537
536
|
end
|
|
@@ -540,7 +539,7 @@ describe Sequel::Model, "#eager" do
|
|
|
540
539
|
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_primary_key=>:xxx, :right_key=>:genre_id, :join_table=>:ag
|
|
541
540
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
542
541
|
as = EagerAlbum.eager(:special_genres).all
|
|
543
|
-
|
|
542
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.xxx) AND (ag.album_id IN (2)))"]
|
|
544
543
|
as.length.should == 1
|
|
545
544
|
as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
546
545
|
end
|
|
@@ -549,101 +548,98 @@ describe Sequel::Model, "#eager" do
|
|
|
549
548
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2
|
|
550
549
|
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
|
|
551
550
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
552
|
-
|
|
551
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
553
552
|
as.length.should == 1
|
|
554
553
|
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
|
|
555
554
|
|
|
556
|
-
|
|
557
|
-
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[
|
|
555
|
+
DB.reset
|
|
556
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[1,1]
|
|
557
|
+
as = EagerAlbum.eager(:first_two_tracks).all
|
|
558
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
559
|
+
as.length.should == 1
|
|
560
|
+
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3)]
|
|
561
|
+
|
|
562
|
+
DB.reset
|
|
563
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[nil,1]
|
|
558
564
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
559
|
-
|
|
565
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
560
566
|
as.length.should == 1
|
|
561
567
|
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3), EagerTrack.load(:album_id=>1, :id=>4)]
|
|
562
568
|
end
|
|
563
569
|
|
|
564
570
|
it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
|
|
565
571
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
566
|
-
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :
|
|
572
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
|
|
567
573
|
a = EagerAlbum.eager(:tracks).all
|
|
568
574
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
569
|
-
|
|
575
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
|
570
576
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
571
|
-
|
|
577
|
+
DB.sqls.should == []
|
|
572
578
|
end
|
|
573
579
|
|
|
574
580
|
it "should respect the :limit option with an offset on a one_to_many association using the :window_function strategy" do
|
|
575
581
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
576
|
-
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :
|
|
577
|
-
a = EagerAlbum.eager(:tracks).all
|
|
578
|
-
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
579
|
-
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
|
580
|
-
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
581
|
-
MODEL_DB.sqls.should == []
|
|
582
|
-
end
|
|
583
|
-
|
|
584
|
-
qspecify "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
|
|
585
|
-
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>2
|
|
582
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1]
|
|
586
583
|
a = EagerAlbum.eager(:tracks).all
|
|
587
584
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
588
|
-
|
|
585
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
|
589
586
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
590
|
-
|
|
587
|
+
DB.sqls.should == []
|
|
591
588
|
end
|
|
592
589
|
|
|
593
|
-
|
|
594
|
-
|
|
590
|
+
it "should respect the :limit option with just an offset on a one_to_many association using the :window_function strategy" do
|
|
591
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
592
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1]
|
|
595
593
|
a = EagerAlbum.eager(:tracks).all
|
|
596
594
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
597
|
-
|
|
595
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x >= 2)']
|
|
598
596
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
599
|
-
|
|
597
|
+
DB.sqls.should == []
|
|
600
598
|
end
|
|
601
599
|
|
|
602
600
|
it "should respect the limit option on a many_to_many association" do
|
|
603
601
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
|
|
604
602
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
605
603
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
606
|
-
|
|
604
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
|
|
607
605
|
as.length.should == 1
|
|
608
606
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
609
607
|
|
|
610
608
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
611
|
-
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[
|
|
609
|
+
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1, 1]
|
|
612
610
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
613
|
-
|
|
611
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
|
|
612
|
+
as.length.should == 1
|
|
613
|
+
as.first.first_two_genres.should == [EagerGenre.load(:id=>6)]
|
|
614
|
+
|
|
615
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
616
|
+
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil, 1]
|
|
617
|
+
as = EagerAlbum.eager(:first_two_genres).all
|
|
618
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
|
|
614
619
|
as.length.should == 1
|
|
615
620
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>6), EagerGenre.load(:id=>7)]
|
|
616
621
|
end
|
|
617
622
|
|
|
618
623
|
it "should respect the limit option on a many_to_many association using the :window_function strategy" do
|
|
619
624
|
def (EagerGenre.dataset).supports_window_functions?() true end
|
|
620
|
-
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :
|
|
621
|
-
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
622
|
-
as = EagerAlbum.eager(:first_two_genres).all
|
|
623
|
-
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
|
|
624
|
-
as.length.should == 1
|
|
625
|
-
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
626
|
-
|
|
625
|
+
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2, :order=>:name
|
|
627
626
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
628
|
-
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>[2, 1], :order=>:name
|
|
629
627
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
630
|
-
|
|
628
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
|
|
631
629
|
as.length.should == 1
|
|
632
630
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
633
|
-
end
|
|
634
631
|
|
|
635
|
-
|
|
636
|
-
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :
|
|
637
|
-
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
632
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
|
633
|
+
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1, 1], :order=>:name
|
|
638
634
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
639
|
-
|
|
635
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 3))"]
|
|
640
636
|
as.length.should == 1
|
|
641
|
-
as.first.first_two_genres.should == [EagerGenre.load(:id=>5)
|
|
637
|
+
as.first.first_two_genres.should == [EagerGenre.load(:id=>5)]
|
|
642
638
|
|
|
643
639
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
644
|
-
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :
|
|
640
|
+
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil, 1], :order=>:name
|
|
645
641
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
646
|
-
|
|
642
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x >= 2)"]
|
|
647
643
|
as.length.should == 1
|
|
648
644
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
649
645
|
end
|
|
@@ -663,7 +659,7 @@ describe Sequel::Model, "#eager" do
|
|
|
663
659
|
end)
|
|
664
660
|
a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
|
|
665
661
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
666
|
-
sqls =
|
|
662
|
+
sqls = DB.sqls
|
|
667
663
|
sqls.shift.should == 'SELECT * FROM albums'
|
|
668
664
|
sqls.sort.should == ['SELECT * FROM bands WHERE (album_id IN (1, 2)) ORDER BY name LIMIT 1',
|
|
669
665
|
'SELECT * FROM genres INNER JOIN ag USING (genre_id) WHERE (album_id IN (1))',
|
|
@@ -672,13 +668,9 @@ describe Sequel::Model, "#eager" do
|
|
|
672
668
|
a.special_band.should == EagerBand.load(:id => 2)
|
|
673
669
|
a.special_tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
674
670
|
a.special_genres.should == [EagerGenre.load(:id => 4)]
|
|
675
|
-
|
|
671
|
+
DB.sqls.should == []
|
|
676
672
|
end
|
|
677
673
|
|
|
678
|
-
it "should raise an error if you use an :eager_loader proc with the wrong arity" do
|
|
679
|
-
proc{EagerAlbum.many_to_one :special_band, :eager_loader=>proc{|a, b|}}.should raise_error(Sequel::Error)
|
|
680
|
-
end
|
|
681
|
-
|
|
682
674
|
it "should respect :after_load callbacks on associations when eager loading" do
|
|
683
675
|
EagerAlbum.many_to_one :al_band, :class=>'EagerBand', :key=>:band_id, :after_load=>proc{|o, a| a.id *=2}
|
|
684
676
|
EagerAlbum.one_to_many :al_tracks, :class=>'EagerTrack', :key=>:album_id, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
@@ -694,7 +686,7 @@ describe Sequel::Model, "#eager" do
|
|
|
694
686
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
|
|
695
687
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
|
|
696
688
|
a = EagerAlbum.eager(:al_genres).all.first
|
|
697
|
-
|
|
689
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
698
690
|
a.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
699
691
|
a.al_genres.should == [EagerGenre.load(:id=>8)]
|
|
700
692
|
end
|
|
@@ -702,7 +694,7 @@ describe Sequel::Model, "#eager" do
|
|
|
702
694
|
it "should respect :distinct option when eagerly loading many_to_many associations" do
|
|
703
695
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :distinct=>true
|
|
704
696
|
a = EagerAlbum.eager(:al_genres).all.first
|
|
705
|
-
|
|
697
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
706
698
|
a.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
707
699
|
a.al_genres.should == [EagerGenre.load(:id=>4)]
|
|
708
700
|
end
|
|
@@ -710,40 +702,40 @@ describe Sequel::Model, "#eager" do
|
|
|
710
702
|
it "should eagerly load a many_to_one association with custom eager block" do
|
|
711
703
|
a = EagerAlbum.eager(:band => proc {|ds| ds.select(:id, :name)}).all
|
|
712
704
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
713
|
-
|
|
705
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT id, name FROM bands WHERE (bands.id IN (2))']
|
|
714
706
|
a.first.band.should == EagerBand.load(:id => 2)
|
|
715
|
-
|
|
707
|
+
DB.sqls.should == []
|
|
716
708
|
end
|
|
717
709
|
|
|
718
710
|
it "should eagerly load a one_to_one association with custom eager block" do
|
|
719
711
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
720
712
|
a = EagerAlbum.eager(:track => proc {|ds| ds.select(:id)}).all
|
|
721
713
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
722
|
-
|
|
714
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
723
715
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
724
|
-
|
|
716
|
+
DB.sqls.should == []
|
|
725
717
|
end
|
|
726
718
|
|
|
727
719
|
it "should eagerly load a one_to_many association with custom eager block" do
|
|
728
720
|
a = EagerAlbum.eager(:tracks => proc {|ds| ds.select(:id)}).all
|
|
729
721
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
730
|
-
|
|
722
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
731
723
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
732
|
-
|
|
724
|
+
DB.sqls.should == []
|
|
733
725
|
end
|
|
734
726
|
|
|
735
727
|
it "should eagerly load a many_to_many association with custom eager block" do
|
|
736
728
|
a = EagerAlbum.eager(:genres => proc {|ds| ds.select(:name)}).all
|
|
737
729
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
738
|
-
|
|
730
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
739
731
|
a.first.genres.should == [EagerGenre.load(:id => 4)]
|
|
740
|
-
|
|
732
|
+
DB.sqls.should == []
|
|
741
733
|
end
|
|
742
734
|
|
|
743
735
|
it "should allow cascading of eager loading within a custom eager block" do
|
|
744
736
|
a = EagerTrack.eager(:album => proc {|ds| ds.eager(:band => :members)}).all
|
|
745
737
|
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
746
|
-
|
|
738
|
+
DB.sqls.should == ['SELECT * FROM tracks',
|
|
747
739
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
748
740
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
749
741
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
@@ -751,13 +743,13 @@ describe Sequel::Model, "#eager" do
|
|
|
751
743
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
752
744
|
a.album.band.should == EagerBand.load(:id => 2)
|
|
753
745
|
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
754
|
-
|
|
746
|
+
DB.sqls.should == []
|
|
755
747
|
end
|
|
756
748
|
|
|
757
749
|
it "should allow cascading of eager loading with custom callback with hash value" do
|
|
758
750
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>{:band => :members}}).all
|
|
759
751
|
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
760
|
-
|
|
752
|
+
DB.sqls.should == ['SELECT * FROM tracks',
|
|
761
753
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
762
754
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
763
755
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
@@ -765,25 +757,25 @@ describe Sequel::Model, "#eager" do
|
|
|
765
757
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
766
758
|
a.album.band.should == EagerBand.load(:id => 2)
|
|
767
759
|
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
768
|
-
|
|
760
|
+
DB.sqls.should == []
|
|
769
761
|
end
|
|
770
762
|
|
|
771
763
|
it "should allow cascading of eager loading with custom callback with symbol value" do
|
|
772
764
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>:band}).all
|
|
773
765
|
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
774
|
-
|
|
766
|
+
DB.sqls.should == ['SELECT * FROM tracks',
|
|
775
767
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
776
768
|
'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
777
769
|
a = a.first
|
|
778
770
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
779
771
|
a.album.band.should == EagerBand.load(:id => 2)
|
|
780
|
-
|
|
772
|
+
DB.sqls.should == []
|
|
781
773
|
end
|
|
782
774
|
|
|
783
775
|
it "should allow cascading of eager loading with custom callback with array value" do
|
|
784
776
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>[:band, :band_name]}).all
|
|
785
777
|
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
786
|
-
sqls =
|
|
778
|
+
sqls = DB.sqls
|
|
787
779
|
sqls.slice!(0..1).should == ['SELECT * FROM tracks',
|
|
788
780
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))']
|
|
789
781
|
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
@@ -792,12 +784,12 @@ describe Sequel::Model, "#eager" do
|
|
|
792
784
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
793
785
|
a.album.band.should == EagerBand.load(:id => 2)
|
|
794
786
|
a.album.band_name.should == EagerBand.load(:id => 2)
|
|
795
|
-
|
|
787
|
+
DB.sqls.should == []
|
|
796
788
|
end
|
|
797
789
|
|
|
798
790
|
it "should call both association and custom eager blocks" do
|
|
799
791
|
EagerBand.eager(:good_albums => proc {|ds| ds.select(:name)}).all
|
|
800
|
-
|
|
792
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
|
|
801
793
|
end
|
|
802
794
|
end
|
|
803
795
|
|
|
@@ -1019,7 +1011,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1019
1011
|
end
|
|
1020
1012
|
|
|
1021
1013
|
it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
|
|
1022
|
-
|
|
1014
|
+
DB.reset
|
|
1023
1015
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1024
1016
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1025
1017
|
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
@@ -1028,7 +1020,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1028
1020
|
a = a.first
|
|
1029
1021
|
a.tracks.should == [GraphTrack.load(:id => 3, :album_id=>1)]
|
|
1030
1022
|
a.tracks.first.album.should == a
|
|
1031
|
-
|
|
1023
|
+
DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
|
|
1032
1024
|
end
|
|
1033
1025
|
|
|
1034
1026
|
it "should eager load multiple associations from the same table" do
|
|
@@ -1086,7 +1078,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1086
1078
|
end
|
|
1087
1079
|
|
|
1088
1080
|
it "should be able to be used in combination with #eager" do
|
|
1089
|
-
|
|
1081
|
+
DB.reset
|
|
1090
1082
|
ds = GraphAlbum.eager_graph(:tracks).eager(:genres)
|
|
1091
1083
|
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1092
1084
|
ds2 = GraphGenre.dataset
|
|
@@ -1096,7 +1088,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1096
1088
|
a = a.first
|
|
1097
1089
|
a.tracks.should == [GraphTrack.load(:id=>3, :album_id=>1)]
|
|
1098
1090
|
a.genres.should == [GraphGenre.load(:id => 6)]
|
|
1099
|
-
|
|
1091
|
+
DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)',
|
|
1100
1092
|
"SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
1101
1093
|
end
|
|
1102
1094
|
|
|
@@ -1332,10 +1324,6 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1332
1324
|
GraphAlbum.eager_graph(:active_genres).sql.should == "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag AS a123 ON (a123.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres USING (album_id)"
|
|
1333
1325
|
end
|
|
1334
1326
|
|
|
1335
|
-
it "should raise an error if you use an :eager_grapher proc with the wrong arity" do
|
|
1336
|
-
proc{GraphAlbum.many_to_one :special_band, :eager_grapher=>proc{|a, b|}}.should raise_error(Sequel::Error)
|
|
1337
|
-
end
|
|
1338
|
-
|
|
1339
1327
|
it "should respect the association's :graph_only_conditions option" do
|
|
1340
1328
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_only_conditions=>{:active=>true}
|
|
1341
1329
|
GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS active_band ON (active_band.active IS TRUE)"
|