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.
Files changed (78) hide show
  1. data/CHANGELOG +51 -1
  2. data/README.rdoc +2 -2
  3. data/Rakefile +2 -2
  4. data/doc/advanced_associations.rdoc +6 -18
  5. data/doc/release_notes/1.0.txt +38 -0
  6. data/doc/release_notes/1.1.txt +143 -0
  7. data/doc/release_notes/1.3.txt +101 -0
  8. data/doc/release_notes/1.4.0.txt +53 -0
  9. data/doc/release_notes/1.5.0.txt +155 -0
  10. data/doc/release_notes/2.0.0.txt +298 -0
  11. data/doc/release_notes/2.1.0.txt +271 -0
  12. data/doc/release_notes/2.10.0.txt +328 -0
  13. data/doc/release_notes/2.11.0.txt +215 -0
  14. data/doc/release_notes/2.2.0.txt +253 -0
  15. data/doc/release_notes/2.3.0.txt +88 -0
  16. data/doc/release_notes/2.4.0.txt +106 -0
  17. data/doc/release_notes/2.5.0.txt +137 -0
  18. data/doc/release_notes/2.6.0.txt +157 -0
  19. data/doc/release_notes/2.7.0.txt +166 -0
  20. data/doc/release_notes/2.8.0.txt +171 -0
  21. data/doc/release_notes/2.9.0.txt +97 -0
  22. data/lib/sequel_core/adapters/ado.rb +3 -0
  23. data/lib/sequel_core/adapters/db2.rb +0 -11
  24. data/lib/sequel_core/adapters/dbi.rb +0 -11
  25. data/lib/sequel_core/adapters/do.rb +0 -12
  26. data/lib/sequel_core/adapters/firebird.rb +21 -16
  27. data/lib/sequel_core/adapters/informix.rb +1 -11
  28. data/lib/sequel_core/adapters/jdbc.rb +1 -13
  29. data/lib/sequel_core/adapters/jdbc/h2.rb +3 -11
  30. data/lib/sequel_core/adapters/jdbc/mysql.rb +0 -17
  31. data/lib/sequel_core/adapters/jdbc/postgresql.rb +3 -15
  32. data/lib/sequel_core/adapters/mysql.rb +31 -27
  33. data/lib/sequel_core/adapters/odbc.rb +34 -28
  34. data/lib/sequel_core/adapters/openbase.rb +0 -11
  35. data/lib/sequel_core/adapters/oracle.rb +11 -9
  36. data/lib/sequel_core/adapters/postgres.rb +14 -17
  37. data/lib/sequel_core/adapters/shared/mssql.rb +6 -15
  38. data/lib/sequel_core/adapters/shared/mysql.rb +29 -14
  39. data/lib/sequel_core/adapters/shared/oracle.rb +4 -0
  40. data/lib/sequel_core/adapters/shared/postgres.rb +30 -35
  41. data/lib/sequel_core/adapters/shared/progress.rb +4 -0
  42. data/lib/sequel_core/adapters/shared/sqlite.rb +73 -13
  43. data/lib/sequel_core/adapters/sqlite.rb +8 -18
  44. data/lib/sequel_core/adapters/utils/date_format.rb +21 -0
  45. data/lib/sequel_core/{dataset → adapters/utils}/stored_procedures.rb +0 -0
  46. data/lib/sequel_core/{dataset → adapters/utils}/unsupported.rb +0 -0
  47. data/lib/sequel_core/core_ext.rb +1 -1
  48. data/lib/sequel_core/core_sql.rb +9 -4
  49. data/lib/sequel_core/database.rb +63 -62
  50. data/lib/sequel_core/dataset.rb +9 -4
  51. data/lib/sequel_core/dataset/convenience.rb +10 -9
  52. data/lib/sequel_core/dataset/prepared_statements.rb +1 -1
  53. data/lib/sequel_core/dataset/sql.rb +130 -36
  54. data/lib/sequel_core/schema/sql.rb +2 -2
  55. data/lib/sequel_core/sql.rb +44 -51
  56. data/lib/sequel_core/version.rb +1 -1
  57. data/lib/sequel_model/associations.rb +25 -17
  58. data/lib/sequel_model/base.rb +35 -7
  59. data/lib/sequel_model/caching.rb +1 -6
  60. data/lib/sequel_model/record.rb +23 -5
  61. data/lib/sequel_model/validations.rb +20 -5
  62. data/spec/adapters/firebird_spec.rb +6 -1
  63. data/spec/adapters/mysql_spec.rb +12 -0
  64. data/spec/adapters/postgres_spec.rb +2 -2
  65. data/spec/adapters/sqlite_spec.rb +81 -2
  66. data/spec/integration/dataset_test.rb +2 -2
  67. data/spec/integration/type_test.rb +12 -2
  68. data/spec/sequel_core/core_sql_spec.rb +46 -12
  69. data/spec/sequel_core/database_spec.rb +24 -12
  70. data/spec/sequel_core/dataset_spec.rb +82 -32
  71. data/spec/sequel_core/schema_spec.rb +16 -0
  72. data/spec/sequel_model/associations_spec.rb +89 -0
  73. data/spec/sequel_model/base_spec.rb +66 -0
  74. data/spec/sequel_model/eager_loading_spec.rb +32 -0
  75. data/spec/sequel_model/record_spec.rb +9 -9
  76. data/spec/sequel_model/spec_helper.rb +3 -0
  77. data/spec/sequel_model/validations_spec.rb +63 -3
  78. 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("TIMESTAMP '%Y-%m-%d %H:%M:%S'")
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("DATE '%Y-%m-%d'")
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 (cast(stamp AS integer), (node_id IS NULL)) name FROM test'
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'))"