sequel 3.29.0 → 3.30.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -6,11 +6,8 @@ describe "optimistic_locking plugin" do
|
|
6
6
|
end
|
7
7
|
h = {1=>{:id=>1, :name=>'John', :lock_version=>2}}
|
8
8
|
lv = @lv = "lock_version"
|
9
|
-
@c.dataset.
|
10
|
-
|
11
|
-
@c.dataset.meta_def(:lv){lv}
|
12
|
-
@c.dataset.meta_def(:update) do |opts|
|
13
|
-
case update_sql(opts)
|
9
|
+
@c.dataset.numrows = proc do |sql|
|
10
|
+
case sql
|
14
11
|
when /UPDATE people SET (name|#{lv}) = ('Jim'|'Bob'|\d+), (?:name|#{lv}) = ('Jim'|'Bob'|\d+) WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
|
15
12
|
name, nlv = $1 == 'name' ? [$2, $3] : [$3, $2]
|
16
13
|
m = h[$4.to_i]
|
@@ -28,20 +25,6 @@ describe "optimistic_locking plugin" do
|
|
28
25
|
else
|
29
26
|
0
|
30
27
|
end
|
31
|
-
else
|
32
|
-
puts update_sql(opts)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
@c.dataset.instance_eval do
|
36
|
-
def fetch_rows(sql)
|
37
|
-
m = h[1].dup
|
38
|
-
v = m.delete(:lock_version)
|
39
|
-
m[lv.to_sym] = v
|
40
|
-
yield(m)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
@c.dataset.meta_def(:delete) do
|
44
|
-
case delete_sql
|
45
28
|
when /DELETE FROM people WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
|
46
29
|
m = h[$1.to_i]
|
47
30
|
if m && m[lv.to_sym] == $2.to_i
|
@@ -51,9 +34,15 @@ describe "optimistic_locking plugin" do
|
|
51
34
|
0
|
52
35
|
end
|
53
36
|
else
|
54
|
-
puts
|
37
|
+
puts sql
|
55
38
|
end
|
56
39
|
end
|
40
|
+
@c.dataset._fetch = proc do |sql|
|
41
|
+
m = h[1].dup
|
42
|
+
v = m.delete(:lock_version)
|
43
|
+
m[lv.to_sym] = v
|
44
|
+
m
|
45
|
+
end
|
57
46
|
@c.columns :id, :name, :lock_version
|
58
47
|
@c.plugin :optimistic_locking
|
59
48
|
end
|
@@ -2,23 +2,14 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "Sequel::Plugins::AssociationPks" do
|
4
4
|
before do
|
5
|
-
@db =
|
6
|
-
|
7
|
-
def
|
8
|
-
|
9
|
-
|
5
|
+
@db = Sequel.mock
|
6
|
+
@db.extend_datasets do
|
7
|
+
def select_sql
|
8
|
+
sql = super
|
9
|
+
sql << ' -- prepared' if is_a?(Sequel::Dataset::PreparedStatementMethods)
|
10
|
+
sql
|
10
11
|
end
|
11
12
|
end
|
12
|
-
@db.meta_def(:dataset) do |*opts|
|
13
|
-
ds = super(*opts)
|
14
|
-
ds.extend mod
|
15
|
-
ds
|
16
|
-
end
|
17
|
-
def @db.transaction(opts)
|
18
|
-
execute('BEGIN')
|
19
|
-
yield
|
20
|
-
execute('COMMIT')
|
21
|
-
end
|
22
13
|
@Artist = Class.new(Sequel::Model(@db[:artists]))
|
23
14
|
@Artist.columns :id, :id2
|
24
15
|
@Album= Class.new(Sequel::Model(@db[:albums]))
|
@@ -32,24 +23,21 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
32
23
|
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
|
33
24
|
@Artist.plugin :many_through_many
|
34
25
|
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
35
|
-
@db.
|
26
|
+
@db.sqls
|
36
27
|
end
|
37
28
|
|
38
29
|
specify "should run correct SQL for associations" do
|
39
30
|
@Artist.load(:id=>1).albums
|
40
|
-
@db.sqls.should == [
|
41
|
-
@db.reset
|
31
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1) -- prepared"]
|
42
32
|
|
43
33
|
@Album.load(:id=>1, :artist_id=>2).artist
|
44
|
-
@db.sqls.should == [
|
45
|
-
@db.reset
|
34
|
+
@db.sqls.should == ["SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1 -- prepared"]
|
46
35
|
|
47
36
|
@Album.load(:id=>1, :artist_id=>2).tags
|
48
|
-
@db.sqls.should == [
|
49
|
-
@db.reset
|
37
|
+
@db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id = tags.id) AND (albums_tags.album_id = 1)) -- prepared"]
|
50
38
|
|
51
39
|
@Artist.load(:id=>1).tags
|
52
|
-
@db.sqls.should == [
|
40
|
+
@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) AND (albums.artist_id = 1)) -- prepared"]
|
53
41
|
end
|
54
42
|
|
55
43
|
specify "should run correct SQL for composite key associations" do
|
@@ -59,19 +47,16 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
59
47
|
@Artist.many_through_many :tags, [[:albums, [:artist_id, :artist_id2], [:id, :id2]], [:albums_tags, [:album_id, :album_id2], [:tag_id, :tag_id2]]], :class=>@Tag, :right_primary_key=>[:id, :id2], :left_primary_key=>[:id, :id2]
|
60
48
|
|
61
49
|
@Artist.load(:id=>1, :id2=>2).albums
|
62
|
-
@db.sqls.should == [
|
63
|
-
@db.reset
|
50
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE ((albums.artist_id = 1) AND (albums.artist_id2 = 2)) -- prepared"]
|
64
51
|
|
65
52
|
@Album.load(:id=>1, :artist_id=>2, :artist_id2=>3).artist
|
66
|
-
@db.sqls.should == [
|
67
|
-
@db.reset
|
53
|
+
@db.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 2) AND (artists.id2 = 3)) LIMIT 1 -- prepared"]
|
68
54
|
|
69
55
|
@Album.load(:id=>1, :artist_id=>2, :id2=>3).tags
|
70
|
-
@db.sqls.should == [
|
71
|
-
@db.reset
|
56
|
+
@db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id = tags.id) AND (albums_tags.tag_id2 = tags.id2) AND (albums_tags.album_id = 1) AND (albums_tags.album_id2 = 3)) -- prepared"]
|
72
57
|
|
73
58
|
@Artist.load(:id=>1, :id2=>2).tags
|
74
|
-
@db.sqls.should == [
|
59
|
+
@db.sqls.should == ["SELECT tags.* FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id = tags.id) AND (albums_tags.tag_id2 = tags.id2)) INNER JOIN albums ON ((albums.id = albums_tags.album_id) AND (albums.id2 = albums_tags.album_id2) AND (albums.artist_id = 1) AND (albums.artist_id2 = 2)) -- prepared"]
|
75
60
|
end
|
76
61
|
|
77
62
|
specify "should not run query if no objects can be associated" do
|
@@ -82,45 +67,45 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
82
67
|
|
83
68
|
specify "should run a regular query if there is a callback" do
|
84
69
|
@Artist.load(:id=>1).albums(proc{|ds| ds})
|
85
|
-
@db.sqls.should == [
|
70
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
86
71
|
end
|
87
72
|
|
88
73
|
specify "should run a regular query if :prepared_statement=>false option is used for the association" do
|
89
74
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :prepared_statement=>false
|
90
75
|
@Artist.load(:id=>1).albums
|
91
|
-
@db.sqls.should == [
|
76
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
92
77
|
end
|
93
78
|
|
94
79
|
specify "should run a regular query if unrecognized association is used" do
|
95
80
|
a = @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
96
81
|
a[:type] = :foo
|
97
82
|
@Artist.load(:id=>1).albums
|
98
|
-
@db.sqls.should == [
|
83
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
99
84
|
end
|
100
85
|
|
101
86
|
specify "should run a regular query if a block is used when defining the association" do
|
102
87
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id do |ds| ds end
|
103
88
|
@Artist.load(:id=>1).albums
|
104
|
-
@db.sqls.should == [
|
89
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
105
90
|
end
|
106
91
|
|
107
92
|
specify "should run a regular query if :conditions option is used when defining the association" do
|
108
93
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>1}
|
109
94
|
@Artist.load(:id=>1).albums
|
110
|
-
@db.sqls.should == [
|
95
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE ((albums.artist_id = 1) AND (a = 1))"]
|
111
96
|
end
|
112
97
|
|
113
98
|
specify "should run a regular query if :dataset option is used when defining the association" do
|
114
99
|
album = @Album
|
115
100
|
@Artist.one_to_many :albums, :class=>@Album, :dataset=>proc{album.filter(:artist_id=>id)}
|
116
101
|
@Artist.load(:id=>1).albums
|
117
|
-
@db.sqls.should == [
|
102
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE (artist_id = 1)"]
|
118
103
|
end
|
119
104
|
|
120
105
|
specify "should run a regular query if :cloning an association that doesn't used prepared statements" do
|
121
106
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>1}
|
122
107
|
@Artist.one_to_many :oalbums, :clone=>:albums
|
123
108
|
@Artist.load(:id=>1).oalbums
|
124
|
-
@db.sqls.should == [
|
109
|
+
@db.sqls.should == ["SELECT * FROM albums WHERE ((albums.artist_id = 1) AND (a = 1))"]
|
125
110
|
end
|
126
111
|
end
|
@@ -2,29 +2,13 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "prepared_statements_safe plugin" do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :name=>'foo', :i=>2}, :autoid=>proc{|sql| 1}, :numrows=>1, :servers=>{:read_only=>{}})
|
6
|
+
@c = Class.new(Sequel::Model(@db[:people]))
|
6
7
|
@c.columns :id, :name, :i
|
7
|
-
@ds = ds = @c.dataset
|
8
8
|
@c.instance_variable_set(:@db_schema, {:i=>{}, :name=>{}, :id=>{:primary_key=>true}})
|
9
|
-
def ds.fetch_rows(sql)
|
10
|
-
db << {:server=>@opts[:server] || :read_only}.merge(opts)[:server]
|
11
|
-
super{|h|}
|
12
|
-
yield(:id=>1, :name=>'foo', :i=>2)
|
13
|
-
end
|
14
|
-
def ds.update(*)
|
15
|
-
db << default_server_opts(opts)[:server]
|
16
|
-
super
|
17
|
-
end
|
18
|
-
def ds.insert(*)
|
19
|
-
db << default_server_opts(opts)[:server]
|
20
|
-
super
|
21
|
-
1
|
22
|
-
end
|
23
9
|
@c.plugin :prepared_statements_safe
|
24
10
|
@p = @c.load(:id=>1, :name=>'foo', :i=>2)
|
25
|
-
@
|
26
|
-
@sqls = @c.db.sqls
|
27
|
-
@sqls.clear
|
11
|
+
@db.sqls
|
28
12
|
end
|
29
13
|
|
30
14
|
specify "should load the prepared_statements plugin" do
|
@@ -39,32 +23,30 @@ describe "prepared_statements_safe plugin" do
|
|
39
23
|
|
40
24
|
specify "should set default values when creating" do
|
41
25
|
@c.create
|
42
|
-
@sqls
|
43
|
-
@sqls.clear
|
26
|
+
@db.sqls.first.should =~ /INSERT INTO people \((i|name), (i|name)\) VALUES \(NULL, NULL\)/
|
44
27
|
@c.create(:name=>'foo')
|
45
|
-
@sqls
|
46
|
-
@sqls.clear
|
28
|
+
@db.sqls.first.should =~ /INSERT INTO people \((i|name), (i|name)\) VALUES \((NULL|'foo'), (NULL|'foo')\)/
|
47
29
|
@c.create(:name=>'foo', :i=>2)
|
48
|
-
@sqls
|
30
|
+
@db.sqls.first.should =~ /INSERT INTO people \((i|name), (i|name)\) VALUES \((2|'foo'), (2|'foo')\)/
|
49
31
|
end
|
50
32
|
|
51
33
|
specify "should use database default values" do
|
52
34
|
@c.instance_variable_set(:@db_schema, {:i=>{:ruby_default=>2}, :name=>{:ruby_default=>'foo'}, :id=>{:primary_key=>true}})
|
53
35
|
c = Class.new(@c)
|
54
36
|
c.create
|
55
|
-
@sqls
|
37
|
+
@db.sqls.first.should =~ /INSERT INTO people \((i|name), (i|name)\) VALUES \((2|'foo'), (2|'foo')\)/
|
56
38
|
end
|
57
39
|
|
58
40
|
specify "should not set defaults for unparseable dataset default values" do
|
59
41
|
@c.instance_variable_set(:@db_schema, {:i=>{:default=>'f(x)'}, :name=>{:ruby_default=>'foo'}, :id=>{:primary_key=>true}})
|
60
42
|
c = Class.new(@c)
|
61
43
|
c.create
|
62
|
-
@sqls
|
44
|
+
@db.sqls.first.should == "INSERT INTO people (name) VALUES ('foo')"
|
63
45
|
end
|
64
46
|
|
65
47
|
specify "should save all fields when updating" do
|
66
48
|
@p.update(:i=>3)
|
67
|
-
@sqls
|
49
|
+
@db.sqls.first.should =~ /UPDATE people SET (name = 'foo'|i = 3), (name = 'foo'|i = 3) WHERE \(id = 1\)/
|
68
50
|
end
|
69
51
|
|
70
52
|
specify "should work with abstract classes" do
|
@@ -2,52 +2,33 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "prepared_statements plugin" do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :name=>'foo', :i=>2}, :autoid=>proc{|sql| 1}, :numrows=>1, :servers=>{:read_only=>{}})
|
6
|
+
@c = Class.new(Sequel::Model(@db[:people]))
|
6
7
|
@c.columns :id, :name, :i
|
7
|
-
@ds = ds = @c.dataset
|
8
|
-
def ds.fetch_rows(sql)
|
9
|
-
db << {:server=>@opts[:server] || :read_only}.merge(opts)[:server]
|
10
|
-
super{|h|}
|
11
|
-
yield(:id=>1, :name=>'foo', :i=>2)
|
12
|
-
end
|
13
|
-
def ds.update(*)
|
14
|
-
db << default_server_opts(opts)[:server]
|
15
|
-
super
|
16
|
-
end
|
17
|
-
def ds.insert(*)
|
18
|
-
db << default_server_opts(opts)[:server]
|
19
|
-
super
|
20
|
-
1
|
21
|
-
end
|
22
|
-
def ds.delete(*)
|
23
|
-
db << default_server_opts(opts)[:server]
|
24
|
-
super
|
25
|
-
end
|
26
8
|
@c.plugin :prepared_statements
|
27
9
|
@p = @c.load(:id=>1, :name=>'foo', :i=>2)
|
28
|
-
@c.
|
29
|
-
@
|
30
|
-
@sqls.clear
|
10
|
+
@ds = @c.dataset
|
11
|
+
@db.sqls
|
31
12
|
end
|
32
13
|
|
33
14
|
specify "should correctly lookup by primary key" do
|
34
15
|
@c[1].should == @p
|
35
|
-
@sqls.should == [
|
16
|
+
@db.sqls.should == ["SELECT * FROM people WHERE (id = 1) LIMIT 1 -- read_only"]
|
36
17
|
end
|
37
18
|
|
38
19
|
specify "should correctly delete instance" do
|
39
20
|
@p.destroy.should == @p
|
40
|
-
@sqls.should == [
|
21
|
+
@db.sqls.should == ["DELETE FROM people WHERE (id = 1)"]
|
41
22
|
end
|
42
23
|
|
43
24
|
specify "should correctly update instance" do
|
44
25
|
@p.update(:name=>'bar').should == @c.load(:id=>1, :name=>'bar', :i => 2)
|
45
|
-
@sqls.should == [
|
26
|
+
@db.sqls.should == ["UPDATE people SET name = 'bar' WHERE (id = 1)"]
|
46
27
|
end
|
47
28
|
|
48
29
|
specify "should correctly create instance" do
|
49
30
|
@c.create(:name=>'foo').should == @c.load(:id=>1, :name=>'foo', :i => 2)
|
50
|
-
@sqls.should == [
|
31
|
+
@db.sqls.should == ["INSERT INTO people (name) VALUES ('foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
|
51
32
|
end
|
52
33
|
|
53
34
|
specify "should correctly create instance if dataset supports insert_select" do
|
@@ -55,18 +36,18 @@ describe "prepared_statements plugin" do
|
|
55
36
|
true
|
56
37
|
end
|
57
38
|
def @ds.insert_select(h)
|
58
|
-
|
39
|
+
{:id=>1, :name=>'foo', :i => 2}
|
59
40
|
end
|
60
41
|
def @ds.insert_sql(*)
|
61
42
|
"#{super}#{' RETURNING *' if opts.has_key?(:returning)}"
|
62
43
|
end
|
63
44
|
@c.create(:name=>'foo').should == @c.load(:id=>1, :name=>'foo', :i => 2)
|
64
|
-
@sqls.should == [
|
45
|
+
@db.sqls.should == ["INSERT INTO people (name) VALUES ('foo') RETURNING *"]
|
65
46
|
end
|
66
47
|
|
67
48
|
specify "should work correctly when subclassing" do
|
68
49
|
c = Class.new(@c)
|
69
50
|
c[1].should == c.load(:id=>1, :name=>'foo', :i=>2)
|
70
|
-
@sqls.should == [
|
51
|
+
@db.sqls.should == ["SELECT * FROM people WHERE (id = 1) LIMIT 1 -- read_only"]
|
71
52
|
end
|
72
53
|
end
|
@@ -2,19 +2,12 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "prepared_statements_with_pk plugin" do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :name=>'foo', :i=>2}, :autoid=>proc{|sql| 1}, :numrows=>1, :servers=>{:read_only=>{}})
|
6
|
+
@c = Class.new(Sequel::Model(@db[:people]))
|
6
7
|
@c.columns :id, :name, :i
|
7
|
-
@ds = ds = @c.dataset
|
8
|
-
def ds.fetch_rows(sql)
|
9
|
-
db << {:server=>@opts[:server] || :read_only}.merge(opts)[:server]
|
10
|
-
super{|h|}
|
11
|
-
yield(:id=>1, :name=>'foo', :i=>2)
|
12
|
-
end
|
13
8
|
@c.plugin :prepared_statements_with_pk
|
14
9
|
@p = @c.load(:id=>1, :name=>'foo', :i=>2)
|
15
|
-
@
|
16
|
-
@sqls = @c.db.sqls
|
17
|
-
@sqls.clear
|
10
|
+
@db.sqls
|
18
11
|
end
|
19
12
|
|
20
13
|
specify "should load the prepared_statements plugin" do
|
@@ -23,16 +16,16 @@ describe "prepared_statements_with_pk plugin" do
|
|
23
16
|
|
24
17
|
specify "should correctly lookup by primary key from dataset" do
|
25
18
|
@c.dataset.filter(:name=>'foo')[1].should == @p
|
26
|
-
@sqls.should == [
|
19
|
+
@c.db.sqls.should == ["SELECT * FROM people WHERE ((name = 'foo') AND (people.id = 1)) LIMIT 1 -- read_only"]
|
27
20
|
end
|
28
21
|
|
29
22
|
specify "should still work correctly if there are multiple conflicting variables" do
|
30
23
|
@c.dataset.filter(:name=>'foo').or(:name=>'bar')[1].should == @p
|
31
|
-
@sqls.should == [
|
24
|
+
@c.db.sqls.should == ["SELECT * FROM people WHERE (((name = 'foo') OR (name = 'bar')) AND (people.id = 1)) LIMIT 1 -- read_only"]
|
32
25
|
end
|
33
26
|
|
34
27
|
specify "should still work correctly if the primary key is used elsewhere in the query" do
|
35
28
|
@c.dataset.filter{id > 2}[1].should == @p
|
36
|
-
@sqls.should == [
|
29
|
+
@c.db.sqls.should == ["SELECT * FROM people WHERE ((id > 2) AND (people.id = 1)) LIMIT 1 -- read_only"]
|
37
30
|
end
|
38
31
|
end
|
@@ -7,12 +7,7 @@ describe "Dataset#print" do
|
|
7
7
|
@output = StringIO.new
|
8
8
|
@orig_stdout = $stdout
|
9
9
|
$stdout = @output
|
10
|
-
@dataset = Sequel
|
11
|
-
def @dataset.fetch_rows(sql)
|
12
|
-
yield({:a=>1, :b=>2})
|
13
|
-
yield({:a=>3, :b=>4})
|
14
|
-
yield({:a=>5, :b=>6})
|
15
|
-
end
|
10
|
+
@dataset = Sequel.mock(:fetch=>[{:a=>1, :b=>2}, {:a=>3, :b=>4}, {:a=>5, :b=>6}])[:items]
|
16
11
|
end
|
17
12
|
|
18
13
|
after do
|
@@ -8,13 +8,6 @@ describe Sequel::Model, "rcte_tree" do
|
|
8
8
|
columns :id, :name, :parent_id, :i, :pi
|
9
9
|
end
|
10
10
|
@ds = @c.dataset
|
11
|
-
class << @ds
|
12
|
-
attr_accessor :row_sets
|
13
|
-
def fetch_rows(sql)
|
14
|
-
@db << sql
|
15
|
-
row_sets.shift.each{|row| yield row}
|
16
|
-
end
|
17
|
-
end
|
18
11
|
@o = @c.load(:id=>2, :parent_id=>1, :name=>'AA', :i=>3, :pi=>4)
|
19
12
|
MODEL_DB.reset
|
20
13
|
end
|
@@ -55,7 +48,7 @@ describe Sequel::Model, "rcte_tree" do
|
|
55
48
|
|
56
49
|
it "should add all parent associations when lazily loading ancestors" do
|
57
50
|
@c.plugin :rcte_tree
|
58
|
-
@ds.
|
51
|
+
@ds._fetch = [[{:id=>1, :name=>'A', :parent_id=>3}, {:id=>4, :name=>'B', :parent_id=>nil}, {:id=>3, :name=>'?', :parent_id=>4}]]
|
59
52
|
@o.ancestors.should == [@c.load(:id=>1, :name=>'A', :parent_id=>3), @c.load(:id=>4, :name=>'B', :parent_id=>nil), @c.load(:id=>3, :name=>'?', :parent_id=>4)]
|
60
53
|
@o.associations[:parent].should == @c.load(:id=>1, :name=>'A', :parent_id=>3)
|
61
54
|
@o.associations[:parent].associations[:parent].should == @c.load(:id=>3, :name=>'?', :parent_id=>4)
|
@@ -65,7 +58,7 @@ describe Sequel::Model, "rcte_tree" do
|
|
65
58
|
|
66
59
|
it "should add all parent associations when lazily loading ancestors and giving options" do
|
67
60
|
@c.plugin :rcte_tree, :primary_key=>:i, :key=>:pi, :ancestors=>{:name=>:as}, :parent=>{:name=>:p}
|
68
|
-
@ds.
|
61
|
+
@ds._fetch = [[{:i=>4, :name=>'A', :pi=>5}, {:i=>6, :name=>'B', :pi=>nil}, {:i=>5, :name=>'?', :pi=>6}]]
|
69
62
|
@o.as.should == [@c.load(:i=>4, :name=>'A', :pi=>5), @c.load(:i=>6, :name=>'B', :pi=>nil), @c.load(:i=>5, :name=>'?', :pi=>6)]
|
70
63
|
@o.associations[:p].should == @c.load(:i=>4, :name=>'A', :pi=>5)
|
71
64
|
@o.associations[:p].associations[:p].should == @c.load(:i=>5, :name=>'?', :pi=>6)
|
@@ -75,7 +68,7 @@ describe Sequel::Model, "rcte_tree" do
|
|
75
68
|
|
76
69
|
it "should add all children associations when lazily loading descendants" do
|
77
70
|
@c.plugin :rcte_tree
|
78
|
-
@ds.
|
71
|
+
@ds._fetch = [[{:id=>3, :name=>'??', :parent_id=>1}, {:id=>1, :name=>'A', :parent_id=>2}, {:id=>4, :name=>'B', :parent_id=>2}, {:id=>5, :name=>'?', :parent_id=>3}]]
|
79
72
|
@o.descendants.should == [@c.load(:id=>3, :name=>'??', :parent_id=>1), @c.load(:id=>1, :name=>'A', :parent_id=>2), @c.load(:id=>4, :name=>'B', :parent_id=>2), @c.load(:id=>5, :name=>'?', :parent_id=>3)]
|
80
73
|
@o.associations[:children].should == [@c.load(:id=>1, :name=>'A', :parent_id=>2), @c.load(:id=>4, :name=>'B', :parent_id=>2)]
|
81
74
|
@o.associations[:children].map{|c1| c1.associations[:children]}.should == [[@c.load(:id=>3, :name=>'??', :parent_id=>1)], []]
|
@@ -85,7 +78,7 @@ describe Sequel::Model, "rcte_tree" do
|
|
85
78
|
|
86
79
|
it "should add all children associations when lazily loading descendants and giving options" do
|
87
80
|
@c.plugin :rcte_tree, :primary_key=>:i, :key=>:pi, :children=>{:name=>:cs}, :descendants=>{:name=>:ds}
|
88
|
-
@ds.
|
81
|
+
@ds._fetch = [[{:i=>7, :name=>'??', :pi=>5}, {:i=>5, :name=>'A', :pi=>3}, {:i=>6, :name=>'B', :pi=>3}, {:i=>8, :name=>'?', :pi=>7}]]
|
89
82
|
@o.ds.should == [@c.load(:i=>7, :name=>'??', :pi=>5), @c.load(:i=>5, :name=>'A', :pi=>3), @c.load(:i=>6, :name=>'B', :pi=>3), @c.load(:i=>8, :name=>'?', :pi=>7)]
|
90
83
|
@o.associations[:cs].should == [@c.load(:i=>5, :name=>'A', :pi=>3), @c.load(:i=>6, :name=>'B', :pi=>3)]
|
91
84
|
@o.associations[:cs].map{|c1| c1.associations[:cs]}.should == [[@c.load(:i=>7, :name=>'??', :pi=>5)], []]
|
@@ -95,13 +88,14 @@ describe Sequel::Model, "rcte_tree" do
|
|
95
88
|
|
96
89
|
it "should eagerly load ancestors" do
|
97
90
|
@c.plugin :rcte_tree
|
98
|
-
@ds.
|
91
|
+
@ds._fetch = [[{:id=>2, :parent_id=>1, :name=>'AA'}, {:id=>6, :parent_id=>2, :name=>'C'}, {:id=>7, :parent_id=>1, :name=>'D'}, {:id=>9, :parent_id=>nil, :name=>'E'}],
|
99
92
|
[{:id=>2, :name=>'AA', :parent_id=>1, :x_root_x=>2},
|
100
93
|
{:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
|
101
94
|
{:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]]
|
102
95
|
os = @ds.eager(:ancestors).all
|
103
|
-
MODEL_DB.sqls
|
104
|
-
|
96
|
+
sqls = MODEL_DB.sqls
|
97
|
+
sqls.first.should == "SELECT * FROM nodes"
|
98
|
+
sqls.last.should =~ /WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(id IN \([12], [12]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\)\) SELECT \* FROM t AS nodes/
|
105
99
|
os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D'), @c.load(:id=>9, :parent_id=>nil, :name=>'E')]
|
106
100
|
os.map{|o| o.ancestors}.should == [[@c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil)],
|
107
101
|
[@c.load(:id=>2, :name=>'AA', :parent_id=>1), @c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil)],
|
@@ -111,18 +105,19 @@ describe Sequel::Model, "rcte_tree" do
|
|
111
105
|
os.map{|o| o.parent.parent if o.parent}.should == [@c.load(:id=>8, :name=>'?', :parent_id=>nil), @c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil), nil]
|
112
106
|
os.map{|o| o.parent.parent.parent if o.parent and o.parent.parent}.should == [nil, @c.load(:id=>8, :name=>'?', :parent_id=>nil), nil, nil]
|
113
107
|
os.map{|o| o.parent.parent.parent.parent if o.parent and o.parent.parent and o.parent.parent.parent}.should == [nil, nil, nil, nil]
|
114
|
-
MODEL_DB.
|
108
|
+
MODEL_DB.sqls.should == []
|
115
109
|
end
|
116
110
|
|
117
111
|
it "should eagerly load ancestors when giving options" do
|
118
112
|
@c.plugin :rcte_tree, :primary_key=>:i, :key=>:pi, :key_alias=>:kal, :cte_name=>:cte, :ancestors=>{:name=>:as}, :parent=>{:name=>:p}
|
119
|
-
@ds.
|
113
|
+
@ds._fetch = [[{:i=>2, :pi=>1, :name=>'AA'}, {:i=>6, :pi=>2, :name=>'C'}, {:i=>7, :pi=>1, :name=>'D'}, {:i=>9, :pi=>nil, :name=>'E'}],
|
120
114
|
[{:i=>2, :name=>'AA', :pi=>1, :kal=>2},
|
121
115
|
{:i=>1, :name=>'00', :pi=>8, :kal=>1}, {:i=>1, :name=>'00', :pi=>8, :kal=>2},
|
122
116
|
{:i=>8, :name=>'?', :pi=>nil, :kal=>2}, {:i=>8, :name=>'?', :pi=>nil, :kal=>1}]]
|
123
117
|
os = @ds.eager(:as).all
|
124
|
-
MODEL_DB.sqls
|
125
|
-
|
118
|
+
sqls = MODEL_DB.sqls
|
119
|
+
sqls.first.should == "SELECT * FROM nodes"
|
120
|
+
sqls.last.should =~ /WITH cte AS \(SELECT i AS kal, nodes\.\* FROM nodes WHERE \(i IN \([12], [12]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.pi = nodes\.i\)\) SELECT \* FROM cte/
|
126
121
|
os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D'), @c.load(:i=>9, :pi=>nil, :name=>'E')]
|
127
122
|
os.map{|o| o.as}.should == [[@c.load(:i=>1, :name=>'00', :pi=>8), @c.load(:i=>8, :name=>'?', :pi=>nil)],
|
128
123
|
[@c.load(:i=>2, :name=>'AA', :pi=>1), @c.load(:i=>1, :name=>'00', :pi=>8), @c.load(:i=>8, :name=>'?', :pi=>nil)],
|
@@ -132,30 +127,30 @@ describe Sequel::Model, "rcte_tree" do
|
|
132
127
|
os.map{|o| o.p.p if o.p}.should == [@c.load(:i=>8, :name=>'?', :pi=>nil), @c.load(:i=>1, :name=>'00', :pi=>8), @c.load(:i=>8, :name=>'?', :pi=>nil), nil]
|
133
128
|
os.map{|o| o.p.p.p if o.p and o.p.p}.should == [nil, @c.load(:i=>8, :name=>'?', :pi=>nil), nil, nil]
|
134
129
|
os.map{|o| o.p.p.p.p if o.p and o.p.p and o.p.p.p}.should == [nil, nil, nil, nil]
|
135
|
-
MODEL_DB.new_sqls.should == []
|
136
130
|
end
|
137
131
|
|
138
132
|
it "should eagerly load ancestors respecting association option :conditions" do
|
139
133
|
@c.plugin :rcte_tree, :conditions => {:i => 1}
|
140
|
-
@ds.
|
134
|
+
@ds._fetch = [[{:id=>2, :parent_id=>1, :name=>'AA'}, {:id=>6, :parent_id=>2, :name=>'C'}, {:id=>7, :parent_id=>1, :name=>'D'}, {:id=>9, :parent_id=>nil, :name=>'E'}],
|
141
135
|
[{:id=>2, :name=>'AA', :parent_id=>1, :x_root_x=>2},
|
142
136
|
{:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
|
143
137
|
{:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]]
|
144
138
|
os = @ds.eager(:ancestors).all
|
145
|
-
MODEL_DB.sqls
|
146
|
-
|
147
|
-
|
139
|
+
sqls = MODEL_DB.sqls
|
140
|
+
sqls.first.should == "SELECT * FROM nodes"
|
141
|
+
sqls.last.should =~ /WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(id IN \([12], [12]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/
|
148
142
|
end
|
149
143
|
|
150
144
|
it "should eagerly load descendants" do
|
151
145
|
@c.plugin :rcte_tree
|
152
|
-
@ds.
|
146
|
+
@ds._fetch = [[{:id=>2, :parent_id=>1, :name=>'AA'}, {:id=>6, :parent_id=>2, :name=>'C'}, {:id=>7, :parent_id=>1, :name=>'D'}],
|
153
147
|
[{:id=>6, :parent_id=>2, :name=>'C', :x_root_x=>2}, {:id=>9, :parent_id=>2, :name=>'E', :x_root_x=>2},
|
154
148
|
{:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
|
155
149
|
{:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]]
|
156
150
|
os = @ds.eager(:descendants).all
|
157
|
-
MODEL_DB.sqls
|
158
|
-
|
151
|
+
sqls = MODEL_DB.sqls
|
152
|
+
sqls.first.should == "SELECT * FROM nodes"
|
153
|
+
sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\)\) SELECT \* FROM t AS nodes/
|
159
154
|
os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
|
160
155
|
os.map{|o| o.descendants}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E'), @c.load(:id=>3, :name=>'00', :parent_id=>6)],
|
161
156
|
[@c.load(:id=>3, :name=>'00', :parent_id=>6)],
|
@@ -163,18 +158,19 @@ describe Sequel::Model, "rcte_tree" do
|
|
163
158
|
os.map{|o| o.children}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E')], [@c.load(:id=>3, :name=>'00', :parent_id=>6)], [@c.load(:id=>4, :name=>'?', :parent_id=>7)]]
|
164
159
|
os.map{|o1| o1.children.map{|o2| o2.children}}.should == [[[@c.load(:id=>3, :name=>'00', :parent_id=>6)], []], [[]], [[@c.load(:id=>5, :name=>'?', :parent_id=>4)]]]
|
165
160
|
os.map{|o1| o1.children.map{|o2| o2.children.map{|o3| o3.children}}}.should == [[[[]], []], [[]], [[[]]]]
|
166
|
-
MODEL_DB.
|
161
|
+
MODEL_DB.sqls.should == []
|
167
162
|
end
|
168
163
|
|
169
164
|
it "should eagerly load descendants when giving options" do
|
170
165
|
@c.plugin :rcte_tree, :primary_key=>:i, :key=>:pi, :key_alias=>:kal, :cte_name=>:cte, :children=>{:name=>:cs}, :descendants=>{:name=>:ds}
|
171
|
-
@ds.
|
166
|
+
@ds._fetch = [[{:i=>2, :pi=>1, :name=>'AA'}, {:i=>6, :pi=>2, :name=>'C'}, {:i=>7, :pi=>1, :name=>'D'}],
|
172
167
|
[{:i=>6, :pi=>2, :name=>'C', :kal=>2}, {:i=>9, :pi=>2, :name=>'E', :kal=>2},
|
173
168
|
{:i=>3, :name=>'00', :pi=>6, :kal=>6}, {:i=>3, :name=>'00', :pi=>6, :kal=>2},
|
174
169
|
{:i=>4, :name=>'?', :pi=>7, :kal=>7}, {:i=>5, :name=>'?', :pi=>4, :kal=>7}]]
|
175
170
|
os = @ds.eager(:ds).all
|
176
|
-
MODEL_DB.sqls
|
177
|
-
|
171
|
+
sqls = MODEL_DB.sqls
|
172
|
+
sqls.first.should == "SELECT * FROM nodes"
|
173
|
+
sqls.last.should =~ /WITH cte AS \(SELECT pi AS kal, nodes\.\* FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\)\) SELECT \* FROM cte/
|
178
174
|
os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
|
179
175
|
os.map{|o| o.ds}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E'), @c.load(:i=>3, :name=>'00', :pi=>6)],
|
180
176
|
[@c.load(:i=>3, :name=>'00', :pi=>6)],
|
@@ -182,18 +178,19 @@ describe Sequel::Model, "rcte_tree" do
|
|
182
178
|
os.map{|o| o.cs}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E')], [@c.load(:i=>3, :name=>'00', :pi=>6)], [@c.load(:i=>4, :name=>'?', :pi=>7)]]
|
183
179
|
os.map{|o1| o1.cs.map{|o2| o2.cs}}.should == [[[@c.load(:i=>3, :name=>'00', :pi=>6)], []], [[]], [[@c.load(:i=>5, :name=>'?', :pi=>4)]]]
|
184
180
|
os.map{|o1| o1.cs.map{|o2| o2.cs.map{|o3| o3.cs}}}.should == [[[[]], []], [[]], [[[]]]]
|
185
|
-
MODEL_DB.
|
181
|
+
MODEL_DB.sqls.should == []
|
186
182
|
end
|
187
183
|
|
188
184
|
it "should eagerly load descendants to a given level" do
|
189
185
|
@c.plugin :rcte_tree
|
190
|
-
@ds.
|
186
|
+
@ds._fetch = [[{:id=>2, :parent_id=>1, :name=>'AA'}, {:id=>6, :parent_id=>2, :name=>'C'}, {:id=>7, :parent_id=>1, :name=>'D'}],
|
191
187
|
[{:id=>6, :parent_id=>2, :name=>'C', :x_root_x=>2, :x_level_x=>0}, {:id=>9, :parent_id=>2, :name=>'E', :x_root_x=>2, :x_level_x=>0},
|
192
188
|
{:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6, :x_level_x=>0}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2, :x_level_x=>1},
|
193
189
|
{:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7, :x_level_x=>0}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7, :x_level_x=>1}]]
|
194
190
|
os = @ds.eager(:descendants=>2).all
|
195
|
-
MODEL_DB.sqls
|
196
|
-
|
191
|
+
sqls = MODEL_DB.sqls
|
192
|
+
sqls.first.should == "SELECT * FROM nodes"
|
193
|
+
sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\*, 0 AS x_level_x FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\*, \(t\.x_level_x \+ 1\) AS x_level_x FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(t\.x_level_x < 1\)\) SELECT \* FROM t AS nodes/
|
197
194
|
os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
|
198
195
|
os.map{|o| o.descendants}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E'), @c.load(:id=>3, :name=>'00', :parent_id=>6)],
|
199
196
|
[@c.load(:id=>3, :name=>'00', :parent_id=>6)],
|
@@ -201,18 +198,19 @@ describe Sequel::Model, "rcte_tree" do
|
|
201
198
|
os.map{|o| o.associations[:children]}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E')], [@c.load(:id=>3, :name=>'00', :parent_id=>6)], [@c.load(:id=>4, :name=>'?', :parent_id=>7)]]
|
202
199
|
os.map{|o1| o1.associations[:children].map{|o2| o2.associations[:children]}}.should == [[[@c.load(:id=>3, :name=>'00', :parent_id=>6)], []], [[]], [[@c.load(:id=>5, :name=>'?', :parent_id=>4)]]]
|
203
200
|
os.map{|o1| o1.associations[:children].map{|o2| o2.associations[:children].map{|o3| o3.associations[:children]}}}.should == [[[[]], []], [[]], [[nil]]]
|
204
|
-
MODEL_DB.
|
201
|
+
MODEL_DB.sqls.should == []
|
205
202
|
end
|
206
203
|
|
207
204
|
it "should eagerly load descendants to a given level when giving options" do
|
208
205
|
@c.plugin :rcte_tree, :primary_key=>:i, :key=>:pi, :key_alias=>:kal, :level_alias=>:lal, :cte_name=>:cte, :children=>{:name=>:cs}, :descendants=>{:name=>:ds}
|
209
|
-
@ds.
|
206
|
+
@ds._fetch = [[{:i=>2, :pi=>1, :name=>'AA'}, {:i=>6, :pi=>2, :name=>'C'}, {:i=>7, :pi=>1, :name=>'D'}],
|
210
207
|
[{:i=>6, :pi=>2, :name=>'C', :kal=>2, :lal=>0}, {:i=>9, :pi=>2, :name=>'E', :kal=>2, :lal=>0},
|
211
208
|
{:i=>3, :name=>'00', :pi=>6, :kal=>6, :lal=>0}, {:i=>3, :name=>'00', :pi=>6, :kal=>2, :lal=>1},
|
212
209
|
{:i=>4, :name=>'?', :pi=>7, :kal=>7, :lal=>0}, {:i=>5, :name=>'?', :pi=>4, :kal=>7, :lal=>1}]]
|
213
210
|
os = @ds.eager(:ds=>2).all
|
214
|
-
MODEL_DB.sqls
|
215
|
-
|
211
|
+
sqls = MODEL_DB.sqls
|
212
|
+
sqls.first.should == "SELECT * FROM nodes"
|
213
|
+
sqls.last.should =~ /WITH cte AS \(SELECT pi AS kal, nodes\.\*, 0 AS lal FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\*, \(cte\.lal \+ 1\) AS lal FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\) WHERE \(cte\.lal < 1\)\) SELECT \* FROM cte/
|
216
214
|
os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
|
217
215
|
os.map{|o| o.ds}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E'), @c.load(:i=>3, :name=>'00', :pi=>6)],
|
218
216
|
[@c.load(:i=>3, :name=>'00', :pi=>6)],
|
@@ -220,18 +218,18 @@ describe Sequel::Model, "rcte_tree" do
|
|
220
218
|
os.map{|o| o.associations[:cs]}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E')], [@c.load(:i=>3, :name=>'00', :pi=>6)], [@c.load(:i=>4, :name=>'?', :pi=>7)]]
|
221
219
|
os.map{|o1| o1.associations[:cs].map{|o2| o2.associations[:cs]}}.should == [[[@c.load(:i=>3, :name=>'00', :pi=>6)], []], [[]], [[@c.load(:i=>5, :name=>'?', :pi=>4)]]]
|
222
220
|
os.map{|o1| o1.associations[:cs].map{|o2| o2.associations[:cs].map{|o3| o3.associations[:cs]}}}.should == [[[[]], []], [[]], [[nil]]]
|
223
|
-
MODEL_DB.
|
221
|
+
MODEL_DB.sqls.should == []
|
224
222
|
end
|
225
223
|
|
226
224
|
it "should eagerly load descendants respecting association option :conditions" do
|
227
225
|
@c.plugin :rcte_tree, :conditions => {:i => 1}
|
228
|
-
@ds.
|
226
|
+
@ds._fetch = [[{:id=>2, :parent_id=>1, :name=>'AA'}, {:id=>6, :parent_id=>2, :name=>'C'}, {:id=>7, :parent_id=>1, :name=>'D'}],
|
229
227
|
[{:id=>6, :parent_id=>2, :name=>'C', :x_root_x=>2}, {:id=>9, :parent_id=>2, :name=>'E', :x_root_x=>2},
|
230
228
|
{:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
|
231
229
|
{:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]]
|
232
230
|
os = @ds.eager(:descendants).all
|
233
|
-
MODEL_DB.sqls
|
234
|
-
|
235
|
-
|
231
|
+
sqls = MODEL_DB.sqls
|
232
|
+
sqls.first.should == "SELECT * FROM nodes"
|
233
|
+
sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(parent_id IN \([267], [267], [267]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/
|
236
234
|
end
|
237
235
|
end
|