sequel 4.9.0 → 4.10.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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +79 -1
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/Rakefile +2 -12
  6. data/bin/sequel +1 -0
  7. data/doc/advanced_associations.rdoc +82 -25
  8. data/doc/association_basics.rdoc +21 -22
  9. data/doc/core_extensions.rdoc +1 -1
  10. data/doc/opening_databases.rdoc +7 -0
  11. data/doc/release_notes/4.10.0.txt +226 -0
  12. data/doc/security.rdoc +1 -0
  13. data/doc/testing.rdoc +7 -7
  14. data/doc/transactions.rdoc +8 -0
  15. data/lib/sequel/adapters/jdbc.rb +160 -168
  16. data/lib/sequel/adapters/jdbc/db2.rb +17 -18
  17. data/lib/sequel/adapters/jdbc/derby.rb +5 -28
  18. data/lib/sequel/adapters/jdbc/h2.rb +11 -22
  19. data/lib/sequel/adapters/jdbc/hsqldb.rb +31 -18
  20. data/lib/sequel/adapters/jdbc/jtds.rb +0 -15
  21. data/lib/sequel/adapters/jdbc/oracle.rb +36 -35
  22. data/lib/sequel/adapters/jdbc/postgresql.rb +72 -90
  23. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +18 -16
  24. data/lib/sequel/adapters/jdbc/sqlite.rb +7 -0
  25. data/lib/sequel/adapters/jdbc/sqlserver.rb +10 -30
  26. data/lib/sequel/adapters/jdbc/transactions.rb +5 -6
  27. data/lib/sequel/adapters/openbase.rb +1 -7
  28. data/lib/sequel/adapters/postgres.rb +1 -1
  29. data/lib/sequel/adapters/shared/access.rb +3 -6
  30. data/lib/sequel/adapters/shared/cubrid.rb +24 -9
  31. data/lib/sequel/adapters/shared/db2.rb +13 -5
  32. data/lib/sequel/adapters/shared/firebird.rb +16 -16
  33. data/lib/sequel/adapters/shared/informix.rb +2 -5
  34. data/lib/sequel/adapters/shared/mssql.rb +72 -63
  35. data/lib/sequel/adapters/shared/mysql.rb +72 -40
  36. data/lib/sequel/adapters/shared/oracle.rb +27 -15
  37. data/lib/sequel/adapters/shared/postgres.rb +24 -44
  38. data/lib/sequel/adapters/shared/progress.rb +1 -5
  39. data/lib/sequel/adapters/shared/sqlanywhere.rb +26 -18
  40. data/lib/sequel/adapters/shared/sqlite.rb +21 -6
  41. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -1
  42. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -2
  43. data/lib/sequel/adapters/utils/split_alter_table.rb +8 -0
  44. data/lib/sequel/core.rb +14 -9
  45. data/lib/sequel/database/dataset_defaults.rb +1 -0
  46. data/lib/sequel/database/misc.rb +12 -0
  47. data/lib/sequel/database/query.rb +4 -1
  48. data/lib/sequel/database/schema_methods.rb +3 -2
  49. data/lib/sequel/database/transactions.rb +47 -17
  50. data/lib/sequel/dataset/features.rb +12 -2
  51. data/lib/sequel/dataset/mutation.rb +2 -0
  52. data/lib/sequel/dataset/placeholder_literalizer.rb +12 -4
  53. data/lib/sequel/dataset/prepared_statements.rb +6 -0
  54. data/lib/sequel/dataset/query.rb +1 -1
  55. data/lib/sequel/dataset/sql.rb +132 -70
  56. data/lib/sequel/extensions/columns_introspection.rb +1 -1
  57. data/lib/sequel/extensions/null_dataset.rb +8 -4
  58. data/lib/sequel/extensions/pg_array.rb +4 -4
  59. data/lib/sequel/extensions/pg_row.rb +1 -0
  60. data/lib/sequel/model/associations.rb +468 -188
  61. data/lib/sequel/model/base.rb +88 -13
  62. data/lib/sequel/plugins/association_pks.rb +23 -64
  63. data/lib/sequel/plugins/auto_validations.rb +3 -2
  64. data/lib/sequel/plugins/dataset_associations.rb +1 -3
  65. data/lib/sequel/plugins/many_through_many.rb +18 -65
  66. data/lib/sequel/plugins/pg_array_associations.rb +97 -86
  67. data/lib/sequel/plugins/prepared_statements.rb +2 -1
  68. data/lib/sequel/plugins/prepared_statements_associations.rb +36 -27
  69. data/lib/sequel/plugins/rcte_tree.rb +12 -16
  70. data/lib/sequel/plugins/sharding.rb +21 -3
  71. data/lib/sequel/plugins/single_table_inheritance.rb +2 -1
  72. data/lib/sequel/plugins/subclasses.rb +1 -9
  73. data/lib/sequel/plugins/tactical_eager_loading.rb +9 -0
  74. data/lib/sequel/plugins/tree.rb +2 -2
  75. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  76. data/lib/sequel/version.rb +1 -1
  77. data/spec/adapters/mssql_spec.rb +57 -15
  78. data/spec/adapters/mysql_spec.rb +11 -0
  79. data/spec/bin_spec.rb +2 -2
  80. data/spec/core/database_spec.rb +38 -4
  81. data/spec/core/dataset_spec.rb +45 -7
  82. data/spec/core/placeholder_literalizer_spec.rb +17 -0
  83. data/spec/core/schema_spec.rb +6 -1
  84. data/spec/extensions/active_model_spec.rb +18 -9
  85. data/spec/extensions/association_pks_spec.rb +20 -18
  86. data/spec/extensions/association_proxies_spec.rb +9 -9
  87. data/spec/extensions/auto_validations_spec.rb +6 -0
  88. data/spec/extensions/columns_introspection_spec.rb +1 -0
  89. data/spec/extensions/constraint_validations_spec.rb +3 -1
  90. data/spec/extensions/many_through_many_spec.rb +191 -111
  91. data/spec/extensions/pg_array_associations_spec.rb +133 -103
  92. data/spec/extensions/prepared_statements_associations_spec.rb +23 -4
  93. data/spec/extensions/rcte_tree_spec.rb +35 -27
  94. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -1
  95. data/spec/extensions/sharding_spec.rb +2 -2
  96. data/spec/extensions/tactical_eager_loading_spec.rb +4 -0
  97. data/spec/extensions/to_dot_spec.rb +1 -0
  98. data/spec/extensions/touch_spec.rb +2 -2
  99. data/spec/integration/associations_test.rb +130 -37
  100. data/spec/integration/dataset_test.rb +17 -0
  101. data/spec/integration/model_test.rb +17 -0
  102. data/spec/integration/schema_test.rb +14 -0
  103. data/spec/integration/transaction_test.rb +25 -1
  104. data/spec/model/association_reflection_spec.rb +63 -24
  105. data/spec/model/associations_spec.rb +104 -57
  106. data/spec/model/base_spec.rb +14 -1
  107. data/spec/model/class_dataset_methods_spec.rb +1 -0
  108. data/spec/model/eager_loading_spec.rb +221 -74
  109. data/spec/model/model_spec.rb +119 -1
  110. metadata +4 -2
@@ -1148,6 +1148,11 @@ describe "Dataset#from" do
1148
1148
  @dataset.from(:a, @dataset.from(:b).lateral).select_sql.should == "SELECT * FROM a, LATERAL (SELECT * FROM b) AS t1"
1149
1149
  end
1150
1150
 
1151
+ specify "should automatically use a default from table if no from table is present" do
1152
+ def @dataset.empty_from_sql; ' FROM DEFFROM'; end
1153
+ @dataset.select_sql.should == "SELECT * FROM DEFFROM"
1154
+ end
1155
+
1151
1156
  specify "should accept :schema__table___alias symbol format" do
1152
1157
  @dataset.from(:abc__def).select_sql.should == "SELECT * FROM abc.def"
1153
1158
  @dataset.from(:a_b__c).select_sql.should == "SELECT * FROM a_b.c"
@@ -2253,7 +2258,9 @@ describe "Dataset#join_table" do
2253
2258
  specify "should hoist WITH clauses from subqueries if the dataset doesn't support CTEs in subselects" do
2254
2259
  meta_def(@d, :supports_cte?){true}
2255
2260
  meta_def(@d, :supports_cte_in_subselect?){false}
2256
- @d.join(Sequel.mock.dataset.from(:categories).with(:a, Sequel.mock.dataset.from(:b)), [:id]).sql.should == 'WITH "a" AS (SELECT * FROM b) SELECT * FROM "items" INNER JOIN (SELECT * FROM categories) AS "t1" USING ("id")'
2261
+ ds = Sequel.mock.dataset.from(:categories)
2262
+ meta_def(ds, :supports_cte?){true}
2263
+ @d.join(ds.with(:a, Sequel.mock.dataset.from(:b)), [:id]).sql.should == 'WITH "a" AS (SELECT * FROM b) SELECT * FROM "items" INNER JOIN (SELECT * FROM categories) AS "t1" USING ("id")'
2257
2264
  end
2258
2265
 
2259
2266
  specify "should raise an error if using an array of symbols with a block" do
@@ -2895,6 +2902,7 @@ describe "Dataset#import" do
2895
2902
  "INSERT INTO items (x, y) VALUES (5, 6)",
2896
2903
  'COMMIT']
2897
2904
  end
2905
+
2898
2906
  specify "should accept a columns array and a values array with :slice option" do
2899
2907
  @ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]], :slice => 2)
2900
2908
  @db.sqls.should == ['BEGIN',
@@ -2905,6 +2913,31 @@ describe "Dataset#import" do
2905
2913
  "INSERT INTO items (x, y) VALUES (5, 6)",
2906
2914
  'COMMIT']
2907
2915
  end
2916
+
2917
+ specify "should use correct sql for :values strategy" do
2918
+ def @ds.multi_insert_sql_strategy; :values end
2919
+ @ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]])
2920
+ @db.sqls.should == ['BEGIN',
2921
+ "INSERT INTO items (x, y) VALUES (1, 2), (3, 4), (5, 6)",
2922
+ 'COMMIT']
2923
+ end
2924
+
2925
+ specify "should use correct sql for :union strategy" do
2926
+ def @ds.multi_insert_sql_strategy; :union end
2927
+ @ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]])
2928
+ @db.sqls.should == ['BEGIN',
2929
+ "INSERT INTO items (x, y) SELECT 1, 2 UNION ALL SELECT 3, 4 UNION ALL SELECT 5, 6",
2930
+ 'COMMIT']
2931
+ end
2932
+
2933
+ specify "should use correct sql for :union strategy when FROM is required" do
2934
+ def @ds.empty_from_sql; ' FROM foo' end
2935
+ def @ds.multi_insert_sql_strategy; :union end
2936
+ @ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]])
2937
+ @db.sqls.should == ['BEGIN',
2938
+ "INSERT INTO items (x, y) SELECT 1, 2 FROM foo UNION ALL SELECT 3, 4 FROM foo UNION ALL SELECT 5, 6 FROM foo",
2939
+ 'COMMIT']
2940
+ end
2908
2941
  end
2909
2942
 
2910
2943
  describe "Dataset#multi_insert" do
@@ -3728,6 +3761,7 @@ describe "Sequel::Dataset #with and #with_recursive" do
3728
3761
  before do
3729
3762
  @db = Sequel::Database.new
3730
3763
  @ds = @db[:t]
3764
+ def @ds.supports_cte?(*) true end
3731
3765
  end
3732
3766
 
3733
3767
  specify "#with should take a name and dataset and use a WITH clause" do
@@ -3766,9 +3800,10 @@ describe "Sequel::Dataset #with and #with_recursive" do
3766
3800
  end
3767
3801
 
3768
3802
  specify "#with should work on insert, update, and delete statements if they support it" do
3769
- [:insert, :update, :delete].each do |m|
3770
- meta_def(@ds, :"#{m}_clause_methods"){[:"#{m}_with_sql"] + super()}
3771
- end
3803
+ sc = class << @ds; self; end
3804
+ Sequel::Dataset.def_sql_method(sc, :delete, %w'with delete from where')
3805
+ Sequel::Dataset.def_sql_method(sc, :insert, %w'with insert into columns values')
3806
+ Sequel::Dataset.def_sql_method(sc, :update, %w'with update table set where')
3772
3807
  @ds.with(:t, @db[:x]).insert_sql(1).should == 'WITH t AS (SELECT * FROM x) INSERT INTO t VALUES (1)'
3773
3808
  @ds.with(:t, @db[:x]).update_sql(:foo=>1).should == 'WITH t AS (SELECT * FROM x) UPDATE t SET foo = 1'
3774
3809
  @ds.with(:t, @db[:x]).delete_sql.should == 'WITH t AS (SELECT * FROM x) DELETE FROM t'
@@ -4318,9 +4353,11 @@ describe "Dataset#returning" do
4318
4353
  before do
4319
4354
  @ds = Sequel.mock(:fetch=>proc{|s| {:foo=>s}})[:t].returning(:foo)
4320
4355
  @pr = proc do
4321
- [:insert, :update, :delete].each do |m|
4322
- meta_def(@ds, :"#{m}_clause_methods"){super() + [:"#{m}_returning_sql"]}
4323
- end
4356
+ def @ds.supports_returning?(*) true end
4357
+ sc = class << @ds; self; end
4358
+ Sequel::Dataset.def_sql_method(sc, :delete, %w'delete from where returning')
4359
+ Sequel::Dataset.def_sql_method(sc, :insert, %w'insert into columns values returning')
4360
+ Sequel::Dataset.def_sql_method(sc, :update, %w'update table set where returning')
4324
4361
  end
4325
4362
  end
4326
4363
 
@@ -4721,6 +4758,7 @@ end
4721
4758
  describe "Dataset mutation methods" do
4722
4759
  def m(&block)
4723
4760
  ds = Sequel.mock[:t]
4761
+ def ds.supports_cte?(*) true end
4724
4762
  ds.instance_exec(&block)
4725
4763
  ds.sql
4726
4764
  end
@@ -29,6 +29,18 @@ describe "Dataset::PlaceholderLiteralizer" do
29
29
  @db.sqls.should == ["SELECT * FROM items WHERE ((a = 1) AND (b = (c + 1)) AND (id = 1))", "SELECT * FROM items WHERE ((a = 2) AND (b = (d + 1)) AND (id = 2))"]
30
30
  end
31
31
 
32
+ specify "should handle calls with placeholders and delayed arguments" do
33
+ h = :h
34
+ s = :s
35
+ d = @ds.having(Sequel.delay{h}).select(Sequel.delay{s})
36
+ loader = @c.loader(d){|pl, ds| ds.where(:a=>pl.arg).where(:b=>Sequel.+(pl.arg, 1)).where(pl.arg)}
37
+ loader.first(1, :c, :id=>1).should == @h
38
+ h = :h2
39
+ s = :s2
40
+ loader.first(2, :d, :id=>2).should == @h
41
+ @db.sqls.should == ["SELECT s FROM items WHERE ((a = 1) AND (b = (c + 1)) AND (id = 1)) HAVING h", "SELECT s2 FROM items WHERE ((a = 2) AND (b = (d + 1)) AND (id = 2)) HAVING h2"]
42
+ end
43
+
32
44
  specify "should handle calls with a placeholders used as filter arguments" do
33
45
  loader = @c.loader(@ds){|pl, ds| ds.where(pl.arg)}
34
46
  loader.first(:id=>1).should == @h
@@ -101,6 +113,11 @@ describe "Dataset::PlaceholderLiteralizer" do
101
113
  @db.sqls.should == ["SELECT * FROM items WHERE (a = 2)"]
102
114
  end
103
115
 
116
+ specify "should literalize args as NULL if :placeholder_literal_null is set" do
117
+ loader = @c.loader(@ds){|pl, ds| ds.where(pl.arg=>:a).clone(:placeholder_literal_null=>true)}
118
+ loader.sql(1).should == "SELECT * FROM items WHERE (NULL = a)"
119
+ end
120
+
104
121
  specify "should raise an error if called with an incorrect number of arguments" do
105
122
  loader = @c.loader(@ds){|pl, ds| ds.where(:a=>pl.arg)}
106
123
  proc{loader.first}.should raise_error(Sequel::Error)
@@ -1433,10 +1433,15 @@ describe "Database#drop_view" do
1433
1433
  @db.sqls.should == ['DROP VIEW cats', 'DROP VIEW dogs']
1434
1434
  end
1435
1435
 
1436
- specify "should take an options hash and support the :cascade option" do
1436
+ specify "should support the :cascade option" do
1437
1437
  @db.drop_view :cats, :dogs, :cascade=>true
1438
1438
  @db.sqls.should == ['DROP VIEW cats CASCADE', 'DROP VIEW dogs CASCADE']
1439
1439
  end
1440
+
1441
+ specify "should support the :if_exists option" do
1442
+ @db.drop_view :cats, :dogs, :if_exists=>true
1443
+ @db.sqls.should == ['DROP VIEW IF EXISTS cats', 'DROP VIEW IF EXISTS dogs']
1444
+ end
1440
1445
  end
1441
1446
 
1442
1447
  describe "Database#alter_table_sql" do
@@ -2,13 +2,22 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  begin
4
4
  require 'active_model'
5
- require 'test/unit'
6
- if Test::Unit.respond_to?(:run=)
7
- Test::Unit.run = false
8
- require 'test/unit/testresult'
9
- elsif defined?(MiniTest::Unit)
10
- class << MiniTest::Unit
11
- def autorun; end
5
+ begin
6
+ require 'minitest'
7
+ if defined?(MiniTest::Unit)
8
+ class << MiniTest::Unit
9
+ def autorun; end
10
+ end
11
+ end
12
+ if defined?(MiniTest::Test)
13
+ test_class = MiniTest::Test
14
+ end
15
+ rescue
16
+ require 'test/unit'
17
+ test_class = Test::Unit::TestCase
18
+ if Test::Unit.respond_to?(:run=)
19
+ Test::Unit.run = false
20
+ require 'test/unit/testresult'
12
21
  end
13
22
  end
14
23
  rescue LoadError => e
@@ -16,7 +25,7 @@ rescue LoadError => e
16
25
  else
17
26
  describe "ActiveModel plugin" do
18
27
  specify "should be compliant to the ActiveModel spec" do
19
- tc = Class.new(Test::Unit::TestCase)
28
+ tc = Class.new(test_class)
20
29
  tc.class_eval do
21
30
  define_method(:setup) do
22
31
  class ::AMLintTest < Sequel::Model
@@ -94,7 +103,7 @@ describe "ActiveModel plugin" do
94
103
  end
95
104
 
96
105
  end
97
- if defined?(MiniTest::Unit)
106
+ if defined?(MiniTest::Test) || defined?(MiniTest::Unit)
98
107
  tc.instance_methods.map{|x| x.to_s}.reject{|n| n !~ /\Atest_/}.each do |m|
99
108
  i = tc.new(m)
100
109
  i.setup
@@ -89,8 +89,10 @@ describe "Sequel::Plugins::AssociationPks" do
89
89
  sqls = @db.sqls
90
90
  sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
91
91
  sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
92
- sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
93
- sqls.length.should == 3
92
+ sqls[2].should == 'BEGIN'
93
+ sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
94
+ sqls[4].should == 'COMMIT'
95
+ sqls.length.should == 5
94
96
  end
95
97
 
96
98
  specify "should return correct right-side associated cpks for one_to_many associations" do
@@ -119,9 +121,9 @@ describe "Sequel::Plugins::AssociationPks" do
119
121
  sqls = @db.sqls
120
122
  sqls[0].should == "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN (('F1', 'L1'), ('F2', 'L2'))))"
121
123
  sqls[1].should == 'SELECT first, last FROM albums_vocalists WHERE (album_id = 2)'
122
- match = sqls[2].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
124
+ match = sqls[3].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
123
125
  Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F1'", "last"=>"'L1'", "album_id"=>"2"}
124
- sqls.length.should == 3
126
+ sqls.length.should == 5
125
127
  end
126
128
 
127
129
  specify "should return correct associated pks for left-side cpks for one_to_many associations" do
@@ -152,9 +154,9 @@ describe "Sequel::Plugins::AssociationPks" do
152
154
  sqls = @db.sqls
153
155
  sqls[0].should == "DELETE FROM vocalists_instruments WHERE ((first = 'F2') AND (last = 'L2') AND (instrument_id NOT IN (1, 2)))"
154
156
  sqls[1].should == "SELECT instrument_id FROM vocalists_instruments WHERE ((first = 'F2') AND (last = 'L2'))"
155
- match = sqls[2].match(/INSERT INTO vocalists_instruments \((.*)\) VALUES \((.*)\)/)
157
+ match = sqls[3].match(/INSERT INTO vocalists_instruments \((.*)\) VALUES \((.*)\)/)
156
158
  Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "instrument_id"=>"1"}
157
- sqls.length.should == 3
159
+ sqls.length.should == 5
158
160
  end
159
161
 
160
162
  specify "should return correct right-side associated cpks for left-side cpks for one_to_many associations" do
@@ -185,9 +187,9 @@ describe "Sequel::Plugins::AssociationPks" do
185
187
  sqls = @db.sqls
186
188
  sqls[0].should == "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
187
189
  sqls[1].should == "SELECT year, week FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2'))"
188
- match = sqls[2].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
190
+ match = sqls[3].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
189
191
  Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "year"=>"1997", "week"=>"1"}
190
- sqls.length.should == 3
192
+ sqls.length.should == 5
191
193
  end
192
194
 
193
195
  specify "should use transactions if the object is configured to use transactions" do
@@ -231,8 +233,8 @@ describe "Sequel::Plugins::AssociationPks" do
231
233
  sqls = @db.sqls
232
234
  sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
233
235
  sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
234
- sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
235
- sqls.length.should == 3
236
+ sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
237
+ sqls.length.should == 5
236
238
  end
237
239
 
238
240
  specify "should not automatically convert keys to numbers if the primary key is an integer for many_to_many associations" do
@@ -241,9 +243,9 @@ describe "Sequel::Plugins::AssociationPks" do
241
243
  sqls = @db.sqls
242
244
  sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN ('1', '3')))"
243
245
  sqls[1].should == 'SELECT tag_id FROM albums_tags WHERE (album_id = 2)'
244
- sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '1'|'1', 2)\)/
245
- sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '3'|'3', 2)\)/
246
- sqls.length.should == 4
246
+ sqls[3].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '1'|'1', 2)\)/
247
+ sqls[4].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '3'|'3', 2)\)/
248
+ sqls.length.should == 6
247
249
  end
248
250
 
249
251
  specify "should automatically convert keys to numbers for appropriate integer primary key for composite key associations" do
@@ -254,9 +256,9 @@ describe "Sequel::Plugins::AssociationPks" do
254
256
  sqls = @db.sqls
255
257
  sqls[0].should == "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
256
258
  sqls[1].should == "SELECT year, week FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2'))"
257
- match = sqls[2].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
259
+ match = sqls[3].match(/INSERT INTO vocalists_hits \((.*)\) VALUES \((.*)\)/)
258
260
  Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"'F2'", "last"=>"'L2'", "year"=>"1997", "week"=>"1"}
259
- sqls.length.should == 3
261
+ sqls.length.should == 5
260
262
 
261
263
  @Vocalist.db_schema[:first][:type] = :integer
262
264
  @Vocalist.db_schema[:last][:type] = :integer
@@ -270,10 +272,10 @@ describe "Sequel::Plugins::AssociationPks" do
270
272
  sqls = @db.sqls
271
273
  sqls[0].should == "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN ((11, 11), (12, 12))))"
272
274
  sqls[1].should == 'SELECT first, last FROM albums_vocalists WHERE (album_id = 2)'
273
- match = sqls[2].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
274
- Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"11", "last"=>"11", "album_id"=>"2"}
275
275
  match = sqls[3].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
276
+ Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"11", "last"=>"11", "album_id"=>"2"}
277
+ match = sqls[4].match(/INSERT INTO albums_vocalists \((.*)\) VALUES \((.*)\)/)
276
278
  Hash[match[1].split(', ').zip(match[2].split(', '))].should == {"first"=>"12", "last"=>"12", "album_id"=>"2"}
277
- sqls.length.should == 4
279
+ sqls.length.should == 6
278
280
  end
279
281
  end
@@ -25,7 +25,7 @@ describe "Sequel::Plugins::AssociationProxies" do
25
25
 
26
26
  it "should send method calls to the association dataset if sent a non-array method" do
27
27
  @i.associations.has_key?(:tags).should == false
28
- @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
28
+ @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
29
29
  @i.associations.has_key?(:tags).should == false
30
30
  end
31
31
 
@@ -34,9 +34,9 @@ describe "Sequel::Plugins::AssociationProxies" do
34
34
  opts[:method] == :where || opts[:arguments].length == 2 || opts[:block]
35
35
  end
36
36
  @i.associations.has_key?(:tags).should == false
37
- @t.where(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
38
- @t.filter('a = ?', 1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
39
- @t.filter{{:a=>1}}.sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
37
+ @t.where(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
38
+ @t.filter('a = ?', 1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
39
+ @t.filter{{:a=>1}}.sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
40
40
 
41
41
  @i.associations.has_key?(:tags).should == false
42
42
  Item.plugin :association_proxies do |opts|
@@ -47,11 +47,11 @@ describe "Sequel::Plugins::AssociationProxies" do
47
47
  is_size && !cached && !proxy_arg && !proxy_block
48
48
  end
49
49
  @t.size.should == 1
50
- Item.db.sqls.should == ["SELECT count(*) AS count FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) LIMIT 1"]
50
+ Item.db.sqls.should == ["SELECT count(*) AS count FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE (items_tags.item_id = 1) LIMIT 1"]
51
51
  @i.tags{|ds| ds}.size.should == 1
52
- Item.db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1))"]
52
+ Item.db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE (items_tags.item_id = 1)"]
53
53
  @i.tags(true).size.should == 1
54
- Item.db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1))"]
54
+ Item.db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE (items_tags.item_id = 1)"]
55
55
  @t.size.should == 1
56
56
  Item.db.sqls.should == []
57
57
  end
@@ -63,7 +63,7 @@ describe "Sequel::Plugins::AssociationProxies" do
63
63
  Item.db.sqls.length.should == 0
64
64
  @i.tags(true).select{|x| false}.should == []
65
65
  Item.db.sqls.length.should == 1
66
- @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
66
+ @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
67
67
  Item.db.sqls.length.should == 0
68
68
  end
69
69
 
@@ -80,7 +80,7 @@ describe "Sequel::Plugins::AssociationProxies" do
80
80
  i.associations.has_key?(:tags).should == false
81
81
  i.tags.select{|x| false}.should == []
82
82
  i.associations.has_key?(:tags).should == true
83
- i.tags.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
83
+ i.tags.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON (items_tags.tag_id = tags.id) WHERE ((items_tags.item_id = 1) AND (a = 1))"
84
84
  end
85
85
 
86
86
  end
@@ -15,6 +15,7 @@ describe "Sequel::Plugins::AutoValidations" do
15
15
  end
16
16
  def db.supports_index_parsing?() true end
17
17
  def db.indexes(t, *)
18
+ raise if t.is_a?(Sequel::Dataset)
18
19
  return [] if t != :test
19
20
  {:a=>{:columns=>[:name, :num], :unique=>true}, :b=>{:columns=>[:num], :unique=>false}}
20
21
  end
@@ -50,6 +51,11 @@ describe "Sequel::Plugins::AutoValidations" do
50
51
  @m.valid?.should == true
51
52
  end
52
53
 
54
+ it "should handle models that select from subqueries" do
55
+ @c.set_dataset @c.dataset.from_self
56
+ proc{@c.send(:setup_auto_validations)}.should_not raise_error
57
+ end
58
+
53
59
  it "should support :not_null=>:presence option" do
54
60
  @c.plugin :auto_validations, :not_null=>:presence
55
61
  @m.set(:d=>Date.today, :num=>'')
@@ -74,6 +74,7 @@ describe "columns_introspection extension" do
74
74
 
75
75
  specify "should issue a database query when common table expressions are used" do
76
76
  @db.instance_variable_set(:@schemas, "a"=>[[:x, {}]])
77
+ def @ds.supports_cte?(*) true end
77
78
  @ds.with(:a, @ds).columns
78
79
  @db.sqls.length.should == 1
79
80
  end
@@ -133,7 +133,9 @@ describe "constraint_validations extension" do
133
133
  @db.extension(:constraint_validations)
134
134
  @db.create_table(:foo){String :name; validate{presence :name}}
135
135
  sqls = @db.sqls
136
- parse_insert(sqls.slice!(1)).should == {:validation_type=>"presence", :column=>"name", :table=>"foo"}
136
+ s = sqls.slice!(1)
137
+ m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z/.match(s)
138
+ Hash[*m[1].split(', ').map{|v| v.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten].should == {:validation_type=>"presence", :column=>"name", :table=>"foo"}
137
139
  sqls.should == ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) IS NOT NULL)))"]
138
140
  end
139
141
 
@@ -41,7 +41,7 @@ describe Sequel::Model, "many_through_many" do
41
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
42
  a = @c1.eager(:tags).all
43
43
  a.should == [@c1.load(:id => 1)]
44
- 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)))"]
44
+ 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) WHERE (albums_artists.artist_id IN (3))"]
45
45
  a.first.tags.should == [@c2.load(:id=>4)]
46
46
  DB.sqls.should == []
47
47
  end
@@ -52,7 +52,7 @@ describe Sequel::Model, "many_through_many" do
52
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
53
  a = @c1.eager(:tags).all
54
54
  a.should == [@c1.load(:id => 1)]
55
- 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)))"]
55
+ 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) WHERE ((albums_artists.artist_id / 3) IN (1))"]
56
56
  a.first.tags.should == [@c2.load(:id=>4)]
57
57
  end
58
58
 
@@ -82,7 +82,7 @@ describe Sequel::Model, "many_through_many" do
82
82
  it "should allow only two arguments with the :through option" do
83
83
  @c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
84
84
  n = @c1.load(: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))'
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) WHERE (albums_artists.artist_id = 1234)'
86
86
  n.tags.should == [@c2.load(:id=>1)]
87
87
  end
88
88
 
@@ -90,14 +90,14 @@ describe Sequel::Model, "many_through_many" do
90
90
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
91
91
  @c1.many_through_many :other_tags, :clone=>:tags
92
92
  n = @c1.load(: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))'
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) WHERE (albums_artists.artist_id = 1234)'
94
94
  n.tags.should == [@c2.load(:id=>1)]
95
95
  end
96
96
 
97
97
  it "should use join tables given" do
98
98
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
99
99
  n = @c1.load(: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))'
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) WHERE (albums_artists.artist_id = 1234)'
101
101
  n.tags.should == [@c2.load(:id=>1)]
102
102
  end
103
103
 
@@ -107,7 +107,7 @@ describe Sequel::Model, "many_through_many" do
107
107
  end
108
108
  @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]]
109
109
  n = @c1.load(:id => 1234)
110
- 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))'
110
+ 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) WHERE (albums_artists_1.artist_id = 1234)'
111
111
  n.albums.should == [Album.load(:id=>1, :x=>1)]
112
112
  ensure
113
113
  Object.send(:remove_const, :Album)
@@ -117,7 +117,7 @@ describe Sequel::Model, "many_through_many" do
117
117
  it "should use explicit class if given" do
118
118
  @c1.many_through_many :albums_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag
119
119
  n = @c1.load(:id => 1234)
120
- 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))'
120
+ 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) WHERE (albums_artists.artist_id = 1234)'
121
121
  n.albums_tags.should == [@c2.load(:id=>1)]
122
122
  end
123
123
 
@@ -125,7 +125,7 @@ describe Sequel::Model, "many_through_many" do
125
125
  @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
126
126
  n = @c1.load(:id => 1234)
127
127
  n.yyy = 85
128
- 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))'
128
+ 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) WHERE (albums_artists.artist_id = 85)'
129
129
  n.tags.should == [@c2.load(:id=>1)]
130
130
  end
131
131
 
@@ -133,7 +133,7 @@ describe Sequel::Model, "many_through_many" do
133
133
  @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]
134
134
  n = @c1.load(:id => 1234)
135
135
  n.yyy = 85
136
- 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))'
136
+ 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)) WHERE ((albums_artists.b1 = 1234) AND (albums_artists.b2 = 85))'
137
137
  n.tags.should == [@c2.load(:id=>1)]
138
138
  end
139
139
 
@@ -305,40 +305,40 @@ describe Sequel::Model, "many_through_many" do
305
305
  it "should support a :conditions option" do
306
306
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
307
307
  n = @c1.load(:id => 1234)
308
- 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)'
308
+ 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) WHERE ((a = 32) AND (albums_artists.artist_id = 1234))'
309
309
  n.tags.should == [@c2.load(:id=>1)]
310
310
 
311
311
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>['a = ?', 42]
312
312
  n = @c1.load(:id => 1234)
313
- 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)'
313
+ 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) WHERE ((a = 42) AND (albums_artists.artist_id = 1234))'
314
314
  n.tags.should == [@c2.load(:id=>1)]
315
315
  end
316
316
 
317
317
  it "should support an :order option" do
318
318
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
319
319
  n = @c1.load(:id => 1234)
320
- 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'
320
+ 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) WHERE (albums_artists.artist_id = 1234) ORDER BY blah'
321
321
  n.tags.should == [@c2.load(:id=>1)]
322
322
  end
323
323
 
324
324
  it "should support an array for the :order option" do
325
325
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
326
326
  n = @c1.load(:id => 1234)
327
- 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'
327
+ 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) WHERE (albums_artists.artist_id = 1234) ORDER BY blah1, blah2'
328
328
  n.tags.should == [@c2.load(:id=>1)]
329
329
  end
330
330
 
331
331
  it "should support a select option" do
332
332
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:blah
333
333
  n = @c1.load(:id => 1234)
334
- 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))'
334
+ 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) WHERE (albums_artists.artist_id = 1234)'
335
335
  n.tags.should == [@c2.load(:id=>1)]
336
336
  end
337
337
 
338
338
  it "should support an array for the select option" do
339
339
  @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]
340
340
  n = @c1.load(:id => 1234)
341
- 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))'
341
+ 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) WHERE (albums_artists.artist_id = 1234)'
342
342
  n.tags.should == [@c2.load(:id=>1)]
343
343
  end
344
344
 
@@ -346,7 +346,7 @@ describe Sequel::Model, "many_through_many" do
346
346
  @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
347
347
  n = @c1.load(:id => 1234)
348
348
  n.yyy = 85
349
- 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)'
349
+ 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) WHERE ((albums_artists.artist_id = 1234) AND (yyy = 85))'
350
350
  n.tags.should == [@c2.load(:id=>1)]
351
351
  end
352
352
 
@@ -354,7 +354,7 @@ describe Sequel::Model, "many_through_many" do
354
354
  @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
355
355
  n = @c1.load(:id => 1234)
356
356
  n.yyy = 85
357
- 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'
357
+ 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) WHERE ((albums_artists.artist_id = 1234) AND (yyy = 85)) ORDER BY blah'
358
358
  n.tags.should == [@c2.load(:id=>1)]
359
359
  end
360
360
 
@@ -368,12 +368,12 @@ describe Sequel::Model, "many_through_many" do
368
368
  it "should support a :limit option" do
369
369
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
370
370
  n = @c1.load(:id => 1234)
371
- 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'
371
+ 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) WHERE (albums_artists.artist_id = 1234) LIMIT 10'
372
372
  n.tags.should == [@c2.load(:id=>1)]
373
373
 
374
374
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>[10, 10]
375
375
  n = @c1.load(:id => 1234)
376
- 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'
376
+ 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) WHERE (albums_artists.artist_id = 1234) LIMIT 10 OFFSET 10'
377
377
  n.tags.should == [@c2.load(:id=>1)]
378
378
  end
379
379
 
@@ -386,7 +386,7 @@ describe Sequel::Model, "many_through_many" do
386
386
  it "should provide an array with all members of the association" do
387
387
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
388
388
  @c1.load(:id => 1234).tags.should == [@c2.load(:id=>1)]
389
- 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))']
389
+ 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) WHERE (albums_artists.artist_id = 1234)']
390
390
  end
391
391
 
392
392
  it "should populate cache when accessed" do
@@ -395,7 +395,7 @@ describe Sequel::Model, "many_through_many" do
395
395
  n.associations[:tags].should == nil
396
396
  DB.sqls.should == []
397
397
  n.tags.should == [@c2.load(:id=>1)]
398
- 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))']
398
+ 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) WHERE (albums_artists.artist_id = 1234)']
399
399
  n.associations[:tags].should == n.tags
400
400
  DB.sqls.length.should == 0
401
401
  end
@@ -414,7 +414,7 @@ describe Sequel::Model, "many_through_many" do
414
414
  n.associations[:tags] = []
415
415
  DB.sqls.should == []
416
416
  n.tags(true).should == [@c2.load(:id=>1)]
417
- 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))']
417
+ 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) WHERE (albums_artists.artist_id = 1234)']
418
418
  n.associations[:tags].should == n.tags
419
419
  DB.sqls.length.should == 0
420
420
  end
@@ -491,7 +491,7 @@ describe 'Sequel::Plugins::ManyThroughMany::ManyThroughManyAssociationReflection
491
491
  end
492
492
  end
493
493
 
494
- describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
494
+ describe "many_through_many eager loading methods" do
495
495
  before do
496
496
  class ::Artist < Sequel::Model
497
497
  plugin :many_through_many
@@ -553,7 +553,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
553
553
  it "should eagerly load a single many_through_many association" do
554
554
  a = @c1.eager(:tags).all
555
555
  a.should == [@c1.load(:id=>1)]
556
- 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)))']
556
+ 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) WHERE (albums_artists.artist_id IN (1))']
557
557
  a.first.tags.should == [Tag.load(:id=>2)]
558
558
  DB.sqls.length.should == 0
559
559
  end
@@ -564,8 +564,8 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
564
564
  sqls = DB.sqls
565
565
  sqls.length.should == 3
566
566
  sqls[0].should == 'SELECT * FROM artists'
567
- 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)))'))
568
- 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)))'))
567
+ 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) WHERE (albums_artists.artist_id IN (1))'))
568
+ 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) WHERE (albums_artists.artist_id IN (1))'))
569
569
  a = a.first
570
570
  a.tags.should == [Tag.load(:id=>2)]
571
571
  a.albums.should == [Album.load(:id=>3)]
@@ -578,8 +578,8 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
578
578
  sqls = DB.sqls
579
579
  sqls.length.should == 3
580
580
  sqls[0].should == 'SELECT * FROM artists'
581
- 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)))'))
582
- 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)))'))
581
+ 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) WHERE (albums_artists.artist_id IN (1))'))
582
+ 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) WHERE (albums_artists.artist_id IN (1))'))
583
583
  a = a.first
584
584
  a.tags.should == [Tag.load(:id=>2)]
585
585
  a.albums.should == [Album.load(:id=>3)]
@@ -590,8 +590,8 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
590
590
  a = @c1.eager(:tags=>:tracks).all
591
591
  a.should == [@c1.load(:id=>1)]
592
592
  DB.sqls.should == ['SELECT * FROM artists',
593
- '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)))',
594
- '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)))']
593
+ '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) WHERE (albums_artists.artist_id IN (1))',
594
+ '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) WHERE (albums_tags.tag_id IN (2))']
595
595
  a = a.first
596
596
  a.tags.should == [Tag.load(:id=>2)]
597
597
  a.tags.first.tracks.should == [Track.load(:id=>4)]
@@ -603,8 +603,8 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
603
603
  a = @c1.eager(:tags).all
604
604
  a.should == [@c1.load(:id=>1)]
605
605
  DB.sqls.should == ['SELECT * FROM artists',
606
- '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)))',
607
- '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)))']
606
+ '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) WHERE (albums_artists.artist_id IN (1))',
607
+ '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) WHERE (albums_tags.tag_id IN (2))']
608
608
  a = a.first
609
609
  a.tags.should == [Tag.load(:id=>2)]
610
610
  a.tags.first.tracks.should == [Track.load(:id=>4)]
@@ -615,8 +615,8 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
615
615
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager=>:tracks
616
616
  a = @c1.load(:id=>1)
617
617
  a.tags.should == [Tag.load(:id=>2)]
618
- 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))',
619
- '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)))']
618
+ 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) WHERE (albums_artists.artist_id = 1)',
619
+ '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) WHERE (albums_tags.tag_id IN (2))']
620
620
  a.tags.first.tracks.should == [Track.load(:id=>4)]
621
621
  DB.sqls.length.should == 0
622
622
  end
@@ -636,7 +636,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
636
636
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
637
637
  a = @c1.load(:id=>1)
638
638
  a.tags
639
- 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)']
639
+ 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) WHERE (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)']
640
640
  a.tags.should == [Tag.load(:id=>2)]
641
641
  a.tags.first.tracks.should == [Track.load(:id=>4)]
642
642
  DB.sqls.length.should == 0
@@ -647,7 +647,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
647
647
  a = @c1.eager(:tags).all
648
648
  a.should == [@c1.load(:id=>1)]
649
649
  DB.sqls.should == ['SELECT * FROM artists',
650
- '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)']
650
+ '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) WHERE ((a = 32) AND (albums_artists.artist_id IN (1)))']
651
651
  a.first.tags.should == [Tag.load(:id=>2)]
652
652
  DB.sqls.length.should == 0
653
653
  end
@@ -657,7 +657,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
657
657
  a = @c1.eager(:tags).all
658
658
  a.should == [@c1.load(:id=>1)]
659
659
  DB.sqls.should == ['SELECT * FROM artists',
660
- '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']
660
+ '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) WHERE (albums_artists.artist_id IN (1)) ORDER BY blah']
661
661
  a.first.tags.should == [Tag.load(:id=>2)]
662
662
  DB.sqls.length.should == 0
663
663
  end
@@ -667,7 +667,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
667
667
  a = @c1.eager(:tags).all
668
668
  a.should == [@c1.load(:id=>1)]
669
669
  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 a']
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) WHERE (a AND (albums_artists.artist_id IN (1)))']
671
671
  a.first.tags.should == [Tag.load(:id=>2)]
672
672
  DB.sqls.length.should == 0
673
673
  end
@@ -677,67 +677,96 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
677
677
  a = @c1.eager(:tags).all
678
678
  a.should == [@c1.load(:id=>1)]
679
679
  DB.sqls.should == ['SELECT * FROM artists',
680
- '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']
680
+ '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) WHERE (b AND (albums_artists.artist_id IN (1)))']
681
681
  a.first.tags.should == [Tag.load(:id=>2)]
682
682
  DB.sqls.length.should == 0
683
683
  end
684
684
 
685
685
  it "should respect the :limit option on a many_through_many association" do
686
686
  @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
687
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
687
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
688
688
  a = @c1.eager(:first_two_tags).all
689
689
  a.should == [@c1.load(:id=>1)]
690
690
  DB.sqls.should == ['SELECT * FROM artists',
691
- '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)))']
691
+ 'SELECT * FROM (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) WHERE (1 = albums_artists.artist_id) LIMIT 2) AS t1']
692
692
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
693
693
  DB.sqls.length.should == 0
694
694
 
695
695
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[1,1]
696
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}]
696
697
  a = @c1.eager(:first_two_tags).all
697
698
  a.should == [@c1.load(:id=>1)]
698
699
  DB.sqls.should == ['SELECT * FROM artists',
699
- '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)))']
700
+ 'SELECT * FROM (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) WHERE (1 = albums_artists.artist_id) LIMIT 1 OFFSET 1) AS t1']
700
701
  a.first.first_two_tags.should == [Tag.load(:id=>6)]
701
702
  DB.sqls.length.should == 0
702
703
 
703
704
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
705
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
704
706
  a = @c1.eager(:first_two_tags).all
705
707
  a.should == [@c1.load(:id=>1)]
706
708
  DB.sqls.should == ['SELECT * FROM artists',
707
- '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)))']
709
+ 'SELECT * FROM (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) WHERE (1 = albums_artists.artist_id) OFFSET 1) AS t1']
710
+ a.first.first_two_tags.should == [Tag.load(:id=>6), Tag.load(:id=>7)]
711
+ DB.sqls.length.should == 0
712
+ end
713
+
714
+ it "should respect the :limit option on a many_through_many association using a :ruby strategy" do
715
+ @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:ruby
716
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
717
+ a = @c1.eager(:first_two_tags).all
718
+ a.should == [@c1.load(:id=>1)]
719
+ DB.sqls.should == ['SELECT * FROM artists',
720
+ '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) WHERE (albums_artists.artist_id IN (1))']
721
+ a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
722
+ DB.sqls.length.should == 0
723
+
724
+ @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[1,1], :eager_limit_strategy=>:ruby
725
+ a = @c1.eager(:first_two_tags).all
726
+ a.should == [@c1.load(:id=>1)]
727
+ DB.sqls.should == ['SELECT * FROM artists',
728
+ '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) WHERE (albums_artists.artist_id IN (1))']
729
+ a.first.first_two_tags.should == [Tag.load(:id=>6)]
730
+ DB.sqls.length.should == 0
731
+
732
+ @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :eager_limit_strategy=>:ruby
733
+ a = @c1.eager(:first_two_tags).all
734
+ a.should == [@c1.load(:id=>1)]
735
+ DB.sqls.should == ['SELECT * FROM artists',
736
+ '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) WHERE (albums_artists.artist_id IN (1))']
708
737
  a.first.first_two_tags.should == [Tag.load(:id=>6), Tag.load(:id=>7)]
709
738
  DB.sqls.length.should == 0
710
739
  end
711
740
 
712
741
  it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
713
742
  Tag.dataset.meta_def(:supports_window_functions?){true}
714
- @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name
743
+ @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
715
744
  Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
716
745
  a = @c1.eager(:first_two_tags).all
717
746
  a.should == [@c1.load(:id=>1)]
718
747
  DB.sqls.should == ['SELECT * FROM artists',
719
- '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)']
748
+ '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) WHERE (albums_artists.artist_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
720
749
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
721
750
  DB.sqls.length.should == 0
722
751
 
723
- @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], :order=>:name
752
+ @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], :order=>:name, :eager_limit_strategy=>:window_function
724
753
  a = @c1.eager(:first_two_tags).all
725
754
  a.should == [@c1.load(:id=>1)]
726
755
  DB.sqls.should == ['SELECT * FROM artists',
727
- '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))']
756
+ '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) WHERE (albums_artists.artist_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
728
757
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
729
758
  DB.sqls.length.should == 0
730
759
 
731
- @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
760
+ @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
732
761
  a = @c1.eager(:first_two_tags).all
733
762
  a.should == [@c1.load(:id=>1)]
734
763
  DB.sqls.should == ['SELECT * FROM artists',
735
- '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)']
764
+ '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) WHERE (albums_artists.artist_id IN (1))) AS t1 WHERE (x_sequel_row_number_x >= 2)']
736
765
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
737
766
  DB.sqls.length.should == 0
738
767
  end
739
768
 
740
- 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
769
+ it "should respect the :limit option on a many_through_many association with composite primary keys on the main table" do
741
770
  Tag.dataset.meta_def(:supports_window_functions?){true}
742
771
  @c1.set_primary_key([:id1, :id2])
743
772
  @c1.columns :id1, :id2
@@ -747,15 +776,38 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
747
776
  a = @c1.eager(:first_two_tags).all
748
777
  a.should == [@c1.load(:id1=>1, :id2=>2)]
749
778
  DB.sqls.should == ['SELECT * FROM artists',
750
- '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)']
779
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((1 = albums_artists.artist_id1) AND (2 = albums_artists.artist_id2)) ORDER BY name LIMIT 2) AS t1']
780
+ a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
781
+ DB.sqls.length.should == 0
782
+
783
+ @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]
784
+ a = @c1.eager(:first_two_tags).all
785
+ a.should == [@c1.load(:id1=>1, :id2=>2)]
786
+ DB.sqls.should == ['SELECT * FROM artists',
787
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((1 = albums_artists.artist_id1) AND (2 = albums_artists.artist_id2)) LIMIT 2 OFFSET 1) AS t1']
788
+ a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
789
+ DB.sqls.length.should == 0
790
+ end
791
+
792
+ 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
793
+ Tag.dataset.meta_def(:supports_window_functions?){true}
794
+ @c1.set_primary_key([:id1, :id2])
795
+ @c1.columns :id1, :id2
796
+ @c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
797
+ @c1.dataset._fetch = [{:id1=>1, :id2=>2}]
798
+ 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}]
799
+ a = @c1.eager(:first_two_tags).all
800
+ a.should == [@c1.load(:id1=>1, :id2=>2)]
801
+ DB.sqls.should == ['SELECT * FROM artists',
802
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
751
803
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
752
804
  DB.sqls.length.should == 0
753
805
 
754
- @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], :order=>:name
806
+ @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], :order=>:name, :eager_limit_strategy=>:window_function
755
807
  a = @c1.eager(:first_two_tags).all
756
808
  a.should == [@c1.load(:id1=>1, :id2=>2)]
757
809
  DB.sqls.should == ['SELECT * FROM artists',
758
- '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))']
810
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
759
811
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
760
812
  DB.sqls.length.should == 0
761
813
  end
@@ -771,7 +823,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
771
823
  a = @c1.eager(:tags).all
772
824
  a.should == [@c1.load(:id=>1)]
773
825
  DB.sqls.should == ['SELECT * FROM artists',
774
- '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)))']
826
+ '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) WHERE (albums_artists.artist_id IN (1))']
775
827
  a.first.tags.should == [Tag.load(:id=>2)]
776
828
  DB.sqls.length.should == 0
777
829
  end
@@ -784,7 +836,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
784
836
  a = @c1.eager(:tags).all
785
837
  a.should == [@c1.load(:id=>1, :yyy=>8)]
786
838
  DB.sqls.should == ['SELECT * FROM artists',
787
- '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)))']
839
+ '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) WHERE (albums_artists.artist_id IN (8))']
788
840
  a.first.tags.should == [Tag.load(:tag_id=>2)]
789
841
  DB.sqls.length.should == 0
790
842
  end
@@ -797,7 +849,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
797
849
  a = @c1.eager(:tags).all
798
850
  a.should == [@c1.load(:id=>1, :yyy=>8)]
799
851
  DB.sqls.should == ['SELECT * FROM artists',
800
- '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))))']
852
+ '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)) WHERE ((albums_artists.b1, albums_artists.b2) IN ((1, 8)))']
801
853
  a.first.tags.should == [Tag.load(:id=>2)]
802
854
  DB.sqls.length.should == 0
803
855
  end
@@ -807,7 +859,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
807
859
  a = @c1.eager(:tags).all
808
860
  a.should == [@c1.load(:id=>2)]
809
861
  DB.sqls.should == ['SELECT * FROM artists',
810
- '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)))']
862
+ '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) WHERE (albums_artists.artist_id IN (1))']
811
863
  a.first.tags.should == [Tag.load(:id=>6)]
812
864
  DB.sqls.length.should == 0
813
865
  end
@@ -910,7 +962,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
910
962
  a = @c1.eager_graph(:tags).eager(:albums).all
911
963
  a.should == [@c1.load(:id=>1)]
912
964
  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)',
913
- '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)))']
965
+ 'SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id IN (1))']
914
966
  a = a.first
915
967
  a.tags.should == [Tag.load(:id=>2)]
916
968
  a.albums.should == [Album.load(:id=>3)]
@@ -1095,13 +1147,13 @@ describe "many_through_many associations with non-column expression keys" do
1095
1147
 
1096
1148
  it "should have working regular association methods" do
1097
1149
  @Foo.first.foos.should == [@foo]
1098
- @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))"]
1150
+ @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]) WHERE (f_0.l[0] = 2)"]
1099
1151
  end
1100
1152
 
1101
1153
  it "should have working eager loading methods" do
1102
1154
  @db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
1103
1155
  @Foo.eager(:foos).all.map{|o| [o, o.foos]}.should == [[@foo, [@foo]]]
1104
- @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)))"]
1156
+ @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]) WHERE (f_0.l[0] IN (2))"]
1105
1157
  end
1106
1158
 
1107
1159
  it "should have working eager graphing methods" do
@@ -1149,7 +1201,7 @@ describe Sequel::Model, "one_through_many" do
1149
1201
  @c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
1150
1202
  a = @c1.eager(:tag).all
1151
1203
  a.should == [@c1.load(:id => 1)]
1152
- 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)))"]
1204
+ 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) WHERE (albums_artists.artist_id IN (3))"]
1153
1205
  a.first.tag.should == @c2.load(:id=>4)
1154
1206
  DB.sqls.should == []
1155
1207
  end
@@ -1160,7 +1212,7 @@ describe Sequel::Model, "one_through_many" do
1160
1212
  @c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
1161
1213
  a = @c1.eager(:tag).all
1162
1214
  a.should == [@c1.load(:id => 1)]
1163
- 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)))"]
1215
+ 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) WHERE ((albums_artists.artist_id / 3) IN (1))"]
1164
1216
  a.first.tag.should == @c2.load(:id=>4)
1165
1217
  end
1166
1218
 
@@ -1173,7 +1225,7 @@ describe Sequel::Model, "one_through_many" do
1173
1225
  it "should allow only two arguments with the :through option" do
1174
1226
  @c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
1175
1227
  n = @c1.load(:id => 1234)
1176
- n.tag_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 1'
1228
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1177
1229
  n.tag.should == @c2.load(:id=>1)
1178
1230
  end
1179
1231
 
@@ -1182,14 +1234,14 @@ describe Sequel::Model, "one_through_many" do
1182
1234
  @c1.many_through_many :tags, :clone=>:tag
1183
1235
  @c1.one_through_many :tag, :clone=>:tags
1184
1236
  n = @c1.load(:id => 1234)
1185
- n.tag_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 1'
1237
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1186
1238
  n.tag.should == @c2.load(:id=>1)
1187
1239
  end
1188
1240
 
1189
1241
  it "should use join tables given" do
1190
1242
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
1191
1243
  n = @c1.load(:id => 1234)
1192
- n.tag_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 1'
1244
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1193
1245
  n.tag.should == @c2.load(:id=>1)
1194
1246
  end
1195
1247
 
@@ -1199,7 +1251,7 @@ describe Sequel::Model, "one_through_many" do
1199
1251
  end
1200
1252
  @c1.one_through_many :album, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]]
1201
1253
  n = @c1.load(:id => 1234)
1202
- n.album_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)) LIMIT 1'
1254
+ n.album_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) WHERE (albums_artists_1.artist_id = 1234) LIMIT 1'
1203
1255
  n.album.should == Album.load(:id=>1, :x=>1)
1204
1256
  ensure
1205
1257
  Object.send(:remove_const, :Album)
@@ -1209,7 +1261,7 @@ describe Sequel::Model, "one_through_many" do
1209
1261
  it "should use explicit class if given" do
1210
1262
  @c1.one_through_many :album_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag
1211
1263
  n = @c1.load(:id => 1234)
1212
- n.album_tag_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 1'
1264
+ n.album_tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1213
1265
  n.album_tag.should == @c2.load(:id=>1)
1214
1266
  end
1215
1267
 
@@ -1217,7 +1269,7 @@ describe Sequel::Model, "one_through_many" do
1217
1269
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :right_primary_key=>:tag_id, :left_primary_key=>:yyy
1218
1270
  n = @c1.load(:id => 1234)
1219
1271
  n.yyy = 85
1220
- n.tag_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)) LIMIT 1'
1272
+ n.tag_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) WHERE (albums_artists.artist_id = 85) LIMIT 1'
1221
1273
  n.tag.should == @c2.load(:id=>1)
1222
1274
  end
1223
1275
 
@@ -1225,7 +1277,7 @@ describe Sequel::Model, "one_through_many" do
1225
1277
  @c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
1226
1278
  n = @c1.load(:id => 1234)
1227
1279
  n.yyy = 85
1228
- n.tag_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)) LIMIT 1'
1280
+ n.tag_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)) WHERE ((albums_artists.b1 = 1234) AND (albums_artists.b2 = 85)) LIMIT 1'
1229
1281
  n.tag.should == @c2.load(:id=>1)
1230
1282
  end
1231
1283
 
@@ -1397,40 +1449,40 @@ describe Sequel::Model, "one_through_many" do
1397
1449
  it "should support a :conditions option" do
1398
1450
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
1399
1451
  n = @c1.load(:id => 1234)
1400
- n.tag_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) LIMIT 1'
1452
+ n.tag_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) WHERE ((a = 32) AND (albums_artists.artist_id = 1234)) LIMIT 1'
1401
1453
  n.tag.should == @c2.load(:id=>1)
1402
1454
 
1403
1455
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>['a = ?', 42]
1404
1456
  n = @c1.load(:id => 1234)
1405
- n.tag_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) LIMIT 1'
1457
+ n.tag_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) WHERE ((a = 42) AND (albums_artists.artist_id = 1234)) LIMIT 1'
1406
1458
  n.tag.should == @c2.load(:id=>1)
1407
1459
  end
1408
1460
 
1409
1461
  it "should support an :order option" do
1410
1462
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
1411
1463
  n = @c1.load(:id => 1234)
1412
- n.tag_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 LIMIT 1'
1464
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) ORDER BY blah LIMIT 1'
1413
1465
  n.tag.should == @c2.load(:id=>1)
1414
1466
  end
1415
1467
 
1416
1468
  it "should support an array for the :order option" do
1417
1469
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
1418
1470
  n = @c1.load(:id => 1234)
1419
- n.tag_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 LIMIT 1'
1471
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) ORDER BY blah1, blah2 LIMIT 1'
1420
1472
  n.tag.should == @c2.load(:id=>1)
1421
1473
  end
1422
1474
 
1423
1475
  it "should support a select option" do
1424
1476
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:blah
1425
1477
  n = @c1.load(:id => 1234)
1426
- n.tag_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)) LIMIT 1'
1478
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1427
1479
  n.tag.should == @c2.load(:id=>1)
1428
1480
  end
1429
1481
 
1430
1482
  it "should support an array for the select option" do
1431
1483
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[Sequel::SQL::ColumnAll.new(:tags), :albums__name]
1432
1484
  n = @c1.load(:id => 1234)
1433
- n.tag_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)) LIMIT 1'
1485
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1'
1434
1486
  n.tag.should == @c2.load(:id=>1)
1435
1487
  end
1436
1488
 
@@ -1438,7 +1490,7 @@ describe Sequel::Model, "one_through_many" do
1438
1490
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]] do |ds| ds.filter(:yyy=>@yyy) end
1439
1491
  n = @c1.load(:id => 1234)
1440
1492
  n.yyy = 85
1441
- n.tag_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) LIMIT 1'
1493
+ n.tag_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) WHERE ((albums_artists.artist_id = 1234) AND (yyy = 85)) LIMIT 1'
1442
1494
  n.tag.should == @c2.load(:id=>1)
1443
1495
  end
1444
1496
 
@@ -1446,7 +1498,7 @@ describe Sequel::Model, "one_through_many" do
1446
1498
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah do |ds| ds.filter(:yyy=>@yyy) end
1447
1499
  n = @c1.load(:id => 1234)
1448
1500
  n.yyy = 85
1449
- n.tag_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 LIMIT 1'
1501
+ n.tag_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) WHERE ((albums_artists.artist_id = 1234) AND (yyy = 85)) ORDER BY blah LIMIT 1'
1450
1502
  n.tag.should == @c2.load(:id=>1)
1451
1503
  end
1452
1504
 
@@ -1460,7 +1512,7 @@ describe Sequel::Model, "one_through_many" do
1460
1512
  it "should support a :limit option to specify an offset" do
1461
1513
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>[nil, 10]
1462
1514
  n = @c1.load(:id => 1234)
1463
- n.tag_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 1 OFFSET 10'
1515
+ n.tag_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) WHERE (albums_artists.artist_id = 1234) LIMIT 1 OFFSET 10'
1464
1516
  n.tag.should == @c2.load(:id=>1)
1465
1517
  end
1466
1518
 
@@ -1473,7 +1525,7 @@ describe Sequel::Model, "one_through_many" do
1473
1525
  it "should return the associated object" do
1474
1526
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
1475
1527
  @c1.load(:id => 1234).tag.should == @c2.load(:id=>1)
1476
- 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)) LIMIT 1']
1528
+ 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) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
1477
1529
  end
1478
1530
 
1479
1531
  it "should populate cache when accessed" do
@@ -1482,7 +1534,7 @@ describe Sequel::Model, "one_through_many" do
1482
1534
  n.associations[:tag].should == nil
1483
1535
  DB.sqls.should == []
1484
1536
  n.tag.should == @c2.load(:id=>1)
1485
- 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)) LIMIT 1']
1537
+ 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) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
1486
1538
  n.associations[:tag].should == n.tag
1487
1539
  DB.sqls.length.should == 0
1488
1540
  end
@@ -1501,7 +1553,7 @@ describe Sequel::Model, "one_through_many" do
1501
1553
  n.associations[:tag] = nil
1502
1554
  DB.sqls.should == []
1503
1555
  n.tag(true).should == @c2.load(:id=>1)
1504
- 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)) LIMIT 1']
1556
+ 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) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
1505
1557
  n.associations[:tag].should == n.tag
1506
1558
  DB.sqls.length.should == 0
1507
1559
  end
@@ -1533,7 +1585,7 @@ describe Sequel::Model, "one_through_many" do
1533
1585
  end
1534
1586
  end
1535
1587
 
1536
- describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1588
+ describe "one_through_many eager loading methods" do
1537
1589
  before do
1538
1590
  class ::Artist < Sequel::Model
1539
1591
  plugin :many_through_many
@@ -1595,7 +1647,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1595
1647
  it "should eagerly load a single one_through_many association" do
1596
1648
  a = @c1.eager(:tag).all
1597
1649
  a.should == [@c1.load(:id=>1)]
1598
- 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)))']
1650
+ 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) WHERE (albums_artists.artist_id IN (1))']
1599
1651
  a.first.tag.should == Tag.load(:id=>2)
1600
1652
  DB.sqls.length.should == 0
1601
1653
  end
@@ -1606,8 +1658,8 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1606
1658
  sqls = DB.sqls
1607
1659
  sqls.length.should == 3
1608
1660
  sqls[0].should == 'SELECT * FROM artists'
1609
- 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)))'))
1610
- 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)))'))
1661
+ 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) WHERE (albums_artists.artist_id IN (1))'))
1662
+ 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) WHERE (albums_artists.artist_id IN (1))'))
1611
1663
  a = a.first
1612
1664
  a.tag.should == Tag.load(:id=>2)
1613
1665
  a.album.should == Album.load(:id=>3)
@@ -1620,8 +1672,8 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1620
1672
  sqls = DB.sqls
1621
1673
  sqls.length.should == 3
1622
1674
  sqls[0].should == 'SELECT * FROM artists'
1623
- 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)))'))
1624
- 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)))'))
1675
+ 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) WHERE (albums_artists.artist_id IN (1))'))
1676
+ 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) WHERE (albums_artists.artist_id IN (1))'))
1625
1677
  a = a.first
1626
1678
  a.tag.should == Tag.load(:id=>2)
1627
1679
  a.album.should == Album.load(:id=>3)
@@ -1632,8 +1684,8 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1632
1684
  a = @c1.eager(:tag=>:track).all
1633
1685
  a.should == [@c1.load(:id=>1)]
1634
1686
  DB.sqls.should == ['SELECT * FROM artists',
1635
- '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)))',
1636
- '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)))']
1687
+ '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) WHERE (albums_artists.artist_id IN (1))',
1688
+ '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) WHERE (albums_tags.tag_id IN (2))']
1637
1689
  a = a.first
1638
1690
  a.tag.should == Tag.load(:id=>2)
1639
1691
  a.tag.track.should == Track.load(:id=>4)
@@ -1645,8 +1697,8 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1645
1697
  a = @c1.eager(:tag).all
1646
1698
  a.should == [@c1.load(:id=>1)]
1647
1699
  DB.sqls.should == ['SELECT * FROM artists',
1648
- '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)))',
1649
- '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)))']
1700
+ '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) WHERE (albums_artists.artist_id IN (1))',
1701
+ '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) WHERE (albums_tags.tag_id IN (2))']
1650
1702
  a = a.first
1651
1703
  a.tag.should == Tag.load(:id=>2)
1652
1704
  a.tag.track.should == Track.load(:id=>4)
@@ -1657,8 +1709,8 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1657
1709
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager=>:track
1658
1710
  a = @c1.load(:id=>1)
1659
1711
  a.tag.should == Tag.load(:id=>2)
1660
- 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)) LIMIT 1',
1661
- '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)))']
1712
+ 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) WHERE (albums_artists.artist_id = 1) LIMIT 1',
1713
+ '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) WHERE (albums_tags.tag_id IN (2))']
1662
1714
  a.tag.track.should == Track.load(:id=>4)
1663
1715
  DB.sqls.length.should == 0
1664
1716
  end
@@ -1678,7 +1730,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1678
1730
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:track
1679
1731
  a = @c1.load(:id=>1)
1680
1732
  a.tag
1681
- DB.sqls.should == [ 'SELECT tags.id, track.id AS track_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)) LIMIT 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 AS track ON (track.album_id = albums.id)']
1733
+ DB.sqls.should == [ 'SELECT tags.id, track.id AS track_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) WHERE (albums_artists.artist_id = 1) LIMIT 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 AS track ON (track.album_id = albums.id)']
1682
1734
  a.tag.should == Tag.load(:id=>2)
1683
1735
  a.tag.track.should == Track.load(:id=>4)
1684
1736
  DB.sqls.length.should == 0
@@ -1689,17 +1741,17 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1689
1741
  a = @c1.eager(:tag).all
1690
1742
  a.should == [@c1.load(:id=>1)]
1691
1743
  DB.sqls.should == ['SELECT * FROM artists',
1692
- '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)']
1744
+ '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) WHERE ((a = 32) AND (albums_artists.artist_id IN (1)))']
1693
1745
  a.first.tag.should == Tag.load(:id=>2)
1694
1746
  DB.sqls.length.should == 0
1695
1747
  end
1696
1748
 
1697
1749
  it "should respect :order when eagerly loading" do
1698
- @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
1750
+ @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah, :eager_limit_strategy=>:ruby
1699
1751
  a = @c1.eager(:tag).all
1700
1752
  a.should == [@c1.load(:id=>1)]
1701
1753
  DB.sqls.should == ['SELECT * FROM artists',
1702
- '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']
1754
+ '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) WHERE (albums_artists.artist_id IN (1)) ORDER BY blah']
1703
1755
  a.first.tag.should == Tag.load(:id=>2)
1704
1756
  DB.sqls.length.should == 0
1705
1757
  end
@@ -1709,7 +1761,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1709
1761
  a = @c1.eager(:tag).all
1710
1762
  a.should == [@c1.load(:id=>1)]
1711
1763
  DB.sqls.should == ['SELECT * FROM artists',
1712
- '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']
1764
+ '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) WHERE (a AND (albums_artists.artist_id IN (1)))']
1713
1765
  a.first.tag.should == Tag.load(:id=>2)
1714
1766
  DB.sqls.length.should == 0
1715
1767
  end
@@ -1719,46 +1771,57 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1719
1771
  a = @c1.eager(:tag).all
1720
1772
  a.should == [@c1.load(:id=>1)]
1721
1773
  DB.sqls.should == ['SELECT * FROM artists',
1722
- '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']
1774
+ '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) WHERE (b AND (albums_artists.artist_id IN (1)))']
1723
1775
  a.first.tag.should == Tag.load(:id=>2)
1724
1776
  DB.sqls.length.should == 0
1725
1777
  end
1726
1778
 
1727
1779
  it "should respect the :limit option on a one_through_many association" do
1728
1780
  @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
1781
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}]
1782
+ a = @c1.eager(:second_tag).all
1783
+ a.should == [@c1.load(:id=>1)]
1784
+ DB.sqls.should == ['SELECT * FROM artists',
1785
+ 'SELECT * FROM (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) WHERE (1 = albums_artists.artist_id) LIMIT 1 OFFSET 1) AS t1']
1786
+ a.first.second_tag.should == Tag.load(:id=>6)
1787
+ DB.sqls.length.should == 0
1788
+ end
1789
+
1790
+ it "should respect the :limit option on a one_through_many association using the :ruby strategy" do
1791
+ @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :eager_limit_strategy=>:ruby
1729
1792
  Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}, {:x_foreign_key_x=>1, :id=>6}]
1730
1793
  a = @c1.eager(:second_tag).all
1731
1794
  a.should == [@c1.load(:id=>1)]
1732
1795
  DB.sqls.should == ['SELECT * FROM artists',
1733
- '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)))']
1796
+ '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) WHERE (albums_artists.artist_id IN (1))']
1734
1797
  a.first.second_tag.should == Tag.load(:id=>6)
1735
1798
  DB.sqls.length.should == 0
1736
1799
  end
1737
1800
 
1738
1801
  it "should eagerly load a single one_through_many association using the :distinct_on strategy" do
1739
1802
  Tag.dataset.meta_def(:supports_distinct_on?){true}
1740
- @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :order=>:name
1803
+ @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :order=>:name, :eager_limit_strategy=>:distinct_on
1741
1804
  Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
1742
1805
  a = @c1.eager(:second_tag).all
1743
1806
  a.should == [@c1.load(:id=>1)]
1744
- DB.sqls.should == ['SELECT * FROM artists', "SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) ORDER BY albums_artists.artist_id, name"]
1807
+ DB.sqls.should == ['SELECT * FROM artists', "SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id IN (1)) ORDER BY albums_artists.artist_id, name"]
1745
1808
  a.first.second_tag.should == Tag.load(:id=>5)
1746
1809
  DB.sqls.length.should == 0
1747
1810
  end
1748
1811
 
1749
1812
  it "should eagerly load a single one_through_many association using the :window_function strategy" do
1750
1813
  Tag.dataset.meta_def(:supports_window_functions?){true}
1751
- @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
1814
+ @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
1752
1815
  Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
1753
1816
  a = @c1.eager(:second_tag).all
1754
1817
  a.should == [@c1.load(:id=>1)]
1755
1818
  DB.sqls.should == ['SELECT * FROM artists',
1756
- '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)']
1819
+ '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) WHERE (albums_artists.artist_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 2)']
1757
1820
  a.first.second_tag.should == Tag.load(:id=>5)
1758
1821
  DB.sqls.length.should == 0
1759
1822
  end
1760
1823
 
1761
- it "should respect the :limit option on a one_through_many association with composite primary keys on the main table using a :window_function strategy" do
1824
+ it "should respect the :limit option on a one_through_many association with composite primary keys on the main table" do
1762
1825
  Tag.dataset.meta_def(:supports_window_functions?){true}
1763
1826
  @c1.set_primary_key([:id1, :id2])
1764
1827
  @c1.columns :id1, :id2
@@ -1770,7 +1833,24 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1770
1833
  a = ds.all
1771
1834
  a.should == [@c1.load(:id1=>1, :id2=>2)]
1772
1835
  DB.sqls.should == ['SELECT * FROM artists',
1773
- '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)']
1836
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((1 = albums_artists.artist_id1) AND (2 = albums_artists.artist_id2)) ORDER BY name LIMIT 1 OFFSET 1) AS t1']
1837
+ a.first.second_tag.should == Tag.load(:id=>5)
1838
+ DB.sqls.length.should == 0
1839
+ end
1840
+
1841
+ it "should respect the :limit option on a one_through_many association with composite primary keys on the main table using a :window_function strategy" do
1842
+ Tag.dataset.meta_def(:supports_window_functions?){true}
1843
+ @c1.set_primary_key([:id1, :id2])
1844
+ @c1.columns :id1, :id2
1845
+
1846
+ @c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
1847
+ ds = @c1.eager(:second_tag)
1848
+ ds._fetch = {:id1=>1, :id2=>2}
1849
+ Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
1850
+ a = ds.all
1851
+ a.should == [@c1.load(:id1=>1, :id2=>2)]
1852
+ DB.sqls.should == ['SELECT * FROM artists',
1853
+ 'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2)))) AS t1 WHERE (x_sequel_row_number_x = 2)']
1774
1854
  a.first.second_tag.should == Tag.load(:id=>5)
1775
1855
  DB.sqls.length.should == 0
1776
1856
  end
@@ -1786,7 +1866,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1786
1866
  a = @c1.eager(:tag).all
1787
1867
  a.should == [@c1.load(:id=>1)]
1788
1868
  DB.sqls.should == ['SELECT * FROM artists',
1789
- '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)))']
1869
+ '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) WHERE (albums_artists.artist_id IN (1))']
1790
1870
  a.first.tag.should == Tag.load(:id=>2)
1791
1871
  DB.sqls.length.should == 0
1792
1872
  end
@@ -1799,7 +1879,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1799
1879
  a = @c1.eager(:tag).all
1800
1880
  a.should == [@c1.load(:id=>1, :yyy=>8)]
1801
1881
  DB.sqls.should == ['SELECT * FROM artists',
1802
- '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)))']
1882
+ '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) WHERE (albums_artists.artist_id IN (8))']
1803
1883
  a.first.tag.should == Tag.load(:tag_id=>2)
1804
1884
  DB.sqls.length.should == 0
1805
1885
  end
@@ -1812,7 +1892,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1812
1892
  a = @c1.eager(:tag).all
1813
1893
  a.should == [@c1.load(:id=>1, :yyy=>8)]
1814
1894
  DB.sqls.should == ['SELECT * FROM artists',
1815
- '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))))']
1895
+ '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)) WHERE ((albums_artists.b1, albums_artists.b2) IN ((1, 8)))']
1816
1896
  a.first.tag.should == Tag.load(:id=>2)
1817
1897
  DB.sqls.length.should == 0
1818
1898
  end
@@ -1822,7 +1902,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1822
1902
  a = @c1.eager(:tag).all
1823
1903
  a.should == [@c1.load(:id=>2)]
1824
1904
  DB.sqls.should == ['SELECT * FROM artists',
1825
- '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)))']
1905
+ '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) WHERE (albums_artists.artist_id IN (1))']
1826
1906
  a.first.tag.should == Tag.load(:id=>6)
1827
1907
  DB.sqls.length.should == 0
1828
1908
  end
@@ -1918,7 +1998,7 @@ describe "Sequel::Plugins::OneThroughMany eager loading methods" do
1918
1998
  a = @c1.eager_graph(:tag).eager(:album).all
1919
1999
  a.should == [@c1.load(:id=>1)]
1920
2000
  DB.sqls.should == ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)',
1921
- '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)))']
2001
+ 'SELECT albums.*, albums_artists.artist_id AS x_foreign_key_x FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id IN (1))']
1922
2002
  a = a.first
1923
2003
  a.tag.should == Tag.load(:id=>2)
1924
2004
  a.album.should == Album.load(:id=>3)