sequel 4.22.0 → 4.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
|
@@ -13,133 +13,133 @@ describe Sequel::Model, "class dataset methods" do
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "should call the dataset method of the same name with the same args" do
|
|
16
|
-
@c.<<({}).
|
|
17
|
-
@db.sqls.
|
|
18
|
-
@c.all.
|
|
19
|
-
@db.sqls.
|
|
20
|
-
@c.avg(:id).
|
|
21
|
-
@db.sqls.
|
|
22
|
-
@c.count.
|
|
23
|
-
@db.sqls.
|
|
24
|
-
@c.cross_join(@c).sql.
|
|
25
|
-
@c.distinct.sql.
|
|
26
|
-
@c.each{|r| r.
|
|
27
|
-
@db.sqls.
|
|
28
|
-
@c.each_server{|r| r.opts[:server].
|
|
29
|
-
@c.empty?.
|
|
30
|
-
@db.sqls.
|
|
31
|
-
@c.except(@d, :from_self=>false).sql.
|
|
32
|
-
@c.exclude(:a).sql.
|
|
33
|
-
@c.exclude_having(:a).sql.
|
|
34
|
-
@c.exclude_where(:a).sql.
|
|
35
|
-
@c.fetch_rows("S"){|r| r.
|
|
36
|
-
@db.sqls.
|
|
37
|
-
@c.filter(:a).sql.
|
|
38
|
-
@c.first.
|
|
39
|
-
@db.sqls.
|
|
40
|
-
@c.first!.
|
|
41
|
-
@db.sqls.
|
|
42
|
-
@c.for_update.sql.
|
|
43
|
-
@c.from.sql.
|
|
44
|
-
@c.from_self.sql.
|
|
45
|
-
@c.full_join(@c).sql.
|
|
46
|
-
@c.full_outer_join(@c).sql.
|
|
47
|
-
@c.get(:a).
|
|
48
|
-
@db.sqls.
|
|
49
|
-
@c.graph(@c, nil, :table_alias=>:a).sql.
|
|
16
|
+
@c.<<({}).must_equal @d
|
|
17
|
+
@db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES"]
|
|
18
|
+
@c.all.must_equal [@c.load(:id=>1)]
|
|
19
|
+
@db.sqls.must_equal ["SELECT * FROM items"]
|
|
20
|
+
@c.avg(:id).must_equal 1
|
|
21
|
+
@db.sqls.must_equal ["SELECT avg(id) AS avg FROM items LIMIT 1"]
|
|
22
|
+
@c.count.must_equal 1
|
|
23
|
+
@db.sqls.must_equal ["SELECT count(*) AS count FROM items LIMIT 1"]
|
|
24
|
+
@c.cross_join(@c).sql.must_equal "SELECT * FROM items CROSS JOIN items"
|
|
25
|
+
@c.distinct.sql.must_equal "SELECT DISTINCT * FROM items"
|
|
26
|
+
@c.each{|r| r.must_equal @c.load(:id=>1)}.must_equal @d
|
|
27
|
+
@db.sqls.must_equal ["SELECT * FROM items"]
|
|
28
|
+
@c.each_server{|r| r.opts[:server].must_equal :default}
|
|
29
|
+
@c.empty?.must_equal false
|
|
30
|
+
@db.sqls.must_equal ["SELECT 1 AS one FROM items LIMIT 1"]
|
|
31
|
+
@c.except(@d, :from_self=>false).sql.must_equal "SELECT * FROM items EXCEPT SELECT * FROM items"
|
|
32
|
+
@c.exclude(:a).sql.must_equal "SELECT * FROM items WHERE NOT a"
|
|
33
|
+
@c.exclude_having(:a).sql.must_equal "SELECT * FROM items HAVING NOT a"
|
|
34
|
+
@c.exclude_where(:a).sql.must_equal "SELECT * FROM items WHERE NOT a"
|
|
35
|
+
@c.fetch_rows("S"){|r| r.must_equal(:id=>1)}
|
|
36
|
+
@db.sqls.must_equal ["S"]
|
|
37
|
+
@c.filter(:a).sql.must_equal "SELECT * FROM items WHERE a"
|
|
38
|
+
@c.first.must_equal @c.load(:id=>1)
|
|
39
|
+
@db.sqls.must_equal ["SELECT * FROM items LIMIT 1"]
|
|
40
|
+
@c.first!.must_equal @c.load(:id=>1)
|
|
41
|
+
@db.sqls.must_equal ["SELECT * FROM items LIMIT 1"]
|
|
42
|
+
@c.for_update.sql.must_equal "SELECT * FROM items FOR UPDATE"
|
|
43
|
+
@c.from.sql.must_equal "SELECT *"
|
|
44
|
+
@c.from_self.sql.must_equal "SELECT * FROM (SELECT * FROM items) AS t1"
|
|
45
|
+
@c.full_join(@c).sql.must_equal "SELECT * FROM items FULL JOIN items"
|
|
46
|
+
@c.full_outer_join(@c).sql.must_equal "SELECT * FROM items FULL OUTER JOIN items"
|
|
47
|
+
@c.get(:a).must_equal 1
|
|
48
|
+
@db.sqls.must_equal ["SELECT a FROM items LIMIT 1"]
|
|
49
|
+
@c.graph(@c, nil, :table_alias=>:a).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items AS a"
|
|
50
50
|
@db.sqls
|
|
51
|
-
@c.grep(:id, 'a%').sql.
|
|
52
|
-
@c.group(:a).sql.
|
|
53
|
-
@c.group_and_count(:a).sql.
|
|
54
|
-
@c.group_by(:a).sql.
|
|
55
|
-
@c.having(:a).sql.
|
|
51
|
+
@c.grep(:id, 'a%').sql.must_equal "SELECT * FROM items WHERE ((id LIKE 'a%' ESCAPE '\\'))"
|
|
52
|
+
@c.group(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
|
|
53
|
+
@c.group_and_count(:a).sql.must_equal "SELECT a, count(*) AS count FROM items GROUP BY a"
|
|
54
|
+
@c.group_by(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
|
|
55
|
+
@c.having(:a).sql.must_equal "SELECT * FROM items HAVING a"
|
|
56
56
|
@c.import([:id], [[1]])
|
|
57
|
-
@db.sqls.
|
|
58
|
-
@c.inner_join(@c).sql.
|
|
59
|
-
@c.insert.
|
|
60
|
-
@db.sqls.
|
|
61
|
-
@c.intersect(@d, :from_self=>false).sql.
|
|
62
|
-
@c.interval(:id).
|
|
63
|
-
@db.sqls.
|
|
64
|
-
@c.join(@c).sql.
|
|
65
|
-
@c.join_table(:inner, @c).sql.
|
|
66
|
-
@c.last.
|
|
67
|
-
@db.sqls.
|
|
68
|
-
@c.left_join(@c).sql.
|
|
69
|
-
@c.left_outer_join(@c).sql.
|
|
70
|
-
@c.limit(2).sql.
|
|
71
|
-
@c.lock_style(:update).sql.
|
|
72
|
-
@c.map(:id).
|
|
73
|
-
@db.sqls.
|
|
74
|
-
@c.max(:id).
|
|
75
|
-
@db.sqls.
|
|
76
|
-
@c.min(:id).
|
|
77
|
-
@db.sqls.
|
|
57
|
+
@db.sqls.must_equal ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
|
58
|
+
@c.inner_join(@c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
|
59
|
+
@c.insert.must_equal 2
|
|
60
|
+
@db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES"]
|
|
61
|
+
@c.intersect(@d, :from_self=>false).sql.must_equal "SELECT * FROM items INTERSECT SELECT * FROM items"
|
|
62
|
+
@c.interval(:id).must_equal 1
|
|
63
|
+
@db.sqls.must_equal ["SELECT (max(id) - min(id)) AS interval FROM items LIMIT 1"]
|
|
64
|
+
@c.join(@c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
|
65
|
+
@c.join_table(:inner, @c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
|
66
|
+
@c.last.must_equal @c.load(:id=>1)
|
|
67
|
+
@db.sqls.must_equal ["SELECT * FROM items ORDER BY id DESC LIMIT 1"]
|
|
68
|
+
@c.left_join(@c).sql.must_equal "SELECT * FROM items LEFT JOIN items"
|
|
69
|
+
@c.left_outer_join(@c).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items"
|
|
70
|
+
@c.limit(2).sql.must_equal "SELECT * FROM items LIMIT 2"
|
|
71
|
+
@c.lock_style(:update).sql.must_equal "SELECT * FROM items FOR UPDATE"
|
|
72
|
+
@c.map(:id).must_equal [1]
|
|
73
|
+
@db.sqls.must_equal ["SELECT * FROM items"]
|
|
74
|
+
@c.max(:id).must_equal 1
|
|
75
|
+
@db.sqls.must_equal ["SELECT max(id) AS max FROM items LIMIT 1"]
|
|
76
|
+
@c.min(:id).must_equal 1
|
|
77
|
+
@db.sqls.must_equal ["SELECT min(id) AS min FROM items LIMIT 1"]
|
|
78
78
|
@c.multi_insert([{:id=>1}])
|
|
79
|
-
@db.sqls.
|
|
80
|
-
@c.naked.row_proc.
|
|
81
|
-
@c.natural_full_join(@c).sql.
|
|
82
|
-
@c.natural_join(@c).sql.
|
|
83
|
-
@c.natural_left_join(@c).sql.
|
|
84
|
-
@c.natural_right_join(@c).sql.
|
|
85
|
-
@c.offset(2).sql.
|
|
86
|
-
@c.order(:a).sql.
|
|
87
|
-
@c.order_append(:a).sql.
|
|
88
|
-
@c.order_by(:a).sql.
|
|
89
|
-
@c.order_more(:a).sql.
|
|
90
|
-
@c.order_prepend(:a).sql.
|
|
91
|
-
@c.paged_each{|r| r.
|
|
92
|
-
@db.sqls.
|
|
93
|
-
@c.qualify.sql.
|
|
94
|
-
@c.right_join(@c).sql.
|
|
95
|
-
@c.right_outer_join(@c).sql.
|
|
96
|
-
@c.select(:a).sql.
|
|
97
|
-
@c.select_all(:items).sql.
|
|
98
|
-
@c.select_append(:a).sql.
|
|
99
|
-
@c.select_group(:a).sql.
|
|
100
|
-
@c.select_hash(:id, :id).
|
|
101
|
-
@db.sqls.
|
|
102
|
-
@c.select_hash_groups(:id, :id).
|
|
103
|
-
@db.sqls.
|
|
104
|
-
@c.select_map(:id).
|
|
105
|
-
@db.sqls.
|
|
106
|
-
@c.select_order_map(:id).
|
|
107
|
-
@db.sqls.
|
|
108
|
-
@c.server(:a).opts[:server].
|
|
109
|
-
@c.set_graph_aliases(:a=>:b).opts[:graph_aliases].
|
|
110
|
-
@c.single_record.
|
|
111
|
-
@db.sqls.
|
|
112
|
-
@c.single_value.
|
|
113
|
-
@db.sqls.
|
|
114
|
-
@c.sum(:id).
|
|
115
|
-
@db.sqls.
|
|
116
|
-
@c.to_hash(:id, :id).
|
|
117
|
-
@db.sqls.
|
|
118
|
-
@c.to_hash_groups(:id, :id).
|
|
119
|
-
@db.sqls.
|
|
79
|
+
@db.sqls.must_equal ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
|
80
|
+
@c.naked.row_proc.must_equal nil
|
|
81
|
+
@c.natural_full_join(@c).sql.must_equal "SELECT * FROM items NATURAL FULL JOIN items"
|
|
82
|
+
@c.natural_join(@c).sql.must_equal "SELECT * FROM items NATURAL JOIN items"
|
|
83
|
+
@c.natural_left_join(@c).sql.must_equal "SELECT * FROM items NATURAL LEFT JOIN items"
|
|
84
|
+
@c.natural_right_join(@c).sql.must_equal "SELECT * FROM items NATURAL RIGHT JOIN items"
|
|
85
|
+
@c.offset(2).sql.must_equal "SELECT * FROM items OFFSET 2"
|
|
86
|
+
@c.order(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
|
87
|
+
@c.order_append(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
|
88
|
+
@c.order_by(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
|
89
|
+
@c.order_more(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
|
90
|
+
@c.order_prepend(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
|
91
|
+
@c.paged_each{|r| r.must_equal @c.load(:id=>1)}
|
|
92
|
+
@db.sqls.must_equal ["BEGIN", "SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0", "COMMIT"]
|
|
93
|
+
@c.qualify.sql.must_equal 'SELECT items.* FROM items'
|
|
94
|
+
@c.right_join(@c).sql.must_equal "SELECT * FROM items RIGHT JOIN items"
|
|
95
|
+
@c.right_outer_join(@c).sql.must_equal "SELECT * FROM items RIGHT OUTER JOIN items"
|
|
96
|
+
@c.select(:a).sql.must_equal "SELECT a FROM items"
|
|
97
|
+
@c.select_all(:items).sql.must_equal "SELECT items.* FROM items"
|
|
98
|
+
@c.select_append(:a).sql.must_equal "SELECT *, a FROM items"
|
|
99
|
+
@c.select_group(:a).sql.must_equal "SELECT a FROM items GROUP BY a"
|
|
100
|
+
@c.select_hash(:id, :id).must_equal(1=>1)
|
|
101
|
+
@db.sqls.must_equal ["SELECT id, id FROM items"]
|
|
102
|
+
@c.select_hash_groups(:id, :id).must_equal(1=>[1])
|
|
103
|
+
@db.sqls.must_equal ["SELECT id, id FROM items"]
|
|
104
|
+
@c.select_map(:id).must_equal [1]
|
|
105
|
+
@db.sqls.must_equal ["SELECT id FROM items"]
|
|
106
|
+
@c.select_order_map(:id).must_equal [1]
|
|
107
|
+
@db.sqls.must_equal ["SELECT id FROM items ORDER BY id"]
|
|
108
|
+
@c.server(:a).opts[:server].must_equal :a
|
|
109
|
+
@c.set_graph_aliases(:a=>:b).opts[:graph_aliases].must_equal(:a=>[:b, :a])
|
|
110
|
+
@c.single_record.must_equal @c.load(:id=>1)
|
|
111
|
+
@db.sqls.must_equal ["SELECT * FROM items LIMIT 1"]
|
|
112
|
+
@c.single_value.must_equal 1
|
|
113
|
+
@db.sqls.must_equal ["SELECT * FROM items LIMIT 1"]
|
|
114
|
+
@c.sum(:id).must_equal 1
|
|
115
|
+
@db.sqls.must_equal ["SELECT sum(id) AS sum FROM items LIMIT 1"]
|
|
116
|
+
@c.to_hash(:id, :id).must_equal(1=>1)
|
|
117
|
+
@db.sqls.must_equal ["SELECT * FROM items"]
|
|
118
|
+
@c.to_hash_groups(:id, :id).must_equal(1=>[1])
|
|
119
|
+
@db.sqls.must_equal ["SELECT * FROM items"]
|
|
120
120
|
@c.truncate
|
|
121
|
-
@db.sqls.
|
|
122
|
-
@c.union(@d, :from_self=>false).sql.
|
|
123
|
-
@c.where(:a).sql.
|
|
124
|
-
@c.with(:a, @d).sql.
|
|
125
|
-
@c.with_recursive(:a, @d, @d).sql.
|
|
126
|
-
@c.with_sql('S').sql.
|
|
121
|
+
@db.sqls.must_equal ["TRUNCATE TABLE items"]
|
|
122
|
+
@c.union(@d, :from_self=>false).sql.must_equal "SELECT * FROM items UNION SELECT * FROM items"
|
|
123
|
+
@c.where(:a).sql.must_equal "SELECT * FROM items WHERE a"
|
|
124
|
+
@c.with(:a, @d).sql.must_equal "WITH a AS (SELECT * FROM items) SELECT * FROM items"
|
|
125
|
+
@c.with_recursive(:a, @d, @d).sql.must_equal "WITH a AS (SELECT * FROM items UNION ALL SELECT * FROM items) SELECT * FROM items"
|
|
126
|
+
@c.with_sql('S').sql.must_equal "S"
|
|
127
127
|
|
|
128
128
|
sc = Class.new(@c)
|
|
129
129
|
sc.set_dataset(@d.where(:a).order(:a).select(:a).group(:a).limit(2))
|
|
130
130
|
@db.sqls
|
|
131
|
-
sc.invert.sql.
|
|
131
|
+
sc.invert.sql.must_equal 'SELECT a FROM items WHERE NOT a GROUP BY a ORDER BY a LIMIT 2'
|
|
132
132
|
sc.dataset._fetch = {:v1=>1, :v2=>2}
|
|
133
|
-
sc.range(:a).
|
|
134
|
-
@db.sqls.
|
|
135
|
-
sc.reverse.sql.
|
|
136
|
-
sc.reverse_order.sql.
|
|
137
|
-
sc.select_more(:a).sql.
|
|
138
|
-
sc.unfiltered.sql.
|
|
139
|
-
sc.ungrouped.sql.
|
|
140
|
-
sc.unordered.sql.
|
|
141
|
-
sc.unlimited.sql.
|
|
133
|
+
sc.range(:a).must_equal(1..2)
|
|
134
|
+
@db.sqls.must_equal ["SELECT min(a) AS v1, max(a) AS v2 FROM (SELECT a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2) AS t1 LIMIT 1"]
|
|
135
|
+
sc.reverse.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
|
|
136
|
+
sc.reverse_order.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
|
|
137
|
+
sc.select_more(:a).sql.must_equal 'SELECT a, a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2'
|
|
138
|
+
sc.unfiltered.sql.must_equal 'SELECT a FROM items GROUP BY a ORDER BY a LIMIT 2'
|
|
139
|
+
sc.ungrouped.sql.must_equal 'SELECT a FROM items WHERE a ORDER BY a LIMIT 2'
|
|
140
|
+
sc.unordered.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a LIMIT 2'
|
|
141
|
+
sc.unlimited.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a'
|
|
142
142
|
sc.dataset.graph!(:a)
|
|
143
|
-
sc.dataset.ungraphed.opts[:graph].
|
|
143
|
+
sc.dataset.ungraphed.opts[:graph].must_equal nil
|
|
144
144
|
end
|
|
145
145
|
end
|
|
@@ -15,26 +15,26 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
|
|
|
15
15
|
|
|
16
16
|
it "should instantiate objects in the dataset and call destroy on each" do
|
|
17
17
|
@d.destroy
|
|
18
|
-
@c::Destroyed.collect{|x| x.values}.
|
|
18
|
+
@c::Destroyed.collect{|x| x.values}.must_equal [{:id=>1}, {:id=>2}]
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "should return the number of records destroyed" do
|
|
22
|
-
@d.destroy.
|
|
22
|
+
@d.destroy.must_equal 2
|
|
23
23
|
@d._fetch = [[{:i=>1}], []]
|
|
24
|
-
@d.destroy.
|
|
25
|
-
@d.destroy.
|
|
24
|
+
@d.destroy.must_equal 1
|
|
25
|
+
@d.destroy.must_equal 0
|
|
26
26
|
end
|
|
27
27
|
|
|
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
|
-
DB.sqls.
|
|
31
|
+
DB.sqls.must_equal ["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
|
-
DB.sqls.
|
|
37
|
+
DB.sqls.must_equal ["SELECT * FROM items"]
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -49,24 +49,24 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
|
|
|
49
49
|
it "should result in a hash with primary key value keys and model object values" do
|
|
50
50
|
@d._fetch = [{:name=>1}, {:name=>2}]
|
|
51
51
|
h = @d.to_hash
|
|
52
|
-
h.
|
|
52
|
+
h.must_be_kind_of(Hash)
|
|
53
53
|
a = h.to_a
|
|
54
|
-
a.collect{|x| x[1].class}.
|
|
55
|
-
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.
|
|
54
|
+
a.collect{|x| x[1].class}.must_equal [@c, @c]
|
|
55
|
+
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[1, {:name=>1}], [2, {:name=>2}]]
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it "should result in a hash with given value keys and model object values" do
|
|
59
59
|
@d._fetch = [{:name=>1, :number=>3}, {:name=>2, :number=>4}]
|
|
60
60
|
h = @d.to_hash(:number)
|
|
61
|
-
h.
|
|
61
|
+
h.must_be_kind_of(Hash)
|
|
62
62
|
a = h.to_a
|
|
63
|
-
a.collect{|x| x[1].class}.
|
|
64
|
-
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.
|
|
63
|
+
a.collect{|x| x[1].class}.must_equal [@c, @c]
|
|
64
|
+
a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[3, {:name=>1, :number=>3}], [4, {:name=>2, :number=>4}]]
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "should raise an error if the class doesn't have a primary key" do
|
|
68
68
|
@c.no_primary_key
|
|
69
|
-
proc{@d.to_hash}.
|
|
69
|
+
proc{@d.to_hash}.must_raise(Sequel::Error)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -77,73 +77,73 @@ describe Sequel::Model::DatasetMethods do
|
|
|
77
77
|
@c.db.reset
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
@c.join(Class.new(Sequel::Model(:categories)), :item_id => :id).sql.
|
|
80
|
+
it "#join_table should allow use to use a model class when joining" do
|
|
81
|
+
@c.join(Class.new(Sequel::Model(:categories)), :item_id => :id).sql.must_equal 'SELECT * FROM items INNER JOIN categories ON (categories.item_id = items.id)'
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
@c.join(Class.new(Sequel::Model(DB[:categories].where(:foo=>1))), :item_id => :id).sql.
|
|
84
|
+
it "#join_table should handle model classes that aren't simple selects using a subselect" do
|
|
85
|
+
@c.join(Class.new(Sequel::Model(DB[:categories].where(:foo=>1))), :item_id => :id).sql.must_equal '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
|
+
it "#graph should allow use to use a model class when joining" do
|
|
89
89
|
c = Class.new(Sequel::Model(:categories))
|
|
90
90
|
c.columns :id
|
|
91
|
-
@c.graph(c, :item_id => :id).sql.
|
|
91
|
+
@c.graph(c, :item_id => :id).sql.must_equal 'SELECT items.id, categories.id AS categories_id FROM items LEFT OUTER JOIN categories ON (categories.item_id = items.id)'
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
@c.dataset.insert_sql(@c.load(:id=>1)).
|
|
94
|
+
it "#insert_sql should handle a single model instance as an argument" do
|
|
95
|
+
@c.dataset.insert_sql(@c.load(:id=>1)).must_equal 'INSERT INTO items (id) VALUES (1)'
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
it "#first should handle no primary key" do
|
|
99
99
|
@c.no_primary_key
|
|
100
|
-
@c.first.
|
|
101
|
-
@c.db.sqls.
|
|
100
|
+
@c.first.must_be_kind_of(@c)
|
|
101
|
+
@c.db.sqls.must_equal ['SELECT * FROM items LIMIT 1']
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
@c.last.
|
|
106
|
-
@c.db.sqls.
|
|
107
|
-
@c.where(:id=>2).last(:foo=>2){{bar=>3}}.
|
|
108
|
-
@c.db.sqls.
|
|
104
|
+
it "#last should reverse order by primary key if not already ordered" do
|
|
105
|
+
@c.last.must_be_kind_of(@c)
|
|
106
|
+
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY id DESC LIMIT 1']
|
|
107
|
+
@c.where(:id=>2).last(:foo=>2){{bar=>3}}.must_be_kind_of(@c)
|
|
108
|
+
@c.db.sqls.must_equal ['SELECT * FROM items WHERE ((id = 2) AND (bar = 3) AND (foo = 2)) ORDER BY id DESC LIMIT 1']
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
@c.order(:foo).last.
|
|
113
|
-
@c.db.sqls.
|
|
111
|
+
it "#last should use existing order if there is one" do
|
|
112
|
+
@c.order(:foo).last.must_be_kind_of(@c)
|
|
113
|
+
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY foo DESC LIMIT 1']
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
it "#last should handle a composite primary key" do
|
|
117
117
|
@c.set_primary_key [:id1, :id2]
|
|
118
|
-
@c.last.
|
|
119
|
-
@c.db.sqls.
|
|
118
|
+
@c.last.must_be_kind_of(@c)
|
|
119
|
+
@c.db.sqls.must_equal ['SELECT * FROM items ORDER BY id1 DESC, id2 DESC LIMIT 1']
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
it "#last should raise an error if no primary key" do
|
|
123
123
|
@c.no_primary_key
|
|
124
|
-
proc{@c.last}.
|
|
124
|
+
proc{@c.last}.must_raise(Sequel::Error)
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
@c.paged_each{|r| r.
|
|
129
|
-
@c.db.sqls.
|
|
127
|
+
it "#paged_each should order by primary key if not already ordered" do
|
|
128
|
+
@c.paged_each{|r| r.must_be_kind_of(@c)}
|
|
129
|
+
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0', 'COMMIT']
|
|
130
130
|
@c.paged_each(:rows_per_fetch=>5){|r|}
|
|
131
|
-
@c.db.sqls.
|
|
131
|
+
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id LIMIT 5 OFFSET 0', 'COMMIT']
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
@c.order(:foo).paged_each{|r| r.
|
|
136
|
-
@c.db.sqls.
|
|
134
|
+
it "#paged_each should use existing order if there is one" do
|
|
135
|
+
@c.order(:foo).paged_each{|r| r.must_be_kind_of(@c)}
|
|
136
|
+
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY foo LIMIT 1000 OFFSET 0', 'COMMIT']
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
it "#paged_each should handle a composite primary key" do
|
|
140
140
|
@c.set_primary_key [:id1, :id2]
|
|
141
|
-
@c.paged_each{|r| r.
|
|
142
|
-
@c.db.sqls.
|
|
141
|
+
@c.paged_each{|r| r.must_be_kind_of(@c)}
|
|
142
|
+
@c.db.sqls.must_equal ['BEGIN', 'SELECT * FROM items ORDER BY id1, id2 LIMIT 1000 OFFSET 0', 'COMMIT']
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
it "#paged_each should raise an error if no primary key" do
|
|
146
146
|
@c.no_primary_key
|
|
147
|
-
proc{@c.paged_each{|r| }}.
|
|
147
|
+
proc{@c.paged_each{|r| }}.must_raise(Sequel::Error)
|
|
148
148
|
end
|
|
149
149
|
end
|
|
@@ -101,12 +101,12 @@ describe Sequel::Model, "#eager" do
|
|
|
101
101
|
|
|
102
102
|
it "should populate :key_hash and :id_map option correctly for custom eager loaders" do
|
|
103
103
|
khs = {}
|
|
104
|
-
pr = proc{|a, m| proc{|h| khs[a] = h[:key_hash][m]; h[:id_map].
|
|
104
|
+
pr = proc{|a, m| proc{|h| khs[a] = h[:key_hash][m]; h[:id_map].must_equal h[:key_hash][m]}}
|
|
105
105
|
EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loader=>pr.call(:sband, :band_id)
|
|
106
106
|
EagerAlbum.one_to_many :stracks, :clone=>:tracks, :eager_loader=>pr.call(:stracks, :id)
|
|
107
107
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loader=>pr.call(:sgenres, :id)
|
|
108
108
|
EagerAlbum.eager(:sband, :stracks, :sgenres).all
|
|
109
|
-
khs.
|
|
109
|
+
khs.must_equal(:sband=>{2=>[EagerAlbum.load(:band_id=>2, :id=>1)]}, :stracks=>{1=>[EagerAlbum.load(:band_id=>2, :id=>1)]}, :sgenres=>{1=>[EagerAlbum.load(:band_id=>2, :id=>1)]})
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
it "should populate :key_hash using the method symbol" do
|
|
@@ -116,114 +116,114 @@ describe Sequel::Model, "#eager" do
|
|
|
116
116
|
EagerAlbum.one_to_many :stracks, :clone=>:tracks, :eager_loader=>pr.call(:stracks, :id), :primary_key=>:id, :primary_key_column=>:i
|
|
117
117
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loader=>pr.call(:sgenres, :id), :left_primary_key=>:id, :left_primary_key_column=>:i
|
|
118
118
|
EagerAlbum.eager(:sband, :stracks, :sgenres).all
|
|
119
|
-
khs.
|
|
119
|
+
khs.must_equal(:sband=>{2=>[EagerAlbum.load(:band_id=>2, :id=>1)]}, :stracks=>{1=>[EagerAlbum.load(:band_id=>2, :id=>1)]}, :sgenres=>{1=>[EagerAlbum.load(:band_id=>2, :id=>1)]})
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "should raise an error if called without a symbol or hash" do
|
|
123
|
-
proc{EagerAlbum.eager(Object.new)}.
|
|
123
|
+
proc{EagerAlbum.eager(Object.new)}.must_raise(Sequel::Error)
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
it "should eagerly load a single many_to_one association" do
|
|
127
127
|
a = EagerAlbum.eager(:band).all
|
|
128
|
-
DB.sqls.
|
|
129
|
-
a.
|
|
130
|
-
a.first.band.
|
|
131
|
-
DB.sqls.
|
|
128
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
129
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
130
|
+
a.first.band.must_equal EagerBand.load(:id=>2)
|
|
131
|
+
DB.sqls.must_equal []
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
it "should skip eager loading for a many_to_one association with no matching keys" do
|
|
135
135
|
EagerAlbum.dataset._fetch = [{:id=>1, :band_id=>nil}]
|
|
136
136
|
a = EagerAlbum.eager(:band).all
|
|
137
|
-
DB.sqls.
|
|
138
|
-
a.
|
|
139
|
-
a.first.associations.fetch(:band).
|
|
140
|
-
a.first.band.
|
|
141
|
-
DB.sqls.
|
|
137
|
+
DB.sqls.must_equal ['SELECT * FROM albums']
|
|
138
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => nil)]
|
|
139
|
+
a.first.associations.fetch(:band).must_equal nil
|
|
140
|
+
a.first.band.must_equal nil
|
|
141
|
+
DB.sqls.must_equal []
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
it "should eagerly load a single many_to_one association with the same name as the column" do
|
|
145
145
|
EagerAlbum.def_column_alias(:band_id_id, :band_id)
|
|
146
146
|
EagerAlbum.many_to_one :band_id, :key_column=>:band_id, :class=>EagerBand
|
|
147
147
|
a = EagerAlbum.eager(:band_id).all
|
|
148
|
-
DB.sqls.
|
|
149
|
-
a.
|
|
150
|
-
a.first.band_id.
|
|
151
|
-
DB.sqls.
|
|
148
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
149
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
150
|
+
a.first.band_id.must_equal EagerBand.load(:id=>2)
|
|
151
|
+
DB.sqls.must_equal []
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
it "should eagerly load a single one_to_one association" do
|
|
155
155
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
156
156
|
a = EagerAlbum.eager(:track).all
|
|
157
|
-
a.
|
|
158
|
-
DB.sqls.
|
|
159
|
-
a.first.track.
|
|
160
|
-
DB.sqls.
|
|
157
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
158
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
159
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
160
|
+
DB.sqls.must_equal []
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
it "should not break if the dataset does not have a row proc" do
|
|
164
164
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
165
165
|
a = EagerAlbum.eager(:track).naked.all
|
|
166
|
-
a.
|
|
167
|
-
DB.sqls.
|
|
166
|
+
a.must_equal [{:id => 1, :band_id => 2}]
|
|
167
|
+
DB.sqls.must_equal ['SELECT * FROM albums']
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
it "should eagerly load a single one_to_one association without an order" do
|
|
171
171
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
172
172
|
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
|
173
173
|
a = EagerAlbum.eager(:track).all
|
|
174
|
-
a.
|
|
175
|
-
DB.sqls.
|
|
176
|
-
a.first.track.
|
|
177
|
-
DB.sqls.
|
|
174
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
175
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
176
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
177
|
+
DB.sqls.must_equal []
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
it "should eagerly load a single one_to_one association with an order" do
|
|
181
181
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a
|
|
182
182
|
a = EagerAlbum.eager(:track).all
|
|
183
|
-
a.
|
|
184
|
-
DB.sqls.
|
|
185
|
-
a.first.track.
|
|
186
|
-
DB.sqls.
|
|
183
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
184
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1']
|
|
185
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
186
|
+
DB.sqls.must_equal []
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
|
|
190
190
|
def (EagerTrack.dataset).supports_distinct_on?() true end
|
|
191
191
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a, :eager_limit_strategy=>:distinct_on
|
|
192
192
|
a = EagerAlbum.eager(:track).all
|
|
193
|
-
a.
|
|
194
|
-
DB.sqls.
|
|
195
|
-
a.first.track.
|
|
196
|
-
DB.sqls.
|
|
193
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
194
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT DISTINCT ON (tracks.album_id) * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY tracks.album_id, a']
|
|
195
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
196
|
+
DB.sqls.must_equal []
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
it "should eagerly load a single one_to_one association using the :window_function strategy" do
|
|
200
200
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
201
201
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy=>:window_function
|
|
202
202
|
a = EagerAlbum.eager(:track).all
|
|
203
|
-
a.
|
|
204
|
-
DB.sqls.
|
|
205
|
-
a.first.track.
|
|
206
|
-
DB.sqls.
|
|
203
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
204
|
+
DB.sqls.must_equal ['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)']
|
|
205
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
206
|
+
DB.sqls.must_equal []
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
it "should automatically use an eager limit stategy if the association has an offset" do
|
|
210
210
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
|
|
211
211
|
EagerTrack.dataset._fetch = [{:id => 4, :album_id=>1}]
|
|
212
212
|
a = EagerAlbum.eager(:track).all
|
|
213
|
-
a.
|
|
214
|
-
DB.sqls.
|
|
215
|
-
a.first.track.
|
|
216
|
-
DB.sqls.
|
|
213
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
214
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
|
215
|
+
a.first.track.must_equal EagerTrack.load(:id => 4, :album_id=>1)
|
|
216
|
+
DB.sqls.must_equal []
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
it "should handle offsets when using the :ruby eager limit stategy" do
|
|
220
220
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :eager_limit_strategy=>:ruby
|
|
221
221
|
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
|
222
222
|
a = EagerAlbum.eager(:track).all
|
|
223
|
-
a.
|
|
224
|
-
DB.sqls.
|
|
225
|
-
a.first.track.
|
|
226
|
-
DB.sqls.
|
|
223
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
224
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
225
|
+
a.first.track.must_equal EagerTrack.load(:id => 4, :album_id=>1)
|
|
226
|
+
DB.sqls.must_equal []
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
it "should support a :subqueries_per_union option for the number of subqueries in a union" do
|
|
@@ -231,181 +231,181 @@ describe Sequel::Model, "#eager" do
|
|
|
231
231
|
EagerAlbum.dataset._fetch = [{:id => 1, :band_id => 2}, {:id => 2, :band_id => 3}, {:id => 3, :band_id => 4}]
|
|
232
232
|
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}], [{:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
|
|
233
233
|
a = EagerAlbum.eager(:track).all
|
|
234
|
-
a.
|
|
235
|
-
DB.sqls.
|
|
236
|
-
a.first.track.
|
|
237
|
-
DB.sqls.
|
|
234
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
|
235
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
|
236
|
+
a.first.track.must_equal EagerTrack.load(:id => 4, :album_id=>1)
|
|
237
|
+
DB.sqls.must_equal []
|
|
238
238
|
|
|
239
239
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>2
|
|
240
240
|
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
|
|
241
241
|
a = EagerAlbum.eager(:track).all
|
|
242
|
-
a.
|
|
243
|
-
DB.sqls.
|
|
244
|
-
a.first.track.
|
|
245
|
-
DB.sqls.
|
|
242
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
|
243
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
|
244
|
+
a.first.track.must_equal EagerTrack.load(:id => 4, :album_id=>1)
|
|
245
|
+
DB.sqls.must_equal []
|
|
246
246
|
|
|
247
247
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>3
|
|
248
248
|
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}, {:id=>6, :album_id=>3}]]
|
|
249
249
|
a = EagerAlbum.eager(:track).all
|
|
250
|
-
a.
|
|
251
|
-
DB.sqls.
|
|
252
|
-
a.first.track.
|
|
253
|
-
DB.sqls.
|
|
250
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
|
251
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
|
252
|
+
a.first.track.must_equal EagerTrack.load(:id => 4, :album_id=>1)
|
|
253
|
+
DB.sqls.must_equal []
|
|
254
254
|
end
|
|
255
255
|
|
|
256
256
|
it "should eagerly load a single one_to_many association" do
|
|
257
257
|
a = EagerAlbum.eager(:tracks).all
|
|
258
|
-
a.
|
|
259
|
-
DB.sqls.
|
|
260
|
-
a.first.tracks.
|
|
261
|
-
DB.sqls.
|
|
258
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
259
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
260
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
261
|
+
DB.sqls.must_equal []
|
|
262
262
|
end
|
|
263
263
|
|
|
264
264
|
it "should eagerly load a single one_through_one association" do
|
|
265
265
|
a = EagerAlbum.eager(:genre).all
|
|
266
|
-
a.
|
|
267
|
-
DB.sqls.
|
|
268
|
-
a.first.genre.
|
|
269
|
-
DB.sqls.
|
|
266
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
267
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
268
|
+
a.first.genre.must_equal EagerGenre.load(:id=>4)
|
|
269
|
+
DB.sqls.must_equal []
|
|
270
270
|
end
|
|
271
271
|
|
|
272
272
|
it "should use first matching entry when eager loading one_through_one association" do
|
|
273
273
|
EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
|
|
274
274
|
a = EagerAlbum.eager(:genre).all
|
|
275
|
-
a.
|
|
276
|
-
DB.sqls.
|
|
277
|
-
a.first.genre.
|
|
278
|
-
DB.sqls.
|
|
275
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
276
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
277
|
+
a.first.genre.must_equal EagerGenre.load(:id=>3)
|
|
278
|
+
DB.sqls.must_equal []
|
|
279
279
|
end
|
|
280
280
|
|
|
281
281
|
it "should eagerly load a single one_through_one association" do
|
|
282
282
|
EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a
|
|
283
283
|
a = EagerAlbum.eager(:genre).all
|
|
284
|
-
a.
|
|
285
|
-
DB.sqls.
|
|
286
|
-
a.first.genre.
|
|
287
|
-
DB.sqls.
|
|
284
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
285
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (1 = ag.album_id) ORDER BY a LIMIT 1) AS t1"]
|
|
286
|
+
a.first.genre.must_equal EagerGenre.load(:id=>4)
|
|
287
|
+
DB.sqls.must_equal []
|
|
288
288
|
end
|
|
289
289
|
|
|
290
290
|
it "should eagerly load a single one_through_one association using the :distinct_on strategy" do
|
|
291
291
|
def (EagerGenre.dataset).supports_distinct_on?() true end
|
|
292
292
|
EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a, :eager_limit_strategy=>:distinct_on
|
|
293
293
|
a = EagerAlbum.eager(:genre).all
|
|
294
|
-
a.
|
|
295
|
-
DB.sqls.
|
|
296
|
-
a.first.genre.
|
|
297
|
-
DB.sqls.
|
|
294
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
295
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT DISTINCT ON (ag.album_id) genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1)) ORDER BY ag.album_id, a"]
|
|
296
|
+
a.first.genre.must_equal EagerGenre.load(:id=>4)
|
|
297
|
+
DB.sqls.must_equal []
|
|
298
298
|
end
|
|
299
299
|
|
|
300
300
|
it "should eagerly load a single one_through_one association using the :window_function strategy" do
|
|
301
301
|
def (EagerGenre.dataset).supports_window_functions?() true end
|
|
302
302
|
EagerAlbum.one_through_one :genre, :clone=>:genre, :eager_limit_strategy=>:window_function
|
|
303
303
|
a = EagerAlbum.eager(:genre).all
|
|
304
|
-
a.
|
|
305
|
-
DB.sqls.
|
|
306
|
-
a.first.genre.
|
|
307
|
-
DB.sqls.
|
|
304
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
305
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)"]
|
|
306
|
+
a.first.genre.must_equal EagerGenre.load(:id=>4)
|
|
307
|
+
DB.sqls.must_equal []
|
|
308
308
|
end
|
|
309
309
|
|
|
310
310
|
it "should automatically use an eager limit stategy if the association has an offset" do
|
|
311
311
|
EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
|
|
312
312
|
a = EagerAlbum.eager(:genre).all
|
|
313
|
-
a.
|
|
314
|
-
DB.sqls.
|
|
315
|
-
a.first.genre.
|
|
316
|
-
DB.sqls.
|
|
313
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
314
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
315
|
+
a.first.genre.must_equal EagerGenre.load(:id=>3)
|
|
316
|
+
DB.sqls.must_equal []
|
|
317
317
|
end
|
|
318
318
|
|
|
319
319
|
it "should eagerly load a single many_to_many association" do
|
|
320
320
|
a = EagerAlbum.eager(:genres).all
|
|
321
|
-
a.
|
|
322
|
-
DB.sqls.
|
|
323
|
-
a.first.genres.
|
|
324
|
-
DB.sqls.
|
|
321
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
322
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
323
|
+
a.first.genres.must_equal [EagerGenre.load(:id=>4)]
|
|
324
|
+
DB.sqls.must_equal []
|
|
325
325
|
end
|
|
326
326
|
|
|
327
327
|
it "should support using a custom :key option when eager loading many_to_one associations" do
|
|
328
328
|
EagerAlbum.many_to_one :sband, :clone=>:band, :key=>:band_id3
|
|
329
329
|
EagerBand.dataset._fetch = {:id=>6}
|
|
330
330
|
a = EagerAlbum.eager(:sband).all
|
|
331
|
-
DB.sqls.
|
|
332
|
-
a.
|
|
333
|
-
a.first.sband.
|
|
334
|
-
DB.sqls.
|
|
331
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (6))']
|
|
332
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
333
|
+
a.first.sband.must_equal EagerBand.load(:id=>6)
|
|
334
|
+
DB.sqls.must_equal []
|
|
335
335
|
end
|
|
336
336
|
|
|
337
337
|
it "should support using a custom :primary_key option when eager loading one_to_many associations" do
|
|
338
338
|
EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
|
|
339
339
|
EagerBand.dataset._fetch = {:id=>6}
|
|
340
340
|
a = EagerBand.eager(:salbums).all
|
|
341
|
-
DB.sqls.
|
|
342
|
-
a.
|
|
343
|
-
a.first.salbums.
|
|
344
|
-
DB.sqls.
|
|
341
|
+
DB.sqls.must_equal ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
|
|
342
|
+
a.must_equal [EagerBand.load(:id => 6)]
|
|
343
|
+
a.first.salbums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
344
|
+
DB.sqls.must_equal []
|
|
345
345
|
end
|
|
346
346
|
|
|
347
347
|
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
|
348
348
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :left_primary_key=>:band_id3
|
|
349
349
|
EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
|
|
350
350
|
a = EagerAlbum.eager(:sgenres).all
|
|
351
|
-
a.
|
|
352
|
-
DB.sqls.
|
|
353
|
-
a.first.sgenres.
|
|
354
|
-
DB.sqls.
|
|
351
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
352
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (6))"]
|
|
353
|
+
a.first.sgenres.must_equal [EagerGenre.load(:id=>4)]
|
|
354
|
+
DB.sqls.must_equal []
|
|
355
355
|
end
|
|
356
356
|
|
|
357
357
|
it "should support using a custom :left_primary_key option when eager loading one_through_one associations" do
|
|
358
358
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :left_primary_key=>:band_id3
|
|
359
359
|
EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
|
|
360
360
|
a = EagerAlbum.eager(:sgenre).all
|
|
361
|
-
a.
|
|
362
|
-
DB.sqls.
|
|
363
|
-
a.first.sgenre.
|
|
364
|
-
DB.sqls.
|
|
361
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
362
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (6))"]
|
|
363
|
+
a.first.sgenre.must_equal EagerGenre.load(:id=>4)
|
|
364
|
+
DB.sqls.must_equal []
|
|
365
365
|
end
|
|
366
366
|
|
|
367
367
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_one associations" do
|
|
368
368
|
EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>Sequel./(:bands__id, 3), :primary_key_method=>:id3
|
|
369
369
|
EagerBand.dataset._fetch = {:id=>6}
|
|
370
370
|
a = EagerAlbum.eager(:sband).all
|
|
371
|
-
DB.sqls.
|
|
372
|
-
a.
|
|
373
|
-
a.first.sband.
|
|
374
|
-
DB.sqls.
|
|
371
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
|
|
372
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
373
|
+
a.first.sband.must_equal EagerBand.load(:id=>6)
|
|
374
|
+
DB.sqls.must_equal []
|
|
375
375
|
end
|
|
376
376
|
|
|
377
377
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
|
|
378
378
|
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
|
|
379
379
|
EagerBand.dataset._fetch = {:id=>6}
|
|
380
380
|
a = EagerBand.eager(:salbums).all
|
|
381
|
-
DB.sqls.
|
|
382
|
-
a.
|
|
383
|
-
a.first.salbums.
|
|
384
|
-
DB.sqls.
|
|
381
|
+
DB.sqls.must_equal ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
|
|
382
|
+
a.must_equal [EagerBand.load(:id => 6)]
|
|
383
|
+
a.first.salbums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
384
|
+
DB.sqls.must_equal []
|
|
385
385
|
end
|
|
386
386
|
|
|
387
387
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_many associations" do
|
|
388
388
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
|
|
389
389
|
a = EagerAlbum.eager(:sgenres).all
|
|
390
|
-
a.
|
|
391
|
-
DB.sqls.
|
|
392
|
-
a.first.sgenres.
|
|
393
|
-
DB.sqls.
|
|
390
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
391
|
+
DB.sqls.must_equal ['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) WHERE ((ag.album_id * 1) IN (1))"]
|
|
392
|
+
a.first.sgenres.must_equal [EagerGenre.load(:id=>4)]
|
|
393
|
+
DB.sqls.must_equal []
|
|
394
394
|
end
|
|
395
395
|
|
|
396
396
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_through_one associations" do
|
|
397
397
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
|
|
398
398
|
a = EagerAlbum.eager(:sgenre).all
|
|
399
|
-
a.
|
|
400
|
-
DB.sqls.
|
|
401
|
-
a.first.sgenre.
|
|
402
|
-
DB.sqls.
|
|
399
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
400
|
+
DB.sqls.must_equal ['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) WHERE ((ag.album_id * 1) IN (1))"]
|
|
401
|
+
a.first.sgenre.must_equal EagerGenre.load(:id=>4)
|
|
402
|
+
DB.sqls.must_equal []
|
|
403
403
|
end
|
|
404
404
|
|
|
405
405
|
it "should raise an error for an unhandled :eager_loader_key option" do
|
|
406
406
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loader_key=>1
|
|
407
407
|
ds = EagerAlbum.eager(:sgenres)
|
|
408
|
-
proc{ds.all}.
|
|
408
|
+
proc{ds.all}.must_raise(Sequel::Error)
|
|
409
409
|
end
|
|
410
410
|
|
|
411
411
|
it "should not add entry to key_hash for :eager_loader_key=>nil option" do
|
|
@@ -413,102 +413,102 @@ describe Sequel::Model, "#eager" do
|
|
|
413
413
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loader_key=>nil, :eager_loader=>proc{|o| eo = o}
|
|
414
414
|
ds = EagerAlbum.eager(:sgenres)
|
|
415
415
|
ds.all
|
|
416
|
-
eo[:key_hash].
|
|
417
|
-
eo[:id_map].
|
|
416
|
+
eo[:key_hash].must_equal({})
|
|
417
|
+
eo[:id_map].must_equal nil
|
|
418
418
|
end
|
|
419
419
|
|
|
420
420
|
it "should correctly handle a :select=>[] option to many_to_many" do
|
|
421
421
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :select=>[]
|
|
422
422
|
EagerAlbum.eager(:sgenres).all
|
|
423
|
-
DB.sqls.
|
|
423
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
424
424
|
end
|
|
425
425
|
|
|
426
426
|
it "should correctly handle a :select=>[] option to one_through_one" do
|
|
427
427
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :select=>[]
|
|
428
428
|
EagerAlbum.eager(:sgenre).all
|
|
429
|
-
DB.sqls.
|
|
429
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
430
430
|
end
|
|
431
431
|
|
|
432
432
|
it "should correctly handle an aliased join table in many_to_many" do
|
|
433
433
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
|
434
434
|
EagerAlbum.eager(:sgenres).all
|
|
435
|
-
DB.sqls.
|
|
435
|
+
DB.sqls.must_equal ['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) WHERE (ga.album_id IN (1))"]
|
|
436
436
|
end
|
|
437
437
|
|
|
438
438
|
it "should correctly handle an aliased join table in one_through_one" do
|
|
439
439
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :join_table=>:ag___ga
|
|
440
440
|
EagerAlbum.eager(:sgenre).all
|
|
441
|
-
DB.sqls.
|
|
441
|
+
DB.sqls.must_equal ['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) WHERE (ga.album_id IN (1))"]
|
|
442
442
|
end
|
|
443
443
|
|
|
444
444
|
it "should eagerly load multiple associations in a single call" do
|
|
445
445
|
a = EagerAlbum.eager(:genres, :tracks, :band).all
|
|
446
|
-
a.
|
|
446
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
447
447
|
sqls = DB.sqls
|
|
448
|
-
sqls.shift.
|
|
449
|
-
sqls.sort.
|
|
448
|
+
sqls.shift.must_equal 'SELECT * FROM albums'
|
|
449
|
+
sqls.sort.must_equal ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
450
450
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
451
451
|
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))']
|
|
452
452
|
a = a.first
|
|
453
|
-
a.band.
|
|
454
|
-
a.tracks.
|
|
455
|
-
a.genres.
|
|
456
|
-
DB.sqls.
|
|
453
|
+
a.band.must_equal EagerBand.load(:id=>2)
|
|
454
|
+
a.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
455
|
+
a.genres.must_equal [EagerGenre.load(:id => 4)]
|
|
456
|
+
DB.sqls.must_equal []
|
|
457
457
|
end
|
|
458
458
|
|
|
459
459
|
it "should eagerly load multiple associations in separate calls" do
|
|
460
460
|
a = EagerAlbum.eager(:genres).eager(:tracks).eager(:band).all
|
|
461
|
-
a.
|
|
461
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
462
462
|
sqls = DB.sqls
|
|
463
|
-
sqls.shift.
|
|
464
|
-
sqls.sort.
|
|
463
|
+
sqls.shift.must_equal 'SELECT * FROM albums'
|
|
464
|
+
sqls.sort.must_equal ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
465
465
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
466
466
|
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))']
|
|
467
467
|
a = a.first
|
|
468
|
-
a.band.
|
|
469
|
-
a.tracks.
|
|
470
|
-
a.genres.
|
|
471
|
-
DB.sqls.
|
|
468
|
+
a.band.must_equal EagerBand.load(:id=>2)
|
|
469
|
+
a.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
470
|
+
a.genres.must_equal [EagerGenre.load(:id => 4)]
|
|
471
|
+
DB.sqls.must_equal []
|
|
472
472
|
end
|
|
473
473
|
|
|
474
474
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
475
475
|
a = EagerTrack.eager(:album=>{:band=>:members}).all
|
|
476
|
-
a.
|
|
477
|
-
DB.sqls.
|
|
476
|
+
a.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
477
|
+
DB.sqls.must_equal ['SELECT * FROM tracks',
|
|
478
478
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
479
479
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
480
480
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
|
481
481
|
a = a.first
|
|
482
|
-
a.album.
|
|
483
|
-
a.album.band.
|
|
484
|
-
a.album.band.members.
|
|
485
|
-
DB.sqls.
|
|
482
|
+
a.album.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
483
|
+
a.album.band.must_equal EagerBand.load(:id => 2)
|
|
484
|
+
a.album.band.members.must_equal [EagerBandMember.load(:id => 5)]
|
|
485
|
+
DB.sqls.must_equal []
|
|
486
486
|
end
|
|
487
487
|
|
|
488
488
|
it "should cascade eager loading when using a UNION strategy for eager loading limited associations" do
|
|
489
489
|
EagerTrack.many_to_one :album2, :clone=>:album
|
|
490
490
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a
|
|
491
491
|
a = EagerAlbum.eager(:track=>:album2).all
|
|
492
|
-
a.
|
|
493
|
-
DB.sqls.
|
|
494
|
-
a.first.track.
|
|
495
|
-
a.first.track.album2.
|
|
496
|
-
DB.sqls.
|
|
492
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
493
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))']
|
|
494
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
495
|
+
a.first.track.album2.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
496
|
+
DB.sqls.must_equal []
|
|
497
497
|
|
|
498
498
|
a = EagerAlbum.eager(:track=>[:album2]).all
|
|
499
|
-
a.
|
|
500
|
-
DB.sqls.
|
|
501
|
-
a.first.track.
|
|
502
|
-
a.first.track.album2.
|
|
503
|
-
DB.sqls.
|
|
499
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
500
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))']
|
|
501
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
502
|
+
a.first.track.album2.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
503
|
+
DB.sqls.must_equal []
|
|
504
504
|
|
|
505
505
|
a = EagerAlbum.eager(:track=>{:album2=>:track}).all
|
|
506
|
-
a.
|
|
507
|
-
DB.sqls.
|
|
508
|
-
a.first.track.
|
|
509
|
-
a.first.track.album2.
|
|
510
|
-
a.first.track.album2.track.
|
|
511
|
-
DB.sqls.
|
|
506
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
507
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1']
|
|
508
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
509
|
+
a.first.track.album2.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
510
|
+
a.first.track.album2.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
511
|
+
DB.sqls.must_equal []
|
|
512
512
|
end
|
|
513
513
|
|
|
514
514
|
it "should call post_load when eager loading limited associations" do
|
|
@@ -522,73 +522,73 @@ describe Sequel::Model, "#eager" do
|
|
|
522
522
|
end
|
|
523
523
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a, :extend=>m
|
|
524
524
|
EagerAlbum.eager(:track).all
|
|
525
|
-
a.
|
|
525
|
+
a.must_equal [1]
|
|
526
526
|
end
|
|
527
527
|
|
|
528
528
|
it "should cascade eagerly loading when the :eager association option is used" do
|
|
529
529
|
a = EagerBand.eager(:albums).all
|
|
530
|
-
a.
|
|
531
|
-
DB.sqls.
|
|
530
|
+
a.must_equal [EagerBand.load(:id=>2)]
|
|
531
|
+
DB.sqls.must_equal ['SELECT * FROM bands',
|
|
532
532
|
'SELECT * FROM albums WHERE (albums.band_id IN (2))',
|
|
533
533
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
534
|
-
a.first.albums.
|
|
535
|
-
a.first.albums.first.tracks.
|
|
536
|
-
DB.sqls.
|
|
534
|
+
a.first.albums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
535
|
+
a.first.albums.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
536
|
+
DB.sqls.must_equal []
|
|
537
537
|
end
|
|
538
538
|
|
|
539
539
|
it "should respect :eager when lazily loading an association" do
|
|
540
540
|
a = EagerBand.all
|
|
541
|
-
a.
|
|
542
|
-
DB.sqls.
|
|
541
|
+
a.must_equal [EagerBand.load(:id=>2)]
|
|
542
|
+
DB.sqls.must_equal ['SELECT * FROM bands']
|
|
543
543
|
a = a.first.albums
|
|
544
|
-
DB.sqls.
|
|
544
|
+
DB.sqls.must_equal ['SELECT * FROM albums WHERE (albums.band_id = 2)',
|
|
545
545
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
546
|
-
a.
|
|
547
|
-
a.first.tracks.
|
|
548
|
-
DB.sqls.
|
|
546
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
547
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
548
|
+
DB.sqls.must_equal []
|
|
549
549
|
end
|
|
550
550
|
|
|
551
551
|
it "should respect :eager with cascaded hash when lazily loading an association" do
|
|
552
552
|
EagerBand.one_to_many :albums, :eager=>{:tracks=>:album}, :clone=>:albums
|
|
553
553
|
a = EagerBand.all
|
|
554
|
-
a.
|
|
555
|
-
DB.sqls.
|
|
554
|
+
a.must_equal [EagerBand.load(:id=>2)]
|
|
555
|
+
DB.sqls.must_equal ['SELECT * FROM bands']
|
|
556
556
|
a = a.first.albums
|
|
557
|
-
DB.sqls.
|
|
557
|
+
DB.sqls.must_equal ['SELECT * FROM albums WHERE (albums.band_id = 2)',
|
|
558
558
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
559
559
|
'SELECT * FROM albums WHERE (albums.id IN (1))']
|
|
560
|
-
a.
|
|
561
|
-
a.first.tracks.
|
|
562
|
-
a.first.tracks.first.album.
|
|
563
|
-
DB.sqls.
|
|
560
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
561
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
562
|
+
a.first.tracks.first.album.must_equal a.first
|
|
563
|
+
DB.sqls.must_equal []
|
|
564
564
|
end
|
|
565
565
|
|
|
566
566
|
it "should cascade eagerly loading when the :eager_graph association option is used" do
|
|
567
567
|
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
568
568
|
a = EagerBand.eager(:graph_albums).all
|
|
569
|
-
a.
|
|
570
|
-
DB.sqls.
|
|
569
|
+
a.must_equal [EagerBand.load(:id=>2)]
|
|
570
|
+
DB.sqls.must_equal ['SELECT * FROM bands',
|
|
571
571
|
'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))']
|
|
572
|
-
a.first.graph_albums.
|
|
573
|
-
a.first.graph_albums.first.tracks.
|
|
574
|
-
DB.sqls.
|
|
572
|
+
a.first.graph_albums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
573
|
+
a.first.graph_albums.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
574
|
+
DB.sqls.must_equal []
|
|
575
575
|
end
|
|
576
576
|
|
|
577
577
|
it "should raise an Error when eager loading a many_to_many association with the :eager_graph option" do
|
|
578
|
-
proc{EagerBand.eager(:graph_members).all}.
|
|
578
|
+
proc{EagerBand.eager(:graph_members).all}.must_raise(Sequel::Error)
|
|
579
579
|
end
|
|
580
580
|
|
|
581
581
|
it "should respect :eager_graph when lazily loading an association" do
|
|
582
582
|
a = EagerBand.all
|
|
583
|
-
a.
|
|
584
|
-
DB.sqls.
|
|
583
|
+
a.must_equal [EagerBand.load(:id=>2)]
|
|
584
|
+
DB.sqls.must_equal ['SELECT * FROM bands']
|
|
585
585
|
a = a.first
|
|
586
586
|
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
587
587
|
a.graph_albums
|
|
588
|
-
DB.sqls.
|
|
589
|
-
a.graph_albums.
|
|
590
|
-
a.graph_albums.first.tracks.
|
|
591
|
-
DB.sqls.
|
|
588
|
+
DB.sqls.must_equal ['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)']
|
|
589
|
+
a.graph_albums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
590
|
+
a.graph_albums.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
591
|
+
DB.sqls.must_equal []
|
|
592
592
|
end
|
|
593
593
|
|
|
594
594
|
it "should respect :eager_graph when lazily loading a many_to_many association" do
|
|
@@ -596,243 +596,243 @@ describe Sequel::Model, "#eager" do
|
|
|
596
596
|
def ds.columns() [:id] end
|
|
597
597
|
ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
|
|
598
598
|
a = EagerBand.load(:id=>2)
|
|
599
|
-
a.graph_members.
|
|
600
|
-
DB.sqls.
|
|
601
|
-
a.graph_members.first.bands.
|
|
602
|
-
DB.sqls.
|
|
599
|
+
a.graph_members.must_equal [EagerBandMember.load(:id=>5)]
|
|
600
|
+
DB.sqls.must_equal ['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) WHERE (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']
|
|
601
|
+
a.graph_members.first.bands.must_equal [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
|
|
602
|
+
DB.sqls.must_equal []
|
|
603
603
|
end
|
|
604
604
|
|
|
605
605
|
it "should respect :conditions when eagerly loading" do
|
|
606
606
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
|
|
607
607
|
a = EagerBandMember.eager(:good_bands).all
|
|
608
|
-
a.
|
|
609
|
-
DB.sqls.
|
|
610
|
-
a.first.good_bands.
|
|
611
|
-
DB.sqls.
|
|
608
|
+
a.must_equal [EagerBandMember.load(:id => 5)]
|
|
609
|
+
DB.sqls.must_equal ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (bm.band_id = bands.id) WHERE ((a = 32) AND (bm.member_id IN (5))) ORDER BY id']
|
|
610
|
+
a.first.good_bands.must_equal [EagerBand.load(:id => 2)]
|
|
611
|
+
DB.sqls.must_equal []
|
|
612
612
|
|
|
613
613
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
|
614
614
|
a = EagerBandMember.eager(:good_bands).all
|
|
615
|
-
DB.sqls.
|
|
615
|
+
DB.sqls.must_equal ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (bm.band_id = bands.id) WHERE ((x = 1) AND (bm.member_id IN (5))) ORDER BY id']
|
|
616
616
|
end
|
|
617
617
|
|
|
618
618
|
it "should respect :order when eagerly loading" do
|
|
619
619
|
a = EagerBandMember.eager(:bands).all
|
|
620
|
-
a.
|
|
621
|
-
DB.sqls.
|
|
622
|
-
a.first.bands.
|
|
623
|
-
DB.sqls.
|
|
620
|
+
a.must_equal [EagerBandMember.load(:id => 5)]
|
|
621
|
+
DB.sqls.must_equal ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (bm.band_id = bands.id) WHERE (bm.member_id IN (5)) ORDER BY id']
|
|
622
|
+
a.first.bands.must_equal [EagerBand.load(:id => 2)]
|
|
623
|
+
DB.sqls.must_equal []
|
|
624
624
|
end
|
|
625
625
|
|
|
626
626
|
it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
|
|
627
627
|
a = EagerAlbum.eager(:tracks).all
|
|
628
|
-
a.
|
|
629
|
-
DB.sqls.
|
|
630
|
-
a.first.tracks.
|
|
631
|
-
a.first.tracks.first.album.
|
|
632
|
-
DB.sqls.
|
|
628
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
629
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
630
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
631
|
+
a.first.tracks.first.album.must_equal a.first
|
|
632
|
+
DB.sqls.must_equal []
|
|
633
633
|
end
|
|
634
634
|
|
|
635
635
|
it "should cache the negative lookup when eagerly loading a many_to_one association" do
|
|
636
636
|
a = EagerAlbum.eager(:band).filter(:id=>101).all
|
|
637
|
-
a.
|
|
638
|
-
DB.sqls.
|
|
639
|
-
a.first.associations.fetch(:band, 2).
|
|
640
|
-
a.first.band.
|
|
641
|
-
DB.sqls.
|
|
637
|
+
a.must_equal [EagerAlbum.load(:id => 101, :band_id => 101)]
|
|
638
|
+
DB.sqls.must_equal ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
|
|
639
|
+
a.first.associations.fetch(:band, 2).must_equal nil
|
|
640
|
+
a.first.band.must_equal nil
|
|
641
|
+
DB.sqls.must_equal []
|
|
642
642
|
end
|
|
643
643
|
|
|
644
644
|
it "should cache the negative lookup when eagerly loading a *_to_many associations" do
|
|
645
645
|
a = EagerBand.eager(:albums).filter('id > 100').all
|
|
646
|
-
a.
|
|
646
|
+
a.must_equal [EagerBand.load(:id => 101), EagerBand.load(:id =>102)]
|
|
647
647
|
sqls = DB.sqls
|
|
648
|
-
['SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', 'SELECT * FROM albums WHERE (albums.band_id IN (102, 101))'].
|
|
649
|
-
sqls.
|
|
650
|
-
a.map{|b| b.associations[:albums]}.
|
|
651
|
-
DB.sqls.
|
|
648
|
+
['SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', 'SELECT * FROM albums WHERE (albums.band_id IN (102, 101))'].must_include(sqls.delete_at(1))
|
|
649
|
+
sqls.must_equal ['SELECT * FROM bands WHERE (id > 100)', "SELECT * FROM tracks WHERE (tracks.album_id IN (101))"]
|
|
650
|
+
a.map{|b| b.associations[:albums]}.must_equal [[EagerAlbum.load({:band_id=>101, :id=>101})], []]
|
|
651
|
+
DB.sqls.must_equal []
|
|
652
652
|
end
|
|
653
653
|
|
|
654
654
|
it "should use the association's block when eager loading by default" do
|
|
655
655
|
EagerAlbum.eager(:good_tracks).all
|
|
656
|
-
DB.sqls.
|
|
656
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((name = 'Good') AND (tracks.album_id IN (1)))"]
|
|
657
657
|
end
|
|
658
658
|
|
|
659
659
|
it "should use the eager_block option when eager loading if given" do
|
|
660
660
|
EagerBand.eager(:good_albums).all
|
|
661
|
-
DB.sqls.
|
|
661
|
+
DB.sqls.must_equal ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))"]
|
|
662
662
|
EagerBand.eager(:good_albums=>:good_tracks).all
|
|
663
|
-
DB.sqls.
|
|
663
|
+
DB.sqls.must_equal ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))", "SELECT * FROM tracks WHERE ((name = 'Good') AND (tracks.album_id IN (1)))"]
|
|
664
664
|
end
|
|
665
665
|
|
|
666
666
|
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
|
667
|
-
proc{EagerBand.eager(:self_titled_albums).all}.
|
|
668
|
-
proc{EagerBand.eager(:albums_by_name).all}.
|
|
667
|
+
proc{EagerBand.eager(:self_titled_albums).all}.must_raise(Sequel::Error)
|
|
668
|
+
proc{EagerBand.eager(:albums_by_name).all}.must_raise(Sequel::Error)
|
|
669
669
|
end
|
|
670
670
|
|
|
671
671
|
it "should respect the association's :select option" do
|
|
672
672
|
EagerAlbum.eager(:band_name).all
|
|
673
|
-
DB.sqls.
|
|
673
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT id, name FROM bands WHERE (bands.id IN (2))"]
|
|
674
674
|
EagerAlbum.eager(:track_names).all
|
|
675
|
-
DB.sqls.
|
|
675
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
676
676
|
EagerAlbum.eager(:genre_names).all
|
|
677
|
-
DB.sqls.
|
|
677
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
678
678
|
end
|
|
679
679
|
|
|
680
680
|
it "should respect many_to_one association's :qualify option" do
|
|
681
681
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :qualify=>false, :key=>:band_id
|
|
682
682
|
EagerBand.dataset._fetch = {:id=>2}
|
|
683
683
|
as = EagerAlbum.eager(:special_band).all
|
|
684
|
-
DB.sqls.
|
|
685
|
-
as.map{|a| a.special_band}.
|
|
686
|
-
DB.sqls.
|
|
684
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
|
|
685
|
+
as.map{|a| a.special_band}.must_equal [EagerBand.load(:id=>2)]
|
|
686
|
+
DB.sqls.must_equal []
|
|
687
687
|
end
|
|
688
688
|
|
|
689
689
|
it "should respect the association's :primary_key option" do
|
|
690
690
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>:p_k, :key=>:band_id
|
|
691
691
|
EagerBand.dataset._fetch = {:p_k=>2, :id=>1}
|
|
692
692
|
as = EagerAlbum.eager(:special_band).all
|
|
693
|
-
DB.sqls.
|
|
694
|
-
as.length.
|
|
695
|
-
as.first.special_band.
|
|
693
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
|
|
694
|
+
as.length.must_equal 1
|
|
695
|
+
as.first.special_band.must_equal EagerBand.load(:p_k=>2, :id=>1)
|
|
696
696
|
|
|
697
697
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
|
|
698
698
|
EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
|
|
699
699
|
as = EagerAlbum.eager(:special_tracks).all
|
|
700
|
-
DB.sqls.
|
|
701
|
-
as.length.
|
|
702
|
-
as.first.special_tracks.
|
|
700
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
|
|
701
|
+
as.length.must_equal 1
|
|
702
|
+
as.first.special_tracks.must_equal [EagerTrack.load(:album_id=>2, :id=>1)]
|
|
703
703
|
end
|
|
704
704
|
|
|
705
705
|
it "should respect the many_to_one association's composite keys" do
|
|
706
706
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>[:id, :p_k], :key=>[:band_id, :id]
|
|
707
707
|
EagerBand.dataset._fetch = {:p_k=>1, :id=>2}
|
|
708
708
|
as = EagerAlbum.eager(:special_band).all
|
|
709
|
-
DB.sqls.
|
|
710
|
-
as.length.
|
|
711
|
-
as.first.special_band.
|
|
709
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
|
|
710
|
+
as.length.must_equal 1
|
|
711
|
+
as.first.special_band.must_equal EagerBand.load(:p_k=>1, :id=>2)
|
|
712
712
|
end
|
|
713
713
|
|
|
714
714
|
it "should respect the one_to_many association's composite keys" do
|
|
715
715
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>[:band_id, :id], :key=>[:id, :album_id]
|
|
716
716
|
EagerTrack.dataset._fetch = {:album_id=>1, :id=>2}
|
|
717
717
|
as = EagerAlbum.eager(:special_tracks).all
|
|
718
|
-
DB.sqls.
|
|
719
|
-
as.length.
|
|
720
|
-
as.first.special_tracks.
|
|
718
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
|
|
719
|
+
as.length.must_equal 1
|
|
720
|
+
as.first.special_tracks.must_equal [EagerTrack.load(:album_id=>1, :id=>2)]
|
|
721
721
|
end
|
|
722
722
|
|
|
723
723
|
it "should respect many_to_many association's composite keys" do
|
|
724
724
|
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
|
|
725
725
|
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}]
|
|
726
726
|
as = EagerAlbum.eager(:special_genres).all
|
|
727
|
-
DB.sqls.
|
|
728
|
-
as.length.
|
|
729
|
-
as.first.special_genres.
|
|
727
|
+
DB.sqls.must_equal ['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)) WHERE ((ag.l1, ag.l2) IN ((2, 1)))"]
|
|
728
|
+
as.length.must_equal 1
|
|
729
|
+
as.first.special_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
730
730
|
end
|
|
731
731
|
|
|
732
732
|
it "should respect one_through_one association's composite keys" do
|
|
733
733
|
EagerAlbum.one_through_one :special_genre, :class=>:EagerGenre, :left_primary_key=>[:band_id, :id], :left_key=>[:l1, :l2], :right_primary_key=>[:xxx, :id], :right_key=>[:r1, :r2], :join_table=>:ag
|
|
734
734
|
EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}]
|
|
735
735
|
as = EagerAlbum.eager(:special_genre).all
|
|
736
|
-
DB.sqls.
|
|
737
|
-
as.length.
|
|
738
|
-
as.first.special_genre.
|
|
736
|
+
DB.sqls.must_equal ['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)) WHERE ((ag.l1, ag.l2) IN ((2, 1)))"]
|
|
737
|
+
as.length.must_equal 1
|
|
738
|
+
as.first.special_genre.must_equal EagerGenre.load(:id=>5)
|
|
739
739
|
end
|
|
740
740
|
|
|
741
741
|
it "should respect many_to_many association's :left_primary_key and :right_primary_key options" do
|
|
742
742
|
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
|
|
743
743
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
744
744
|
as = EagerAlbum.eager(:special_genres).all
|
|
745
|
-
DB.sqls.
|
|
746
|
-
as.length.
|
|
747
|
-
as.first.special_genres.
|
|
745
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.xxx) WHERE (ag.album_id IN (2))"]
|
|
746
|
+
as.length.must_equal 1
|
|
747
|
+
as.first.special_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
748
748
|
end
|
|
749
749
|
|
|
750
750
|
it "should respect one_through_one association's :left_primary_key and :right_primary_key options" do
|
|
751
751
|
EagerAlbum.one_through_one :special_genre, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_primary_key=>:xxx, :right_key=>:genre_id, :join_table=>:ag
|
|
752
752
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
|
753
753
|
as = EagerAlbum.eager(:special_genre).all
|
|
754
|
-
DB.sqls.
|
|
755
|
-
as.length.
|
|
756
|
-
as.first.special_genre.
|
|
754
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.xxx) WHERE (ag.album_id IN (2))"]
|
|
755
|
+
as.length.must_equal 1
|
|
756
|
+
as.first.special_genre.must_equal EagerGenre.load(:id=>5)
|
|
757
757
|
end
|
|
758
758
|
|
|
759
759
|
it "should respect the :limit option on a one_to_many association using the :ruby strategy" do
|
|
760
760
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_limit_strategy=>:ruby
|
|
761
761
|
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
|
|
762
762
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
763
|
-
DB.sqls.
|
|
764
|
-
as.length.
|
|
765
|
-
as.first.first_two_tracks.
|
|
763
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
764
|
+
as.length.must_equal 1
|
|
765
|
+
as.first.first_two_tracks.must_equal [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
|
|
766
766
|
|
|
767
767
|
DB.reset
|
|
768
768
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[1,1], :eager_limit_strategy=>:ruby
|
|
769
769
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
770
|
-
DB.sqls.
|
|
771
|
-
as.length.
|
|
772
|
-
as.first.first_two_tracks.
|
|
770
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
771
|
+
as.length.must_equal 1
|
|
772
|
+
as.first.first_two_tracks.must_equal [EagerTrack.load(:album_id=>1, :id=>3)]
|
|
773
773
|
|
|
774
774
|
DB.reset
|
|
775
775
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[nil,1], :eager_limit_strategy=>:ruby
|
|
776
776
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
777
|
-
DB.sqls.
|
|
778
|
-
as.length.
|
|
779
|
-
as.first.first_two_tracks.
|
|
777
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
778
|
+
as.length.must_equal 1
|
|
779
|
+
as.first.first_two_tracks.must_equal [EagerTrack.load(:album_id=>1, :id=>3), EagerTrack.load(:album_id=>1, :id=>4)]
|
|
780
780
|
end
|
|
781
781
|
|
|
782
782
|
it "should respect the :limit option on a one_to_many association" do
|
|
783
783
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
|
|
784
784
|
a = EagerAlbum.eager(:tracks).all
|
|
785
|
-
a.
|
|
786
|
-
DB.sqls.
|
|
787
|
-
a.first.tracks.
|
|
788
|
-
DB.sqls.
|
|
785
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
786
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name LIMIT 2) AS t1']
|
|
787
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
788
|
+
DB.sqls.must_equal []
|
|
789
789
|
|
|
790
790
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1]
|
|
791
791
|
a = EagerAlbum.eager(:tracks).all
|
|
792
|
-
a.
|
|
793
|
-
DB.sqls.
|
|
794
|
-
a.first.tracks.
|
|
795
|
-
DB.sqls.
|
|
792
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
793
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name LIMIT 2 OFFSET 1) AS t1']
|
|
794
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
795
|
+
DB.sqls.must_equal []
|
|
796
796
|
|
|
797
797
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1]
|
|
798
798
|
a = EagerAlbum.eager(:tracks).all
|
|
799
|
-
a.
|
|
800
|
-
DB.sqls.
|
|
801
|
-
a.first.tracks.
|
|
802
|
-
DB.sqls.
|
|
799
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
800
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name OFFSET 1) AS t1']
|
|
801
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
802
|
+
DB.sqls.must_equal []
|
|
803
803
|
end
|
|
804
804
|
|
|
805
805
|
it "should respect the :limit option on a one_to_many association with an association block" do
|
|
806
806
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2 do |ds| ds.where(:a=>1) end
|
|
807
807
|
a = EagerAlbum.eager(:tracks).all
|
|
808
|
-
a.
|
|
809
|
-
DB.sqls.
|
|
810
|
-
a.first.tracks.
|
|
811
|
-
DB.sqls.
|
|
808
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
809
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE ((a = 1) AND (1 = tracks.album_id)) ORDER BY name LIMIT 2) AS t1']
|
|
810
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
811
|
+
DB.sqls.must_equal []
|
|
812
812
|
end
|
|
813
813
|
|
|
814
814
|
it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
|
|
815
815
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
816
816
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2, :eager_limit_strategy=>:window_function
|
|
817
817
|
a = EagerAlbum.eager(:tracks).all
|
|
818
|
-
a.
|
|
819
|
-
DB.sqls.
|
|
820
|
-
a.first.tracks.
|
|
821
|
-
DB.sqls.
|
|
818
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
819
|
+
DB.sqls.must_equal ['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)']
|
|
820
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
821
|
+
DB.sqls.must_equal []
|
|
822
822
|
|
|
823
823
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1], :eager_limit_strategy=>:window_function
|
|
824
824
|
a = EagerAlbum.eager(:tracks).all
|
|
825
|
-
a.
|
|
826
|
-
DB.sqls.
|
|
827
|
-
a.first.tracks.
|
|
828
|
-
DB.sqls.
|
|
825
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
826
|
+
DB.sqls.must_equal ['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))']
|
|
827
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
828
|
+
DB.sqls.must_equal []
|
|
829
829
|
|
|
830
830
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1], :eager_limit_strategy=>:window_function
|
|
831
831
|
a = EagerAlbum.eager(:tracks).all
|
|
832
|
-
a.
|
|
833
|
-
DB.sqls.
|
|
834
|
-
a.first.tracks.
|
|
835
|
-
DB.sqls.
|
|
832
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
833
|
+
DB.sqls.must_equal ['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)']
|
|
834
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
835
|
+
DB.sqls.must_equal []
|
|
836
836
|
end
|
|
837
837
|
|
|
838
838
|
it "should use a ruby strategy for limit if :eager_graph option is used" do
|
|
@@ -840,45 +840,45 @@ describe Sequel::Model, "#eager" do
|
|
|
840
840
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_graph=>:album2
|
|
841
841
|
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2, :album2_id=>1, :band_id=>5}, {:album_id=>1, :id=>3, :album2_id=>1, :band_id=>5}, {:album_id=>1, :id=>4, :album2_id=>1, :band_id=>5}]
|
|
842
842
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
843
|
-
DB.sqls.
|
|
844
|
-
as.length.
|
|
843
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT tracks.id, tracks.album_id, album2.id AS album2_id, album2.band_id FROM tracks LEFT OUTER JOIN albums AS album2 ON (album2.id = tracks.album_id) WHERE (tracks.album_id IN (1))"]
|
|
844
|
+
as.length.must_equal 1
|
|
845
845
|
tracks = as.first.first_two_tracks
|
|
846
|
-
tracks.
|
|
847
|
-
tracks.first.album2.
|
|
848
|
-
tracks.last.album2.
|
|
846
|
+
tracks.must_equal [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
|
|
847
|
+
tracks.first.album2.must_equal EagerAlbum.load(:id=>1, :band_id=>5)
|
|
848
|
+
tracks.last.album2.must_equal EagerAlbum.load(:id=>1, :band_id=>5)
|
|
849
849
|
end
|
|
850
850
|
|
|
851
851
|
it "should not use a union strategy for limit by default if providing a per-eager load callback" do
|
|
852
852
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
|
853
853
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
|
|
854
854
|
a = EagerAlbum.eager(:tracks=>proc{|ds| ds.where(:id=>3)}).all
|
|
855
|
-
a.
|
|
856
|
-
DB.sqls.
|
|
857
|
-
a.first.tracks.
|
|
858
|
-
DB.sqls.
|
|
855
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
856
|
+
DB.sqls.must_equal ['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)) AND (id = 3))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
|
857
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
858
|
+
DB.sqls.must_equal []
|
|
859
859
|
end
|
|
860
860
|
|
|
861
861
|
it "should respect the limit option on a many_to_many association using the :ruby strategy" do
|
|
862
862
|
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, :eager_limit_strategy=>:ruby
|
|
863
863
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
864
864
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
865
|
-
DB.sqls.
|
|
866
|
-
as.length.
|
|
867
|
-
as.first.first_two_genres.
|
|
865
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (2))"]
|
|
866
|
+
as.length.must_equal 1
|
|
867
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
868
868
|
|
|
869
869
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
870
870
|
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], :eager_limit_strategy=>:ruby
|
|
871
871
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
872
|
-
DB.sqls.
|
|
873
|
-
as.length.
|
|
874
|
-
as.first.first_two_genres.
|
|
872
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (2))"]
|
|
873
|
+
as.length.must_equal 1
|
|
874
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>6)]
|
|
875
875
|
|
|
876
876
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
877
877
|
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], :eager_limit_strategy=>:ruby
|
|
878
878
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
879
|
-
DB.sqls.
|
|
880
|
-
as.length.
|
|
881
|
-
as.first.first_two_genres.
|
|
879
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (2))"]
|
|
880
|
+
as.length.must_equal 1
|
|
881
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>6), EagerGenre.load(:id=>7)]
|
|
882
882
|
end
|
|
883
883
|
|
|
884
884
|
it "should respect the limit option on a many_to_many association" do
|
|
@@ -886,23 +886,23 @@ describe Sequel::Model, "#eager" do
|
|
|
886
886
|
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
|
|
887
887
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
888
888
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
889
|
-
DB.sqls.
|
|
890
|
-
as.length.
|
|
891
|
-
as.first.first_two_genres.
|
|
889
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name LIMIT 2) AS t1"]
|
|
890
|
+
as.length.must_equal 1
|
|
891
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
892
892
|
|
|
893
893
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
|
894
894
|
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
|
|
895
895
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
896
|
-
DB.sqls.
|
|
897
|
-
as.length.
|
|
898
|
-
as.first.first_two_genres.
|
|
896
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name LIMIT 1 OFFSET 1) AS t1"]
|
|
897
|
+
as.length.must_equal 1
|
|
898
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5)]
|
|
899
899
|
|
|
900
900
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
901
901
|
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
|
|
902
902
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
903
|
-
DB.sqls.
|
|
904
|
-
as.length.
|
|
905
|
-
as.first.first_two_genres.
|
|
903
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name OFFSET 1) AS t1"]
|
|
904
|
+
as.length.must_equal 1
|
|
905
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
906
906
|
end
|
|
907
907
|
|
|
908
908
|
it "should respect the limit option on a many_to_many association using the :window_function strategy" do
|
|
@@ -910,23 +910,23 @@ describe Sequel::Model, "#eager" do
|
|
|
910
910
|
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, :eager_limit_strategy=>:window_function
|
|
911
911
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
912
912
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
913
|
-
DB.sqls.
|
|
914
|
-
as.length.
|
|
915
|
-
as.first.first_two_genres.
|
|
913
|
+
DB.sqls.must_equal ['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) WHERE (ag.album_id IN (2))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
|
|
914
|
+
as.length.must_equal 1
|
|
915
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
916
916
|
|
|
917
917
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
|
918
918
|
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, :eager_limit_strategy=>:window_function
|
|
919
919
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
920
|
-
DB.sqls.
|
|
921
|
-
as.length.
|
|
922
|
-
as.first.first_two_genres.
|
|
920
|
+
DB.sqls.must_equal ['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) WHERE (ag.album_id IN (2))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 3))"]
|
|
921
|
+
as.length.must_equal 1
|
|
922
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5)]
|
|
923
923
|
|
|
924
924
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
925
925
|
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, :eager_limit_strategy=>:window_function
|
|
926
926
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
927
|
-
DB.sqls.
|
|
928
|
-
as.length.
|
|
929
|
-
as.first.first_two_genres.
|
|
927
|
+
DB.sqls.must_equal ['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) WHERE (ag.album_id IN (2))) AS t1 WHERE (x_sequel_row_number_x >= 2)"]
|
|
928
|
+
as.length.must_equal 1
|
|
929
|
+
as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
930
930
|
end
|
|
931
931
|
|
|
932
932
|
it "should use the :eager_loader association option when eager loading" do
|
|
@@ -943,17 +943,17 @@ describe Sequel::Model, "#eager" do
|
|
|
943
943
|
eo[:rows].each{|r| r.associations[:special_genres] = items}
|
|
944
944
|
end)
|
|
945
945
|
a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
|
|
946
|
-
a.
|
|
946
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
947
947
|
sqls = DB.sqls
|
|
948
|
-
sqls.shift.
|
|
949
|
-
sqls.sort.
|
|
948
|
+
sqls.shift.must_equal 'SELECT * FROM albums'
|
|
949
|
+
sqls.sort.must_equal ['SELECT * FROM bands WHERE (album_id IN (1, 2)) ORDER BY name LIMIT 1',
|
|
950
950
|
'SELECT * FROM genres INNER JOIN ag USING (genre_id) WHERE (album_id IN (1))',
|
|
951
951
|
'SELECT * FROM tracks WHERE (album_id IN (1, 2))']
|
|
952
952
|
a = a.first
|
|
953
|
-
a.special_band.
|
|
954
|
-
a.special_tracks.
|
|
955
|
-
a.special_genres.
|
|
956
|
-
DB.sqls.
|
|
953
|
+
a.special_band.must_equal EagerBand.load(:id => 2)
|
|
954
|
+
a.special_tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
955
|
+
a.special_genres.must_equal [EagerGenre.load(:id => 4)]
|
|
956
|
+
DB.sqls.must_equal []
|
|
957
957
|
end
|
|
958
958
|
|
|
959
959
|
it "should respect :after_load callbacks on associations when eager loading" do
|
|
@@ -961,122 +961,122 @@ describe Sequel::Model, "#eager" do
|
|
|
961
961
|
EagerAlbum.one_to_many :al_tracks, :class=>'EagerTrack', :key=>:album_id, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
962
962
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
963
963
|
a = EagerAlbum.eager(:al_band, :al_tracks, :al_genres).all.first
|
|
964
|
-
a.
|
|
965
|
-
a.al_band.
|
|
966
|
-
a.al_tracks.
|
|
967
|
-
a.al_genres.
|
|
964
|
+
a.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
965
|
+
a.al_band.must_equal EagerBand.load(:id=>4)
|
|
966
|
+
a.al_tracks.must_equal [EagerTrack.load(:id=>6, :album_id=>1)]
|
|
967
|
+
a.al_genres.must_equal [EagerGenre.load(:id=>8)]
|
|
968
968
|
end
|
|
969
969
|
|
|
970
970
|
it "should respect :uniq option when eagerly loading many_to_many associations" do
|
|
971
971
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
|
|
972
972
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
|
|
973
973
|
a = EagerAlbum.eager(:al_genres).all.first
|
|
974
|
-
DB.sqls.
|
|
975
|
-
a.
|
|
976
|
-
a.al_genres.
|
|
974
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
975
|
+
a.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
976
|
+
a.al_genres.must_equal [EagerGenre.load(:id=>8)]
|
|
977
977
|
end
|
|
978
978
|
|
|
979
979
|
it "should respect :distinct option when eagerly loading many_to_many associations" do
|
|
980
980
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :distinct=>true
|
|
981
981
|
a = EagerAlbum.eager(:al_genres).all.first
|
|
982
|
-
DB.sqls.
|
|
983
|
-
a.
|
|
984
|
-
a.al_genres.
|
|
982
|
+
DB.sqls.must_equal ['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) WHERE (ag.album_id IN (1))"]
|
|
983
|
+
a.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
984
|
+
a.al_genres.must_equal [EagerGenre.load(:id=>4)]
|
|
985
985
|
end
|
|
986
986
|
|
|
987
987
|
it "should eagerly load a many_to_one association with custom eager block" do
|
|
988
988
|
a = EagerAlbum.eager(:band => proc {|ds| ds.select(:id, :name)}).all
|
|
989
|
-
a.
|
|
990
|
-
DB.sqls.
|
|
991
|
-
a.first.band.
|
|
992
|
-
DB.sqls.
|
|
989
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
990
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT id, name FROM bands WHERE (bands.id IN (2))']
|
|
991
|
+
a.first.band.must_equal EagerBand.load(:id => 2)
|
|
992
|
+
DB.sqls.must_equal []
|
|
993
993
|
end
|
|
994
994
|
|
|
995
995
|
it "should eagerly load a one_to_one association with custom eager block" do
|
|
996
996
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
|
997
997
|
a = EagerAlbum.eager(:track => proc {|ds| ds.select(:id)}).all
|
|
998
|
-
a.
|
|
999
|
-
DB.sqls.
|
|
1000
|
-
a.first.track.
|
|
1001
|
-
DB.sqls.
|
|
998
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
999
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
1000
|
+
a.first.track.must_equal EagerTrack.load(:id => 3, :album_id=>1)
|
|
1001
|
+
DB.sqls.must_equal []
|
|
1002
1002
|
end
|
|
1003
1003
|
|
|
1004
1004
|
it "should eagerly load a one_to_many association with custom eager block" do
|
|
1005
1005
|
a = EagerAlbum.eager(:tracks => proc {|ds| ds.select(:id)}).all
|
|
1006
|
-
a.
|
|
1007
|
-
DB.sqls.
|
|
1008
|
-
a.first.tracks.
|
|
1009
|
-
DB.sqls.
|
|
1006
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
1007
|
+
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
1008
|
+
a.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
1009
|
+
DB.sqls.must_equal []
|
|
1010
1010
|
end
|
|
1011
1011
|
|
|
1012
1012
|
it "should eagerly load a many_to_many association with custom eager block" do
|
|
1013
1013
|
a = EagerAlbum.eager(:genres => proc {|ds| ds.select(:name)}).all
|
|
1014
|
-
a.
|
|
1015
|
-
DB.sqls.
|
|
1016
|
-
a.first.genres.
|
|
1017
|
-
DB.sqls.
|
|
1014
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
1015
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
1016
|
+
a.first.genres.must_equal [EagerGenre.load(:id => 4)]
|
|
1017
|
+
DB.sqls.must_equal []
|
|
1018
1018
|
end
|
|
1019
1019
|
|
|
1020
1020
|
it "should eagerly load a one_through_one association with custom eager block" do
|
|
1021
1021
|
a = EagerAlbum.eager(:genre => proc {|ds| ds.select(:name)}).all
|
|
1022
|
-
a.
|
|
1023
|
-
DB.sqls.
|
|
1024
|
-
a.first.genre.
|
|
1025
|
-
DB.sqls.
|
|
1022
|
+
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
1023
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
1024
|
+
a.first.genre.must_equal EagerGenre.load(:id => 4)
|
|
1025
|
+
DB.sqls.must_equal []
|
|
1026
1026
|
end
|
|
1027
1027
|
|
|
1028
1028
|
it "should allow cascading of eager loading within a custom eager block" do
|
|
1029
1029
|
a = EagerTrack.eager(:album => proc {|ds| ds.eager(:band => :members)}).all
|
|
1030
|
-
a.
|
|
1031
|
-
DB.sqls.
|
|
1030
|
+
a.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
1031
|
+
DB.sqls.must_equal ['SELECT * FROM tracks',
|
|
1032
1032
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
1033
1033
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
1034
1034
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
|
1035
1035
|
a = a.first
|
|
1036
|
-
a.album.
|
|
1037
|
-
a.album.band.
|
|
1038
|
-
a.album.band.members.
|
|
1039
|
-
DB.sqls.
|
|
1036
|
+
a.album.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
1037
|
+
a.album.band.must_equal EagerBand.load(:id => 2)
|
|
1038
|
+
a.album.band.members.must_equal [EagerBandMember.load(:id => 5)]
|
|
1039
|
+
DB.sqls.must_equal []
|
|
1040
1040
|
end
|
|
1041
1041
|
|
|
1042
1042
|
it "should allow cascading of eager loading with custom callback with hash value" do
|
|
1043
1043
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>{:band => :members}}).all
|
|
1044
|
-
a.
|
|
1045
|
-
DB.sqls.
|
|
1044
|
+
a.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
1045
|
+
DB.sqls.must_equal ['SELECT * FROM tracks',
|
|
1046
1046
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
1047
1047
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
1048
1048
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
|
1049
1049
|
a = a.first
|
|
1050
|
-
a.album.
|
|
1051
|
-
a.album.band.
|
|
1052
|
-
a.album.band.members.
|
|
1053
|
-
DB.sqls.
|
|
1050
|
+
a.album.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
1051
|
+
a.album.band.must_equal EagerBand.load(:id => 2)
|
|
1052
|
+
a.album.band.members.must_equal [EagerBandMember.load(:id => 5)]
|
|
1053
|
+
DB.sqls.must_equal []
|
|
1054
1054
|
end
|
|
1055
1055
|
|
|
1056
1056
|
it "should allow cascading of eager loading with custom callback with symbol value" do
|
|
1057
1057
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>:band}).all
|
|
1058
|
-
a.
|
|
1059
|
-
DB.sqls.
|
|
1058
|
+
a.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
1059
|
+
DB.sqls.must_equal ['SELECT * FROM tracks',
|
|
1060
1060
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
1061
1061
|
'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
1062
1062
|
a = a.first
|
|
1063
|
-
a.album.
|
|
1064
|
-
a.album.band.
|
|
1065
|
-
DB.sqls.
|
|
1063
|
+
a.album.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
1064
|
+
a.album.band.must_equal EagerBand.load(:id => 2)
|
|
1065
|
+
DB.sqls.must_equal []
|
|
1066
1066
|
end
|
|
1067
1067
|
|
|
1068
1068
|
it "should allow cascading of eager loading with custom callback with symbol value when association has a limit" do
|
|
1069
1069
|
EagerAlbum.dataset._fetch = (1..11).map{|i| {:band_id=>2, :id=>i}}
|
|
1070
1070
|
EagerTrack.dataset._fetch = [{:id=>3, :album_id=>1}]
|
|
1071
1071
|
a = EagerBand.eager(:top_10_albums=>{proc{|ds| ds.select(:id, :name)}=>:tracks}).all
|
|
1072
|
-
a.
|
|
1072
|
+
a.must_equal [EagerBand.load(:id => 2)]
|
|
1073
1073
|
sqls = DB.sqls
|
|
1074
|
-
sqls.pop.
|
|
1075
|
-
sqls.
|
|
1074
|
+
sqls.pop.must_match(/SELECT \* FROM tracks WHERE \(tracks.album_id IN \((\d+, ){10}\d+\)\)/)
|
|
1075
|
+
sqls.must_equal ['SELECT * FROM bands', 'SELECT id, name FROM albums WHERE (albums.band_id IN (2))']
|
|
1076
1076
|
a = a.first
|
|
1077
|
-
a.top_10_albums.
|
|
1078
|
-
a.top_10_albums.map{|x| x.tracks}.
|
|
1079
|
-
DB.sqls.
|
|
1077
|
+
a.top_10_albums.must_equal((1..10).map{|i| EagerAlbum.load(:band_id=>2, :id=>i)})
|
|
1078
|
+
a.top_10_albums.map{|x| x.tracks}.must_equal [[EagerTrack.load(:id => 3, :album_id=>1)]] + ([[]] * 9)
|
|
1079
|
+
DB.sqls.must_equal []
|
|
1080
1080
|
end
|
|
1081
1081
|
|
|
1082
1082
|
it "should allow cascading of eager loading with custom callback with symbol value when association has a limit when using window function eager limit strategy" do
|
|
@@ -1084,34 +1084,34 @@ describe Sequel::Model, "#eager" do
|
|
|
1084
1084
|
EagerAlbum.dataset._fetch = {:band_id=>2, :id=>1}
|
|
1085
1085
|
EagerTrack.dataset._fetch = [{:id=>3, :album_id=>1}]
|
|
1086
1086
|
a = EagerBand.eager(:top_10_albums=>{proc{|ds| ds.select(:id, :name)}=>:tracks}).all
|
|
1087
|
-
a.
|
|
1088
|
-
DB.sqls.
|
|
1087
|
+
a.must_equal [EagerBand.load(:id => 2)]
|
|
1088
|
+
DB.sqls.must_equal ['SELECT * FROM bands',
|
|
1089
1089
|
'SELECT * FROM (SELECT id, name, row_number() OVER (PARTITION BY albums.band_id) AS x_sequel_row_number_x FROM albums WHERE (albums.band_id IN (2))) AS t1 WHERE (x_sequel_row_number_x <= 10)',
|
|
1090
1090
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
1091
1091
|
a = a.first
|
|
1092
|
-
a.top_10_albums.
|
|
1093
|
-
a.top_10_albums.first.tracks.
|
|
1094
|
-
DB.sqls.
|
|
1092
|
+
a.top_10_albums.must_equal [EagerAlbum.load(:band_id=>2, :id=>1)]
|
|
1093
|
+
a.top_10_albums.first.tracks.must_equal [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
1094
|
+
DB.sqls.must_equal []
|
|
1095
1095
|
end
|
|
1096
1096
|
|
|
1097
1097
|
it "should allow cascading of eager loading with custom callback with array value" do
|
|
1098
1098
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>[:band, :band_name]}).all
|
|
1099
|
-
a.
|
|
1099
|
+
a.must_equal [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
1100
1100
|
sqls = DB.sqls
|
|
1101
|
-
sqls.slice!(0..1).
|
|
1101
|
+
sqls.slice!(0..1).must_equal ['SELECT * FROM tracks',
|
|
1102
1102
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))']
|
|
1103
|
-
sqls.sort.
|
|
1103
|
+
sqls.sort.must_equal ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
1104
1104
|
'SELECT id, name FROM bands WHERE (bands.id IN (2))']
|
|
1105
1105
|
a = a.first
|
|
1106
|
-
a.album.
|
|
1107
|
-
a.album.band.
|
|
1108
|
-
a.album.band_name.
|
|
1109
|
-
DB.sqls.
|
|
1106
|
+
a.album.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
|
|
1107
|
+
a.album.band.must_equal EagerBand.load(:id => 2)
|
|
1108
|
+
a.album.band_name.must_equal EagerBand.load(:id => 2)
|
|
1109
|
+
DB.sqls.must_equal []
|
|
1110
1110
|
end
|
|
1111
1111
|
|
|
1112
1112
|
it "should call both association and custom eager blocks" do
|
|
1113
1113
|
EagerBand.eager(:good_albums => proc {|ds| ds.select(:name)}).all
|
|
1114
|
-
DB.sqls.
|
|
1114
|
+
DB.sqls.must_equal ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))"]
|
|
1115
1115
|
end
|
|
1116
1116
|
end
|
|
1117
1117
|
|
|
@@ -1155,136 +1155,139 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1155
1155
|
many_to_many :bands, :class=>'GraphBand', :left_key=>:member_id, :right_key=>:band_id, :join_table=>:bm
|
|
1156
1156
|
end
|
|
1157
1157
|
end
|
|
1158
|
+
before do
|
|
1159
|
+
DB.sqls
|
|
1160
|
+
end
|
|
1158
1161
|
after(:all) do
|
|
1159
1162
|
[:GraphAlbum, :GraphBand, :GraphTrack, :GraphGenre, :GraphBandMember].each{|x| Object.send(:remove_const, x)}
|
|
1160
1163
|
end
|
|
1161
1164
|
|
|
1162
1165
|
it "should raise an error if called without a symbol or hash" do
|
|
1163
|
-
proc{GraphAlbum.eager_graph(Object.new)}.
|
|
1166
|
+
proc{GraphAlbum.eager_graph(Object.new)}.must_raise(Sequel::Error)
|
|
1164
1167
|
end
|
|
1165
1168
|
|
|
1166
1169
|
it "should work correctly with select_map" do
|
|
1167
1170
|
ds = GraphAlbum.eager_graph(:band)
|
|
1168
1171
|
ds._fetch = [{:id=>1}, {:id=>2}]
|
|
1169
|
-
ds.select_map(:albums__id).
|
|
1170
|
-
DB.sqls.
|
|
1172
|
+
ds.select_map(:albums__id).must_equal [1, 2]
|
|
1173
|
+
DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
|
|
1171
1174
|
ds._fetch = [{:id=>1}, {:id=>2}]
|
|
1172
|
-
ds.select_map([:albums__id, :albums__id]).
|
|
1173
|
-
DB.sqls.
|
|
1175
|
+
ds.select_map([:albums__id, :albums__id]).must_equal [[1, 1], [2, 2]]
|
|
1176
|
+
DB.sqls.must_equal ['SELECT albums.id, albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
|
|
1174
1177
|
end
|
|
1175
1178
|
|
|
1176
1179
|
it "should work correctly with single_value" do
|
|
1177
1180
|
ds = GraphAlbum.eager_graph(:band).select(:albums__id)
|
|
1178
1181
|
ds._fetch = [{:id=>1}]
|
|
1179
|
-
ds.single_value.
|
|
1180
|
-
DB.sqls.
|
|
1182
|
+
ds.single_value.must_equal 1
|
|
1183
|
+
DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) LIMIT 1']
|
|
1181
1184
|
end
|
|
1182
1185
|
|
|
1183
1186
|
it "should not split results and assign associations if ungraphed is called" do
|
|
1184
1187
|
ds = GraphAlbum.eager_graph(:band).ungraphed
|
|
1185
|
-
ds.sql.
|
|
1188
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1186
1189
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1187
|
-
ds.all.
|
|
1190
|
+
ds.all.must_equal [GraphAlbum.load(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)]
|
|
1188
1191
|
end
|
|
1189
1192
|
|
|
1190
1193
|
it "should not modify existing dataset" do
|
|
1191
1194
|
ds1 = GraphAlbum.dataset
|
|
1192
1195
|
ds2 = ds1.eager_graph(:band)
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
+
ds1.eager_graph(:band)
|
|
1197
|
+
ds2.eager_graph(:tracks)
|
|
1198
|
+
ds2.eager_graph(:tracks)
|
|
1196
1199
|
end
|
|
1197
1200
|
|
|
1198
1201
|
it "should allow manually selecting the alias base per call via an AliasedExpression" do
|
|
1199
1202
|
ds = GraphAlbum.eager_graph(Sequel.as(:band, :b))
|
|
1200
|
-
ds.sql.
|
|
1203
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, b.id AS b_id, b.vocalist_id FROM albums LEFT OUTER JOIN bands AS b ON (b.id = albums.band_id)'
|
|
1201
1204
|
ds._fetch = {:id=>1, :band_id=>2, :b_id=>2, :vocalist_id=>3}
|
|
1202
1205
|
a = ds.all
|
|
1203
|
-
a.
|
|
1204
|
-
a.first.band.
|
|
1206
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1207
|
+
a.first.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
|
|
1205
1208
|
end
|
|
1206
1209
|
|
|
1207
1210
|
it "should handle multiple associations using the same alias base" do
|
|
1208
1211
|
ds = GraphAlbum.eager_graph(Sequel.as(:genres, :b), Sequel.as(:tracks, :b), Sequel.as(:band, :b))
|
|
1209
|
-
ds.sql.
|
|
1212
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, b.id AS b_id, b_0.id AS b_0_id, b_0.album_id, b_1.id AS b_1_id, b_1.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS b ON (b.id = ag.genre_id) LEFT OUTER JOIN tracks AS b_0 ON (b_0.album_id = albums.id) LEFT OUTER JOIN bands AS b_1 ON (b_1.id = albums.band_id)'
|
|
1210
1213
|
ds._fetch = {:id=>1, :band_id=>2, :b_id=>4, :b_0_id=>3, :album_id=>1, :b_1_id=>2, :vocalist_id=>6}
|
|
1211
1214
|
a = ds.all
|
|
1212
|
-
a.
|
|
1215
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1213
1216
|
a = a.first
|
|
1214
|
-
a.band.
|
|
1215
|
-
a.tracks.
|
|
1216
|
-
a.genres.
|
|
1217
|
+
a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1218
|
+
a.tracks.must_equal [GraphTrack.load({:id => 3, :album_id=>1})]
|
|
1219
|
+
a.genres.must_equal [GraphGenre.load(:id => 4)]
|
|
1217
1220
|
|
|
1218
1221
|
ds = GraphTrack.eager_graph(Sequel.as(:album, :b)=>{Sequel.as(:band, :b)=>Sequel.as(:members, :b)})
|
|
1219
|
-
ds.sql.
|
|
1222
|
+
ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, b.id AS b_id, b.band_id, b_0.id AS b_0_id, b_0.vocalist_id, b_1.id AS b_1_id FROM tracks LEFT OUTER JOIN albums AS b ON (b.id = tracks.album_id) LEFT OUTER JOIN bands AS b_0 ON (b_0.id = b.band_id) LEFT OUTER JOIN bm ON (bm.band_id = b_0.id) LEFT OUTER JOIN members AS b_1 ON (b_1.id = bm.member_id)'
|
|
1220
1223
|
ds._fetch = {:id=>3, :album_id=>1, :b_id=>1, :band_id=>2, :b_1_id=>5, :b_0_id=>2, :vocalist_id=>6}
|
|
1221
1224
|
a = ds.all
|
|
1222
|
-
a.
|
|
1225
|
+
a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1223
1226
|
a = a.first
|
|
1224
|
-
a.album.
|
|
1225
|
-
a.album.band.
|
|
1226
|
-
a.album.band.members.
|
|
1227
|
+
a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1228
|
+
a.album.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1229
|
+
a.album.band.members.must_equal [GraphBandMember.load(:id => 5)]
|
|
1227
1230
|
end
|
|
1228
1231
|
|
|
1229
1232
|
it "should set up correct inner joins when using association_join" do
|
|
1230
|
-
GraphAlbum.association_join(:band).sql.
|
|
1231
|
-
GraphAlbum.association_join(:track).sql.
|
|
1232
|
-
GraphAlbum.association_join(:tracks).sql.
|
|
1233
|
-
GraphAlbum.association_join(:genres).sql.
|
|
1234
|
-
GraphAlbum.association_join(:genre).sql.
|
|
1233
|
+
GraphAlbum.association_join(:band).sql.must_equal 'SELECT * FROM albums INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1234
|
+
GraphAlbum.association_join(:track).sql.must_equal 'SELECT * FROM albums INNER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1235
|
+
GraphAlbum.association_join(:tracks).sql.must_equal 'SELECT * FROM albums INNER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1236
|
+
GraphAlbum.association_join(:genres).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1237
|
+
GraphAlbum.association_join(:genre).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres AS genre ON (genre.id = ag.genre_id)'
|
|
1235
1238
|
end
|
|
1236
1239
|
|
|
1237
1240
|
it "should handle custom selects when using association_join" do
|
|
1238
|
-
GraphAlbum.select{a(b)}.association_join(:band).sql.
|
|
1239
|
-
GraphAlbum.select{a(b)}.association_join(:track).sql.
|
|
1240
|
-
GraphAlbum.select{a(b)}.association_join(:tracks).sql.
|
|
1241
|
-
GraphAlbum.select{a(b)}.association_join(:genres).sql.
|
|
1242
|
-
GraphAlbum.select{a(b)}.association_join(:genre).sql.
|
|
1241
|
+
GraphAlbum.select{a(b)}.association_join(:band).sql.must_equal 'SELECT a(b) FROM albums INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1242
|
+
GraphAlbum.select{a(b)}.association_join(:track).sql.must_equal 'SELECT a(b) FROM albums INNER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1243
|
+
GraphAlbum.select{a(b)}.association_join(:tracks).sql.must_equal 'SELECT a(b) FROM albums INNER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1244
|
+
GraphAlbum.select{a(b)}.association_join(:genres).sql.must_equal 'SELECT a(b) FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1245
|
+
GraphAlbum.select{a(b)}.association_join(:genre).sql.must_equal 'SELECT a(b) FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres AS genre ON (genre.id = ag.genre_id)'
|
|
1243
1246
|
end
|
|
1244
1247
|
|
|
1245
1248
|
it "should set up correct join types when using association_*_join" do
|
|
1246
|
-
GraphAlbum.association_inner_join(:band).sql.
|
|
1247
|
-
GraphAlbum.association_left_join(:track).sql.
|
|
1248
|
-
GraphAlbum.association_right_join(:tracks).sql.
|
|
1249
|
-
GraphAlbum.association_full_join(:genres).sql.
|
|
1249
|
+
GraphAlbum.association_inner_join(:band).sql.must_equal 'SELECT * FROM albums INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1250
|
+
GraphAlbum.association_left_join(:track).sql.must_equal 'SELECT * FROM albums LEFT JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1251
|
+
GraphAlbum.association_right_join(:tracks).sql.must_equal 'SELECT * FROM albums RIGHT JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1252
|
+
GraphAlbum.association_full_join(:genres).sql.must_equal 'SELECT * FROM albums FULL JOIN ag ON (ag.album_id = albums.id) FULL JOIN genres ON (genres.id = ag.genre_id)'
|
|
1250
1253
|
end
|
|
1251
1254
|
|
|
1252
1255
|
it "should eagerly load a single many_to_one association" do
|
|
1253
1256
|
ds = GraphAlbum.eager_graph(:band)
|
|
1254
|
-
ds.sql.
|
|
1257
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1255
1258
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1256
1259
|
a = ds.all
|
|
1257
|
-
a.
|
|
1258
|
-
a.first.band.
|
|
1260
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1261
|
+
a.first.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
|
|
1259
1262
|
end
|
|
1260
1263
|
|
|
1261
1264
|
it "should eagerly load a single many_to_one association with the same name as a column" do
|
|
1262
1265
|
GraphAlbum.def_column_alias(:band_id_id, :band_id)
|
|
1263
1266
|
GraphAlbum.many_to_one :band_id, :key_column=>:band_id, :class=>GraphBand
|
|
1264
1267
|
ds = GraphAlbum.eager_graph(:band_id)
|
|
1265
|
-
ds.sql.
|
|
1268
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band_id.id AS band_id_id, band_id.vocalist_id FROM albums LEFT OUTER JOIN bands AS band_id ON (band_id.id = albums.band_id)'
|
|
1266
1269
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_id=>2, :vocalist_id=>3}
|
|
1267
1270
|
a = ds.all
|
|
1268
|
-
a.
|
|
1269
|
-
a.first.band_id.
|
|
1271
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1272
|
+
a.first.band_id.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
|
|
1270
1273
|
end
|
|
1271
1274
|
|
|
1272
1275
|
it "should support :join_type eager_graph option one_to_one association" do
|
|
1273
1276
|
ds = GraphAlbum.eager_graph_with_options(:track, :join_type=>:inner)
|
|
1274
|
-
ds.sql.
|
|
1277
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, track.id AS track_id, track.album_id FROM albums INNER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1275
1278
|
ds._fetch = {:id=>1, :band_id=>2, :track_id=>3, :album_id=>1}
|
|
1276
1279
|
a = ds.all
|
|
1277
|
-
a.
|
|
1278
|
-
a.first.track.
|
|
1280
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1281
|
+
a.first.track.must_equal GraphTrack.load(:id => 3, :album_id=>1)
|
|
1279
1282
|
end
|
|
1280
1283
|
|
|
1281
1284
|
it "should eagerly load a single one_to_one association" do
|
|
1282
1285
|
ds = GraphAlbum.eager_graph(:track)
|
|
1283
|
-
ds.sql.
|
|
1286
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, track.id AS track_id, track.album_id FROM albums LEFT OUTER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1284
1287
|
ds._fetch = {:id=>1, :band_id=>2, :track_id=>3, :album_id=>1}
|
|
1285
1288
|
a = ds.all
|
|
1286
|
-
a.
|
|
1287
|
-
a.first.track.
|
|
1289
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1290
|
+
a.first.track.must_equal GraphTrack.load(:id => 3, :album_id=>1)
|
|
1288
1291
|
end
|
|
1289
1292
|
|
|
1290
1293
|
it "should eagerly graph a single one_to_one association using the :distinct_on strategy" do
|
|
@@ -1293,11 +1296,11 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1293
1296
|
def (sub.dataset).columns() [:id, :album_id] end
|
|
1294
1297
|
GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
|
|
1295
1298
|
ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>true)
|
|
1296
|
-
ds.sql.
|
|
1299
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT DISTINCT ON (tracks.album_id) * FROM tracks ORDER BY tracks.album_id) AS ltrack ON (ltrack.album_id = albums.id)'
|
|
1297
1300
|
ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
|
|
1298
1301
|
a = ds.all
|
|
1299
|
-
a.
|
|
1300
|
-
a.first.ltrack.
|
|
1302
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1303
|
+
a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
|
|
1301
1304
|
end
|
|
1302
1305
|
|
|
1303
1306
|
it "should eagerly graph a single one_to_one association using the :window_function strategy" do
|
|
@@ -1306,11 +1309,11 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1306
1309
|
def (sub.dataset).columns() [:id, :album_id] end
|
|
1307
1310
|
GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
|
|
1308
1311
|
ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>true)
|
|
1309
|
-
ds.sql.
|
|
1312
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT id, album_id FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks) AS t1 WHERE (x_sequel_row_number_x = 1)) AS ltrack ON (ltrack.album_id = albums.id)'
|
|
1310
1313
|
ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
|
|
1311
1314
|
a = ds.all
|
|
1312
|
-
a.
|
|
1313
|
-
a.first.ltrack.
|
|
1315
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1316
|
+
a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
|
|
1314
1317
|
end
|
|
1315
1318
|
|
|
1316
1319
|
it "should eagerly graph a single one_to_one association using the :correlated_subquery strategy" do
|
|
@@ -1319,20 +1322,20 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1319
1322
|
def (sub.dataset).columns() [:id, :album_id] end
|
|
1320
1323
|
GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
|
|
1321
1324
|
ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>:correlated_subquery)
|
|
1322
|
-
ds.sql.
|
|
1325
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT * FROM tracks WHERE (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) LIMIT 1))) AS ltrack ON (ltrack.album_id = albums.id)'
|
|
1323
1326
|
ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
|
|
1324
1327
|
a = ds.all
|
|
1325
|
-
a.
|
|
1326
|
-
a.first.ltrack.
|
|
1328
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1329
|
+
a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
|
|
1327
1330
|
end
|
|
1328
1331
|
|
|
1329
1332
|
it "should eagerly load a single one_to_many association" do
|
|
1330
1333
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1331
|
-
ds.sql.
|
|
1334
|
+
ds.sql.must_equal '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)'
|
|
1332
1335
|
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1333
1336
|
a = ds.all
|
|
1334
|
-
a.
|
|
1335
|
-
a.first.tracks.
|
|
1337
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1338
|
+
a.first.tracks.must_equal [GraphTrack.load(:id => 3, :album_id=>1)]
|
|
1336
1339
|
end
|
|
1337
1340
|
|
|
1338
1341
|
it "should eagerly graph a single one_to_many association using the :window_function strategy" do
|
|
@@ -1341,20 +1344,20 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1341
1344
|
def (sub.dataset).columns() [:id, :album_id] end
|
|
1342
1345
|
GraphAlbum.one_to_many :ltracks, :clone=>:tracks, :limit=>2, :class=>sub
|
|
1343
1346
|
ds = GraphAlbum.eager_graph_with_options(:ltracks, :limit_strategy=>true)
|
|
1344
|
-
ds.sql.
|
|
1347
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltracks.id AS ltracks_id, ltracks.album_id FROM albums LEFT OUTER JOIN (SELECT id, album_id FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS ltracks ON (ltracks.album_id = albums.id)'
|
|
1345
1348
|
ds._fetch = {:id=>1, :band_id=>2, :ltracks_id=>3, :album_id=>1}
|
|
1346
1349
|
a = ds.all
|
|
1347
|
-
a.
|
|
1348
|
-
a.first.ltracks.
|
|
1350
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1351
|
+
a.first.ltracks.must_equal [sub.load(:id => 3, :album_id=>1)]
|
|
1349
1352
|
end
|
|
1350
1353
|
|
|
1351
1354
|
it "should eagerly load a single many_to_many association" do
|
|
1352
1355
|
ds = GraphAlbum.eager_graph(:genres)
|
|
1353
|
-
ds.sql.
|
|
1356
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1354
1357
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
|
|
1355
1358
|
a = ds.all
|
|
1356
|
-
a.
|
|
1357
|
-
a.first.genres.
|
|
1359
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1360
|
+
a.first.genres.must_equal [GraphGenre.load(:id => 4)]
|
|
1358
1361
|
end
|
|
1359
1362
|
|
|
1360
1363
|
it "should eagerly graph a single many_to_many association using the :window_function strategy" do
|
|
@@ -1363,20 +1366,20 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1363
1366
|
def (sub.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
|
1364
1367
|
GraphAlbum.many_to_many :lgenres, :clone=>:genres, :class=>sub, :limit=>2
|
|
1365
1368
|
ds = GraphAlbum.eager_graph_with_options(:lgenres, :limit_strategy=>true)
|
|
1366
|
-
ds.sql.
|
|
1369
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenres.id AS lgenres_id FROM albums LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS lgenres ON (lgenres.x_foreign_key_x = albums.id)'
|
|
1367
1370
|
ds._fetch = {:id=>1, :band_id=>2, :lgenres_id=>4}
|
|
1368
1371
|
a = ds.all
|
|
1369
|
-
a.
|
|
1370
|
-
a.first.lgenres.
|
|
1372
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1373
|
+
a.first.lgenres.must_equal [sub.load(:id => 4)]
|
|
1371
1374
|
end
|
|
1372
1375
|
|
|
1373
1376
|
it "should eagerly load a single one_through_one association" do
|
|
1374
1377
|
ds = GraphAlbum.eager_graph(:genre)
|
|
1375
|
-
ds.sql.
|
|
1378
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ag.genre_id)'
|
|
1376
1379
|
ds._fetch = {:id=>1, :band_id=>2, :genre_id=>4}
|
|
1377
1380
|
a = ds.all
|
|
1378
|
-
a.
|
|
1379
|
-
a.first.genre.
|
|
1381
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1382
|
+
a.first.genre.must_equal GraphGenre.load(:id => 4)
|
|
1380
1383
|
end
|
|
1381
1384
|
|
|
1382
1385
|
it "should eagerly graph a single one_through_one association using the :distinct_on strategy" do
|
|
@@ -1385,11 +1388,11 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1385
1388
|
def (sub.dataset).columns() [:id] end
|
|
1386
1389
|
GraphAlbum.one_through_one :lgenre, :clone=>:genre, :class=>sub
|
|
1387
1390
|
ds = GraphAlbum.eager_graph_with_options(:lgenre, :limit_strategy=>true)
|
|
1388
|
-
ds.sql.
|
|
1391
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id FROM albums LEFT OUTER JOIN (SELECT DISTINCT ON (ag.album_id) genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) ORDER BY ag.album_id) AS lgenre ON (lgenre.x_foreign_key_x = albums.id)'
|
|
1389
1392
|
ds._fetch = {:id=>1, :band_id=>2, :lgenre_id=>4}
|
|
1390
1393
|
a = ds.all
|
|
1391
|
-
a.
|
|
1392
|
-
a.first.lgenre.
|
|
1394
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1395
|
+
a.first.lgenre.must_equal sub.load(:id => 4)
|
|
1393
1396
|
end
|
|
1394
1397
|
|
|
1395
1398
|
it "should eagerly graph a single one_through_one association using the :window_function strategy" do
|
|
@@ -1398,42 +1401,42 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1398
1401
|
def (sub.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
|
1399
1402
|
GraphAlbum.one_through_one :lgenre, :clone=>:genre, :class=>sub
|
|
1400
1403
|
ds = GraphAlbum.eager_graph_with_options(:lgenre, :limit_strategy=>true)
|
|
1401
|
-
ds.sql.
|
|
1404
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id FROM albums LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id)) AS t1 WHERE (x_sequel_row_number_x = 1)) AS lgenre ON (lgenre.x_foreign_key_x = albums.id)'
|
|
1402
1405
|
ds._fetch = {:id=>1, :band_id=>2, :lgenre_id=>4}
|
|
1403
1406
|
a = ds.all
|
|
1404
|
-
a.
|
|
1405
|
-
a.first.lgenre.
|
|
1407
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1408
|
+
a.first.lgenre.must_equal sub.load(:id => 4)
|
|
1406
1409
|
end
|
|
1407
1410
|
|
|
1408
1411
|
it "should correctly handle an aliased join table in many_to_many and one_through_one" do
|
|
1409
1412
|
c = Class.new(GraphAlbum)
|
|
1410
1413
|
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga
|
|
1411
|
-
c.eager_graph(:genres).sql.
|
|
1414
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
|
1412
1415
|
|
|
1413
1416
|
c.many_to_many :genre, :clone=>:genre, :join_table=>:ag___ga
|
|
1414
|
-
c.eager_graph(:genre).sql.
|
|
1417
|
+
c.eager_graph(:genre).sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ga.genre_id)'
|
|
1415
1418
|
|
|
1416
1419
|
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___albums
|
|
1417
|
-
c.eager_graph(:genres).sql.
|
|
1420
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS albums_0 ON (albums_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = albums_0.genre_id)'
|
|
1418
1421
|
|
|
1419
1422
|
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___genres
|
|
1420
|
-
c.eager_graph(:genres).sql.
|
|
1423
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS genres_0 ON (genres_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = genres_0.genre_id)'
|
|
1421
1424
|
end
|
|
1422
1425
|
|
|
1423
1426
|
it "should handle multiple associations in a single call to association_join" do
|
|
1424
|
-
GraphAlbum.association_join(:genres, :tracks, :band).sql.
|
|
1427
|
+
GraphAlbum.association_join(:genres, :tracks, :band).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id) INNER JOIN tracks ON (tracks.album_id = albums.id) INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1425
1428
|
end
|
|
1426
1429
|
|
|
1427
1430
|
it "should eagerly load multiple associations in a single call" do
|
|
1428
1431
|
ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
|
|
1429
|
-
ds.sql.
|
|
1432
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1430
1433
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
|
|
1431
1434
|
a = ds.all
|
|
1432
|
-
a.
|
|
1435
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1433
1436
|
a = a.first
|
|
1434
|
-
a.band.
|
|
1435
|
-
a.tracks.
|
|
1436
|
-
a.genres.
|
|
1437
|
+
a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1438
|
+
a.tracks.must_equal [GraphTrack.load({:id => 3, :album_id=>1})]
|
|
1439
|
+
a.genres.must_equal [GraphGenre.load(:id => 4)]
|
|
1437
1440
|
end
|
|
1438
1441
|
|
|
1439
1442
|
it "should eagerly load multiple associations with different limit strategies in a single call" do
|
|
@@ -1445,55 +1448,55 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1445
1448
|
GraphAlbum.many_to_many :lgenres, :clone=>:genres, :class=>subg, :limit=>2
|
|
1446
1449
|
|
|
1447
1450
|
ds = GraphAlbum.eager_graph_with_options([:lgenre, :lgenres], :limit_strategy=>{:lgenre=>:distinct_on, :lgenres=>:window_function})
|
|
1448
|
-
ds.sql.
|
|
1451
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id, lgenres.id AS lgenres_id FROM albums LEFT OUTER JOIN (SELECT DISTINCT ON (ag.album_id) genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) ORDER BY ag.album_id) AS lgenre ON (lgenre.x_foreign_key_x = albums.id) LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS lgenres ON (lgenres.x_foreign_key_x = albums.id)'
|
|
1449
1452
|
ds._fetch = {:id=>1, :band_id=>2, :lgenres_id=>4, :lgenre_id=>3}
|
|
1450
1453
|
a = ds.all
|
|
1451
|
-
a.
|
|
1454
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1452
1455
|
a = a.first
|
|
1453
|
-
a.lgenre.
|
|
1454
|
-
a.lgenres.
|
|
1456
|
+
a.lgenre.must_equal subg.load(:id => 3)
|
|
1457
|
+
a.lgenres.must_equal [subg.load(:id => 4)]
|
|
1455
1458
|
end
|
|
1456
1459
|
|
|
1457
1460
|
it "should handle multiple associations in separate calls to association_join" do
|
|
1458
|
-
GraphAlbum.association_join(:genres).association_join(:tracks).association_join(:band).sql.
|
|
1461
|
+
GraphAlbum.association_join(:genres).association_join(:tracks).association_join(:band).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id) INNER JOIN tracks ON (tracks.album_id = albums.id) INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1459
1462
|
end
|
|
1460
1463
|
|
|
1461
1464
|
it "should eagerly load multiple associations in separate calls" do
|
|
1462
1465
|
ds = GraphAlbum.eager_graph(:genres).eager_graph(:tracks).eager_graph(:band)
|
|
1463
|
-
ds.sql.
|
|
1466
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1464
1467
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
|
|
1465
1468
|
a = ds.all
|
|
1466
|
-
a.
|
|
1469
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1467
1470
|
a = a.first
|
|
1468
|
-
a.band.
|
|
1469
|
-
a.tracks.
|
|
1470
|
-
a.genres.
|
|
1471
|
+
a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1472
|
+
a.tracks.must_equal [GraphTrack.load({:id => 3, :album_id=>1})]
|
|
1473
|
+
a.genres.must_equal [GraphGenre.load(:id => 4)]
|
|
1471
1474
|
end
|
|
1472
1475
|
|
|
1473
1476
|
it "should handle cascading associations in a single call to association_join" do
|
|
1474
|
-
GraphTrack.association_join(:album=>{:band=>:members}).sql.
|
|
1475
|
-
GraphBand.association_join({:albums=>:tracks}, :members).sql.
|
|
1477
|
+
GraphTrack.association_join(:album=>{:band=>:members}).sql.must_equal 'SELECT * FROM tracks INNER JOIN albums AS album ON (album.id = tracks.album_id) INNER JOIN bands AS band ON (band.id = album.band_id) INNER JOIN bm ON (bm.band_id = band.id) INNER JOIN members ON (members.id = bm.member_id)'
|
|
1478
|
+
GraphBand.association_join({:albums=>:tracks}, :members).sql.must_equal 'SELECT * FROM bands INNER JOIN albums ON (albums.band_id = bands.id) INNER JOIN tracks ON (tracks.album_id = albums.id) INNER JOIN bm ON (bm.band_id = bands.id) INNER JOIN members ON (members.id = bm.member_id)'
|
|
1476
1479
|
end
|
|
1477
1480
|
|
|
1478
1481
|
it "should handle matching association names for different models when using association_join" do
|
|
1479
|
-
GraphAlbum.association_join(:genres).association_join(:band=>:genres).sql.
|
|
1482
|
+
GraphAlbum.association_join(:genres).association_join(:band=>:genres).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id) INNER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN bg ON (bg.band_id = band.id) INNER JOIN genres AS genres_0 ON (genres_0.id = bg.genre_id)'
|
|
1480
1483
|
end
|
|
1481
1484
|
|
|
1482
1485
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
1483
1486
|
ds = GraphTrack.eager_graph(:album=>{:band=>:members})
|
|
1484
|
-
ds.sql.
|
|
1487
|
+
ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN albums AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1485
1488
|
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
|
|
1486
1489
|
a = ds.all
|
|
1487
|
-
a.
|
|
1490
|
+
a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1488
1491
|
a = a.first
|
|
1489
|
-
a.album.
|
|
1490
|
-
a.album.band.
|
|
1491
|
-
a.album.band.members.
|
|
1492
|
+
a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1493
|
+
a.album.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1494
|
+
a.album.band.members.must_equal [GraphBandMember.load(:id => 5)]
|
|
1492
1495
|
end
|
|
1493
1496
|
|
|
1494
1497
|
it "should allow cascading of eager loading for multiple *_to_many associations, eliminating duplicates caused by cartesian products" do
|
|
1495
1498
|
ds = GraphBand.eager_graph({:albums=>:tracks}, :members)
|
|
1496
|
-
ds.sql.
|
|
1499
|
+
ds.sql.must_equal 'SELECT bands.id, bands.vocalist_id, albums.id AS albums_id, albums.band_id, tracks.id AS tracks_id, tracks.album_id, members.id AS members_id FROM bands LEFT OUTER JOIN albums ON (albums.band_id = bands.id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1497
1500
|
ds._fetch = [{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>5},
|
|
1498
1501
|
{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>6},
|
|
1499
1502
|
{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>5, :album_id=>3, :members_id=>5},
|
|
@@ -1511,80 +1514,80 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1511
1514
|
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>5},
|
|
1512
1515
|
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>6}]
|
|
1513
1516
|
a = ds.all
|
|
1514
|
-
a.
|
|
1517
|
+
a.must_equal [GraphBand.load(:id=>1, :vocalist_id=>2), GraphBand.load(:id=>2, :vocalist_id=>2)]
|
|
1515
1518
|
members = a.map{|x| x.members}
|
|
1516
|
-
members.
|
|
1519
|
+
members.must_equal [[GraphBandMember.load(:id=>5), GraphBandMember.load(:id=>6)], [GraphBandMember.load(:id=>5), GraphBandMember.load(:id=>6)]]
|
|
1517
1520
|
albums = a.map{|x| x.albums}
|
|
1518
|
-
albums.
|
|
1521
|
+
albums.must_equal [[GraphAlbum.load(:id=>3, :band_id=>1), GraphAlbum.load(:id=>4, :band_id=>1)], [GraphAlbum.load(:id=>5, :band_id=>2), GraphAlbum.load(:id=>6, :band_id=>2)]]
|
|
1519
1522
|
tracks = albums.map{|x| x.map{|y| y.tracks}}
|
|
1520
|
-
tracks.
|
|
1523
|
+
tracks.must_equal [[[GraphTrack.load(:id=>4, :album_id=>3), GraphTrack.load(:id=>5, :album_id=>3)], [GraphTrack.load(:id=>6, :album_id=>4), GraphTrack.load(:id=>7, :album_id=>4)]], [[GraphTrack.load(:id=>8, :album_id=>5), GraphTrack.load(:id=>9, :album_id=>5)], [GraphTrack.load(:id=>1, :album_id=>6), GraphTrack.load(:id=>2, :album_id=>6)]]]
|
|
1521
1524
|
end
|
|
1522
1525
|
|
|
1523
1526
|
it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
|
|
1524
1527
|
DB.reset
|
|
1525
1528
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1526
|
-
ds.sql.
|
|
1529
|
+
ds.sql.must_equal '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)'
|
|
1527
1530
|
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1528
1531
|
a = ds.all
|
|
1529
|
-
a.
|
|
1532
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1530
1533
|
a = a.first
|
|
1531
|
-
a.tracks.
|
|
1532
|
-
a.tracks.first.album.
|
|
1533
|
-
DB.sqls.
|
|
1534
|
+
a.tracks.must_equal [GraphTrack.load(:id => 3, :album_id=>1)]
|
|
1535
|
+
a.tracks.first.album.must_equal a
|
|
1536
|
+
DB.sqls.must_equal ['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)']
|
|
1534
1537
|
end
|
|
1535
1538
|
|
|
1536
1539
|
it "should eager load multiple associations from the same table" do
|
|
1537
1540
|
ds = GraphBand.eager_graph(:vocalist, :members)
|
|
1538
|
-
ds.sql.
|
|
1541
|
+
ds.sql.must_equal 'SELECT bands.id, bands.vocalist_id, vocalist.id AS vocalist_id_0, members.id AS members_id FROM bands LEFT OUTER JOIN members AS vocalist ON (vocalist.id = bands.vocalist_id) LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1539
1542
|
ds._fetch = {:id=>2, :vocalist_id=>6, :vocalist_id_0=>6, :members_id=>5}
|
|
1540
1543
|
a = ds.all
|
|
1541
|
-
a.
|
|
1544
|
+
a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1542
1545
|
a = a.first
|
|
1543
|
-
a.vocalist.
|
|
1544
|
-
a.members.
|
|
1546
|
+
a.vocalist.must_equal GraphBandMember.load(:id => 6)
|
|
1547
|
+
a.members.must_equal [GraphBandMember.load(:id => 5)]
|
|
1545
1548
|
end
|
|
1546
1549
|
|
|
1547
1550
|
it "should give you a plain hash when called without .all" do
|
|
1548
1551
|
ds = GraphAlbum.eager_graph(:band)
|
|
1549
|
-
ds.sql.
|
|
1552
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1550
1553
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1551
|
-
ds.first.
|
|
1554
|
+
ds.first.must_equal(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)
|
|
1552
1555
|
end
|
|
1553
1556
|
|
|
1554
1557
|
it "should not drop any associated objects if the graph could not be a cartesian product" do
|
|
1555
1558
|
ds = GraphBand.eager_graph(:members, :vocalist)
|
|
1556
|
-
ds.sql.
|
|
1559
|
+
ds.sql.must_equal 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, vocalist.id AS vocalist_id_0 FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN members AS vocalist ON (vocalist.id = bands.vocalist_id)'
|
|
1557
1560
|
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6}, {:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6}]
|
|
1558
1561
|
a = ds.all
|
|
1559
|
-
a.
|
|
1562
|
+
a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1560
1563
|
a = a.first
|
|
1561
|
-
a.vocalist.
|
|
1562
|
-
a.members.
|
|
1564
|
+
a.vocalist.must_equal GraphBandMember.load(:id => 6)
|
|
1565
|
+
a.members.must_equal [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 5)]
|
|
1563
1566
|
end
|
|
1564
1567
|
|
|
1565
1568
|
it "should respect the :cartesian_product_number option" do
|
|
1566
1569
|
GraphBand.many_to_one :other_vocalist, :class=>'GraphBandMember', :key=>:vocalist_id, :cartesian_product_number=>1
|
|
1567
1570
|
ds = GraphBand.eager_graph(:members, :other_vocalist)
|
|
1568
|
-
ds.sql.
|
|
1571
|
+
ds.sql.must_equal 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, other_vocalist.id AS other_vocalist_id FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN members AS other_vocalist ON (other_vocalist.id = bands.vocalist_id)'
|
|
1569
1572
|
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6}, {:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6}]
|
|
1570
1573
|
a = ds.all
|
|
1571
|
-
a.
|
|
1572
|
-
a.first.other_vocalist.
|
|
1573
|
-
a.first.members.
|
|
1574
|
+
a.must_equal [GraphBand.load(:id=>2, :vocalist_id => 6)]
|
|
1575
|
+
a.first.other_vocalist.must_equal GraphBandMember.load(:id=>6)
|
|
1576
|
+
a.first.members.must_equal [GraphBandMember.load(:id=>5)]
|
|
1574
1577
|
end
|
|
1575
1578
|
|
|
1576
1579
|
it "should drop duplicate items that occur in sequence if the graph could be a cartesian product" do
|
|
1577
1580
|
ds = GraphBand.eager_graph(:members, :genres)
|
|
1578
|
-
ds.sql.
|
|
1581
|
+
ds.sql.must_equal 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, genres.id AS genres_id FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN bg ON (bg.band_id = bands.id) LEFT OUTER JOIN genres ON (genres.id = bg.genre_id)'
|
|
1579
1582
|
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>7},
|
|
1580
1583
|
{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>8},
|
|
1581
1584
|
{:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>7},
|
|
1582
1585
|
{:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>8}]
|
|
1583
1586
|
a = ds.all
|
|
1584
|
-
a.
|
|
1587
|
+
a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1585
1588
|
a = a.first
|
|
1586
|
-
a.members.
|
|
1587
|
-
a.genres.
|
|
1589
|
+
a.members.must_equal [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 6)]
|
|
1590
|
+
a.genres.must_equal [GraphGenre.load(:id => 7), GraphGenre.load(:id => 8)]
|
|
1588
1591
|
end
|
|
1589
1592
|
|
|
1590
1593
|
it "should be able to be used in combination with #eager" do
|
|
@@ -1594,145 +1597,145 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1594
1597
|
ds2 = GraphGenre.dataset
|
|
1595
1598
|
ds2._fetch = {:id=>6, :x_foreign_key_x=>1}
|
|
1596
1599
|
a = ds.all
|
|
1597
|
-
a.
|
|
1600
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1598
1601
|
a = a.first
|
|
1599
|
-
a.tracks.
|
|
1600
|
-
a.genres.
|
|
1601
|
-
DB.sqls.
|
|
1602
|
+
a.tracks.must_equal [GraphTrack.load(:id=>3, :album_id=>1)]
|
|
1603
|
+
a.genres.must_equal [GraphGenre.load(:id => 6)]
|
|
1604
|
+
DB.sqls.must_equal ['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)',
|
|
1602
1605
|
"SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
|
1603
1606
|
end
|
|
1604
1607
|
|
|
1605
1608
|
it "should handle no associated records for a single many_to_one association" do
|
|
1606
1609
|
ds = GraphAlbum.eager_graph(:band)
|
|
1607
|
-
ds.sql.
|
|
1610
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1608
1611
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>nil, :vocalist_id=>nil}
|
|
1609
1612
|
a = ds.all
|
|
1610
|
-
a.
|
|
1611
|
-
a.first.band.
|
|
1613
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1614
|
+
a.first.band.must_equal nil
|
|
1612
1615
|
end
|
|
1613
1616
|
|
|
1614
1617
|
it "should handle no associated records for a single one_to_one association" do
|
|
1615
1618
|
ds = GraphAlbum.eager_graph(:track)
|
|
1616
|
-
ds.sql.
|
|
1619
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, track.id AS track_id, track.album_id FROM albums LEFT OUTER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1617
1620
|
ds._fetch = {:id=>1, :band_id=>2, :track_id=>nil, :album_id=>nil}
|
|
1618
1621
|
a = ds.all
|
|
1619
|
-
a.
|
|
1620
|
-
a.first.track.
|
|
1622
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1623
|
+
a.first.track.must_equal nil
|
|
1621
1624
|
end
|
|
1622
1625
|
|
|
1623
1626
|
it "should handle no associated records for a single one_to_many association" do
|
|
1624
1627
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1625
|
-
ds.sql.
|
|
1628
|
+
ds.sql.must_equal '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)'
|
|
1626
1629
|
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>nil, :album_id=>nil}
|
|
1627
1630
|
a = ds.all
|
|
1628
|
-
a.
|
|
1629
|
-
a.first.tracks.
|
|
1631
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1632
|
+
a.first.tracks.must_equal []
|
|
1630
1633
|
end
|
|
1631
1634
|
|
|
1632
1635
|
it "should handle no associated records for a single one_through_one association" do
|
|
1633
1636
|
ds = GraphAlbum.eager_graph(:genre)
|
|
1634
|
-
ds.sql.
|
|
1637
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ag.genre_id)'
|
|
1635
1638
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>nil}
|
|
1636
1639
|
a = ds.all
|
|
1637
|
-
a.
|
|
1638
|
-
a.first.genre.
|
|
1640
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1641
|
+
a.first.genre.must_equal nil
|
|
1639
1642
|
end
|
|
1640
1643
|
|
|
1641
1644
|
it "should handle no associated records for a single many_to_many association" do
|
|
1642
1645
|
ds = GraphAlbum.eager_graph(:genres)
|
|
1643
|
-
ds.sql.
|
|
1646
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1644
1647
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>nil}
|
|
1645
1648
|
a = ds.all
|
|
1646
|
-
a.
|
|
1647
|
-
a.first.genres.
|
|
1649
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1650
|
+
a.first.genres.must_equal []
|
|
1648
1651
|
end
|
|
1649
1652
|
|
|
1650
1653
|
it "should handle missing associated records when loading multiple associations" do
|
|
1651
1654
|
ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
|
|
1652
|
-
ds.sql.
|
|
1655
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1653
1656
|
ds._fetch = [{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>3, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
1654
1657
|
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>4, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
1655
1658
|
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>5, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
1656
1659
|
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>6, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil}]
|
|
1657
1660
|
a = ds.all
|
|
1658
|
-
a.
|
|
1661
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1659
1662
|
a = a.first
|
|
1660
|
-
a.tracks.
|
|
1661
|
-
a.band.
|
|
1662
|
-
a.genres.
|
|
1663
|
+
a.tracks.must_equal [GraphTrack.load(:id => 3, :album_id => 1), GraphTrack.load(:id => 4, :album_id => 1), GraphTrack.load(:id => 5, :album_id => 1), GraphTrack.load(:id => 6, :album_id => 1)]
|
|
1664
|
+
a.band.must_equal nil
|
|
1665
|
+
a.genres.must_equal []
|
|
1663
1666
|
end
|
|
1664
1667
|
|
|
1665
1668
|
it "should handle missing associated records when cascading eager loading for associations of associated models" do
|
|
1666
1669
|
ds = GraphTrack.eager_graph(:album=>{:band=>:members})
|
|
1667
|
-
ds.sql.
|
|
1670
|
+
ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN albums AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1668
1671
|
ds._fetch = [{:id=>2, :album_id=>2, :album_id_0=>nil, :band_id=>nil, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
|
|
1669
1672
|
{:id=>3, :album_id=>3, :album_id_0=>3, :band_id=>3, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
|
|
1670
1673
|
{:id=>4, :album_id=>4, :album_id_0=>4, :band_id=>2, :members_id=>nil, :band_id_0=>2, :vocalist_id=>6},
|
|
1671
1674
|
{:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>5, :band_id_0=>4, :vocalist_id=>8},
|
|
1672
1675
|
{:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>6, :band_id_0=>4, :vocalist_id=>8}]
|
|
1673
1676
|
a = ds.all
|
|
1674
|
-
a.
|
|
1675
|
-
a.map{|x| x.album}.
|
|
1676
|
-
a.map{|x| x.album.band if x.album}.
|
|
1677
|
-
a.map{|x| x.album.band.members if x.album && x.album.band}.
|
|
1677
|
+
a.must_equal [GraphTrack.load(:id => 2, :album_id => 2), GraphTrack.load(:id => 3, :album_id => 3), GraphTrack.load(:id => 4, :album_id => 4), GraphTrack.load(:id => 5, :album_id => 1)]
|
|
1678
|
+
a.map{|x| x.album}.must_equal [nil, GraphAlbum.load(:id => 3, :band_id => 3), GraphAlbum.load(:id => 4, :band_id => 2), GraphAlbum.load(:id => 1, :band_id => 4)]
|
|
1679
|
+
a.map{|x| x.album.band if x.album}.must_equal [nil, nil, GraphBand.load(:id => 2, :vocalist_id=>6), GraphBand.load(:id => 4, :vocalist_id=>8)]
|
|
1680
|
+
a.map{|x| x.album.band.members if x.album && x.album.band}.must_equal [nil, nil, [], [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 6)]]
|
|
1678
1681
|
end
|
|
1679
1682
|
|
|
1680
1683
|
it "should respect the association's :primary_key option" do
|
|
1681
1684
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :primary_key=>:vocalist_id
|
|
1682
1685
|
ds = GraphAlbum.eager_graph(:inner_band)
|
|
1683
|
-
ds.sql.
|
|
1686
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, inner_band.id AS inner_band_id, inner_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS inner_band ON (inner_band.vocalist_id = albums.band_id)'
|
|
1684
1687
|
ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>5, :vocalist_id=>2}
|
|
1685
1688
|
as = ds.all
|
|
1686
|
-
as.
|
|
1687
|
-
as.first.inner_band.
|
|
1689
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1690
|
+
as.first.inner_band.must_equal GraphBand.load(:id=>5, :vocalist_id=>2)
|
|
1688
1691
|
|
|
1689
1692
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id, :reciprocal=>nil
|
|
1690
1693
|
ds = GraphAlbum.eager_graph(:right_tracks)
|
|
1691
|
-
ds.sql.
|
|
1694
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.band_id)'
|
|
1692
1695
|
ds._fetch = [{:id=>3, :band_id=>2, :right_tracks_id=>5, :album_id=>2}, {:id=>3, :band_id=>2, :right_tracks_id=>6, :album_id=>2}]
|
|
1693
1696
|
as = ds.all
|
|
1694
|
-
as.
|
|
1695
|
-
as.first.right_tracks.
|
|
1697
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1698
|
+
as.first.right_tracks.must_equal [GraphTrack.load(:id=>5, :album_id=>2), GraphTrack.load(:id=>6, :album_id=>2)]
|
|
1696
1699
|
end
|
|
1697
1700
|
|
|
1698
1701
|
it "should respect many_to_one association's composite keys" do
|
|
1699
1702
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>[:band_id, :id], :primary_key=>[:vocalist_id, :id]
|
|
1700
1703
|
ds = GraphAlbum.eager_graph(:inner_band)
|
|
1701
|
-
ds.sql.
|
|
1704
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, inner_band.id AS inner_band_id, inner_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS inner_band ON ((inner_band.vocalist_id = albums.band_id) AND (inner_band.id = albums.id))'
|
|
1702
1705
|
ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>3, :vocalist_id=>2}
|
|
1703
1706
|
as = ds.all
|
|
1704
|
-
as.
|
|
1705
|
-
as.first.inner_band.
|
|
1707
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1708
|
+
as.first.inner_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>2)
|
|
1706
1709
|
end
|
|
1707
1710
|
|
|
1708
1711
|
it "should respect one_to_many association's composite keys" do
|
|
1709
1712
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>[:album_id, :id], :primary_key=>[:band_id, :id]
|
|
1710
1713
|
ds = GraphAlbum.eager_graph(:right_tracks)
|
|
1711
|
-
ds.sql.
|
|
1714
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.band_id) AND (right_tracks.id = albums.id))'
|
|
1712
1715
|
ds._fetch = {:id=>3, :band_id=>2, :right_tracks_id=>3, :album_id=>2}
|
|
1713
1716
|
as = ds.all
|
|
1714
|
-
as.
|
|
1715
|
-
as.first.right_tracks.
|
|
1717
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1718
|
+
as.first.right_tracks.must_equal [GraphTrack.load(:id=>3, :album_id=>2)]
|
|
1716
1719
|
end
|
|
1717
1720
|
|
|
1718
1721
|
it "should respect many_to_many association's composite keys" do
|
|
1719
1722
|
GraphAlbum.many_to_many :sbands, :class=>'GraphBand', :left_key=>[:l1, :l2], :left_primary_key=>[:band_id, :id], :right_key=>[:r1, :r2], :right_primary_key=>[:vocalist_id, :id], :join_table=>:b
|
|
1720
1723
|
ds = GraphAlbum.eager_graph(:sbands)
|
|
1721
|
-
ds.sql.
|
|
1724
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, sbands.id AS sbands_id, sbands.vocalist_id FROM albums LEFT OUTER JOIN b ON ((b.l1 = albums.band_id) AND (b.l2 = albums.id)) LEFT OUTER JOIN bands AS sbands ON ((sbands.vocalist_id = b.r1) AND (sbands.id = b.r2))'
|
|
1722
1725
|
ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6}, {:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22}]
|
|
1723
1726
|
as = ds.all
|
|
1724
|
-
as.
|
|
1725
|
-
as.first.sbands.
|
|
1727
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1728
|
+
as.first.sbands.must_equal [GraphBand.load(:id=>5, :vocalist_id=>6), GraphBand.load(:id=>6, :vocalist_id=>22)]
|
|
1726
1729
|
end
|
|
1727
1730
|
|
|
1728
1731
|
it "should respect many_to_many association's :left_primary_key and :right_primary_key options" do
|
|
1729
1732
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :left_primary_key=>:band_id, :right_key=>:genre_id, :right_primary_key=>:xxx, :join_table=>:ag
|
|
1730
1733
|
ds = GraphAlbum.eager_graph(:inner_genres)
|
|
1731
|
-
ds.sql.
|
|
1734
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.band_id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.xxx = ag.genre_id)'
|
|
1732
1735
|
ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
|
|
1733
1736
|
as = ds.all
|
|
1734
|
-
as.
|
|
1735
|
-
as.first.inner_genres.
|
|
1737
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1738
|
+
as.first.inner_genres.must_equal [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
|
|
1736
1739
|
end
|
|
1737
1740
|
|
|
1738
1741
|
it "should respect composite primary keys for classes when eager loading" do
|
|
@@ -1743,181 +1746,181 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1743
1746
|
c1.many_to_many :sbands, :class=>c2, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :join_table=>:b
|
|
1744
1747
|
c2.one_to_many :salbums, :class=>c1, :key=>[:band_id, :id]
|
|
1745
1748
|
ds = c1.eager_graph(:sbands=>:salbums)
|
|
1746
|
-
ds.sql.
|
|
1749
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, sbands.id AS sbands_id, sbands.vocalist_id, salbums.id AS salbums_id, salbums.band_id AS salbums_band_id FROM albums LEFT OUTER JOIN b ON ((b.l1 = albums.band_id) AND (b.l2 = albums.id)) LEFT OUTER JOIN bands AS sbands ON ((sbands.vocalist_id = b.r1) AND (sbands.id = b.r2)) LEFT OUTER JOIN albums AS salbums ON ((salbums.band_id = sbands.vocalist_id) AND (salbums.id = sbands.id))'
|
|
1747
1750
|
ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>7, :salbums_band_id=>8},
|
|
1748
1751
|
{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>9, :salbums_band_id=>10},
|
|
1749
1752
|
{:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22, :salbums_id=>nil, :salbums_band_id=>nil},
|
|
1750
1753
|
{:id=>7, :band_id=>8, :sbands_id=>nil, :vocalist_id=>nil, :salbums_id=>nil, :salbums_band_id=>nil}]
|
|
1751
1754
|
as = ds.all
|
|
1752
|
-
as.
|
|
1753
|
-
as.map{|x| x.sbands}.
|
|
1754
|
-
as.map{|x| x.sbands.map{|y| y.salbums}}.
|
|
1755
|
+
as.must_equal [c1.load(:id=>3, :band_id=>2), c1.load(:id=>7, :band_id=>8)]
|
|
1756
|
+
as.map{|x| x.sbands}.must_equal [[c2.load(:id=>5, :vocalist_id=>6), c2.load(:id=>6, :vocalist_id=>22)], []]
|
|
1757
|
+
as.map{|x| x.sbands.map{|y| y.salbums}}.must_equal [[[c1.load(:id=>7, :band_id=>8), c1.load(:id=>9, :band_id=>10)], []], []]
|
|
1755
1758
|
end
|
|
1756
1759
|
|
|
1757
1760
|
it "should respect the association's :graph_select option" do
|
|
1758
1761
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :graph_select=>:vocalist_id
|
|
1759
|
-
GraphAlbum.eager_graph(:inner_band).sql.
|
|
1762
|
+
GraphAlbum.eager_graph(:inner_band).sql.must_equal 'SELECT albums.id, albums.band_id, inner_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS inner_band ON (inner_band.id = albums.band_id)'
|
|
1760
1763
|
|
|
1761
1764
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_select=>[:album_id]
|
|
1762
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1765
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id)'
|
|
1763
1766
|
|
|
1764
1767
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_select=>[]
|
|
1765
|
-
GraphAlbum.eager_graph(:inner_genres).sql.
|
|
1768
|
+
GraphAlbum.eager_graph(:inner_genres).sql.must_equal 'SELECT albums.id, albums.band_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.id = ag.genre_id)'
|
|
1766
1769
|
end
|
|
1767
1770
|
|
|
1768
1771
|
it "should respect the association's :graph_alias_base option" do
|
|
1769
1772
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :graph_alias_base=>:foo
|
|
1770
1773
|
ds = GraphAlbum.eager_graph(:inner_band)
|
|
1771
|
-
ds.sql.
|
|
1774
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, foo.id AS foo_id, foo.vocalist_id FROM albums LEFT OUTER JOIN bands AS foo ON (foo.id = albums.band_id)'
|
|
1772
1775
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_alias_base=>:foo
|
|
1773
|
-
ds.eager_graph(:right_tracks).sql.
|
|
1776
|
+
ds.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, foo.id AS foo_id, foo.vocalist_id, foo_0.id AS foo_0_id, foo_0.album_id FROM albums LEFT OUTER JOIN bands AS foo ON (foo.id = albums.band_id) LEFT OUTER JOIN tracks AS foo_0 ON (foo_0.album_id = albums.id)'
|
|
1774
1777
|
end
|
|
1775
1778
|
|
|
1776
1779
|
it "should respect the association's :graph_join_type option" do
|
|
1777
1780
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :graph_join_type=>:inner
|
|
1778
|
-
GraphAlbum.eager_graph(:inner_band).sql.
|
|
1781
|
+
GraphAlbum.eager_graph(:inner_band).sql.must_equal 'SELECT albums.id, albums.band_id, inner_band.id AS inner_band_id, inner_band.vocalist_id FROM albums INNER JOIN bands AS inner_band ON (inner_band.id = albums.band_id)'
|
|
1779
1782
|
|
|
1780
1783
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_join_type=>:right_outer
|
|
1781
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1784
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums RIGHT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id)'
|
|
1782
1785
|
|
|
1783
1786
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_type=>:inner
|
|
1784
|
-
GraphAlbum.eager_graph(:inner_genres).sql.
|
|
1787
|
+
GraphAlbum.eager_graph(:inner_genres).sql.must_equal 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres AS inner_genres ON (inner_genres.id = ag.genre_id)'
|
|
1785
1788
|
end
|
|
1786
1789
|
|
|
1787
1790
|
it "should respect the association's :graph_join_table_join_type option" do
|
|
1788
1791
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_join_type=>:inner
|
|
1789
|
-
GraphAlbum.eager_graph(:inner_genres).sql.
|
|
1792
|
+
GraphAlbum.eager_graph(:inner_genres).sql.must_equal 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums INNER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.id = ag.genre_id)'
|
|
1790
1793
|
|
|
1791
1794
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_join_type=>:inner, :graph_join_type=>:right_outer
|
|
1792
|
-
GraphAlbum.eager_graph(:inner_genres).sql.
|
|
1795
|
+
GraphAlbum.eager_graph(:inner_genres).sql.must_equal 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums INNER JOIN ag ON (ag.album_id = albums.id) RIGHT OUTER JOIN genres AS inner_genres ON (inner_genres.id = ag.genre_id)'
|
|
1793
1796
|
end
|
|
1794
1797
|
|
|
1795
1798
|
it "should respect the association's :conditions option" do
|
|
1796
1799
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :conditions=>{:active=>true}
|
|
1797
|
-
GraphAlbum.eager_graph(:active_band).sql.
|
|
1800
|
+
GraphAlbum.eager_graph(:active_band).sql.must_equal "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.id = albums.band_id) AND (active_band.active IS TRUE))"
|
|
1798
1801
|
|
|
1799
1802
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}, :reciprocal=>nil
|
|
1800
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1803
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND (right_tracks.id >= 0) AND (right_tracks.id <= 100))'
|
|
1801
1804
|
|
|
1802
1805
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :conditions=>{true=>:active}
|
|
1803
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1806
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
|
1804
1807
|
end
|
|
1805
1808
|
|
|
1806
1809
|
it "should respect the association's :graph_conditions option" do
|
|
1807
1810
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_conditions=>{:active=>true}
|
|
1808
|
-
GraphAlbum.eager_graph(:active_band).sql.
|
|
1811
|
+
GraphAlbum.eager_graph(:active_band).sql.must_equal "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.id = albums.band_id) AND (active_band.active IS TRUE))"
|
|
1809
1812
|
|
|
1810
1813
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_conditions=>{:id=>(0..100)}
|
|
1811
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1814
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND (right_tracks.id >= 0) AND (right_tracks.id <= 100))'
|
|
1812
1815
|
|
|
1813
1816
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_conditions=>{true=>:active}
|
|
1814
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1817
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
|
1815
1818
|
end
|
|
1816
1819
|
|
|
1817
1820
|
it "should respect the association's :graph_join_table_conditions option" do
|
|
1818
1821
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_conditions=>{:active=>true}
|
|
1819
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1822
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON ((ag.album_id = albums.id) AND (ag.active IS TRUE)) LEFT OUTER JOIN genres AS active_genres ON (active_genres.id = ag.genre_id)"
|
|
1820
1823
|
|
|
1821
1824
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_conditions=>{true=>:active}, :graph_join_table_conditions=>{true=>:active}
|
|
1822
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1825
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON ((ag.album_id = albums.id) AND ('t' = albums.active)) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
|
1823
1826
|
end
|
|
1824
1827
|
|
|
1825
1828
|
it "should respect the association's :graph_block option" do
|
|
1826
1829
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}
|
|
1827
|
-
GraphAlbum.eager_graph(:active_band).sql.
|
|
1830
|
+
GraphAlbum.eager_graph(:active_band).sql.must_equal "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.id = albums.band_id) AND (active_band.active IS TRUE))"
|
|
1828
1831
|
|
|
1829
1832
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :id)=>(0..100)}}
|
|
1830
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1833
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND (right_tracks.id >= 0) AND (right_tracks.id <= 100))'
|
|
1831
1834
|
|
|
1832
1835
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_block=>proc{|ja,lja,js| {true=>Sequel.qualify(lja, :active)}}
|
|
1833
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1836
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
|
1834
1837
|
end
|
|
1835
1838
|
|
|
1836
1839
|
it "should respect the association's :graph_join_table_block option" do
|
|
1837
1840
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}
|
|
1838
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1841
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON ((ag.album_id = albums.id) AND (ag.active IS TRUE)) LEFT OUTER JOIN genres AS active_genres ON (active_genres.id = ag.genre_id)"
|
|
1839
1842
|
|
|
1840
1843
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_block=>proc{|ja,lja,js| {true=>Sequel.qualify(lja, :active)}}, :graph_join_table_block=>proc{|ja,lja,js| {true=>Sequel.qualify(lja, :active)}}
|
|
1841
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1844
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON ((ag.album_id = albums.id) AND ('t' = albums.active)) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
|
1842
1845
|
end
|
|
1843
1846
|
|
|
1844
1847
|
it "should respect the association's :eager_grapher option" do
|
|
1845
1848
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphBand, {:active=>true}, :table_alias=>eo[:table_alias], :join_type=>:inner)}
|
|
1846
|
-
GraphAlbum.eager_graph(:active_band).sql.
|
|
1849
|
+
GraphAlbum.eager_graph(:active_band).sql.must_equal "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums INNER JOIN bands AS active_band ON (active_band.active IS TRUE)"
|
|
1847
1850
|
|
|
1848
1851
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphTrack, nil, :join_type=>:natural, :table_alias=>eo[:table_alias])}
|
|
1849
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1852
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums NATURAL JOIN tracks AS right_tracks'
|
|
1850
1853
|
|
|
1851
1854
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :eager_grapher=>proc{|eo| eo[:self].graph(:ag, {:album_id=>:id}, :table_alias=>:a123, :implicit_qualifier=>eo[:implicit_qualifier]).graph(GraphGenre, [:album_id], :table_alias=>eo[:table_alias])}
|
|
1852
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1855
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "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)"
|
|
1853
1856
|
end
|
|
1854
1857
|
|
|
1855
1858
|
it "should respect the association's :graph_only_conditions option" do
|
|
1856
1859
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_only_conditions=>{:active=>true}
|
|
1857
|
-
GraphAlbum.eager_graph(:active_band).sql.
|
|
1860
|
+
GraphAlbum.eager_graph(:active_band).sql.must_equal "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)"
|
|
1858
1861
|
|
|
1859
1862
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_only_conditions=>nil, :graph_join_type=>:natural
|
|
1860
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1863
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums NATURAL JOIN tracks AS right_tracks'
|
|
1861
1864
|
|
|
1862
1865
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_only_conditions=>[:album_id]
|
|
1863
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1866
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres USING (album_id)"
|
|
1864
1867
|
end
|
|
1865
1868
|
|
|
1866
1869
|
it "should respect the association's :graph_join_table_only_conditions option" do
|
|
1867
1870
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_only_conditions=>{:active=>true}
|
|
1868
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1871
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.active IS TRUE) LEFT OUTER JOIN genres AS active_genres ON (active_genres.id = ag.genre_id)"
|
|
1869
1872
|
|
|
1870
1873
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_only_conditions=>(Sequel.expr(:price) + 2 > 100), :graph_join_table_only_conditions=>"active"
|
|
1871
|
-
GraphAlbum.eager_graph(:active_genres).sql.
|
|
1874
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (active) LEFT OUTER JOIN genres AS active_genres ON ((price + 2) > 100)"
|
|
1872
1875
|
end
|
|
1873
1876
|
|
|
1874
1877
|
it "should create unique table aliases for all associations" do
|
|
1875
|
-
GraphAlbum.eager_graph(:previous_album=>{:previous_album=>:previous_album}).sql.
|
|
1878
|
+
GraphAlbum.eager_graph(:previous_album=>{:previous_album=>:previous_album}).sql.must_equal "SELECT albums.id, albums.band_id, previous_album.id AS previous_album_id, previous_album.band_id AS previous_album_band_id, previous_album_0.id AS previous_album_0_id, previous_album_0.band_id AS previous_album_0_band_id, previous_album_1.id AS previous_album_1_id, previous_album_1.band_id AS previous_album_1_band_id FROM albums LEFT OUTER JOIN albums AS previous_album ON (previous_album.id = albums.previous_album_id) LEFT OUTER JOIN albums AS previous_album_0 ON (previous_album_0.id = previous_album.previous_album_id) LEFT OUTER JOIN albums AS previous_album_1 ON (previous_album_1.id = previous_album_0.previous_album_id)"
|
|
1876
1879
|
end
|
|
1877
1880
|
|
|
1878
1881
|
it "should respect the association's :order" do
|
|
1879
1882
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
|
|
1880
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1883
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id) ORDER BY right_tracks.id, right_tracks.album_id'
|
|
1881
1884
|
end
|
|
1882
1885
|
|
|
1883
1886
|
it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
|
|
1884
1887
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
1885
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1888
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id) ORDER BY right_tracks.blah__id, right_tracks.blah__id DESC, blah.id DESC, blah.id, right_tracks.album_id, right_tracks.album_id DESC, 1, RANDOM(), b.a'
|
|
1886
1889
|
end
|
|
1887
1890
|
|
|
1888
1891
|
it "should not respect the association's :order if :order_eager_graph is false" do
|
|
1889
1892
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id], :order_eager_graph=>false
|
|
1890
|
-
GraphAlbum.eager_graph(:right_tracks).sql.
|
|
1893
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id)'
|
|
1891
1894
|
end
|
|
1892
1895
|
|
|
1893
1896
|
it "should add the association's :order to the existing order" do
|
|
1894
1897
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
|
|
1895
|
-
GraphAlbum.order(:band_id).eager_graph(:right_tracks).sql.
|
|
1898
|
+
GraphAlbum.order(:band_id).eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id) ORDER BY band_id, right_tracks.id, right_tracks.album_id'
|
|
1896
1899
|
end
|
|
1897
1900
|
|
|
1898
1901
|
it "should use the association's :graph_order in preference or order" do
|
|
1899
1902
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:tracks__id, :tracks__album_id], :graph_order=>[:id, :album_id]
|
|
1900
|
-
GraphAlbum.order(:band_id).eager_graph(:right_tracks).sql.
|
|
1903
|
+
GraphAlbum.order(:band_id).eager_graph(:right_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.id) ORDER BY band_id, right_tracks.id, right_tracks.album_id'
|
|
1901
1904
|
end
|
|
1902
1905
|
|
|
1903
1906
|
it "should add the association's :order for cascading associations" do
|
|
1904
1907
|
GraphBand.one_to_many :a_albums, :class=>'GraphAlbum', :key=>:band_id, :order=>:name, :reciprocal=>nil
|
|
1905
1908
|
GraphAlbum.one_to_many :b_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
|
|
1906
|
-
GraphBand.eager_graph(:a_albums=>:b_tracks).sql.
|
|
1909
|
+
GraphBand.eager_graph(:a_albums=>:b_tracks).sql.must_equal 'SELECT bands.id, bands.vocalist_id, a_albums.id AS a_albums_id, a_albums.band_id, b_tracks.id AS b_tracks_id, b_tracks.album_id FROM bands LEFT OUTER JOIN albums AS a_albums ON (a_albums.band_id = bands.id) LEFT OUTER JOIN tracks AS b_tracks ON (b_tracks.album_id = a_albums.id) ORDER BY a_albums.name, b_tracks.id, b_tracks.album_id'
|
|
1907
1910
|
GraphAlbum.one_to_many :albums, :class=>'GraphAlbum', :key=>:band_id, :order=>[:band_id, :id]
|
|
1908
|
-
GraphAlbum.eager_graph(:albums=>{:albums=>:albums}).sql.
|
|
1911
|
+
GraphAlbum.eager_graph(:albums=>{:albums=>:albums}).sql.must_equal 'SELECT albums.id, albums.band_id, albums_0.id AS albums_0_id, albums_0.band_id AS albums_0_band_id, albums_1.id AS albums_1_id, albums_1.band_id AS albums_1_band_id, albums_2.id AS albums_2_id, albums_2.band_id AS albums_2_band_id FROM albums LEFT OUTER JOIN albums AS albums_0 ON (albums_0.band_id = albums.id) LEFT OUTER JOIN albums AS albums_1 ON (albums_1.band_id = albums_0.id) LEFT OUTER JOIN albums AS albums_2 ON (albums_2.band_id = albums_1.id) ORDER BY albums_0.band_id, albums_0.id, albums_1.band_id, albums_1.id, albums_2.band_id, albums_2.id'
|
|
1909
1912
|
end
|
|
1910
1913
|
|
|
1911
1914
|
it "should add the associations :order for multiple associations" do
|
|
1912
1915
|
GraphAlbum.many_to_many :a_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :order=>:id
|
|
1913
1916
|
GraphAlbum.one_to_many :b_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
|
|
1914
|
-
GraphAlbum.eager_graph(:a_genres, :b_tracks).sql.
|
|
1917
|
+
GraphAlbum.eager_graph(:a_genres, :b_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, a_genres.id AS a_genres_id, b_tracks.id AS b_tracks_id, b_tracks.album_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS a_genres ON (a_genres.id = ag.genre_id) LEFT OUTER JOIN tracks AS b_tracks ON (b_tracks.album_id = albums.id) ORDER BY a_genres.id, b_tracks.id, b_tracks.album_id'
|
|
1915
1918
|
end
|
|
1916
1919
|
|
|
1917
1920
|
it "should use the correct qualifier when graphing multiple tables with extra conditions" do
|
|
1918
1921
|
GraphAlbum.many_to_many :a_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag
|
|
1919
1922
|
GraphAlbum.one_to_many :b_tracks, :class=>'GraphTrack', :key=>:album_id, :graph_conditions=>{:a=>:b}
|
|
1920
|
-
GraphAlbum.eager_graph(:a_genres, :b_tracks).sql.
|
|
1923
|
+
GraphAlbum.eager_graph(:a_genres, :b_tracks).sql.must_equal 'SELECT albums.id, albums.band_id, a_genres.id AS a_genres_id, b_tracks.id AS b_tracks_id, b_tracks.album_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS a_genres ON (a_genres.id = ag.genre_id) LEFT OUTER JOIN tracks AS b_tracks ON ((b_tracks.album_id = albums.id) AND (b_tracks.a = albums.b))'
|
|
1921
1924
|
end
|
|
1922
1925
|
|
|
1923
1926
|
it "should eagerly load associated records for classes that do not have a primary key" do
|
|
@@ -1925,27 +1928,27 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1925
1928
|
GraphGenre.no_primary_key
|
|
1926
1929
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :left_primary_key=>:band_id, :right_key=>:genre_id, :right_primary_key=>:xxx, :join_table=>:ag
|
|
1927
1930
|
ds = GraphAlbum.eager_graph(:inner_genres)
|
|
1928
|
-
ds.sql.
|
|
1931
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.band_id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.xxx = ag.genre_id)'
|
|
1929
1932
|
ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
|
|
1930
1933
|
as = ds.all
|
|
1931
|
-
as.
|
|
1932
|
-
as.first.inner_genres.
|
|
1934
|
+
as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1935
|
+
as.first.inner_genres.must_equal [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
|
|
1933
1936
|
GraphAlbum.set_primary_key :id
|
|
1934
1937
|
GraphGenre.set_primary_key :id
|
|
1935
1938
|
end
|
|
1936
1939
|
|
|
1937
1940
|
it "should handle eager loading with schemas and aliases of different types" do
|
|
1938
|
-
GraphAlbum.eager_graph(:band).join(:s__genres, [:b_id]).eager_graph(:genres).sql.
|
|
1939
|
-
GraphAlbum.eager_graph(:band).join(Sequel.qualify(:s, :genres), [:b_id]).eager_graph(:genres).sql.
|
|
1940
|
-
GraphAlbum.eager_graph(:band).join(Sequel.expr(:s__b).as('genres'), [:b_id]).eager_graph(:genres).sql.
|
|
1941
|
-
GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.
|
|
1942
|
-
GraphAlbum.eager_graph(:band).join(Sequel.identifier(:genres), [:b_id]).eager_graph(:genres).sql.
|
|
1943
|
-
GraphAlbum.eager_graph(:band).join('genres', [:b_id]).eager_graph(:genres).sql.
|
|
1941
|
+
GraphAlbum.eager_graph(:band).join(:s__genres, [:b_id]).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1942
|
+
GraphAlbum.eager_graph(:band).join(Sequel.qualify(:s, :genres), [:b_id]).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1943
|
+
GraphAlbum.eager_graph(:band).join(Sequel.expr(:s__b).as('genres'), [:b_id]).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1944
|
+
GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1945
|
+
GraphAlbum.eager_graph(:band).join(Sequel.identifier(:genres), [:b_id]).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1946
|
+
GraphAlbum.eager_graph(:band).join('genres', [:b_id]).eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
|
1944
1947
|
end
|
|
1945
1948
|
|
|
1946
1949
|
it "should raise errors if invalid aliases or table styles are used" do
|
|
1947
|
-
proc{GraphAlbum.from_self(:alias=>Sequel.qualify(:s, :bands)).eager_graph(:band)}.
|
|
1948
|
-
proc{GraphAlbum.from(Sequel.lit('?', :bands)).eager_graph(:band)}.
|
|
1950
|
+
proc{GraphAlbum.from_self(:alias=>Sequel.qualify(:s, :bands)).eager_graph(:band)}.must_raise(Sequel::Error)
|
|
1951
|
+
proc{GraphAlbum.from(Sequel.lit('?', :bands)).eager_graph(:band)}.must_raise(Sequel::Error)
|
|
1949
1952
|
end
|
|
1950
1953
|
|
|
1951
1954
|
it "should eagerly load schema qualified tables correctly with joins" do
|
|
@@ -1956,9 +1959,9 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1956
1959
|
c2.dataset = c2.dataset.from(:s__g)
|
|
1957
1960
|
c1.many_to_many :a_genres, :class=>c2, :left_primary_key=>:id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:s__ag
|
|
1958
1961
|
ds = c1.join(:s__t, [:b_id]).eager_graph(:a_genres)
|
|
1959
|
-
ds.sql.
|
|
1962
|
+
ds.sql.must_equal 'SELECT a.id, a_genres.id AS a_genres_id FROM (SELECT * FROM s.a INNER JOIN s.t USING (b_id)) AS a LEFT OUTER JOIN s.ag AS ag ON (ag.album_id = a.id) LEFT OUTER JOIN s.g AS a_genres ON (a_genres.id = ag.genre_id)'
|
|
1960
1963
|
ds = c1.eager_graph(:a_genres)
|
|
1961
|
-
ds.sql.
|
|
1964
|
+
ds.sql.must_equal 'SELECT s.a.id, a_genres.id AS a_genres_id FROM s.a LEFT OUTER JOIN s.ag AS ag ON (ag.album_id = s.a.id) LEFT OUTER JOIN s.g AS a_genres ON (a_genres.id = ag.genre_id)'
|
|
1962
1965
|
end
|
|
1963
1966
|
|
|
1964
1967
|
it "should respect :after_load callbacks on associations when eager graphing" do
|
|
@@ -1966,13 +1969,13 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1966
1969
|
GraphAlbum.one_to_many :al_tracks, :class=>GraphTrack, :key=>:album_id, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
1967
1970
|
GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
1968
1971
|
ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
|
|
1969
|
-
ds.sql.
|
|
1972
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_tracks.id AS al_tracks_id, al_tracks.album_id, al_genres.id AS al_genres_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genres ON (al_genres.id = ag.genre_id)"
|
|
1970
1973
|
ds._fetch = {:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7}
|
|
1971
1974
|
a = ds.all.first
|
|
1972
|
-
a.
|
|
1973
|
-
a.al_band.
|
|
1974
|
-
a.al_tracks.
|
|
1975
|
-
a.al_genres.
|
|
1975
|
+
a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1976
|
+
a.al_band.must_equal GraphBand.load(:id=>6, :vocalist_id=>4)
|
|
1977
|
+
a.al_tracks.must_equal [GraphTrack.load(:id=>10, :album_id=>6)]
|
|
1978
|
+
a.al_genres.must_equal [GraphGenre.load(:id=>14)]
|
|
1976
1979
|
end
|
|
1977
1980
|
|
|
1978
1981
|
it "should respect limits on associations when eager graphing" do
|
|
@@ -1980,25 +1983,25 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1980
1983
|
GraphAlbum.one_to_many :al_tracks, :class=>GraphTrack, :key=>:album_id, :limit=>2
|
|
1981
1984
|
GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
|
|
1982
1985
|
ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
|
|
1983
|
-
ds.sql.
|
|
1986
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_tracks.id AS al_tracks_id, al_tracks.album_id, al_genres.id AS al_genres_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genres ON (al_genres.id = ag.genre_id)"
|
|
1984
1987
|
ds._fetch = [{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7},
|
|
1985
1988
|
{:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_tracks_id=>10, :album_id=>11, :al_genres_id=>12},
|
|
1986
1989
|
{:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]
|
|
1987
1990
|
a = ds.all.first
|
|
1988
|
-
a.
|
|
1989
|
-
a.al_band.
|
|
1990
|
-
a.al_tracks.
|
|
1991
|
-
a.al_genres.
|
|
1991
|
+
a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1992
|
+
a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
|
|
1993
|
+
a.al_tracks.must_equal [GraphTrack.load(:id=>5, :album_id=>6), GraphTrack.load(:id=>10, :album_id=>11)]
|
|
1994
|
+
a.al_genres.must_equal [GraphGenre.load(:id=>7), GraphGenre.load(:id=>12)]
|
|
1992
1995
|
end
|
|
1993
1996
|
|
|
1994
1997
|
it "should handle offsets on associations with no results when eager graphing" do
|
|
1995
1998
|
GraphAlbum.one_to_many :al_tracks, :class=>GraphTrack, :key=>:album_id, :limit=>[2, 1]
|
|
1996
1999
|
ds = GraphAlbum.eager_graph(:al_tracks)
|
|
1997
|
-
ds.sql.
|
|
2000
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, al_tracks.id AS al_tracks_id, al_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id)"
|
|
1998
2001
|
ds._fetch = [{:id=>1, :band_id=>2, :al_tracks_id=>nil, :album_id=>nil}]
|
|
1999
2002
|
a = ds.all.first
|
|
2000
|
-
a.
|
|
2001
|
-
a.al_tracks.
|
|
2003
|
+
a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
2004
|
+
a.al_tracks.must_equal []
|
|
2002
2005
|
end
|
|
2003
2006
|
|
|
2004
2007
|
it "should respect offsets on associations when eager graphing" do
|
|
@@ -2006,15 +2009,15 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
2006
2009
|
GraphAlbum.one_to_many :al_tracks, :class=>GraphTrack, :key=>:album_id, :limit=>[1, 1]
|
|
2007
2010
|
GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1,1]
|
|
2008
2011
|
ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
|
|
2009
|
-
ds.sql.
|
|
2012
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_tracks.id AS al_tracks_id, al_tracks.album_id, al_genres.id AS al_genres_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genres ON (al_genres.id = ag.genre_id)"
|
|
2010
2013
|
ds._fetch = [{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7},
|
|
2011
2014
|
{:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_tracks_id=>10, :album_id=>11, :al_genres_id=>12},
|
|
2012
2015
|
{:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]
|
|
2013
2016
|
a = ds.all.first
|
|
2014
|
-
a.
|
|
2015
|
-
a.al_band.
|
|
2016
|
-
a.al_tracks.
|
|
2017
|
-
a.al_genres.
|
|
2017
|
+
a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
2018
|
+
a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
|
|
2019
|
+
a.al_tracks.must_equal [GraphTrack.load(:id=>10, :album_id=>11)]
|
|
2020
|
+
a.al_genres.must_equal [GraphGenre.load(:id=>12)]
|
|
2018
2021
|
end
|
|
2019
2022
|
|
|
2020
2023
|
it "should respect offsets on associations when eager graphing one_to_one and one_through_one associations" do
|
|
@@ -2022,84 +2025,84 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
2022
2025
|
GraphAlbum.one_to_one :al_track, :class=>GraphTrack, :key=>:album_id, :limit=>[nil, 1]
|
|
2023
2026
|
GraphAlbum.one_through_one :al_genre, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil,1]
|
|
2024
2027
|
ds = GraphAlbum.eager_graph(:al_band, :al_track, :al_genre)
|
|
2025
|
-
ds.sql.
|
|
2028
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_track.id AS al_track_id, al_track.album_id, al_genre.id AS al_genre_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_track ON (al_track.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genre ON (al_genre.id = ag.genre_id)"
|
|
2026
2029
|
ds._fetch = [{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_track_id=>5, :album_id=>6, :al_genre_id=>7},
|
|
2027
2030
|
{:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_track_id=>10, :album_id=>11, :al_genre_id=>12},
|
|
2028
2031
|
{:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_track_id=>15, :album_id=>16, :al_genre_id=>17}]
|
|
2029
2032
|
a = ds.all.first
|
|
2030
|
-
a.
|
|
2031
|
-
a.al_band.
|
|
2032
|
-
a.al_track.
|
|
2033
|
-
a.al_genre.
|
|
2033
|
+
a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
2034
|
+
a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
|
|
2035
|
+
a.al_track.must_equal GraphTrack.load(:id=>10, :album_id=>11)
|
|
2036
|
+
a.al_genre.must_equal GraphGenre.load(:id=>12)
|
|
2034
2037
|
end
|
|
2035
2038
|
|
|
2036
2039
|
it "should eagerly load a many_to_one association with a custom callback" do
|
|
2037
2040
|
ds = GraphAlbum.eager_graph(:band => proc {|ds1| ds1.select(:id).columns(:id)})
|
|
2038
|
-
ds.sql.
|
|
2041
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0 FROM albums LEFT OUTER JOIN (SELECT id FROM bands) AS band ON (band.id = albums.band_id)'
|
|
2039
2042
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2}
|
|
2040
2043
|
a = ds.all
|
|
2041
|
-
a.
|
|
2042
|
-
a.first.band.
|
|
2044
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
2045
|
+
a.first.band.must_equal GraphBand.load(:id => 2)
|
|
2043
2046
|
end
|
|
2044
2047
|
|
|
2045
2048
|
it "should eagerly load a one_to_one association with a custom callback" do
|
|
2046
2049
|
ds = GraphAlbum.eager_graph(:track => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
|
|
2047
|
-
ds.sql.
|
|
2050
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, track.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS track ON (track.album_id = albums.id)'
|
|
2048
2051
|
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
|
2049
2052
|
a = ds.all
|
|
2050
|
-
a.
|
|
2051
|
-
a.first.track.
|
|
2053
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
2054
|
+
a.first.track.must_equal GraphTrack.load(:album_id=>1)
|
|
2052
2055
|
end
|
|
2053
2056
|
|
|
2054
2057
|
it "should eagerly load a one_to_many association with a custom callback" do
|
|
2055
2058
|
ds = GraphAlbum.eager_graph(:tracks => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
|
|
2056
|
-
ds.sql.
|
|
2059
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, tracks.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS tracks ON (tracks.album_id = albums.id)'
|
|
2057
2060
|
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
|
2058
2061
|
a = ds.all
|
|
2059
|
-
a.
|
|
2060
|
-
a.first.tracks.
|
|
2062
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
2063
|
+
a.first.tracks.must_equal [GraphTrack.load(:album_id=>1)]
|
|
2061
2064
|
end
|
|
2062
2065
|
|
|
2063
2066
|
it "should eagerly load a one_through_one association with a custom callback" do
|
|
2064
2067
|
ds = GraphAlbum.eager_graph(:genre => proc {|ds1| ds1.select(:id).columns(:id)})
|
|
2065
|
-
ds.sql.
|
|
2068
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN (SELECT id FROM genres) AS genre ON (genre.id = ag.genre_id)'
|
|
2066
2069
|
ds._fetch = {:id=>1, :band_id=>2, :genre_id=>4}
|
|
2067
2070
|
a = ds.all
|
|
2068
|
-
a.
|
|
2069
|
-
a.first.genre.
|
|
2071
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
2072
|
+
a.first.genre.must_equal GraphGenre.load(:id => 4)
|
|
2070
2073
|
end
|
|
2071
2074
|
|
|
2072
2075
|
it "should eagerly load a many_to_many association with a custom callback" do
|
|
2073
2076
|
ds = GraphAlbum.eager_graph(:genres => proc {|ds1| ds1.select(:id).columns(:id)})
|
|
2074
|
-
ds.sql.
|
|
2077
|
+
ds.sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN (SELECT id FROM genres) AS genres ON (genres.id = ag.genre_id)'
|
|
2075
2078
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
|
|
2076
2079
|
a = ds.all
|
|
2077
|
-
a.
|
|
2078
|
-
a.first.genres.
|
|
2080
|
+
a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
2081
|
+
a.first.genres.must_equal [GraphGenre.load(:id => 4)]
|
|
2079
2082
|
end
|
|
2080
2083
|
|
|
2081
2084
|
it "should allow cascading of eager loading with a custom callback with hash value" do
|
|
2082
2085
|
ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>{:band=>:members}})
|
|
2083
|
-
ds.sql.
|
|
2086
|
+
ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
2084
2087
|
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
|
|
2085
2088
|
a = ds.all
|
|
2086
|
-
a.
|
|
2089
|
+
a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
2087
2090
|
a = a.first
|
|
2088
|
-
a.album.
|
|
2089
|
-
a.album.band.
|
|
2090
|
-
a.album.band.members.
|
|
2091
|
+
a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
2092
|
+
a.album.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
2093
|
+
a.album.band.members.must_equal [GraphBandMember.load(:id => 5)]
|
|
2091
2094
|
end
|
|
2092
2095
|
|
|
2093
2096
|
it "should allow cascading of eager loading with a custom callback with array value" do
|
|
2094
2097
|
ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>[:band, :tracks]})
|
|
2095
|
-
ds.sql.
|
|
2098
|
+
ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, tracks_0.id AS tracks_0_id, tracks_0.album_id AS tracks_0_album_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN tracks AS tracks_0 ON (tracks_0.album_id = album.id)'
|
|
2096
2099
|
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>6, :tracks_0_id=>3, :tracks_0_album_id=>1}
|
|
2097
2100
|
a = ds.all
|
|
2098
|
-
a.
|
|
2101
|
+
a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
2099
2102
|
a = a.first
|
|
2100
|
-
a.album.
|
|
2101
|
-
a.album.band.
|
|
2102
|
-
a.album.tracks.
|
|
2103
|
+
a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
|
|
2104
|
+
a.album.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
2105
|
+
a.album.tracks.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
2103
2106
|
end
|
|
2104
2107
|
end
|
|
2105
2108
|
|
|
@@ -2115,9 +2118,9 @@ describe "Sequel::Models with double underscores in table names" do
|
|
|
2115
2118
|
it "should have working eager_graph implementations" do
|
|
2116
2119
|
@db.fetch = {:id=>1, :foo_id=>1, :foos_id=>1, :foos_foo_id=>1}
|
|
2117
2120
|
foos = @Foo.eager_graph(:foos).all
|
|
2118
|
-
@db.sqls.
|
|
2119
|
-
foos.
|
|
2120
|
-
foos.first.foos.
|
|
2121
|
+
@db.sqls.must_equal ["SELECT fo__os.id, fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM fo__os LEFT OUTER JOIN (SELECT * FROM fo__os) AS foos ON (foos._id = fo__os.id)"]
|
|
2122
|
+
foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
|
2123
|
+
foos.first.foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
|
2121
2124
|
end
|
|
2122
2125
|
|
|
2123
2126
|
it "should have working eager_graph implementations when qualified" do
|
|
@@ -2126,9 +2129,9 @@ describe "Sequel::Models with double underscores in table names" do
|
|
|
2126
2129
|
@db.sqls
|
|
2127
2130
|
@db.fetch = {:id=>1, :foo_id=>1, :foos_id=>1, :foos_foo_id=>1}
|
|
2128
2131
|
foos = @Foo.eager_graph(:foos).all
|
|
2129
|
-
@db.sqls.
|
|
2130
|
-
foos.
|
|
2131
|
-
foos.first.foos.
|
|
2132
|
+
@db.sqls.must_equal ["SELECT s.fo__os.id, s.fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM s.fo__os LEFT OUTER JOIN (SELECT * FROM s.fo__os) AS foos ON (foos._id = s.fo__os.id)"]
|
|
2133
|
+
foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
|
2134
|
+
foos.first.foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
|
2132
2135
|
end
|
|
2133
2136
|
end
|
|
2134
2137
|
|