sequel 4.41.0 → 4.42.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 +98 -0
- data/README.rdoc +23 -10
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +5 -2
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/core_extensions.rdoc +2 -2
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +19 -1
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/release_notes/4.42.0.txt +221 -0
- data/doc/testing.rdoc +3 -1
- data/lib/sequel/adapters/ado/access.rb +0 -1
- data/lib/sequel/adapters/ado/mssql.rb +0 -1
- data/lib/sequel/adapters/do/mysql.rb +0 -1
- data/lib/sequel/adapters/do/postgres.rb +0 -1
- data/lib/sequel/adapters/do/sqlite3.rb +0 -1
- data/lib/sequel/adapters/ibmdb.rb +21 -25
- data/lib/sequel/adapters/jdbc.rb +8 -16
- data/lib/sequel/adapters/jdbc/as400.rb +0 -1
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
- data/lib/sequel/adapters/jdbc/db2.rb +0 -1
- data/lib/sequel/adapters/jdbc/derby.rb +0 -1
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
- data/lib/sequel/adapters/jdbc/h2.rb +0 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
- data/lib/sequel/adapters/mock.rb +54 -12
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +11 -17
- data/lib/sequel/adapters/odbc/mssql.rb +0 -1
- data/lib/sequel/adapters/oracle.rb +8 -20
- data/lib/sequel/adapters/postgres.rb +11 -29
- data/lib/sequel/adapters/shared/access.rb +5 -12
- data/lib/sequel/adapters/shared/cubrid.rb +4 -13
- data/lib/sequel/adapters/shared/db2.rb +4 -2
- data/lib/sequel/adapters/shared/firebird.rb +2 -4
- data/lib/sequel/adapters/shared/informix.rb +4 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -5
- data/lib/sequel/adapters/shared/mysql.rb +4 -14
- data/lib/sequel/adapters/shared/oracle.rb +1 -3
- data/lib/sequel/adapters/shared/postgres.rb +16 -38
- data/lib/sequel/adapters/shared/progress.rb +0 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
- data/lib/sequel/adapters/shared/sqlite.rb +20 -16
- data/lib/sequel/adapters/sqlite.rb +8 -20
- data/lib/sequel/adapters/swift/mysql.rb +0 -1
- data/lib/sequel/adapters/swift/postgres.rb +0 -1
- data/lib/sequel/adapters/swift/sqlite.rb +0 -1
- data/lib/sequel/adapters/tinytds.rb +4 -12
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
- data/lib/sequel/ast_transformer.rb +2 -2
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +0 -66
- data/lib/sequel/database/features.rb +6 -0
- data/lib/sequel/database/misc.rb +31 -17
- data/lib/sequel/database/query.rb +7 -4
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset.rb +8 -8
- data/lib/sequel/dataset/actions.rb +140 -46
- data/lib/sequel/dataset/features.rb +1 -5
- data/lib/sequel/dataset/graph.rb +7 -8
- data/lib/sequel/dataset/misc.rb +127 -56
- data/lib/sequel/dataset/mutation.rb +9 -20
- data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
- data/lib/sequel/dataset/prepared_statements.rb +102 -46
- data/lib/sequel/dataset/query.rb +155 -72
- data/lib/sequel/dataset/sql.rb +26 -9
- data/lib/sequel/extensions/columns_introspection.rb +3 -1
- data/lib/sequel/extensions/core_extensions.rb +5 -5
- data/lib/sequel/extensions/core_refinements.rb +5 -5
- data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
- data/lib/sequel/extensions/freeze_datasets.rb +69 -0
- data/lib/sequel/extensions/identifier_mangling.rb +196 -0
- data/lib/sequel/extensions/looser_typecasting.rb +11 -7
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +5 -2
- data/lib/sequel/extensions/pagination.rb +42 -23
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
- data/lib/sequel/model/associations.rb +25 -8
- data/lib/sequel/model/base.rb +88 -29
- data/lib/sequel/model/dataset_module.rb +37 -0
- data/lib/sequel/plugins/association_pks.rb +4 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/constraint_validations.rb +1 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +8 -8
- data/lib/sequel/plugins/eager_each.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -4
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -2
- data/lib/sequel/sql.rb +69 -36
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +10 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -5
- data/spec/adapters/mysql_spec.rb +9 -9
- data/spec/adapters/postgres_spec.rb +67 -68
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +29 -15
- data/spec/core/connection_pool_spec.rb +14 -14
- data/spec/core/database_spec.rb +38 -180
- data/spec/core/dataset_mutation_spec.rb +253 -0
- data/spec/core/dataset_spec.rb +394 -537
- data/spec/core/expression_filters_spec.rb +34 -32
- data/spec/core/mock_adapter_spec.rb +27 -35
- data/spec/core/placeholder_literalizer_spec.rb +2 -4
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +1 -2
- data/spec/core_extensions_spec.rb +22 -29
- data/spec/extensions/active_model_spec.rb +6 -6
- data/spec/extensions/association_dependencies_spec.rb +2 -2
- data/spec/extensions/blacklist_security_spec.rb +3 -3
- data/spec/extensions/boolean_readers_spec.rb +12 -12
- data/spec/extensions/caching_spec.rb +13 -10
- data/spec/extensions/class_table_inheritance_spec.rb +38 -43
- data/spec/extensions/column_conflicts_spec.rb +1 -3
- data/spec/extensions/columns_introspection_spec.rb +2 -3
- data/spec/extensions/composition_spec.rb +5 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
- data/spec/extensions/constraint_validations_spec.rb +14 -8
- data/spec/extensions/core_refinements_spec.rb +22 -29
- data/spec/extensions/csv_serializer_spec.rb +7 -6
- data/spec/extensions/date_arithmetic_spec.rb +15 -15
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +19 -10
- data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
- data/spec/extensions/eager_each_spec.rb +12 -16
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +4 -3
- data/spec/extensions/force_encoding_spec.rb +12 -12
- data/spec/extensions/freeze_datasets_spec.rb +31 -0
- data/spec/extensions/graph_each_spec.rb +6 -18
- data/spec/extensions/hook_class_methods_spec.rb +7 -7
- data/spec/extensions/identifier_mangling_spec.rb +307 -0
- data/spec/extensions/instance_filters_spec.rb +5 -6
- data/spec/extensions/instance_hooks_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +12 -15
- data/spec/extensions/lazy_attributes_spec.rb +4 -4
- data/spec/extensions/list_spec.rb +19 -21
- data/spec/extensions/many_through_many_spec.rb +108 -163
- data/spec/extensions/meta_def_spec.rb +7 -2
- data/spec/extensions/migration_spec.rb +10 -12
- data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
- data/spec/extensions/named_timezones_spec.rb +4 -3
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +17 -12
- data/spec/extensions/optimistic_locking_spec.rb +4 -5
- data/spec/extensions/pagination_spec.rb +8 -10
- data/spec/extensions/pg_array_associations_spec.rb +28 -27
- data/spec/extensions/pg_array_ops_spec.rb +2 -1
- data/spec/extensions/pg_array_spec.rb +6 -2
- data/spec/extensions/pg_enum_spec.rb +5 -3
- data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
- data/spec/extensions/pg_hstore_spec.rb +7 -6
- data/spec/extensions/pg_inet_ops_spec.rb +2 -1
- data/spec/extensions/pg_inet_spec.rb +2 -1
- data/spec/extensions/pg_interval_spec.rb +2 -1
- data/spec/extensions/pg_json_ops_spec.rb +2 -1
- data/spec/extensions/pg_json_spec.rb +6 -3
- data/spec/extensions/pg_loose_count_spec.rb +1 -0
- data/spec/extensions/pg_range_ops_spec.rb +3 -1
- data/spec/extensions/pg_range_spec.rb +9 -5
- data/spec/extensions/pg_row_ops_spec.rb +2 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -6
- data/spec/extensions/pg_row_spec.rb +5 -3
- data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
- data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +12 -11
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +8 -5
- data/spec/extensions/rcte_tree_spec.rb +39 -39
- data/spec/extensions/round_timestamps_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +1 -2
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
- data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
- data/spec/extensions/serialization_spec.rb +15 -13
- data/spec/extensions/set_overrides_spec.rb +14 -8
- data/spec/extensions/sharding_spec.rb +9 -18
- data/spec/extensions/shared_caching_spec.rb +3 -4
- data/spec/extensions/single_table_inheritance_spec.rb +11 -11
- data/spec/extensions/skip_create_refresh_spec.rb +2 -1
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/split_values_spec.rb +2 -2
- data/spec/extensions/sql_comments_spec.rb +6 -0
- data/spec/extensions/static_cache_spec.rb +7 -9
- data/spec/extensions/string_agg_spec.rb +30 -29
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
- data/spec/extensions/thread_local_timezones_spec.rb +2 -2
- data/spec/extensions/timestamps_spec.rb +28 -3
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/tree_spec.rb +33 -29
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -0
- data/spec/extensions/update_primary_key_spec.rb +11 -7
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +0 -1
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/extensions/validation_helpers_spec.rb +10 -10
- data/spec/extensions/xml_serializer_spec.rb +7 -3
- data/spec/integration/associations_test.rb +31 -31
- data/spec/integration/dataset_test.rb +17 -19
- data/spec/integration/eager_loader_test.rb +24 -24
- data/spec/integration/model_test.rb +6 -6
- data/spec/integration/plugin_test.rb +43 -43
- data/spec/integration/prepared_statement_test.rb +6 -6
- data/spec/integration/schema_test.rb +63 -52
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/transaction_test.rb +13 -13
- data/spec/model/association_reflection_spec.rb +17 -17
- data/spec/model/associations_spec.rb +101 -96
- data/spec/model/base_spec.rb +175 -49
- data/spec/model/class_dataset_methods_spec.rb +5 -9
- data/spec/model/dataset_methods_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +209 -235
- data/spec/model/hooks_spec.rb +15 -15
- data/spec/model/model_spec.rb +28 -21
- data/spec/model/plugins_spec.rb +4 -5
- data/spec/model/record_spec.rb +59 -57
- data/spec/model/spec_helper.rb +1 -1
- data/spec/model/validations_spec.rb +6 -6
- data/spec/spec_config.rb +1 -1
- metadata +10 -2
|
@@ -3,7 +3,6 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
3
3
|
describe "instance_filters plugin" do
|
|
4
4
|
before do
|
|
5
5
|
@c = Class.new(Sequel::Model(:people))
|
|
6
|
-
@c.dataset.quote_identifiers = false
|
|
7
6
|
@c.columns :id, :name, :num
|
|
8
7
|
@c.plugin :instance_filters
|
|
9
8
|
@p = @c.load(:id=>1, :name=>'John', :num=>1)
|
|
@@ -14,7 +13,7 @@ describe "instance_filters plugin" do
|
|
|
14
13
|
@p.update(:name=>'Bob')
|
|
15
14
|
DB.sqls.must_equal ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
|
|
16
15
|
@p.instance_filter(:name=>'Jim')
|
|
17
|
-
@p.this.
|
|
16
|
+
@p.instance_variable_set(:@this, @p.this.with_numrows(0))
|
|
18
17
|
proc{@p.update(:name=>'Joe')}.must_raise(Sequel::Plugins::InstanceFilters::Error)
|
|
19
18
|
DB.sqls.must_equal ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
|
|
20
19
|
end
|
|
@@ -23,7 +22,7 @@ describe "instance_filters plugin" do
|
|
|
23
22
|
@p.destroy
|
|
24
23
|
DB.sqls.must_equal ["DELETE FROM people WHERE id = 1"]
|
|
25
24
|
@p.instance_filter(:name=>'Jim')
|
|
26
|
-
@p.this.
|
|
25
|
+
@p.instance_variable_set(:@this, @p.this.with_numrows(0))
|
|
27
26
|
proc{@p.destroy}.must_raise(Sequel::Plugins::InstanceFilters::Error)
|
|
28
27
|
DB.sqls.must_equal ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
|
|
29
28
|
end
|
|
@@ -34,16 +33,16 @@ describe "instance_filters plugin" do
|
|
|
34
33
|
@p.update(:name=>'Bob')
|
|
35
34
|
DB.sqls.must_equal ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
|
|
36
35
|
@p.instance_filter(:name=>'Jim')
|
|
37
|
-
@p.this.
|
|
36
|
+
@p.instance_variable_set(:@this, @p.this.with_numrows(0))
|
|
38
37
|
proc{@p.update(:name=>'Joe')}.must_raise(Sequel::Plugins::InstanceFilters::Error)
|
|
39
38
|
DB.sqls.must_equal ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
|
|
40
39
|
|
|
41
40
|
@p = @c.load(:id=>1, :name=>'John', :num=>1)
|
|
42
|
-
@p.this.
|
|
41
|
+
@p.instance_variable_set(:@this, @p.this.with_numrows(1))
|
|
43
42
|
@p.destroy
|
|
44
43
|
DB.sqls.must_equal ["DELETE FROM people WHERE (id = 1)"]
|
|
45
44
|
@p.instance_filter(:name=>'Jim')
|
|
46
|
-
@p.this.
|
|
45
|
+
@p.instance_variable_set(:@this, @p.this.with_numrows(0))
|
|
47
46
|
proc{@p.destroy}.must_raise(Sequel::Plugins::InstanceFilters::Error)
|
|
48
47
|
DB.sqls.must_equal ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
|
|
49
48
|
|
|
@@ -28,10 +28,10 @@ describe "InstanceHooks plugin" do
|
|
|
28
28
|
@o.after_create_hook{r 1}
|
|
29
29
|
@o.before_create_hook{r false}
|
|
30
30
|
@o.before_create_hook{r 4}
|
|
31
|
-
@o.save.
|
|
31
|
+
@o.save.must_be_nil
|
|
32
32
|
@r.must_equal [4, false]
|
|
33
33
|
@r.clear
|
|
34
|
-
@o.save.
|
|
34
|
+
@o.save.must_be_nil
|
|
35
35
|
@r.must_equal [4, false]
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -50,10 +50,10 @@ describe "InstanceHooks plugin" do
|
|
|
50
50
|
@x.after_update_hook{r 1}
|
|
51
51
|
@x.before_update_hook{r false}
|
|
52
52
|
@x.before_update_hook{r 4}
|
|
53
|
-
@x.save.
|
|
53
|
+
@x.save.must_be_nil
|
|
54
54
|
@r.must_equal [4, false]
|
|
55
55
|
@r.clear
|
|
56
|
-
@x.save.
|
|
56
|
+
@x.save.must_be_nil
|
|
57
57
|
@r.must_equal [4, false]
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -80,17 +80,17 @@ describe "InstanceHooks plugin" do
|
|
|
80
80
|
@x.after_save_hook{r 1}
|
|
81
81
|
@x.before_save_hook{r false}
|
|
82
82
|
@x.before_save_hook{r 4}
|
|
83
|
-
@x.save.
|
|
83
|
+
@x.save.must_be_nil
|
|
84
84
|
@r.must_equal [4, false]
|
|
85
85
|
@r.clear
|
|
86
86
|
|
|
87
87
|
@x.after_save_hook{r 1}
|
|
88
88
|
@x.before_save_hook{r false}
|
|
89
89
|
@x.before_save_hook{r 4}
|
|
90
|
-
@x.save.
|
|
90
|
+
@x.save.must_be_nil
|
|
91
91
|
@r.must_equal [4, false]
|
|
92
92
|
@r.clear
|
|
93
|
-
@x.save.
|
|
93
|
+
@x.save.must_be_nil
|
|
94
94
|
@r.must_equal [4, false]
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -107,7 +107,7 @@ describe "InstanceHooks plugin" do
|
|
|
107
107
|
@x.after_destroy_hook{r 1}
|
|
108
108
|
@x.before_destroy_hook{r false}
|
|
109
109
|
@x.before_destroy_hook{r 4}
|
|
110
|
-
@x.destroy.
|
|
110
|
+
@x.destroy.must_be_nil
|
|
111
111
|
@r.must_equal [4, false]
|
|
112
112
|
end
|
|
113
113
|
|
|
@@ -180,9 +180,9 @@ describe "InstanceHooks plugin" do
|
|
|
180
180
|
it "should not clear validations hooks on successful save" do
|
|
181
181
|
@x.after_validation_hook{@x.errors.add(:id, 'a') if @x.id == 1; r 1}
|
|
182
182
|
@x.before_validation_hook{r 2}
|
|
183
|
-
@x.save.
|
|
183
|
+
@x.save.must_be_nil
|
|
184
184
|
@r.must_equal [2, 1]
|
|
185
|
-
@x.save.
|
|
185
|
+
@x.save.must_be_nil
|
|
186
186
|
@r.must_equal [2, 1, 2, 1]
|
|
187
187
|
@x.id = 2
|
|
188
188
|
@x.save.must_equal @x
|
|
@@ -237,7 +237,7 @@ describe "InstanceHooks plugin with transactions" do
|
|
|
237
237
|
it "should support after_rollback_hook" do
|
|
238
238
|
@or.after_rollback_hook{@db.execute('ar1')}
|
|
239
239
|
@or.after_rollback_hook{@db.execute('ar2')}
|
|
240
|
-
@or.save.
|
|
240
|
+
@or.save.must_be_nil
|
|
241
241
|
@db.sqls.must_equal ['BEGIN', 'as', 'ROLLBACK', 'ar1', 'ar2']
|
|
242
242
|
end
|
|
243
243
|
|
|
@@ -251,7 +251,7 @@ describe "InstanceHooks plugin with transactions" do
|
|
|
251
251
|
it "should support after_rollback_hook" do
|
|
252
252
|
@or.after_destroy_rollback_hook{@db.execute('adr1')}
|
|
253
253
|
@or.after_destroy_rollback_hook{@db.execute('adr2')}
|
|
254
|
-
@or.destroy.
|
|
254
|
+
@or.destroy.must_be_nil
|
|
255
255
|
@db.sqls.must_equal ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'ROLLBACK', 'adr1', 'adr2']
|
|
256
256
|
end
|
|
257
257
|
|
|
@@ -174,16 +174,15 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
it "should support a to_json class and dataset method" do
|
|
177
|
-
Album.dataset
|
|
178
|
-
Artist.dataset
|
|
177
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
178
|
+
Artist.dataset = Artist.dataset.with_fetch(:id=>2, :name=>'YJM')
|
|
179
179
|
Album.array_from_json(Album.to_json).must_equal [@album]
|
|
180
180
|
Album.array_from_json(Album.to_json(:include=>:artist), :associations=>:artist).map{|x| x.artist}.must_equal [@artist]
|
|
181
181
|
Album.array_from_json(Album.dataset.to_json(:only=>:name)).must_equal [Album.load(:name=>@album.name)]
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
it "should have dataset to_json method work with naked datasets" do
|
|
185
|
-
ds = Album.dataset.naked
|
|
186
|
-
ds._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
|
|
185
|
+
ds = Album.dataset.naked.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
187
186
|
Sequel.parse_json(ds.to_json).must_equal [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
|
|
188
187
|
end
|
|
189
188
|
|
|
@@ -227,7 +226,7 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
227
226
|
end
|
|
228
227
|
end
|
|
229
228
|
Namespace::Album.new({}).to_json(:root=>true).to_s.must_equal '{"album":{}}'
|
|
230
|
-
Namespace::Album.dataset
|
|
229
|
+
Namespace::Album.dataset = Namespace::Album.dataset.with_fetch([{}])
|
|
231
230
|
Namespace::Album.dataset.to_json(:root=>:collection).to_s.must_equal '{"albums":[{}]}'
|
|
232
231
|
Namespace::Album.dataset.to_json(:root=>:both).to_s.must_equal '{"albums":[{"album":{}}]}'
|
|
233
232
|
Object.send(:remove_const, :Namespace)
|
|
@@ -239,25 +238,23 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
|
239
238
|
end
|
|
240
239
|
|
|
241
240
|
it "should handle the :root=>:both option to qualify a dataset of records" do
|
|
242
|
-
Album.dataset.
|
|
243
|
-
Album.dataset.to_json(:root=>:both, :only => :id).to_s.must_equal '{"albums":[{"album":{"id":1}},{"album":{"id":1}}]}'
|
|
241
|
+
Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]).to_json(:root=>:both, :only => :id).to_s.must_equal '{"albums":[{"album":{"id":1}},{"album":{"id":1}}]}'
|
|
244
242
|
end
|
|
245
243
|
|
|
246
244
|
it "should handle the :root=>:collection option to qualify just the collection" do
|
|
247
|
-
Album.dataset.
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
ds = Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}])
|
|
246
|
+
ds.to_json(:root=>:collection, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
|
|
247
|
+
ds.to_json(:root=>true, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
|
|
250
248
|
end
|
|
251
249
|
|
|
252
250
|
it "should handle the :root=>:instance option to qualify just the instances" do
|
|
253
|
-
Album.dataset.
|
|
254
|
-
Album.dataset.to_json(:root=>:instance, :only => :id).to_s.must_equal '[{"album":{"id":1}},{"album":{"id":1}}]'
|
|
251
|
+
Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]).to_json(:root=>:instance, :only => :id).to_s.must_equal '[{"album":{"id":1}},{"album":{"id":1}}]'
|
|
255
252
|
end
|
|
256
253
|
|
|
257
254
|
it "should handle the :root=>string option to qualify just the collection using the string as the key" do
|
|
258
|
-
Album.dataset.
|
|
259
|
-
|
|
260
|
-
|
|
255
|
+
ds = Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}])
|
|
256
|
+
ds.to_json(:root=>"foos", :only => :id).to_s.must_equal '{"foos":[{"id":1},{"id":1}]}'
|
|
257
|
+
ds.to_json(:root=>"bars", :only => :id).to_s.must_equal '{"bars":[{"id":1},{"id":1}]}'
|
|
261
258
|
end
|
|
262
259
|
|
|
263
260
|
it "should use an alias for an included asscociation to qualify an association" do
|
|
@@ -12,7 +12,7 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
12
12
|
meta_def(:columns){[:id, :name]}
|
|
13
13
|
lazy_attributes :name
|
|
14
14
|
meta_def(:columns){[:id]}
|
|
15
|
-
|
|
15
|
+
set_dataset dataset.with_fetch(proc do |sql|
|
|
16
16
|
if sql !~ /WHERE/
|
|
17
17
|
if sql =~ /name/
|
|
18
18
|
[{:id=>1, :name=>'1'}, {:id=>2, :name=>'2'}]
|
|
@@ -32,7 +32,7 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
-
end
|
|
35
|
+
end)
|
|
36
36
|
end
|
|
37
37
|
@c = ::LazyAttributesModel
|
|
38
38
|
@ds = LazyAttributesModel.dataset
|
|
@@ -108,7 +108,7 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
108
108
|
it "should not lazily load the attribute for a single model object if it is a new record" do
|
|
109
109
|
m = @c.new
|
|
110
110
|
m.values.must_equal({})
|
|
111
|
-
m.name.
|
|
111
|
+
m.name.must_be_nil
|
|
112
112
|
@db.sqls.must_equal []
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -148,7 +148,7 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
|
148
148
|
|
|
149
149
|
it "should work with the serialization plugin" do
|
|
150
150
|
@c.plugin :serialization, :yaml, :name
|
|
151
|
-
@c.
|
|
151
|
+
@ds = @c.dataset = @ds.with_fetch([[{:id=>1}, {:id=>2}], [{:id=>1, :name=>"--- 3\n"}, {:id=>2, :name=>"--- 6\n"}], [{:id=>1}], [{:name=>"--- 3\n"}]])
|
|
152
152
|
ms = @ds.all
|
|
153
153
|
ms.map{|m| m.values}.must_equal [{:id=>1}, {:id=>2}]
|
|
154
154
|
ms.map{|m| m.name}.must_equal [3,6]
|
|
@@ -56,7 +56,7 @@ describe "List plugin" do
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it "should be able to access the scope proc as a class attribute" do
|
|
59
|
-
@c.scope_proc.
|
|
59
|
+
@c.scope_proc.must_be_nil
|
|
60
60
|
@sc.scope_proc[@sc.new(:scope_id=>4)].sql.must_equal 'SELECT * FROM items WHERE (scope_id = 4) ORDER BY scope_id, position'
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -67,17 +67,16 @@ describe "List plugin" do
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
it "should have at_position return the model object at the given position" do
|
|
70
|
-
@c.dataset
|
|
70
|
+
@c.dataset = @c.dataset.with_fetch(:id=>1, :position=>1)
|
|
71
71
|
@o.at_position(10).must_equal @c.load(:id=>1, :position=>1)
|
|
72
|
-
@sc.dataset
|
|
72
|
+
@sc.dataset = @sc.dataset.with_fetch(:id=>2, :position=>2, :scope_id=>5)
|
|
73
73
|
@so.at_position(20).must_equal @sc.load(:id=>2, :position=>2, :scope_id=>5)
|
|
74
74
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 10) ORDER BY position LIMIT 1",
|
|
75
75
|
"SELECT * FROM items WHERE ((scope_id = 5) AND (position = 20)) ORDER BY scope_id, position LIMIT 1"]
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
it "should have position field set to max+1 when creating if not already set" do
|
|
79
|
-
@c.
|
|
80
|
-
@c.instance_dataset.autoid = @c.dataset.autoid = 1
|
|
79
|
+
@c.dataset = @c.dataset.with_autoid(1).with_fetch([[{:pos=>nil}], [{:id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :position=>2}]])
|
|
81
80
|
@c.create.values.must_equal(:id=>1, :position=>1)
|
|
82
81
|
@c.create.values.must_equal(:id=>2, :position=>2)
|
|
83
82
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
@@ -89,8 +88,7 @@ describe "List plugin" do
|
|
|
89
88
|
end
|
|
90
89
|
|
|
91
90
|
it "should have position field set to max+1 in scope when creating if not already set" do
|
|
92
|
-
@sc.
|
|
93
|
-
@sc.instance_dataset.autoid = @sc.dataset.autoid = 1
|
|
91
|
+
@sc.dataset = @sc.dataset.with_autoid(1).with_fetch([[{:pos=>nil}], [{:id=>1, :scope_id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :scope_id=>1, :position=>2}], [{:pos=>nil}], [{:id=>3, :scope_id=>2, :position=>1}]])
|
|
94
92
|
@sc.create(:scope_id=>1).values.must_equal(:id=>1, :scope_id=>1, :position=>1)
|
|
95
93
|
@sc.create(:scope_id=>1).values.must_equal(:id=>2, :scope_id=>1, :position=>2)
|
|
96
94
|
@sc.create(:scope_id=>2).values.must_equal(:id=>3, :scope_id=>2, :position=>1)
|
|
@@ -112,9 +110,9 @@ describe "List plugin" do
|
|
|
112
110
|
end
|
|
113
111
|
|
|
114
112
|
it "should have last_position return the last position in the list" do
|
|
115
|
-
@c.dataset
|
|
113
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
116
114
|
@o.last_position.must_equal 10
|
|
117
|
-
@sc.dataset
|
|
115
|
+
@sc.dataset = @sc.dataset.with_fetch(:max=>20)
|
|
118
116
|
@so.last_position.must_equal 20
|
|
119
117
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
120
118
|
"SELECT max(position) AS max FROM items WHERE (scope_id = 5) LIMIT 1"]
|
|
@@ -129,7 +127,7 @@ describe "List plugin" do
|
|
|
129
127
|
end
|
|
130
128
|
|
|
131
129
|
it "should have move_down without an argument move down a single position" do
|
|
132
|
-
@c.dataset
|
|
130
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
133
131
|
@o.move_down.must_equal @o
|
|
134
132
|
@o.position.must_equal 4
|
|
135
133
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
@@ -138,7 +136,7 @@ describe "List plugin" do
|
|
|
138
136
|
end
|
|
139
137
|
|
|
140
138
|
it "should have move_down with an argument move down the given number of positions" do
|
|
141
|
-
@c.dataset
|
|
139
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
142
140
|
@o.move_down(3).must_equal @o
|
|
143
141
|
@o.position.must_equal 6
|
|
144
142
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
@@ -156,7 +154,7 @@ describe "List plugin" do
|
|
|
156
154
|
it "should have move_to handle out of range targets" do
|
|
157
155
|
@o.move_to(0)
|
|
158
156
|
@o.position.must_equal 1
|
|
159
|
-
@c.dataset
|
|
157
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
160
158
|
@o.move_to(11)
|
|
161
159
|
@o.position.must_equal 10
|
|
162
160
|
end
|
|
@@ -183,13 +181,13 @@ describe "List plugin" do
|
|
|
183
181
|
end
|
|
184
182
|
|
|
185
183
|
it "should have move to shift entries correctly between current and target if moving down" do
|
|
186
|
-
@c.dataset
|
|
184
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
187
185
|
@o.move_to(4)
|
|
188
186
|
@db.sqls[1].must_equal "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 4))"
|
|
189
187
|
end
|
|
190
188
|
|
|
191
189
|
it "should have move_to_bottom move the item to the last position" do
|
|
192
|
-
@c.dataset
|
|
190
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
193
191
|
@o.move_to_bottom
|
|
194
192
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
195
193
|
"UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 10))",
|
|
@@ -217,7 +215,7 @@ describe "List plugin" do
|
|
|
217
215
|
end
|
|
218
216
|
|
|
219
217
|
it "should have move_up with a negative argument move down the given number of positions" do
|
|
220
|
-
@c.dataset
|
|
218
|
+
@c.dataset = @c.dataset.with_fetch(:max=>10)
|
|
221
219
|
@o.move_up(-1).must_equal @o
|
|
222
220
|
@o.position.must_equal 4
|
|
223
221
|
@db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
|
|
@@ -226,19 +224,19 @@ describe "List plugin" do
|
|
|
226
224
|
end
|
|
227
225
|
|
|
228
226
|
it "should have next return the next entry in the list if not given an argument" do
|
|
229
|
-
@c.dataset
|
|
227
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>4)
|
|
230
228
|
@o.next.must_equal @c.load(:id=>9, :position=>4)
|
|
231
229
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
|
|
232
230
|
end
|
|
233
231
|
|
|
234
232
|
it "should have next return the entry the given number of positions below the instance if given an argument" do
|
|
235
|
-
@c.dataset
|
|
233
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>5)
|
|
236
234
|
@o.next(2).must_equal @c.load(:id=>9, :position=>5)
|
|
237
235
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 5) ORDER BY position LIMIT 1"]
|
|
238
236
|
end
|
|
239
237
|
|
|
240
238
|
it "should have next return a previous entry if given a negative argument" do
|
|
241
|
-
@c.dataset
|
|
239
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>2)
|
|
242
240
|
@o.next(-1).must_equal @c.load(:id=>9, :position=>2)
|
|
243
241
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
|
|
244
242
|
end
|
|
@@ -248,19 +246,19 @@ describe "List plugin" do
|
|
|
248
246
|
end
|
|
249
247
|
|
|
250
248
|
it "should have prev return the previous entry in the list if not given an argument" do
|
|
251
|
-
@c.dataset
|
|
249
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>2)
|
|
252
250
|
@o.prev.must_equal @c.load(:id=>9, :position=>2)
|
|
253
251
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
|
|
254
252
|
end
|
|
255
253
|
|
|
256
254
|
it "should have prev return the entry the given number of positions above the instance if given an argument" do
|
|
257
|
-
@c.dataset
|
|
255
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>1)
|
|
258
256
|
@o.prev(2).must_equal @c.load(:id=>9, :position=>1)
|
|
259
257
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 1) ORDER BY position LIMIT 1"]
|
|
260
258
|
end
|
|
261
259
|
|
|
262
260
|
it "should have prev return a following entry if given a negative argument" do
|
|
263
|
-
@c.dataset
|
|
261
|
+
@c.dataset = @c.dataset.with_fetch(:id=>9, :position=>4)
|
|
264
262
|
@o.prev(-1).must_equal @c.load(:id=>9, :position=>4)
|
|
265
263
|
@db.sqls.must_equal ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
|
|
266
264
|
end
|
|
@@ -12,8 +12,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
12
12
|
end
|
|
13
13
|
@c1 = Artist
|
|
14
14
|
@c2 = Tag
|
|
15
|
-
@dataset = @c2.dataset
|
|
16
|
-
@dataset._fetch = {:id=>1}
|
|
15
|
+
@dataset = @c2.dataset = @c2.dataset.with_fetch(:id=>1)
|
|
17
16
|
DB.reset
|
|
18
17
|
end
|
|
19
18
|
after do
|
|
@@ -50,8 +49,8 @@ describe Sequel::Model, "many_through_many" do
|
|
|
50
49
|
|
|
51
50
|
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
|
52
51
|
@c1.send(:define_method, :id3){id*3}
|
|
53
|
-
@c1.dataset
|
|
54
|
-
@c2.dataset
|
|
52
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
53
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>3)
|
|
55
54
|
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
|
|
56
55
|
a = @c1.eager(:tags).all
|
|
57
56
|
a.must_equal [@c1.load(:id => 1)]
|
|
@@ -61,8 +60,8 @@ describe Sequel::Model, "many_through_many" do
|
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
|
64
|
-
@c1.dataset
|
|
65
|
-
@c2.dataset
|
|
63
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
64
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
66
65
|
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
|
|
67
66
|
a = @c1.eager(:tags).all
|
|
68
67
|
a.must_equal [@c1.load(:id => 1)]
|
|
@@ -74,12 +73,13 @@ describe Sequel::Model, "many_through_many" do
|
|
|
74
73
|
@c1.many_through_many :tags, :through=>[[:myschema__albums_artists, :artist_id, :album_id], [:myschema__albums, :id, :id], [:myschema__albums_tags, :album_id, :tag_id]]
|
|
75
74
|
@c1.load(:id=>1).tags_dataset.sql.must_equal "SELECT tags.* FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id = 1)"
|
|
76
75
|
|
|
77
|
-
@c1.dataset
|
|
78
|
-
@c2.dataset
|
|
76
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
77
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
79
78
|
a = @c1.eager(:tags).all
|
|
80
79
|
a.must_equal [@c1.load(:id => 1)]
|
|
81
80
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, myschema.albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id IN (1))"]
|
|
82
81
|
|
|
82
|
+
Tag.dataset.columns(:id, :h1, :h2)
|
|
83
83
|
@c1.eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id, tags.h1, tags.h2 FROM artists LEFT OUTER JOIN myschema.albums_artists AS albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN myschema.albums AS albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN myschema.albums_tags AS albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)'
|
|
84
84
|
end
|
|
85
85
|
|
|
@@ -200,25 +200,25 @@ describe Sequel::Model, "many_through_many" do
|
|
|
200
200
|
end
|
|
201
201
|
|
|
202
202
|
it "should allowing filtering by many_through_many associations with :limit" do
|
|
203
|
-
|
|
203
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
|
|
204
204
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
|
|
205
205
|
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.must_equal 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))'
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
it "should allowing filtering by many_through_many associations with :limit and composite keys" do
|
|
209
|
-
|
|
209
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
|
|
210
210
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :limit=>10
|
|
211
211
|
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2))) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))'
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
it "should allowing filtering by many_through_many associations with :limit and :conditions" do
|
|
215
|
-
|
|
215
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
|
|
216
216
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :limit=>10
|
|
217
217
|
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.must_equal "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))"
|
|
218
218
|
end
|
|
219
219
|
|
|
220
220
|
it "should allowing filtering by many_through_many associations with :limit and :conditions and composite keys" do
|
|
221
|
-
|
|
221
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
|
|
222
222
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :limit=>10
|
|
223
223
|
@c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))"
|
|
224
224
|
end
|
|
@@ -419,7 +419,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
419
419
|
it "should populate cache when accessed" do
|
|
420
420
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
421
421
|
n = @c1.load(:id => 1234)
|
|
422
|
-
n.associations[:tags].
|
|
422
|
+
n.associations[:tags].must_be_nil
|
|
423
423
|
DB.sqls.must_equal []
|
|
424
424
|
n.tags.must_equal [@c2.load(:id=>1)]
|
|
425
425
|
DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234)']
|
|
@@ -465,7 +465,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
465
465
|
v.each{|x| model::Foo << x.pk * 20}
|
|
466
466
|
end
|
|
467
467
|
end
|
|
468
|
-
@c2.dataset
|
|
468
|
+
@c2.dataset = @c2.dataset.with_fetch([{:id=>20}, {:id=>30}])
|
|
469
469
|
p = @c1.load(:id=>10, :parent_id=>20)
|
|
470
470
|
p.tags
|
|
471
471
|
h.must_equal [400, 600]
|
|
@@ -474,7 +474,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
474
474
|
|
|
475
475
|
it "should support a :uniq option that removes duplicates from the association" do
|
|
476
476
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :uniq=>true
|
|
477
|
-
@c2.dataset
|
|
477
|
+
@c2.dataset = @c2.dataset.with_fetch([{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}])
|
|
478
478
|
@c1.load(:id=>10).tags.must_equal [@c2.load(:id=>20), @c2.load(:id=>30)]
|
|
479
479
|
end
|
|
480
480
|
end
|
|
@@ -514,7 +514,7 @@ describe 'Sequel::Plugins::ManyThroughMany::ManyThroughManyAssociationReflection
|
|
|
514
514
|
end
|
|
515
515
|
|
|
516
516
|
it "#reciprocal should be nil" do
|
|
517
|
-
@ar.reciprocal.
|
|
517
|
+
@ar.reciprocal.must_be_nil
|
|
518
518
|
end
|
|
519
519
|
end
|
|
520
520
|
|
|
@@ -535,7 +535,7 @@ describe "many_through_many eager loading methods" do
|
|
|
535
535
|
end
|
|
536
536
|
class ::Track < Sequel::Model
|
|
537
537
|
end
|
|
538
|
-
Artist.dataset
|
|
538
|
+
Artist.dataset = Artist.dataset.with_fetch(proc do |sql|
|
|
539
539
|
h = {:id => 1}
|
|
540
540
|
if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
|
|
541
541
|
h[:tags_id] = 2
|
|
@@ -545,9 +545,10 @@ describe "many_through_many eager loading methods" do
|
|
|
545
545
|
h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
|
|
546
546
|
end
|
|
547
547
|
h
|
|
548
|
-
end
|
|
548
|
+
end)
|
|
549
|
+
Artist.dataset.columns(:id)
|
|
549
550
|
|
|
550
|
-
Tag.dataset
|
|
551
|
+
Tag.dataset = Tag.dataset.with_fetch(proc do |sql|
|
|
551
552
|
h = {:id => 2}
|
|
552
553
|
if sql =~ /albums_artists.artist_id IN \(([18])\)/
|
|
553
554
|
h[:x_foreign_key_x] = $1.to_i
|
|
@@ -556,19 +557,19 @@ describe "many_through_many eager loading methods" do
|
|
|
556
557
|
end
|
|
557
558
|
h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
|
|
558
559
|
h
|
|
559
|
-
end
|
|
560
|
+
end)
|
|
560
561
|
|
|
561
|
-
Album.dataset
|
|
562
|
+
Album.dataset = Album.dataset.with_fetch(proc do |sql|
|
|
562
563
|
h = {:id => 3}
|
|
563
564
|
h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
|
|
564
565
|
h
|
|
565
|
-
end
|
|
566
|
+
end)
|
|
566
567
|
|
|
567
|
-
Track.dataset
|
|
568
|
+
Track.dataset = Track.dataset.with_fetch(proc do |sql|
|
|
568
569
|
h = {:id => 4}
|
|
569
570
|
h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
|
|
570
571
|
h
|
|
571
|
-
end
|
|
572
|
+
end)
|
|
572
573
|
|
|
573
574
|
@c1 = Artist
|
|
574
575
|
DB.reset
|
|
@@ -654,12 +655,7 @@ describe "many_through_many eager loading methods" do
|
|
|
654
655
|
end
|
|
655
656
|
|
|
656
657
|
it "should respect :eager_graph when lazily loading an association" do
|
|
657
|
-
Tag.dataset
|
|
658
|
-
Tag.dataset.extend(Module.new {
|
|
659
|
-
def columns
|
|
660
|
-
[:id]
|
|
661
|
-
end
|
|
662
|
-
})
|
|
658
|
+
Tag.dataset = Tag.dataset.with_fetch(:id=>2, :tracks_id=>4).with_extend{def columns; [:id] end}
|
|
663
659
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
|
|
664
660
|
a = @c1.load(:id=>1)
|
|
665
661
|
a.tags
|
|
@@ -711,7 +707,7 @@ describe "many_through_many eager loading methods" do
|
|
|
711
707
|
|
|
712
708
|
it "should respect the :limit option on a many_through_many association" do
|
|
713
709
|
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2
|
|
714
|
-
Tag.dataset
|
|
710
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}])
|
|
715
711
|
a = @c1.eager(:first_two_tags).all
|
|
716
712
|
a.must_equal [@c1.load(:id=>1)]
|
|
717
713
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -720,7 +716,7 @@ describe "many_through_many eager loading methods" do
|
|
|
720
716
|
DB.sqls.length.must_equal 0
|
|
721
717
|
|
|
722
718
|
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[1,1]
|
|
723
|
-
Tag.dataset
|
|
719
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}])
|
|
724
720
|
a = @c1.eager(:first_two_tags).all
|
|
725
721
|
a.must_equal [@c1.load(:id=>1)]
|
|
726
722
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -729,7 +725,7 @@ describe "many_through_many eager loading methods" do
|
|
|
729
725
|
DB.sqls.length.must_equal 0
|
|
730
726
|
|
|
731
727
|
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
|
|
732
|
-
Tag.dataset
|
|
728
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}])
|
|
733
729
|
a = @c1.eager(:first_two_tags).all
|
|
734
730
|
a.must_equal [@c1.load(:id=>1)]
|
|
735
731
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -740,7 +736,7 @@ describe "many_through_many eager loading methods" do
|
|
|
740
736
|
|
|
741
737
|
it "should respect the :limit option on a many_through_many association using a :ruby strategy" do
|
|
742
738
|
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:ruby
|
|
743
|
-
Tag.dataset
|
|
739
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}])
|
|
744
740
|
a = @c1.eager(:first_two_tags).all
|
|
745
741
|
a.must_equal [@c1.load(:id=>1)]
|
|
746
742
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -766,9 +762,8 @@ describe "many_through_many eager loading methods" do
|
|
|
766
762
|
end
|
|
767
763
|
|
|
768
764
|
it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
|
|
769
|
-
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
770
765
|
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
|
|
771
|
-
Tag.dataset
|
|
766
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]).with_extend{def supports_window_functions?; true end}
|
|
772
767
|
a = @c1.eager(:first_two_tags).all
|
|
773
768
|
a.must_equal [@c1.load(:id=>1)]
|
|
774
769
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -794,12 +789,11 @@ describe "many_through_many eager loading methods" do
|
|
|
794
789
|
end
|
|
795
790
|
|
|
796
791
|
it "should respect the :limit option on a many_through_many association with composite primary keys on the main table" do
|
|
797
|
-
|
|
792
|
+
@c1.dataset = @c1.dataset.with_fetch([{:id1=>1, :id2=>2}])
|
|
793
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
|
|
798
794
|
@c1.set_primary_key([:id1, :id2])
|
|
799
795
|
@c1.columns :id1, :id2
|
|
800
796
|
@c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name
|
|
801
|
-
@c1.dataset._fetch = [{:id1=>1, :id2=>2}]
|
|
802
|
-
Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]
|
|
803
797
|
a = @c1.eager(:first_two_tags).all
|
|
804
798
|
a.must_equal [@c1.load(:id1=>1, :id2=>2)]
|
|
805
799
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -817,12 +811,11 @@ describe "many_through_many eager loading methods" do
|
|
|
817
811
|
end
|
|
818
812
|
|
|
819
813
|
it "should respect the :limit option on a many_through_many association with composite primary keys on the main table using a :window_function strategy" do
|
|
820
|
-
|
|
814
|
+
@c1.dataset = @c1.dataset.with_fetch([{:id1=>1, :id2=>2}])
|
|
815
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
|
|
821
816
|
@c1.set_primary_key([:id1, :id2])
|
|
822
817
|
@c1.columns :id1, :id2
|
|
823
818
|
@c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
|
|
824
|
-
@c1.dataset._fetch = [{:id1=>1, :id2=>2}]
|
|
825
|
-
Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]
|
|
826
819
|
a = @c1.eager(:first_two_tags).all
|
|
827
820
|
a.must_equal [@c1.load(:id1=>1, :id2=>2)]
|
|
828
821
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -857,8 +850,7 @@ describe "many_through_many eager loading methods" do
|
|
|
857
850
|
|
|
858
851
|
it "should respect many_through_many association's :left_primary_key and :right_primary_key options" do
|
|
859
852
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
860
|
-
@c1.dataset
|
|
861
|
-
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
853
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
|
|
862
854
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
|
863
855
|
a = @c1.eager(:tags).all
|
|
864
856
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
@@ -870,8 +862,7 @@ describe "many_through_many eager loading methods" do
|
|
|
870
862
|
|
|
871
863
|
it "should handle composite keys" do
|
|
872
864
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
873
|
-
@c1.dataset
|
|
874
|
-
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
865
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
|
|
875
866
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
|
876
867
|
a = @c1.eager(:tags).all
|
|
877
868
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
@@ -912,12 +903,12 @@ describe "many_through_many eager loading methods" do
|
|
|
912
903
|
end
|
|
913
904
|
|
|
914
905
|
it "should eagerly graph a single many_through_many association using the :window_function strategy" do
|
|
915
|
-
|
|
916
|
-
|
|
906
|
+
Tag.dataset = Tag.dataset.with_extend do
|
|
907
|
+
def supports_window_functions?; true end
|
|
908
|
+
def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
|
909
|
+
end
|
|
917
910
|
@c1.many_through_many :tags, :clone=>:tags, :limit=>2
|
|
918
|
-
|
|
919
|
-
ds._fetch = {:id=>1, :tags_id=>2}
|
|
920
|
-
a = ds.all
|
|
911
|
+
a = @c1.eager_graph_with_options(:tags, :limit_strategy=>true).with_fetch(:id=>1, :tags_id=>2).all
|
|
921
912
|
a.must_equal [@c1.load(:id=>1)]
|
|
922
913
|
DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS tags ON (tags.x_foreign_key_x = artists.id)']
|
|
923
914
|
a.first.tags.must_equal [Tag.load(:id=>2)]
|
|
@@ -955,10 +946,7 @@ describe "many_through_many eager loading methods" do
|
|
|
955
946
|
end
|
|
956
947
|
|
|
957
948
|
it "eager graphing should eliminate duplicates caused by cartesian products" do
|
|
958
|
-
|
|
959
|
-
# Assume artist has 2 albums each with 2 tags
|
|
960
|
-
ds._fetch = [{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]
|
|
961
|
-
a = ds.all
|
|
949
|
+
a = @c1.eager_graph(:tags).with_fetch([{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]).all
|
|
962
950
|
a.must_equal [@c1.load(:id=>1)]
|
|
963
951
|
DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
|
|
964
952
|
a.first.tags.must_equal [Tag.load(:id=>2), Tag.load(:id=>3)]
|
|
@@ -1001,9 +989,7 @@ describe "many_through_many eager loading methods" do
|
|
|
1001
989
|
end
|
|
1002
990
|
|
|
1003
991
|
it "should handle no associated records when eagerly graphing a single many_through_many association" do
|
|
1004
|
-
|
|
1005
|
-
ds._fetch = {:id=>1, :tags_id=>nil}
|
|
1006
|
-
a = ds.all
|
|
992
|
+
a = @c1.eager_graph(:tags).with_fetch(:id=>1, :tags_id=>nil).all
|
|
1007
993
|
a.must_equal [@c1.load(:id=>1)]
|
|
1008
994
|
DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
|
|
1009
995
|
a.first.tags.must_equal []
|
|
@@ -1011,9 +997,7 @@ describe "many_through_many eager loading methods" do
|
|
|
1011
997
|
end
|
|
1012
998
|
|
|
1013
999
|
it "should handle no associated records when eagerly graphing multiple many_through_many associations" do
|
|
1014
|
-
|
|
1015
|
-
ds._fetch = [{:id=>1, :tags_id=>nil, :albums_0_id=>3}, {:id=>1, :tags_id=>2, :albums_0_id=>nil}, {:id=>1, :tags_id=>5, :albums_0_id=>6}, {:id=>7, :tags_id=>nil, :albums_0_id=>nil}]
|
|
1016
|
-
a = ds.all
|
|
1000
|
+
a = @c1.eager_graph(:tags, :albums).with_fetch([{:id=>1, :tags_id=>nil, :albums_0_id=>3}, {:id=>1, :tags_id=>2, :albums_0_id=>nil}, {:id=>1, :tags_id=>5, :albums_0_id=>6}, {:id=>7, :tags_id=>nil, :albums_0_id=>nil}]).all
|
|
1017
1001
|
a.must_equal [@c1.load(:id=>1), @c1.load(:id=>7)]
|
|
1018
1002
|
DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id, albums_0.id AS albums_0_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id)']
|
|
1019
1003
|
a.first.tags.must_equal [Tag.load(:id=>2), Tag.load(:id=>5)]
|
|
@@ -1024,9 +1008,7 @@ describe "many_through_many eager loading methods" do
|
|
|
1024
1008
|
end
|
|
1025
1009
|
|
|
1026
1010
|
it "should handle missing associated records when cascading eager graphing for associations of associated models" do
|
|
1027
|
-
|
|
1028
|
-
ds._fetch = [{:id=>1, :tags_id=>2, :tracks_id=>4}, {:id=>1, :tags_id=>3, :tracks_id=>nil}, {:id=>2, :tags_id=>nil, :tracks_id=>nil}]
|
|
1029
|
-
a = ds.all
|
|
1011
|
+
a = @c1.eager_graph(:tags=>:tracks).with_fetch([{:id=>1, :tags_id=>2, :tracks_id=>4}, {:id=>1, :tags_id=>3, :tracks_id=>nil}, {:id=>2, :tags_id=>nil, :tracks_id=>nil}]).all
|
|
1030
1012
|
a.must_equal [@c1.load(:id=>1), @c1.load(:id=>2)]
|
|
1031
1013
|
DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id, tracks.id AS tracks_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums_0.id)']
|
|
1032
1014
|
a.last.tags.must_equal []
|
|
@@ -1039,11 +1021,9 @@ describe "many_through_many eager loading methods" do
|
|
|
1039
1021
|
|
|
1040
1022
|
it "eager graphing should respect :left_primary_key and :right_primary_key options" do
|
|
1041
1023
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
|
1042
|
-
@c1.dataset.
|
|
1043
|
-
Tag.dataset.
|
|
1044
|
-
|
|
1045
|
-
ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
|
|
1046
|
-
a = ds.all
|
|
1024
|
+
@c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
|
|
1025
|
+
Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
|
|
1026
|
+
a = @c1.eager_graph(:tags).with_fetch(:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4).all
|
|
1047
1027
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
1048
1028
|
DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.tag_id = albums_tags.tag_id)']
|
|
1049
1029
|
a.first.tags.must_equal [Tag.load(:id=>2, :tag_id=>4)]
|
|
@@ -1052,11 +1032,9 @@ describe "many_through_many eager loading methods" do
|
|
|
1052
1032
|
|
|
1053
1033
|
it "eager graphing should respect composite keys" do
|
|
1054
1034
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:id, :tag_id], :left_primary_key=>[:id, :yyy]
|
|
1055
|
-
@c1.dataset.
|
|
1056
|
-
Tag.dataset.
|
|
1057
|
-
|
|
1058
|
-
ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
|
|
1059
|
-
a = ds.all
|
|
1035
|
+
@c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
|
|
1036
|
+
Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
|
|
1037
|
+
a = @c1.eager_graph(:tags).with_fetch(:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4).all
|
|
1060
1038
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
1061
1039
|
DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags ON ((tags.id = albums_tags.g1) AND (tags.tag_id = albums_tags.g2))']
|
|
1062
1040
|
a.first.tags.must_equal [Tag.load(:id=>2, :tag_id=>4)]
|
|
@@ -1065,9 +1043,7 @@ describe "many_through_many eager loading methods" do
|
|
|
1065
1043
|
|
|
1066
1044
|
it "should respect the association's :graph_select option" do
|
|
1067
1045
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
|
|
1068
|
-
|
|
1069
|
-
ds._fetch = {:id=>1, :b=>2}
|
|
1070
|
-
a = ds.all
|
|
1046
|
+
a = @c1.eager_graph(:tags).with_fetch(:id=>1, :b=>2).all
|
|
1071
1047
|
a.must_equal [@c1.load(:id=>1)]
|
|
1072
1048
|
DB.sqls.must_equal ['SELECT artists.id, tags.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
|
|
1073
1049
|
a.first.tags.must_equal [Tag.load(:b=>2)]
|
|
@@ -1216,8 +1192,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1216
1192
|
end
|
|
1217
1193
|
@c1 = Artist
|
|
1218
1194
|
@c2 = Tag
|
|
1219
|
-
@dataset = @c2.dataset
|
|
1220
|
-
@dataset._fetch = {:id=>1}
|
|
1195
|
+
@dataset = @c2.dataset = @c2.dataset.with_fetch(:id=>1)
|
|
1221
1196
|
DB.reset
|
|
1222
1197
|
end
|
|
1223
1198
|
after do
|
|
@@ -1227,8 +1202,8 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1227
1202
|
|
|
1228
1203
|
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
|
1229
1204
|
@c1.send(:define_method, :id3){id*3}
|
|
1230
|
-
@c1.dataset
|
|
1231
|
-
@c2.dataset
|
|
1205
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
1206
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>3)
|
|
1232
1207
|
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
|
|
1233
1208
|
a = @c1.eager(:tag).all
|
|
1234
1209
|
a.must_equal [@c1.load(:id => 1)]
|
|
@@ -1238,8 +1213,8 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1238
1213
|
end
|
|
1239
1214
|
|
|
1240
1215
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
|
1241
|
-
@c1.dataset
|
|
1242
|
-
@c2.dataset
|
|
1216
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1)
|
|
1217
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
|
|
1243
1218
|
@c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
|
|
1244
1219
|
a = @c1.eager(:tag).all
|
|
1245
1220
|
a.must_equal [@c1.load(:id => 1)]
|
|
@@ -1348,25 +1323,25 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1348
1323
|
end
|
|
1349
1324
|
|
|
1350
1325
|
it "should allowing filtering by one_through_many associations with :order" do
|
|
1351
|
-
|
|
1326
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
|
|
1352
1327
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:name
|
|
1353
1328
|
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.must_equal 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))'
|
|
1354
1329
|
end
|
|
1355
1330
|
|
|
1356
1331
|
it "should allowing filtering by one_through_many associations with :order and composite keys" do
|
|
1357
|
-
|
|
1332
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
|
|
1358
1333
|
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :order=>:name
|
|
1359
1334
|
@c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))'
|
|
1360
1335
|
end
|
|
1361
1336
|
|
|
1362
1337
|
it "should allowing filtering by one_through_many associations with :order and :conditions" do
|
|
1363
|
-
|
|
1338
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
|
|
1364
1339
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :order=>:name
|
|
1365
1340
|
@c1.filter(:tag=>@c2.load(:id=>1234)).sql.must_equal "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A') ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))"
|
|
1366
1341
|
end
|
|
1367
1342
|
|
|
1368
1343
|
it "should allowing filtering by one_through_many associations with :order and :conditions and composite keys" do
|
|
1369
|
-
|
|
1344
|
+
@c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
|
|
1370
1345
|
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :order=>:name
|
|
1371
1346
|
@c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A') ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))"
|
|
1372
1347
|
end
|
|
@@ -1562,7 +1537,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1562
1537
|
it "should populate cache when accessed" do
|
|
1563
1538
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
1564
1539
|
n = @c1.load(:id => 1234)
|
|
1565
|
-
n.associations[:tag].
|
|
1540
|
+
n.associations[:tag].must_be_nil
|
|
1566
1541
|
DB.sqls.must_equal []
|
|
1567
1542
|
n.tag.must_equal @c2.load(:id=>1)
|
|
1568
1543
|
DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
|
|
@@ -1574,7 +1549,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1574
1549
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
1575
1550
|
n = @c1.load(:id => 1234)
|
|
1576
1551
|
n.associations[:tag] = nil
|
|
1577
|
-
n.tag.
|
|
1552
|
+
n.tag.must_be_nil
|
|
1578
1553
|
DB.sqls.must_equal []
|
|
1579
1554
|
end
|
|
1580
1555
|
|
|
@@ -1608,7 +1583,7 @@ describe Sequel::Model, "one_through_many" do
|
|
|
1608
1583
|
model::Foo << v.pk * 20
|
|
1609
1584
|
end
|
|
1610
1585
|
end
|
|
1611
|
-
@c2.dataset
|
|
1586
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>20)
|
|
1612
1587
|
p = @c1.load(:id=>10, :parent_id=>20)
|
|
1613
1588
|
p.tag
|
|
1614
1589
|
h.must_equal [400]
|
|
@@ -1633,7 +1608,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1633
1608
|
end
|
|
1634
1609
|
class ::Track < Sequel::Model
|
|
1635
1610
|
end
|
|
1636
|
-
Artist.dataset
|
|
1611
|
+
Artist.dataset = Artist.dataset.with_fetch(proc do |sql|
|
|
1637
1612
|
h = {:id => 1}
|
|
1638
1613
|
if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
|
|
1639
1614
|
h[:tag_id] = 2
|
|
@@ -1643,9 +1618,10 @@ describe "one_through_many eager loading methods" do
|
|
|
1643
1618
|
h[:artist_id] = 10 if sql =~ /artists_0\.id AS artist_id/
|
|
1644
1619
|
end
|
|
1645
1620
|
h
|
|
1646
|
-
end
|
|
1621
|
+
end)
|
|
1622
|
+
Artist.dataset.columns(:id)
|
|
1647
1623
|
|
|
1648
|
-
Tag.dataset
|
|
1624
|
+
Tag.dataset = Tag.dataset.with_fetch(proc do |sql|
|
|
1649
1625
|
h = {:id => 2}
|
|
1650
1626
|
if sql =~ /albums_artists.artist_id IN \(([18])\)/
|
|
1651
1627
|
h[:x_foreign_key_x] = $1.to_i
|
|
@@ -1654,19 +1630,19 @@ describe "one_through_many eager loading methods" do
|
|
|
1654
1630
|
end
|
|
1655
1631
|
h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
|
|
1656
1632
|
h
|
|
1657
|
-
end
|
|
1633
|
+
end)
|
|
1658
1634
|
|
|
1659
|
-
Album.dataset
|
|
1635
|
+
Album.dataset = Album.dataset.with_fetch(proc do |sql|
|
|
1660
1636
|
h = {:id => 3}
|
|
1661
1637
|
h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
|
|
1662
1638
|
h
|
|
1663
|
-
end
|
|
1639
|
+
end)
|
|
1664
1640
|
|
|
1665
|
-
Track.dataset
|
|
1641
|
+
Track.dataset = Track.dataset.with_fetch(proc do |sql|
|
|
1666
1642
|
h = {:id => 4}
|
|
1667
1643
|
h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
|
|
1668
1644
|
h
|
|
1669
|
-
end
|
|
1645
|
+
end)
|
|
1670
1646
|
|
|
1671
1647
|
@c1 = Artist
|
|
1672
1648
|
DB.reset
|
|
@@ -1752,12 +1728,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1752
1728
|
end
|
|
1753
1729
|
|
|
1754
1730
|
it "should respect :eager_graph when lazily loading an association" do
|
|
1755
|
-
Tag.dataset
|
|
1756
|
-
Tag.dataset.extend(Module.new {
|
|
1757
|
-
def columns
|
|
1758
|
-
[:id]
|
|
1759
|
-
end
|
|
1760
|
-
})
|
|
1731
|
+
Tag.dataset = Tag.dataset.with_fetch(:id=>2, :track_id=>4).with_extend{def columns; [:id] end}
|
|
1761
1732
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:track
|
|
1762
1733
|
a = @c1.load(:id=>1)
|
|
1763
1734
|
a.tag
|
|
@@ -1809,7 +1780,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1809
1780
|
|
|
1810
1781
|
it "should respect the :limit option on a one_through_many association" do
|
|
1811
1782
|
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
|
|
1812
|
-
Tag.dataset
|
|
1783
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}])
|
|
1813
1784
|
a = @c1.eager(:second_tag).all
|
|
1814
1785
|
a.must_equal [@c1.load(:id=>1)]
|
|
1815
1786
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -1820,7 +1791,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1820
1791
|
|
|
1821
1792
|
it "should respect the :limit option on a one_through_many association using the :ruby strategy" do
|
|
1822
1793
|
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :eager_limit_strategy=>:ruby
|
|
1823
|
-
Tag.dataset
|
|
1794
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}, {:x_foreign_key_x=>1, :id=>6}])
|
|
1824
1795
|
a = @c1.eager(:second_tag).all
|
|
1825
1796
|
a.must_equal [@c1.load(:id=>1)]
|
|
1826
1797
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -1830,9 +1801,8 @@ describe "one_through_many eager loading methods" do
|
|
|
1830
1801
|
end
|
|
1831
1802
|
|
|
1832
1803
|
it "should eagerly load a single one_through_many association using the :distinct_on strategy" do
|
|
1833
|
-
Tag.dataset.meta_def(:supports_distinct_on?){true}
|
|
1834
1804
|
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :order=>:name, :eager_limit_strategy=>:distinct_on
|
|
1835
|
-
Tag.dataset
|
|
1805
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}]).with_extend{def supports_distinct_on?; true end}
|
|
1836
1806
|
a = @c1.eager(:second_tag).all
|
|
1837
1807
|
a.must_equal [@c1.load(:id=>1)]
|
|
1838
1808
|
DB.sqls.must_equal ['SELECT * FROM artists', "SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id IN (1)) ORDER BY albums_artists.artist_id, name"]
|
|
@@ -1841,9 +1811,8 @@ describe "one_through_many eager loading methods" do
|
|
|
1841
1811
|
end
|
|
1842
1812
|
|
|
1843
1813
|
it "should eagerly load a single one_through_many association using the :window_function strategy" do
|
|
1844
|
-
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
1845
1814
|
@c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
|
|
1846
|
-
Tag.dataset
|
|
1815
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}]).with_extend{def supports_window_functions?; true end}
|
|
1847
1816
|
a = @c1.eager(:second_tag).all
|
|
1848
1817
|
a.must_equal [@c1.load(:id=>1)]
|
|
1849
1818
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
@@ -1853,15 +1822,12 @@ describe "one_through_many eager loading methods" do
|
|
|
1853
1822
|
end
|
|
1854
1823
|
|
|
1855
1824
|
it "should respect the :limit option on a one_through_many association with composite primary keys on the main table" do
|
|
1856
|
-
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
1857
1825
|
@c1.set_primary_key([:id1, :id2])
|
|
1858
1826
|
@c1.columns :id1, :id2
|
|
1859
1827
|
|
|
1860
1828
|
@c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
|
|
1864
|
-
a = ds.all
|
|
1829
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]).with_extend{def supports_window_functions?; true end}
|
|
1830
|
+
a = @c1.eager(:second_tag).with_fetch(:id1=>1, :id2=>2).all
|
|
1865
1831
|
a.must_equal [@c1.load(:id1=>1, :id2=>2)]
|
|
1866
1832
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
1867
1833
|
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((1 = albums_artists.artist_id1) AND (2 = albums_artists.artist_id2)) ORDER BY name LIMIT 1 OFFSET 1) AS t1']
|
|
@@ -1870,15 +1836,12 @@ describe "one_through_many eager loading methods" do
|
|
|
1870
1836
|
end
|
|
1871
1837
|
|
|
1872
1838
|
it "should respect the :limit option on a one_through_many association with composite primary keys on the main table using a :window_function strategy" do
|
|
1873
|
-
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
1874
1839
|
@c1.set_primary_key([:id1, :id2])
|
|
1875
1840
|
@c1.columns :id1, :id2
|
|
1876
1841
|
|
|
1877
1842
|
@c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
|
|
1881
|
-
a = ds.all
|
|
1843
|
+
Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]).with_extend{def supports_window_functions?; true end}
|
|
1844
|
+
a = @c1.eager(:second_tag).with_fetch(:id1=>1, :id2=>2).all
|
|
1882
1845
|
a.must_equal [@c1.load(:id1=>1, :id2=>2)]
|
|
1883
1846
|
DB.sqls.must_equal ['SELECT * FROM artists',
|
|
1884
1847
|
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2)))) AS t1 WHERE (x_sequel_row_number_x = 2)']
|
|
@@ -1904,8 +1867,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1904
1867
|
|
|
1905
1868
|
it "should respect one_through_many association's :left_primary_key and :right_primary_key options" do
|
|
1906
1869
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
1907
|
-
@c1.dataset
|
|
1908
|
-
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
1870
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
|
|
1909
1871
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
|
1910
1872
|
a = @c1.eager(:tag).all
|
|
1911
1873
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
@@ -1917,8 +1879,7 @@ describe "one_through_many eager loading methods" do
|
|
|
1917
1879
|
|
|
1918
1880
|
it "should handle composite keys" do
|
|
1919
1881
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
1920
|
-
@c1.dataset
|
|
1921
|
-
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
1882
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
|
|
1922
1883
|
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
|
1923
1884
|
a = @c1.eager(:tag).all
|
|
1924
1885
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
@@ -1951,10 +1912,8 @@ describe "one_through_many eager loading methods" do
|
|
|
1951
1912
|
end
|
|
1952
1913
|
|
|
1953
1914
|
it "should eagerly graph a single one_through_many association using the :distinct_on strategy" do
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
ds._fetch = {:id=>1, :tag_id=>2}
|
|
1957
|
-
a = ds.all
|
|
1915
|
+
Tag.dataset = Tag.dataset.with_extend{def supports_distinct_on?; true end}
|
|
1916
|
+
a = @c1.eager_graph_with_options(:tag, :limit_strategy=>true).with_fetch(:id=>1, :tag_id=>2).all
|
|
1958
1917
|
a.must_equal [@c1.load(:id=>1)]
|
|
1959
1918
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id) AS tag ON (tag.x_foreign_key_x = artists.id)']
|
|
1960
1919
|
a.first.tag.must_equal Tag.load(:id=>2)
|
|
@@ -1962,11 +1921,11 @@ describe "one_through_many eager loading methods" do
|
|
|
1962
1921
|
end
|
|
1963
1922
|
|
|
1964
1923
|
it "should eagerly graph a single one_through_many association using the :window_function strategy" do
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
a =
|
|
1924
|
+
Tag.dataset = Tag.dataset.with_extend do
|
|
1925
|
+
def supports_window_functions?; true end
|
|
1926
|
+
def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
|
|
1927
|
+
end
|
|
1928
|
+
a = @c1.eager_graph_with_options(:tag, :limit_strategy=>true).with_fetch(:id=>1, :tag_id=>2).all
|
|
1970
1929
|
a.must_equal [@c1.load(:id=>1)]
|
|
1971
1930
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x = 1)) AS tag ON (tag.x_foreign_key_x = artists.id)']
|
|
1972
1931
|
a.first.tag.must_equal Tag.load(:id=>2)
|
|
@@ -2014,9 +1973,7 @@ describe "one_through_many eager loading methods" do
|
|
|
2014
1973
|
end
|
|
2015
1974
|
|
|
2016
1975
|
it "should eager graph a self_referential association" do
|
|
2017
|
-
|
|
2018
|
-
ds._fetch = {:id=>1, :tag_id=>2, :artist_id=>10}
|
|
2019
|
-
a = ds.all
|
|
1976
|
+
a = @c1.eager_graph(:tag, :artist).with_fetch(:id=>1, :tag_id=>2, :artist_id=>10).all
|
|
2020
1977
|
a.must_equal [@c1.load(:id=>1)]
|
|
2021
1978
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, artist.id AS artist_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_0.id) LEFT OUTER JOIN artists AS artist ON (artist.id = albums_artists_1.artist_id)']
|
|
2022
1979
|
a = a.first
|
|
@@ -2037,48 +1994,40 @@ describe "one_through_many eager loading methods" do
|
|
|
2037
1994
|
end
|
|
2038
1995
|
|
|
2039
1996
|
it "should handle no associated records when eagerly graphing a single one_through_many association" do
|
|
2040
|
-
|
|
2041
|
-
ds._fetch = {:id=>1, :tag_id=>nil}
|
|
2042
|
-
a = ds.all
|
|
1997
|
+
a = @c1.eager_graph(:tag).with_fetch(:id=>1, :tag_id=>nil).all
|
|
2043
1998
|
a.must_equal [@c1.load(:id=>1)]
|
|
2044
1999
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
|
|
2045
|
-
a.first.tag.
|
|
2000
|
+
a.first.tag.must_be_nil
|
|
2046
2001
|
DB.sqls.length.must_equal 0
|
|
2047
2002
|
end
|
|
2048
2003
|
|
|
2049
2004
|
it "should handle no associated records when eagerly graphing multiple one_through_many associations" do
|
|
2050
|
-
|
|
2051
|
-
ds._fetch = [{:id=>1, :tag_id=>5, :album_id=>6}, {:id=>7, :tag_id=>nil, :albums_0_id=>nil}]
|
|
2052
|
-
a = ds.all
|
|
2005
|
+
a = @c1.eager_graph(:tag, :album).with_fetch([{:id=>1, :tag_id=>5, :album_id=>6}, {:id=>7, :tag_id=>nil, :albums_0_id=>nil}]).all
|
|
2053
2006
|
a.must_equal [@c1.load(:id=>1), @c1.load(:id=>7)]
|
|
2054
2007
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, album.id AS album_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS album ON (album.id = albums_artists_0.album_id)']
|
|
2055
2008
|
a.first.tag.must_equal Tag.load(:id=>5)
|
|
2056
2009
|
a.first.album.must_equal Album.load(:id=>6)
|
|
2057
|
-
a.last.tag.
|
|
2058
|
-
a.last.album.
|
|
2010
|
+
a.last.tag.must_be_nil
|
|
2011
|
+
a.last.album.must_be_nil
|
|
2059
2012
|
DB.sqls.length.must_equal 0
|
|
2060
2013
|
end
|
|
2061
2014
|
|
|
2062
2015
|
it "should handle missing associated records when cascading eager graphing for associations of associated models" do
|
|
2063
|
-
|
|
2064
|
-
ds._fetch = [{:id=>1, :tag_id=>2, :track_id=>nil}, {:id=>2, :tag_id=>nil, :tracks_id=>nil}]
|
|
2065
|
-
a = ds.all
|
|
2016
|
+
a = @c1.eager_graph(:tag=>:track).with_fetch([{:id=>1, :tag_id=>2, :track_id=>nil}, {:id=>2, :tag_id=>nil, :tracks_id=>nil}]).all
|
|
2066
2017
|
a.must_equal [@c1.load(:id=>1), @c1.load(:id=>2)]
|
|
2067
2018
|
DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, track.id AS track_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tag.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks AS track ON (track.album_id = albums_0.id)']
|
|
2068
|
-
a.last.tag.
|
|
2019
|
+
a.last.tag.must_be_nil
|
|
2069
2020
|
a = a.first
|
|
2070
2021
|
a.tag.must_equal Tag.load(:id=>2)
|
|
2071
|
-
a.tag.track.
|
|
2022
|
+
a.tag.track.must_be_nil
|
|
2072
2023
|
DB.sqls.length.must_equal 0
|
|
2073
2024
|
end
|
|
2074
2025
|
|
|
2075
2026
|
it "eager graphing should respect :left_primary_key and :right_primary_key options" do
|
|
2076
2027
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
|
|
2077
|
-
@c1.dataset.
|
|
2078
|
-
Tag.dataset.
|
|
2079
|
-
|
|
2080
|
-
ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
|
|
2081
|
-
a = ds.all
|
|
2028
|
+
@c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
|
|
2029
|
+
Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
|
|
2030
|
+
a = @c1.eager_graph(:tag).with_fetch(:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4).all
|
|
2082
2031
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
2083
2032
|
DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.tag_id = albums_tags.tag_id)']
|
|
2084
2033
|
a.first.tag.must_equal Tag.load(:id=>2, :tag_id=>4)
|
|
@@ -2087,11 +2036,9 @@ describe "one_through_many eager loading methods" do
|
|
|
2087
2036
|
|
|
2088
2037
|
it "eager graphing should respect composite keys" do
|
|
2089
2038
|
@c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:id, :tag_id], :left_primary_key=>[:id, :yyy]
|
|
2090
|
-
@c1.dataset.
|
|
2091
|
-
Tag.dataset.
|
|
2092
|
-
|
|
2093
|
-
ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
|
|
2094
|
-
a = ds.all
|
|
2039
|
+
@c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
|
|
2040
|
+
Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
|
|
2041
|
+
a = @c1.eager_graph(:tag).with_fetch(:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4).all
|
|
2095
2042
|
a.must_equal [@c1.load(:id=>1, :yyy=>8)]
|
|
2096
2043
|
DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.g1) AND (tag.tag_id = albums_tags.g2))']
|
|
2097
2044
|
a.first.tag.must_equal Tag.load(:id=>2, :tag_id=>4)
|
|
@@ -2100,9 +2047,7 @@ describe "one_through_many eager loading methods" do
|
|
|
2100
2047
|
|
|
2101
2048
|
it "should respect the association's :graph_select option" do
|
|
2102
2049
|
@c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
|
|
2103
|
-
|
|
2104
|
-
ds._fetch = {:id=>1, :b=>2}
|
|
2105
|
-
a = ds.all
|
|
2050
|
+
a = @c1.eager_graph(:tag).with_fetch(:id=>1, :b=>2).all
|
|
2106
2051
|
a.must_equal [@c1.load(:id=>1)]
|
|
2107
2052
|
DB.sqls.must_equal ['SELECT artists.id, tag.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
|
|
2108
2053
|
a.first.tag.must_equal Tag.load(:b=>2)
|