sequel 3.29.0 → 3.30.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 (106) hide show
  1. data/CHANGELOG +35 -3
  2. data/Rakefile +2 -1
  3. data/doc/association_basics.rdoc +11 -0
  4. data/doc/opening_databases.rdoc +2 -0
  5. data/doc/release_notes/3.30.0.txt +135 -0
  6. data/doc/testing.rdoc +17 -3
  7. data/lib/sequel/adapters/amalgalite.rb +2 -2
  8. data/lib/sequel/adapters/do/mysql.rb +5 -2
  9. data/lib/sequel/adapters/ibmdb.rb +2 -2
  10. data/lib/sequel/adapters/jdbc.rb +126 -43
  11. data/lib/sequel/adapters/jdbc/as400.rb +11 -3
  12. data/lib/sequel/adapters/jdbc/db2.rb +2 -1
  13. data/lib/sequel/adapters/jdbc/derby.rb +44 -19
  14. data/lib/sequel/adapters/jdbc/h2.rb +32 -19
  15. data/lib/sequel/adapters/jdbc/hsqldb.rb +21 -17
  16. data/lib/sequel/adapters/jdbc/jtds.rb +9 -4
  17. data/lib/sequel/adapters/jdbc/mssql.rb +3 -1
  18. data/lib/sequel/adapters/jdbc/mysql.rb +2 -1
  19. data/lib/sequel/adapters/jdbc/oracle.rb +21 -7
  20. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -2
  21. data/lib/sequel/adapters/jdbc/sqlite.rb +2 -1
  22. data/lib/sequel/adapters/jdbc/sqlserver.rb +48 -18
  23. data/lib/sequel/adapters/mock.rb +2 -1
  24. data/lib/sequel/adapters/mysql.rb +4 -2
  25. data/lib/sequel/adapters/mysql2.rb +2 -2
  26. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  27. data/lib/sequel/adapters/openbase.rb +1 -1
  28. data/lib/sequel/adapters/oracle.rb +6 -6
  29. data/lib/sequel/adapters/postgres.rb +25 -12
  30. data/lib/sequel/adapters/shared/access.rb +14 -6
  31. data/lib/sequel/adapters/shared/db2.rb +36 -13
  32. data/lib/sequel/adapters/shared/firebird.rb +12 -5
  33. data/lib/sequel/adapters/shared/informix.rb +11 -3
  34. data/lib/sequel/adapters/shared/mssql.rb +94 -47
  35. data/lib/sequel/adapters/shared/mysql.rb +107 -49
  36. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +2 -2
  37. data/lib/sequel/adapters/shared/oracle.rb +54 -27
  38. data/lib/sequel/adapters/shared/postgres.rb +65 -26
  39. data/lib/sequel/adapters/shared/progress.rb +4 -1
  40. data/lib/sequel/adapters/shared/sqlite.rb +36 -20
  41. data/lib/sequel/adapters/sqlite.rb +2 -3
  42. data/lib/sequel/adapters/swift/mysql.rb +3 -2
  43. data/lib/sequel/adapters/swift/sqlite.rb +2 -2
  44. data/lib/sequel/adapters/tinytds.rb +14 -8
  45. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -4
  46. data/lib/sequel/database/misc.rb +6 -2
  47. data/lib/sequel/dataset/graph.rb +33 -7
  48. data/lib/sequel/dataset/prepared_statements.rb +19 -5
  49. data/lib/sequel/dataset/sql.rb +611 -201
  50. data/lib/sequel/model/associations.rb +12 -5
  51. data/lib/sequel/model/base.rb +20 -5
  52. data/lib/sequel/plugins/sharding.rb +9 -29
  53. data/lib/sequel/sql.rb +2 -1
  54. data/lib/sequel/timezones.rb +14 -4
  55. data/lib/sequel/version.rb +1 -1
  56. data/spec/adapters/mysql_spec.rb +10 -0
  57. data/spec/adapters/oracle_spec.rb +1 -1
  58. data/spec/core/core_sql_spec.rb +3 -1
  59. data/spec/core/database_spec.rb +42 -0
  60. data/spec/core/dataset_spec.rb +10 -3
  61. data/spec/core/mock_adapter_spec.rb +4 -0
  62. data/spec/core/object_graph_spec.rb +38 -0
  63. data/spec/extensions/association_autoreloading_spec.rb +1 -10
  64. data/spec/extensions/association_dependencies_spec.rb +2 -12
  65. data/spec/extensions/association_pks_spec.rb +35 -39
  66. data/spec/extensions/caching_spec.rb +23 -50
  67. data/spec/extensions/class_table_inheritance_spec.rb +30 -82
  68. data/spec/extensions/composition_spec.rb +18 -13
  69. data/spec/extensions/hook_class_methods_spec.rb +65 -91
  70. data/spec/extensions/identity_map_spec.rb +33 -103
  71. data/spec/extensions/instance_filters_spec.rb +10 -21
  72. data/spec/extensions/instance_hooks_spec.rb +6 -24
  73. data/spec/extensions/json_serializer_spec.rb +4 -5
  74. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  75. data/spec/extensions/list_spec.rb +17 -39
  76. data/spec/extensions/many_through_many_spec.rb +135 -277
  77. data/spec/extensions/migration_spec.rb +18 -15
  78. data/spec/extensions/named_timezones_spec.rb +1 -1
  79. data/spec/extensions/nested_attributes_spec.rb +97 -92
  80. data/spec/extensions/optimistic_locking_spec.rb +9 -20
  81. data/spec/extensions/prepared_statements_associations_spec.rb +22 -37
  82. data/spec/extensions/prepared_statements_safe_spec.rb +9 -27
  83. data/spec/extensions/prepared_statements_spec.rb +11 -30
  84. data/spec/extensions/prepared_statements_with_pk_spec.rb +6 -13
  85. data/spec/extensions/pretty_table_spec.rb +1 -6
  86. data/spec/extensions/rcte_tree_spec.rb +41 -43
  87. data/spec/extensions/schema_dumper_spec.rb +3 -6
  88. data/spec/extensions/serialization_spec.rb +20 -32
  89. data/spec/extensions/sharding_spec.rb +66 -140
  90. data/spec/extensions/single_table_inheritance_spec.rb +14 -36
  91. data/spec/extensions/spec_helper.rb +10 -64
  92. data/spec/extensions/sql_expr_spec.rb +20 -60
  93. data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
  94. data/spec/extensions/timestamps_spec.rb +6 -6
  95. data/spec/extensions/to_dot_spec.rb +1 -2
  96. data/spec/extensions/touch_spec.rb +13 -14
  97. data/spec/extensions/tree_spec.rb +11 -26
  98. data/spec/extensions/update_primary_key_spec.rb +30 -24
  99. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  100. data/spec/extensions/validation_helpers_spec.rb +16 -35
  101. data/spec/integration/dataset_test.rb +16 -4
  102. data/spec/integration/prepared_statement_test.rb +4 -2
  103. data/spec/model/eager_loading_spec.rb +16 -0
  104. data/spec/model/model_spec.rb +15 -1
  105. data/spec/model/record_spec.rb +60 -0
  106. metadata +23 -40
@@ -2,19 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "instance_filters plugin" do
4
4
  before do
5
- @c = Class.new(Sequel::Model(:people)) do
6
- end
7
- @sql = sql = ''
8
- @v = v = [1]
5
+ @c = Class.new(Sequel::Model(:people))
9
6
  @c.dataset.quote_identifiers = false
10
- @c.dataset.meta_def(:update) do |opts|
11
- sql.replace(update_sql(opts))
12
- return v.first
13
- end
14
- @c.dataset.meta_def(:delete) do
15
- sql.replace(delete_sql)
16
- return v.first
17
- end
18
7
  @c.columns :id, :name, :num
19
8
  @c.plugin :instance_filters
20
9
  @p = @c.load(:id=>1, :name=>'John', :num=>1)
@@ -22,34 +11,34 @@ describe "instance_filters plugin" do
22
11
 
23
12
  specify "should raise an error when updating a stale record" do
24
13
  @p.update(:name=>'Bob')
25
- @sql.should == "UPDATE people SET name = 'Bob' WHERE (id = 1)"
14
+ MODEL_DB.sqls.should == ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
26
15
  @p.instance_filter(:name=>'Jim')
27
- @v.replace([0])
16
+ @p.this.numrows = 0
28
17
  proc{@p.update(:name=>'Joe')}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
29
- @sql.should == "UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"
18
+ MODEL_DB.sqls.should == ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
30
19
  end
31
20
 
32
21
  specify "should raise an error when destroying a stale record" do
33
22
  @p.destroy
34
- @sql.should == "DELETE FROM people WHERE (id = 1)"
23
+ MODEL_DB.sqls.should == ["DELETE FROM people WHERE (id = 1)"]
35
24
  @p.instance_filter(:name=>'Jim')
36
- @v.replace([0])
25
+ @p.this.numrows = 0
37
26
  proc{@p.destroy}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
38
- @sql.should == "DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"
27
+ MODEL_DB.sqls.should == ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
39
28
  end
40
29
 
41
30
  specify "should apply all instance filters" do
42
31
  @p.instance_filter(:name=>'Jim')
43
32
  @p.instance_filter{num > 2}
44
33
  @p.update(:name=>'Bob')
45
- @sql.should == "UPDATE people SET name = 'Bob' WHERE ((id = 1) AND (name = 'Jim') AND (num > 2))"
34
+ MODEL_DB.sqls.should == ["UPDATE people SET name = 'Bob' WHERE ((id = 1) AND (name = 'Jim') AND (num > 2))"]
46
35
  end
47
36
 
48
37
  specify "should drop instance filters after updating" do
49
38
  @p.instance_filter(:name=>'Joe')
50
39
  @p.update(:name=>'Joe')
51
- @sql.should == "UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Joe'))"
40
+ MODEL_DB.sqls.should == ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Joe'))"]
52
41
  @p.update(:name=>'Bob')
53
- @sql.should == "UPDATE people SET name = 'Bob' WHERE (id = 1)"
42
+ MODEL_DB.sqls.should == ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
54
43
  end
55
44
  end
@@ -180,29 +180,10 @@ end
180
180
 
181
181
  describe "InstanceHooks plugin with transactions" do
182
182
  before do
183
- @logger = Object.new
184
- def @logger.method_missing(meth, sql)
185
- (@sqls ||= []) << sql
186
- end
187
- def @logger.sqls
188
- @sqls
189
- end
190
- @db = Class.new(Sequel::Database) do
191
- def connect(*)
192
- Object.new
193
- end
194
- def log_connection_execute(conn, sql)
195
- execute(sql)
196
- end
197
- def execute(sql, opts={})
198
- @loggers.each{|l| l.info(sql)}
199
- end
200
- end.new(:loggers=>[@logger])
183
+ @db = Sequel.mock(:numrows=>1)
201
184
  pr = proc{|x| r(x)}
202
185
  @c = Class.new(Sequel::Model(@db[:items])) do
203
186
  attr_accessor :rb
204
- def _delete
205
- end
206
187
  def after_save
207
188
  db.execute('as')
208
189
  raise Sequel::Rollback if rb
@@ -218,33 +199,34 @@ describe "InstanceHooks plugin with transactions" do
218
199
  @or = @c.load({:id=>1})
219
200
  @or.rb = true
220
201
  @r = []
202
+ @db.sqls
221
203
  end
222
204
 
223
205
  it "should support after_commit_hook" do
224
206
  @o.after_commit_hook{@db.execute('ac1')}
225
207
  @o.after_commit_hook{@db.execute('ac2')}
226
208
  @o.save.should_not be_nil
227
- @logger.sqls.should == ['BEGIN', 'as', 'COMMIT', 'ac1', 'ac2']
209
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT', 'ac1', 'ac2']
228
210
  end
229
211
 
230
212
  it "should support after_rollback_hook" do
231
213
  @or.after_rollback_hook{@db.execute('ar1')}
232
214
  @or.after_rollback_hook{@db.execute('ar2')}
233
215
  @or.save.should be_nil
234
- @logger.sqls.should == ['BEGIN', 'as', 'ROLLBACK', 'ar1', 'ar2']
216
+ @db.sqls.should == ['BEGIN', 'as', 'ROLLBACK', 'ar1', 'ar2']
235
217
  end
236
218
 
237
219
  it "should support after_commit_hook" do
238
220
  @o.after_destroy_commit_hook{@db.execute('adc1')}
239
221
  @o.after_destroy_commit_hook{@db.execute('adc2')}
240
222
  @o.destroy.should_not be_nil
241
- @logger.sqls.should == ['BEGIN', 'ad', 'COMMIT', 'adc1', 'adc2']
223
+ @db.sqls.should == ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'COMMIT', 'adc1', 'adc2']
242
224
  end
243
225
 
244
226
  it "should support after_rollback_hook" do
245
227
  @or.after_destroy_rollback_hook{@db.execute('adr1')}
246
228
  @or.after_destroy_rollback_hook{@db.execute('adr2')}
247
229
  @or.destroy.should be_nil
248
- @logger.sqls.should == ['BEGIN', 'ad', 'ROLLBACK', 'adr1', 'adr2']
230
+ @db.sqls.should == ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'ROLLBACK', 'adr1', 'adr2']
249
231
  end
250
232
  end
@@ -102,8 +102,8 @@ describe "Sequel::Plugins::JsonSerializer" do
102
102
  end
103
103
 
104
104
  it "should support a to_json class and dataset method" do
105
- album = @album
106
- Album.dataset.meta_def(:all){[album]}
105
+ Album.dataset._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
106
+ Artist.dataset._fetch = {:id=>2, :name=>'YJM'}
107
107
  JSON.parse(Album.to_json).should == [@album]
108
108
  JSON.parse(Album.to_json(:include=>:artist)).map{|x| x.artist}.should == [@artist]
109
109
  JSON.parse(Album.dataset.to_json(:only=>:name)).should == [Album.load(:name=>@album.name)]
@@ -112,7 +112,7 @@ describe "Sequel::Plugins::JsonSerializer" do
112
112
  it "should have dataset to_json method work with naked datasets" do
113
113
  album = @album
114
114
  ds = Album.dataset.naked
115
- ds.meta_def(:all){[album.values]}
115
+ ds._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
116
116
  JSON.parse(ds.to_json).should == [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
117
117
  end
118
118
 
@@ -137,8 +137,7 @@ describe "Sequel::Plugins::JsonSerializer" do
137
137
  end
138
138
 
139
139
  it "should handle the :root option to qualify a dataset of records" do
140
- album = @album
141
- Album.dataset.meta_def(:all){[album, album]}
140
+ Album.dataset._fetch = [{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]
142
141
  Album.dataset.to_json(:root=>true, :only => :id).to_s.should == '{"albums":[{"album":{"id":1}},{"album":{"id":1}}]}'
143
142
  end
144
143
 
@@ -1,8 +1,9 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+ require 'yaml'
2
3
 
3
4
  describe "Sequel::Plugins::LazyAttributes" do
4
5
  before do
5
- @db = MockDatabase.new
6
+ @db = Sequel.mock
6
7
  @db.meta_def(:schema){|*a| [[:id, {:type=>:integer}], [:name,{:type=>:string}]]}
7
8
  class ::LazyAttributesModel < Sequel::Model(@db[:la])
8
9
  plugin :lazy_attributes
@@ -10,27 +11,23 @@ describe "Sequel::Plugins::LazyAttributes" do
10
11
  meta_def(:columns){[:id, :name]}
11
12
  lazy_attributes :name
12
13
  meta_def(:columns){[:id]}
13
- ds = dataset
14
- def ds.fetch_rows(sql)
15
- execute(sql)
16
- select = @opts[:select]
17
- where = @opts[:where]
18
- block = @mod_block || proc{|s| s}
19
- if !where
20
- if select.include?(:name)
21
- yield(block[:id=>1, :name=>'1'])
22
- yield(block[:id=>2, :name=>'2'])
14
+ dataset._fetch = proc do |sql|
15
+ if sql !~ /WHERE/
16
+ if sql =~ /name/
17
+ [{:id=>1, :name=>'1'}, {:id=>2, :name=>'2'}]
23
18
  else
24
- yield(:id=>1)
25
- yield(:id=>2)
19
+ [{:id=>1}, {:id=>2}]
26
20
  end
27
21
  else
28
- i = where.args.last
29
- Array(i).each do |x|
22
+ if sql =~ /id IN \(([\d, ]+)\)/
23
+ $1.split(', ')
24
+ elsif sql =~ /id = (\d)/
25
+ [$1]
26
+ end.map do |x|
30
27
  if sql =~ /SELECT name FROM/
31
- yield(block[:name=>x.to_s])
28
+ {:name=>x.to_s}
32
29
  else
33
- yield(block[:id=>x, :name=>x.to_s])
30
+ {:id=>x.to_i, :name=>x.to_s}
34
31
  end
35
32
  end
36
33
  end
@@ -38,7 +35,7 @@ describe "Sequel::Plugins::LazyAttributes" do
38
35
  end
39
36
  @c = ::LazyAttributesModel
40
37
  @ds = LazyAttributesModel.dataset
41
- @db.reset
38
+ @db.sqls
42
39
  end
43
40
  after do
44
41
  Object.send(:remove_const, :LazyAttributesModel)
@@ -136,7 +133,7 @@ describe "Sequel::Plugins::LazyAttributes" do
136
133
 
137
134
  it "should work with the serialization plugin" do
138
135
  @c.plugin :serialization, :yaml, :name
139
- @ds.instance_variable_set(:@mod_block, proc{|s| s.merge(:name=>"--- #{s[:name].to_i*3}\n")})
136
+ @ds._fetch = [[{:id=>1}, {:id=>2}], [{:id=>1, :name=>"--- 3\n"}, {:id=>2, :name=>"--- 6\n"}], [{:id=>1}], [{:name=>"--- 3\n"}]]
140
137
  @c.with_identity_map do
141
138
  ms = @ds.all
142
139
  ms.map{|m| m.values}.should == [{:id=>1}, {:id=>2}]
@@ -146,7 +143,6 @@ describe "Sequel::Plugins::LazyAttributes" do
146
143
  ms.map{|m| m.name}.should == [3,6]
147
144
  @db.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
148
145
  end
149
- @db.reset
150
146
  @c.with_identity_map do
151
147
  m = @ds.first
152
148
  m.values.should == {:id=>1}
@@ -8,32 +8,10 @@ describe "List plugin" do
8
8
  columns :id, :position, :scope_id, :pos
9
9
  plugin :list, opts
10
10
  self.use_transactions = false
11
-
12
- class << self
13
- attr_accessor :rows
14
- end
15
-
16
- def checked_transaction(opts={})
17
- return super if @in_transaction || !use_transaction?(opts)
18
- @in_transaction = true
19
- db.execute 'BEGIN'
20
- super
21
- db.execute 'COMMIT'
22
- @in_transaction = false
23
- end
24
11
  end
25
12
  c
26
13
  end
27
14
 
28
- def y(c, *hs)
29
- c.rows = hs
30
- ds = c.dataset
31
- def ds.fetch_rows(sql)
32
- db.execute(sql)
33
- yield model.rows.shift
34
- end
35
- end
36
-
37
15
  before do
38
16
  @c = klass
39
17
  @o = @c.load(:id=>7, :position=>3)
@@ -89,18 +67,18 @@ describe "List plugin" do
89
67
  end
90
68
 
91
69
  it "should have at_position return the model object at the given position" do
92
- y(@c, :id=>1, :position=>1)
70
+ @c.dataset._fetch = {:id=>1, :position=>1}
93
71
  @o.at_position(10).should == @c.load(:id=>1, :position=>1)
94
- y(@sc, :id=>2, :position=>2, :scope_id=>5)
72
+ @sc.dataset._fetch = {:id=>2, :position=>2, :scope_id=>5}
95
73
  @so.at_position(20).should == @sc.load(:id=>2, :position=>2, :scope_id=>5)
96
74
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 10) ORDER BY position LIMIT 1",
97
75
  "SELECT * FROM items WHERE ((scope_id = 5) AND (position = 20)) ORDER BY scope_id, position LIMIT 1"]
98
76
  end
99
77
 
100
78
  it "should have last_position return the last position in the list" do
101
- y(@c, :max=>10)
79
+ @c.dataset._fetch = {:max=>10}
102
80
  @o.last_position.should == 10
103
- y(@sc, :max=>20)
81
+ @sc.dataset._fetch = {:max=>20}
104
82
  @so.last_position.should == 20
105
83
  @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
106
84
  "SELECT max(position) FROM items WHERE (scope_id = 5) LIMIT 1"]
@@ -115,7 +93,7 @@ describe "List plugin" do
115
93
  end
116
94
 
117
95
  it "should have move_down without an argument move down a single position" do
118
- y(@c, :max=>10)
96
+ @c.dataset._fetch = {:max=>10}
119
97
  @o.move_down.should == @o
120
98
  @o.position.should == 4
121
99
  @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
@@ -124,7 +102,7 @@ describe "List plugin" do
124
102
  end
125
103
 
126
104
  it "should have move_down with an argument move down the given number of positions" do
127
- y(@c, :max=>10)
105
+ @c.dataset._fetch = {:max=>10}
128
106
  @o.move_down(3).should == @o
129
107
  @o.position.should == 6
130
108
  @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
@@ -141,11 +119,11 @@ describe "List plugin" do
141
119
 
142
120
  it "should have move_to raise an error if an invalid target is used" do
143
121
  proc{@o.move_to(0)}.should raise_error(Sequel::Error)
144
- y(@c, :max=>10)
122
+ @c.dataset._fetch = {:max=>10}
145
123
  proc{@o.move_to(11)}.should raise_error(Sequel::Error)
146
124
  end
147
125
 
148
- it "should have move_to use a transaction is the instance is configured to use transactions" do
126
+ it "should have move_to use a transaction if the instance is configured to use transactions" do
149
127
  @o.use_transactions = true
150
128
  @o.move_to(2)
151
129
  @db.sqls.should == ["BEGIN",
@@ -167,13 +145,13 @@ describe "List plugin" do
167
145
  end
168
146
 
169
147
  it "should have move to shift entries correctly between current and target if moving down" do
170
- y(@c, :max=>10)
148
+ @c.dataset._fetch = {:max=>10}
171
149
  @o.move_to(4)
172
150
  @db.sqls[1].should == "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 4))"
173
151
  end
174
152
 
175
153
  it "should have move_to_bottom move the item to the last position" do
176
- y(@c, :max=>10)
154
+ @c.dataset._fetch = {:max=>10}
177
155
  @o.move_to_bottom
178
156
  @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
179
157
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 10))",
@@ -201,7 +179,7 @@ describe "List plugin" do
201
179
  end
202
180
 
203
181
  it "should have move_up with a negative argument move down the given number of positions" do
204
- y(@c, :max=>10)
182
+ @c.dataset._fetch = {:max=>10}
205
183
  @o.move_up(-1).should == @o
206
184
  @o.position.should == 4
207
185
  @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
@@ -210,19 +188,19 @@ describe "List plugin" do
210
188
  end
211
189
 
212
190
  it "should have next return the next entry in the list if not given an argument" do
213
- y(@c, :id=>9, :position=>4)
191
+ @c.dataset._fetch = {:id=>9, :position=>4}
214
192
  @o.next.should == @c.load(:id=>9, :position=>4)
215
193
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
216
194
  end
217
195
 
218
196
  it "should have next return the entry the given number of positions below the instance if given an argument" do
219
- y(@c, :id=>9, :position=>5)
197
+ @c.dataset._fetch = {:id=>9, :position=>5}
220
198
  @o.next(2).should == @c.load(:id=>9, :position=>5)
221
199
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 5) ORDER BY position LIMIT 1"]
222
200
  end
223
201
 
224
202
  it "should have next return a previous entry if given a negative argument" do
225
- y(@c, :id=>9, :position=>2)
203
+ @c.dataset._fetch = {:id=>9, :position=>2}
226
204
  @o.next(-1).should == @c.load(:id=>9, :position=>2)
227
205
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
228
206
  end
@@ -232,19 +210,19 @@ describe "List plugin" do
232
210
  end
233
211
 
234
212
  it "should have prev return the previous entry in the list if not given an argument" do
235
- y(@c, :id=>9, :position=>2)
213
+ @c.dataset._fetch = {:id=>9, :position=>2}
236
214
  @o.prev.should == @c.load(:id=>9, :position=>2)
237
215
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
238
216
  end
239
217
 
240
218
  it "should have prev return the entry the given number of positions above the instance if given an argument" do
241
- y(@c, :id=>9, :position=>1)
219
+ @c.dataset._fetch = {:id=>9, :position=>1}
242
220
  @o.prev(2).should == @c.load(:id=>9, :position=>1)
243
221
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 1) ORDER BY position LIMIT 1"]
244
222
  end
245
223
 
246
224
  it "should have prev return a following entry if given a negative argument" do
247
- y(@c, :id=>9, :position=>4)
225
+ @c.dataset._fetch = {:id=>9, :position=>4}
248
226
  @o.prev(-1).should == @c.load(:id=>9, :position=>4)
249
227
  @db.sqls.should == ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
250
228
  end
@@ -10,14 +10,11 @@ describe Sequel::Model, "many_through_many" do
10
10
  class ::Tag < Sequel::Model
11
11
  columns :id, :h1, :h2
12
12
  end
13
- MODEL_DB.reset
14
13
  @c1 = Artist
15
14
  @c2 = Tag
16
15
  @dataset = @c2.dataset
17
- def @dataset.fetch_rows(sql)
18
- @db << sql
19
- yield({:id=>1})
20
- end
16
+ @dataset._fetch = {:id=>1}
17
+ MODEL_DB.reset
21
18
  end
22
19
  after do
23
20
  Object.send(:remove_const, :Artist)
@@ -25,16 +22,20 @@ describe Sequel::Model, "many_through_many" do
25
22
  end
26
23
 
27
24
  it "should default to associating to other models in the same scope" do
28
- class ::AssociationModuleTest
29
- class Artist < Sequel::Model
30
- plugin :many_through_many
31
- many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
32
- end
33
- class Tag < Sequel::Model
25
+ begin
26
+ class ::AssociationModuleTest
27
+ class Artist < Sequel::Model
28
+ plugin :many_through_many
29
+ many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
30
+ end
31
+ class Tag < Sequel::Model
32
+ end
34
33
  end
35
- end
36
-
37
- ::AssociationModuleTest::Artist.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
34
+
35
+ ::AssociationModuleTest::Artist.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
36
+ ensure
37
+ Object.send(:remove_const, :AssociationModuleTest)
38
+ end
38
39
  end
39
40
 
40
41
  it "should raise an error if in invalid form of through is used" do
@@ -46,9 +47,7 @@ describe Sequel::Model, "many_through_many" do
46
47
  it "should allow only two arguments with the :through option" do
47
48
  @c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
48
49
  n = @c1.load(:id => 1234)
49
- a = n.tags_dataset
50
- a.should be_a_kind_of(Sequel::Dataset)
51
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
50
+ 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))'
52
51
  n.tags.should == [@c2.load(:id=>1)]
53
52
  end
54
53
 
@@ -56,18 +55,14 @@ describe Sequel::Model, "many_through_many" do
56
55
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
57
56
  @c1.many_through_many :other_tags, :clone=>:tags
58
57
  n = @c1.load(:id => 1234)
59
- a = n.other_tags_dataset
60
- a.should be_a_kind_of(Sequel::Dataset)
61
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
58
+ 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))'
62
59
  n.tags.should == [@c2.load(:id=>1)]
63
60
  end
64
61
 
65
62
  it "should use join tables given" do
66
63
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
67
64
  n = @c1.load(:id => 1234)
68
- a = n.tags_dataset
69
- a.should be_a_kind_of(Sequel::Dataset)
70
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
65
+ 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))'
71
66
  n.tags.should == [@c2.load(:id=>1)]
72
67
  end
73
68
 
@@ -76,9 +71,7 @@ describe Sequel::Model, "many_through_many" do
76
71
  end
77
72
  @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]]
78
73
  n = @c1.load(:id => 1234)
79
- a = n.albums_dataset
80
- a.should be_a_kind_of(Sequel::Dataset)
81
- a.sql.should == 'SELECT albums.* FROM albums INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) INNER JOIN artists ON (artists.id = albums_artists.artist_id) INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) INNER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) INNER JOIN albums_artists AS albums_artists_1 ON ((albums_artists_1.album_id = albums_0.id) AND (albums_artists_1.artist_id = 1234))'
74
+ 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))'
82
75
  n.albums.should == [Album.load(:id=>1, :x=>1)]
83
76
  Object.send(:remove_const, :Album)
84
77
  end
@@ -86,9 +79,7 @@ describe Sequel::Model, "many_through_many" do
86
79
  it "should use explicit class if given" do
87
80
  @c1.many_through_many :albums_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag
88
81
  n = @c1.load(:id => 1234)
89
- a = n.albums_tags_dataset
90
- a.should be_a_kind_of(Sequel::Dataset)
91
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
82
+ 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))'
92
83
  n.albums_tags.should == [@c2.load(:id=>1)]
93
84
  end
94
85
 
@@ -96,9 +87,7 @@ describe Sequel::Model, "many_through_many" do
96
87
  @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
97
88
  n = @c1.load(:id => 1234)
98
89
  n.yyy = 85
99
- a = n.tags_dataset
100
- a.should be_a_kind_of(Sequel::Dataset)
101
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.tag_id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 85))'
90
+ 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))'
102
91
  n.tags.should == [@c2.load(:id=>1)]
103
92
  end
104
93
 
@@ -106,9 +95,7 @@ describe Sequel::Model, "many_through_many" do
106
95
  @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]
107
96
  n = @c1.load(:id => 1234)
108
97
  n.yyy = 85
109
- a = n.tags_dataset
110
- a.should be_a_kind_of(Sequel::Dataset)
111
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2) AND (albums_artists.b1 = 1234) AND (albums_artists.b2 = 85))'
98
+ 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))'
112
99
  n.tags.should == [@c2.load(:id=>1)]
113
100
  end
114
101
 
@@ -191,52 +178,40 @@ describe Sequel::Model, "many_through_many" do
191
178
  it "should support a :conditions option" do
192
179
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:a=>32}
193
180
  n = @c1.load(:id => 1234)
194
- a = n.tags_dataset
195
- a.should be_a_kind_of(Sequel::Dataset)
196
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (a = 32)'
181
+ 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)'
197
182
  n.tags.should == [@c2.load(:id=>1)]
198
183
 
199
184
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>['a = ?', 42]
200
185
  n = @c1.load(:id => 1234)
201
- a = n.tags_dataset
202
- a.should be_a_kind_of(Sequel::Dataset)
203
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (a = 42)'
186
+ 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)'
204
187
  n.tags.should == [@c2.load(:id=>1)]
205
188
  end
206
189
 
207
190
  it "should support an :order option" do
208
191
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:blah
209
192
  n = @c1.load(:id => 1234)
210
- a = n.tags_dataset
211
- a.should be_a_kind_of(Sequel::Dataset)
212
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) ORDER BY blah'
193
+ 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'
213
194
  n.tags.should == [@c2.load(:id=>1)]
214
195
  end
215
196
 
216
197
  it "should support an array for the :order option" do
217
198
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>[:blah1, :blah2]
218
199
  n = @c1.load(:id => 1234)
219
- a = n.tags_dataset
220
- a.should be_a_kind_of(Sequel::Dataset)
221
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) ORDER BY blah1, blah2'
200
+ 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'
222
201
  n.tags.should == [@c2.load(:id=>1)]
223
202
  end
224
203
 
225
204
  it "should support a select option" do
226
205
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>:blah
227
206
  n = @c1.load(:id => 1234)
228
- a = n.tags_dataset
229
- a.should be_a_kind_of(Sequel::Dataset)
230
- a.sql.should == 'SELECT blah FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
207
+ 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))'
231
208
  n.tags.should == [@c2.load(:id=>1)]
232
209
  end
233
210
 
234
211
  it "should support an array for the select option" do
235
212
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :select=>[:tags.*, :albums__name]
236
213
  n = @c1.load(:id => 1234)
237
- a = n.tags_dataset
238
- a.should be_a_kind_of(Sequel::Dataset)
239
- a.sql.should == 'SELECT tags.*, albums.name FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))'
214
+ 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))'
240
215
  n.tags.should == [@c2.load(:id=>1)]
241
216
  end
242
217
 
@@ -244,9 +219,7 @@ describe Sequel::Model, "many_through_many" do
244
219
  @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
245
220
  n = @c1.load(:id => 1234)
246
221
  n.yyy = 85
247
- a = n.tags_dataset
248
- a.should be_a_kind_of(Sequel::Dataset)
249
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85)'
222
+ 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)'
250
223
  n.tags.should == [@c2.load(:id=>1)]
251
224
  end
252
225
 
@@ -254,34 +227,26 @@ describe Sequel::Model, "many_through_many" do
254
227
  @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
255
228
  n = @c1.load(:id => 1234)
256
229
  n.yyy = 85
257
- a = n.tags_dataset
258
- a.should be_a_kind_of(Sequel::Dataset)
259
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) WHERE (yyy = 85) ORDER BY blah'
230
+ 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'
260
231
  n.tags.should == [@c2.load(:id=>1)]
261
232
  end
262
233
 
263
234
  it "should support a :dataset option that is used instead of the default" do
264
235
  @c1.many_through_many :tags, [[:a, :b, :c]], :dataset=>proc{Tag.join(:albums_tags, [:tag_id]).join(:albums, [:album_id]).join(:albums_artists, [:album_id]).filter(:albums_artists__artist_id=>id)}
265
236
  n = @c1.load(:id => 1234)
266
- a = n.tags_dataset
267
- a.should be_a_kind_of(Sequel::Dataset)
268
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234)'
237
+ n.tags_dataset.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags USING (tag_id) INNER JOIN albums USING (album_id) INNER JOIN albums_artists USING (album_id) WHERE (albums_artists.artist_id = 1234)'
269
238
  n.tags.should == [@c2.load(:id=>1)]
270
239
  end
271
240
 
272
241
  it "should support a :limit option" do
273
242
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
274
243
  n = @c1.load(:id => 1234)
275
- a = n.tags_dataset
276
- a.should be_a_kind_of(Sequel::Dataset)
277
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 10'
244
+ 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'
278
245
  n.tags.should == [@c2.load(:id=>1)]
279
246
 
280
247
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>[10, 10]
281
248
  n = @c1.load(:id => 1234)
282
- a = n.tags_dataset
283
- a.should be_a_kind_of(Sequel::Dataset)
284
- a.sql.should == 'SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234)) LIMIT 10 OFFSET 10'
249
+ 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'
285
250
  n.tags.should == [@c2.load(:id=>1)]
286
251
  end
287
252
 
@@ -305,7 +270,7 @@ describe Sequel::Model, "many_through_many" do
305
270
  n.tags.should == [@c2.load(:id=>1)]
306
271
  MODEL_DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))']
307
272
  n.associations[:tags].should == n.tags
308
- MODEL_DB.sqls.length.should == 1
273
+ MODEL_DB.sqls.length.should == 0
309
274
  end
310
275
 
311
276
  it "should use cached instance variable if available" do
@@ -324,7 +289,7 @@ describe Sequel::Model, "many_through_many" do
324
289
  n.tags(true).should == [@c2.load(:id=>1)]
325
290
  MODEL_DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1234))']
326
291
  n.associations[:tags].should == n.tags
327
- MODEL_DB.sqls.length.should == 1
292
+ MODEL_DB.sqls.length.should == 0
328
293
  end
329
294
 
330
295
  it "should not add associations methods directly to class" do
@@ -341,18 +306,13 @@ describe Sequel::Model, "many_through_many" do
341
306
  h = []
342
307
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :after_load=>:al
343
308
  @c1.class_eval do
344
- class_variable_set(:@@blah, h)
309
+ self::Foo = h
345
310
  def al(v)
346
- v.each{|x| self.class.send(:class_variable_get, :@@blah) << x.pk * 20}
347
- end
348
- end
349
- @c2.class_eval do
350
- def @dataset.fetch_rows(sql)
351
- yield({:id=>20})
352
- yield({:id=>30})
311
+ v.each{|x| model::Foo << x.pk * 20}
353
312
  end
354
313
  end
355
- p = @c1.load(:id=>10, :parent_id=>20)
314
+ @c2.dataset._fetch = [{:id=>20}, {:id=>30}]
315
+ p = @c1.load(:id=>10, :parent_id=>20)
356
316
  p.tags
357
317
  h.should == [400, 600]
358
318
  p.tags.collect{|a| a.pk}.should == [20, 30]
@@ -361,14 +321,7 @@ describe Sequel::Model, "many_through_many" do
361
321
  it "should support a :uniq option that removes duplicates from the association" do
362
322
  h = []
363
323
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :uniq=>true
364
- @c2.class_eval do
365
- def @dataset.fetch_rows(sql)
366
- yield({:id=>20})
367
- yield({:id=>30})
368
- yield({:id=>20})
369
- yield({:id=>30})
370
- end
371
- end
324
+ @c2.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
372
325
  @c1.load(:id=>10).tags.should == [@c2.load(:id=>20), @c2.load(:id=>30)]
373
326
  end
374
327
  end
@@ -429,57 +382,40 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
429
382
  end
430
383
  class ::Track < Sequel::Model
431
384
  end
432
-
433
- Artist.dataset.extend(Module.new {
434
- def columns
435
- [:id]
436
- end
437
-
438
- def fetch_rows(sql)
439
- @db << sql
440
- h = {:id => 1}
441
- if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
442
- h[:tags_id] = 2
443
- h[:albums_0_id] = 3 if sql =~ /LEFT OUTER JOIN albums AS albums_0/
444
- h[:tracks_id] = 4 if sql =~ /LEFT OUTER JOIN tracks/
445
- h[:other_tags_id] = 9 if sql =~ /other_tags\.id AS other_tags_id/
446
- h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
447
- end
448
- yield h
449
- end
450
- })
451
-
452
- Tag.dataset.extend(Module.new {
453
- def fetch_rows(sql)
454
- @db << sql
455
- h = {:id => 2}
456
- if sql =~ /albums_artists.artist_id IN \(([18])\)/
457
- h.merge!(:x_foreign_key_x=>$1.to_i)
458
- elsif sql =~ /\(\(albums_artists.b1, albums_artists.b2\) IN \(\(1, 8\)\)\)/
459
- h.merge!(:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>8)
460
- end
461
- h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
462
- yield h
385
+ Artist.dataset.columns(:id)._fetch = proc do |sql|
386
+ h = {:id => 1}
387
+ if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
388
+ h[:tags_id] = 2
389
+ h[:albums_0_id] = 3 if sql =~ /LEFT OUTER JOIN albums AS albums_0/
390
+ h[:tracks_id] = 4 if sql =~ /LEFT OUTER JOIN tracks/
391
+ h[:other_tags_id] = 9 if sql =~ /other_tags\.id AS other_tags_id/
392
+ h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
463
393
  end
464
- })
394
+ h
395
+ end
465
396
 
466
- Album.dataset.extend(Module.new {
467
- def fetch_rows(sql)
468
- @db << sql
469
- h = {:id => 3}
470
- h.merge!(:x_foreign_key_x=>1) if sql =~ /albums_artists.artist_id IN \(1\)/
471
- yield h
397
+ Tag.dataset._fetch = proc do |sql|
398
+ h = {:id => 2}
399
+ if sql =~ /albums_artists.artist_id IN \(([18])\)/
400
+ h[:x_foreign_key_x] = $1.to_i
401
+ elsif sql =~ /\(\(albums_artists.b1, albums_artists.b2\) IN \(\(1, 8\)\)\)/
402
+ h.merge!(:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>8)
472
403
  end
473
- })
404
+ h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
405
+ h
406
+ end
474
407
 
475
- Track.dataset.extend(Module.new {
476
- def fetch_rows(sql)
477
- @db << sql
478
- h = {:id => 4}
479
- h.merge!(:x_foreign_key_x=>2) if sql =~ /albums_tags.tag_id IN \(2\)/
480
- yield h
481
- end
482
- })
408
+ Album.dataset._fetch = proc do |sql|
409
+ h = {:id => 3}
410
+ h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
411
+ h
412
+ end
413
+
414
+ Track.dataset._fetch = proc do |sql|
415
+ h = {:id => 4}
416
+ h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
417
+ h
418
+ end
483
419
 
484
420
  @c1 = Artist
485
421
  MODEL_DB.reset
@@ -493,33 +429,35 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
493
429
  a.should == [@c1.load(:id=>1)]
494
430
  MODEL_DB.sqls.should == ['SELECT * FROM artists', 'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
495
431
  a.first.tags.should == [Tag.load(:id=>2)]
496
- MODEL_DB.sqls.length.should == 2
432
+ MODEL_DB.sqls.length.should == 0
497
433
  end
498
434
 
499
435
  it "should eagerly load multiple associations in a single call" do
500
436
  a = @c1.eager(:tags, :albums).all
501
437
  a.should == [@c1.load(:id=>1)]
502
- MODEL_DB.sqls.length.should == 3
503
- MODEL_DB.sqls[0].should == 'SELECT * FROM artists'
504
- MODEL_DB.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)))'))
505
- MODEL_DB.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)))'))
438
+ sqls = MODEL_DB.sqls
439
+ sqls.length.should == 3
440
+ sqls[0].should == 'SELECT * FROM artists'
441
+ 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)))'))
442
+ 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)))'))
506
443
  a = a.first
507
444
  a.tags.should == [Tag.load(:id=>2)]
508
445
  a.albums.should == [Album.load(:id=>3)]
509
- MODEL_DB.sqls.length.should == 3
446
+ MODEL_DB.sqls.length.should == 0
510
447
  end
511
448
 
512
449
  it "should eagerly load multiple associations in separate" do
513
450
  a = @c1.eager(:tags).eager(:albums).all
514
451
  a.should == [@c1.load(:id=>1)]
515
- MODEL_DB.sqls.length.should == 3
516
- MODEL_DB.sqls[0].should == 'SELECT * FROM artists'
517
- MODEL_DB.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)))'))
518
- MODEL_DB.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)))'))
452
+ sqls = MODEL_DB.sqls
453
+ sqls.length.should == 3
454
+ sqls[0].should == 'SELECT * FROM artists'
455
+ 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)))'))
456
+ 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)))'))
519
457
  a = a.first
520
458
  a.tags.should == [Tag.load(:id=>2)]
521
459
  a.albums.should == [Album.load(:id=>3)]
522
- MODEL_DB.sqls.length.should == 3
460
+ MODEL_DB.sqls.length.should == 0
523
461
  end
524
462
 
525
463
  it "should allow cascading of eager loading for associations of associated models" do
@@ -531,7 +469,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
531
469
  a = a.first
532
470
  a.tags.should == [Tag.load(:id=>2)]
533
471
  a.tags.first.tracks.should == [Track.load(:id=>4)]
534
- MODEL_DB.sqls.length.should == 3
472
+ MODEL_DB.sqls.length.should == 0
535
473
  end
536
474
 
537
475
  it "should cascade eagerly loading when the :eager association option is used" do
@@ -544,7 +482,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
544
482
  a = a.first
545
483
  a.tags.should == [Tag.load(:id=>2)]
546
484
  a.tags.first.tracks.should == [Track.load(:id=>4)]
547
- MODEL_DB.sqls.length.should == 3
485
+ MODEL_DB.sqls.length.should == 0
548
486
  end
549
487
 
550
488
  it "should respect :eager when lazily loading an association" do
@@ -554,7 +492,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
554
492
  MODEL_DB.sqls.should == ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1))',
555
493
  '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)))']
556
494
  a.tags.first.tracks.should == [Track.load(:id=>4)]
557
- MODEL_DB.sqls.length.should == 2
495
+ MODEL_DB.sqls.length.should == 0
558
496
  end
559
497
 
560
498
  it "should cascade eagerly loading when the :eager_graph association option is used" do
@@ -563,14 +501,11 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
563
501
  end
564
502
 
565
503
  it "should respect :eager_graph when lazily loading an association" do
504
+ Tag.dataset._fetch = {:id=>2, :tracks_id=>4}
566
505
  Tag.dataset.extend(Module.new {
567
506
  def columns
568
507
  [:id]
569
508
  end
570
- def fetch_rows(sql)
571
- @db << sql
572
- yield({:id=>2, :tracks_id=>4})
573
- end
574
509
  })
575
510
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
576
511
  a = @c1.load(:id=>1)
@@ -578,7 +513,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
578
513
  MODEL_DB.sqls.should == [ 'SELECT tags.id, tracks.id AS tracks_id FROM (SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id = 1))) AS tags LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums ON (albums.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
579
514
  a.tags.should == [Tag.load(:id=>2)]
580
515
  a.tags.first.tracks.should == [Track.load(:id=>4)]
581
- MODEL_DB.sqls.length.should == 1
516
+ MODEL_DB.sqls.length.should == 0
582
517
  end
583
518
 
584
519
  it "should respect :conditions when eagerly loading" do
@@ -588,7 +523,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
588
523
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
589
524
  '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)']
590
525
  a.first.tags.should == [Tag.load(:id=>2)]
591
- MODEL_DB.sqls.length.should == 2
526
+ MODEL_DB.sqls.length.should == 0
592
527
  end
593
528
 
594
529
  it "should respect :order when eagerly loading" do
@@ -598,7 +533,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
598
533
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
599
534
  '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']
600
535
  a.first.tags.should == [Tag.load(:id=>2)]
601
- MODEL_DB.sqls.length.should == 2
536
+ MODEL_DB.sqls.length.should == 0
602
537
  end
603
538
 
604
539
  it "should use the association's block when eager loading by default" do
@@ -608,7 +543,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
608
543
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
609
544
  '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']
610
545
  a.first.tags.should == [Tag.load(:id=>2)]
611
- MODEL_DB.sqls.length.should == 2
546
+ MODEL_DB.sqls.length.should == 0
612
547
  end
613
548
 
614
549
  it "should use the :eager_block option when eager loading if given" do
@@ -618,121 +553,87 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
618
553
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
619
554
  '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']
620
555
  a.first.tags.should == [Tag.load(:id=>2)]
621
- MODEL_DB.sqls.length.should == 2
556
+ MODEL_DB.sqls.length.should == 0
622
557
  end
623
558
 
624
559
  it "should respect the :limit option on a many_through_many association" do
625
560
  @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
626
- Tag.dataset.extend(Module.new {
627
- def fetch_rows(sql)
628
- MODEL_DB.sqls << sql
629
- yield({:x_foreign_key_x=>1, :id=>5})
630
- yield({:x_foreign_key_x=>1, :id=>6})
631
- yield({:x_foreign_key_x=>1, :id=>7})
632
- end
633
- })
561
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
634
562
  a = @c1.eager(:first_two_tags).all
635
563
  a.should == [@c1.load(:id=>1)]
636
564
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
637
565
  '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)))']
638
566
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
639
- MODEL_DB.sqls.length.should == 2
567
+ MODEL_DB.sqls.length.should == 0
640
568
 
641
- MODEL_DB.reset
642
569
  @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]
643
570
  a = @c1.eager(:first_two_tags).all
644
571
  a.should == [@c1.load(:id=>1)]
645
572
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
646
573
  '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)))']
647
574
  a.first.first_two_tags.should == [Tag.load(:id=>6), Tag.load(:id=>7)]
648
- MODEL_DB.sqls.length.should == 2
575
+ MODEL_DB.sqls.length.should == 0
649
576
  end
650
577
 
651
578
  it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
652
579
  Tag.dataset.meta_def(:supports_window_functions?){true}
653
580
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>true, :order=>:name
654
- Tag.dataset.extend(Module.new {
655
- def fetch_rows(sql)
656
- MODEL_DB.sqls << sql
657
- yield({:x_foreign_key_x=>1, :id=>5})
658
- yield({:x_foreign_key_x=>1, :id=>6})
659
- end
660
- })
581
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
661
582
  a = @c1.eager(:first_two_tags).all
662
583
  a.should == [@c1.load(:id=>1)]
663
584
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
664
585
  '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)']
665
586
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
666
- MODEL_DB.sqls.length.should == 2
587
+ MODEL_DB.sqls.length.should == 0
667
588
 
668
- MODEL_DB.reset
669
589
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>true, :order=>:name
670
590
  a = @c1.eager(:first_two_tags).all
671
591
  a.should == [@c1.load(:id=>1)]
672
592
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
673
593
  '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))']
674
594
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
675
- MODEL_DB.sqls.length.should == 2
595
+ MODEL_DB.sqls.length.should == 0
676
596
  end
677
597
 
678
598
  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
679
599
  Tag.dataset.meta_def(:supports_window_functions?){true}
680
600
  @c1.set_primary_key([:id1, :id2])
681
601
  @c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>true, :order=>:name
682
- @c1.dataset.extend(Module.new {
683
- def fetch_rows(sql)
684
- MODEL_DB.sqls << sql
685
- yield({:id1=>1, :id2=>2})
686
- end
687
- })
688
- Tag.dataset.extend(Module.new {
689
- def fetch_rows(sql)
690
- MODEL_DB.sqls << sql
691
- yield({:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5})
692
- yield({:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6})
693
- end
694
- })
602
+ @c1.dataset._fetch = [{:id1=>1, :id2=>2}]
603
+ 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}]
695
604
  a = @c1.eager(:first_two_tags).all
696
605
  a.should == [@c1.load(:id1=>1, :id2=>2)]
697
606
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
698
607
  '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)']
699
608
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
700
- MODEL_DB.sqls.length.should == 2
609
+ MODEL_DB.sqls.length.should == 0
701
610
 
702
- MODEL_DB.reset
703
611
  @c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>true, :order=>:name
704
612
  a = @c1.eager(:first_two_tags).all
705
613
  a.should == [@c1.load(:id1=>1, :id2=>2)]
706
614
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
707
615
  '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))']
708
616
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
709
- MODEL_DB.sqls.length.should == 2
617
+ MODEL_DB.sqls.length.should == 0
710
618
  end
711
619
 
712
620
  it "should respect the :limit option on a many_through_many association using a :correlated_subquery strategy" do
713
621
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:correlated_subquery, :order=>:name
714
- Tag.dataset.extend(Module.new {
715
- def fetch_rows(sql)
716
- MODEL_DB.sqls << sql
717
- yield({:x_foreign_key_x=>1, :id=>5})
718
- yield({:x_foreign_key_x=>1, :id=>6})
719
- end
720
- })
622
+ Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
721
623
  a = @c1.eager(:first_two_tags).all
722
624
  a.should == [@c1.load(:id=>1)]
723
625
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
724
626
  'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2)) ORDER BY name']
725
627
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
726
- MODEL_DB.sqls.length.should == 2
628
+ MODEL_DB.sqls.length.should == 0
727
629
 
728
- MODEL_DB.reset
729
630
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>:correlated_subquery, :order=>:name
730
631
  a = @c1.eager(:first_two_tags).all
731
632
  a.should == [@c1.load(:id=>1)]
732
633
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
733
634
  'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2 OFFSET 1)) ORDER BY name']
734
635
  a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
735
- MODEL_DB.sqls.length.should == 2
636
+ MODEL_DB.sqls.length.should == 0
736
637
  end
737
638
 
738
639
  it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
@@ -748,47 +649,33 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
748
649
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
749
650
  '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)))']
750
651
  a.first.tags.should == [Tag.load(:id=>2)]
751
- MODEL_DB.sqls.length.should == 2
652
+ MODEL_DB.sqls.length.should == 0
752
653
  end
753
654
 
754
655
  it "should respect many_through_many association's :left_primary_key and :right_primary_key options" do
755
656
  @c1.send(:define_method, :yyy){values[:yyy]}
756
- @c1.dataset.extend(Module.new {
757
- def columns
758
- [:id, :yyy]
759
- end
760
- def fetch_rows(sql)
761
- @db << sql
762
- yield({:id=>1, :yyy=>8})
763
- end
764
- })
657
+ @c1.dataset._fetch = {:id=>1, :yyy=>8}
658
+ @c1.dataset.meta_def(:columns){[:id, :yyy]}
765
659
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
766
660
  a = @c1.eager(:tags).all
767
661
  a.should == [@c1.load(:id=>1, :yyy=>8)]
768
662
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
769
663
  '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)))']
770
664
  a.first.tags.should == [Tag.load(:tag_id=>2)]
771
- MODEL_DB.sqls.length.should == 2
665
+ MODEL_DB.sqls.length.should == 0
772
666
  end
773
667
 
774
668
  it "should handle composite keys" do
775
669
  @c1.send(:define_method, :yyy){values[:yyy]}
776
- @c1.dataset.extend(Module.new {
777
- def columns
778
- [:id, :yyy]
779
- end
780
- def fetch_rows(sql)
781
- @db << sql
782
- yield({:id=>1, :yyy=>8})
783
- end
784
- })
670
+ @c1.dataset._fetch = {:id=>1, :yyy=>8}
671
+ @c1.dataset.meta_def(:columns){[:id, :yyy]}
785
672
  @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]
786
673
  a = @c1.eager(:tags).all
787
674
  a.should == [@c1.load(:id=>1, :yyy=>8)]
788
675
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
789
676
  '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))))']
790
677
  a.first.tags.should == [Tag.load(:id=>2)]
791
- MODEL_DB.sqls.length.should == 2
678
+ MODEL_DB.sqls.length.should == 0
792
679
  end
793
680
 
794
681
  it "should respect :after_load callbacks on associations when eager loading" do
@@ -798,7 +685,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
798
685
  MODEL_DB.sqls.should == ['SELECT * FROM artists',
799
686
  '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)))']
800
687
  a.first.tags.should == [Tag.load(:id=>6)]
801
- MODEL_DB.sqls.length.should == 2
688
+ MODEL_DB.sqls.length.should == 0
802
689
  end
803
690
 
804
691
  it "should raise an error if called without a symbol or hash" do
@@ -810,7 +697,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
810
697
  a.should == [@c1.load(:id=>1)]
811
698
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
812
699
  a.first.tags.should == [Tag.load(:id=>2)]
813
- MODEL_DB.sqls.length.should == 1
700
+ MODEL_DB.sqls.length.should == 0
814
701
  end
815
702
 
816
703
  it "should eagerly graph multiple associations in a single call" do
@@ -820,7 +707,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
820
707
  a = a.first
821
708
  a.tags.should == [Tag.load(:id=>2)]
822
709
  a.albums.should == [Album.load(:id=>3)]
823
- MODEL_DB.sqls.length.should == 1
710
+ MODEL_DB.sqls.length.should == 0
824
711
  end
825
712
 
826
713
  it "should eagerly graph multiple associations in separate calls" do
@@ -830,7 +717,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
830
717
  a = a.first
831
718
  a.tags.should == [Tag.load(:id=>2)]
832
719
  a.albums.should == [Album.load(:id=>3)]
833
- MODEL_DB.sqls.length.should == 1
720
+ MODEL_DB.sqls.length.should == 0
834
721
  end
835
722
 
836
723
  it "should allow cascading of eager graphing for associations of associated models" do
@@ -840,24 +727,18 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
840
727
  a = a.first
841
728
  a.tags.should == [Tag.load(:id=>2)]
842
729
  a.tags.first.tracks.should == [Track.load(:id=>4)]
843
- MODEL_DB.sqls.length.should == 1
730
+ MODEL_DB.sqls.length.should == 0
844
731
  end
845
732
 
846
733
  it "eager graphing should eliminate duplicates caused by cartesian products" do
847
734
  ds = @c1.eager_graph(:tags)
848
- def ds.fetch_rows(sql, &block)
849
- @db << sql
850
- # Assume artist has 2 albums each with 2 tags
851
- yield({:id=>1, :tags_id=>2})
852
- yield({:id=>1, :tags_id=>3})
853
- yield({:id=>1, :tags_id=>2})
854
- yield({:id=>1, :tags_id=>3})
855
- end
735
+ # Assume artist has 2 albums each with 2 tags
736
+ ds._fetch = [{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]
856
737
  a = ds.all
857
738
  a.should == [@c1.load(:id=>1)]
858
739
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
859
740
  a.first.tags.should == [Tag.load(:id=>2), Tag.load(:id=>3)]
860
- MODEL_DB.sqls.length.should == 1
741
+ MODEL_DB.sqls.length.should == 0
861
742
  end
862
743
 
863
744
  it "should eager graph multiple associations from the same table" do
@@ -867,7 +748,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
867
748
  a = a.first
868
749
  a.tags.should == [Tag.load(:id=>2)]
869
750
  a.other_tags.should == [Tag.load(:id=>9)]
870
- MODEL_DB.sqls.length.should == 1
751
+ MODEL_DB.sqls.length.should == 0
871
752
  end
872
753
 
873
754
  it "should eager graph a self_referential association" do
@@ -877,7 +758,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
877
758
  a = a.first
878
759
  a.tags.should == [Tag.load(:id=>2)]
879
760
  a.artists.should == [@c1.load(:id=>10)]
880
- MODEL_DB.sqls.length.should == 1
761
+ MODEL_DB.sqls.length.should == 0
881
762
  end
882
763
 
883
764
  it "eager graphing should give you a plain hash when called without .all" do
@@ -892,31 +773,22 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
892
773
  a = a.first
893
774
  a.tags.should == [Tag.load(:id=>2)]
894
775
  a.albums.should == [Album.load(:id=>3)]
895
- MODEL_DB.sqls.length.should == 2
776
+ MODEL_DB.sqls.length.should == 0
896
777
  end
897
778
 
898
779
  it "should handle no associated records when eagerly graphing a single many_through_many association" do
899
780
  ds = @c1.eager_graph(:tags)
900
- def ds.fetch_rows(sql)
901
- @db << sql
902
- yield({:id=>1, :tags_id=>nil})
903
- end
781
+ ds._fetch = {:id=>1, :tags_id=>nil}
904
782
  a = ds.all
905
783
  a.should == [@c1.load(:id=>1)]
906
784
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
907
785
  a.first.tags.should == []
908
- MODEL_DB.sqls.length.should == 1
786
+ MODEL_DB.sqls.length.should == 0
909
787
  end
910
788
 
911
789
  it "should handle no associated records when eagerly graphing multiple many_through_many associations" do
912
790
  ds = @c1.eager_graph(:tags, :albums)
913
- def ds.fetch_rows(sql)
914
- @db << sql
915
- yield({:id=>1, :tags_id=>nil, :albums_0_id=>3})
916
- yield({:id=>1, :tags_id=>2, :albums_0_id=>nil})
917
- yield({:id=>1, :tags_id=>5, :albums_0_id=>6})
918
- yield({:id=>7, :tags_id=>nil, :albums_0_id=>nil})
919
- end
791
+ ds._fetch = [{:id=>1, :tags_id=>nil, :albums_0_id=>3}, {:id=>1, :tags_id=>2, :albums_0_id=>nil}, {:id=>1, :tags_id=>5, :albums_0_id=>6}, {:id=>7, :tags_id=>nil, :albums_0_id=>nil}]
920
792
  a = ds.all
921
793
  a.should == [@c1.load(:id=>1), @c1.load(:id=>7)]
922
794
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id, albums_0.id AS albums_0_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id)']
@@ -924,17 +796,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
924
796
  a.first.albums.should == [Album.load(:id=>3), Album.load(:id=>6)]
925
797
  a.last.tags.should == []
926
798
  a.last.albums.should == []
927
- MODEL_DB.sqls.length.should == 1
799
+ MODEL_DB.sqls.length.should == 0
928
800
  end
929
801
 
930
802
  it "should handle missing associated records when cascading eager graphing for associations of associated models" do
931
803
  ds = @c1.eager_graph(:tags=>:tracks)
932
- def ds.fetch_rows(sql)
933
- @db << sql
934
- yield({:id=>1, :tags_id=>2, :tracks_id=>4})
935
- yield({:id=>1, :tags_id=>3, :tracks_id=>nil})
936
- yield({:id=>2, :tags_id=>nil, :tracks_id=>nil})
937
- end
804
+ ds._fetch = [{:id=>1, :tags_id=>2, :tracks_id=>4}, {:id=>1, :tags_id=>3, :tracks_id=>nil}, {:id=>2, :tags_id=>nil, :tracks_id=>nil}]
938
805
  a = ds.all
939
806
  a.should == [@c1.load(:id=>1), @c1.load(:id=>2)]
940
807
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.id AS tags_id, tracks.id AS tracks_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums_0.id)']
@@ -943,7 +810,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
943
810
  a.tags.should == [Tag.load(:id=>2), Tag.load(:id=>3)]
944
811
  a.tags.first.tracks.should == [Track.load(:id=>4)]
945
812
  a.tags.last.tracks.should == []
946
- MODEL_DB.sqls.length.should == 1
813
+ MODEL_DB.sqls.length.should == 0
947
814
  end
948
815
 
949
816
  it "eager graphing should respect :left_primary_key and :right_primary_key options" do
@@ -951,15 +818,12 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
951
818
  @c1.dataset.meta_def(:columns){[:id, :yyy]}
952
819
  Tag.dataset.meta_def(:columns){[:id, :tag_id]}
953
820
  ds = @c1.eager_graph(:tags)
954
- def ds.fetch_rows(sql)
955
- @db << sql
956
- yield({:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4})
957
- end
821
+ ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
958
822
  a = ds.all
959
823
  a.should == [@c1.load(:id=>1, :yyy=>8)]
960
824
  MODEL_DB.sqls.should == ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.tag_id = albums_tags.tag_id)']
961
825
  a.first.tags.should == [Tag.load(:id=>2, :tag_id=>4)]
962
- MODEL_DB.sqls.length.should == 1
826
+ MODEL_DB.sqls.length.should == 0
963
827
  end
964
828
 
965
829
  it "eager graphing should respect composite keys" do
@@ -967,29 +831,23 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
967
831
  @c1.dataset.meta_def(:columns){[:id, :yyy]}
968
832
  Tag.dataset.meta_def(:columns){[:id, :tag_id]}
969
833
  ds = @c1.eager_graph(:tags)
970
- def ds.fetch_rows(sql)
971
- @db << sql
972
- yield({:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4})
973
- end
834
+ ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
974
835
  a = ds.all
975
836
  a.should == [@c1.load(:id=>1, :yyy=>8)]
976
837
  MODEL_DB.sqls.should == ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags ON ((tags.id = albums_tags.g1) AND (tags.tag_id = albums_tags.g2))']
977
838
  a.first.tags.should == [Tag.load(:id=>2, :tag_id=>4)]
978
- MODEL_DB.sqls.length.should == 1
839
+ MODEL_DB.sqls.length.should == 0
979
840
  end
980
841
 
981
842
  it "should respect the association's :graph_select option" do
982
843
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
983
844
  ds = @c1.eager_graph(:tags)
984
- def ds.fetch_rows(sql)
985
- @db << sql
986
- yield({:id=>1, :b=>2})
987
- end
845
+ ds._fetch = {:id=>1, :b=>2}
988
846
  a = ds.all
989
847
  a.should == [@c1.load(:id=>1)]
990
848
  MODEL_DB.sqls.should == ['SELECT artists.id, tags.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
991
849
  a.first.tags.should == [Tag.load(:b=>2)]
992
- MODEL_DB.sqls.length.should == 1
850
+ MODEL_DB.sqls.length.should == 0
993
851
  end
994
852
 
995
853
  it "should respect the association's :graph_join_type option" do