sequel 3.21.0 → 3.32.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 (234) hide show
  1. data/CHANGELOG +539 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +20 -6
  4. data/Rakefile +37 -19
  5. data/bin/sequel +1 -5
  6. data/doc/advanced_associations.rdoc +17 -0
  7. data/doc/association_basics.rdoc +293 -43
  8. data/doc/dataset_basics.rdoc +4 -4
  9. data/doc/dataset_filtering.rdoc +8 -0
  10. data/doc/mass_assignment.rdoc +54 -0
  11. data/doc/migration.rdoc +15 -538
  12. data/doc/model_hooks.rdoc +72 -27
  13. data/doc/opening_databases.rdoc +89 -50
  14. data/doc/prepared_statements.rdoc +40 -13
  15. data/doc/reflection.rdoc +8 -2
  16. data/doc/release_notes/3.22.0.txt +39 -0
  17. data/doc/release_notes/3.23.0.txt +172 -0
  18. data/doc/release_notes/3.24.0.txt +420 -0
  19. data/doc/release_notes/3.25.0.txt +88 -0
  20. data/doc/release_notes/3.26.0.txt +88 -0
  21. data/doc/release_notes/3.27.0.txt +82 -0
  22. data/doc/release_notes/3.28.0.txt +304 -0
  23. data/doc/release_notes/3.29.0.txt +459 -0
  24. data/doc/release_notes/3.30.0.txt +135 -0
  25. data/doc/release_notes/3.31.0.txt +146 -0
  26. data/doc/release_notes/3.32.0.txt +202 -0
  27. data/doc/schema_modification.rdoc +547 -0
  28. data/doc/sharding.rdoc +7 -1
  29. data/doc/testing.rdoc +129 -0
  30. data/doc/transactions.rdoc +137 -0
  31. data/doc/virtual_rows.rdoc +2 -2
  32. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  33. data/lib/sequel/adapters/ado.rb +40 -18
  34. data/lib/sequel/adapters/amalgalite.rb +17 -9
  35. data/lib/sequel/adapters/db2.rb +175 -86
  36. data/lib/sequel/adapters/dbi.rb +15 -15
  37. data/lib/sequel/adapters/do/mysql.rb +5 -7
  38. data/lib/sequel/adapters/do/postgres.rb +0 -5
  39. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  40. data/lib/sequel/adapters/do.rb +17 -36
  41. data/lib/sequel/adapters/firebird.rb +27 -208
  42. data/lib/sequel/adapters/ibmdb.rb +448 -0
  43. data/lib/sequel/adapters/informix.rb +6 -23
  44. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  45. data/lib/sequel/adapters/jdbc/db2.rb +52 -0
  46. data/lib/sequel/adapters/jdbc/derby.rb +260 -0
  47. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  48. data/lib/sequel/adapters/jdbc/h2.rb +66 -30
  49. data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -0
  50. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  51. data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
  52. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  53. data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
  54. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  55. data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
  56. data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
  57. data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
  58. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  59. data/lib/sequel/adapters/jdbc.rb +231 -78
  60. data/lib/sequel/adapters/mock.rb +339 -0
  61. data/lib/sequel/adapters/mysql.rb +85 -184
  62. data/lib/sequel/adapters/mysql2.rb +26 -25
  63. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  64. data/lib/sequel/adapters/odbc/mssql.rb +1 -6
  65. data/lib/sequel/adapters/odbc.rb +28 -9
  66. data/lib/sequel/adapters/openbase.rb +3 -5
  67. data/lib/sequel/adapters/oracle.rb +355 -53
  68. data/lib/sequel/adapters/postgres.rb +194 -33
  69. data/lib/sequel/adapters/shared/access.rb +32 -9
  70. data/lib/sequel/adapters/shared/db2.rb +328 -0
  71. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  72. data/lib/sequel/adapters/shared/informix.rb +53 -0
  73. data/lib/sequel/adapters/shared/mssql.rb +278 -107
  74. data/lib/sequel/adapters/shared/mysql.rb +203 -65
  75. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  76. data/lib/sequel/adapters/shared/oracle.rb +237 -46
  77. data/lib/sequel/adapters/shared/postgres.rb +214 -82
  78. data/lib/sequel/adapters/shared/progress.rb +5 -8
  79. data/lib/sequel/adapters/shared/sqlite.rb +200 -50
  80. data/lib/sequel/adapters/sqlite.rb +29 -21
  81. data/lib/sequel/adapters/swift/mysql.rb +12 -7
  82. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  83. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  84. data/lib/sequel/adapters/swift.rb +5 -5
  85. data/lib/sequel/adapters/tinytds.rb +160 -19
  86. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  87. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  88. data/lib/sequel/ast_transformer.rb +190 -0
  89. data/lib/sequel/connection_pool/threaded.rb +3 -2
  90. data/lib/sequel/connection_pool.rb +1 -1
  91. data/lib/sequel/core.rb +68 -5
  92. data/lib/sequel/database/connecting.rb +5 -6
  93. data/lib/sequel/database/dataset.rb +4 -4
  94. data/lib/sequel/database/dataset_defaults.rb +59 -1
  95. data/lib/sequel/database/logging.rb +1 -1
  96. data/lib/sequel/database/misc.rb +104 -19
  97. data/lib/sequel/database/query.rb +163 -59
  98. data/lib/sequel/database/schema_generator.rb +17 -7
  99. data/lib/sequel/database/schema_methods.rb +59 -29
  100. data/lib/sequel/dataset/actions.rb +240 -76
  101. data/lib/sequel/dataset/features.rb +91 -8
  102. data/lib/sequel/dataset/graph.rb +38 -11
  103. data/lib/sequel/dataset/misc.rb +50 -23
  104. data/lib/sequel/dataset/mutation.rb +12 -7
  105. data/lib/sequel/dataset/prepared_statements.rb +59 -27
  106. data/lib/sequel/dataset/query.rb +236 -43
  107. data/lib/sequel/dataset/sql.rb +676 -267
  108. data/lib/sequel/dataset.rb +8 -0
  109. data/lib/sequel/exceptions.rb +4 -0
  110. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  111. data/lib/sequel/extensions/migration.rb +6 -4
  112. data/lib/sequel/extensions/named_timezones.rb +5 -0
  113. data/lib/sequel/extensions/query.rb +1 -1
  114. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  115. data/lib/sequel/extensions/to_dot.rb +95 -83
  116. data/lib/sequel/model/associations.rb +1081 -344
  117. data/lib/sequel/model/base.rb +420 -133
  118. data/lib/sequel/model/errors.rb +1 -1
  119. data/lib/sequel/model/exceptions.rb +5 -1
  120. data/lib/sequel/model.rb +20 -10
  121. data/lib/sequel/plugins/active_model.rb +13 -1
  122. data/lib/sequel/plugins/association_pks.rb +22 -4
  123. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  124. data/lib/sequel/plugins/composition.rb +43 -10
  125. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  126. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  127. data/lib/sequel/plugins/force_encoding.rb +6 -6
  128. data/lib/sequel/plugins/identity_map.rb +114 -7
  129. data/lib/sequel/plugins/many_through_many.rb +68 -7
  130. data/lib/sequel/plugins/nested_attributes.rb +65 -10
  131. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  132. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  133. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  134. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  135. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  136. data/lib/sequel/plugins/serialization.rb +98 -49
  137. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  138. data/lib/sequel/plugins/sharding.rb +21 -54
  139. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  140. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  141. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  142. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  143. data/lib/sequel/sql.rb +109 -52
  144. data/lib/sequel/timezones.rb +57 -38
  145. data/lib/sequel/version.rb +1 -1
  146. data/spec/adapters/db2_spec.rb +146 -0
  147. data/spec/adapters/mssql_spec.rb +135 -30
  148. data/spec/adapters/mysql_spec.rb +244 -212
  149. data/spec/adapters/oracle_spec.rb +67 -77
  150. data/spec/adapters/postgres_spec.rb +267 -78
  151. data/spec/adapters/spec_helper.rb +6 -5
  152. data/spec/adapters/sqlite_spec.rb +35 -21
  153. data/spec/core/connection_pool_spec.rb +71 -92
  154. data/spec/core/core_sql_spec.rb +21 -30
  155. data/spec/core/database_spec.rb +789 -512
  156. data/spec/core/dataset_spec.rb +1176 -1061
  157. data/spec/core/expression_filters_spec.rb +159 -42
  158. data/spec/core/mock_adapter_spec.rb +419 -0
  159. data/spec/core/object_graph_spec.rb +86 -114
  160. data/spec/core/schema_generator_spec.rb +3 -3
  161. data/spec/core/schema_spec.rb +298 -38
  162. data/spec/core/spec_helper.rb +6 -48
  163. data/spec/extensions/active_model_spec.rb +13 -0
  164. data/spec/extensions/association_autoreloading_spec.rb +1 -10
  165. data/spec/extensions/association_dependencies_spec.rb +2 -12
  166. data/spec/extensions/association_pks_spec.rb +66 -32
  167. data/spec/extensions/caching_spec.rb +23 -50
  168. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  169. data/spec/extensions/columns_introspection_spec.rb +91 -0
  170. data/spec/extensions/composition_spec.rb +18 -13
  171. data/spec/extensions/dataset_associations_spec.rb +199 -0
  172. data/spec/extensions/defaults_setter_spec.rb +64 -0
  173. data/spec/extensions/hook_class_methods_spec.rb +65 -91
  174. data/spec/extensions/identity_map_spec.rb +114 -22
  175. data/spec/extensions/instance_filters_spec.rb +11 -21
  176. data/spec/extensions/instance_hooks_spec.rb +53 -0
  177. data/spec/extensions/json_serializer_spec.rb +4 -5
  178. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  179. data/spec/extensions/list_spec.rb +17 -39
  180. data/spec/extensions/many_through_many_spec.rb +283 -250
  181. data/spec/extensions/migration_spec.rb +35 -32
  182. data/spec/extensions/named_timezones_spec.rb +23 -3
  183. data/spec/extensions/nested_attributes_spec.rb +97 -88
  184. data/spec/extensions/optimistic_locking_spec.rb +9 -20
  185. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  186. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  187. data/spec/extensions/prepared_statements_spec.rb +53 -0
  188. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  189. data/spec/extensions/pretty_table_spec.rb +1 -6
  190. data/spec/extensions/query_spec.rb +6 -0
  191. data/spec/extensions/rcte_tree_spec.rb +41 -43
  192. data/spec/extensions/schema_dumper_spec.rb +5 -8
  193. data/spec/extensions/schema_spec.rb +13 -21
  194. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  195. data/spec/extensions/serialization_spec.rb +81 -43
  196. data/spec/extensions/sharding_spec.rb +66 -140
  197. data/spec/extensions/single_table_inheritance_spec.rb +18 -29
  198. data/spec/extensions/spec_helper.rb +13 -61
  199. data/spec/extensions/sql_expr_spec.rb +20 -60
  200. data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
  201. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  202. data/spec/extensions/timestamps_spec.rb +6 -6
  203. data/spec/extensions/to_dot_spec.rb +4 -7
  204. data/spec/extensions/touch_spec.rb +13 -14
  205. data/spec/extensions/tree_spec.rb +11 -26
  206. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  207. data/spec/extensions/update_primary_key_spec.rb +30 -24
  208. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  209. data/spec/extensions/validation_helpers_spec.rb +16 -35
  210. data/spec/extensions/xml_serializer_spec.rb +16 -4
  211. data/spec/integration/associations_test.rb +661 -21
  212. data/spec/integration/database_test.rb +4 -2
  213. data/spec/integration/dataset_test.rb +500 -67
  214. data/spec/integration/eager_loader_test.rb +19 -21
  215. data/spec/integration/model_test.rb +80 -1
  216. data/spec/integration/plugin_test.rb +367 -119
  217. data/spec/integration/prepared_statement_test.rb +222 -125
  218. data/spec/integration/schema_test.rb +217 -39
  219. data/spec/integration/spec_helper.rb +39 -30
  220. data/spec/integration/timezone_test.rb +38 -12
  221. data/spec/integration/transaction_test.rb +182 -5
  222. data/spec/integration/type_test.rb +17 -3
  223. data/spec/model/association_reflection_spec.rb +201 -7
  224. data/spec/model/associations_spec.rb +955 -662
  225. data/spec/model/base_spec.rb +275 -95
  226. data/spec/model/dataset_methods_spec.rb +7 -27
  227. data/spec/model/eager_loading_spec.rb +677 -676
  228. data/spec/model/hooks_spec.rb +349 -67
  229. data/spec/model/model_spec.rb +222 -168
  230. data/spec/model/plugins_spec.rb +24 -13
  231. data/spec/model/record_spec.rb +381 -218
  232. data/spec/model/spec_helper.rb +13 -71
  233. data/spec/model/validations_spec.rb +11 -0
  234. metadata +117 -73
@@ -42,27 +42,27 @@ describe "MySQL", '#create_table' do
42
42
  after do
43
43
  @db.drop_table(:dolls) rescue nil
44
44
  end
45
-
45
+
46
46
  specify "should allow to specify options for MySQL" do
47
47
  @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
48
- @db.sqls.should == ["CREATE TABLE dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
48
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
49
49
  end
50
-
50
+
51
51
  specify "should create a temporary table" do
52
52
  @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
53
- @db.sqls.should == ["CREATE TEMPORARY TABLE tmp_dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
53
+ @db.sqls.should == ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
54
54
  end
55
-
55
+
56
56
  specify "should not use a default for a String :text=>true type" do
57
57
  @db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
58
- @db.sqls.should == ["CREATE TABLE dolls (name text)"]
58
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` text)"]
59
59
  end
60
-
60
+
61
61
  specify "should not use a default for a File type" do
62
62
  @db.create_table(:dolls){File :name, :default=>'blah'}
63
- @db.sqls.should == ["CREATE TABLE dolls (name blob)"]
63
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` blob)"]
64
64
  end
65
-
65
+
66
66
  specify "should respect the size option for File type" do
67
67
  @db.create_table(:dolls) do
68
68
  File :n1
@@ -82,17 +82,23 @@ describe "MySQL", '#create_table' do
82
82
  end
83
83
  @db.schema(:dolls).map{|k, v| v[:auto_increment]}.should == [nil, nil, true]
84
84
  end
85
+
86
+ specify "should support collate with various other column options" do
87
+ @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
88
+ @db[:dolls].insert
89
+ @db[:dolls].select_map(:name).should == ["foo"]
90
+ end
85
91
  end
86
92
 
87
93
  describe "A MySQL database" do
88
94
  specify "should provide the server version" do
89
95
  MYSQL_DB.server_version.should >= 40000
90
96
  end
91
-
97
+
92
98
  specify "should handle the creation and dropping of an InnoDB table with foreign keys" do
93
99
  proc{MYSQL_DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}}.should_not raise_error
94
100
  end
95
-
101
+
96
102
  specify "should support for_share" do
97
103
  MYSQL_DB.transaction{MYSQL_DB[:test2].for_share.all.should == []}
98
104
  end
@@ -106,18 +112,18 @@ if MYSQL_DB.adapter_scheme == :mysql
106
112
  @ds = @db[:booltest]
107
113
  end
108
114
  after do
109
- Sequel::MySQL.convert_tinyint_to_bool = true
115
+ @db.convert_tinyint_to_bool = true
110
116
  @db.drop_table(:booltest)
111
117
  end
112
-
118
+
113
119
  specify "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
114
120
  @db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
115
- Sequel::MySQL.convert_tinyint_to_bool = false
121
+ @db.convert_tinyint_to_bool = false
116
122
  @db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
117
123
  end
118
-
124
+
119
125
  specify "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
120
- Sequel::MySQL.convert_tinyint_to_bool = true
126
+ @db.convert_tinyint_to_bool = true
121
127
  @ds.delete
122
128
  @ds << {:b=>true, :i=>10}
123
129
  @ds.all.should == [{:b=>true, :i=>10}]
@@ -130,14 +136,14 @@ if MYSQL_DB.adapter_scheme == :mysql
130
136
  end
131
137
 
132
138
  specify "should return all tinyints as integers when unset" do
133
- Sequel::MySQL.convert_tinyint_to_bool = false
139
+ @db.convert_tinyint_to_bool = false
134
140
  @ds.delete
135
141
  @ds << {:b=>true, :i=>10}
136
142
  @ds.all.should == [{:b=>1, :i=>10}]
137
143
  @ds.delete
138
144
  @ds << {:b=>false, :i=>0}
139
145
  @ds.all.should == [{:b=>0, :i=>0}]
140
-
146
+
141
147
  @ds.delete
142
148
  @ds << {:b=>1, :i=>10}
143
149
  @ds.all.should == [{:b=>1, :i=>10}]
@@ -157,18 +163,18 @@ describe "A MySQL dataset" do
157
163
  after do
158
164
  MYSQL_DB.drop_table(:items)
159
165
  end
160
-
166
+
161
167
  specify "should quote columns and tables using back-ticks if quoting identifiers" do
162
168
  @d.quote_identifiers = true
163
169
  @d.select(:name).sql.should == \
164
170
  'SELECT `name` FROM `items`'
165
-
171
+
166
172
  @d.select('COUNT(*)'.lit).sql.should == \
167
173
  'SELECT COUNT(*) FROM `items`'
168
174
 
169
175
  @d.select(:max.sql_function(:value)).sql.should == \
170
176
  'SELECT max(`value`) FROM `items`'
171
-
177
+
172
178
  @d.select(:NOW.sql_function).sql.should == \
173
179
  'SELECT NOW() FROM `items`'
174
180
 
@@ -180,13 +186,13 @@ describe "A MySQL dataset" do
180
186
 
181
187
  @d.select('items.name AS item_name'.lit).sql.should == \
182
188
  'SELECT items.name AS item_name FROM `items`'
183
-
189
+
184
190
  @d.select('`name`'.lit).sql.should == \
185
191
  'SELECT `name` FROM `items`'
186
192
 
187
193
  @d.select('max(items.`name`) AS `max_name`'.lit).sql.should == \
188
194
  'SELECT max(items.`name`) AS `max_name` FROM `items`'
189
-
195
+
190
196
  @d.select(:test.sql_function(:abc, 'hello')).sql.should == \
191
197
  "SELECT test(`abc`, 'hello') FROM `items`"
192
198
 
@@ -202,7 +208,7 @@ describe "A MySQL dataset" do
202
208
  @d.insert_sql(:x => :y).should == \
203
209
  'INSERT INTO `items` (`x`) VALUES (`y`)'
204
210
  end
205
-
211
+
206
212
  specify "should quote fields correctly when reversing the order" do
207
213
  @d.quote_identifiers = true
208
214
  @d.reverse_order(:name).sql.should == \
@@ -217,37 +223,47 @@ describe "A MySQL dataset" do
217
223
  @d.reverse_order(:name.desc, :test).sql.should == \
218
224
  'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
219
225
  end
220
-
226
+
221
227
  specify "should support ORDER clause in UPDATE statements" do
222
228
  @d.order(:name).update_sql(:value => 1).should == \
223
- 'UPDATE items SET value = 1 ORDER BY name'
229
+ 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
224
230
  end
225
-
231
+
226
232
  specify "should support LIMIT clause in UPDATE statements" do
227
233
  @d.limit(10).update_sql(:value => 1).should == \
228
- 'UPDATE items SET value = 1 LIMIT 10'
234
+ 'UPDATE `items` SET `value` = 1 LIMIT 10'
229
235
  end
230
-
236
+
231
237
  specify "should support regexps" do
232
238
  @d << {:name => 'abc', :value => 1}
233
239
  @d << {:name => 'bcd', :value => 2}
234
240
  @d.filter(:name => /bc/).count.should == 2
235
241
  @d.filter(:name => /^bc/).count.should == 1
236
242
  end
237
-
243
+
238
244
  specify "should correctly literalize strings with comment backslashes in them" do
239
245
  @d.delete
240
246
  proc {@d << {:name => ':\\'}}.should_not raise_error
241
-
247
+
242
248
  @d.first[:name].should == ':\\'
243
249
  end
250
+
251
+ specify "should handle prepared statements with on_duplicate_key_update" do
252
+ @d.db.add_index :items, :value, :unique=>true
253
+ ds = @d.on_duplicate_key_update
254
+ ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
255
+ ps.call(:v => 1, :n => 'a')
256
+ ds.all.should == [{:value=>1, :name=>'a'}]
257
+ ps.call(:v => 1, :n => 'b')
258
+ ds.all.should == [{:value=>1, :name=>'b'}]
259
+ end
244
260
  end
245
261
 
246
262
  describe "MySQL datasets" do
247
263
  before do
248
264
  @d = MYSQL_DB[:orders]
249
265
  end
250
-
266
+
251
267
  specify "should correctly quote column references" do
252
268
  @d.quote_identifiers = true
253
269
  market = 'ICE'
@@ -271,7 +287,7 @@ describe "Dataset#distinct" do
271
287
  after do
272
288
  @db.drop_table(:a)
273
289
  end
274
-
290
+
275
291
  it "#distinct with arguments should return results distinct on those arguments" do
276
292
  @ds.insert(20, 10)
277
293
  @ds.insert(30, 10)
@@ -293,43 +309,43 @@ describe "MySQL join expressions" do
293
309
  end
294
310
  specify "should support natural left joins" do
295
311
  @ds.join_table(:natural_left, :nodes).sql.should == \
296
- 'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
312
+ 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
297
313
  end
298
314
  specify "should support natural right joins" do
299
315
  @ds.join_table(:natural_right, :nodes).sql.should == \
300
- 'SELECT * FROM nodes NATURAL RIGHT JOIN nodes'
316
+ 'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
301
317
  end
302
318
  specify "should support natural left outer joins" do
303
319
  @ds.join_table(:natural_left_outer, :nodes).sql.should == \
304
- 'SELECT * FROM nodes NATURAL LEFT OUTER JOIN nodes'
320
+ 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
305
321
  end
306
322
  specify "should support natural right outer joins" do
307
323
  @ds.join_table(:natural_right_outer, :nodes).sql.should == \
308
- 'SELECT * FROM nodes NATURAL RIGHT OUTER JOIN nodes'
324
+ 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
309
325
  end
310
326
  specify "should support natural inner joins" do
311
327
  @ds.join_table(:natural_inner, :nodes).sql.should == \
312
- 'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
328
+ 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
313
329
  end
314
330
  specify "should support cross joins" do
315
331
  @ds.join_table(:cross, :nodes).sql.should == \
316
- 'SELECT * FROM nodes CROSS JOIN nodes'
332
+ 'SELECT * FROM `nodes` CROSS JOIN `nodes`'
317
333
  end
318
334
  specify "should support cross joins as inner joins if conditions are used" do
319
335
  @ds.join_table(:cross, :nodes, :id=>:id).sql.should == \
320
- 'SELECT * FROM nodes INNER JOIN nodes ON (nodes.id = nodes.id)'
336
+ 'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
321
337
  end
322
338
  specify "should support straight joins (force left table to be read before right)" do
323
339
  @ds.join_table(:straight, :nodes).sql.should == \
324
- 'SELECT * FROM nodes STRAIGHT_JOIN nodes'
340
+ 'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
325
341
  end
326
342
  specify "should support natural joins on multiple tables." do
327
343
  @ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.should == \
328
- 'SELECT * FROM nodes NATURAL LEFT OUTER JOIN (nodes, branches)'
344
+ 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
329
345
  end
330
346
  specify "should support straight joins on multiple tables." do
331
347
  @ds.join_table(:straight, [:nodes,:branches]).sql.should == \
332
- 'SELECT * FROM nodes STRAIGHT_JOIN (nodes, branches)'
348
+ 'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
333
349
  end
334
350
  end
335
351
 
@@ -337,23 +353,23 @@ describe "Joined MySQL dataset" do
337
353
  before do
338
354
  @ds = MYSQL_DB[:nodes]
339
355
  end
340
-
356
+
341
357
  specify "should quote fields correctly" do
342
358
  @ds.quote_identifiers = true
343
359
  @ds.join(:attributes, :node_id => :id).sql.should == \
344
360
  "SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
345
361
  end
346
-
362
+
347
363
  specify "should allow a having clause on ungrouped datasets" do
348
364
  proc {@ds.having('blah')}.should_not raise_error
349
365
 
350
366
  @ds.having('blah').sql.should == \
351
- "SELECT * FROM nodes HAVING (blah)"
367
+ "SELECT * FROM `nodes` HAVING (blah)"
352
368
  end
353
-
369
+
354
370
  specify "should put a having clause before an order by clause" do
355
371
  @ds.order(:aaa).having(:bbb => :ccc).sql.should == \
356
- "SELECT * FROM nodes HAVING (bbb = ccc) ORDER BY aaa"
372
+ "SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
357
373
  end
358
374
  end
359
375
 
@@ -364,19 +380,19 @@ describe "A MySQL database" do
364
380
 
365
381
  specify "should support add_column operations" do
366
382
  @db.add_column :test2, :xyz, :text
367
-
383
+
368
384
  @db[:test2].columns.should == [:name, :value, :xyz]
369
385
  @db[:test2] << {:name => 'mmm', :value => 111, :xyz => '000'}
370
386
  @db[:test2].first[:xyz].should == '000'
371
387
  end
372
-
388
+
373
389
  specify "should support drop_column operations" do
374
390
  @db[:test2].columns.should == [:name, :value, :xyz]
375
391
  @db.drop_column :test2, :xyz
376
-
392
+
377
393
  @db[:test2].columns.should == [:name, :value]
378
394
  end
379
-
395
+
380
396
  specify "should support rename_column operations" do
381
397
  @db[:test2].delete
382
398
  @db.add_column :test2, :xyz, :text
@@ -387,7 +403,7 @@ describe "A MySQL database" do
387
403
  @db[:test2].columns.should == [:name, :value, :zyx]
388
404
  @db[:test2].first[:zyx].should == 'qqqq'
389
405
  end
390
-
406
+
391
407
  specify "should support rename_column operations with types like varchar(255)" do
392
408
  @db[:test2].delete
393
409
  @db.add_column :test2, :tre, :text
@@ -398,24 +414,24 @@ describe "A MySQL database" do
398
414
  @db[:test2].columns.should == [:name, :value, :zyx, :ert]
399
415
  @db[:test2].first[:ert].should == 'qqqq'
400
416
  end
401
-
417
+
402
418
  specify "should support set_column_type operations" do
403
419
  @db.add_column :test2, :xyz, :float
404
420
  @db[:test2].delete
405
421
  @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
406
422
  @db.set_column_type :test2, :xyz, :integer
407
-
423
+
408
424
  @db[:test2].first[:xyz].should == 57
409
425
  end
410
-
426
+
411
427
  specify "should support add_index" do
412
428
  @db.add_index :test2, :value
413
429
  end
414
-
430
+
415
431
  specify "should support drop_index" do
416
432
  @db.drop_index :test2, :value
417
433
  end
418
-
434
+
419
435
  specify "should support add_foreign_key" do
420
436
  @db.alter_table :test2 do
421
437
  add_foreign_key :value2, :test2, :key=>:value
@@ -427,14 +443,14 @@ end
427
443
  describe "A MySQL database with table options" do
428
444
  before do
429
445
  @options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
430
-
446
+
431
447
  Sequel::MySQL.default_engine = 'InnoDB'
432
448
  Sequel::MySQL.default_charset = 'utf8'
433
449
  Sequel::MySQL.default_collate = 'utf8_general_ci'
434
-
450
+
435
451
  @db = MYSQL_DB
436
452
  @db.drop_table(:items) rescue nil
437
-
453
+
438
454
  MYSQL_DB.sqls.clear
439
455
  end
440
456
  after do
@@ -444,20 +460,20 @@ describe "A MySQL database with table options" do
444
460
  Sequel::MySQL.default_charset = nil
445
461
  Sequel::MySQL.default_collate = nil
446
462
  end
447
-
463
+
448
464
  specify "should allow to pass custom options (engine, charset, collate) for table creation" do
449
465
  @db.create_table(:items, @options){Integer :size; text :name}
450
- @db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
466
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
451
467
  end
452
-
468
+
453
469
  specify "should use default options if specified (engine, charset, collate) for table creation" do
454
470
  @db.create_table(:items){Integer :size; text :name}
455
- @db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
471
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
456
472
  end
457
-
473
+
458
474
  specify "should not use default if option has a nil value" do
459
475
  @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
460
- @db.sqls.should == ["CREATE TABLE items (size integer, name text)"]
476
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text)"]
461
477
  end
462
478
  end
463
479
 
@@ -470,36 +486,36 @@ describe "A MySQL database" do
470
486
  after do
471
487
  @db.drop_table(:items) rescue nil
472
488
  end
473
-
489
+
474
490
  specify "should support defaults for boolean columns" do
475
491
  @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
476
- @db.sqls.should == ["CREATE TABLE items (active1 tinyint(1) DEFAULT 1, active2 tinyint(1) DEFAULT 0)"]
492
+ @db.sqls.should == ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
477
493
  end
478
-
494
+
479
495
  specify "should correctly format CREATE TABLE statements with foreign keys" do
480
496
  @db.create_table(:items){Integer :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
481
- @db.sqls.should == ["CREATE TABLE items (id integer, p_id integer NOT NULL, FOREIGN KEY (p_id) REFERENCES items(id) ON DELETE CASCADE)"]
497
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer, `p_id` integer NOT NULL, FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
482
498
  end
483
-
499
+
484
500
  specify "should correctly format ALTER TABLE statements with foreign keys" do
485
501
  @db.create_table(:items){Integer :id}
486
502
  @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
487
- @db.sqls.should == ["CREATE TABLE items (id integer)", "ALTER TABLE items ADD COLUMN p_id integer NOT NULL", "ALTER TABLE items ADD FOREIGN KEY (p_id) REFERENCES users(id) ON DELETE CASCADE"]
503
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer)", "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL", "ALTER TABLE `items` ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
488
504
  end
489
-
505
+
490
506
  specify "should have rename_column support keep existing options" do
491
507
  @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
492
508
  @db.alter_table(:items){rename_column :id, :nid}
493
- @db.sqls.should == ["CREATE TABLE items (id varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id nid varchar(255) NOT NULL DEFAULT 'blah'"]
509
+ @db.sqls.should == ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
494
510
  @db[:items].insert
495
511
  @db[:items].all.should == [{:nid=>'blah'}]
496
512
  proc{@db[:items].insert(:nid=>nil)}.should raise_error(Sequel::DatabaseError)
497
513
  end
498
-
514
+
499
515
  specify "should have set_column_type support keep existing options" do
500
516
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
501
517
  @db.alter_table(:items){set_column_type :id, Bignum}
502
- @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id bigint NOT NULL DEFAULT 5"]
518
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
503
519
  @db[:items].insert
504
520
  @db[:items].all.should == [{:id=>5}]
505
521
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -511,35 +527,35 @@ describe "A MySQL database" do
511
527
  specify "should have set_column_type pass through options" do
512
528
  @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
513
529
  @db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
514
- @db.sqls.should == ["CREATE TABLE items (id integer, list enum('one'))", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(8) UNSIGNED NULL", "ALTER TABLE items CHANGE COLUMN list list enum('two') NULL"]
530
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL", "ALTER TABLE `items` CHANGE COLUMN `list` `list` enum('two') NULL"]
515
531
  end
516
-
532
+
517
533
  specify "should have set_column_default support keep existing options" do
518
534
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
519
535
  @db.alter_table(:items){set_column_default :id, 6}
520
- @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NOT NULL DEFAULT 6"]
536
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
521
537
  @db[:items].insert
522
538
  @db[:items].all.should == [{:id=>6}]
523
539
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
524
540
  end
525
-
541
+
526
542
  specify "should have set_column_allow_null support keep existing options" do
527
543
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
528
544
  @db.alter_table(:items){set_column_allow_null :id, true}
529
- @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NULL DEFAULT 5"]
545
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
530
546
  @db[:items].insert
531
547
  @db[:items].all.should == [{:id=>5}]
532
548
  proc{@db[:items].insert(:id=>nil)}.should_not
533
549
  end
534
-
550
+
535
551
  specify "should accept repeated raw sql statements using Database#<<" do
536
552
  @db.create_table(:items){String :name; Integer :value}
537
553
  @db << 'DELETE FROM items'
538
554
  @db[:items].count.should == 0
539
-
555
+
540
556
  @db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
541
557
  @db[:items].first.should == {:name => 'tutu', :value => 1234}
542
-
558
+
543
559
  @db << 'DELETE FROM items'
544
560
  @db[:items].first.should == nil
545
561
  end
@@ -552,12 +568,12 @@ if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.adapter_sch
552
568
  db = Sequel.mysql(MYSQL_DB.opts[:database], :host => 'localhost', :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
553
569
  proc {db.test_connection}.should_not raise_error
554
570
  end
555
-
571
+
556
572
  specify "should accept a socket option without host option" do
557
573
  db = Sequel.mysql(MYSQL_DB.opts[:database], :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
558
574
  proc {db.test_connection}.should_not raise_error
559
575
  end
560
-
576
+
561
577
  specify "should fail to connect with invalid socket" do
562
578
  db = Sequel.mysql(MYSQL_DB.opts[:database], :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket =>'blah')
563
579
  proc {db.test_connection}.should raise_error
@@ -587,12 +603,12 @@ describe "A grouped MySQL dataset" do
587
603
  MYSQL_DB[:test2] << {:name => '12', :value => 20}
588
604
  MYSQL_DB[:test2] << {:name => '13', :value => 10}
589
605
  end
590
-
606
+
591
607
  specify "should return the correct count for raw sql query" do
592
608
  ds = MYSQL_DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
593
609
  ds.count.should == 1
594
610
  end
595
-
611
+
596
612
  specify "should return the correct count for a normal dataset" do
597
613
  ds = MYSQL_DB[:test2].select(:name).where(:name => '11').group(:name)
598
614
  ds.count.should == 1
@@ -608,15 +624,15 @@ describe "A MySQL database" do
608
624
  after do
609
625
  @db.drop_table(:posts) rescue nil
610
626
  end
611
-
627
+
612
628
  specify "should support fulltext indexes and full_text_search" do
613
629
  @db.create_table(:posts){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
614
630
  @db.sqls.should == [
615
- "CREATE TABLE posts (title text, body text)",
616
- "CREATE FULLTEXT INDEX posts_title_index ON posts (title)",
617
- "CREATE FULLTEXT INDEX posts_title_body_index ON posts (title, body)"
631
+ "CREATE TABLE `posts` (`title` text, `body` text)",
632
+ "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
633
+ "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
618
634
  ]
619
-
635
+
620
636
  @db[:posts].insert(:title=>'ruby rails', :body=>'y')
621
637
  @db[:posts].insert(:title=>'sequel', :body=>'ruby')
622
638
  @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
@@ -626,32 +642,35 @@ describe "A MySQL database" do
626
642
  @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
627
643
  @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.should == [{:title=>'ruby scooby', :body=>'x'}]
628
644
  @db.sqls.should == [
629
- "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('rails'))",
630
- "SELECT * FROM posts WHERE (MATCH (title, body) AGAINST ('sequel ruby'))",
631
- "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
645
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
646
+ "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
647
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
648
+
649
+ @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
650
+ @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
632
651
  end
633
652
 
634
653
  specify "should support spatial indexes" do
635
654
  @db.create_table(:posts){point :geom, :null=>false; spatial_index [:geom]}
636
655
  @db.sqls.should == [
637
- "CREATE TABLE posts (geom point NOT NULL)",
638
- "CREATE SPATIAL INDEX posts_geom_index ON posts (geom)"
656
+ "CREATE TABLE `posts` (`geom` point NOT NULL)",
657
+ "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
639
658
  ]
640
659
  end
641
660
 
642
661
  specify "should support indexes with index type" do
643
662
  @db.create_table(:posts){Integer :id; index :id, :type => :btree}
644
663
  @db.sqls.should == [
645
- "CREATE TABLE posts (id integer)",
646
- "CREATE INDEX posts_id_index USING btree ON posts (id)"
664
+ "CREATE TABLE `posts` (`id` integer)",
665
+ "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
647
666
  ]
648
667
  end
649
668
 
650
669
  specify "should support unique indexes with index type" do
651
670
  @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
652
671
  @db.sqls.should == [
653
- "CREATE TABLE posts (id integer)",
654
- "CREATE UNIQUE INDEX posts_id_index USING btree ON posts (id)"
672
+ "CREATE TABLE `posts` (`id` integer)",
673
+ "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
655
674
  ]
656
675
  end
657
676
 
@@ -680,38 +699,20 @@ describe "MySQL::Dataset#insert and related methods" do
680
699
 
681
700
  specify "#insert should insert record with default values when no arguments given" do
682
701
  @d.insert
683
-
684
- MYSQL_DB.sqls.should == [
685
- "INSERT INTO items () VALUES ()"
686
- ]
687
-
688
- @d.all.should == [
689
- {:name => nil, :value => nil}
690
- ]
702
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
703
+ @d.all.should == [{:name => nil, :value => nil}]
691
704
  end
692
705
 
693
706
  specify "#insert should insert record with default values when empty hash given" do
694
707
  @d.insert({})
695
-
696
- MYSQL_DB.sqls.should == [
697
- "INSERT INTO items () VALUES ()"
698
- ]
699
-
700
- @d.all.should == [
701
- {:name => nil, :value => nil}
702
- ]
708
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
709
+ @d.all.should == [{:name => nil, :value => nil}]
703
710
  end
704
711
 
705
712
  specify "#insert should insert record with default values when empty array given" do
706
713
  @d.insert []
707
-
708
- MYSQL_DB.sqls.should == [
709
- "INSERT INTO items () VALUES ()"
710
- ]
711
-
712
- @d.all.should == [
713
- {:name => nil, :value => nil}
714
- ]
714
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
715
+ @d.all.should == [{:name => nil, :value => nil}]
715
716
  end
716
717
 
717
718
  specify "#on_duplicate_key_update should work with regular inserts" do
@@ -722,19 +723,19 @@ describe "MySQL::Dataset#insert and related methods" do
722
723
  @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
723
724
 
724
725
  MYSQL_DB.sqls.length.should == 3
725
- MYSQL_DB.sqls[0].should =~ /\AINSERT INTO items \((name|value), (name|value)\) VALUES \(('abc'|1), (1|'abc')\)\z/
726
- MYSQL_DB.sqls[1].should =~ /\AINSERT INTO items \((name|value), (name|value)\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE name=VALUES\(name\), value=6\z/
727
- MYSQL_DB.sqls[2].should =~ /\AINSERT INTO items \((name|value), (name|value)\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE name=VALUES\(name\), value=6\z/
726
+ MYSQL_DB.sqls[0].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/
727
+ MYSQL_DB.sqls[1].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
728
+ MYSQL_DB.sqls[2].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
728
729
 
729
730
  @d.all.should == [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
730
731
  end
731
732
 
732
733
  specify "#multi_insert should insert multiple records in a single statement" do
733
734
  @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
734
-
735
+
735
736
  MYSQL_DB.sqls.should == [
736
737
  SQL_BEGIN,
737
- "INSERT INTO items (name) VALUES ('abc'), ('def')",
738
+ "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
738
739
  SQL_COMMIT
739
740
  ]
740
741
 
@@ -749,13 +750,13 @@ describe "MySQL::Dataset#insert and related methods" do
749
750
 
750
751
  MYSQL_DB.sqls.should == [
751
752
  SQL_BEGIN,
752
- "INSERT INTO items (value) VALUES (1), (2)",
753
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
753
754
  SQL_COMMIT,
754
755
  SQL_BEGIN,
755
- "INSERT INTO items (value) VALUES (3), (4)",
756
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
756
757
  SQL_COMMIT
757
758
  ]
758
-
759
+
759
760
  @d.all.should == [
760
761
  {:name => nil, :value => 1},
761
762
  {:name => nil, :value => 2},
@@ -770,13 +771,13 @@ describe "MySQL::Dataset#insert and related methods" do
770
771
 
771
772
  MYSQL_DB.sqls.should == [
772
773
  SQL_BEGIN,
773
- "INSERT INTO items (value) VALUES (1), (2)",
774
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
774
775
  SQL_COMMIT,
775
776
  SQL_BEGIN,
776
- "INSERT INTO items (value) VALUES (3), (4)",
777
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
777
778
  SQL_COMMIT
778
779
  ]
779
-
780
+
780
781
  @d.all.should == [
781
782
  {:name => nil, :value => 1},
782
783
  {:name => nil, :value => 2},
@@ -784,28 +785,28 @@ describe "MySQL::Dataset#insert and related methods" do
784
785
  {:name => nil, :value => 4}
785
786
  ]
786
787
  end
787
-
788
+
788
789
  specify "#import should support inserting using columns and values arrays" do
789
790
  @d.import([:name, :value], [['abc', 1], ['def', 2]])
790
791
 
791
792
  MYSQL_DB.sqls.should == [
792
793
  SQL_BEGIN,
793
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2)",
794
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
794
795
  SQL_COMMIT
795
796
  ]
796
-
797
+
797
798
  @d.all.should == [
798
799
  {:name => 'abc', :value => 1},
799
800
  {:name => 'def', :value => 2}
800
801
  ]
801
802
  end
802
-
803
+
803
804
  specify "#insert_ignore should add the IGNORE keyword when inserting" do
804
805
  @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
805
-
806
+
806
807
  MYSQL_DB.sqls.should == [
807
808
  SQL_BEGIN,
808
- "INSERT IGNORE INTO items (name) VALUES ('abc'), ('def')",
809
+ "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
809
810
  SQL_COMMIT
810
811
  ]
811
812
 
@@ -813,20 +814,20 @@ describe "MySQL::Dataset#insert and related methods" do
813
814
  {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
814
815
  ]
815
816
  end
816
-
817
+
817
818
  specify "#insert_ignore should add the IGNORE keyword for single inserts" do
818
819
  @d.insert_ignore.insert(:name => 'ghi')
819
- MYSQL_DB.sqls.should == ["INSERT IGNORE INTO items (name) VALUES ('ghi')"]
820
+ MYSQL_DB.sqls.should == ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
820
821
  @d.all.should == [{:name => 'ghi', :value => nil}]
821
822
  end
822
-
823
+
823
824
  specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
824
825
  @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
825
-
826
+
826
827
  MYSQL_DB.sqls.should == [
827
- "SELECT * FROM items LIMIT 1",
828
+ "SELECT * FROM `items` LIMIT 1",
828
829
  SQL_BEGIN,
829
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE name=VALUES(name), value=VALUES(value)",
830
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
830
831
  SQL_COMMIT
831
832
  ]
832
833
 
@@ -834,15 +835,15 @@ describe "MySQL::Dataset#insert and related methods" do
834
835
  {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
835
836
  ]
836
837
  end
837
-
838
+
838
839
  specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
839
840
  @d.on_duplicate_key_update(:value).import([:name,:value],
840
841
  [['abc', 1], ['def',2]]
841
842
  )
842
-
843
+
843
844
  MYSQL_DB.sqls.should == [
844
845
  SQL_BEGIN,
845
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE value=VALUES(value)",
846
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
846
847
  SQL_COMMIT
847
848
  ]
848
849
 
@@ -850,7 +851,27 @@ describe "MySQL::Dataset#insert and related methods" do
850
851
  {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
851
852
  ]
852
853
  end
853
-
854
+
855
+ end
856
+
857
+ describe "MySQL::Dataset#update and related methods" do
858
+ before do
859
+ MYSQL_DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
860
+ @d = MYSQL_DB[:items]
861
+ end
862
+ after do
863
+ MYSQL_DB.drop_table(:items)
864
+ end
865
+
866
+ specify "#update_ignore should not raise error where normal update would fail" do
867
+ @d.insert(:name => 'cow', :value => 0)
868
+ @d.insert(:name => 'cat', :value => 1)
869
+ proc{@d.where(:value => 1).update(:name => 'cow')}.should raise_error(Sequel::DatabaseError)
870
+ MYSQL_DB.sqls.clear
871
+ @d.update_ignore.where(:value => 1).update(:name => 'cow')
872
+ MYSQL_DB.sqls.should == ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
873
+ @d.order(:name).all.should == [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
874
+ end
854
875
  end
855
876
 
856
877
  describe "MySQL::Dataset#replace" do
@@ -862,7 +883,7 @@ describe "MySQL::Dataset#replace" do
862
883
  after do
863
884
  MYSQL_DB.drop_table(:items)
864
885
  end
865
-
886
+
866
887
  specify "should use default values if they exist" do
867
888
  MYSQL_DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
868
889
  @d.replace
@@ -872,7 +893,7 @@ describe "MySQL::Dataset#replace" do
872
893
  @d.replace({})
873
894
  @d.all.should == [{:id=>1, :value=>2}]
874
895
  end
875
-
896
+
876
897
  specify "should use support arrays, datasets, and multiple values" do
877
898
  @d.replace([1, 2])
878
899
  @d.all.should == [{:id=>1, :value=>2}]
@@ -881,12 +902,12 @@ describe "MySQL::Dataset#replace" do
881
902
  @d.replace(@d)
882
903
  @d.all.should == [{:id=>1, :value=>2}]
883
904
  end
884
-
905
+
885
906
  specify "should create a record if the condition is not met" do
886
907
  @d.replace(:id => 111, :value => 333)
887
908
  @d.all.should == [{:id => 111, :value => 333}]
888
909
  end
889
-
910
+
890
911
  specify "should update a record if the condition is met" do
891
912
  @d << {:id => 111}
892
913
  @d.all.should == [{:id => 111, :value => nil}]
@@ -901,25 +922,25 @@ describe "MySQL::Dataset#complex_expression_sql" do
901
922
  end
902
923
 
903
924
  specify "should handle pattern matches correctly" do
904
- @d.literal(:x.like('a')).should == "(x LIKE BINARY 'a')"
905
- @d.literal(~:x.like('a')).should == "(x NOT LIKE BINARY 'a')"
906
- @d.literal(:x.ilike('a')).should == "(x LIKE 'a')"
907
- @d.literal(~:x.ilike('a')).should == "(x NOT LIKE 'a')"
908
- @d.literal(:x.like(/a/)).should == "(x REGEXP BINARY 'a')"
909
- @d.literal(~:x.like(/a/)).should == "(x NOT REGEXP BINARY 'a')"
910
- @d.literal(:x.like(/a/i)).should == "(x REGEXP 'a')"
911
- @d.literal(~:x.like(/a/i)).should == "(x NOT REGEXP 'a')"
925
+ @d.literal(:x.like('a')).should == "(`x` LIKE BINARY 'a')"
926
+ @d.literal(~:x.like('a')).should == "(`x` NOT LIKE BINARY 'a')"
927
+ @d.literal(:x.ilike('a')).should == "(`x` LIKE 'a')"
928
+ @d.literal(~:x.ilike('a')).should == "(`x` NOT LIKE 'a')"
929
+ @d.literal(:x.like(/a/)).should == "(`x` REGEXP BINARY 'a')"
930
+ @d.literal(~:x.like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
931
+ @d.literal(:x.like(/a/i)).should == "(`x` REGEXP 'a')"
932
+ @d.literal(~:x.like(/a/i)).should == "(`x` NOT REGEXP 'a')"
912
933
  end
913
934
 
914
935
  specify "should handle string concatenation with CONCAT if more than one record" do
915
- @d.literal([:x, :y].sql_string_join).should == "CONCAT(x, y)"
916
- @d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(x, ' ', y)"
917
- @d.literal([:x.sql_function(:y), 1, 'z'.lit].sql_string_join(:y.sql_subscript(1))).should == "CONCAT(x(y), y[1], '1', y[1], z)"
936
+ @d.literal([:x, :y].sql_string_join).should == "CONCAT(`x`, `y`)"
937
+ @d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(`x`, ' ', `y`)"
938
+ @d.literal([:x.sql_function(:y), 1, 'z'.lit].sql_string_join(:y.sql_subscript(1))).should == "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
918
939
  end
919
940
 
920
941
  specify "should handle string concatenation as simple string if just one record" do
921
- @d.literal([:x].sql_string_join).should == "x"
922
- @d.literal([:x].sql_string_join(' ')).should == "x"
942
+ @d.literal([:x].sql_string_join).should == "`x`"
943
+ @d.literal([:x].sql_string_join(' ')).should == "`x`"
923
944
  end
924
945
  end
925
946
 
@@ -933,7 +954,7 @@ describe "MySQL::Dataset#calc_found_rows" do
933
954
 
934
955
  specify "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
935
956
  MYSQL_DB[:items].select(:a).calc_found_rows.limit(1).sql.should == \
936
- 'SELECT SQL_CALC_FOUND_ROWS a FROM items LIMIT 1'
957
+ 'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
937
958
  end
938
959
 
939
960
  specify "should count matching rows disregarding LIMIT clause" do
@@ -944,13 +965,13 @@ describe "MySQL::Dataset#calc_found_rows" do
944
965
  MYSQL_DB.dataset.select(:FOUND_ROWS.sql_function.as(:rows)).all.should == [{:rows => 2 }]
945
966
 
946
967
  MYSQL_DB.sqls.should == [
947
- 'SELECT SQL_CALC_FOUND_ROWS * FROM items WHERE (a = 1) LIMIT 1',
948
- 'SELECT FOUND_ROWS() AS rows',
968
+ 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
969
+ 'SELECT FOUND_ROWS() AS `rows`',
949
970
  ]
950
971
  end
951
972
  end
952
973
 
953
- if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
974
+ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc or MYSQL_DB.adapter_scheme == :mysql2
954
975
  describe "MySQL Stored Procedures" do
955
976
  before do
956
977
  MYSQL_DB.create_table(:items){Integer :id; Integer :value}
@@ -961,7 +982,7 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
961
982
  MYSQL_DB.drop_table(:items)
962
983
  MYSQL_DB.execute('DROP PROCEDURE test_sproc')
963
984
  end
964
-
985
+
965
986
  specify "should be callable on the database object" do
966
987
  MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
967
988
  MYSQL_DB[:items].delete
@@ -970,27 +991,38 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
970
991
  MYSQL_DB.call_sproc(:test_sproc)
971
992
  MYSQL_DB[:items].count.should == 0
972
993
  end
973
-
974
- specify "should be callable on the dataset object" do
975
- MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
976
- MYSQL_DB[:items].delete
977
- @d = MYSQL_DB[:items]
978
- @d.call_sproc(:select, :test_sproc, 3).should == []
979
- @d.insert(:value=>1)
980
- @d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
981
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
982
- @d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
994
+
995
+ # Mysql2 doesn't support stored procedures that return result sets, probably because
996
+ # CLIENT_MULTI_RESULTS is not set.
997
+ unless MYSQL_DB.adapter_scheme == :mysql2
998
+ specify "should be callable on the dataset object" do
999
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
1000
+ MYSQL_DB[:items].delete
1001
+ @d = MYSQL_DB[:items]
1002
+ @d.call_sproc(:select, :test_sproc, 3).should == []
1003
+ @d.insert(:value=>1)
1004
+ @d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
1005
+ @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1006
+ @d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
1007
+ end
1008
+
1009
+ specify "should be callable on the dataset object with multiple arguments" do
1010
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
1011
+ MYSQL_DB[:items].delete
1012
+ @d = MYSQL_DB[:items]
1013
+ @d.call_sproc(:select, :test_sproc, 3, 4).should == []
1014
+ @d.insert(:value=>1)
1015
+ @d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
1016
+ @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1017
+ @d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
1018
+ end
983
1019
  end
984
-
985
- specify "should be callable on the dataset object with multiple arguments" do
986
- MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
1020
+
1021
+ specify "should deal with nil values" do
1022
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
987
1023
  MYSQL_DB[:items].delete
988
- @d = MYSQL_DB[:items]
989
- @d.call_sproc(:select, :test_sproc, 3, 4).should == []
990
- @d.insert(:value=>1)
991
- @d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
992
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
993
- @d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
1024
+ MYSQL_DB.call_sproc(:test_sproc, :args=>[1, nil])
1025
+ MYSQL_DB[:items].all.should == [{:id=>1, :value=>nil}]
994
1026
  end
995
1027
  end
996
1028
  end
@@ -998,35 +1030,35 @@ end
998
1030
  if MYSQL_DB.adapter_scheme == :mysql
999
1031
  describe "MySQL bad date/time conversions" do
1000
1032
  after do
1001
- Sequel::MySQL.convert_invalid_date_time = false
1033
+ MYSQL_DB.convert_invalid_date_time = false
1002
1034
  end
1003
-
1035
+
1004
1036
  specify "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
1005
- Sequel::MySQL.convert_invalid_date_time = false
1037
+ MYSQL_DB.convert_invalid_date_time = false
1006
1038
  proc{MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value}.should raise_error(Sequel::InvalidValue)
1007
1039
  proc{MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.should raise_error(Sequel::InvalidValue)
1008
1040
  proc{MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value}.should raise_error(Sequel::InvalidValue)
1009
1041
  end
1010
-
1042
+
1011
1043
  specify "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
1012
- Sequel::MySQL.convert_invalid_date_time = nil
1044
+ MYSQL_DB.convert_invalid_date_time = nil
1013
1045
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
1014
1046
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
1015
1047
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
1016
- Sequel::MySQL.convert_invalid_date_time = :nil
1048
+ MYSQL_DB.convert_invalid_date_time = :nil
1017
1049
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
1018
1050
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
1019
1051
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
1020
1052
  end
1021
-
1053
+
1022
1054
  specify "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
1023
- Sequel::MySQL.convert_invalid_date_time = :string
1055
+ MYSQL_DB.convert_invalid_date_time = :string
1024
1056
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == '0000-00-00'
1025
1057
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == '0000-00-00 00:00:00'
1026
1058
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == '25:00:00'
1027
1059
  end
1028
1060
  end
1029
-
1061
+
1030
1062
  describe "MySQL multiple result sets" do
1031
1063
  before do
1032
1064
  MYSQL_DB.create_table!(:a){Integer :a}
@@ -1040,39 +1072,39 @@ if MYSQL_DB.adapter_scheme == :mysql
1040
1072
  after do
1041
1073
  MYSQL_DB.drop_table(:a, :b)
1042
1074
  end
1043
-
1075
+
1044
1076
  specify "should combine all results by default" do
1045
1077
  @ds.all.should == [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
1046
1078
  end
1047
-
1079
+
1048
1080
  specify "should work with Database#run" do
1049
1081
  proc{MYSQL_DB.run('SELECT * FROM a; SELECT * FROM b')}.should_not raise_error
1050
1082
  proc{MYSQL_DB.run('SELECT * FROM a; SELECT * FROM b')}.should_not raise_error
1051
1083
  end
1052
-
1084
+
1053
1085
  specify "should work with Database#run and other statements" do
1054
1086
  proc{MYSQL_DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')}.should_not raise_error
1055
1087
  MYSQL_DB[:a].select_order_map(:a).should == [1, 1]
1056
1088
  MYSQL_DB[:b].all.should == []
1057
1089
  end
1058
-
1090
+
1059
1091
  specify "should split results returned into arrays if split_multiple_result_sets is used" do
1060
1092
  @ds.split_multiple_result_sets.all.should == [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
1061
1093
  end
1062
-
1094
+
1063
1095
  specify "should have regular row_procs work when splitting multiple result sets" do
1064
1096
  @ds.row_proc = proc{|x| x[x.keys.first] *= 2; x}
1065
1097
  @ds.split_multiple_result_sets.all.should == [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
1066
1098
  end
1067
-
1099
+
1068
1100
  specify "should use the columns from the first result set when splitting result sets" do
1069
1101
  @ds.split_multiple_result_sets.columns.should == [:a]
1070
1102
  end
1071
-
1103
+
1072
1104
  specify "should not allow graphing a dataset that splits multiple statements" do
1073
1105
  proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.should raise_error(Sequel::Error)
1074
1106
  end
1075
-
1107
+
1076
1108
  specify "should not allow splitting a graphed dataset" do
1077
1109
  proc{MYSQL_DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.should raise_error(Sequel::Error)
1078
1110
  end