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.
- data/CHANGELOG +539 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +293 -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/release_notes/3.32.0.txt +202 -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 +52 -0
- data/lib/sequel/adapters/jdbc/derby.rb +260 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +66 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -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 +88 -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 +339 -0
- data/lib/sequel/adapters/mysql.rb +85 -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 +355 -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 +328 -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 +278 -107
- data/lib/sequel/adapters/shared/mysql.rb +203 -65
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +237 -46
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +200 -50
- 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 +68 -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 +163 -59
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +240 -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 +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +59 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +676 -267
- 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/query.rb +1 -1
- 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 +1081 -344
- data/lib/sequel/model/base.rb +420 -133
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +20 -10
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +43 -10
- 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 +68 -7
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- 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 +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -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 +135 -30
- data/spec/adapters/mysql_spec.rb +244 -212
- data/spec/adapters/oracle_spec.rb +67 -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 +789 -512
- data/spec/core/dataset_spec.rb +1176 -1061
- 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/active_model_spec.rb +13 -0
- 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/query_spec.rb +6 -0
- 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 +72 -0
- data/spec/extensions/serialization_spec.rb +81 -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 +661 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +500 -67
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +367 -119
- data/spec/integration/prepared_statement_test.rb +222 -125
- data/spec/integration/schema_test.rb +217 -39
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +182 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +955 -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 +349 -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 +117 -73
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -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
|
-
|
|
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,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
|
-
|
|
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
|
|
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
|
|
|
@@ -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
|
|
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
|
|
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,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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)"
|
|
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
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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
|
|
986
|
-
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(
|
|
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
|
-
|
|
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}]
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|