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.
- data/CHANGELOG +35 -3
- data/Rakefile +2 -1
- data/doc/association_basics.rdoc +11 -0
- data/doc/opening_databases.rdoc +2 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/testing.rdoc +17 -3
- data/lib/sequel/adapters/amalgalite.rb +2 -2
- data/lib/sequel/adapters/do/mysql.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc.rb +126 -43
- data/lib/sequel/adapters/jdbc/as400.rb +11 -3
- data/lib/sequel/adapters/jdbc/db2.rb +2 -1
- data/lib/sequel/adapters/jdbc/derby.rb +44 -19
- data/lib/sequel/adapters/jdbc/h2.rb +32 -19
- data/lib/sequel/adapters/jdbc/hsqldb.rb +21 -17
- data/lib/sequel/adapters/jdbc/jtds.rb +9 -4
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +2 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +21 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -2
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +48 -18
- data/lib/sequel/adapters/mock.rb +2 -1
- data/lib/sequel/adapters/mysql.rb +4 -2
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/openbase.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +6 -6
- data/lib/sequel/adapters/postgres.rb +25 -12
- data/lib/sequel/adapters/shared/access.rb +14 -6
- data/lib/sequel/adapters/shared/db2.rb +36 -13
- data/lib/sequel/adapters/shared/firebird.rb +12 -5
- data/lib/sequel/adapters/shared/informix.rb +11 -3
- data/lib/sequel/adapters/shared/mssql.rb +94 -47
- data/lib/sequel/adapters/shared/mysql.rb +107 -49
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +2 -2
- data/lib/sequel/adapters/shared/oracle.rb +54 -27
- data/lib/sequel/adapters/shared/postgres.rb +65 -26
- data/lib/sequel/adapters/shared/progress.rb +4 -1
- data/lib/sequel/adapters/shared/sqlite.rb +36 -20
- data/lib/sequel/adapters/sqlite.rb +2 -3
- data/lib/sequel/adapters/swift/mysql.rb +3 -2
- data/lib/sequel/adapters/swift/sqlite.rb +2 -2
- data/lib/sequel/adapters/tinytds.rb +14 -8
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -4
- data/lib/sequel/database/misc.rb +6 -2
- data/lib/sequel/dataset/graph.rb +33 -7
- data/lib/sequel/dataset/prepared_statements.rb +19 -5
- data/lib/sequel/dataset/sql.rb +611 -201
- data/lib/sequel/model/associations.rb +12 -5
- data/lib/sequel/model/base.rb +20 -5
- data/lib/sequel/plugins/sharding.rb +9 -29
- data/lib/sequel/sql.rb +2 -1
- data/lib/sequel/timezones.rb +14 -4
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +10 -0
- data/spec/adapters/oracle_spec.rb +1 -1
- data/spec/core/core_sql_spec.rb +3 -1
- data/spec/core/database_spec.rb +42 -0
- data/spec/core/dataset_spec.rb +10 -3
- data/spec/core/mock_adapter_spec.rb +4 -0
- data/spec/core/object_graph_spec.rb +38 -0
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +35 -39
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +30 -82
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +33 -103
- data/spec/extensions/instance_filters_spec.rb +10 -21
- data/spec/extensions/instance_hooks_spec.rb +6 -24
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +135 -277
- data/spec/extensions/migration_spec.rb +18 -15
- data/spec/extensions/named_timezones_spec.rb +1 -1
- data/spec/extensions/nested_attributes_spec.rb +97 -92
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +22 -37
- data/spec/extensions/prepared_statements_safe_spec.rb +9 -27
- data/spec/extensions/prepared_statements_spec.rb +11 -30
- data/spec/extensions/prepared_statements_with_pk_spec.rb +6 -13
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +3 -6
- data/spec/extensions/serialization_spec.rb +20 -32
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +14 -36
- data/spec/extensions/spec_helper.rb +10 -64
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/integration/dataset_test.rb +16 -4
- data/spec/integration/prepared_statement_test.rb +4 -2
- data/spec/model/eager_loading_spec.rb +16 -0
- data/spec/model/model_spec.rb +15 -1
- data/spec/model/record_spec.rb +60 -0
- 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))
|
|
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
|
-
|
|
14
|
+
MODEL_DB.sqls.should == ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
|
|
26
15
|
@p.instance_filter(:name=>'Jim')
|
|
27
|
-
@
|
|
16
|
+
@p.this.numrows = 0
|
|
28
17
|
proc{@p.update(:name=>'Joe')}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
|
29
|
-
|
|
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
|
-
|
|
23
|
+
MODEL_DB.sqls.should == ["DELETE FROM people WHERE (id = 1)"]
|
|
35
24
|
@p.instance_filter(:name=>'Jim')
|
|
36
|
-
@
|
|
25
|
+
@p.this.numrows = 0
|
|
37
26
|
proc{@p.destroy}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40
|
+
MODEL_DB.sqls.should == ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Joe'))"]
|
|
52
41
|
@p.update(:name=>'Bob')
|
|
53
|
-
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
|
|
106
|
-
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
25
|
-
yield(:id=>2)
|
|
19
|
+
[{:id=>1}, {:id=>2}]
|
|
26
20
|
end
|
|
27
21
|
else
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
28
|
+
{:name=>x.to_s}
|
|
32
29
|
else
|
|
33
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
70
|
+
@c.dataset._fetch = {:id=>1, :position=>1}
|
|
93
71
|
@o.at_position(10).should == @c.load(:id=>1, :position=>1)
|
|
94
|
-
|
|
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
|
-
|
|
79
|
+
@c.dataset._fetch = {:max=>10}
|
|
102
80
|
@o.last_position.should == 10
|
|
103
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
29
|
-
class
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 ==
|
|
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 ==
|
|
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
|
-
|
|
309
|
+
self::Foo = h
|
|
345
310
|
def al(v)
|
|
346
|
-
v.each{|x|
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
434
|
-
|
|
435
|
-
[:
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
h =
|
|
470
|
-
|
|
471
|
-
|
|
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
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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 ==
|
|
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
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
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 ==
|
|
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
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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.
|
|
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 ==
|
|
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 ==
|
|
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.
|
|
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 ==
|
|
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 ==
|
|
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.
|
|
683
|
-
|
|
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 ==
|
|
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 ==
|
|
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.
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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.
|
|
757
|
-
|
|
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 ==
|
|
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.
|
|
777
|
-
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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
|
-
|
|
849
|
-
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 ==
|
|
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
|