sequel 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +51 -1
- data/README.rdoc +2 -2
- data/Rakefile +2 -2
- data/doc/advanced_associations.rdoc +6 -18
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/lib/sequel_core/adapters/ado.rb +3 -0
- data/lib/sequel_core/adapters/db2.rb +0 -11
- data/lib/sequel_core/adapters/dbi.rb +0 -11
- data/lib/sequel_core/adapters/do.rb +0 -12
- data/lib/sequel_core/adapters/firebird.rb +21 -16
- data/lib/sequel_core/adapters/informix.rb +1 -11
- data/lib/sequel_core/adapters/jdbc.rb +1 -13
- data/lib/sequel_core/adapters/jdbc/h2.rb +3 -11
- data/lib/sequel_core/adapters/jdbc/mysql.rb +0 -17
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +3 -15
- data/lib/sequel_core/adapters/mysql.rb +31 -27
- data/lib/sequel_core/adapters/odbc.rb +34 -28
- data/lib/sequel_core/adapters/openbase.rb +0 -11
- data/lib/sequel_core/adapters/oracle.rb +11 -9
- data/lib/sequel_core/adapters/postgres.rb +14 -17
- data/lib/sequel_core/adapters/shared/mssql.rb +6 -15
- data/lib/sequel_core/adapters/shared/mysql.rb +29 -14
- data/lib/sequel_core/adapters/shared/oracle.rb +4 -0
- data/lib/sequel_core/adapters/shared/postgres.rb +30 -35
- data/lib/sequel_core/adapters/shared/progress.rb +4 -0
- data/lib/sequel_core/adapters/shared/sqlite.rb +73 -13
- data/lib/sequel_core/adapters/sqlite.rb +8 -18
- data/lib/sequel_core/adapters/utils/date_format.rb +21 -0
- data/lib/sequel_core/{dataset → adapters/utils}/stored_procedures.rb +0 -0
- data/lib/sequel_core/{dataset → adapters/utils}/unsupported.rb +0 -0
- data/lib/sequel_core/core_ext.rb +1 -1
- data/lib/sequel_core/core_sql.rb +9 -4
- data/lib/sequel_core/database.rb +63 -62
- data/lib/sequel_core/dataset.rb +9 -4
- data/lib/sequel_core/dataset/convenience.rb +10 -9
- data/lib/sequel_core/dataset/prepared_statements.rb +1 -1
- data/lib/sequel_core/dataset/sql.rb +130 -36
- data/lib/sequel_core/schema/sql.rb +2 -2
- data/lib/sequel_core/sql.rb +44 -51
- data/lib/sequel_core/version.rb +1 -1
- data/lib/sequel_model/associations.rb +25 -17
- data/lib/sequel_model/base.rb +35 -7
- data/lib/sequel_model/caching.rb +1 -6
- data/lib/sequel_model/record.rb +23 -5
- data/lib/sequel_model/validations.rb +20 -5
- data/spec/adapters/firebird_spec.rb +6 -1
- data/spec/adapters/mysql_spec.rb +12 -0
- data/spec/adapters/postgres_spec.rb +2 -2
- data/spec/adapters/sqlite_spec.rb +81 -2
- data/spec/integration/dataset_test.rb +2 -2
- data/spec/integration/type_test.rb +12 -2
- data/spec/sequel_core/core_sql_spec.rb +46 -12
- data/spec/sequel_core/database_spec.rb +24 -12
- data/spec/sequel_core/dataset_spec.rb +82 -32
- data/spec/sequel_core/schema_spec.rb +16 -0
- data/spec/sequel_model/associations_spec.rb +89 -0
- data/spec/sequel_model/base_spec.rb +66 -0
- data/spec/sequel_model/eager_loading_spec.rb +32 -0
- data/spec/sequel_model/record_spec.rb +9 -9
- data/spec/sequel_model/spec_helper.rb +3 -0
- data/spec/sequel_model/validations_spec.rb +63 -3
- metadata +41 -4
@@ -81,6 +81,13 @@ context "Dataset" do
|
|
81
81
|
@dataset.literal(:a).should == 'a'
|
82
82
|
end
|
83
83
|
|
84
|
+
specify "should have upcase_identifiers? method which returns whether identifiers are currently upcased" do
|
85
|
+
@dataset.upcase_identifiers = true
|
86
|
+
@dataset.upcase_identifiers?.should == true
|
87
|
+
@dataset.upcase_identifiers = false
|
88
|
+
@dataset.upcase_identifiers?.should == false
|
89
|
+
end
|
90
|
+
|
84
91
|
specify "should have identifier_input_method= method which changes literalization of identifiers" do
|
85
92
|
@dataset.identifier_input_method = :upcase
|
86
93
|
@dataset.literal(:a).should == 'A'
|
@@ -696,6 +703,10 @@ context "Dataset#literal" do
|
|
696
703
|
@dataset.literal("a\\'bc").should == "'a\\\\''bc'"
|
697
704
|
end
|
698
705
|
|
706
|
+
specify "should escape blobs as strings by default" do
|
707
|
+
@dataset.literal('abc'.to_sequel_blob).should == "'abc'"
|
708
|
+
end
|
709
|
+
|
699
710
|
specify "should literalize numbers properly" do
|
700
711
|
@dataset.literal(1).should == "1"
|
701
712
|
@dataset.literal(1.5).should == "1.5"
|
@@ -727,13 +738,19 @@ context "Dataset#literal" do
|
|
727
738
|
|
728
739
|
specify "should literalize Time properly" do
|
729
740
|
t = Time.now
|
730
|
-
s = t.strftime("
|
741
|
+
s = t.strftime("'%Y-%m-%dT%H:%M:%S%z'").gsub(/(\d\d')\z/, ':\1')
|
742
|
+
@dataset.literal(t).should == s
|
743
|
+
end
|
744
|
+
|
745
|
+
specify "should literalize DateTime properly" do
|
746
|
+
t = DateTime.now
|
747
|
+
s = t.strftime("'%Y-%m-%dT%H:%M:%S%z'").gsub(/(\d\d')\z/, ':\1')
|
731
748
|
@dataset.literal(t).should == s
|
732
749
|
end
|
733
750
|
|
734
751
|
specify "should literalize Date properly" do
|
735
752
|
d = Date.today
|
736
|
-
s = d.strftime("
|
753
|
+
s = d.strftime("'%Y-%m-%d'")
|
737
754
|
@dataset.literal(d).should == s
|
738
755
|
end
|
739
756
|
|
@@ -867,6 +884,20 @@ context "Dataset#select" do
|
|
867
884
|
|
868
885
|
@d.select(nil, 1, :x => :y).sql.should == "SELECT NULL, 1, x AS y FROM test"
|
869
886
|
end
|
887
|
+
|
888
|
+
specify "should accept a block that yields a virtual row" do
|
889
|
+
@d.select{|o| o.a}.sql.should == 'SELECT a FROM test'
|
890
|
+
@d.select{|o| o.a(1)}.sql.should == 'SELECT a(1) FROM test'
|
891
|
+
@d.select{|o| o.a(1, 2)}.sql.should == 'SELECT a(1, 2) FROM test'
|
892
|
+
@d.select{|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT a, a(1, 2) FROM test'
|
893
|
+
end
|
894
|
+
|
895
|
+
specify "should merge regular arguments with argument returned from block" do
|
896
|
+
@d.select(:b){|o| o.a}.sql.should == 'SELECT b, a FROM test'
|
897
|
+
@d.select(:b, :c){|o| o.a(1)}.sql.should == 'SELECT b, c, a(1) FROM test'
|
898
|
+
@d.select(:b){|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT b, a, a(1, 2) FROM test'
|
899
|
+
@d.select(:b, :c){|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT b, c, a, a(1, 2) FROM test'
|
900
|
+
end
|
870
901
|
end
|
871
902
|
|
872
903
|
context "Dataset#select_all" do
|
@@ -898,6 +929,11 @@ context "Dataset#select_more" do
|
|
898
929
|
@d.select(:a).select_more(:b).sql.should == 'SELECT a, b FROM test'
|
899
930
|
@d.select(:a.*).select_more(:b.*).sql.should == 'SELECT a.*, b.* FROM test'
|
900
931
|
end
|
932
|
+
|
933
|
+
specify "should accept a block that yields a virtual row" do
|
934
|
+
@d.select(:a).select_more{|o| o.b}.sql.should == 'SELECT a, b FROM test'
|
935
|
+
@d.select(:a.*).select_more(:b.*){|o| o.b(1)}.sql.should == 'SELECT a.*, b.*, b(1) FROM test'
|
936
|
+
end
|
901
937
|
end
|
902
938
|
|
903
939
|
context "Dataset#order" do
|
@@ -934,6 +970,20 @@ context "Dataset#order" do
|
|
934
970
|
@dataset.order(:bah).order(nil).sql.should ==
|
935
971
|
'SELECT * FROM test'
|
936
972
|
end
|
973
|
+
|
974
|
+
specify "should accept a block that yields a virtual row" do
|
975
|
+
@dataset.order{|o| o.a}.sql.should == 'SELECT * FROM test ORDER BY a'
|
976
|
+
@dataset.order{|o| o.a(1)}.sql.should == 'SELECT * FROM test ORDER BY a(1)'
|
977
|
+
@dataset.order{|o| o.a(1, 2)}.sql.should == 'SELECT * FROM test ORDER BY a(1, 2)'
|
978
|
+
@dataset.order{|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT * FROM test ORDER BY a, a(1, 2)'
|
979
|
+
end
|
980
|
+
|
981
|
+
specify "should merge regular arguments with argument returned from block" do
|
982
|
+
@dataset.order(:b){|o| o.a}.sql.should == 'SELECT * FROM test ORDER BY b, a'
|
983
|
+
@dataset.order(:b, :c){|o| o.a(1)}.sql.should == 'SELECT * FROM test ORDER BY b, c, a(1)'
|
984
|
+
@dataset.order(:b){|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT * FROM test ORDER BY b, a, a(1, 2)'
|
985
|
+
@dataset.order(:b, :c){|o| [o.a, o.a(1, 2)]}.sql.should == 'SELECT * FROM test ORDER BY b, c, a, a(1, 2)'
|
986
|
+
end
|
937
987
|
end
|
938
988
|
|
939
989
|
context "Dataset#unfiltered" do
|
@@ -958,6 +1008,21 @@ context "Dataset#unordered" do
|
|
958
1008
|
end
|
959
1009
|
end
|
960
1010
|
|
1011
|
+
context "Dataset#with_sql" do
|
1012
|
+
setup do
|
1013
|
+
@dataset = Sequel::Dataset.new(nil).from(:test)
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
specify "should remove use static sql" do
|
1017
|
+
@dataset.with_sql('SELECT 1 FROM test').sql.should == 'SELECT 1 FROM test'
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
specify "should keep row_proc and transform" do
|
1021
|
+
@dataset.with_sql('SELECT 1 FROM test').row_proc.should == @dataset.row_proc
|
1022
|
+
@dataset.with_sql('SELECT 1 FROM test').instance_variable_get(:@transform).should == @dataset.instance_variable_get(:@transform)
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
|
961
1026
|
context "Dataset#order_by" do
|
962
1027
|
setup do
|
963
1028
|
@dataset = Sequel::Dataset.new(nil).from(:test)
|
@@ -1003,6 +1068,11 @@ context "Dataset#order_more" do
|
|
1003
1068
|
@dataset.order(:name).order_more(:stamp.desc).sql.should ==
|
1004
1069
|
'SELECT * FROM test ORDER BY name, stamp DESC'
|
1005
1070
|
end
|
1071
|
+
|
1072
|
+
specify "should accept a block that yields a virtual row" do
|
1073
|
+
@dataset.order(:a).order_more{|o| o.b}.sql.should == 'SELECT * FROM test ORDER BY a, b'
|
1074
|
+
@dataset.order(:a, :b).order_more(:c, :d){|o| [o.e, o.f(1, 2)]}.sql.should == 'SELECT * FROM test ORDER BY a, b, c, d, e, f(1, 2)'
|
1075
|
+
end
|
1006
1076
|
end
|
1007
1077
|
|
1008
1078
|
context "Dataset#reverse_order" do
|
@@ -1186,7 +1256,7 @@ context "Dataset#uniq" do
|
|
1186
1256
|
specify "should accept an expression list" do
|
1187
1257
|
@dataset.uniq(:a, :b).sql.should == 'SELECT DISTINCT ON (a, b) name FROM test'
|
1188
1258
|
|
1189
|
-
@dataset.uniq(:stamp.cast_as(:integer), :node_id=>nil).sql.should == 'SELECT DISTINCT ON (
|
1259
|
+
@dataset.uniq(:stamp.cast_as(:integer), :node_id=>nil).sql.should == 'SELECT DISTINCT ON (CAST(stamp AS integer), (node_id IS NULL)) name FROM test'
|
1190
1260
|
end
|
1191
1261
|
|
1192
1262
|
specify "should do a subselect for count" do
|
@@ -1961,6 +2031,15 @@ context "Dataset#get" do
|
|
1961
2031
|
specify "should work with aliased fields" do
|
1962
2032
|
@d.get(:x__b.as(:name)).should == "SELECT x.b AS name FROM test LIMIT 1"
|
1963
2033
|
end
|
2034
|
+
|
2035
|
+
specify "should accept a block that yields a virtual row" do
|
2036
|
+
@d.get{|o| o.x__b.as(:name)}.should == "SELECT x.b AS name FROM test LIMIT 1"
|
2037
|
+
@d.get{|o| o.x(1).as(:name)}.should == "SELECT x(1) AS name FROM test LIMIT 1"
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
specify "should raise an error if both a regular argument and block argument are used" do
|
2041
|
+
proc{@d.get(:name){|o| o.x__b.as(:name)}}.should raise_error(Sequel::Error)
|
2042
|
+
end
|
1964
2043
|
end
|
1965
2044
|
|
1966
2045
|
context "Dataset#set_row_proc" do
|
@@ -3396,32 +3475,3 @@ context "Sequel::Dataset#each" do
|
|
3396
3475
|
end
|
3397
3476
|
end
|
3398
3477
|
end
|
3399
|
-
|
3400
|
-
context Sequel::Dataset::UnsupportedIntersectExcept do
|
3401
|
-
before do
|
3402
|
-
@ds = Sequel::Dataset.new(nil).from(:items)
|
3403
|
-
@ds2 = Sequel::Dataset.new(nil).from(:i)
|
3404
|
-
@ds.extend(Sequel::Dataset::UnsupportedIntersectExcept)
|
3405
|
-
end
|
3406
|
-
|
3407
|
-
specify "should raise an error if INTERSECT or EXCEPT is USED" do
|
3408
|
-
@ds.union(@ds2).sql.should == 'SELECT * FROM items UNION SELECT * FROM i'
|
3409
|
-
proc{@ds.intersect(@ds2)}.should raise_error(Sequel::Error)
|
3410
|
-
proc{@ds.except(@ds2)}.should raise_error(Sequel::Error)
|
3411
|
-
end
|
3412
|
-
end
|
3413
|
-
|
3414
|
-
context Sequel::Dataset::UnsupportedIntersectExceptAll do
|
3415
|
-
before do
|
3416
|
-
@ds = Sequel::Dataset.new(nil).from(:items)
|
3417
|
-
@ds2 = Sequel::Dataset.new(nil).from(:i)
|
3418
|
-
@ds.extend(Sequel::Dataset::UnsupportedIntersectExceptAll)
|
3419
|
-
end
|
3420
|
-
|
3421
|
-
specify "should raise an error if INTERSECT or EXCEPT is USED" do
|
3422
|
-
@ds.intersect(@ds2).sql.should == 'SELECT * FROM items INTERSECT SELECT * FROM i'
|
3423
|
-
@ds.except(@ds2).sql.should == 'SELECT * FROM items EXCEPT SELECT * FROM i'
|
3424
|
-
proc{@ds.intersect(@ds2, true)}.should raise_error(Sequel::Error)
|
3425
|
-
proc{@ds.except(@ds2, true)}.should raise_error(Sequel::Error)
|
3426
|
-
end
|
3427
|
-
end
|
@@ -327,6 +327,22 @@ context "DB#create_table" do
|
|
327
327
|
@db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)", "CREATE INDEX cats_name_index ON cats (name)"]
|
328
328
|
end
|
329
329
|
|
330
|
+
specify "should accept functional indexes" do
|
331
|
+
@db.create_table(:cats) do
|
332
|
+
integer :id
|
333
|
+
index :lower.sql_function(:name)
|
334
|
+
end
|
335
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower_name__index ON cats (lower(name))"]
|
336
|
+
end
|
337
|
+
|
338
|
+
specify "should accept indexes with identifiers" do
|
339
|
+
@db.create_table(:cats) do
|
340
|
+
integer :id
|
341
|
+
index :lower__name.identifier
|
342
|
+
end
|
343
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower__name_index ON cats (lower__name)"]
|
344
|
+
end
|
345
|
+
|
330
346
|
specify "should accept custom index names" do
|
331
347
|
@db.create_table(:cats) do
|
332
348
|
integer :id
|
@@ -15,6 +15,34 @@ describe Sequel::Model, "associate" do
|
|
15
15
|
klass.association_reflection(:"par_parent1s").associated_class.should == ParParent
|
16
16
|
klass.association_reflection(:"par_parent2s").associated_class.should == ParParent
|
17
17
|
end
|
18
|
+
|
19
|
+
it "should add a model_object and association_reflection accessors to the dataset, and return it with the current model object" do
|
20
|
+
MODEL_DB.reset
|
21
|
+
klass = Class.new(Sequel::Model(:nodes)) do
|
22
|
+
columns :id, :a_id
|
23
|
+
end
|
24
|
+
mod = Module.new do
|
25
|
+
def blah
|
26
|
+
filter{|o| o.__send__(association_reflection[:key]) > model_object.id*2}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
klass.associate :many_to_one, :a, :class=>klass
|
31
|
+
klass.associate :one_to_many, :bs, :key=>:b_id, :class=>klass, :extend=>mod
|
32
|
+
klass.associate :many_to_many, :cs, :class=>klass
|
33
|
+
|
34
|
+
node = klass.load(:id=>1)
|
35
|
+
node.a_dataset.model_object.should == node
|
36
|
+
node.bs_dataset.model_object.should == node
|
37
|
+
node.cs_dataset.model_object.should == node
|
38
|
+
|
39
|
+
node.a_dataset.association_reflection.should == klass.association_reflection(:a)
|
40
|
+
node.bs_dataset.association_reflection.should == klass.association_reflection(:bs)
|
41
|
+
node.cs_dataset.association_reflection.should == klass.association_reflection(:cs)
|
42
|
+
|
43
|
+
node.bs_dataset.blah.sql.should == 'SELECT * FROM nodes WHERE ((nodes.b_id = 1) AND (b_id > 2))'
|
44
|
+
end
|
45
|
+
|
18
46
|
it "should allow extending the dataset with :extend option" do
|
19
47
|
MODEL_DB.reset
|
20
48
|
klass = Class.new(Sequel::Model(:nodes)) do
|
@@ -41,6 +69,34 @@ describe Sequel::Model, "associate" do
|
|
41
69
|
node.cs_dataset.blah.should == 1
|
42
70
|
node.cs_dataset.blar.should == 2
|
43
71
|
end
|
72
|
+
|
73
|
+
it "should clone an existing association with the :clone option" do
|
74
|
+
MODEL_DB.reset
|
75
|
+
klass = Class.new(Sequel::Model(:nodes))
|
76
|
+
|
77
|
+
klass.many_to_one(:par_parent, :order=>:a){1}
|
78
|
+
klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){4}
|
79
|
+
klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){2}
|
80
|
+
|
81
|
+
klass.many_to_one :par, :clone=>:par_parent, :select=>:b
|
82
|
+
klass.one_to_many :par1s, :clone=>:par_parent1s, :order=>:b, :limit=>10, :block=>nil
|
83
|
+
klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){3}
|
84
|
+
|
85
|
+
klass.association_reflection(:par).associated_class.should == ParParent
|
86
|
+
klass.association_reflection(:par1s).associated_class.should == ParParent
|
87
|
+
klass.association_reflection(:par2s).associated_class.should == ParParent
|
88
|
+
|
89
|
+
klass.association_reflection(:par)[:order].should == :a
|
90
|
+
klass.association_reflection(:par).select.should == :b
|
91
|
+
klass.association_reflection(:par)[:block].call.should == 1
|
92
|
+
klass.association_reflection(:par1s)[:limit].should == 10
|
93
|
+
klass.association_reflection(:par1s)[:order].should == :b
|
94
|
+
klass.association_reflection(:par1s)[:block].should == nil
|
95
|
+
klass.association_reflection(:par2s)[:after_load].length.should == 1
|
96
|
+
klass.association_reflection(:par2s)[:order].should == :c
|
97
|
+
klass.association_reflection(:par2s)[:block].call.should == 3
|
98
|
+
end
|
99
|
+
|
44
100
|
end
|
45
101
|
|
46
102
|
describe Sequel::Model, "many_to_one" do
|
@@ -117,6 +173,17 @@ describe Sequel::Model, "many_to_one" do
|
|
117
173
|
MODEL_DB.sqls.should == ["SELECT id, name FROM nodes WHERE (nodes.id = 567) LIMIT 1"]
|
118
174
|
end
|
119
175
|
|
176
|
+
it "should use :conditions option if given" do
|
177
|
+
@c2.many_to_one :parent, :class => @c2, :key => :blah, :conditions=>{:a=>32}
|
178
|
+
@c2.new(:id => 1, :blah => 567).parent
|
179
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 567) AND (a = 32)) LIMIT 1"]
|
180
|
+
|
181
|
+
@c2.many_to_one :parent, :class => @c2, :key => :blah, :conditions=>:a
|
182
|
+
MODEL_DB.sqls.clear
|
183
|
+
@c2.new(:id => 1, :blah => 567).parent
|
184
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 567) AND a) LIMIT 1"]
|
185
|
+
end
|
186
|
+
|
120
187
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
121
188
|
c2 = @c2
|
122
189
|
@c2.many_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{c2.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
@@ -594,6 +661,15 @@ describe Sequel::Model, "one_to_many" do
|
|
594
661
|
n.attributes_dataset.sql.should == "SELECT id, name FROM attributes WHERE (attributes.node_id = 1234)"
|
595
662
|
end
|
596
663
|
|
664
|
+
it "should support a conditions option" do
|
665
|
+
@c2.one_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
666
|
+
n = @c2.new(:id => 1234)
|
667
|
+
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (a = 32))"
|
668
|
+
@c2.one_to_many :attributes, :class => @c1, :conditions => ~:a
|
669
|
+
n = @c2.new(:id => 1234)
|
670
|
+
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND NOT a)"
|
671
|
+
end
|
672
|
+
|
597
673
|
it "should support an order option" do
|
598
674
|
@c2.one_to_many :attributes, :class => @c1, :order => :kind
|
599
675
|
|
@@ -1152,6 +1228,19 @@ describe Sequel::Model, "many_to_many" do
|
|
1152
1228
|
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attribute2node ON ((attribute2node.attributeid = attributes.id) AND (attribute2node.nodeid = 1234))'
|
1153
1229
|
end
|
1154
1230
|
|
1231
|
+
it "should support a conditions option" do
|
1232
|
+
@c2.many_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
1233
|
+
n = @c2.new(:id => 1234)
|
1234
|
+
a = n.attributes_dataset
|
1235
|
+
a.should be_a_kind_of(Sequel::Dataset)
|
1236
|
+
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
1237
|
+
@c2.many_to_many :attributes, :class => @c1, :conditions => ['a = ?', 32]
|
1238
|
+
n = @c2.new(:id => 1234)
|
1239
|
+
a = n.attributes_dataset
|
1240
|
+
a.should be_a_kind_of(Sequel::Dataset)
|
1241
|
+
a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (a = 32)'
|
1242
|
+
end
|
1243
|
+
|
1155
1244
|
it "should support an order option" do
|
1156
1245
|
@c2.many_to_many :attributes, :class => @c1, :order => :blah
|
1157
1246
|
|
@@ -417,3 +417,69 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
417
417
|
proc{@c.new(:z=>1)}.should_not raise_error
|
418
418
|
end
|
419
419
|
end
|
420
|
+
|
421
|
+
describe Sequel::Model, ".[] optimization" do
|
422
|
+
setup do
|
423
|
+
@c = Class.new(Sequel::Model(:a))
|
424
|
+
@c.instance_eval do
|
425
|
+
def simple_table
|
426
|
+
@simple_table
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
it "should set simple_pk to the literalized primary key column name if a single primary key" do
|
432
|
+
@c.simple_pk.should == 'id'
|
433
|
+
@c.set_primary_key :b
|
434
|
+
@c.simple_pk.should == 'b'
|
435
|
+
@c.set_primary_key :b__a.identifier
|
436
|
+
@c.simple_pk.should == 'b__a'
|
437
|
+
end
|
438
|
+
|
439
|
+
it "should have simple_pk be blank if compound or no primary key" do
|
440
|
+
@c.no_primary_key
|
441
|
+
@c.simple_pk.should == nil
|
442
|
+
@c.set_primary_key :b, :a
|
443
|
+
@c.simple_pk.should == nil
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should have simple table set if passed a Symbol to set_dataset" do
|
447
|
+
@c.set_dataset :a
|
448
|
+
@c.simple_table.should == 'a'
|
449
|
+
@c.set_dataset :b
|
450
|
+
@c.simple_table.should == 'b'
|
451
|
+
@c.set_dataset :b__a
|
452
|
+
@c.simple_table.should == 'b.a'
|
453
|
+
end
|
454
|
+
|
455
|
+
it "should have simple_table = nil if passed a dataset to set_dataset" do
|
456
|
+
@c.set_dataset @c.db[:a]
|
457
|
+
@c.simple_table.should == nil
|
458
|
+
end
|
459
|
+
|
460
|
+
it "should have simple_table superclasses setting if inheriting" do
|
461
|
+
@c.set_dataset :a
|
462
|
+
Class.new(@c).simple_table.should == 'a'
|
463
|
+
@c.instance_variable_set(:@simple_table, nil)
|
464
|
+
Class.new(@c).simple_table.should == nil
|
465
|
+
@c.instance_variable_set(:@simple_table, "'b'")
|
466
|
+
Class.new(@c).simple_table.should == "'b'"
|
467
|
+
end
|
468
|
+
|
469
|
+
it "should have simple_table = nil if inheriting and sti_key is set" do
|
470
|
+
@c.set_sti_key :x
|
471
|
+
Class.new(@c).simple_table.should == nil
|
472
|
+
end
|
473
|
+
|
474
|
+
it "should use Dataset#with_sql if simple_table and simple_pk are true" do
|
475
|
+
@c.set_dataset :a
|
476
|
+
@c.dataset.should_receive(:with_sql).and_return(@c.dataset)
|
477
|
+
@c[1]
|
478
|
+
end
|
479
|
+
|
480
|
+
it "should not use Dataset#with_sql if either simple_table or simple_pk is nil" do
|
481
|
+
@c.set_dataset @c.dataset
|
482
|
+
@c.dataset.should_not_receive(:with_sql)
|
483
|
+
@c[1]
|
484
|
+
end
|
485
|
+
end
|
@@ -328,6 +328,27 @@ describe Sequel::Model, "#eager" do
|
|
328
328
|
MODEL_DB.sqls.length.should == 2
|
329
329
|
end
|
330
330
|
|
331
|
+
it "should respect :conditions when eagerly loading" do
|
332
|
+
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
|
333
|
+
a = EagerBandMember.eager(:good_bands).all
|
334
|
+
a.should be_a_kind_of(Array)
|
335
|
+
a.size.should == 1
|
336
|
+
a.first.should be_a_kind_of(EagerBandMember)
|
337
|
+
a.first.values.should == {:id => 5}
|
338
|
+
MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (a = 32) ORDER BY id']
|
339
|
+
a = a.first
|
340
|
+
a.good_bands.should be_a_kind_of(Array)
|
341
|
+
a.good_bands.size.should == 1
|
342
|
+
a.good_bands.first.should be_a_kind_of(EagerBand)
|
343
|
+
a.good_bands.first.values.should == {:id => 2}
|
344
|
+
MODEL_DB.sqls.length.should == 2
|
345
|
+
|
346
|
+
MODEL_DB.sqls.clear
|
347
|
+
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
348
|
+
a = EagerBandMember.eager(:good_bands).all
|
349
|
+
MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (x = 1) ORDER BY id']
|
350
|
+
end
|
351
|
+
|
331
352
|
it "should respect :order when eagerly loading" do
|
332
353
|
a = EagerBandMember.eager(:bands).all
|
333
354
|
a.should be_a_kind_of(Array)
|
@@ -1019,6 +1040,17 @@ describe Sequel::Model, "#eager_graph" do
|
|
1019
1040
|
GraphAlbum.eager_graph(:inner_genres).sql.should == 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums INNER JOIN ag ON (ag.album_id = albums.id) RIGHT OUTER JOIN genres AS inner_genres ON (inner_genres.id = ag.genre_id)'
|
1020
1041
|
end
|
1021
1042
|
|
1043
|
+
it "should respect the association's :conditions option" do
|
1044
|
+
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :conditions=>{:active=>true}
|
1045
|
+
GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS active_band ON ((active_band.id = albums.band_id) AND (active_band.active = 't'))"
|
1046
|
+
|
1047
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}
|
1048
|
+
GraphAlbum.eager_graph(:right_tracks).sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND ((right_tracks.id >= 0) AND (right_tracks.id <= 100)))'
|
1049
|
+
|
1050
|
+
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :conditions=>{true=>:active}
|
1051
|
+
GraphAlbum.eager_graph(:active_genres).sql.should == "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres ON ((active_genres.id = ag.genre_id) AND ('t' = ag.active))"
|
1052
|
+
end
|
1053
|
+
|
1022
1054
|
it "should respect the association's :graph_conditions option" do
|
1023
1055
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_conditions=>{:active=>true}
|
1024
1056
|
GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS active_band ON ((active_band.id = albums.band_id) AND (active_band.active = 't'))"
|