sequel 4.41.0 → 4.42.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|