sequel 3.21.0 → 3.41.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.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -8,32 +8,69 @@ describe Sequel::Model, "many_through_many" do
|
|
|
8
8
|
plugin :many_through_many
|
|
9
9
|
end
|
|
10
10
|
class ::Tag < Sequel::Model
|
|
11
|
+
columns :id, :h1, :h2
|
|
11
12
|
end
|
|
12
|
-
MODEL_DB.reset
|
|
13
13
|
@c1 = Artist
|
|
14
14
|
@c2 = Tag
|
|
15
15
|
@dataset = @c2.dataset
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
yield({:id=>1})
|
|
19
|
-
end
|
|
16
|
+
@dataset._fetch = {:id=>1}
|
|
17
|
+
MODEL_DB.reset
|
|
20
18
|
end
|
|
21
19
|
after do
|
|
22
20
|
Object.send(:remove_const, :Artist)
|
|
23
21
|
Object.send(:remove_const, :Tag)
|
|
24
22
|
end
|
|
25
23
|
|
|
24
|
+
it "should populate :key_hash and :id_map option correctly for custom eager loaders" do
|
|
25
|
+
khs = []
|
|
26
|
+
pr = proc{|h| khs << [h[:key_hash], h[:id_map]]}
|
|
27
|
+
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loader=>pr
|
|
28
|
+
@c1.eager(:tags).all
|
|
29
|
+
khs.should == [[{:id=>{1=>[Artist.load(:x=>1, :id=>1)]}}, {1=>[Artist.load(:x=>1, :id=>1)]}]]
|
|
30
|
+
|
|
31
|
+
khs.clear
|
|
32
|
+
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id, :left_primary_key_column=>:i, :eager_loader=>pr
|
|
33
|
+
@c1.eager(:tags).all
|
|
34
|
+
khs.should == [[{:id=>{1=>[Artist.load(:x=>1, :id=>1)]}}, {1=>[Artist.load(:x=>1, :id=>1)]}]]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
|
|
38
|
+
@c1.send(:define_method, :id3){id*3}
|
|
39
|
+
@c1.dataset._fetch = {:id=>1}
|
|
40
|
+
@c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>3}
|
|
41
|
+
@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
|
|
42
|
+
a = @c1.eager(:tags).all
|
|
43
|
+
a.should == [@c1.load(:id => 1)]
|
|
44
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists', "SELECT 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) AND (albums_artists.artist_id IN (3)))"]
|
|
45
|
+
a.first.tags.should == [@c2.load(:id=>4)]
|
|
46
|
+
MODEL_DB.sqls.should == []
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
|
|
50
|
+
@c1.dataset._fetch = {:id=>1}
|
|
51
|
+
@c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>1}
|
|
52
|
+
@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)
|
|
53
|
+
a = @c1.eager(:tags).all
|
|
54
|
+
a.should == [@c1.load(:id => 1)]
|
|
55
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists', "SELECT tags.*, (albums_artists.artist_id / 3) 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) AND ((albums_artists.artist_id / 3) IN (1)))"]
|
|
56
|
+
a.first.tags.should == [@c2.load(:id=>4)]
|
|
57
|
+
end
|
|
58
|
+
|
|
26
59
|
it "should default to associating to other models in the same scope" do
|
|
27
|
-
|
|
28
|
-
class
|
|
29
|
-
|
|
30
|
-
|
|
60
|
+
begin
|
|
61
|
+
class ::AssociationModuleTest
|
|
62
|
+
class Artist < Sequel::Model
|
|
63
|
+
plugin :many_through_many
|
|
64
|
+
many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
65
|
+
end
|
|
66
|
+
class Tag < Sequel::Model
|
|
67
|
+
end
|
|
31
68
|
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
69
|
+
|
|
70
|
+
::AssociationModuleTest::Artist.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
|
|
71
|
+
ensure
|
|
72
|
+
Object.send(:remove_const, :AssociationModuleTest)
|
|
73
|
+
end
|
|
37
74
|
end
|
|
38
75
|
|
|
39
76
|
it "should raise an error if in invalid form of through is used" do
|
|
@@ -45,9 +82,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
45
82
|
it "should allow only two arguments with the :through option" do
|
|
46
83
|
@c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
47
84
|
n = @c1.load(:id => 1234)
|
|
48
|
-
|
|
49
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
50
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
85
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
51
86
|
n.tags.should == [@c2.load(:id=>1)]
|
|
52
87
|
end
|
|
53
88
|
|
|
@@ -55,18 +90,14 @@ describe Sequel::Model, "many_through_many" do
|
|
|
55
90
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
56
91
|
@c1.many_through_many :other_tags, :clone=>:tags
|
|
57
92
|
n = @c1.load(:id => 1234)
|
|
58
|
-
|
|
59
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
60
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
93
|
+
n.other_tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
61
94
|
n.tags.should == [@c2.load(:id=>1)]
|
|
62
95
|
end
|
|
63
96
|
|
|
64
97
|
it "should use join tables given" do
|
|
65
98
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
66
99
|
n = @c1.load(:id => 1234)
|
|
67
|
-
|
|
68
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
69
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
100
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
70
101
|
n.tags.should == [@c2.load(:id=>1)]
|
|
71
102
|
end
|
|
72
103
|
|
|
@@ -75,9 +106,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
75
106
|
end
|
|
76
107
|
@c1.many_through_many :albums, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]]
|
|
77
108
|
n = @c1.load(:id => 1234)
|
|
78
|
-
|
|
79
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
80
|
-
a.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234))'
|
|
109
|
+
n.albums_dataset.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234))'
|
|
81
110
|
n.albums.should == [Album.load(:id=>1, :x=>1)]
|
|
82
111
|
Object.send(:remove_const, :Album)
|
|
83
112
|
end
|
|
@@ -85,9 +114,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
85
114
|
it "should use explicit class if given" do
|
|
86
115
|
@c1.many_through_many :albums_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag
|
|
87
116
|
n = @c1.load(:id => 1234)
|
|
88
|
-
|
|
89
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
90
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
117
|
+
n.albums_tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234))'
|
|
91
118
|
n.albums_tags.should == [@c2.load(:id=>1)]
|
|
92
119
|
end
|
|
93
120
|
|
|
@@ -95,9 +122,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
95
122
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :right_primary_key=>:tag_id, :left_primary_key=>:yyy
|
|
96
123
|
n = @c1.load(:id => 1234)
|
|
97
124
|
n.yyy = 85
|
|
98
|
-
|
|
99
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
100
|
-
a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 85))'
|
|
125
|
+
n.tags_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 85))'
|
|
101
126
|
n.tags.should == [@c2.load(:id=>1)]
|
|
102
127
|
end
|
|
103
128
|
|
|
@@ -105,61 +130,123 @@ describe Sequel::Model, "many_through_many" do
|
|
|
105
130
|
@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]
|
|
106
131
|
n = @c1.load(:id => 1234)
|
|
107
132
|
n.yyy = 85
|
|
108
|
-
|
|
109
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
110
|
-
a.sql.should == 'SELECT tags.* 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) AND (albums_artists.b1 = 1234) AND (albums_artists.b2 = 85))'
|
|
133
|
+
n.tags_dataset.sql.should == 'SELECT tags.* 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) AND (albums_artists.b1 = 1234) AND (albums_artists.b2 = 85))'
|
|
111
134
|
n.tags.should == [@c2.load(:id=>1)]
|
|
112
135
|
end
|
|
113
136
|
|
|
137
|
+
it "should allowing filtering by many_through_many associations" do
|
|
138
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
139
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should allowing filtering by many_through_many associations with a single through table" do
|
|
143
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id]]
|
|
144
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists WHERE ((albums_artists.album_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should allowing filtering by many_through_many associations with aliased tables" do
|
|
148
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :id, :id], [:albums_artists, :album_id, :tag_id]]
|
|
149
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.id = albums_artists.album_id) INNER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_artists_0.id) WHERE ((albums_artists_1.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should allowing filtering by many_through_many associations with composite keys" do
|
|
153
|
+
@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]
|
|
154
|
+
@c1.filter(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should allowing excluding by many_through_many associations" do
|
|
158
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
159
|
+
@c1.exclude(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should allowing excluding by many_through_many associations with composite keys" do
|
|
163
|
+
@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]
|
|
164
|
+
@c1.exclude(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "should allowing filtering by multiple many_through_many associations" do
|
|
168
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
169
|
+
@c1.filter(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL))))'
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should allowing filtering by multiple many_through_many associations with composite keys" do
|
|
173
|
+
@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]
|
|
174
|
+
@c1.filter(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "should allowing excluding by multiple many_through_many associations" do
|
|
178
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
179
|
+
@c1.exclude(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should allowing excluding by multiple many_through_many associations with composite keys" do
|
|
183
|
+
@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]
|
|
184
|
+
@c1.exclude(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should allowing filtering/excluding many_through_many associations with NULL values" do
|
|
188
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
189
|
+
@c1.filter(:tags=>@c2.new).sql.should == 'SELECT * FROM artists WHERE \'f\''
|
|
190
|
+
@c1.exclude(:tags=>@c2.new).sql.should == 'SELECT * FROM artists WHERE \'t\''
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "should allowing filtering by many_through_many association datasets" do
|
|
194
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
195
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL))))'
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "should allowing filtering by many_through_many association datasets with composite keys" do
|
|
199
|
+
@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]
|
|
200
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "should allowing excluding by many_through_many association datasets" do
|
|
204
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
|
205
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should allowing excluding by many_through_many association datasets with composite keys" do
|
|
209
|
+
@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]
|
|
210
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
|
211
|
+
end
|
|
212
|
+
|
|
114
213
|
it "should support a :conditions option" do
|
|
115
214
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
|
|
116
215
|
n = @c1.load(:id => 1234)
|
|
117
|
-
a =
|
|
118
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
119
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (a = 32)'
|
|
216
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (a = 32)'
|
|
120
217
|
n.tags.should == [@c2.load(:id=>1)]
|
|
121
218
|
|
|
122
219
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>['a = ?', 42]
|
|
123
220
|
n = @c1.load(:id => 1234)
|
|
124
|
-
a =
|
|
125
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
126
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (a = 42)'
|
|
221
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (a = 42)'
|
|
127
222
|
n.tags.should == [@c2.load(:id=>1)]
|
|
128
223
|
end
|
|
129
224
|
|
|
130
225
|
it "should support an :order option" do
|
|
131
226
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
|
|
132
227
|
n = @c1.load(:id => 1234)
|
|
133
|
-
|
|
134
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
135
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) ORDER BY blah'
|
|
228
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) ORDER BY blah'
|
|
136
229
|
n.tags.should == [@c2.load(:id=>1)]
|
|
137
230
|
end
|
|
138
231
|
|
|
139
232
|
it "should support an array for the :order option" do
|
|
140
233
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
|
|
141
234
|
n = @c1.load(:id => 1234)
|
|
142
|
-
|
|
143
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
144
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) ORDER BY blah1, blah2'
|
|
235
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) ORDER BY blah1, blah2'
|
|
145
236
|
n.tags.should == [@c2.load(:id=>1)]
|
|
146
237
|
end
|
|
147
238
|
|
|
148
239
|
it "should support a select option" do
|
|
149
240
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:blah
|
|
150
241
|
n = @c1.load(:id => 1234)
|
|
151
|
-
|
|
152
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
153
|
-
a.sql.should == 'SELECT blah 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) AND (albums_artists.artist_id = 1234))'
|
|
242
|
+
n.tags_dataset.sql.should == 'SELECT blah 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) AND (albums_artists.artist_id = 1234))'
|
|
154
243
|
n.tags.should == [@c2.load(:id=>1)]
|
|
155
244
|
end
|
|
156
245
|
|
|
157
246
|
it "should support an array for the select option" do
|
|
158
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[:tags
|
|
247
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :albums__name]
|
|
159
248
|
n = @c1.load(:id => 1234)
|
|
160
|
-
|
|
161
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
162
|
-
a.sql.should == 'SELECT tags.*, albums.name 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) AND (albums_artists.artist_id = 1234))'
|
|
249
|
+
n.tags_dataset.sql.should == 'SELECT tags.*, albums.name 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) AND (albums_artists.artist_id = 1234))'
|
|
163
250
|
n.tags.should == [@c2.load(:id=>1)]
|
|
164
251
|
end
|
|
165
252
|
|
|
@@ -167,9 +254,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
167
254
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]] do |ds| ds.filter(:yyy=>@yyy) end
|
|
168
255
|
n = @c1.load(:id => 1234)
|
|
169
256
|
n.yyy = 85
|
|
170
|
-
|
|
171
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
172
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85)'
|
|
257
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85)'
|
|
173
258
|
n.tags.should == [@c2.load(:id=>1)]
|
|
174
259
|
end
|
|
175
260
|
|
|
@@ -177,34 +262,26 @@ describe Sequel::Model, "many_through_many" do
|
|
|
177
262
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah do |ds| ds.filter(:yyy=>@yyy) end
|
|
178
263
|
n = @c1.load(:id => 1234)
|
|
179
264
|
n.yyy = 85
|
|
180
|
-
|
|
181
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
182
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85) ORDER BY blah'
|
|
265
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85) ORDER BY blah'
|
|
183
266
|
n.tags.should == [@c2.load(:id=>1)]
|
|
184
267
|
end
|
|
185
268
|
|
|
186
269
|
it "should support a :dataset option that is used instead of the default" do
|
|
187
270
|
@c1.many_through_many :tags, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(:albums_artists__artist_id=>id)}
|
|
188
271
|
n = @c1.load(:id => 1234)
|
|
189
|
-
|
|
190
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
191
|
-
a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234)'
|
|
272
|
+
n.tags_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234)'
|
|
192
273
|
n.tags.should == [@c2.load(:id=>1)]
|
|
193
274
|
end
|
|
194
275
|
|
|
195
276
|
it "should support a :limit option" do
|
|
196
277
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
|
|
197
278
|
n = @c1.load(:id => 1234)
|
|
198
|
-
|
|
199
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
200
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) LIMIT 10'
|
|
279
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) LIMIT 10'
|
|
201
280
|
n.tags.should == [@c2.load(:id=>1)]
|
|
202
281
|
|
|
203
282
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>[10, 10]
|
|
204
283
|
n = @c1.load(:id => 1234)
|
|
205
|
-
|
|
206
|
-
a.should be_a_kind_of(Sequel::Dataset)
|
|
207
|
-
a.sql.should == '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) AND (albums_artists.artist_id = 1234)) LIMIT 10 OFFSET 10'
|
|
284
|
+
n.tags_dataset.sql.should == '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) AND (albums_artists.artist_id = 1234)) LIMIT 10 OFFSET 10'
|
|
208
285
|
n.tags.should == [@c2.load(:id=>1)]
|
|
209
286
|
end
|
|
210
287
|
|
|
@@ -228,7 +305,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
228
305
|
n.tags.should == [@c2.load(:id=>1)]
|
|
229
306
|
MODEL_DB.sqls.should == ['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) AND (albums_artists.artist_id = 1234))']
|
|
230
307
|
n.associations[:tags].should == n.tags
|
|
231
|
-
MODEL_DB.sqls.length.should ==
|
|
308
|
+
MODEL_DB.sqls.length.should == 0
|
|
232
309
|
end
|
|
233
310
|
|
|
234
311
|
it "should use cached instance variable if available" do
|
|
@@ -247,7 +324,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
247
324
|
n.tags(true).should == [@c2.load(:id=>1)]
|
|
248
325
|
MODEL_DB.sqls.should == ['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) AND (albums_artists.artist_id = 1234))']
|
|
249
326
|
n.associations[:tags].should == n.tags
|
|
250
|
-
MODEL_DB.sqls.length.should ==
|
|
327
|
+
MODEL_DB.sqls.length.should == 0
|
|
251
328
|
end
|
|
252
329
|
|
|
253
330
|
it "should not add associations methods directly to class" do
|
|
@@ -264,18 +341,13 @@ describe Sequel::Model, "many_through_many" do
|
|
|
264
341
|
h = []
|
|
265
342
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :after_load=>:al
|
|
266
343
|
@c1.class_eval do
|
|
267
|
-
|
|
344
|
+
self::Foo = h
|
|
268
345
|
def al(v)
|
|
269
|
-
v.each{|x|
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
@c2.class_eval do
|
|
273
|
-
def @dataset.fetch_rows(sql)
|
|
274
|
-
yield({:id=>20})
|
|
275
|
-
yield({:id=>30})
|
|
346
|
+
v.each{|x| model::Foo << x.pk * 20}
|
|
276
347
|
end
|
|
277
348
|
end
|
|
278
|
-
|
|
349
|
+
@c2.dataset._fetch = [{:id=>20}, {:id=>30}]
|
|
350
|
+
p = @c1.load(:id=>10, :parent_id=>20)
|
|
279
351
|
p.tags
|
|
280
352
|
h.should == [400, 600]
|
|
281
353
|
p.tags.collect{|a| a.pk}.should == [20, 30]
|
|
@@ -284,14 +356,7 @@ describe Sequel::Model, "many_through_many" do
|
|
|
284
356
|
it "should support a :uniq option that removes duplicates from the association" do
|
|
285
357
|
h = []
|
|
286
358
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :uniq=>true
|
|
287
|
-
@c2.
|
|
288
|
-
def @dataset.fetch_rows(sql)
|
|
289
|
-
yield({:id=>20})
|
|
290
|
-
yield({:id=>30})
|
|
291
|
-
yield({:id=>20})
|
|
292
|
-
yield({:id=>30})
|
|
293
|
-
end
|
|
294
|
-
end
|
|
359
|
+
@c2.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
|
|
295
360
|
@c1.load(:id=>10).tags.should == [@c2.load(:id=>20), @c2.load(:id=>30)]
|
|
296
361
|
end
|
|
297
362
|
end
|
|
@@ -352,57 +417,40 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
352
417
|
end
|
|
353
418
|
class ::Track < Sequel::Model
|
|
354
419
|
end
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
[:
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
h = {:id => 1}
|
|
364
|
-
if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
|
|
365
|
-
h[:tags_id] = 2
|
|
366
|
-
h[:albums_0_id] = 3 if sql =~ /LEFT OUTER JOIN albums AS albums_0/
|
|
367
|
-
h[:tracks_id] = 4 if sql =~ /LEFT OUTER JOIN tracks/
|
|
368
|
-
h[:other_tags_id] = 9 if sql =~ /other_tags\.id AS other_tags_id/
|
|
369
|
-
h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
|
|
370
|
-
end
|
|
371
|
-
yield h
|
|
420
|
+
Artist.dataset.columns(:id)._fetch = proc do |sql|
|
|
421
|
+
h = {:id => 1}
|
|
422
|
+
if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
|
|
423
|
+
h[:tags_id] = 2
|
|
424
|
+
h[:albums_0_id] = 3 if sql =~ /LEFT OUTER JOIN albums AS albums_0/
|
|
425
|
+
h[:tracks_id] = 4 if sql =~ /LEFT OUTER JOIN tracks/
|
|
426
|
+
h[:other_tags_id] = 9 if sql =~ /other_tags\.id AS other_tags_id/
|
|
427
|
+
h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
|
|
372
428
|
end
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
Tag.dataset.extend(Module.new {
|
|
376
|
-
def fetch_rows(sql)
|
|
377
|
-
@db << sql
|
|
378
|
-
h = {:id => 2}
|
|
379
|
-
if sql =~ /albums_artists.artist_id IN \(([18])\)/
|
|
380
|
-
h.merge!(:x_foreign_key_x=>$1.to_i)
|
|
381
|
-
elsif sql =~ /\(\(albums_artists.b1, albums_artists.b2\) IN \(\(1, 8\)\)\)/
|
|
382
|
-
h.merge!(:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>8)
|
|
383
|
-
end
|
|
384
|
-
h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
|
|
385
|
-
yield h
|
|
386
|
-
end
|
|
387
|
-
})
|
|
429
|
+
h
|
|
430
|
+
end
|
|
388
431
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
h =
|
|
393
|
-
|
|
394
|
-
|
|
432
|
+
Tag.dataset._fetch = proc do |sql|
|
|
433
|
+
h = {:id => 2}
|
|
434
|
+
if sql =~ /albums_artists.artist_id IN \(([18])\)/
|
|
435
|
+
h[:x_foreign_key_x] = $1.to_i
|
|
436
|
+
elsif sql =~ /\(\(albums_artists.b1, albums_artists.b2\) IN \(\(1, 8\)\)\)/
|
|
437
|
+
h.merge!(:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>8)
|
|
395
438
|
end
|
|
396
|
-
|
|
439
|
+
h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
|
|
440
|
+
h
|
|
441
|
+
end
|
|
397
442
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
443
|
+
Album.dataset._fetch = proc do |sql|
|
|
444
|
+
h = {:id => 3}
|
|
445
|
+
h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
|
|
446
|
+
h
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
Track.dataset._fetch = proc do |sql|
|
|
450
|
+
h = {:id => 4}
|
|
451
|
+
h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
|
|
452
|
+
h
|
|
453
|
+
end
|
|
406
454
|
|
|
407
455
|
@c1 = Artist
|
|
408
456
|
MODEL_DB.reset
|
|
@@ -416,33 +464,35 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
416
464
|
a.should == [@c1.load(:id=>1)]
|
|
417
465
|
MODEL_DB.sqls.should == ['SELECT * FROM artists', 'SELECT 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) AND (albums_artists.artist_id IN (1)))']
|
|
418
466
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
419
|
-
MODEL_DB.sqls.length.should ==
|
|
467
|
+
MODEL_DB.sqls.length.should == 0
|
|
420
468
|
end
|
|
421
469
|
|
|
422
470
|
it "should eagerly load multiple associations in a single call" do
|
|
423
471
|
a = @c1.eager(:tags, :albums).all
|
|
424
472
|
a.should == [@c1.load(:id=>1)]
|
|
425
|
-
MODEL_DB.sqls
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
473
|
+
sqls = MODEL_DB.sqls
|
|
474
|
+
sqls.length.should == 3
|
|
475
|
+
sqls[0].should == 'SELECT * FROM artists'
|
|
476
|
+
sqls[1..-1].should(include('SELECT 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) AND (albums_artists.artist_id IN (1)))'))
|
|
477
|
+
sqls[1..-1].should(include('SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
|
429
478
|
a = a.first
|
|
430
479
|
a.tags.should == [Tag.load(:id=>2)]
|
|
431
480
|
a.albums.should == [Album.load(:id=>3)]
|
|
432
|
-
MODEL_DB.sqls.length.should ==
|
|
481
|
+
MODEL_DB.sqls.length.should == 0
|
|
433
482
|
end
|
|
434
483
|
|
|
435
484
|
it "should eagerly load multiple associations in separate" do
|
|
436
485
|
a = @c1.eager(:tags).eager(:albums).all
|
|
437
486
|
a.should == [@c1.load(:id=>1)]
|
|
438
|
-
MODEL_DB.sqls
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
487
|
+
sqls = MODEL_DB.sqls
|
|
488
|
+
sqls.length.should == 3
|
|
489
|
+
sqls[0].should == 'SELECT * FROM artists'
|
|
490
|
+
sqls[1..-1].should(include('SELECT 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) AND (albums_artists.artist_id IN (1)))'))
|
|
491
|
+
sqls[1..-1].should(include('SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))'))
|
|
442
492
|
a = a.first
|
|
443
493
|
a.tags.should == [Tag.load(:id=>2)]
|
|
444
494
|
a.albums.should == [Album.load(:id=>3)]
|
|
445
|
-
MODEL_DB.sqls.length.should ==
|
|
495
|
+
MODEL_DB.sqls.length.should == 0
|
|
446
496
|
end
|
|
447
497
|
|
|
448
498
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
@@ -454,7 +504,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
454
504
|
a = a.first
|
|
455
505
|
a.tags.should == [Tag.load(:id=>2)]
|
|
456
506
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
457
|
-
MODEL_DB.sqls.length.should ==
|
|
507
|
+
MODEL_DB.sqls.length.should == 0
|
|
458
508
|
end
|
|
459
509
|
|
|
460
510
|
it "should cascade eagerly loading when the :eager association option is used" do
|
|
@@ -467,7 +517,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
467
517
|
a = a.first
|
|
468
518
|
a.tags.should == [Tag.load(:id=>2)]
|
|
469
519
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
470
|
-
MODEL_DB.sqls.length.should ==
|
|
520
|
+
MODEL_DB.sqls.length.should == 0
|
|
471
521
|
end
|
|
472
522
|
|
|
473
523
|
it "should respect :eager when lazily loading an association" do
|
|
@@ -477,39 +527,20 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
477
527
|
MODEL_DB.sqls.should == ['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) AND (albums_artists.artist_id = 1))',
|
|
478
528
|
'SELECT tracks.*, albums_tags.tag_id AS x_foreign_key_x FROM tracks INNER JOIN albums ON (albums.id = tracks.album_id) INNER JOIN albums_tags ON ((albums_tags.album_id = albums.id) AND (albums_tags.tag_id IN (2)))']
|
|
479
529
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
480
|
-
MODEL_DB.sqls.length.should ==
|
|
530
|
+
MODEL_DB.sqls.length.should == 0
|
|
481
531
|
end
|
|
482
532
|
|
|
483
533
|
it "should cascade eagerly loading when the :eager_graph association option is used" do
|
|
484
|
-
Tag.dataset.extend(Module.new {
|
|
485
|
-
def columns
|
|
486
|
-
[:id]
|
|
487
|
-
end
|
|
488
|
-
def fetch_rows(sql)
|
|
489
|
-
@db << sql
|
|
490
|
-
yield({:id=>2, :tracks_id=>4, :x_foreign_key_x=>1})
|
|
491
|
-
end
|
|
492
|
-
})
|
|
493
534
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
|
|
494
|
-
|
|
495
|
-
a.should == [@c1.load(:id=>1)]
|
|
496
|
-
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
497
|
-
'SELECT tags.id, tracks.id AS tracks_id, albums_artists.artist_id AS x_foreign_key_x FROM (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) AND (albums_artists.artist_id IN (1)))) AS tags LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums ON (albums.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
|
|
498
|
-
a = a.first
|
|
499
|
-
a.tags.should == [Tag.load(:id=>2)]
|
|
500
|
-
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
501
|
-
MODEL_DB.sqls.length.should == 2
|
|
535
|
+
proc{@c1.eager(:tags).all}.should raise_error(Sequel::Error)
|
|
502
536
|
end
|
|
503
537
|
|
|
504
538
|
it "should respect :eager_graph when lazily loading an association" do
|
|
539
|
+
Tag.dataset._fetch = {:id=>2, :tracks_id=>4}
|
|
505
540
|
Tag.dataset.extend(Module.new {
|
|
506
541
|
def columns
|
|
507
542
|
[:id]
|
|
508
543
|
end
|
|
509
|
-
def fetch_rows(sql)
|
|
510
|
-
@db << sql
|
|
511
|
-
yield({:id=>2, :tracks_id=>4})
|
|
512
|
-
end
|
|
513
544
|
})
|
|
514
545
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
|
|
515
546
|
a = @c1.load(:id=>1)
|
|
@@ -517,7 +548,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
517
548
|
MODEL_DB.sqls.should == [ 'SELECT tags.id, tracks.id AS tracks_id FROM (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) AND (albums_artists.artist_id = 1))) AS tags LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums ON (albums.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
|
|
518
549
|
a.tags.should == [Tag.load(:id=>2)]
|
|
519
550
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
520
|
-
MODEL_DB.sqls.length.should ==
|
|
551
|
+
MODEL_DB.sqls.length.should == 0
|
|
521
552
|
end
|
|
522
553
|
|
|
523
554
|
it "should respect :conditions when eagerly loading" do
|
|
@@ -527,7 +558,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
527
558
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
528
559
|
'SELECT 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) AND (albums_artists.artist_id IN (1))) WHERE (a = 32)']
|
|
529
560
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
530
|
-
MODEL_DB.sqls.length.should ==
|
|
561
|
+
MODEL_DB.sqls.length.should == 0
|
|
531
562
|
end
|
|
532
563
|
|
|
533
564
|
it "should respect :order when eagerly loading" do
|
|
@@ -537,7 +568,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
537
568
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
538
569
|
'SELECT 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) AND (albums_artists.artist_id IN (1))) ORDER BY blah']
|
|
539
570
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
540
|
-
MODEL_DB.sqls.length.should ==
|
|
571
|
+
MODEL_DB.sqls.length.should == 0
|
|
541
572
|
end
|
|
542
573
|
|
|
543
574
|
it "should use the association's block when eager loading by default" do
|
|
@@ -547,7 +578,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
547
578
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
548
579
|
'SELECT 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) AND (albums_artists.artist_id IN (1))) WHERE a']
|
|
549
580
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
550
|
-
MODEL_DB.sqls.length.should ==
|
|
581
|
+
MODEL_DB.sqls.length.should == 0
|
|
551
582
|
end
|
|
552
583
|
|
|
553
584
|
it "should use the :eager_block option when eager loading if given" do
|
|
@@ -557,7 +588,88 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
557
588
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
558
589
|
'SELECT 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) AND (albums_artists.artist_id IN (1))) WHERE b']
|
|
559
590
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
560
|
-
MODEL_DB.sqls.length.should ==
|
|
591
|
+
MODEL_DB.sqls.length.should == 0
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
it "should respect the :limit option on a many_through_many association" do
|
|
595
|
+
@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
|
|
596
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
|
|
597
|
+
a = @c1.eager(:first_two_tags).all
|
|
598
|
+
a.should == [@c1.load(:id=>1)]
|
|
599
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
600
|
+
'SELECT 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) AND (albums_artists.artist_id IN (1)))']
|
|
601
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
602
|
+
MODEL_DB.sqls.length.should == 0
|
|
603
|
+
|
|
604
|
+
@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,1]
|
|
605
|
+
a = @c1.eager(:first_two_tags).all
|
|
606
|
+
a.should == [@c1.load(:id=>1)]
|
|
607
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
608
|
+
'SELECT 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) AND (albums_artists.artist_id IN (1)))']
|
|
609
|
+
a.first.first_two_tags.should == [Tag.load(:id=>6), Tag.load(:id=>7)]
|
|
610
|
+
MODEL_DB.sqls.length.should == 0
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
|
|
614
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
615
|
+
@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=>true, :order=>:name
|
|
616
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
|
|
617
|
+
a = @c1.eager(:first_two_tags).all
|
|
618
|
+
a.should == [@c1.load(:id=>1)]
|
|
619
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
620
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id 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) AND (albums_artists.artist_id IN (1)))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
|
621
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
622
|
+
MODEL_DB.sqls.length.should == 0
|
|
623
|
+
|
|
624
|
+
@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,1], :eager_limit_strategy=>true, :order=>:name
|
|
625
|
+
a = @c1.eager(:first_two_tags).all
|
|
626
|
+
a.should == [@c1.load(:id=>1)]
|
|
627
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
628
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id 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) AND (albums_artists.artist_id IN (1)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
|
629
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
630
|
+
MODEL_DB.sqls.length.should == 0
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
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
|
|
634
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
|
635
|
+
@c1.set_primary_key([:id1, :id2])
|
|
636
|
+
@c1.columns :id1, :id2
|
|
637
|
+
@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, :eager_limit_strategy=>true, :order=>:name
|
|
638
|
+
@c1.dataset._fetch = [{:id1=>1, :id2=>2}]
|
|
639
|
+
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}]
|
|
640
|
+
a = @c1.eager(:first_two_tags).all
|
|
641
|
+
a.should == [@c1.load(:id1=>1, :id2=>2)]
|
|
642
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
643
|
+
'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) AND ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2))))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
|
644
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
645
|
+
MODEL_DB.sqls.length.should == 0
|
|
646
|
+
|
|
647
|
+
@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,1], :eager_limit_strategy=>true, :order=>:name
|
|
648
|
+
a = @c1.eager(:first_two_tags).all
|
|
649
|
+
a.should == [@c1.load(:id1=>1, :id2=>2)]
|
|
650
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
651
|
+
'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) AND ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2))))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
|
652
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
653
|
+
MODEL_DB.sqls.length.should == 0
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
it "should respect the :limit option on a many_through_many association using a :correlated_subquery strategy" do
|
|
657
|
+
@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=>:correlated_subquery, :order=>:name
|
|
658
|
+
Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
|
|
659
|
+
a = @c1.eager(:first_two_tags).all
|
|
660
|
+
a.should == [@c1.load(:id=>1)]
|
|
661
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
662
|
+
'SELECT 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) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2)) ORDER BY name']
|
|
663
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
664
|
+
MODEL_DB.sqls.length.should == 0
|
|
665
|
+
|
|
666
|
+
@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,1], :eager_limit_strategy=>:correlated_subquery, :order=>:name
|
|
667
|
+
a = @c1.eager(:first_two_tags).all
|
|
668
|
+
a.should == [@c1.load(:id=>1)]
|
|
669
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
670
|
+
'SELECT 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) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2 OFFSET 1)) ORDER BY name']
|
|
671
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
|
672
|
+
MODEL_DB.sqls.length.should == 0
|
|
561
673
|
end
|
|
562
674
|
|
|
563
675
|
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
|
@@ -573,47 +685,33 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
573
685
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
574
686
|
'SELECT tags.name, 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) AND (albums_artists.artist_id IN (1)))']
|
|
575
687
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
576
|
-
MODEL_DB.sqls.length.should ==
|
|
688
|
+
MODEL_DB.sqls.length.should == 0
|
|
577
689
|
end
|
|
578
690
|
|
|
579
|
-
it "should respect
|
|
691
|
+
it "should respect many_through_many association's :left_primary_key and :right_primary_key options" do
|
|
580
692
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
581
|
-
@c1.dataset.
|
|
582
|
-
|
|
583
|
-
[:id, :yyy]
|
|
584
|
-
end
|
|
585
|
-
def fetch_rows(sql)
|
|
586
|
-
@db << sql
|
|
587
|
-
yield({:id=>1, :yyy=>8})
|
|
588
|
-
end
|
|
589
|
-
})
|
|
693
|
+
@c1.dataset._fetch = {:id=>1, :yyy=>8}
|
|
694
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
590
695
|
@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
|
|
591
696
|
a = @c1.eager(:tags).all
|
|
592
697
|
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
|
593
698
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
594
699
|
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (8)))']
|
|
595
700
|
a.first.tags.should == [Tag.load(:tag_id=>2)]
|
|
596
|
-
MODEL_DB.sqls.length.should ==
|
|
701
|
+
MODEL_DB.sqls.length.should == 0
|
|
597
702
|
end
|
|
598
703
|
|
|
599
704
|
it "should handle composite keys" do
|
|
600
705
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
|
601
|
-
@c1.dataset.
|
|
602
|
-
|
|
603
|
-
[:id, :yyy]
|
|
604
|
-
end
|
|
605
|
-
def fetch_rows(sql)
|
|
606
|
-
@db << sql
|
|
607
|
-
yield({:id=>1, :yyy=>8})
|
|
608
|
-
end
|
|
609
|
-
})
|
|
706
|
+
@c1.dataset._fetch = {:id=>1, :yyy=>8}
|
|
707
|
+
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
610
708
|
@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]
|
|
611
709
|
a = @c1.eager(:tags).all
|
|
612
710
|
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
|
613
711
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
614
712
|
'SELECT tags.*, albums_artists.b1 AS x_foreign_key_0_x, albums_artists.b2 AS x_foreign_key_1_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) AND ((albums_artists.b1, albums_artists.b2) IN ((1, 8))))']
|
|
615
713
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
616
|
-
MODEL_DB.sqls.length.should ==
|
|
714
|
+
MODEL_DB.sqls.length.should == 0
|
|
617
715
|
end
|
|
618
716
|
|
|
619
717
|
it "should respect :after_load callbacks on associations when eager loading" do
|
|
@@ -623,7 +721,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
623
721
|
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
|
624
722
|
'SELECT 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) AND (albums_artists.artist_id IN (1)))']
|
|
625
723
|
a.first.tags.should == [Tag.load(:id=>6)]
|
|
626
|
-
MODEL_DB.sqls.length.should ==
|
|
724
|
+
MODEL_DB.sqls.length.should == 0
|
|
627
725
|
end
|
|
628
726
|
|
|
629
727
|
it "should raise an error if called without a symbol or hash" do
|
|
@@ -635,7 +733,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
635
733
|
a.should == [@c1.load(:id=>1)]
|
|
636
734
|
MODEL_DB.sqls.should == ['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)']
|
|
637
735
|
a.first.tags.should == [Tag.load(:id=>2)]
|
|
638
|
-
MODEL_DB.sqls.length.should ==
|
|
736
|
+
MODEL_DB.sqls.length.should == 0
|
|
639
737
|
end
|
|
640
738
|
|
|
641
739
|
it "should eagerly graph multiple associations in a single call" do
|
|
@@ -645,7 +743,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
645
743
|
a = a.first
|
|
646
744
|
a.tags.should == [Tag.load(:id=>2)]
|
|
647
745
|
a.albums.should == [Album.load(:id=>3)]
|
|
648
|
-
MODEL_DB.sqls.length.should ==
|
|
746
|
+
MODEL_DB.sqls.length.should == 0
|
|
649
747
|
end
|
|
650
748
|
|
|
651
749
|
it "should eagerly graph multiple associations in separate calls" do
|
|
@@ -655,7 +753,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
655
753
|
a = a.first
|
|
656
754
|
a.tags.should == [Tag.load(:id=>2)]
|
|
657
755
|
a.albums.should == [Album.load(:id=>3)]
|
|
658
|
-
MODEL_DB.sqls.length.should ==
|
|
756
|
+
MODEL_DB.sqls.length.should == 0
|
|
659
757
|
end
|
|
660
758
|
|
|
661
759
|
it "should allow cascading of eager graphing for associations of associated models" do
|
|
@@ -665,24 +763,18 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
665
763
|
a = a.first
|
|
666
764
|
a.tags.should == [Tag.load(:id=>2)]
|
|
667
765
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
668
|
-
MODEL_DB.sqls.length.should ==
|
|
766
|
+
MODEL_DB.sqls.length.should == 0
|
|
669
767
|
end
|
|
670
768
|
|
|
671
769
|
it "eager graphing should eliminate duplicates caused by cartesian products" do
|
|
672
770
|
ds = @c1.eager_graph(:tags)
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
# Assume artist has 2 albums each with 2 tags
|
|
676
|
-
yield({:id=>1, :tags_id=>2})
|
|
677
|
-
yield({:id=>1, :tags_id=>3})
|
|
678
|
-
yield({:id=>1, :tags_id=>2})
|
|
679
|
-
yield({:id=>1, :tags_id=>3})
|
|
680
|
-
end
|
|
771
|
+
# Assume artist has 2 albums each with 2 tags
|
|
772
|
+
ds._fetch = [{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]
|
|
681
773
|
a = ds.all
|
|
682
774
|
a.should == [@c1.load(:id=>1)]
|
|
683
775
|
MODEL_DB.sqls.should == ['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)']
|
|
684
776
|
a.first.tags.should == [Tag.load(:id=>2), Tag.load(:id=>3)]
|
|
685
|
-
MODEL_DB.sqls.length.should ==
|
|
777
|
+
MODEL_DB.sqls.length.should == 0
|
|
686
778
|
end
|
|
687
779
|
|
|
688
780
|
it "should eager graph multiple associations from the same table" do
|
|
@@ -692,7 +784,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
692
784
|
a = a.first
|
|
693
785
|
a.tags.should == [Tag.load(:id=>2)]
|
|
694
786
|
a.other_tags.should == [Tag.load(:id=>9)]
|
|
695
|
-
MODEL_DB.sqls.length.should ==
|
|
787
|
+
MODEL_DB.sqls.length.should == 0
|
|
696
788
|
end
|
|
697
789
|
|
|
698
790
|
it "should eager graph a self_referential association" do
|
|
@@ -702,11 +794,11 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
702
794
|
a = a.first
|
|
703
795
|
a.tags.should == [Tag.load(:id=>2)]
|
|
704
796
|
a.artists.should == [@c1.load(:id=>10)]
|
|
705
|
-
MODEL_DB.sqls.length.should ==
|
|
797
|
+
MODEL_DB.sqls.length.should == 0
|
|
706
798
|
end
|
|
707
799
|
|
|
708
|
-
it "eager graphing should give you a
|
|
709
|
-
@c1.eager_graph(:tags, :artists).first.should == {:
|
|
800
|
+
it "eager graphing should give you a plain hash when called without .all" do
|
|
801
|
+
@c1.eager_graph(:tags, :artists).first.should == {:albums_0_id=>3, :artists_0_id=>10, :id=>1, :tags_id=>2}
|
|
710
802
|
end
|
|
711
803
|
|
|
712
804
|
it "should be able to use eager and eager_graph together" do
|
|
@@ -717,31 +809,22 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
717
809
|
a = a.first
|
|
718
810
|
a.tags.should == [Tag.load(:id=>2)]
|
|
719
811
|
a.albums.should == [Album.load(:id=>3)]
|
|
720
|
-
MODEL_DB.sqls.length.should ==
|
|
812
|
+
MODEL_DB.sqls.length.should == 0
|
|
721
813
|
end
|
|
722
814
|
|
|
723
815
|
it "should handle no associated records when eagerly graphing a single many_through_many association" do
|
|
724
816
|
ds = @c1.eager_graph(:tags)
|
|
725
|
-
|
|
726
|
-
@db << sql
|
|
727
|
-
yield({:id=>1, :tags_id=>nil})
|
|
728
|
-
end
|
|
817
|
+
ds._fetch = {:id=>1, :tags_id=>nil}
|
|
729
818
|
a = ds.all
|
|
730
819
|
a.should == [@c1.load(:id=>1)]
|
|
731
820
|
MODEL_DB.sqls.should == ['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)']
|
|
732
821
|
a.first.tags.should == []
|
|
733
|
-
MODEL_DB.sqls.length.should ==
|
|
822
|
+
MODEL_DB.sqls.length.should == 0
|
|
734
823
|
end
|
|
735
824
|
|
|
736
825
|
it "should handle no associated records when eagerly graphing multiple many_through_many associations" do
|
|
737
826
|
ds = @c1.eager_graph(:tags, :albums)
|
|
738
|
-
|
|
739
|
-
@db << sql
|
|
740
|
-
yield({:id=>1, :tags_id=>nil, :albums_0_id=>3})
|
|
741
|
-
yield({:id=>1, :tags_id=>2, :albums_0_id=>nil})
|
|
742
|
-
yield({:id=>1, :tags_id=>5, :albums_0_id=>6})
|
|
743
|
-
yield({:id=>7, :tags_id=>nil, :albums_0_id=>nil})
|
|
744
|
-
end
|
|
827
|
+
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}]
|
|
745
828
|
a = ds.all
|
|
746
829
|
a.should == [@c1.load(:id=>1), @c1.load(:id=>7)]
|
|
747
830
|
MODEL_DB.sqls.should == ['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)']
|
|
@@ -749,17 +832,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
749
832
|
a.first.albums.should == [Album.load(:id=>3), Album.load(:id=>6)]
|
|
750
833
|
a.last.tags.should == []
|
|
751
834
|
a.last.albums.should == []
|
|
752
|
-
MODEL_DB.sqls.length.should ==
|
|
835
|
+
MODEL_DB.sqls.length.should == 0
|
|
753
836
|
end
|
|
754
837
|
|
|
755
838
|
it "should handle missing associated records when cascading eager graphing for associations of associated models" do
|
|
756
839
|
ds = @c1.eager_graph(:tags=>:tracks)
|
|
757
|
-
|
|
758
|
-
@db << sql
|
|
759
|
-
yield({:id=>1, :tags_id=>2, :tracks_id=>4})
|
|
760
|
-
yield({:id=>1, :tags_id=>3, :tracks_id=>nil})
|
|
761
|
-
yield({:id=>2, :tags_id=>nil, :tracks_id=>nil})
|
|
762
|
-
end
|
|
840
|
+
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}]
|
|
763
841
|
a = ds.all
|
|
764
842
|
a.should == [@c1.load(:id=>1), @c1.load(:id=>2)]
|
|
765
843
|
MODEL_DB.sqls.should == ['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)']
|
|
@@ -768,7 +846,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
768
846
|
a.tags.should == [Tag.load(:id=>2), Tag.load(:id=>3)]
|
|
769
847
|
a.tags.first.tracks.should == [Track.load(:id=>4)]
|
|
770
848
|
a.tags.last.tracks.should == []
|
|
771
|
-
MODEL_DB.sqls.length.should ==
|
|
849
|
+
MODEL_DB.sqls.length.should == 0
|
|
772
850
|
end
|
|
773
851
|
|
|
774
852
|
it "eager graphing should respect :left_primary_key and :right_primary_key options" do
|
|
@@ -776,15 +854,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
776
854
|
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
777
855
|
Tag.dataset.meta_def(:columns){[:id, :tag_id]}
|
|
778
856
|
ds = @c1.eager_graph(:tags)
|
|
779
|
-
|
|
780
|
-
@db << sql
|
|
781
|
-
yield({:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4})
|
|
782
|
-
end
|
|
857
|
+
ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
|
|
783
858
|
a = ds.all
|
|
784
859
|
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
|
785
860
|
MODEL_DB.sqls.should == ['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)']
|
|
786
861
|
a.first.tags.should == [Tag.load(:id=>2, :tag_id=>4)]
|
|
787
|
-
MODEL_DB.sqls.length.should ==
|
|
862
|
+
MODEL_DB.sqls.length.should == 0
|
|
788
863
|
end
|
|
789
864
|
|
|
790
865
|
it "eager graphing should respect composite keys" do
|
|
@@ -792,29 +867,23 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
792
867
|
@c1.dataset.meta_def(:columns){[:id, :yyy]}
|
|
793
868
|
Tag.dataset.meta_def(:columns){[:id, :tag_id]}
|
|
794
869
|
ds = @c1.eager_graph(:tags)
|
|
795
|
-
|
|
796
|
-
@db << sql
|
|
797
|
-
yield({:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4})
|
|
798
|
-
end
|
|
870
|
+
ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
|
|
799
871
|
a = ds.all
|
|
800
872
|
a.should == [@c1.load(:id=>1, :yyy=>8)]
|
|
801
873
|
MODEL_DB.sqls.should == ['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))']
|
|
802
874
|
a.first.tags.should == [Tag.load(:id=>2, :tag_id=>4)]
|
|
803
|
-
MODEL_DB.sqls.length.should ==
|
|
875
|
+
MODEL_DB.sqls.length.should == 0
|
|
804
876
|
end
|
|
805
877
|
|
|
806
878
|
it "should respect the association's :graph_select option" do
|
|
807
879
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
|
|
808
880
|
ds = @c1.eager_graph(:tags)
|
|
809
|
-
|
|
810
|
-
@db << sql
|
|
811
|
-
yield({:id=>1, :b=>2})
|
|
812
|
-
end
|
|
881
|
+
ds._fetch = {:id=>1, :b=>2}
|
|
813
882
|
a = ds.all
|
|
814
883
|
a.should == [@c1.load(:id=>1)]
|
|
815
884
|
MODEL_DB.sqls.should == ['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)']
|
|
816
885
|
a.first.tags.should == [Tag.load(:b=>2)]
|
|
817
|
-
MODEL_DB.sqls.length.should ==
|
|
886
|
+
MODEL_DB.sqls.length.should == 0
|
|
818
887
|
end
|
|
819
888
|
|
|
820
889
|
it "should respect the association's :graph_join_type option" do
|
|
@@ -845,12 +914,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
845
914
|
end
|
|
846
915
|
|
|
847
916
|
it "should respect the association's :graph_block option" do
|
|
848
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_block=>proc{|ja,lja,js| {
|
|
917
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}
|
|
849
918
|
@c1.eager_graph(:tags).sql.should == '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) AND (tags.active IS TRUE))'
|
|
850
919
|
end
|
|
851
920
|
|
|
852
921
|
it "should respect the association's :block option on through" do
|
|
853
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :block=>proc{|ja,lja,js| {
|
|
922
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id, :block=>proc{|ja,lja,js| {Sequel.qualify(ja, :active)=>true}}}, [:albums_tags, :album_id, :tag_id]]
|
|
854
923
|
@c1.eager_graph(:tags).sql.should == '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) AND (albums.active IS TRUE)) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)'
|
|
855
924
|
end
|
|
856
925
|
|
|
@@ -874,7 +943,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
874
943
|
end
|
|
875
944
|
|
|
876
945
|
it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
|
|
877
|
-
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[:blah__id.identifier
|
|
946
|
+
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], {:table=>:albums, :left=>:id, :right=>:id}, [:albums_tags, :album_id, :tag_id]], :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
|
878
947
|
@c1.order(:artists__blah2, :artists__blah3).eager_graph(:tags).sql.should == '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) ORDER BY artists.blah2, artists.blah3, tags.blah__id, tags.blah__id DESC, blah.id DESC, blah.id, tags.album_id, tags.album_id DESC, 1, RANDOM(), b.a'
|
|
879
948
|
end
|
|
880
949
|
|
|
@@ -901,3 +970,48 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
|
901
970
|
@c1.eager_graph(:tags, :albums).sql.should == '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) AND (albums_artists.a = artists.b)) 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) AND (albums_artists_0.c = artists.d)) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id)'
|
|
902
971
|
end
|
|
903
972
|
end
|
|
973
|
+
|
|
974
|
+
describe "many_through_many associations with non-column expression keys" do
|
|
975
|
+
before do
|
|
976
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :object_ids=>[2]})
|
|
977
|
+
@Foo = Class.new(Sequel::Model(@db[:foos]))
|
|
978
|
+
@Foo.columns :id, :object_ids
|
|
979
|
+
@Foo.plugin :many_through_many
|
|
980
|
+
m = Module.new{def obj_id; object_ids[0]; end}
|
|
981
|
+
@Foo.include m
|
|
982
|
+
|
|
983
|
+
@Foo.many_through_many :foos, [
|
|
984
|
+
[:f, Sequel.subscript(:l, 0), Sequel.subscript(:r, 0)],
|
|
985
|
+
[:f, Sequel.subscript(:l, 1), Sequel.subscript(:r, 1)]
|
|
986
|
+
], :class=>@Foo, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id
|
|
987
|
+
@foo = @Foo.load(:id=>1, :object_ids=>[2])
|
|
988
|
+
@db.sqls
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
it "should have working regular association methods" do
|
|
992
|
+
@Foo.first.foos.should == [@foo]
|
|
993
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT foos.* FROM foos INNER JOIN f ON (f.r[1] = foos.object_ids[0]) INNER JOIN f AS f_0 ON ((f_0.r[0] = f.l[1]) AND (f_0.l[0] = 2))"]
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
it "should have working eager loading methods" do
|
|
997
|
+
@db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
|
|
998
|
+
@Foo.eager(:foos).all.map{|o| [o, o.foos]}.should == [[@foo, [@foo]]]
|
|
999
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT foos.*, f_0.l[0] AS x_foreign_key_x FROM foos INNER JOIN f ON (f.r[1] = foos.object_ids[0]) INNER JOIN f AS f_0 ON ((f_0.r[0] = f.l[1]) AND (f_0.l[0] IN (2)))"]
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
it "should have working eager graphing methods" do
|
|
1003
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :foos_0_id=>1, :foos_0_object_ids=>[2]}
|
|
1004
|
+
@Foo.eager_graph(:foos).all.map{|o| [o, o.foos]}.should == [[@foo, [@foo]]]
|
|
1005
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, foos_0.id AS foos_0_id, foos_0.object_ids AS foos_0_object_ids FROM foos LEFT OUTER JOIN f ON (f.l[0] = foos.object_ids[0]) LEFT OUTER JOIN f AS f_0 ON (f_0.l[1] = f.r[0]) LEFT OUTER JOIN foos AS foos_0 ON (foos_0.object_ids[0] = f_0.r[1])"]
|
|
1006
|
+
end
|
|
1007
|
+
|
|
1008
|
+
it "should have working filter by associations with model instances" do
|
|
1009
|
+
@Foo.first(:foos=>@foo).should == @foo
|
|
1010
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT f.l[0] FROM f INNER JOIN f AS f_0 ON (f_0.l[1] = f.r[0]) WHERE ((f_0.r[1] = 2) AND (f.l[0] IS NOT NULL)))) LIMIT 1"]
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
it "should have working filter by associations with model datasets" do
|
|
1014
|
+
@Foo.first(:foos=>@Foo.where(:id=>@foo.id)).should == @foo
|
|
1015
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT f.l[0] FROM f INNER JOIN f AS f_0 ON (f_0.l[1] = f.r[0]) WHERE ((f_0.r[1] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) AND (f.l[0] IS NOT NULL)))) LIMIT 1"]
|
|
1016
|
+
end
|
|
1017
|
+
end
|