sequel 3.21.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +485 -3
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +249 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +45 -0
- data/lib/sequel/adapters/jdbc/derby.rb +247 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +56 -29
- data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +335 -0
- data/lib/sequel/adapters/mysql.rb +82 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +351 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +321 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +231 -106
- data/lib/sequel/adapters/shared/mysql.rb +181 -63
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +231 -41
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +4 -7
- data/lib/sequel/adapters/shared/sqlite.rb +201 -57
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +231 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +48 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +665 -253
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1020 -337
- data/lib/sequel/model/base.rb +414 -132
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +88 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +111 -29
- data/spec/adapters/mysql_spec.rb +135 -123
- data/spec/adapters/oracle_spec.rb +49 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +788 -512
- data/spec/core/dataset_spec.rb +1073 -1053
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +72 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +537 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +461 -65
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +212 -122
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +865 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +115 -73
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
@@ -241,6 +247,16 @@ describe "A MySQL dataset" do
|
|
|
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
|
|
@@ -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
|
|
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
|
|
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
|
|
348
|
+
'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
|
|
333
349
|
end
|
|
334
350
|
end
|
|
335
351
|
|
|
@@ -348,12 +364,12 @@ describe "Joined MySQL dataset" 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
|
|
|
@@ -447,17 +463,17 @@ describe "A MySQL database with table options" do
|
|
|
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
|
|
|
@@ -473,24 +489,24 @@ describe "A MySQL database" do
|
|
|
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)
|
|
@@ -499,7 +515,7 @@ describe "A MySQL database" do
|
|
|
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,13 +527,13 @@ 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)
|
|
@@ -526,7 +542,7 @@ describe "A MySQL database" do
|
|
|
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
|
|
@@ -612,9 +628,9 @@ describe "A MySQL database" do
|
|
|
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
|
|
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')
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,9 +723,9 @@ 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)
|
|
726
|
-
MYSQL_DB.sqls[1].should =~ /\AINSERT INTO items \((name|value)
|
|
727
|
-
MYSQL_DB.sqls[2].should =~ /\AINSERT INTO items \((name|value)
|
|
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
|
|
@@ -734,7 +735,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
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,10 +750,10 @@ 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
|
|
|
@@ -770,10 +771,10 @@ 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
|
|
|
@@ -790,7 +791,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
790
791
|
|
|
791
792
|
MYSQL_DB.sqls.should == [
|
|
792
793
|
SQL_BEGIN,
|
|
793
|
-
"INSERT INTO items (name
|
|
794
|
+
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
|
|
794
795
|
SQL_COMMIT
|
|
795
796
|
]
|
|
796
797
|
|
|
@@ -805,7 +806,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
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
|
|
|
@@ -816,7 +817,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
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
|
|
|
@@ -824,9 +825,9 @@ describe "MySQL::Dataset#insert and related methods" 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
|
|
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
|
|
|
@@ -842,7 +843,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
842
843
|
|
|
843
844
|
MYSQL_DB.sqls.should == [
|
|
844
845
|
SQL_BEGIN,
|
|
845
|
-
"INSERT INTO items (name
|
|
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
|
|
|
@@ -901,25 +902,25 @@ describe "MySQL::Dataset#complex_expression_sql" do
|
|
|
901
902
|
end
|
|
902
903
|
|
|
903
904
|
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')"
|
|
905
|
+
@d.literal(:x.like('a')).should == "(`x` LIKE BINARY 'a')"
|
|
906
|
+
@d.literal(~:x.like('a')).should == "(`x` NOT LIKE BINARY 'a')"
|
|
907
|
+
@d.literal(:x.ilike('a')).should == "(`x` LIKE 'a')"
|
|
908
|
+
@d.literal(~:x.ilike('a')).should == "(`x` NOT LIKE 'a')"
|
|
909
|
+
@d.literal(:x.like(/a/)).should == "(`x` REGEXP BINARY 'a')"
|
|
910
|
+
@d.literal(~:x.like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
|
|
911
|
+
@d.literal(:x.like(/a/i)).should == "(`x` REGEXP 'a')"
|
|
912
|
+
@d.literal(~:x.like(/a/i)).should == "(`x` NOT REGEXP 'a')"
|
|
912
913
|
end
|
|
913
914
|
|
|
914
915
|
specify "should handle string concatenation with CONCAT if more than one record" do
|
|
915
|
-
@d.literal([:x, :y].sql_string_join).should == "CONCAT(x
|
|
916
|
-
@d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(x
|
|
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)"
|
|
916
|
+
@d.literal([:x, :y].sql_string_join).should == "CONCAT(`x`, `y`)"
|
|
917
|
+
@d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(`x`, ' ', `y`)"
|
|
918
|
+
@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
919
|
end
|
|
919
920
|
|
|
920
921
|
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"
|
|
922
|
+
@d.literal([:x].sql_string_join).should == "`x`"
|
|
923
|
+
@d.literal([:x].sql_string_join(' ')).should == "`x`"
|
|
923
924
|
end
|
|
924
925
|
end
|
|
925
926
|
|
|
@@ -933,7 +934,7 @@ describe "MySQL::Dataset#calc_found_rows" do
|
|
|
933
934
|
|
|
934
935
|
specify "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
|
|
935
936
|
MYSQL_DB[:items].select(:a).calc_found_rows.limit(1).sql.should == \
|
|
936
|
-
'SELECT SQL_CALC_FOUND_ROWS a FROM items LIMIT 1'
|
|
937
|
+
'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
|
|
937
938
|
end
|
|
938
939
|
|
|
939
940
|
specify "should count matching rows disregarding LIMIT clause" do
|
|
@@ -944,13 +945,13 @@ describe "MySQL::Dataset#calc_found_rows" do
|
|
|
944
945
|
MYSQL_DB.dataset.select(:FOUND_ROWS.sql_function.as(:rows)).all.should == [{:rows => 2 }]
|
|
945
946
|
|
|
946
947
|
MYSQL_DB.sqls.should == [
|
|
947
|
-
'SELECT SQL_CALC_FOUND_ROWS * FROM items WHERE (a = 1) LIMIT 1',
|
|
948
|
-
'SELECT FOUND_ROWS() AS rows',
|
|
948
|
+
'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
|
|
949
|
+
'SELECT FOUND_ROWS() AS `rows`',
|
|
949
950
|
]
|
|
950
951
|
end
|
|
951
952
|
end
|
|
952
953
|
|
|
953
|
-
if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
954
|
+
if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc or MYSQL_DB.adapter_scheme == :mysql2
|
|
954
955
|
describe "MySQL Stored Procedures" do
|
|
955
956
|
before do
|
|
956
957
|
MYSQL_DB.create_table(:items){Integer :id; Integer :value}
|
|
@@ -971,26 +972,37 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
|
971
972
|
MYSQL_DB[:items].count.should == 0
|
|
972
973
|
end
|
|
973
974
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
975
|
+
# Mysql2 doesn't support stored procedures that return result sets, probably because
|
|
976
|
+
# CLIENT_MULTI_RESULTS is not set.
|
|
977
|
+
unless MYSQL_DB.adapter_scheme == :mysql2
|
|
978
|
+
specify "should be callable on the dataset object" do
|
|
979
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
|
|
980
|
+
MYSQL_DB[:items].delete
|
|
981
|
+
@d = MYSQL_DB[:items]
|
|
982
|
+
@d.call_sproc(:select, :test_sproc, 3).should == []
|
|
983
|
+
@d.insert(:value=>1)
|
|
984
|
+
@d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
|
|
985
|
+
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
986
|
+
@d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
|
|
987
|
+
end
|
|
988
|
+
|
|
989
|
+
specify "should be callable on the dataset object with multiple arguments" do
|
|
990
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
|
|
991
|
+
MYSQL_DB[:items].delete
|
|
992
|
+
@d = MYSQL_DB[:items]
|
|
993
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == []
|
|
994
|
+
@d.insert(:value=>1)
|
|
995
|
+
@d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
|
|
996
|
+
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
997
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
|
|
998
|
+
end
|
|
983
999
|
end
|
|
984
|
-
|
|
985
|
-
specify "should
|
|
986
|
-
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(
|
|
1000
|
+
|
|
1001
|
+
specify "should deal with nil values" do
|
|
1002
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
|
|
987
1003
|
MYSQL_DB[:items].delete
|
|
988
|
-
|
|
989
|
-
|
|
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}]
|
|
1004
|
+
MYSQL_DB.call_sproc(:test_sproc, :args=>[1, nil])
|
|
1005
|
+
MYSQL_DB[:items].all.should == [{:id=>1, :value=>nil}]
|
|
994
1006
|
end
|
|
995
1007
|
end
|
|
996
1008
|
end
|
|
@@ -998,29 +1010,29 @@ end
|
|
|
998
1010
|
if MYSQL_DB.adapter_scheme == :mysql
|
|
999
1011
|
describe "MySQL bad date/time conversions" do
|
|
1000
1012
|
after do
|
|
1001
|
-
|
|
1013
|
+
MYSQL_DB.convert_invalid_date_time = false
|
|
1002
1014
|
end
|
|
1003
1015
|
|
|
1004
1016
|
specify "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
|
|
1005
|
-
|
|
1017
|
+
MYSQL_DB.convert_invalid_date_time = false
|
|
1006
1018
|
proc{MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1007
1019
|
proc{MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1008
1020
|
proc{MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1009
1021
|
end
|
|
1010
1022
|
|
|
1011
1023
|
specify "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
|
|
1012
|
-
|
|
1024
|
+
MYSQL_DB.convert_invalid_date_time = nil
|
|
1013
1025
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
|
|
1014
1026
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
|
|
1015
1027
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
|
|
1016
|
-
|
|
1028
|
+
MYSQL_DB.convert_invalid_date_time = :nil
|
|
1017
1029
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
|
|
1018
1030
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
|
|
1019
1031
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
|
|
1020
1032
|
end
|
|
1021
1033
|
|
|
1022
1034
|
specify "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
|
|
1023
|
-
|
|
1035
|
+
MYSQL_DB.convert_invalid_date_time = :string
|
|
1024
1036
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == '0000-00-00'
|
|
1025
1037
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == '0000-00-00 00:00:00'
|
|
1026
1038
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == '25:00:00'
|