sequel 3.28.0 → 3.29.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 (148) hide show
  1. data/CHANGELOG +119 -3
  2. data/Rakefile +5 -3
  3. data/bin/sequel +1 -5
  4. data/doc/model_hooks.rdoc +9 -1
  5. data/doc/opening_databases.rdoc +49 -40
  6. data/doc/prepared_statements.rdoc +27 -6
  7. data/doc/release_notes/3.28.0.txt +2 -2
  8. data/doc/release_notes/3.29.0.txt +459 -0
  9. data/doc/sharding.rdoc +7 -1
  10. data/doc/testing.rdoc +18 -9
  11. data/doc/transactions.rdoc +41 -1
  12. data/lib/sequel/adapters/ado.rb +28 -17
  13. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  14. data/lib/sequel/adapters/amalgalite.rb +11 -7
  15. data/lib/sequel/adapters/db2.rb +122 -70
  16. data/lib/sequel/adapters/dbi.rb +15 -15
  17. data/lib/sequel/adapters/do.rb +5 -36
  18. data/lib/sequel/adapters/do/mysql.rb +0 -5
  19. data/lib/sequel/adapters/do/postgres.rb +0 -5
  20. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  21. data/lib/sequel/adapters/firebird.rb +3 -6
  22. data/lib/sequel/adapters/ibmdb.rb +24 -16
  23. data/lib/sequel/adapters/informix.rb +2 -4
  24. data/lib/sequel/adapters/jdbc.rb +47 -11
  25. data/lib/sequel/adapters/jdbc/as400.rb +5 -24
  26. data/lib/sequel/adapters/jdbc/db2.rb +0 -5
  27. data/lib/sequel/adapters/jdbc/derby.rb +217 -0
  28. data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
  29. data/lib/sequel/adapters/jdbc/h2.rb +10 -12
  30. data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
  31. data/lib/sequel/adapters/jdbc/informix.rb +0 -5
  32. data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
  34. data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
  36. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
  38. data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
  39. data/lib/sequel/adapters/mock.rb +315 -0
  40. data/lib/sequel/adapters/mysql.rb +64 -51
  41. data/lib/sequel/adapters/mysql2.rb +15 -9
  42. data/lib/sequel/adapters/odbc.rb +13 -6
  43. data/lib/sequel/adapters/odbc/db2.rb +0 -4
  44. data/lib/sequel/adapters/odbc/mssql.rb +0 -5
  45. data/lib/sequel/adapters/openbase.rb +2 -4
  46. data/lib/sequel/adapters/oracle.rb +333 -51
  47. data/lib/sequel/adapters/postgres.rb +80 -27
  48. data/lib/sequel/adapters/shared/access.rb +0 -6
  49. data/lib/sequel/adapters/shared/db2.rb +13 -15
  50. data/lib/sequel/adapters/shared/firebird.rb +6 -6
  51. data/lib/sequel/adapters/shared/mssql.rb +23 -18
  52. data/lib/sequel/adapters/shared/mysql.rb +6 -6
  53. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
  54. data/lib/sequel/adapters/shared/oracle.rb +185 -30
  55. data/lib/sequel/adapters/shared/postgres.rb +35 -18
  56. data/lib/sequel/adapters/shared/progress.rb +0 -6
  57. data/lib/sequel/adapters/shared/sqlite.rb +116 -37
  58. data/lib/sequel/adapters/sqlite.rb +16 -8
  59. data/lib/sequel/adapters/swift.rb +5 -5
  60. data/lib/sequel/adapters/swift/mysql.rb +0 -5
  61. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  62. data/lib/sequel/adapters/swift/sqlite.rb +6 -4
  63. data/lib/sequel/adapters/tinytds.rb +13 -10
  64. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
  65. data/lib/sequel/core.rb +40 -0
  66. data/lib/sequel/database/connecting.rb +1 -2
  67. data/lib/sequel/database/dataset.rb +3 -3
  68. data/lib/sequel/database/dataset_defaults.rb +58 -0
  69. data/lib/sequel/database/misc.rb +62 -2
  70. data/lib/sequel/database/query.rb +113 -49
  71. data/lib/sequel/database/schema_methods.rb +7 -2
  72. data/lib/sequel/dataset/actions.rb +37 -19
  73. data/lib/sequel/dataset/features.rb +24 -0
  74. data/lib/sequel/dataset/graph.rb +7 -6
  75. data/lib/sequel/dataset/misc.rb +11 -3
  76. data/lib/sequel/dataset/mutation.rb +2 -3
  77. data/lib/sequel/dataset/prepared_statements.rb +6 -4
  78. data/lib/sequel/dataset/query.rb +46 -15
  79. data/lib/sequel/dataset/sql.rb +28 -4
  80. data/lib/sequel/extensions/named_timezones.rb +5 -0
  81. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  82. data/lib/sequel/model.rb +2 -1
  83. data/lib/sequel/model/associations.rb +115 -33
  84. data/lib/sequel/model/base.rb +91 -31
  85. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  86. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  87. data/lib/sequel/plugins/force_encoding.rb +6 -6
  88. data/lib/sequel/plugins/identity_map.rb +1 -1
  89. data/lib/sequel/plugins/many_through_many.rb +6 -10
  90. data/lib/sequel/plugins/prepared_statements.rb +12 -1
  91. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
  92. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  93. data/lib/sequel/plugins/serialization.rb +6 -1
  94. data/lib/sequel/plugins/sharding.rb +0 -5
  95. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  96. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  97. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  98. data/lib/sequel/timezones.rb +42 -42
  99. data/lib/sequel/version.rb +1 -1
  100. data/spec/adapters/mssql_spec.rb +29 -29
  101. data/spec/adapters/mysql_spec.rb +86 -104
  102. data/spec/adapters/oracle_spec.rb +48 -76
  103. data/spec/adapters/postgres_spec.rb +98 -33
  104. data/spec/adapters/spec_helper.rb +0 -5
  105. data/spec/adapters/sqlite_spec.rb +24 -21
  106. data/spec/core/connection_pool_spec.rb +9 -15
  107. data/spec/core/core_sql_spec.rb +20 -31
  108. data/spec/core/database_spec.rb +491 -227
  109. data/spec/core/dataset_spec.rb +638 -1051
  110. data/spec/core/expression_filters_spec.rb +0 -1
  111. data/spec/core/mock_adapter_spec.rb +378 -0
  112. data/spec/core/object_graph_spec.rb +48 -114
  113. data/spec/core/schema_generator_spec.rb +3 -3
  114. data/spec/core/schema_spec.rb +51 -114
  115. data/spec/core/spec_helper.rb +3 -90
  116. data/spec/extensions/class_table_inheritance_spec.rb +1 -1
  117. data/spec/extensions/dataset_associations_spec.rb +199 -0
  118. data/spec/extensions/instance_hooks_spec.rb +71 -0
  119. data/spec/extensions/named_timezones_spec.rb +22 -2
  120. data/spec/extensions/nested_attributes_spec.rb +3 -0
  121. data/spec/extensions/schema_spec.rb +1 -1
  122. data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
  123. data/spec/extensions/serialization_spec.rb +5 -8
  124. data/spec/extensions/spec_helper.rb +4 -0
  125. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  126. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  127. data/spec/integration/associations_test.rb +123 -12
  128. data/spec/integration/dataset_test.rb +140 -47
  129. data/spec/integration/eager_loader_test.rb +19 -21
  130. data/spec/integration/model_test.rb +80 -1
  131. data/spec/integration/plugin_test.rb +179 -128
  132. data/spec/integration/prepared_statement_test.rb +92 -91
  133. data/spec/integration/schema_test.rb +42 -23
  134. data/spec/integration/spec_helper.rb +25 -31
  135. data/spec/integration/timezone_test.rb +38 -12
  136. data/spec/integration/transaction_test.rb +161 -34
  137. data/spec/integration/type_test.rb +3 -3
  138. data/spec/model/association_reflection_spec.rb +83 -7
  139. data/spec/model/associations_spec.rb +393 -676
  140. data/spec/model/base_spec.rb +186 -116
  141. data/spec/model/dataset_methods_spec.rb +7 -27
  142. data/spec/model/eager_loading_spec.rb +343 -867
  143. data/spec/model/hooks_spec.rb +160 -79
  144. data/spec/model/model_spec.rb +118 -165
  145. data/spec/model/plugins_spec.rb +7 -13
  146. data/spec/model/record_spec.rb +138 -207
  147. data/spec/model/spec_helper.rb +10 -73
  148. metadata +14 -8
@@ -5,219 +5,220 @@ describe "Prepared Statements and Bound Arguments" do
5
5
  @db = INTEGRATION_DB
6
6
  @db.create_table!(:items) do
7
7
  primary_key :id
8
- integer :number
8
+ integer :numb
9
9
  end
10
10
  @c = Class.new(Sequel::Model(:items))
11
11
  @ds = @db[:items]
12
- @ds.insert(:number=>10)
12
+ @ds.insert(:numb=>10)
13
+ @pr = @ds.requires_placeholder_type_specifiers? ? proc{|i| :"#{i}__integer"} : proc{|i| i}
13
14
  end
14
15
  after do
15
16
  @db.drop_table(:items)
16
17
  end
17
18
 
18
19
  specify "should support bound variables with select, all, and first" do
19
- @ds.filter(:number=>:$n).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
20
- @ds.filter(:number=>:$n).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
21
- @ds.filter(:number=>:$n).call(:first, :n=>10).should == {:id=>1, :number=>10}
20
+ @ds.filter(:numb=>:$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
21
+ @ds.filter(:numb=>:$n).call(:all, :n=>10).should == [{:id=>1, :numb=>10}]
22
+ @ds.filter(:numb=>:$n).call(:first, :n=>10).should == {:id=>1, :numb=>10}
22
23
  end
23
24
 
24
25
  specify "should support blocks for select and all" do
25
- @ds.filter(:number=>:$n).call(:select, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
26
- @ds.filter(:number=>:$n).call(:all, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
26
+ @ds.filter(:numb=>:$n).call(:select, :n=>10){|r| r[:numb] *= 2}.should == [{:id=>1, :numb=>20}]
27
+ @ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.should == [{:id=>1, :numb=>20}]
27
28
  end
28
29
 
29
30
  specify "should support binding variables before the call with #bind" do
30
- @ds.filter(:number=>:$n).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
31
- @ds.filter(:number=>:$n).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
32
- @ds.filter(:number=>:$n).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
31
+ @ds.filter(:numb=>:$n).bind(:n=>10).call(:select).should == [{:id=>1, :numb=>10}]
32
+ @ds.filter(:numb=>:$n).bind(:n=>10).call(:all).should == [{:id=>1, :numb=>10}]
33
+ @ds.filter(:numb=>:$n).bind(:n=>10).call(:first).should == {:id=>1, :numb=>10}
33
34
 
34
- @ds.bind(:n=>10).filter(:number=>:$n).call(:select).should == [{:id=>1, :number=>10}]
35
- @ds.bind(:n=>10).filter(:number=>:$n).call(:all).should == [{:id=>1, :number=>10}]
36
- @ds.bind(:n=>10).filter(:number=>:$n).call(:first).should == {:id=>1, :number=>10}
35
+ @ds.bind(:n=>10).filter(:numb=>:$n).call(:select).should == [{:id=>1, :numb=>10}]
36
+ @ds.bind(:n=>10).filter(:numb=>:$n).call(:all).should == [{:id=>1, :numb=>10}]
37
+ @ds.bind(:n=>10).filter(:numb=>:$n).call(:first).should == {:id=>1, :numb=>10}
37
38
  end
38
39
 
39
40
  specify "should allow overriding variables specified with #bind" do
40
- @ds.filter(:number=>:$n).bind(:n=>1).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
41
- @ds.filter(:number=>:$n).bind(:n=>1).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
42
- @ds.filter(:number=>:$n).bind(:n=>1).call(:first, :n=>10).should == {:id=>1, :number=>10}
41
+ @ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
42
+ @ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).should == [{:id=>1, :numb=>10}]
43
+ @ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).should == {:id=>1, :numb=>10}
43
44
 
44
- @ds.filter(:number=>:$n).bind(:n=>1).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
45
- @ds.filter(:number=>:$n).bind(:n=>1).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
46
- @ds.filter(:number=>:$n).bind(:n=>1).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
45
+ @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).should == [{:id=>1, :numb=>10}]
46
+ @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).should == [{:id=>1, :numb=>10}]
47
+ @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).should == {:id=>1, :numb=>10}
47
48
  end
48
49
 
49
50
  specify "should support placeholder literal strings with call" do
50
- @ds.filter("number = ?", :$n).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
51
+ @ds.filter("numb = ?", :$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
51
52
  end
52
53
 
53
54
  specify "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
54
- @ds.filter("number = :n", :n=>:$n).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
55
- @ds.insert(:number=>20)
56
- @ds.insert(:number=>30)
57
- @ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
55
+ @ds.filter("numb = :n", :n=>:$n).call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
56
+ @ds.insert(:numb=>20)
57
+ @ds.insert(:numb=>30)
58
+ @ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :numb=>20}]
58
59
  end
59
60
 
60
61
  specify "should support datasets with static sql and placeholders with call" do
61
- @db["SELECT * FROM items WHERE number = ?", :$n].call(:select, :n=>10).should == [{:id=>1, :number=>10}]
62
+ @db["SELECT * FROM items WHERE numb = ?", :$n].call(:select, :n=>10).should == [{:id=>1, :numb=>10}]
62
63
  end
63
64
 
64
65
  specify "should support subselects with call" do
65
- @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>:$n)).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
66
+ @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
66
67
  end
67
68
 
68
69
  specify "should support subselects with literal strings with call" do
69
- @ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", :$n)).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
70
+ @ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).call(:select, :n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
70
71
  end
71
72
 
72
73
  specify "should support subselects with static sql and placeholders with call" do
73
- @ds.filter(:id=>:$i, :number=>@db["SELECT number FROM items WHERE number = ?", :$n]).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
74
+ @ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).call(:select, :n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
74
75
  end
75
76
 
76
77
  specify "should support subselects of subselects with call" do
77
- @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
78
+ @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
78
79
  end
79
80
 
80
81
  cspecify "should support using a bound variable for a limit and offset", [:jdbc, :db2] do
81
- @ds.insert(:number=>20)
82
+ @ds.insert(:numb=>20)
82
83
  ds = @ds.limit(:$n, :$n2).order(:id)
83
- ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
84
- ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
84
+ ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :numb=>10}]
85
+ ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :numb=>20}]
85
86
  ds.call(:select, :n=>1, :n2=>2).should == []
86
- ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
87
- ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
87
+ ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
88
+ ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :numb=>20}]
88
89
  end
89
90
 
90
91
  specify "should support bound variables with insert" do
91
- @ds.call(:insert, {:n=>20}, :number=>:$n)
92
+ @ds.call(:insert, {:n=>20}, :numb=>:$n)
92
93
  @ds.count.should == 2
93
- @ds.order(:id).map(:number).should == [10, 20]
94
+ @ds.order(:id).map(:numb).should == [10, 20]
94
95
  end
95
96
 
96
97
  specify "should support bound variables with NULL values" do
97
98
  @ds.delete
98
- @ds.call(:insert, {:n=>nil}, :number=>:$n)
99
+ @ds.call(:insert, {:n=>nil}, :numb=>@pr[:$n])
99
100
  @ds.count.should == 1
100
- @ds.map(:number).should == [nil]
101
+ @ds.map(:numb).should == [nil]
101
102
  end
102
103
 
103
104
  specify "should have insert return primary key value when using bound arguments" do
104
- @ds.call(:insert, {:n=>20}, :number=>:$n).should == 2
105
- @ds.filter(:id=>2).first[:number].should == 20
105
+ @ds.call(:insert, {:n=>20}, :numb=>:$n).should == 2
106
+ @ds.filter(:id=>2).first[:numb].should == 20
106
107
  end
107
108
 
108
109
  specify "should support bound variables with delete" do
109
- @ds.filter(:number=>:$n).call(:delete, :n=>10).should == 1
110
+ @ds.filter(:numb=>:$n).call(:delete, :n=>10).should == 1
110
111
  @ds.count.should == 0
111
112
  end
112
113
 
113
114
  specify "should support bound variables with update" do
114
- @ds.filter(:number=>:$n).call(:update, {:n=>10, :nn=>20}, :number=>:number+:$nn).should == 1
115
- @ds.all.should == [{:id=>1, :number=>30}]
115
+ @ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb=>:numb+:$nn).should == 1
116
+ @ds.all.should == [{:id=>1, :numb=>30}]
116
117
  end
117
118
 
118
119
  specify "should support prepared statements with select, first, and all" do
119
- @ds.filter(:number=>:$n).prepare(:select, :select_n)
120
- @db.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
121
- @ds.filter(:number=>:$n).prepare(:all, :select_n)
122
- @db.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
123
- @ds.filter(:number=>:$n).prepare(:first, :select_n)
124
- @db.call(:select_n, :n=>10).should == {:id=>1, :number=>10}
120
+ @ds.filter(:numb=>:$n).prepare(:select, :select_n)
121
+ @db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
122
+ @ds.filter(:numb=>:$n).prepare(:all, :select_n)
123
+ @db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
124
+ @ds.filter(:numb=>:$n).prepare(:first, :select_n)
125
+ @db.call(:select_n, :n=>10).should == {:id=>1, :numb=>10}
125
126
  end
126
127
 
127
128
  specify "should support prepared statements being call multiple times with different arguments" do
128
- @ds.filter(:number=>:$n).prepare(:select, :select_n)
129
- @db.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
129
+ @ds.filter(:numb=>:$n).prepare(:select, :select_n)
130
+ @db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
130
131
  @db.call(:select_n, :n=>0).should == []
131
- @db.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
132
+ @db.call(:select_n, :n=>10).should == [{:id=>1, :numb=>10}]
132
133
  end
133
134
 
134
135
  specify "should support placeholder literal strings with prepare" do
135
- @ds.filter("number = ?", :$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
136
+ @ds.filter("numb = ?", :$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
136
137
  end
137
138
 
138
139
  specify "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
139
- @ds.filter("number = :n", :n=>:$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
140
- @ds.insert(:number=>20)
141
- @ds.insert(:number=>30)
142
- @ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
140
+ @ds.filter("numb = :n", :n=>:$n).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
141
+ @ds.insert(:numb=>20)
142
+ @ds.insert(:numb=>30)
143
+ @ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :numb=>20}]
143
144
  end
144
145
 
145
146
  specify "should support datasets with static sql and placeholders with prepare" do
146
- @db["SELECT * FROM items WHERE number = ?", :$n].prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
147
+ @db["SELECT * FROM items WHERE numb = ?", :$n].prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :numb=>10}]
147
148
  end
148
149
 
149
150
  specify "should support subselects with prepare" do
150
- @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>:$n)).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
151
+ @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
151
152
  end
152
153
 
153
154
  specify "should support subselects with literal strings with prepare" do
154
- @ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", :$n)).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
155
+ @ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
155
156
  end
156
157
 
157
158
  specify "should support subselects with static sql and placeholders with prepare" do
158
- @ds.filter(:id=>:$i, :number=>@db["SELECT number FROM items WHERE number = ?", :$n]).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
159
+ @ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :numb=>10}]
159
160
  end
160
161
 
161
162
  specify "should support subselects of subselects with prepare" do
162
- @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
163
+ @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :numb=>10}]
163
164
  end
164
165
 
165
166
  cspecify "should support using a prepared_statement for a limit and offset", :db2 do
166
- @ds.insert(:number=>20)
167
+ @ds.insert(:numb=>20)
167
168
  ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
168
- ps.call(:n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
169
- ps.call(:n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
169
+ ps.call(:n=>1, :n2=>0).should == [{:id=>1, :numb=>10}]
170
+ ps.call(:n=>1, :n2=>1).should == [{:id=>2, :numb=>20}]
170
171
  ps.call(:n=>1, :n2=>2).should == []
171
- ps.call(:n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
172
- ps.call(:n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
172
+ ps.call(:n=>2, :n2=>0).should == [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
173
+ ps.call(:n=>2, :n2=>1).should == [{:id=>2, :numb=>20}]
173
174
  end
174
175
 
175
176
  specify "should support prepared statements with insert" do
176
- @ds.prepare(:insert, :insert_n, :number=>:$n)
177
+ @ds.prepare(:insert, :insert_n, :numb=>:$n)
177
178
  @db.call(:insert_n, :n=>20)
178
179
  @ds.count.should == 2
179
- @ds.order(:id).map(:number).should == [10, 20]
180
+ @ds.order(:id).map(:numb).should == [10, 20]
180
181
  end
181
182
 
182
183
  specify "should support prepared statements with NULL values" do
183
184
  @ds.delete
184
- @ds.prepare(:insert, :insert_n, :number=>:$n)
185
+ @ds.prepare(:insert, :insert_n, :numb=>@pr[:$n])
185
186
  @db.call(:insert_n, :n=>nil)
186
187
  @ds.count.should == 1
187
- @ds.map(:number).should == [nil]
188
+ @ds.map(:numb).should == [nil]
188
189
  end
189
190
 
190
191
  specify "should have insert return primary key value when using prepared statements" do
191
- @ds.prepare(:insert, :insert_n, :number=>:$n)
192
+ @ds.prepare(:insert, :insert_n, :numb=>:$n)
192
193
  @db.call(:insert_n, :n=>20).should == 2
193
- @ds.filter(:id=>2).first[:number].should == 20
194
+ @ds.filter(:id=>2).first[:numb].should == 20
194
195
  end
195
196
 
196
197
  specify "should support prepared statements with delete" do
197
- @ds.filter(:number=>:$n).prepare(:delete, :delete_n)
198
+ @ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
198
199
  @db.call(:delete_n, :n=>10).should == 1
199
200
  @ds.count.should == 0
200
201
  end
201
202
 
202
203
  specify "should support prepared statements with update" do
203
- @ds.filter(:number=>:$n).prepare(:update, :update_n, :number=>:number+:$nn)
204
+ @ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb=>:numb+:$nn)
204
205
  @db.call(:update_n, :n=>10, :nn=>20).should == 1
205
- @ds.all.should == [{:id=>1, :number=>30}]
206
+ @ds.all.should == [{:id=>1, :numb=>30}]
206
207
  end
207
208
 
208
209
  specify "model datasets should return model instances when using select, all, and first with bound variables" do
209
- @c.filter(:number=>:$n).call(:select, :n=>10).should == [@c.load(:id=>1, :number=>10)]
210
- @c.filter(:number=>:$n).call(:all, :n=>10).should == [@c.load(:id=>1, :number=>10)]
211
- @c.filter(:number=>:$n).call(:first, :n=>10).should == @c.load(:id=>1, :number=>10)
210
+ @c.filter(:numb=>:$n).call(:select, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
211
+ @c.filter(:numb=>:$n).call(:all, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
212
+ @c.filter(:numb=>:$n).call(:first, :n=>10).should == @c.load(:id=>1, :numb=>10)
212
213
  end
213
214
 
214
215
  specify "model datasets should return model instances when using select, all, and first with prepared statements" do
215
- @c.filter(:number=>:$n).prepare(:select, :select_n)
216
- @db.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
217
- @c.filter(:number=>:$n).prepare(:all, :select_n)
218
- @db.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
219
- @c.filter(:number=>:$n).prepare(:first, :select_n)
220
- @db.call(:select_n, :n=>10).should == @c.load(:id=>1, :number=>10)
216
+ @c.filter(:numb=>:$n).prepare(:select, :select_n1)
217
+ @db.call(:select_n1, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
218
+ @c.filter(:numb=>:$n).prepare(:all, :select_n1)
219
+ @db.call(:select_n1, :n=>10).should == [@c.load(:id=>1, :numb=>10)]
220
+ @c.filter(:numb=>:$n).prepare(:first, :select_n1)
221
+ @db.call(:select_n1, :n=>10).should == @c.load(:id=>1, :numb=>10)
221
222
  end
222
223
  end
223
224
 
@@ -246,11 +247,11 @@ describe "Bound Argument Types" do
246
247
  @db.drop_table(:items)
247
248
  end
248
249
 
249
- cspecify "should handle date type", [:do, :sqlite], :mssql, [:jdbc, :sqlite] do
250
+ cspecify "should handle date type", [:do, :sqlite], :mssql, [:jdbc, :sqlite], :oracle do
250
251
  @ds.filter(:d=>:$x).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].should == @vs[:d]
251
252
  end
252
253
 
253
- cspecify "should handle datetime type", [:do], [:mysql2], [:swift], [:jdbc, :sqlite], [:tinytds] do
254
+ cspecify "should handle datetime type", [:do], [:mysql2], [:swift], [:jdbc, :sqlite], [:tinytds], [:oracle] do
254
255
  Sequel.datetime_class = DateTime
255
256
  @ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].should == @vs[:dt]
256
257
  end
@@ -259,7 +260,7 @@ describe "Bound Argument Types" do
259
260
  @ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
260
261
  end
261
262
 
262
- cspecify "should handle blob type", [:swift], [:odbc], [:jdbc, :db2] do
263
+ cspecify "should handle blob type", [:swift], [:odbc], [:jdbc, :db2], :oracle, :derby do
263
264
  @ds.filter(:file=>:$x).prepare(:first, :ps_blob).call(:x=>@vs[:file])[:file].should == @vs[:file]
264
265
  end
265
266
 
@@ -271,10 +272,10 @@ describe "Bound Argument Types" do
271
272
  @ds.filter(:s=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].should == @vs[:s]
272
273
  end
273
274
 
274
- cspecify "should handle boolean type", [:do, :sqlite], [:odbc, :mssql], [:jdbc, :sqlite], [:jdbc, :db2] do
275
+ cspecify "should handle boolean type", [:do, :sqlite], [:odbc, :mssql], [:jdbc, :sqlite], [:jdbc, :db2], :oracle do
275
276
  @ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].should == @vs[:b]
276
277
  end
277
- end unless INTEGRATION_DB.adapter_scheme == :swift && INTEGRATION_DB.database_type == :postgres
278
+ end unless Sequel.guarded?([:swift, :postgres])
278
279
 
279
280
  describe "Dataset#unbind" do
280
281
  before do
@@ -316,7 +317,7 @@ describe "Dataset#unbind" do
316
317
  @u[@ds.filter{c > 0}].should == {:c=>BigDecimal.new('1.1')}
317
318
  end
318
319
 
319
- cspecify "should handle dates and times", [:sqlite], [:do], [:jdbc, :mssql], [:tinytds] do
320
+ cspecify "should handle dates and times", [:do], [:jdbc, :mssql], [:jdbc, :sqlite], [:tinytds], :oracle do
320
321
  @ct[Date, Date.today]
321
322
  @u[@ds.filter(:c=>Date.today)].should == {:c=>Date.today}
322
323
  t = Time.now
@@ -7,7 +7,6 @@ describe "Database schema parser" do
7
7
  @iim = INTEGRATION_DB.identifier_input_method
8
8
  @defsch = INTEGRATION_DB.default_schema
9
9
  @qi = INTEGRATION_DB.quote_identifiers?
10
- clear_sqls
11
10
  end
12
11
  after do
13
12
  INTEGRATION_DB.identifier_output_method = @iom
@@ -17,22 +16,45 @@ describe "Database schema parser" do
17
16
  INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
18
17
  end
19
18
 
20
- specify "should handle a database with a identifier_output_method" do
19
+ specify "should handle a database with a identifier methods" do
21
20
  INTEGRATION_DB.identifier_output_method = :reverse
22
21
  INTEGRATION_DB.identifier_input_method = :reverse
23
22
  INTEGRATION_DB.quote_identifiers = true
24
23
  INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
25
24
  INTEGRATION_DB.create_table!(:items){Integer :number}
26
- INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
27
- INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
25
+ begin
26
+ INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
27
+ INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
28
+ ensure
29
+ INTEGRATION_DB.drop_table(:items)
30
+ end
31
+ end
32
+
33
+ specify "should handle a dataset with identifier methods different than the database's" do
34
+ INTEGRATION_DB.identifier_output_method = :reverse
35
+ INTEGRATION_DB.identifier_input_method = :reverse
36
+ INTEGRATION_DB.quote_identifiers = true
37
+ INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
38
+ INTEGRATION_DB.create_table!(:items){Integer :number}
39
+ INTEGRATION_DB.identifier_output_method = @iom
40
+ INTEGRATION_DB.identifier_input_method = @iim
41
+ ds = INTEGRATION_DB[:items]
42
+ ds.identifier_output_method = :reverse
43
+ ds.identifier_input_method = :reverse
44
+ begin
45
+ INTEGRATION_DB.schema(ds, :reload=>true).should be_a_kind_of(Array)
46
+ INTEGRATION_DB.schema(ds, :reload=>true).first.first.should == :number
47
+ ensure
48
+ INTEGRATION_DB.identifier_output_method = :reverse
49
+ INTEGRATION_DB.identifier_input_method = :reverse
50
+ INTEGRATION_DB.drop_table(:items)
51
+ end
28
52
  end
29
53
 
30
54
  specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
31
55
  INTEGRATION_DB.create_table!(:items){Integer :number}
32
56
  INTEGRATION_DB.schema(:items, :reload=>true)
33
- clear_sqls
34
57
  INTEGRATION_DB.schema(:items)
35
- clear_sqls
36
58
  INTEGRATION_DB.schema(:items, :reload=>true)
37
59
  end
38
60
 
@@ -59,11 +81,10 @@ describe "Database schema parser" do
59
81
  col_info = col.last
60
82
  col_info.should be_a_kind_of(Hash)
61
83
  col_info[:type].should == :integer
62
- clear_sqls
63
84
  INTEGRATION_DB.schema(:items)
64
85
  end
65
86
 
66
- cspecify "should parse primary keys from the schema properly", [proc{|db| db.adapter_scheme != :jdbc}, :mssql] do
87
+ specify "should parse primary keys from the schema properly" do
67
88
  INTEGRATION_DB.create_table!(:items){Integer :number}
68
89
  INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
69
90
  INTEGRATION_DB.create_table!(:items){primary_key :number}
@@ -88,7 +109,7 @@ describe "Database schema parser" do
88
109
  INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
89
110
  end
90
111
 
91
- cspecify "should parse types from the schema properly", [:jdbc, :db2] do
112
+ cspecify "should parse types from the schema properly", [:jdbc, :db2], :oracle do
92
113
  INTEGRATION_DB.create_table!(:items){Integer :number}
93
114
  INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
94
115
  INTEGRATION_DB.create_table!(:items){Fixnum :number}
@@ -159,7 +180,6 @@ describe "Database schema modifiers" do
159
180
  before do
160
181
  @db = INTEGRATION_DB
161
182
  @ds = @db[:items]
162
- clear_sqls
163
183
  end
164
184
  after do
165
185
  @db.drop_table(:items) if @db.table_exists?(:items)
@@ -242,7 +262,7 @@ describe "Database schema modifiers" do
242
262
  @ds.all.should == [{:number=>10, :name=>nil}]
243
263
  end
244
264
 
245
- cspecify "should add primary key columns to tables correctly", :h2 do
265
+ cspecify "should add primary key columns to tables correctly", :h2, :derby do
246
266
  @db.create_table!(:items){Integer :number}
247
267
  @ds.insert(:number=>10)
248
268
  @db.alter_table(:items){add_primary_key :id}
@@ -252,7 +272,7 @@ describe "Database schema modifiers" do
252
272
  proc{@ds.insert(:id=>@ds.map(:id).first)}.should raise_error
253
273
  end
254
274
 
255
- cspecify "should drop primary key constraints from tables correctly", :sqlite do
275
+ specify "should drop primary key constraints from tables correctly" do
256
276
  @db.create_table!(:items){Integer :number; primary_key [:number], :name=>:items_pk}
257
277
  @ds.insert(:number=>10)
258
278
  @db.alter_table(:items){drop_constraint :items_pk, :type=>:primary_key}
@@ -262,7 +282,8 @@ describe "Database schema modifiers" do
262
282
 
263
283
  specify "should add foreign key columns to tables correctly" do
264
284
  @db.create_table!(:items){primary_key :id}
265
- i = @ds.insert
285
+ @ds.insert
286
+ i = @ds.get(:id)
266
287
  @db.alter_table(:items){add_foreign_key :item_id, :items}
267
288
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
268
289
  @ds.columns!.should == [:id, :item_id]
@@ -299,7 +320,7 @@ describe "Database schema modifiers" do
299
320
  proc{@ds.insert(:n=>nil)}.should raise_error(Sequel::DatabaseError)
300
321
  end
301
322
 
302
- cspecify "should set column NULL/NOT NULL correctly", [:jdbc, :db2] do
323
+ cspecify "should set column NULL/NOT NULL correctly", [:jdbc, :db2], [:db2] do
303
324
  @db.create_table!(:items, :engine=>:InnoDB){Integer :id}
304
325
  @ds.insert(:id=>10)
305
326
  @db.alter_table(:items){set_column_allow_null :id, false}
@@ -307,7 +328,7 @@ describe "Database schema modifiers" do
307
328
  @ds.columns!.should == [:id]
308
329
  proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
309
330
  @db.alter_table(:items){set_column_allow_null :id, true}
310
- @ds.insert
331
+ @ds.insert(:id=>nil)
311
332
  @ds.all.should == [{:id=>10}, {:id=>nil}]
312
333
  end
313
334
 
@@ -321,17 +342,17 @@ describe "Database schema modifiers" do
321
342
  @ds.all.should == [{:id=>10}, {:id=>20}]
322
343
  end
323
344
 
324
- cspecify "should set column types correctly", [:jdbc, :db2] do
345
+ cspecify "should set column types correctly", [:jdbc, :db2], [:db2], :oracle do
325
346
  @db.create_table!(:items){Integer :id}
326
347
  @ds.insert(:id=>10)
327
348
  @db.alter_table(:items){set_column_type :id, String}
328
349
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
329
350
  @ds.columns!.should == [:id]
330
- @ds.insert(:id=>20)
351
+ @ds.insert(:id=>'20')
331
352
  @ds.all.should == [{:id=>"10"}, {:id=>"20"}]
332
353
  end
333
354
 
334
- cspecify "should add unnamed unique constraints and foreign key table constraints correctly", :sqlite do
355
+ specify "should add unnamed unique constraints and foreign key table constraints correctly" do
335
356
  @db.create_table!(:items, :engine=>:InnoDB){Integer :id; Integer :item_id}
336
357
  @db.alter_table(:items) do
337
358
  add_unique_constraint [:item_id, :id]
@@ -344,7 +365,7 @@ describe "Database schema modifiers" do
344
365
  proc{@ds.insert(1, 2)}.should raise_error
345
366
  end
346
367
 
347
- cspecify "should add named unique constraints and foreign key table constraints correctly", :sqlite do
368
+ specify "should add named unique constraints and foreign key table constraints correctly" do
348
369
  @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null=>false; Integer :item_id, :null=>false}
349
370
  @db.alter_table(:items) do
350
371
  add_unique_constraint [:item_id, :id], :name=>:unique_iii
@@ -357,7 +378,7 @@ describe "Database schema modifiers" do
357
378
  proc{@ds.insert(1, 2)}.should raise_error
358
379
  end
359
380
 
360
- cspecify "should drop unique constraints and foreign key table constraints correctly", :sqlite do
381
+ specify "should drop unique constraints and foreign key table constraints correctly" do
361
382
  @db.create_table!(:items) do
362
383
  Integer :id
363
384
  Integer :item_id
@@ -374,7 +395,7 @@ describe "Database schema modifiers" do
374
395
  proc{@ds.insert(1, 2)}.should_not raise_error
375
396
  end
376
397
 
377
- cspecify "should remove columns from tables correctly", :h2, :mssql, [:jdbc, :db2] do
398
+ cspecify "should remove columns from tables correctly", :h2, :mssql, [:jdbc, :db2], :hsqldb do
378
399
  @db.create_table!(:items) do
379
400
  primary_key :id
380
401
  String :name
@@ -430,7 +451,6 @@ describe "Database#tables" do
430
451
  @db.create_view :sequel_test_view, @db[:sequel_test_table]
431
452
  @iom = @db.identifier_output_method
432
453
  @iim = @db.identifier_input_method
433
- clear_sqls
434
454
  end
435
455
  after do
436
456
  @db.identifier_output_method = @iom
@@ -472,7 +492,6 @@ describe "Database#views" do
472
492
  @db.create_view :sequel_test_view, @db[:sequel_test_table]
473
493
  @iom = @db.identifier_output_method
474
494
  @iim = @db.identifier_input_method
475
- clear_sqls
476
495
  end
477
496
  after do
478
497
  @db.identifier_output_method = @iom