sequel 3.21.0 → 3.24.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 +112 -0
- data/README.rdoc +15 -1
- data/doc/association_basics.rdoc +159 -40
- data/doc/model_hooks.rdoc +64 -27
- data/doc/prepared_statements.rdoc +8 -4
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +2 -1
- data/lib/sequel/adapters/db2.rb +8 -1
- data/lib/sequel/adapters/firebird.rb +25 -9
- data/lib/sequel/adapters/informix.rb +4 -19
- data/lib/sequel/adapters/jdbc/h2.rb +5 -0
- data/lib/sequel/adapters/jdbc/informix.rb +31 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +46 -0
- data/lib/sequel/adapters/jdbc.rb +39 -20
- data/lib/sequel/adapters/odbc.rb +2 -0
- data/lib/sequel/adapters/oracle.rb +12 -0
- data/lib/sequel/adapters/postgres.rb +30 -1
- data/lib/sequel/adapters/shared/access.rb +10 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +106 -11
- data/lib/sequel/adapters/shared/mysql.rb +25 -7
- data/lib/sequel/adapters/shared/postgres.rb +39 -6
- data/lib/sequel/adapters/shared/sqlite.rb +57 -5
- data/lib/sequel/adapters/sqlite.rb +8 -3
- data/lib/sequel/adapters/swift/mysql.rb +9 -0
- data/lib/sequel/adapters/tinytds.rb +4 -3
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/misc.rb +6 -0
- data/lib/sequel/database/query.rb +33 -3
- data/lib/sequel/database/schema_methods.rb +13 -4
- data/lib/sequel/dataset/features.rb +6 -0
- data/lib/sequel/dataset/prepared_statements.rb +17 -2
- data/lib/sequel/dataset/query.rb +17 -0
- data/lib/sequel/dataset/sql.rb +2 -53
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +4 -3
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +234 -32
- data/lib/sequel/model/base.rb +187 -60
- data/lib/sequel/model/exceptions.rb +3 -1
- data/lib/sequel/model.rb +5 -0
- data/lib/sequel/plugins/association_pks.rb +6 -4
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/identity_map.rb +2 -2
- data/lib/sequel/plugins/many_through_many.rb +33 -3
- data/lib/sequel/plugins/prepared_statements.rb +140 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +72 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -0
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +8 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +36 -0
- data/spec/adapters/mysql_spec.rb +6 -0
- data/spec/adapters/postgres_spec.rb +43 -18
- data/spec/adapters/spec_helper.rb +5 -0
- data/spec/core/connection_pool_spec.rb +56 -77
- data/spec/core/database_spec.rb +33 -0
- data/spec/core/dataset_spec.rb +127 -16
- data/spec/core/expression_filters_spec.rb +13 -0
- data/spec/core/schema_spec.rb +13 -1
- data/spec/core/spec_helper.rb +5 -0
- data/spec/extensions/association_pks_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/many_through_many_spec.rb +77 -0
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/nested_attributes_spec.rb +1 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +69 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +36 -0
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +3 -1
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/xml_serializer_spec.rb +12 -0
- data/spec/integration/associations_test.rb +212 -0
- data/spec/integration/dataset_test.rb +8 -1
- data/spec/integration/plugin_test.rb +134 -0
- data/spec/integration/prepared_statement_test.rb +72 -1
- data/spec/integration/schema_test.rb +66 -8
- data/spec/integration/spec_helper.rb +5 -0
- data/spec/integration/transaction_test.rb +40 -0
- data/spec/integration/type_test.rb +7 -0
- data/spec/model/associations_spec.rb +463 -5
- data/spec/model/base_spec.rb +59 -0
- data/spec/model/eager_loading_spec.rb +269 -1
- data/spec/model/hooks_spec.rb +161 -0
- data/spec/model/record_spec.rb +30 -0
- data/spec/model/spec_helper.rb +5 -0
- metadata +29 -4
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "serialization_modification_detection plugin" do
|
|
4
|
+
before do
|
|
5
|
+
@c = Class.new(Sequel::Model(:items))
|
|
6
|
+
@c.class_eval do
|
|
7
|
+
columns :id, :h
|
|
8
|
+
plugin :serialization, :yaml, :h
|
|
9
|
+
plugin :serialization_modification_detection
|
|
10
|
+
end
|
|
11
|
+
@o1 = @c.new
|
|
12
|
+
@o2 = @c.load(:id=>1, :h=>"--- {}\n\n")
|
|
13
|
+
MODEL_DB.reset
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should not detect columns that haven't been changed" do
|
|
17
|
+
@o2.changed_columns.should == []
|
|
18
|
+
@o2.h.should == {}
|
|
19
|
+
@o2.h[1] = 2
|
|
20
|
+
@o2.h.clear
|
|
21
|
+
@o2.changed_columns.should == []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should detect columns that have been changed" do
|
|
25
|
+
@o2.changed_columns.should == []
|
|
26
|
+
@o2.h.should == {}
|
|
27
|
+
@o2.h[1] = 2
|
|
28
|
+
@o2.changed_columns.should == [:h]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should report correct changed_columns after saving" do
|
|
32
|
+
@o2.h[1] = 2
|
|
33
|
+
@o2.save_changes
|
|
34
|
+
@o2.changed_columns.should == []
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -54,6 +54,17 @@ describe Sequel::Model, "#sti_key" do
|
|
|
54
54
|
StiTest.all.collect{|x| x.class}.should == [StiTest, StiTestSub1, StiTestSub2]
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
it "should return rows with the correct class for subclasses based on the polymorphic_key value" do
|
|
58
|
+
class ::StiTestSub1Sub < StiTestSub1
|
|
59
|
+
end
|
|
60
|
+
ds = StiTestSub1.dataset
|
|
61
|
+
def ds.fetch_rows(sql)
|
|
62
|
+
yield({:kind=>'StiTestSub1'})
|
|
63
|
+
yield({:kind=>'StiTestSub1Sub'})
|
|
64
|
+
end
|
|
65
|
+
StiTestSub1.all.collect{|x| x.class}.should == [StiTestSub1, StiTestSub1Sub]
|
|
66
|
+
end
|
|
67
|
+
|
|
57
68
|
it "should fallback to the main class if the given class does not exist" do
|
|
58
69
|
def @ds.fetch_rows(sql)
|
|
59
70
|
yield({:kind=>'StiTestSub3'})
|
|
@@ -8,9 +8,11 @@ unless Sequel.const_defined?('Model')
|
|
|
8
8
|
require 'sequel/model'
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones to_dot')
|
|
11
|
+
Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones to_dot columns_introspection')
|
|
12
12
|
{:hook_class_methods=>[], :schema=>[], :validation_class_methods=>[]}.each{|p, opts| Sequel::Model.plugin(p, *opts)}
|
|
13
13
|
|
|
14
|
+
Sequel::Dataset.introspect_all_columns if ENV['SEQUEL_COLUMNS_INTROSPECTION']
|
|
15
|
+
|
|
14
16
|
def skip_warn(s)
|
|
15
17
|
warn "Skipping test of #{s}" if ENV["SKIPPED_TEST_WARN"]
|
|
16
18
|
end
|
|
@@ -2,9 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe Sequel::Model, "to_dot extension" do
|
|
4
4
|
def dot(ds)
|
|
5
|
-
|
|
6
|
-
ds.send(:_to_dot, a, "", 0, ds, 0)
|
|
7
|
-
a[2..-1]
|
|
5
|
+
Sequel::ToDot.new(ds).instance_variable_get(:@dot)[4...-1]
|
|
8
6
|
end
|
|
9
7
|
|
|
10
8
|
before do
|
|
@@ -123,7 +121,7 @@ END
|
|
|
123
121
|
end
|
|
124
122
|
|
|
125
123
|
it "should handle SQL::Subscript" do
|
|
126
|
-
dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript
|
|
124
|
+
dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
it "should handle SQL::WindowFunction" do
|
|
@@ -135,7 +133,7 @@ END
|
|
|
135
133
|
end
|
|
136
134
|
|
|
137
135
|
it "should handle JOIN ON" do
|
|
138
|
-
dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"
|
|
136
|
+
dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"ComplexExpression: =\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"QualifiedIdentifier\"];", "8 -> 9 [label=\"table\"];", "9 [label=\"\\\"d\\\"\"];", "8 -> 10 [label=\"column\"];", "10 [label=\"\\\"b\\\"\"];", "7 -> 11 [label=\"1\"];", "11 [label=\"QualifiedIdentifier\"];", "11 -> 12 [label=\"table\"];", "12 [label=\"\\\"a\\\"\"];", "11 -> 13 [label=\"column\"];", "13 [label=\"\\\"c\\\"\"];"]
|
|
139
137
|
end
|
|
140
138
|
|
|
141
139
|
it "should handle JOIN USING" do
|
|
@@ -36,6 +36,18 @@ describe "Sequel::Plugins::XmlSerializer" do
|
|
|
36
36
|
Album.from_xml(@album.to_xml).should == @album
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
it "should round trip successfully for namespaced models" do
|
|
40
|
+
module XmlSerializerTest
|
|
41
|
+
class Artist < Sequel::Model
|
|
42
|
+
plugin :xml_serializer
|
|
43
|
+
columns :id, :name
|
|
44
|
+
@db_schema = {:id=>{:type=>:integer}, :name=>{:type=>:string}}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
artist = XmlSerializerTest::Artist.load(:id=>2, :name=>'YJM')
|
|
48
|
+
XmlSerializerTest::Artist.from_xml(artist.to_xml).should == artist
|
|
49
|
+
end
|
|
50
|
+
|
|
39
51
|
it "should round trip successfully with empty strings" do
|
|
40
52
|
artist = Artist.load(:id=>2, :name=>'')
|
|
41
53
|
Artist.from_xml(artist.to_xml).should == artist
|
|
@@ -22,6 +22,172 @@ shared_examples_for "regular and composite key associations" do
|
|
|
22
22
|
@tag.albums.should == [@album]
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
specify "should work correctly with prepared_statements_association plugin" do
|
|
26
|
+
@album.update(:artist => @artist)
|
|
27
|
+
@album.add_tag(@tag)
|
|
28
|
+
|
|
29
|
+
@album.reload
|
|
30
|
+
@artist.reload
|
|
31
|
+
@tag.reload
|
|
32
|
+
|
|
33
|
+
[Tag, Album, Artist].each{|x| x.plugin :prepared_statements_associations}
|
|
34
|
+
@album.artist.should == @artist
|
|
35
|
+
@artist.albums.should == [@album]
|
|
36
|
+
@album.tags.should == [@tag]
|
|
37
|
+
@tag.albums.should == [@album]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
specify "should work correctly when filtering by associations" do
|
|
41
|
+
@album.update(:artist => @artist)
|
|
42
|
+
@album.add_tag(@tag)
|
|
43
|
+
|
|
44
|
+
Artist.filter(:albums=>@album).all.should == [@artist]
|
|
45
|
+
Album.filter(:artist=>@artist).all.should == [@album]
|
|
46
|
+
Album.filter(:tags=>@tag).all.should == [@album]
|
|
47
|
+
Tag.filter(:albums=>@album).all.should == [@tag]
|
|
48
|
+
Album.filter(:artist=>@artist, :tags=>@tag).all.should == [@album]
|
|
49
|
+
@artist.albums_dataset.filter(:tags=>@tag).all.should == [@album]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
specify "should work correctly when excluding by associations" do
|
|
53
|
+
@album.update(:artist => @artist)
|
|
54
|
+
@album.add_tag(@tag)
|
|
55
|
+
album, artist, tag = @pr.call
|
|
56
|
+
|
|
57
|
+
Artist.exclude(:albums=>@album).all.should == [artist]
|
|
58
|
+
Album.exclude(:artist=>@artist).all.should == [album]
|
|
59
|
+
Album.exclude(:tags=>@tag).all.should == [album]
|
|
60
|
+
Tag.exclude(:albums=>@album).all.should == [tag]
|
|
61
|
+
Album.exclude(:artist=>@artist, :tags=>@tag).all.should == [album]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
specify "should work correctly when filtering by multiple associations" do
|
|
65
|
+
album, artist, tag = @pr.call
|
|
66
|
+
@album.update(:artist => @artist)
|
|
67
|
+
@album.add_tag(@tag)
|
|
68
|
+
|
|
69
|
+
Artist.filter(:albums=>[@album, album]).all.should == [@artist]
|
|
70
|
+
Album.filter(:artist=>[@artist, artist]).all.should == [@album]
|
|
71
|
+
Album.filter(:tags=>[@tag, tag]).all.should == [@album]
|
|
72
|
+
Tag.filter(:albums=>[@album, album]).all.should == [@tag]
|
|
73
|
+
Album.filter(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.should == [@album]
|
|
74
|
+
@artist.albums_dataset.filter(:tags=>[@tag, tag]).all.should == [@album]
|
|
75
|
+
|
|
76
|
+
album.add_tag(tag)
|
|
77
|
+
|
|
78
|
+
Artist.filter(:albums=>[@album, album]).all.should == [@artist]
|
|
79
|
+
Album.filter(:artist=>[@artist, artist]).all.should == [@album]
|
|
80
|
+
Album.filter(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
81
|
+
Tag.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
|
82
|
+
Album.filter(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.should == [@album]
|
|
83
|
+
|
|
84
|
+
album.update(:artist => artist)
|
|
85
|
+
|
|
86
|
+
Artist.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
|
87
|
+
Album.filter(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
88
|
+
Album.filter(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
89
|
+
Tag.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
|
90
|
+
Album.filter(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
specify "should work correctly when excluding by multiple associations" do
|
|
94
|
+
album, artist, tag = @pr.call
|
|
95
|
+
|
|
96
|
+
Artist.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
|
97
|
+
Album.exclude(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
98
|
+
Album.exclude(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
99
|
+
Tag.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
|
100
|
+
Album.exclude(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
101
|
+
|
|
102
|
+
@album.update(:artist => @artist)
|
|
103
|
+
@album.add_tag(@tag)
|
|
104
|
+
|
|
105
|
+
Artist.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [artist]
|
|
106
|
+
Album.exclude(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [album]
|
|
107
|
+
Album.exclude(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [album]
|
|
108
|
+
Tag.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [tag]
|
|
109
|
+
Album.exclude(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [album]
|
|
110
|
+
|
|
111
|
+
album.add_tag(tag)
|
|
112
|
+
|
|
113
|
+
Artist.exclude(:albums=>[@album, album]).all.should == [artist]
|
|
114
|
+
Album.exclude(:artist=>[@artist, artist]).all.should == [album]
|
|
115
|
+
Album.exclude(:tags=>[@tag, tag]).all.should == []
|
|
116
|
+
Tag.exclude(:albums=>[@album, album]).all.should == []
|
|
117
|
+
Album.exclude(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.should == [album]
|
|
118
|
+
|
|
119
|
+
album.update(:artist => artist)
|
|
120
|
+
|
|
121
|
+
Artist.exclude(:albums=>[@album, album]).all.should == []
|
|
122
|
+
Album.exclude(:artist=>[@artist, artist]).all.should == []
|
|
123
|
+
Album.exclude(:tags=>[@tag, tag]).all.should == []
|
|
124
|
+
Tag.exclude(:albums=>[@album, album]).all.should == []
|
|
125
|
+
Album.exclude(:artist=>[@artist, artist], :tags=>[@tag, tag]).all.should == []
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
specify "should work correctly when excluding by associations in regards to NULL values" do
|
|
129
|
+
Artist.exclude(:albums=>@album).all.should == [@artist]
|
|
130
|
+
Album.exclude(:artist=>@artist).all.should == [@album]
|
|
131
|
+
Album.exclude(:tags=>@tag).all.should == [@album]
|
|
132
|
+
Tag.exclude(:albums=>@album).all.should == [@tag]
|
|
133
|
+
Album.exclude(:artist=>@artist, :tags=>@tag).all.should == [@album]
|
|
134
|
+
|
|
135
|
+
@album.update(:artist => @artist)
|
|
136
|
+
@artist.albums_dataset.exclude(:tags=>@tag).all.should == [@album]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
specify "should handle NULL values in join table correctly when filtering/excluding many_to_many associations" do
|
|
140
|
+
@ins.call
|
|
141
|
+
Album.exclude(:tags=>@tag).all.should == [@album]
|
|
142
|
+
@album.add_tag(@tag)
|
|
143
|
+
Album.filter(:tags=>@tag).all.should == [@album]
|
|
144
|
+
album, artist, tag = @pr.call
|
|
145
|
+
Album.exclude(:tags=>@tag).all.should == [album]
|
|
146
|
+
Album.exclude(:tags=>tag).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
specify "should work correctly when filtering by association datasets" do
|
|
150
|
+
album, artist, tag = @pr.call
|
|
151
|
+
@album.update(:artist => @artist)
|
|
152
|
+
@album.add_tag(@tag)
|
|
153
|
+
album.add_tag(tag)
|
|
154
|
+
album.update(:artist => artist)
|
|
155
|
+
|
|
156
|
+
Artist.filter(:albums=>Album.dataset).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
|
157
|
+
Artist.filter(:albums=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [artist]
|
|
158
|
+
Artist.filter(:albums=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
|
159
|
+
Album.filter(:artist=>Artist.dataset).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
160
|
+
Album.filter(:artist=>Artist.dataset.filter(Array(Artist.primary_key).zip(Array(artist.pk)))).all.sort_by{|x| x.pk}.should == [album]
|
|
161
|
+
Album.filter(:artist=>Artist.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
|
162
|
+
Album.filter(:tags=>Tag.dataset).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
163
|
+
Album.filter(:tags=>Tag.dataset.filter(Array(Tag.primary_key).zip(Array(tag.pk)))).all.sort_by{|x| x.pk}.should == [album]
|
|
164
|
+
Album.filter(:tags=>Tag.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
|
165
|
+
Tag.filter(:albums=>Album.dataset).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
|
166
|
+
Tag.filter(:albums=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [tag]
|
|
167
|
+
Tag.filter(:albums=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
specify "should work correctly when excluding by association datasets" do
|
|
171
|
+
album, artist, tag = @pr.call
|
|
172
|
+
@album.update(:artist => @artist)
|
|
173
|
+
@album.add_tag(@tag)
|
|
174
|
+
album.add_tag(tag)
|
|
175
|
+
album.update(:artist => artist)
|
|
176
|
+
|
|
177
|
+
Artist.exclude(:albums=>Album.dataset).all.sort_by{|x| x.pk}.should == []
|
|
178
|
+
Artist.exclude(:albums=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [@artist]
|
|
179
|
+
Artist.exclude(:albums=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
|
180
|
+
Album.exclude(:artist=>Artist.dataset).all.sort_by{|x| x.pk}.should == []
|
|
181
|
+
Album.exclude(:artist=>Artist.dataset.filter(Array(Artist.primary_key).zip(Array(artist.pk)))).all.sort_by{|x| x.pk}.should == [@album]
|
|
182
|
+
Album.exclude(:artist=>Artist.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
183
|
+
Album.exclude(:tags=>Tag.dataset).all.sort_by{|x| x.pk}.should == []
|
|
184
|
+
Album.exclude(:tags=>Tag.dataset.filter(Array(Tag.primary_key).zip(Array(tag.pk)))).all.sort_by{|x| x.pk}.should == [@album]
|
|
185
|
+
Album.exclude(:tags=>Tag.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == [@album, album]
|
|
186
|
+
Tag.exclude(:albums=>Album.dataset).all.sort_by{|x| x.pk}.should == []
|
|
187
|
+
Tag.exclude(:albums=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [@tag]
|
|
188
|
+
Tag.exclude(:albums=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
|
189
|
+
end
|
|
190
|
+
|
|
25
191
|
specify "should have remove methods work" do
|
|
26
192
|
@album.update(:artist => @artist)
|
|
27
193
|
@album.add_tag(@tag)
|
|
@@ -151,6 +317,8 @@ describe "Sequel::Model Simple Associations" do
|
|
|
151
317
|
@album = Album.create(:name=>'Al')
|
|
152
318
|
@artist = Artist.create(:name=>'Ar')
|
|
153
319
|
@tag = Tag.create(:name=>'T')
|
|
320
|
+
@pr = lambda{[Album.create(:name=>'Al2'),Artist.create(:name=>'Ar2'),Tag.create(:name=>'T2')]}
|
|
321
|
+
@ins = lambda{@db[:albums_tags].insert(:tag_id=>@tag.id)}
|
|
154
322
|
end
|
|
155
323
|
after do
|
|
156
324
|
@db.drop_table(:albums_tags, :tags, :albums, :artists)
|
|
@@ -216,6 +384,48 @@ describe "Sequel::Model Simple Associations" do
|
|
|
216
384
|
@tag.reload.albums.should == []
|
|
217
385
|
end
|
|
218
386
|
|
|
387
|
+
specify "should handle dynamic callbacks for regular loading" do
|
|
388
|
+
@artist.add_album(@album)
|
|
389
|
+
|
|
390
|
+
@artist.albums.should == [@album]
|
|
391
|
+
@artist.albums(proc{|ds| ds.exclude(:id=>@album.id)}).should == []
|
|
392
|
+
@artist.albums(proc{|ds| ds.filter(:id=>@album.id)}).should == [@album]
|
|
393
|
+
|
|
394
|
+
@album.artist.should == @artist
|
|
395
|
+
@album.artist(proc{|ds| ds.exclude(:id=>@artist.id)}).should == nil
|
|
396
|
+
@album.artist(proc{|ds| ds.filter(:id=>@artist.id)}).should == @artist
|
|
397
|
+
|
|
398
|
+
if RUBY_VERSION >= '1.8.7'
|
|
399
|
+
@artist.albums{|ds| ds.exclude(:id=>@album.id)}.should == []
|
|
400
|
+
@artist.albums{|ds| ds.filter(:id=>@album.id)}.should == [@album]
|
|
401
|
+
@album.artist{|ds| ds.exclude(:id=>@artist.id)}.should == nil
|
|
402
|
+
@album.artist{|ds| ds.filter(:id=>@artist.id)}.should == @artist
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
specify "should handle dynamic callbacks for eager loading via eager and eager_graph" do
|
|
407
|
+
@artist.add_album(@album)
|
|
408
|
+
@album.add_tag(@tag)
|
|
409
|
+
album2 = @artist.add_album(:name=>'Foo')
|
|
410
|
+
tag2 = album2.add_tag(:name=>'T2')
|
|
411
|
+
|
|
412
|
+
artist = Artist.eager(:albums=>:tags).all.first
|
|
413
|
+
artist.albums.should == [@album, album2]
|
|
414
|
+
artist.albums.map{|x| x.tags}.should == [[@tag], [tag2]]
|
|
415
|
+
|
|
416
|
+
artist = Artist.eager_graph(:albums=>:tags).all.first
|
|
417
|
+
artist.albums.should == [@album, album2]
|
|
418
|
+
artist.albums.map{|x| x.tags}.should == [[@tag], [tag2]]
|
|
419
|
+
|
|
420
|
+
artist = Artist.eager(:albums=>{proc{|ds| ds.where(:id=>album2.id)}=>:tags}).all.first
|
|
421
|
+
artist.albums.should == [album2]
|
|
422
|
+
artist.albums.first.tags.should == [tag2]
|
|
423
|
+
|
|
424
|
+
artist = Artist.eager_graph(:albums=>{proc{|ds| ds.where(:id=>album2.id)}=>:tags}).all.first
|
|
425
|
+
artist.albums.should == [album2]
|
|
426
|
+
artist.albums.first.tags.should == [tag2]
|
|
427
|
+
end
|
|
428
|
+
|
|
219
429
|
specify "should have remove method raise an error for one_to_many records if the object isn't already associated" do
|
|
220
430
|
proc{@artist.remove_album(@album.id)}.should raise_error(Sequel::Error)
|
|
221
431
|
proc{@artist.remove_album(@album)}.should raise_error(Sequel::Error)
|
|
@@ -275,6 +485,8 @@ describe "Sequel::Model Composite Key Associations" do
|
|
|
275
485
|
@album = Album.create(:name=>'Al', :id1=>1, :id2=>2)
|
|
276
486
|
@artist = Artist.create(:name=>'Ar', :id1=>3, :id2=>4)
|
|
277
487
|
@tag = Tag.create(:name=>'T', :id1=>5, :id2=>6)
|
|
488
|
+
@pr = lambda{[Album.create(:name=>'Al2', :id1=>11, :id2=>12),Artist.create(:name=>'Ar2', :id1=>13, :id2=>14),Tag.create(:name=>'T2', :id1=>15, :id2=>16)]}
|
|
489
|
+
@ins = lambda{@db[:albums_tags].insert(:tag_id1=>@tag.id1, :tag_id2=>@tag.id2)}
|
|
278
490
|
end
|
|
279
491
|
after do
|
|
280
492
|
@db.drop_table(:albums_tags, :tags, :albums, :artists)
|
|
@@ -86,6 +86,13 @@ describe "Simple Dataset operations" do
|
|
|
86
86
|
specify "should alias columns correctly" do
|
|
87
87
|
@ds.select(:id___x, :number___n).first.should == {:x=>1, :n=>10}
|
|
88
88
|
end
|
|
89
|
+
|
|
90
|
+
specify "should handle true/false properly" do
|
|
91
|
+
@ds.filter(Sequel::TRUE).select_map(:number).should == [10]
|
|
92
|
+
@ds.filter(Sequel::FALSE).select_map(:number).should == []
|
|
93
|
+
@ds.filter(true).select_map(:number).should == [10]
|
|
94
|
+
@ds.filter(false).select_map(:number).should == []
|
|
95
|
+
end
|
|
89
96
|
end
|
|
90
97
|
|
|
91
98
|
describe Sequel::Dataset do
|
|
@@ -471,7 +478,7 @@ describe Sequel::SQL::Constants do
|
|
|
471
478
|
@c2 = proc{|v| v.is_a?(Date) ? v : Date.parse(v) }
|
|
472
479
|
end
|
|
473
480
|
after do
|
|
474
|
-
@db.drop_table(:constants)
|
|
481
|
+
@db.drop_table(:constants) if @db.table_exists?(:constants)
|
|
475
482
|
end
|
|
476
483
|
|
|
477
484
|
cspecify "should have working CURRENT_DATE", [:odbc, :mssql], [:jdbc, :sqlite] do
|
|
@@ -196,6 +196,12 @@ describe "Many Through Many Plugin" do
|
|
|
196
196
|
Artist[3].albums.map{|x| x.name}.sort.should == %w'B C'
|
|
197
197
|
Artist[4].albums.map{|x| x.name}.sort.should == %w'B D'
|
|
198
198
|
|
|
199
|
+
Artist.plugin :prepared_statements_associations
|
|
200
|
+
Artist[1].albums.map{|x| x.name}.sort.should == %w'A D'
|
|
201
|
+
Artist[2].albums.map{|x| x.name}.sort.should == %w'A C'
|
|
202
|
+
Artist[3].albums.map{|x| x.name}.sort.should == %w'B C'
|
|
203
|
+
Artist[4].albums.map{|x| x.name}.sort.should == %w'B D'
|
|
204
|
+
|
|
199
205
|
Artist.filter(:id=>1).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A D'
|
|
200
206
|
Artist.filter(:id=>2).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A C'
|
|
201
207
|
Artist.filter(:id=>3).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B C'
|
|
@@ -205,6 +211,25 @@ describe "Many Through Many Plugin" do
|
|
|
205
211
|
Artist.filter(:artists__id=>2).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A C'
|
|
206
212
|
Artist.filter(:artists__id=>3).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B C'
|
|
207
213
|
Artist.filter(:artists__id=>4).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
|
|
214
|
+
|
|
215
|
+
Artist.filter(:albums=>@album1).all.map{|a| a.name}.sort.should == %w'1 2'
|
|
216
|
+
Artist.filter(:albums=>@album2).all.map{|a| a.name}.sort.should == %w'3 4'
|
|
217
|
+
Artist.filter(:albums=>@album3).all.map{|a| a.name}.sort.should == %w'2 3'
|
|
218
|
+
Artist.filter(:albums=>@album4).all.map{|a| a.name}.sort.should == %w'1 4'
|
|
219
|
+
|
|
220
|
+
Artist.exclude(:albums=>@album1).all.map{|a| a.name}.sort.should == %w'3 4'
|
|
221
|
+
Artist.exclude(:albums=>@album2).all.map{|a| a.name}.sort.should == %w'1 2'
|
|
222
|
+
Artist.exclude(:albums=>@album3).all.map{|a| a.name}.sort.should == %w'1 4'
|
|
223
|
+
Artist.exclude(:albums=>@album4).all.map{|a| a.name}.sort.should == %w'2 3'
|
|
224
|
+
|
|
225
|
+
Artist.filter(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
226
|
+
Artist.filter(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w'1 3 4'
|
|
227
|
+
|
|
228
|
+
Artist.exclude(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'4'
|
|
229
|
+
Artist.exclude(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w'2'
|
|
230
|
+
|
|
231
|
+
Artist.filter(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
232
|
+
Artist.exclude(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4'
|
|
208
233
|
end
|
|
209
234
|
|
|
210
235
|
specify "should handle typical case with 3 join tables" do
|
|
@@ -214,6 +239,12 @@ describe "Many Through Many Plugin" do
|
|
|
214
239
|
Artist[3].related_artists.map{|x| x.name}.sort.should == %w'2 3 4'
|
|
215
240
|
Artist[4].related_artists.map{|x| x.name}.sort.should == %w'1 3 4'
|
|
216
241
|
|
|
242
|
+
Artist.plugin :prepared_statements_associations
|
|
243
|
+
Artist[1].related_artists.map{|x| x.name}.sort.should == %w'1 2 4'
|
|
244
|
+
Artist[2].related_artists.map{|x| x.name}.sort.should == %w'1 2 3'
|
|
245
|
+
Artist[3].related_artists.map{|x| x.name}.sort.should == %w'2 3 4'
|
|
246
|
+
Artist[4].related_artists.map{|x| x.name}.sort.should == %w'1 3 4'
|
|
247
|
+
|
|
217
248
|
Artist.filter(:id=>1).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4'
|
|
218
249
|
Artist.filter(:id=>2).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
|
|
219
250
|
Artist.filter(:id=>3).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
|
|
@@ -223,6 +254,22 @@ describe "Many Through Many Plugin" do
|
|
|
223
254
|
Artist.filter(:artists__id=>2).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
|
|
224
255
|
Artist.filter(:artists__id=>3).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
|
|
225
256
|
Artist.filter(:artists__id=>4).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4'
|
|
257
|
+
|
|
258
|
+
Artist.filter(:related_artists=>@artist1).all.map{|a| a.name}.sort.should == %w'1 2 4'
|
|
259
|
+
Artist.filter(:related_artists=>@artist2).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
260
|
+
Artist.filter(:related_artists=>@artist3).all.map{|a| a.name}.sort.should == %w'2 3 4'
|
|
261
|
+
Artist.filter(:related_artists=>@artist4).all.map{|a| a.name}.sort.should == %w'1 3 4'
|
|
262
|
+
|
|
263
|
+
Artist.exclude(:related_artists=>@artist1).all.map{|a| a.name}.sort.should == %w'3'
|
|
264
|
+
Artist.exclude(:related_artists=>@artist2).all.map{|a| a.name}.sort.should == %w'4'
|
|
265
|
+
Artist.exclude(:related_artists=>@artist3).all.map{|a| a.name}.sort.should == %w'1'
|
|
266
|
+
Artist.exclude(:related_artists=>@artist4).all.map{|a| a.name}.sort.should == %w'2'
|
|
267
|
+
|
|
268
|
+
Artist.filter(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
|
|
269
|
+
Artist.exclude(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.should == %w''
|
|
270
|
+
|
|
271
|
+
Artist.filter(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.should == %w'1 2 4'
|
|
272
|
+
Artist.exclude(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.should == %w'3'
|
|
226
273
|
end
|
|
227
274
|
|
|
228
275
|
specify "should handle extreme case with 5 join tables" do
|
|
@@ -241,6 +288,12 @@ describe "Many Through Many Plugin" do
|
|
|
241
288
|
Artist[3].related_albums.map{|x| x.name}.sort.should == %w'A B D'
|
|
242
289
|
Artist[4].related_albums.map{|x| x.name}.sort.should == %w'B D'
|
|
243
290
|
|
|
291
|
+
Artist.plugin :prepared_statements_associations
|
|
292
|
+
Artist[1].related_albums.map{|x| x.name}.sort.should == %w'A B C'
|
|
293
|
+
Artist[2].related_albums.map{|x| x.name}.sort.should == %w'A B C D'
|
|
294
|
+
Artist[3].related_albums.map{|x| x.name}.sort.should == %w'A B D'
|
|
295
|
+
Artist[4].related_albums.map{|x| x.name}.sort.should == %w'B D'
|
|
296
|
+
|
|
244
297
|
Artist.filter(:id=>1).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C'
|
|
245
298
|
Artist.filter(:id=>2).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
|
|
246
299
|
Artist.filter(:id=>3).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
|
|
@@ -250,6 +303,25 @@ describe "Many Through Many Plugin" do
|
|
|
250
303
|
Artist.filter(:artists__id=>2).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
|
|
251
304
|
Artist.filter(:artists__id=>3).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
|
|
252
305
|
Artist.filter(:artists__id=>4).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
|
|
306
|
+
|
|
307
|
+
Artist.filter(:related_albums=>@album1).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
308
|
+
Artist.filter(:related_albums=>@album2).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
|
|
309
|
+
Artist.filter(:related_albums=>@album3).all.map{|a| a.name}.sort.should == %w'1 2'
|
|
310
|
+
Artist.filter(:related_albums=>@album4).all.map{|a| a.name}.sort.should == %w'2 3 4'
|
|
311
|
+
|
|
312
|
+
Artist.exclude(:related_albums=>@album1).all.map{|a| a.name}.sort.should == %w'4'
|
|
313
|
+
Artist.exclude(:related_albums=>@album2).all.map{|a| a.name}.sort.should == %w''
|
|
314
|
+
Artist.exclude(:related_albums=>@album3).all.map{|a| a.name}.sort.should == %w'3 4'
|
|
315
|
+
Artist.exclude(:related_albums=>@album4).all.map{|a| a.name}.sort.should == %w'1'
|
|
316
|
+
|
|
317
|
+
Artist.filter(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
318
|
+
Artist.filter(:related_albums=>[@album3, @album4]).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
|
|
319
|
+
|
|
320
|
+
Artist.exclude(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'4'
|
|
321
|
+
Artist.exclude(:related_albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w''
|
|
322
|
+
|
|
323
|
+
Artist.filter(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'1 2 3'
|
|
324
|
+
Artist.exclude(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4'
|
|
253
325
|
end
|
|
254
326
|
end
|
|
255
327
|
|
|
@@ -1306,3 +1378,65 @@ describe "Sequel::Plugins::Tree" do
|
|
|
1306
1378
|
end
|
|
1307
1379
|
end
|
|
1308
1380
|
end
|
|
1381
|
+
|
|
1382
|
+
describe "Sequel::Plugins::PreparedStatements" do
|
|
1383
|
+
before do
|
|
1384
|
+
@db = INTEGRATION_DB
|
|
1385
|
+
@db.create_table!(:ps_test) do
|
|
1386
|
+
primary_key :id
|
|
1387
|
+
String :name
|
|
1388
|
+
Integer :i
|
|
1389
|
+
end
|
|
1390
|
+
@c = Class.new(Sequel::Model(@db[:ps_test]))
|
|
1391
|
+
@foo = @c.create(:name=>'foo', :i=>10)
|
|
1392
|
+
@bar = @c.create(:name=>'bar', :i=>20)
|
|
1393
|
+
@c.plugin :prepared_statements_with_pk
|
|
1394
|
+
end
|
|
1395
|
+
after do
|
|
1396
|
+
@db.drop_table(:ps_test)
|
|
1397
|
+
end
|
|
1398
|
+
|
|
1399
|
+
it "should work with looking up using Model.[]" do
|
|
1400
|
+
@c[@foo.id].should == @foo
|
|
1401
|
+
@c[@bar.id].should == @bar
|
|
1402
|
+
@c[0].should == nil
|
|
1403
|
+
end
|
|
1404
|
+
|
|
1405
|
+
it "should work with looking up using Dataset#with_pk" do
|
|
1406
|
+
@c.dataset.with_pk(@foo.id).should == @foo
|
|
1407
|
+
@c.dataset.with_pk(@bar.id).should == @bar
|
|
1408
|
+
@c.dataset.with_pk(0).should == nil
|
|
1409
|
+
|
|
1410
|
+
@c.dataset.filter(:i=>0).with_pk(@foo.id).should == nil
|
|
1411
|
+
@c.dataset.filter(:i=>10).with_pk(@foo.id).should == @foo
|
|
1412
|
+
@c.dataset.filter(:i=>20).with_pk(@bar.id).should == @bar
|
|
1413
|
+
@c.dataset.filter(:name=>'foo').with_pk(@foo.id).should == @foo
|
|
1414
|
+
@c.dataset.filter(:name=>'bar').with_pk(@bar.id).should == @bar
|
|
1415
|
+
@c.dataset.filter(:name=>'baz').with_pk(@bar.id).should == nil
|
|
1416
|
+
end
|
|
1417
|
+
|
|
1418
|
+
it "should work with Model#destroy" do
|
|
1419
|
+
@foo.destroy
|
|
1420
|
+
@bar.destroy
|
|
1421
|
+
@c[@foo.id].should == nil
|
|
1422
|
+
@c[@bar.id].should == nil
|
|
1423
|
+
end
|
|
1424
|
+
|
|
1425
|
+
it "should work with Model#update" do
|
|
1426
|
+
@foo.update(:name=>'foo2', :i=>30)
|
|
1427
|
+
@c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo2', :i=>30)
|
|
1428
|
+
@foo.update(:name=>'foo3')
|
|
1429
|
+
@c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>30)
|
|
1430
|
+
@foo.update(:i=>40)
|
|
1431
|
+
@c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>40)
|
|
1432
|
+
end
|
|
1433
|
+
|
|
1434
|
+
it "should work with Model#create" do
|
|
1435
|
+
o = @c.create(:name=>'foo2', :i=>30)
|
|
1436
|
+
@c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>30)
|
|
1437
|
+
o = @c.create(:name=>'foo2')
|
|
1438
|
+
@c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>nil)
|
|
1439
|
+
o = @c.create(:i=>30)
|
|
1440
|
+
@c[o.id].should == @c.load(:id=>o.id, :name=>nil, :i=>30)
|
|
1441
|
+
end
|
|
1442
|
+
end
|
|
@@ -251,7 +251,7 @@ describe "Bound Argument Types" do
|
|
|
251
251
|
@ds.filter(:t=>@ds.ba(:$x, :timestamp)).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
-
cspecify "should handle blob type", [:swift] do
|
|
254
|
+
cspecify "should handle blob type", [:swift], [:odbc] do
|
|
255
255
|
@ds.filter(:file=>@ds.ba(:$x, :bytea)).prepare(:first, :ps_blob).call(:x=>@vs[:file])[:file].should == @vs[:file]
|
|
256
256
|
end
|
|
257
257
|
|
|
@@ -268,3 +268,74 @@ describe "Bound Argument Types" do
|
|
|
268
268
|
end
|
|
269
269
|
end unless INTEGRATION_DB.adapter_scheme == :swift && INTEGRATION_DB.database_type == :postgres
|
|
270
270
|
|
|
271
|
+
describe "Dataset#unbind" do
|
|
272
|
+
before do
|
|
273
|
+
@ds = ds = INTEGRATION_DB[:items]
|
|
274
|
+
@ct = proc do |t, v|
|
|
275
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
276
|
+
column :c, t
|
|
277
|
+
end
|
|
278
|
+
ds.insert(:c=>v)
|
|
279
|
+
end
|
|
280
|
+
@u = proc{|ds| ds, bv = ds.unbind; ds.call(:first, bv)}
|
|
281
|
+
end
|
|
282
|
+
after do
|
|
283
|
+
INTEGRATION_DB.drop_table(:items) rescue nil
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
specify "should unbind values assigned to equality and inequality statements" do
|
|
287
|
+
@ct[Integer, 10]
|
|
288
|
+
@u[@ds.filter(:c=>10)].should == {:c=>10}
|
|
289
|
+
@u[@ds.exclude(:c=>10)].should == nil
|
|
290
|
+
@u[@ds.filter{c < 10}].should == nil
|
|
291
|
+
@u[@ds.filter{c <= 10}].should == {:c=>10}
|
|
292
|
+
@u[@ds.filter{c > 10}].should == nil
|
|
293
|
+
@u[@ds.filter{c >= 10}].should == {:c=>10}
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
cspecify "should handle numerics and strings", [:odbc], [:swift, :sqlite] do
|
|
297
|
+
@ct[Integer, 10]
|
|
298
|
+
@u[@ds.filter(:c=>10)].should == {:c=>10}
|
|
299
|
+
@ct[Float, 0.0]
|
|
300
|
+
@u[@ds.filter{c < 1}].should == {:c=>0.0}
|
|
301
|
+
@ct[String, 'foo']
|
|
302
|
+
@u[@ds.filter(:c=>'foo')].should == {:c=>'foo'}
|
|
303
|
+
|
|
304
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
305
|
+
BigDecimal :c, :size=>[15,2]
|
|
306
|
+
end
|
|
307
|
+
@ds.insert(:c=>BigDecimal.new('1.1'))
|
|
308
|
+
@u[@ds.filter{c > 0}].should == {:c=>BigDecimal.new('1.1')}
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
cspecify "should handle dates and times", [:sqlite], [:do], [:jdbc, :mssql], [:tinytds] do
|
|
312
|
+
@ct[Date, Date.today]
|
|
313
|
+
@u[@ds.filter(:c=>Date.today)].should == {:c=>Date.today}
|
|
314
|
+
t = Time.now
|
|
315
|
+
@ct[Time, t]
|
|
316
|
+
@u[@ds.filter{c < t + 1}][:c].to_i.should == t.to_i
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
specify "should handle QualifiedIdentifiers" do
|
|
320
|
+
@ct[Integer, 10]
|
|
321
|
+
@u[@ds.filter{items__c > 1}].should == {:c=>10}
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
specify "should handle deep nesting" do
|
|
325
|
+
INTEGRATION_DB.create_table!(:items) do
|
|
326
|
+
Integer :a
|
|
327
|
+
Integer :b
|
|
328
|
+
Integer :c
|
|
329
|
+
Integer :d
|
|
330
|
+
end
|
|
331
|
+
@ds.insert(:a=>2, :b=>0, :c=>3, :d=>5)
|
|
332
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~{:d=>4}=>1}.case(0) => 1)].should == {:a=>2, :b=>0, :c=>3, :d=>5}
|
|
333
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~{:d=>5}=>1}.case(0) => 1)].should == nil
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
specify "should handle case where the same variable has the same value in multiple places " do
|
|
337
|
+
@ct[Integer, 1]
|
|
338
|
+
@u[@ds.filter{c > 1}.or{c < 1}.invert].should == {:c=>1}
|
|
339
|
+
@u[@ds.filter{c > 1}.or{c < 1}].should == nil
|
|
340
|
+
end
|
|
341
|
+
end
|