sequel 2.10.0 → 2.11.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 +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'))"
|