sequel 3.21.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 (200) hide show
  1. data/CHANGELOG +413 -3
  2. data/README.rdoc +20 -6
  3. data/Rakefile +23 -16
  4. data/bin/sequel +1 -5
  5. data/doc/association_basics.rdoc +210 -43
  6. data/doc/dataset_basics.rdoc +4 -4
  7. data/doc/mass_assignment.rdoc +54 -0
  8. data/doc/migration.rdoc +15 -538
  9. data/doc/model_hooks.rdoc +72 -27
  10. data/doc/opening_databases.rdoc +86 -50
  11. data/doc/prepared_statements.rdoc +40 -13
  12. data/doc/reflection.rdoc +8 -2
  13. data/doc/release_notes/3.22.0.txt +39 -0
  14. data/doc/release_notes/3.23.0.txt +172 -0
  15. data/doc/release_notes/3.24.0.txt +420 -0
  16. data/doc/release_notes/3.25.0.txt +88 -0
  17. data/doc/release_notes/3.26.0.txt +88 -0
  18. data/doc/release_notes/3.27.0.txt +82 -0
  19. data/doc/release_notes/3.28.0.txt +304 -0
  20. data/doc/release_notes/3.29.0.txt +459 -0
  21. data/doc/schema_modification.rdoc +547 -0
  22. data/doc/sharding.rdoc +7 -1
  23. data/doc/testing.rdoc +115 -0
  24. data/doc/transactions.rdoc +137 -0
  25. data/doc/virtual_rows.rdoc +2 -2
  26. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  27. data/lib/sequel/adapters/ado.rb +40 -18
  28. data/lib/sequel/adapters/amalgalite.rb +15 -7
  29. data/lib/sequel/adapters/db2.rb +175 -86
  30. data/lib/sequel/adapters/dbi.rb +15 -15
  31. data/lib/sequel/adapters/do/mysql.rb +0 -5
  32. data/lib/sequel/adapters/do/postgres.rb +0 -5
  33. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  34. data/lib/sequel/adapters/do.rb +17 -36
  35. data/lib/sequel/adapters/firebird.rb +27 -208
  36. data/lib/sequel/adapters/ibmdb.rb +448 -0
  37. data/lib/sequel/adapters/informix.rb +6 -23
  38. data/lib/sequel/adapters/jdbc/as400.rb +5 -31
  39. data/lib/sequel/adapters/jdbc/db2.rb +44 -0
  40. data/lib/sequel/adapters/jdbc/derby.rb +217 -0
  41. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  42. data/lib/sequel/adapters/jdbc/h2.rb +26 -17
  43. data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
  44. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  45. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  46. data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
  47. data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
  48. data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
  49. data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
  50. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  51. data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
  52. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  53. data/lib/sequel/adapters/jdbc.rb +107 -38
  54. data/lib/sequel/adapters/mock.rb +315 -0
  55. data/lib/sequel/adapters/mysql.rb +78 -182
  56. data/lib/sequel/adapters/mysql2.rb +24 -23
  57. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  58. data/lib/sequel/adapters/odbc/mssql.rb +0 -5
  59. data/lib/sequel/adapters/odbc.rb +28 -9
  60. data/lib/sequel/adapters/openbase.rb +2 -4
  61. data/lib/sequel/adapters/oracle.rb +349 -51
  62. data/lib/sequel/adapters/postgres.rb +169 -21
  63. data/lib/sequel/adapters/shared/access.rb +21 -6
  64. data/lib/sequel/adapters/shared/db2.rb +288 -0
  65. data/lib/sequel/adapters/shared/firebird.rb +214 -0
  66. data/lib/sequel/adapters/shared/informix.rb +45 -0
  67. data/lib/sequel/adapters/shared/mssql.rb +108 -65
  68. data/lib/sequel/adapters/shared/mysql.rb +56 -13
  69. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  70. data/lib/sequel/adapters/shared/oracle.rb +185 -34
  71. data/lib/sequel/adapters/shared/postgres.rb +107 -58
  72. data/lib/sequel/adapters/shared/progress.rb +0 -6
  73. data/lib/sequel/adapters/shared/sqlite.rb +168 -41
  74. data/lib/sequel/adapters/sqlite.rb +27 -18
  75. data/lib/sequel/adapters/swift/mysql.rb +9 -5
  76. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  77. data/lib/sequel/adapters/swift/sqlite.rb +6 -4
  78. data/lib/sequel/adapters/swift.rb +5 -5
  79. data/lib/sequel/adapters/tinytds.rb +152 -17
  80. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
  81. data/lib/sequel/ast_transformer.rb +190 -0
  82. data/lib/sequel/connection_pool/threaded.rb +3 -2
  83. data/lib/sequel/connection_pool.rb +1 -1
  84. data/lib/sequel/core.rb +46 -5
  85. data/lib/sequel/database/connecting.rb +5 -6
  86. data/lib/sequel/database/dataset.rb +4 -4
  87. data/lib/sequel/database/dataset_defaults.rb +59 -1
  88. data/lib/sequel/database/logging.rb +1 -1
  89. data/lib/sequel/database/misc.rb +100 -19
  90. data/lib/sequel/database/query.rb +153 -58
  91. data/lib/sequel/database/schema_generator.rb +8 -5
  92. data/lib/sequel/database/schema_methods.rb +59 -29
  93. data/lib/sequel/dataset/actions.rb +194 -57
  94. data/lib/sequel/dataset/features.rb +81 -8
  95. data/lib/sequel/dataset/graph.rb +8 -7
  96. data/lib/sequel/dataset/misc.rb +50 -23
  97. data/lib/sequel/dataset/mutation.rb +5 -6
  98. data/lib/sequel/dataset/prepared_statements.rb +32 -15
  99. data/lib/sequel/dataset/query.rb +223 -42
  100. data/lib/sequel/dataset/sql.rb +58 -61
  101. data/lib/sequel/dataset.rb +8 -0
  102. data/lib/sequel/exceptions.rb +4 -0
  103. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  104. data/lib/sequel/extensions/migration.rb +6 -4
  105. data/lib/sequel/extensions/named_timezones.rb +5 -0
  106. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  107. data/lib/sequel/extensions/to_dot.rb +95 -83
  108. data/lib/sequel/model/associations.rb +997 -331
  109. data/lib/sequel/model/base.rb +386 -129
  110. data/lib/sequel/model/errors.rb +1 -1
  111. data/lib/sequel/model/exceptions.rb +5 -1
  112. data/lib/sequel/model.rb +15 -8
  113. data/lib/sequel/plugins/association_pks.rb +22 -4
  114. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  115. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  116. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  117. data/lib/sequel/plugins/force_encoding.rb +6 -6
  118. data/lib/sequel/plugins/identity_map.rb +114 -7
  119. data/lib/sequel/plugins/many_through_many.rb +65 -7
  120. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  121. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  122. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  123. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  124. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  125. data/lib/sequel/plugins/serialization.rb +6 -1
  126. data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
  127. data/lib/sequel/plugins/sharding.rb +12 -25
  128. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  129. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  130. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  131. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  132. data/lib/sequel/sql.rb +107 -51
  133. data/lib/sequel/timezones.rb +44 -35
  134. data/lib/sequel/version.rb +1 -1
  135. data/spec/adapters/db2_spec.rb +146 -0
  136. data/spec/adapters/mssql_spec.rb +65 -29
  137. data/spec/adapters/mysql_spec.rb +122 -123
  138. data/spec/adapters/oracle_spec.rb +48 -76
  139. data/spec/adapters/postgres_spec.rb +213 -61
  140. data/spec/adapters/spec_helper.rb +6 -5
  141. data/spec/adapters/sqlite_spec.rb +35 -21
  142. data/spec/core/connection_pool_spec.rb +71 -92
  143. data/spec/core/core_sql_spec.rb +20 -31
  144. data/spec/core/database_spec.rb +729 -508
  145. data/spec/core/dataset_spec.rb +980 -1044
  146. data/spec/core/expression_filters_spec.rb +159 -42
  147. data/spec/core/mock_adapter_spec.rb +378 -0
  148. data/spec/core/object_graph_spec.rb +48 -114
  149. data/spec/core/schema_generator_spec.rb +3 -3
  150. data/spec/core/schema_spec.rb +298 -38
  151. data/spec/core/spec_helper.rb +6 -48
  152. data/spec/extensions/association_pks_spec.rb +38 -0
  153. data/spec/extensions/class_table_inheritance_spec.rb +1 -1
  154. data/spec/extensions/columns_introspection_spec.rb +91 -0
  155. data/spec/extensions/dataset_associations_spec.rb +199 -0
  156. data/spec/extensions/defaults_setter_spec.rb +64 -0
  157. data/spec/extensions/identity_map_spec.rb +162 -0
  158. data/spec/extensions/instance_hooks_spec.rb +71 -0
  159. data/spec/extensions/many_through_many_spec.rb +195 -20
  160. data/spec/extensions/migration_spec.rb +17 -17
  161. data/spec/extensions/named_timezones_spec.rb +22 -2
  162. data/spec/extensions/nested_attributes_spec.rb +4 -0
  163. data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
  164. data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
  165. data/spec/extensions/prepared_statements_spec.rb +72 -0
  166. data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
  167. data/spec/extensions/schema_dumper_spec.rb +2 -2
  168. data/spec/extensions/schema_spec.rb +13 -21
  169. data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
  170. data/spec/extensions/serialization_spec.rb +5 -8
  171. data/spec/extensions/single_table_inheritance_spec.rb +11 -0
  172. data/spec/extensions/spec_helper.rb +7 -1
  173. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  174. data/spec/extensions/to_dot_spec.rb +3 -5
  175. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  176. data/spec/extensions/xml_serializer_spec.rb +16 -4
  177. data/spec/integration/associations_test.rb +522 -21
  178. data/spec/integration/database_test.rb +4 -2
  179. data/spec/integration/dataset_test.rb +375 -62
  180. data/spec/integration/eager_loader_test.rb +19 -21
  181. data/spec/integration/model_test.rb +80 -1
  182. data/spec/integration/plugin_test.rb +304 -116
  183. data/spec/integration/prepared_statement_test.rb +200 -120
  184. data/spec/integration/schema_test.rb +161 -30
  185. data/spec/integration/spec_helper.rb +39 -30
  186. data/spec/integration/timezone_test.rb +38 -12
  187. data/spec/integration/transaction_test.rb +172 -5
  188. data/spec/integration/type_test.rb +17 -3
  189. data/spec/model/association_reflection_spec.rb +174 -7
  190. data/spec/model/associations_spec.rb +849 -661
  191. data/spec/model/base_spec.rb +255 -95
  192. data/spec/model/dataset_methods_spec.rb +7 -27
  193. data/spec/model/eager_loading_spec.rb +640 -676
  194. data/spec/model/hooks_spec.rb +309 -67
  195. data/spec/model/model_spec.rb +207 -167
  196. data/spec/model/plugins_spec.rb +24 -13
  197. data/spec/model/record_spec.rb +321 -218
  198. data/spec/model/spec_helper.rb +13 -71
  199. data/spec/model/validations_spec.rb +11 -0
  200. metadata +95 -38
@@ -45,22 +45,22 @@ describe "MySQL", '#create_table' do
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
@@ -82,6 +82,12 @@ 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
@@ -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,7 +136,7 @@ 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}]
@@ -220,12 +226,12 @@ describe "A MySQL dataset" do
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
@@ -293,43 +299,43 @@ describe "MySQL join expressions" do
293
299
  end
294
300
  specify "should support natural left joins" do
295
301
  @ds.join_table(:natural_left, :nodes).sql.should == \
296
- 'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
302
+ 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
297
303
  end
298
304
  specify "should support natural right joins" do
299
305
  @ds.join_table(:natural_right, :nodes).sql.should == \
300
- 'SELECT * FROM nodes NATURAL RIGHT JOIN nodes'
306
+ 'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
301
307
  end
302
308
  specify "should support natural left outer joins" do
303
309
  @ds.join_table(:natural_left_outer, :nodes).sql.should == \
304
- 'SELECT * FROM nodes NATURAL LEFT OUTER JOIN nodes'
310
+ 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
305
311
  end
306
312
  specify "should support natural right outer joins" do
307
313
  @ds.join_table(:natural_right_outer, :nodes).sql.should == \
308
- 'SELECT * FROM nodes NATURAL RIGHT OUTER JOIN nodes'
314
+ 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
309
315
  end
310
316
  specify "should support natural inner joins" do
311
317
  @ds.join_table(:natural_inner, :nodes).sql.should == \
312
- 'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
318
+ 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
313
319
  end
314
320
  specify "should support cross joins" do
315
321
  @ds.join_table(:cross, :nodes).sql.should == \
316
- 'SELECT * FROM nodes CROSS JOIN nodes'
322
+ 'SELECT * FROM `nodes` CROSS JOIN `nodes`'
317
323
  end
318
324
  specify "should support cross joins as inner joins if conditions are used" do
319
325
  @ds.join_table(:cross, :nodes, :id=>:id).sql.should == \
320
- 'SELECT * FROM nodes INNER JOIN nodes ON (nodes.id = nodes.id)'
326
+ 'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
321
327
  end
322
328
  specify "should support straight joins (force left table to be read before right)" do
323
329
  @ds.join_table(:straight, :nodes).sql.should == \
324
- 'SELECT * FROM nodes STRAIGHT_JOIN nodes'
330
+ 'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
325
331
  end
326
332
  specify "should support natural joins on multiple tables." do
327
333
  @ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.should == \
328
- 'SELECT * FROM nodes NATURAL LEFT OUTER JOIN (nodes, branches)'
334
+ 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
329
335
  end
330
336
  specify "should support straight joins on multiple tables." do
331
337
  @ds.join_table(:straight, [:nodes,:branches]).sql.should == \
332
- 'SELECT * FROM nodes STRAIGHT_JOIN (nodes, branches)'
338
+ 'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
333
339
  end
334
340
  end
335
341
 
@@ -348,12 +354,12 @@ describe "Joined MySQL dataset" do
348
354
  proc {@ds.having('blah')}.should_not raise_error
349
355
 
350
356
  @ds.having('blah').sql.should == \
351
- "SELECT * FROM nodes HAVING (blah)"
357
+ "SELECT * FROM `nodes` HAVING (blah)"
352
358
  end
353
359
 
354
360
  specify "should put a having clause before an order by clause" do
355
361
  @ds.order(:aaa).having(:bbb => :ccc).sql.should == \
356
- "SELECT * FROM nodes HAVING (bbb = ccc) ORDER BY aaa"
362
+ "SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
357
363
  end
358
364
  end
359
365
 
@@ -447,17 +453,17 @@ describe "A MySQL database with table options" do
447
453
 
448
454
  specify "should allow to pass custom options (engine, charset, collate) for table creation" do
449
455
  @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"]
456
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
451
457
  end
452
458
 
453
459
  specify "should use default options if specified (engine, charset, collate) for table creation" do
454
460
  @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"]
461
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
456
462
  end
457
463
 
458
464
  specify "should not use default if option has a nil value" do
459
465
  @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)"]
466
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text)"]
461
467
  end
462
468
  end
463
469
 
@@ -473,24 +479,24 @@ describe "A MySQL database" do
473
479
 
474
480
  specify "should support defaults for boolean columns" do
475
481
  @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)"]
482
+ @db.sqls.should == ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
477
483
  end
478
484
 
479
485
  specify "should correctly format CREATE TABLE statements with foreign keys" do
480
486
  @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)"]
487
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer, `p_id` integer NOT NULL, FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
482
488
  end
483
489
 
484
490
  specify "should correctly format ALTER TABLE statements with foreign keys" do
485
491
  @db.create_table(:items){Integer :id}
486
492
  @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"]
493
+ @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
494
  end
489
495
 
490
496
  specify "should have rename_column support keep existing options" do
491
497
  @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
492
498
  @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'"]
499
+ @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
500
  @db[:items].insert
495
501
  @db[:items].all.should == [{:nid=>'blah'}]
496
502
  proc{@db[:items].insert(:nid=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -499,7 +505,7 @@ describe "A MySQL database" do
499
505
  specify "should have set_column_type support keep existing options" do
500
506
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
501
507
  @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"]
508
+ @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
509
  @db[:items].insert
504
510
  @db[:items].all.should == [{:id=>5}]
505
511
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -511,13 +517,13 @@ describe "A MySQL database" do
511
517
  specify "should have set_column_type pass through options" do
512
518
  @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
513
519
  @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"]
520
+ @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
521
  end
516
522
 
517
523
  specify "should have set_column_default support keep existing options" do
518
524
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
519
525
  @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"]
526
+ @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
527
  @db[:items].insert
522
528
  @db[:items].all.should == [{:id=>6}]
523
529
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -526,7 +532,7 @@ describe "A MySQL database" do
526
532
  specify "should have set_column_allow_null support keep existing options" do
527
533
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
528
534
  @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"]
535
+ @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
536
  @db[:items].insert
531
537
  @db[:items].all.should == [{:id=>5}]
532
538
  proc{@db[:items].insert(:id=>nil)}.should_not
@@ -612,9 +618,9 @@ describe "A MySQL database" do
612
618
  specify "should support fulltext indexes and full_text_search" do
613
619
  @db.create_table(:posts){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
614
620
  @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)"
621
+ "CREATE TABLE `posts` (`title` text, `body` text)",
622
+ "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
623
+ "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
618
624
  ]
619
625
 
620
626
  @db[:posts].insert(:title=>'ruby rails', :body=>'y')
@@ -626,32 +632,32 @@ describe "A MySQL database" do
626
632
  @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
627
633
  @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.should == [{:title=>'ruby scooby', :body=>'x'}]
628
634
  @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))"]
635
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
636
+ "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
637
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
632
638
  end
633
639
 
634
640
  specify "should support spatial indexes" do
635
641
  @db.create_table(:posts){point :geom, :null=>false; spatial_index [:geom]}
636
642
  @db.sqls.should == [
637
- "CREATE TABLE posts (geom point NOT NULL)",
638
- "CREATE SPATIAL INDEX posts_geom_index ON posts (geom)"
643
+ "CREATE TABLE `posts` (`geom` point NOT NULL)",
644
+ "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
639
645
  ]
640
646
  end
641
647
 
642
648
  specify "should support indexes with index type" do
643
649
  @db.create_table(:posts){Integer :id; index :id, :type => :btree}
644
650
  @db.sqls.should == [
645
- "CREATE TABLE posts (id integer)",
646
- "CREATE INDEX posts_id_index USING btree ON posts (id)"
651
+ "CREATE TABLE `posts` (`id` integer)",
652
+ "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
647
653
  ]
648
654
  end
649
655
 
650
656
  specify "should support unique indexes with index type" do
651
657
  @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
652
658
  @db.sqls.should == [
653
- "CREATE TABLE posts (id integer)",
654
- "CREATE UNIQUE INDEX posts_id_index USING btree ON posts (id)"
659
+ "CREATE TABLE `posts` (`id` integer)",
660
+ "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
655
661
  ]
656
662
  end
657
663
 
@@ -680,38 +686,20 @@ describe "MySQL::Dataset#insert and related methods" do
680
686
 
681
687
  specify "#insert should insert record with default values when no arguments given" do
682
688
  @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
- ]
689
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
690
+ @d.all.should == [{:name => nil, :value => nil}]
691
691
  end
692
692
 
693
693
  specify "#insert should insert record with default values when empty hash given" do
694
694
  @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
- ]
695
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
696
+ @d.all.should == [{:name => nil, :value => nil}]
703
697
  end
704
698
 
705
699
  specify "#insert should insert record with default values when empty array given" do
706
700
  @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
- ]
701
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
702
+ @d.all.should == [{:name => nil, :value => nil}]
715
703
  end
716
704
 
717
705
  specify "#on_duplicate_key_update should work with regular inserts" do
@@ -722,9 +710,9 @@ describe "MySQL::Dataset#insert and related methods" do
722
710
  @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
723
711
 
724
712
  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/
713
+ MYSQL_DB.sqls[0].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/
714
+ 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/
715
+ 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
716
 
729
717
  @d.all.should == [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
730
718
  end
@@ -734,7 +722,7 @@ describe "MySQL::Dataset#insert and related methods" do
734
722
 
735
723
  MYSQL_DB.sqls.should == [
736
724
  SQL_BEGIN,
737
- "INSERT INTO items (name) VALUES ('abc'), ('def')",
725
+ "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
738
726
  SQL_COMMIT
739
727
  ]
740
728
 
@@ -749,10 +737,10 @@ describe "MySQL::Dataset#insert and related methods" do
749
737
 
750
738
  MYSQL_DB.sqls.should == [
751
739
  SQL_BEGIN,
752
- "INSERT INTO items (value) VALUES (1), (2)",
740
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
753
741
  SQL_COMMIT,
754
742
  SQL_BEGIN,
755
- "INSERT INTO items (value) VALUES (3), (4)",
743
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
756
744
  SQL_COMMIT
757
745
  ]
758
746
 
@@ -770,10 +758,10 @@ describe "MySQL::Dataset#insert and related methods" do
770
758
 
771
759
  MYSQL_DB.sqls.should == [
772
760
  SQL_BEGIN,
773
- "INSERT INTO items (value) VALUES (1), (2)",
761
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
774
762
  SQL_COMMIT,
775
763
  SQL_BEGIN,
776
- "INSERT INTO items (value) VALUES (3), (4)",
764
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
777
765
  SQL_COMMIT
778
766
  ]
779
767
 
@@ -790,7 +778,7 @@ describe "MySQL::Dataset#insert and related methods" do
790
778
 
791
779
  MYSQL_DB.sqls.should == [
792
780
  SQL_BEGIN,
793
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2)",
781
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
794
782
  SQL_COMMIT
795
783
  ]
796
784
 
@@ -805,7 +793,7 @@ describe "MySQL::Dataset#insert and related methods" do
805
793
 
806
794
  MYSQL_DB.sqls.should == [
807
795
  SQL_BEGIN,
808
- "INSERT IGNORE INTO items (name) VALUES ('abc'), ('def')",
796
+ "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
809
797
  SQL_COMMIT
810
798
  ]
811
799
 
@@ -816,7 +804,7 @@ describe "MySQL::Dataset#insert and related methods" do
816
804
 
817
805
  specify "#insert_ignore should add the IGNORE keyword for single inserts" do
818
806
  @d.insert_ignore.insert(:name => 'ghi')
819
- MYSQL_DB.sqls.should == ["INSERT IGNORE INTO items (name) VALUES ('ghi')"]
807
+ MYSQL_DB.sqls.should == ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
820
808
  @d.all.should == [{:name => 'ghi', :value => nil}]
821
809
  end
822
810
 
@@ -824,9 +812,9 @@ describe "MySQL::Dataset#insert and related methods" do
824
812
  @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
825
813
 
826
814
  MYSQL_DB.sqls.should == [
827
- "SELECT * FROM items LIMIT 1",
815
+ "SELECT * FROM `items` LIMIT 1",
828
816
  SQL_BEGIN,
829
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE name=VALUES(name), value=VALUES(value)",
817
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
830
818
  SQL_COMMIT
831
819
  ]
832
820
 
@@ -842,7 +830,7 @@ describe "MySQL::Dataset#insert and related methods" do
842
830
 
843
831
  MYSQL_DB.sqls.should == [
844
832
  SQL_BEGIN,
845
- "INSERT INTO items (name, value) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE value=VALUES(value)",
833
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
846
834
  SQL_COMMIT
847
835
  ]
848
836
 
@@ -901,25 +889,25 @@ describe "MySQL::Dataset#complex_expression_sql" do
901
889
  end
902
890
 
903
891
  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')"
892
+ @d.literal(:x.like('a')).should == "(`x` LIKE BINARY 'a')"
893
+ @d.literal(~:x.like('a')).should == "(`x` NOT LIKE BINARY 'a')"
894
+ @d.literal(:x.ilike('a')).should == "(`x` LIKE 'a')"
895
+ @d.literal(~:x.ilike('a')).should == "(`x` NOT LIKE 'a')"
896
+ @d.literal(:x.like(/a/)).should == "(`x` REGEXP BINARY 'a')"
897
+ @d.literal(~:x.like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
898
+ @d.literal(:x.like(/a/i)).should == "(`x` REGEXP 'a')"
899
+ @d.literal(~:x.like(/a/i)).should == "(`x` NOT REGEXP 'a')"
912
900
  end
913
901
 
914
902
  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)"
903
+ @d.literal([:x, :y].sql_string_join).should == "CONCAT(`x`, `y`)"
904
+ @d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(`x`, ' ', `y`)"
905
+ @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
906
  end
919
907
 
920
908
  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"
909
+ @d.literal([:x].sql_string_join).should == "`x`"
910
+ @d.literal([:x].sql_string_join(' ')).should == "`x`"
923
911
  end
924
912
  end
925
913
 
@@ -933,7 +921,7 @@ describe "MySQL::Dataset#calc_found_rows" do
933
921
 
934
922
  specify "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
935
923
  MYSQL_DB[:items].select(:a).calc_found_rows.limit(1).sql.should == \
936
- 'SELECT SQL_CALC_FOUND_ROWS a FROM items LIMIT 1'
924
+ 'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
937
925
  end
938
926
 
939
927
  specify "should count matching rows disregarding LIMIT clause" do
@@ -944,13 +932,13 @@ describe "MySQL::Dataset#calc_found_rows" do
944
932
  MYSQL_DB.dataset.select(:FOUND_ROWS.sql_function.as(:rows)).all.should == [{:rows => 2 }]
945
933
 
946
934
  MYSQL_DB.sqls.should == [
947
- 'SELECT SQL_CALC_FOUND_ROWS * FROM items WHERE (a = 1) LIMIT 1',
948
- 'SELECT FOUND_ROWS() AS rows',
935
+ 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
936
+ 'SELECT FOUND_ROWS() AS `rows`',
949
937
  ]
950
938
  end
951
939
  end
952
940
 
953
- if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
941
+ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc or MYSQL_DB.adapter_scheme == :mysql2
954
942
  describe "MySQL Stored Procedures" do
955
943
  before do
956
944
  MYSQL_DB.create_table(:items){Integer :id; Integer :value}
@@ -971,26 +959,37 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
971
959
  MYSQL_DB[:items].count.should == 0
972
960
  end
973
961
 
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}]
962
+ # Mysql2 doesn't support stored procedures that return result sets, probably because
963
+ # CLIENT_MULTI_RESULTS is not set.
964
+ unless MYSQL_DB.adapter_scheme == :mysql2
965
+ specify "should be callable on the dataset object" do
966
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
967
+ MYSQL_DB[:items].delete
968
+ @d = MYSQL_DB[:items]
969
+ @d.call_sproc(:select, :test_sproc, 3).should == []
970
+ @d.insert(:value=>1)
971
+ @d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
972
+ @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
973
+ @d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
974
+ end
975
+
976
+ specify "should be callable on the dataset object with multiple arguments" do
977
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
978
+ MYSQL_DB[:items].delete
979
+ @d = MYSQL_DB[:items]
980
+ @d.call_sproc(:select, :test_sproc, 3, 4).should == []
981
+ @d.insert(:value=>1)
982
+ @d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
983
+ @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
984
+ @d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
985
+ end
983
986
  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')
987
+
988
+ specify "should deal with nil values" do
989
+ MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
987
990
  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}]
991
+ MYSQL_DB.call_sproc(:test_sproc, :args=>[1, nil])
992
+ MYSQL_DB[:items].all.should == [{:id=>1, :value=>nil}]
994
993
  end
995
994
  end
996
995
  end
@@ -998,29 +997,29 @@ end
998
997
  if MYSQL_DB.adapter_scheme == :mysql
999
998
  describe "MySQL bad date/time conversions" do
1000
999
  after do
1001
- Sequel::MySQL.convert_invalid_date_time = false
1000
+ MYSQL_DB.convert_invalid_date_time = false
1002
1001
  end
1003
1002
 
1004
1003
  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
1004
+ MYSQL_DB.convert_invalid_date_time = false
1006
1005
  proc{MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value}.should raise_error(Sequel::InvalidValue)
1007
1006
  proc{MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.should raise_error(Sequel::InvalidValue)
1008
1007
  proc{MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value}.should raise_error(Sequel::InvalidValue)
1009
1008
  end
1010
1009
 
1011
1010
  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
1011
+ MYSQL_DB.convert_invalid_date_time = nil
1013
1012
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
1014
1013
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
1015
1014
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
1016
- Sequel::MySQL.convert_invalid_date_time = :nil
1015
+ MYSQL_DB.convert_invalid_date_time = :nil
1017
1016
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
1018
1017
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
1019
1018
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
1020
1019
  end
1021
1020
 
1022
1021
  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
1022
+ MYSQL_DB.convert_invalid_date_time = :string
1024
1023
  MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == '0000-00-00'
1025
1024
  MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == '0000-00-00 00:00:00'
1026
1025
  MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == '25:00:00'