sequel 4.22.0 → 4.23.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.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -30,35 +30,35 @@ describe "MySQL", '#create_table' do
|
|
|
30
30
|
@db.drop_table?(:dolls)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
it "should allow to specify options for MySQL" do
|
|
34
34
|
@db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
|
|
35
35
|
check_sqls do
|
|
36
|
-
@db.sqls.
|
|
36
|
+
@db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
it "should create a temporary table" do
|
|
41
41
|
@db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
|
|
42
42
|
check_sqls do
|
|
43
|
-
@db.sqls.
|
|
43
|
+
@db.sqls.must_equal ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
it "should not use a default for a String :text=>true type" do
|
|
48
48
|
@db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
|
|
49
49
|
check_sqls do
|
|
50
|
-
@db.sqls.
|
|
50
|
+
@db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text)"]
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
it "should not use a default for a File type" do
|
|
55
55
|
@db.create_table(:dolls){File :name, :default=>'blah'}
|
|
56
56
|
check_sqls do
|
|
57
|
-
@db.sqls.
|
|
57
|
+
@db.sqls.must_equal ["CREATE TABLE `dolls` (`name` blob)"]
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
it "should respect the size option for File type" do
|
|
62
62
|
@db.create_table(:dolls) do
|
|
63
63
|
File :n1
|
|
64
64
|
File :n2, :size=>:tiny
|
|
@@ -66,36 +66,36 @@ describe "MySQL", '#create_table' do
|
|
|
66
66
|
File :n4, :size=>:long
|
|
67
67
|
File :n5, :size=>255
|
|
68
68
|
end
|
|
69
|
-
@db.schema(:dolls).map{|k, v| v[:db_type]}.
|
|
69
|
+
@db.schema(:dolls).map{|k, v| v[:db_type]}.must_equal %w"blob tinyblob mediumblob longblob blob"
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
it "should include an :auto_increment schema attribute if auto incrementing" do
|
|
73
73
|
@db.create_table(:dolls) do
|
|
74
74
|
primary_key :n4
|
|
75
75
|
Integer :n2
|
|
76
76
|
String :n3
|
|
77
77
|
end
|
|
78
|
-
@db.schema(:dolls).map{|k, v| v[:auto_increment]}.
|
|
78
|
+
@db.schema(:dolls).map{|k, v| v[:auto_increment]}.must_equal [true, nil, nil]
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
it "should support collate with various other column options" do
|
|
82
82
|
@db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
|
|
83
83
|
@db[:dolls].insert
|
|
84
|
-
@db[:dolls].select_map(:name).
|
|
84
|
+
@db[:dolls].select_map(:name).must_equal ["foo"]
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
it "should be able to parse the default value for set and enum types" do
|
|
88
88
|
@db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
|
|
89
|
-
@db.schema(:dolls).first.last[:ruby_default].
|
|
89
|
+
@db.schema(:dolls).first.last[:ruby_default].must_equal 'a,b'
|
|
90
90
|
@db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
|
|
91
|
-
@db.schema(:dolls).first.last[:ruby_default].
|
|
91
|
+
@db.schema(:dolls).first.last[:ruby_default].must_equal 'b'
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
it "should allow setting auto_increment for existing column" do
|
|
95
95
|
@db.create_table(:dolls){Integer :a, :primary_key=>true}
|
|
96
|
-
@db.schema(:dolls).first.last[:auto_increment].
|
|
96
|
+
@db.schema(:dolls).first.last[:auto_increment].must_equal false
|
|
97
97
|
@db.set_column_type :dolls, :a, Integer, :auto_increment=>true
|
|
98
|
-
@db.schema(:dolls).first.last[:auto_increment].
|
|
98
|
+
@db.schema(:dolls).first.last[:auto_increment].must_equal true
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -111,51 +111,51 @@ if [:mysql, :mysql2].include?(DB.adapter_scheme)
|
|
|
111
111
|
@db.drop_table?(:booltest)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
@db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.
|
|
114
|
+
it "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
|
|
115
|
+
@db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:boolean, :integer]
|
|
116
116
|
@db.convert_tinyint_to_bool = false
|
|
117
|
-
@db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.
|
|
117
|
+
@db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:integer, :integer]
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
it "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
|
|
121
121
|
@db.convert_tinyint_to_bool = true
|
|
122
122
|
@ds.delete
|
|
123
123
|
@ds << {:b=>true, :i=>10}
|
|
124
|
-
@ds.all.
|
|
124
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
125
125
|
@ds.delete
|
|
126
126
|
@ds << {:b=>false, :i=>0}
|
|
127
|
-
@ds.all.
|
|
127
|
+
@ds.all.must_equal [{:b=>false, :i=>0}]
|
|
128
128
|
@ds.delete
|
|
129
129
|
@ds << {:b=>true, :i=>1}
|
|
130
|
-
@ds.all.
|
|
130
|
+
@ds.all.must_equal [{:b=>true, :i=>1}]
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
it "should return all tinyints as integers when unset" do
|
|
134
134
|
@db.convert_tinyint_to_bool = false
|
|
135
135
|
@ds.delete
|
|
136
136
|
@ds << {:b=>true, :i=>10}
|
|
137
|
-
@ds.all.
|
|
137
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
138
138
|
@ds.delete
|
|
139
139
|
@ds << {:b=>false, :i=>0}
|
|
140
|
-
@ds.all.
|
|
140
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
141
141
|
|
|
142
142
|
@ds.delete
|
|
143
143
|
@ds << {:b=>1, :i=>10}
|
|
144
|
-
@ds.all.
|
|
144
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
145
145
|
@ds.delete
|
|
146
146
|
@ds << {:b=>0, :i=>0}
|
|
147
|
-
@ds.all.
|
|
147
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
it "should allow disabling the conversion on a per-dataset basis" do
|
|
151
151
|
@db.convert_tinyint_to_bool = true
|
|
152
152
|
ds = @ds.clone
|
|
153
153
|
def ds.cast_tinyint_integer?(f) true end #mysql
|
|
154
154
|
def ds.convert_tinyint_to_bool?() false end #mysql2
|
|
155
155
|
ds.delete
|
|
156
156
|
ds << {:b=>true, :i=>10}
|
|
157
|
-
ds.all.
|
|
158
|
-
@ds.all.
|
|
157
|
+
ds.all.must_equal [{:b=>1, :i=>10}]
|
|
158
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
end
|
|
@@ -170,68 +170,68 @@ describe "A MySQL dataset" do
|
|
|
170
170
|
DB.drop_table?(:items)
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
it "should quote columns and tables using back-ticks if quoting identifiers" do
|
|
174
174
|
@d.quote_identifiers = true
|
|
175
|
-
@d.select(:name).sql.
|
|
176
|
-
@d.select(Sequel.lit('COUNT(*)')).sql.
|
|
177
|
-
@d.select(Sequel.function(:max, :value)).sql.
|
|
178
|
-
@d.select(Sequel.function(:NOW)).sql.
|
|
179
|
-
@d.select(Sequel.function(:max, :items__value)).sql.
|
|
180
|
-
@d.order(Sequel.expr(:name).desc).sql.
|
|
181
|
-
@d.select(Sequel.lit('items.name AS item_name')).sql.
|
|
182
|
-
@d.select(Sequel.lit('`name`')).sql.
|
|
183
|
-
@d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.
|
|
184
|
-
@d.select(Sequel.function(:test, :abc, 'hello')).sql.
|
|
185
|
-
@d.select(Sequel.function(:test, :abc__def, 'hello')).sql.
|
|
186
|
-
@d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.
|
|
187
|
-
@d.insert_sql(:value => 333).
|
|
188
|
-
@d.insert_sql(:x => :y).
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
|
|
175
|
+
@d.select(:name).sql.must_equal 'SELECT `name` FROM `items`'
|
|
176
|
+
@d.select(Sequel.lit('COUNT(*)')).sql.must_equal 'SELECT COUNT(*) FROM `items`'
|
|
177
|
+
@d.select(Sequel.function(:max, :value)).sql.must_equal 'SELECT max(`value`) FROM `items`'
|
|
178
|
+
@d.select(Sequel.function(:NOW)).sql.must_equal 'SELECT NOW() FROM `items`'
|
|
179
|
+
@d.select(Sequel.function(:max, :items__value)).sql.must_equal 'SELECT max(`items`.`value`) FROM `items`'
|
|
180
|
+
@d.order(Sequel.expr(:name).desc).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
|
|
181
|
+
@d.select(Sequel.lit('items.name AS item_name')).sql.must_equal 'SELECT items.name AS item_name FROM `items`'
|
|
182
|
+
@d.select(Sequel.lit('`name`')).sql.must_equal 'SELECT `name` FROM `items`'
|
|
183
|
+
@d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.must_equal 'SELECT max(items.`name`) AS `max_name` FROM `items`'
|
|
184
|
+
@d.select(Sequel.function(:test, :abc, 'hello')).sql.must_equal "SELECT test(`abc`, 'hello') FROM `items`"
|
|
185
|
+
@d.select(Sequel.function(:test, :abc__def, 'hello')).sql.must_equal "SELECT test(`abc`.`def`, 'hello') FROM `items`"
|
|
186
|
+
@d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.must_equal "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
|
|
187
|
+
@d.insert_sql(:value => 333).must_equal 'INSERT INTO `items` (`value`) VALUES (333)'
|
|
188
|
+
@d.insert_sql(:x => :y).must_equal 'INSERT INTO `items` (`x`) VALUES (`y`)'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should quote fields correctly when reversing the order" do
|
|
192
192
|
@d.quote_identifiers = true
|
|
193
|
-
@d.reverse_order(:name).sql.
|
|
194
|
-
@d.reverse_order(Sequel.desc(:name)).sql.
|
|
195
|
-
@d.reverse_order(:name, Sequel.desc(:test)).sql.
|
|
196
|
-
@d.reverse_order(Sequel.desc(:name), :test).sql.
|
|
193
|
+
@d.reverse_order(:name).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
|
|
194
|
+
@d.reverse_order(Sequel.desc(:name)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC'
|
|
195
|
+
@d.reverse_order(:name, Sequel.desc(:test)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
|
|
196
|
+
@d.reverse_order(Sequel.desc(:name), :test).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
@d.order(:name).update_sql(:value => 1).
|
|
199
|
+
it "should support ORDER clause in UPDATE statements" do
|
|
200
|
+
@d.order(:name).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
|
|
201
201
|
end
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
@d.limit(10).update_sql(:value => 1).
|
|
203
|
+
it "should support LIMIT clause in UPDATE statements" do
|
|
204
|
+
@d.limit(10).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 LIMIT 10'
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
it "should support regexps" do
|
|
208
208
|
@d << {:name => 'abc', :value => 1}
|
|
209
209
|
@d << {:name => 'bcd', :value => 2}
|
|
210
|
-
@d.filter(:name => /bc/).count.
|
|
211
|
-
@d.filter(:name => /^bc/).count.
|
|
210
|
+
@d.filter(:name => /bc/).count.must_equal 2
|
|
211
|
+
@d.filter(:name => /^bc/).count.must_equal 1
|
|
212
212
|
end
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
@d.explain.
|
|
216
|
-
@d.explain(:extended=>true).
|
|
217
|
-
@d.explain.
|
|
214
|
+
it "should have explain output" do
|
|
215
|
+
@d.explain.must_be_kind_of(String)
|
|
216
|
+
@d.explain(:extended=>true).must_be_kind_of(String)
|
|
217
|
+
@d.explain.wont_equal @d.explain(:extended=>true)
|
|
218
218
|
end
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
it "should correctly literalize strings with comment backslashes in them" do
|
|
221
221
|
@d.delete
|
|
222
|
-
|
|
222
|
+
@d << {:name => ':\\'}
|
|
223
223
|
|
|
224
|
-
@d.first[:name].
|
|
224
|
+
@d.first[:name].must_equal ':\\'
|
|
225
225
|
end
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
it "should handle prepared statements with on_duplicate_key_update" do
|
|
228
228
|
@d.db.add_index :items, :value, :unique=>true
|
|
229
229
|
ds = @d.on_duplicate_key_update
|
|
230
230
|
ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
|
|
231
231
|
ps.call(:v => 1, :n => 'a')
|
|
232
|
-
ds.all.
|
|
232
|
+
ds.all.must_equal [{:value=>1, :name=>'a'}]
|
|
233
233
|
ps.call(:v => 1, :n => 'b')
|
|
234
|
-
ds.all.
|
|
234
|
+
ds.all.must_equal [{:value=>1, :name=>'b'}]
|
|
235
235
|
end
|
|
236
236
|
end
|
|
237
237
|
|
|
@@ -240,13 +240,13 @@ describe "MySQL datasets" do
|
|
|
240
240
|
@d = DB[:orders]
|
|
241
241
|
end
|
|
242
242
|
|
|
243
|
-
|
|
243
|
+
it "should correctly quote column references" do
|
|
244
244
|
@d.quote_identifiers = true
|
|
245
245
|
market = 'ICE'
|
|
246
246
|
ack_stamp = Time.now - 15 * 60 # 15 minutes ago
|
|
247
247
|
@d.select(:market, Sequel.function(:minute, Sequel.function(:from_unixtime, :ack)).as(:minute)).
|
|
248
248
|
where{(ack > ack_stamp) & {:market => market}}.
|
|
249
|
-
group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.
|
|
249
|
+
group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.must_equal \
|
|
250
250
|
"SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
|
|
251
251
|
end
|
|
252
252
|
end
|
|
@@ -267,10 +267,10 @@ describe "Dataset#distinct" do
|
|
|
267
267
|
it "#distinct with arguments should return results distinct on those arguments" do
|
|
268
268
|
@ds.insert(20, 10)
|
|
269
269
|
@ds.insert(30, 10)
|
|
270
|
-
@ds.order(:b, :a).distinct.map(:a).
|
|
271
|
-
@ds.order(:b, Sequel.desc(:a)).distinct.map(:a).
|
|
270
|
+
@ds.order(:b, :a).distinct.map(:a).must_equal [20, 30]
|
|
271
|
+
@ds.order(:b, Sequel.desc(:a)).distinct.map(:a).must_equal [30, 20]
|
|
272
272
|
# MySQL doesn't respect orders when using the nonstandard GROUP BY
|
|
273
|
-
[[20], [30]].
|
|
273
|
+
[[20], [30]].must_include(@ds.order(:b, :a).distinct(:b).map(:a))
|
|
274
274
|
end
|
|
275
275
|
end
|
|
276
276
|
|
|
@@ -279,48 +279,38 @@ describe "MySQL join expressions" do
|
|
|
279
279
|
@ds = DB[:nodes]
|
|
280
280
|
end
|
|
281
281
|
|
|
282
|
-
|
|
283
|
-
lambda{@ds.join_table(:full_outer, :nodes)}.
|
|
282
|
+
it "should raise error for :full_outer join requests." do
|
|
283
|
+
lambda{@ds.join_table(:full_outer, :nodes)}.must_raise(Sequel::Error)
|
|
284
284
|
end
|
|
285
|
-
|
|
286
|
-
@ds.join_table(:natural_left, :nodes).sql.
|
|
287
|
-
'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
285
|
+
it "should support natural left joins" do
|
|
286
|
+
@ds.join_table(:natural_left, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
288
287
|
end
|
|
289
|
-
|
|
290
|
-
@ds.join_table(:natural_right, :nodes).sql.
|
|
291
|
-
'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
|
|
288
|
+
it "should support natural right joins" do
|
|
289
|
+
@ds.join_table(:natural_right, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
|
|
292
290
|
end
|
|
293
|
-
|
|
294
|
-
@ds.join_table(:natural_left_outer, :nodes).sql.
|
|
295
|
-
'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
|
|
291
|
+
it "should support natural left outer joins" do
|
|
292
|
+
@ds.join_table(:natural_left_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
|
|
296
293
|
end
|
|
297
|
-
|
|
298
|
-
@ds.join_table(:natural_right_outer, :nodes).sql.
|
|
299
|
-
'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
|
|
294
|
+
it "should support natural right outer joins" do
|
|
295
|
+
@ds.join_table(:natural_right_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
|
|
300
296
|
end
|
|
301
|
-
|
|
302
|
-
@ds.join_table(:natural_inner, :nodes).sql.
|
|
303
|
-
'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
297
|
+
it "should support natural inner joins" do
|
|
298
|
+
@ds.join_table(:natural_inner, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
304
299
|
end
|
|
305
|
-
|
|
306
|
-
@ds.join_table(:cross, :nodes).sql.
|
|
307
|
-
'SELECT * FROM `nodes` CROSS JOIN `nodes`'
|
|
300
|
+
it "should support cross joins" do
|
|
301
|
+
@ds.join_table(:cross, :nodes).sql.must_equal 'SELECT * FROM `nodes` CROSS JOIN `nodes`'
|
|
308
302
|
end
|
|
309
|
-
|
|
310
|
-
@ds.join_table(:cross, :nodes, :id=>:id).sql.
|
|
311
|
-
'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
|
|
303
|
+
it "should support cross joins as inner joins if conditions are used" do
|
|
304
|
+
@ds.join_table(:cross, :nodes, :id=>:id).sql.must_equal 'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
|
|
312
305
|
end
|
|
313
|
-
|
|
314
|
-
@ds.join_table(:straight, :nodes).sql.
|
|
315
|
-
'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
|
|
306
|
+
it "should support straight joins (force left table to be read before right)" do
|
|
307
|
+
@ds.join_table(:straight, :nodes).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
|
|
316
308
|
end
|
|
317
|
-
|
|
318
|
-
@ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.
|
|
319
|
-
'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
|
|
309
|
+
it "should support natural joins on multiple tables." do
|
|
310
|
+
@ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
|
|
320
311
|
end
|
|
321
|
-
|
|
322
|
-
@ds.join_table(:straight, [:nodes,:branches]).sql.
|
|
323
|
-
'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
|
|
312
|
+
it "should support straight joins on multiple tables." do
|
|
313
|
+
@ds.join_table(:straight, [:nodes,:branches]).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
|
|
324
314
|
end
|
|
325
315
|
end
|
|
326
316
|
|
|
@@ -329,22 +319,19 @@ describe "Joined MySQL dataset" do
|
|
|
329
319
|
@ds = DB[:nodes]
|
|
330
320
|
end
|
|
331
321
|
|
|
332
|
-
|
|
322
|
+
it "should quote fields correctly" do
|
|
333
323
|
@ds.quote_identifiers = true
|
|
334
|
-
@ds.join(:attributes, :node_id => :id).sql.
|
|
335
|
-
"SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
|
|
324
|
+
@ds.join(:attributes, :node_id => :id).sql.must_equal "SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
|
|
336
325
|
end
|
|
337
326
|
|
|
338
|
-
|
|
339
|
-
|
|
327
|
+
it "should allow a having clause on ungrouped datasets" do
|
|
328
|
+
@ds.having('blah')
|
|
340
329
|
|
|
341
|
-
@ds.having('blah').sql.
|
|
342
|
-
"SELECT * FROM `nodes` HAVING (blah)"
|
|
330
|
+
@ds.having('blah').sql.must_equal "SELECT * FROM `nodes` HAVING (blah)"
|
|
343
331
|
end
|
|
344
332
|
|
|
345
|
-
|
|
346
|
-
@ds.order(:aaa).having(:bbb => :ccc).sql.
|
|
347
|
-
"SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
|
|
333
|
+
it "should put a having clause before an order by clause" do
|
|
334
|
+
@ds.order(:aaa).having(:bbb => :ccc).sql.must_equal "SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
|
|
348
335
|
end
|
|
349
336
|
end
|
|
350
337
|
|
|
@@ -353,8 +340,8 @@ describe "A MySQL database" do
|
|
|
353
340
|
DB.drop_table?(:test_innodb)
|
|
354
341
|
end
|
|
355
342
|
|
|
356
|
-
|
|
357
|
-
|
|
343
|
+
it "should handle the creation and dropping of an InnoDB table with foreign keys" do
|
|
344
|
+
DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}
|
|
358
345
|
end
|
|
359
346
|
end
|
|
360
347
|
|
|
@@ -370,82 +357,70 @@ describe "A MySQL database" do
|
|
|
370
357
|
@db.drop_table?(:test2)
|
|
371
358
|
end
|
|
372
359
|
|
|
373
|
-
|
|
374
|
-
@db.server_version.
|
|
360
|
+
it "should provide the server version" do
|
|
361
|
+
@db.server_version.must_be :>=, 40000
|
|
375
362
|
end
|
|
376
363
|
|
|
377
|
-
|
|
364
|
+
it "should cache the server version" do
|
|
378
365
|
# warm cache:
|
|
379
366
|
@db.server_version
|
|
380
367
|
@db.sqls.clear
|
|
381
368
|
3.times{@db.server_version}
|
|
382
|
-
@db.sqls.
|
|
369
|
+
@db.sqls.must_be :empty?
|
|
383
370
|
end
|
|
384
371
|
|
|
385
|
-
|
|
386
|
-
@db
|
|
372
|
+
it "should support for_share" do
|
|
373
|
+
@db[:test2].delete
|
|
374
|
+
@db.transaction{@db[:test2].for_share.all.must_equal []}
|
|
387
375
|
end
|
|
388
376
|
|
|
389
|
-
|
|
377
|
+
it "should support column operations" do
|
|
390
378
|
@db.add_column :test2, :xyz, :text
|
|
391
379
|
|
|
392
|
-
@db[:test2].columns.
|
|
380
|
+
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
393
381
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => '000'}
|
|
394
|
-
@db[:test2].first[:xyz].
|
|
395
|
-
end
|
|
382
|
+
@db[:test2].first[:xyz].must_equal '000'
|
|
396
383
|
|
|
397
|
-
|
|
398
|
-
@db[:test2].columns.should == [:name, :value, :xyz]
|
|
384
|
+
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
399
385
|
@db.drop_column :test2, :xyz
|
|
400
386
|
|
|
401
|
-
@db[:test2].columns.
|
|
402
|
-
end
|
|
387
|
+
@db[:test2].columns.must_equal [:name, :value]
|
|
403
388
|
|
|
404
|
-
specify "should support rename_column operations" do
|
|
405
389
|
@db[:test2].delete
|
|
406
390
|
@db.add_column :test2, :xyz, :text
|
|
407
391
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
|
|
408
392
|
|
|
409
|
-
@db[:test2].columns.
|
|
393
|
+
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
410
394
|
@db.rename_column :test2, :xyz, :zyx, :type => :text
|
|
411
|
-
@db[:test2].columns.
|
|
412
|
-
@db[:test2].first[:zyx].
|
|
413
|
-
end
|
|
395
|
+
@db[:test2].columns.must_equal [:name, :value, :zyx]
|
|
396
|
+
@db[:test2].first[:zyx].must_equal 'qqqq'
|
|
414
397
|
|
|
415
|
-
specify "should support rename_column operations with types like varchar(255)" do
|
|
416
398
|
@db[:test2].delete
|
|
417
399
|
@db.add_column :test2, :tre, :text
|
|
418
400
|
@db[:test2] << {:name => 'mmm', :value => 111, :tre => 'qqqq'}
|
|
419
401
|
|
|
420
|
-
@db[:test2].columns.
|
|
402
|
+
@db[:test2].columns.must_equal [:name, :value, :zyx, :tre]
|
|
421
403
|
@db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
|
|
422
|
-
@db[:test2].columns.
|
|
423
|
-
@db[:test2].first[:ert].
|
|
424
|
-
end
|
|
404
|
+
@db[:test2].columns.must_equal [:name, :value, :zyx, :ert]
|
|
405
|
+
@db[:test2].first[:ert].must_equal 'qqqq'
|
|
425
406
|
|
|
426
|
-
specify "should support set_column_type operations" do
|
|
427
407
|
@db.add_column :test2, :xyz, :float
|
|
428
408
|
@db[:test2].delete
|
|
429
409
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
|
|
430
410
|
@db.set_column_type :test2, :xyz, :integer
|
|
431
411
|
|
|
432
|
-
@db[:test2].first[:xyz].
|
|
433
|
-
end
|
|
412
|
+
@db[:test2].first[:xyz].must_equal 57
|
|
434
413
|
|
|
435
|
-
specify "should support add_index" do
|
|
436
|
-
@db.add_index :test2, :value
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
specify "should support drop_index" do
|
|
440
|
-
@db.drop_index :test2, :value
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
specify "should support add_foreign_key" do
|
|
444
414
|
@db.alter_table :test2 do
|
|
445
415
|
add_index :value, :unique=>true
|
|
446
416
|
add_foreign_key :value2, :test2, :key=>:value
|
|
447
417
|
end
|
|
448
|
-
@db[:test2].columns.
|
|
418
|
+
@db[:test2].columns.must_equal [:name, :value, :zyx, :ert, :xyz, :value2]
|
|
419
|
+
|
|
420
|
+
@db.alter_table :test2 do
|
|
421
|
+
drop_foreign_key :value2
|
|
422
|
+
drop_index :value
|
|
423
|
+
end
|
|
449
424
|
end
|
|
450
425
|
end
|
|
451
426
|
|
|
@@ -470,24 +445,24 @@ describe "A MySQL database with table options" do
|
|
|
470
445
|
Sequel::MySQL.default_collate = nil
|
|
471
446
|
end
|
|
472
447
|
|
|
473
|
-
|
|
448
|
+
it "should allow to pass custom options (engine, charset, collate) for table creation" do
|
|
474
449
|
@db.create_table(:items, @options){Integer :size; text :name}
|
|
475
450
|
check_sqls do
|
|
476
|
-
@db.sqls.
|
|
451
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
|
|
477
452
|
end
|
|
478
453
|
end
|
|
479
454
|
|
|
480
|
-
|
|
455
|
+
it "should use default options if specified (engine, charset, collate) for table creation" do
|
|
481
456
|
@db.create_table(:items){Integer :size; text :name}
|
|
482
457
|
check_sqls do
|
|
483
|
-
@db.sqls.
|
|
458
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
|
|
484
459
|
end
|
|
485
460
|
end
|
|
486
461
|
|
|
487
|
-
|
|
462
|
+
it "should not use default if option has a nil value" do
|
|
488
463
|
@db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
|
|
489
464
|
check_sqls do
|
|
490
|
-
@db.sqls.
|
|
465
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text)"]
|
|
491
466
|
end
|
|
492
467
|
end
|
|
493
468
|
end
|
|
@@ -502,146 +477,146 @@ describe "A MySQL database" do
|
|
|
502
477
|
@db.drop_table?(:items, :users)
|
|
503
478
|
end
|
|
504
479
|
|
|
505
|
-
|
|
480
|
+
it "should support defaults for boolean columns" do
|
|
506
481
|
@db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
|
|
507
482
|
check_sqls do
|
|
508
|
-
@db.sqls.
|
|
483
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
|
|
509
484
|
end
|
|
510
485
|
end
|
|
511
486
|
|
|
512
|
-
|
|
487
|
+
it "should correctly format CREATE TABLE statements with foreign keys" do
|
|
513
488
|
@db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
|
|
514
489
|
check_sqls do
|
|
515
|
-
@db.sqls.
|
|
490
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
|
|
516
491
|
end
|
|
517
492
|
end
|
|
518
493
|
|
|
519
|
-
|
|
494
|
+
it "should correctly format CREATE TABLE statements with foreign keys, when :key != the default (:id)" do
|
|
520
495
|
@db.create_table(:items){primary_key :id; Integer :other_than_id; foreign_key :p_id, :items, :key => :other_than_id, :null => false, :on_delete => :cascade}
|
|
521
496
|
check_sqls do
|
|
522
|
-
@db.sqls.
|
|
497
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `other_than_id` integer, `p_id` integer NOT NULL, UNIQUE (`other_than_id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`other_than_id`) ON DELETE CASCADE)"]
|
|
523
498
|
end
|
|
524
499
|
end
|
|
525
500
|
|
|
526
|
-
|
|
501
|
+
it "should correctly format ALTER TABLE statements with foreign keys" do
|
|
527
502
|
@db.create_table(:items){Integer :id}
|
|
528
503
|
@db.create_table(:users){primary_key :id}
|
|
529
504
|
@db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
|
|
530
505
|
check_sqls do
|
|
531
|
-
@db.sqls.
|
|
506
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
|
|
532
507
|
"CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
|
|
533
508
|
"ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
|
|
534
509
|
end
|
|
535
510
|
end
|
|
536
511
|
|
|
537
|
-
|
|
512
|
+
it "should correctly format ALTER TABLE statements with named foreign keys" do
|
|
538
513
|
@db.create_table(:items){Integer :id}
|
|
539
514
|
@db.create_table(:users){primary_key :id}
|
|
540
515
|
@db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade, :foreign_key_constraint_name => :pk_items__users }
|
|
541
516
|
check_sqls do
|
|
542
|
-
@db.sqls.
|
|
517
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
|
|
543
518
|
"CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
|
|
544
519
|
"ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD CONSTRAINT `pk_items__users` FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
|
|
545
520
|
end
|
|
546
521
|
end
|
|
547
522
|
|
|
548
|
-
|
|
523
|
+
it "should have rename_column support keep existing options" do
|
|
549
524
|
@db.create_table(:items){String :id, :null=>false, :default=>'blah'}
|
|
550
525
|
@db.alter_table(:items){rename_column :id, :nid}
|
|
551
526
|
check_sqls do
|
|
552
|
-
@db.sqls.
|
|
527
|
+
@db.sqls.must_equal ["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'"]
|
|
553
528
|
end
|
|
554
529
|
@db[:items].insert
|
|
555
|
-
@db[:items].all.
|
|
556
|
-
proc{@db[:items].insert(:nid=>nil)}.
|
|
530
|
+
@db[:items].all.must_equal [{:nid=>'blah'}]
|
|
531
|
+
proc{@db[:items].insert(:nid=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
|
|
557
532
|
end
|
|
558
533
|
|
|
559
|
-
|
|
534
|
+
it "should have set_column_type support keep existing options" do
|
|
560
535
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
561
536
|
@db.alter_table(:items){set_column_type :id, Bignum}
|
|
562
537
|
check_sqls do
|
|
563
|
-
@db.sqls.
|
|
538
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
|
|
564
539
|
end
|
|
565
540
|
@db[:items].insert
|
|
566
|
-
@db[:items].all.
|
|
567
|
-
proc{@db[:items].insert(:id=>nil)}.
|
|
541
|
+
@db[:items].all.must_equal [{:id=>5}]
|
|
542
|
+
proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
|
|
568
543
|
@db[:items].delete
|
|
569
544
|
@db[:items].insert(2**40)
|
|
570
|
-
@db[:items].all.
|
|
545
|
+
@db[:items].all.must_equal [{:id=>2**40}]
|
|
571
546
|
end
|
|
572
547
|
|
|
573
|
-
|
|
548
|
+
it "should have set_column_type pass through options" do
|
|
574
549
|
@db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
|
|
575
550
|
@db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
|
|
576
551
|
check_sqls do
|
|
577
|
-
@db.sqls.
|
|
552
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
|
|
578
553
|
end
|
|
579
554
|
end
|
|
580
555
|
|
|
581
|
-
|
|
556
|
+
it "should have set_column_default support keep existing options" do
|
|
582
557
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
583
558
|
@db.alter_table(:items){set_column_default :id, 6}
|
|
584
559
|
check_sqls do
|
|
585
|
-
@db.sqls.
|
|
560
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
|
|
586
561
|
end
|
|
587
562
|
@db[:items].insert
|
|
588
|
-
@db[:items].all.
|
|
589
|
-
proc{@db[:items].insert(:id=>nil)}.
|
|
563
|
+
@db[:items].all.must_equal [{:id=>6}]
|
|
564
|
+
proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
|
|
590
565
|
end
|
|
591
566
|
|
|
592
|
-
|
|
567
|
+
it "should have set_column_allow_null support keep existing options" do
|
|
593
568
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
594
569
|
@db.alter_table(:items){set_column_allow_null :id, true}
|
|
595
570
|
check_sqls do
|
|
596
|
-
@db.sqls.
|
|
571
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
|
|
597
572
|
end
|
|
598
573
|
@db[:items].insert
|
|
599
|
-
@db[:items].all.
|
|
600
|
-
|
|
574
|
+
@db[:items].all.must_equal [{:id=>5}]
|
|
575
|
+
@db[:items].insert(:id=>nil)
|
|
601
576
|
end
|
|
602
577
|
|
|
603
|
-
|
|
578
|
+
it "should accept repeated raw sql statements using Database#<<" do
|
|
604
579
|
@db.create_table(:items){String :name; Integer :value}
|
|
605
580
|
@db << 'DELETE FROM items'
|
|
606
|
-
@db[:items].count.
|
|
581
|
+
@db[:items].count.must_equal 0
|
|
607
582
|
|
|
608
583
|
@db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
|
|
609
|
-
@db[:items].first.
|
|
584
|
+
@db[:items].first.must_equal(:name => 'tutu', :value => 1234)
|
|
610
585
|
|
|
611
586
|
@db << 'DELETE FROM items'
|
|
612
|
-
@db[:items].first.
|
|
587
|
+
@db[:items].first.must_equal nil
|
|
613
588
|
end
|
|
614
589
|
end
|
|
615
590
|
|
|
616
591
|
# Socket tests should only be run if the MySQL server is on localhost
|
|
617
592
|
if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and DB.adapter_scheme == :mysql
|
|
618
593
|
describe "A MySQL database" do
|
|
619
|
-
|
|
594
|
+
it "should accept a socket option" do
|
|
620
595
|
db = Sequel.mysql(DB.opts[:database], :host => 'localhost', :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
|
|
621
|
-
|
|
596
|
+
db.test_connection
|
|
622
597
|
end
|
|
623
598
|
|
|
624
|
-
|
|
599
|
+
it "should accept a socket option without host option" do
|
|
625
600
|
db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
|
|
626
|
-
|
|
601
|
+
db.test_connection
|
|
627
602
|
end
|
|
628
603
|
|
|
629
|
-
|
|
604
|
+
it "should fail to connect with invalid socket" do
|
|
630
605
|
db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket =>'blah')
|
|
631
|
-
proc
|
|
606
|
+
proc{db.test_connection}.must_raise Sequel::DatabaseConnectionError
|
|
632
607
|
end
|
|
633
608
|
end
|
|
634
609
|
end
|
|
635
610
|
|
|
636
611
|
describe "A MySQL database" do
|
|
637
|
-
|
|
612
|
+
it "should accept a read_timeout option when connecting" do
|
|
638
613
|
db = Sequel.connect(DB.opts.merge(:read_timeout=>22342))
|
|
639
|
-
|
|
614
|
+
db.test_connection
|
|
640
615
|
end
|
|
641
616
|
|
|
642
|
-
|
|
617
|
+
it "should accept a connect_timeout option when connecting" do
|
|
643
618
|
db = Sequel.connect(DB.opts.merge(:connect_timeout=>22342))
|
|
644
|
-
|
|
619
|
+
db.test_connection
|
|
645
620
|
end
|
|
646
621
|
end
|
|
647
622
|
|
|
@@ -650,42 +625,42 @@ describe "MySQL foreign key support" do
|
|
|
650
625
|
DB.drop_table?(:testfk, :testpk)
|
|
651
626
|
end
|
|
652
627
|
|
|
653
|
-
|
|
628
|
+
it "should create table without :key" do
|
|
654
629
|
DB.create_table!(:testpk){primary_key :id}
|
|
655
630
|
DB.create_table!(:testfk){foreign_key :fk, :testpk}
|
|
656
631
|
end
|
|
657
632
|
|
|
658
|
-
|
|
633
|
+
it "should create table with composite keys without :key" do
|
|
659
634
|
DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
|
|
660
635
|
DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
|
|
661
636
|
end
|
|
662
637
|
|
|
663
|
-
|
|
638
|
+
it "should create table with self referential without :key" do
|
|
664
639
|
DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
|
|
665
640
|
end
|
|
666
641
|
|
|
667
|
-
|
|
642
|
+
it "should create table with self referential with composite keys without :key" do
|
|
668
643
|
DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
|
|
669
644
|
end
|
|
670
645
|
|
|
671
|
-
|
|
646
|
+
it "should alter table without :key" do
|
|
672
647
|
DB.create_table!(:testpk){primary_key :id}
|
|
673
648
|
DB.create_table!(:testfk){Integer :id}
|
|
674
649
|
DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
|
|
675
650
|
end
|
|
676
651
|
|
|
677
|
-
|
|
652
|
+
it "should alter table with composite keys without :key" do
|
|
678
653
|
DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
|
|
679
654
|
DB.create_table!(:testfk){Integer :fk; Integer :fk2}
|
|
680
655
|
DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
|
|
681
656
|
end
|
|
682
657
|
|
|
683
|
-
|
|
658
|
+
it "should alter table with self referential without :key" do
|
|
684
659
|
DB.create_table!(:testfk){primary_key :id}
|
|
685
660
|
DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
|
|
686
661
|
end
|
|
687
662
|
|
|
688
|
-
|
|
663
|
+
it "should alter table with self referential with composite keys without :key" do
|
|
689
664
|
DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
|
|
690
665
|
DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
|
|
691
666
|
end
|
|
@@ -708,14 +683,14 @@ describe "A grouped MySQL dataset" do
|
|
|
708
683
|
DB.drop_table?(:test2)
|
|
709
684
|
end
|
|
710
685
|
|
|
711
|
-
|
|
686
|
+
it "should return the correct count for raw sql query" do
|
|
712
687
|
ds = DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
|
|
713
|
-
ds.count.
|
|
688
|
+
ds.count.must_equal 1
|
|
714
689
|
end
|
|
715
690
|
|
|
716
|
-
|
|
691
|
+
it "should return the correct count for a normal dataset" do
|
|
717
692
|
ds = DB[:test2].select(:name).where(:name => '11').group(:name)
|
|
718
|
-
ds.count.
|
|
693
|
+
ds.count.must_equal 1
|
|
719
694
|
end
|
|
720
695
|
end
|
|
721
696
|
|
|
@@ -729,10 +704,10 @@ describe "A MySQL database" do
|
|
|
729
704
|
@db.drop_table?(:posts)
|
|
730
705
|
end
|
|
731
706
|
|
|
732
|
-
|
|
707
|
+
it "should support fulltext indexes and full_text_search" do
|
|
733
708
|
@db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
|
|
734
709
|
check_sqls do
|
|
735
|
-
@db.sqls.
|
|
710
|
+
@db.sqls.must_equal [
|
|
736
711
|
"CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
|
|
737
712
|
"CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
|
|
738
713
|
"CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
|
|
@@ -744,60 +719,60 @@ describe "A MySQL database" do
|
|
|
744
719
|
@db[:posts].insert(:title=>'ruby scooby', :body=>'x')
|
|
745
720
|
@db.sqls.clear
|
|
746
721
|
|
|
747
|
-
@db[:posts].full_text_search(:title, 'rails').all.
|
|
748
|
-
@db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.
|
|
749
|
-
@db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.
|
|
722
|
+
@db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
|
|
723
|
+
@db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
|
|
724
|
+
@db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.must_equal [{:title=>'ruby scooby', :body=>'x'}]
|
|
750
725
|
check_sqls do
|
|
751
|
-
@db.sqls.
|
|
726
|
+
@db.sqls.must_equal [
|
|
752
727
|
"SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
|
|
753
728
|
"SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
|
|
754
729
|
"SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
|
|
755
730
|
end
|
|
756
731
|
|
|
757
|
-
@db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').
|
|
758
|
-
@db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').
|
|
732
|
+
@db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
|
|
733
|
+
@db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
|
|
759
734
|
end
|
|
760
735
|
|
|
761
|
-
|
|
736
|
+
it "should support spatial indexes" do
|
|
762
737
|
@db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
|
|
763
738
|
check_sqls do
|
|
764
|
-
@db.sqls.
|
|
739
|
+
@db.sqls.must_equal [
|
|
765
740
|
"CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
|
|
766
741
|
"CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
|
|
767
742
|
]
|
|
768
743
|
end
|
|
769
744
|
end
|
|
770
745
|
|
|
771
|
-
|
|
746
|
+
it "should support indexes with index type" do
|
|
772
747
|
@db.create_table(:posts){Integer :id; index :id, :type => :btree}
|
|
773
748
|
check_sqls do
|
|
774
|
-
@db.sqls.
|
|
749
|
+
@db.sqls.must_equal [
|
|
775
750
|
"CREATE TABLE `posts` (`id` integer)",
|
|
776
751
|
"CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
|
|
777
752
|
]
|
|
778
753
|
end
|
|
779
754
|
end
|
|
780
755
|
|
|
781
|
-
|
|
756
|
+
it "should support unique indexes with index type" do
|
|
782
757
|
@db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
|
|
783
758
|
check_sqls do
|
|
784
|
-
@db.sqls.
|
|
759
|
+
@db.sqls.must_equal [
|
|
785
760
|
"CREATE TABLE `posts` (`id` integer)",
|
|
786
761
|
"CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
|
|
787
762
|
]
|
|
788
763
|
end
|
|
789
764
|
end
|
|
790
765
|
|
|
791
|
-
|
|
766
|
+
it "should not dump partial indexes" do
|
|
792
767
|
@db.create_table(:posts){text :id}
|
|
793
768
|
@db << "CREATE INDEX posts_id_index ON posts (id(10))"
|
|
794
|
-
@db.indexes(:posts).
|
|
769
|
+
@db.indexes(:posts).must_equal({})
|
|
795
770
|
end
|
|
796
771
|
|
|
797
|
-
|
|
772
|
+
it "should dump partial indexes if :partial option is set to true" do
|
|
798
773
|
@db.create_table(:posts){text :id}
|
|
799
774
|
@db << "CREATE INDEX posts_id_index ON posts (id(10))"
|
|
800
|
-
@db.indexes(:posts, :partial => true).
|
|
775
|
+
@db.indexes(:posts, :partial => true).must_equal(:posts_id_index => {:columns => [:id], :unique => false})
|
|
801
776
|
end
|
|
802
777
|
end
|
|
803
778
|
|
|
@@ -811,31 +786,31 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
811
786
|
DB.drop_table?(:items)
|
|
812
787
|
end
|
|
813
788
|
|
|
814
|
-
|
|
789
|
+
it "#insert should insert record with default values when no arguments given" do
|
|
815
790
|
@d.insert
|
|
816
791
|
check_sqls do
|
|
817
|
-
DB.sqls.
|
|
792
|
+
DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
|
|
818
793
|
end
|
|
819
|
-
@d.all.
|
|
794
|
+
@d.all.must_equal [{:name => nil, :value => nil}]
|
|
820
795
|
end
|
|
821
796
|
|
|
822
|
-
|
|
797
|
+
it "#insert should insert record with default values when empty hash given" do
|
|
823
798
|
@d.insert({})
|
|
824
799
|
check_sqls do
|
|
825
|
-
DB.sqls.
|
|
800
|
+
DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
|
|
826
801
|
end
|
|
827
|
-
@d.all.
|
|
802
|
+
@d.all.must_equal [{:name => nil, :value => nil}]
|
|
828
803
|
end
|
|
829
804
|
|
|
830
|
-
|
|
805
|
+
it "#insert should insert record with default values when empty array given" do
|
|
831
806
|
@d.insert []
|
|
832
807
|
check_sqls do
|
|
833
|
-
DB.sqls.
|
|
808
|
+
DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
|
|
834
809
|
end
|
|
835
|
-
@d.all.
|
|
810
|
+
@d.all.must_equal [{:name => nil, :value => nil}]
|
|
836
811
|
end
|
|
837
812
|
|
|
838
|
-
|
|
813
|
+
it "#on_duplicate_key_update should work with regular inserts" do
|
|
839
814
|
DB.add_index :items, :name, :unique=>true
|
|
840
815
|
DB.sqls.clear
|
|
841
816
|
@d.insert(:name => 'abc', :value => 1)
|
|
@@ -843,37 +818,37 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
843
818
|
@d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
|
|
844
819
|
|
|
845
820
|
check_sqls do
|
|
846
|
-
DB.sqls.length.
|
|
847
|
-
DB.sqls[0].
|
|
848
|
-
DB.sqls[1].
|
|
849
|
-
DB.sqls[2].
|
|
821
|
+
DB.sqls.length.must_equal 3
|
|
822
|
+
DB.sqls[0].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/)
|
|
823
|
+
DB.sqls[1].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
|
|
824
|
+
DB.sqls[2].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
|
|
850
825
|
end
|
|
851
826
|
|
|
852
|
-
@d.all.
|
|
827
|
+
@d.all.must_equal [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
|
|
853
828
|
end
|
|
854
829
|
|
|
855
|
-
|
|
830
|
+
it "#multi_replace should insert multiple records in a single statement" do
|
|
856
831
|
@d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
|
|
857
832
|
|
|
858
833
|
check_sqls do
|
|
859
|
-
DB.sqls.
|
|
834
|
+
DB.sqls.must_equal [
|
|
860
835
|
SQL_BEGIN,
|
|
861
836
|
"REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
862
837
|
SQL_COMMIT
|
|
863
838
|
]
|
|
864
839
|
end
|
|
865
840
|
|
|
866
|
-
@d.all.
|
|
841
|
+
@d.all.must_equal [
|
|
867
842
|
{:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
|
|
868
843
|
]
|
|
869
844
|
end
|
|
870
845
|
|
|
871
|
-
|
|
846
|
+
it "#multi_replace should split the list of records into batches if :commit_every option is given" do
|
|
872
847
|
@d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
873
848
|
:commit_every => 2)
|
|
874
849
|
|
|
875
850
|
check_sqls do
|
|
876
|
-
DB.sqls.
|
|
851
|
+
DB.sqls.must_equal [
|
|
877
852
|
SQL_BEGIN,
|
|
878
853
|
"REPLACE INTO `items` (`value`) VALUES (1), (2)",
|
|
879
854
|
SQL_COMMIT,
|
|
@@ -883,7 +858,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
883
858
|
]
|
|
884
859
|
end
|
|
885
860
|
|
|
886
|
-
@d.all.
|
|
861
|
+
@d.all.must_equal [
|
|
887
862
|
{:name => nil, :value => 1},
|
|
888
863
|
{:name => nil, :value => 2},
|
|
889
864
|
{:name => nil, :value => 3},
|
|
@@ -891,12 +866,12 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
891
866
|
]
|
|
892
867
|
end
|
|
893
868
|
|
|
894
|
-
|
|
869
|
+
it "#multi_replace should split the list of records into batches if :slice option is given" do
|
|
895
870
|
@d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
896
871
|
:slice => 2)
|
|
897
872
|
|
|
898
873
|
check_sqls do
|
|
899
|
-
DB.sqls.
|
|
874
|
+
DB.sqls.must_equal [
|
|
900
875
|
SQL_BEGIN,
|
|
901
876
|
"REPLACE INTO `items` (`value`) VALUES (1), (2)",
|
|
902
877
|
SQL_COMMIT,
|
|
@@ -906,7 +881,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
906
881
|
]
|
|
907
882
|
end
|
|
908
883
|
|
|
909
|
-
@d.all.
|
|
884
|
+
@d.all.must_equal [
|
|
910
885
|
{:name => nil, :value => 1},
|
|
911
886
|
{:name => nil, :value => 2},
|
|
912
887
|
{:name => nil, :value => 3},
|
|
@@ -914,28 +889,28 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
914
889
|
]
|
|
915
890
|
end
|
|
916
891
|
|
|
917
|
-
|
|
892
|
+
it "#multi_insert should insert multiple records in a single statement" do
|
|
918
893
|
@d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
|
|
919
894
|
|
|
920
895
|
check_sqls do
|
|
921
|
-
DB.sqls.
|
|
896
|
+
DB.sqls.must_equal [
|
|
922
897
|
SQL_BEGIN,
|
|
923
898
|
"INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
924
899
|
SQL_COMMIT
|
|
925
900
|
]
|
|
926
901
|
end
|
|
927
902
|
|
|
928
|
-
@d.all.
|
|
903
|
+
@d.all.must_equal [
|
|
929
904
|
{:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
|
|
930
905
|
]
|
|
931
906
|
end
|
|
932
907
|
|
|
933
|
-
|
|
908
|
+
it "#multi_insert should split the list of records into batches if :commit_every option is given" do
|
|
934
909
|
@d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
935
910
|
:commit_every => 2)
|
|
936
911
|
|
|
937
912
|
check_sqls do
|
|
938
|
-
DB.sqls.
|
|
913
|
+
DB.sqls.must_equal [
|
|
939
914
|
SQL_BEGIN,
|
|
940
915
|
"INSERT INTO `items` (`value`) VALUES (1), (2)",
|
|
941
916
|
SQL_COMMIT,
|
|
@@ -945,7 +920,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
945
920
|
]
|
|
946
921
|
end
|
|
947
922
|
|
|
948
|
-
@d.all.
|
|
923
|
+
@d.all.must_equal [
|
|
949
924
|
{:name => nil, :value => 1},
|
|
950
925
|
{:name => nil, :value => 2},
|
|
951
926
|
{:name => nil, :value => 3},
|
|
@@ -953,12 +928,12 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
953
928
|
]
|
|
954
929
|
end
|
|
955
930
|
|
|
956
|
-
|
|
931
|
+
it "#multi_insert should split the list of records into batches if :slice option is given" do
|
|
957
932
|
@d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
958
933
|
:slice => 2)
|
|
959
934
|
|
|
960
935
|
check_sqls do
|
|
961
|
-
DB.sqls.
|
|
936
|
+
DB.sqls.must_equal [
|
|
962
937
|
SQL_BEGIN,
|
|
963
938
|
"INSERT INTO `items` (`value`) VALUES (1), (2)",
|
|
964
939
|
SQL_COMMIT,
|
|
@@ -968,7 +943,7 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
968
943
|
]
|
|
969
944
|
end
|
|
970
945
|
|
|
971
|
-
@d.all.
|
|
946
|
+
@d.all.must_equal [
|
|
972
947
|
{:name => nil, :value => 1},
|
|
973
948
|
{:name => nil, :value => 2},
|
|
974
949
|
{:name => nil, :value => 3},
|
|
@@ -976,52 +951,52 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
976
951
|
]
|
|
977
952
|
end
|
|
978
953
|
|
|
979
|
-
|
|
954
|
+
it "#import should support inserting using columns and values arrays" do
|
|
980
955
|
@d.import([:name, :value], [['abc', 1], ['def', 2]])
|
|
981
956
|
|
|
982
957
|
check_sqls do
|
|
983
|
-
DB.sqls.
|
|
958
|
+
DB.sqls.must_equal [
|
|
984
959
|
SQL_BEGIN,
|
|
985
960
|
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
|
|
986
961
|
SQL_COMMIT
|
|
987
962
|
]
|
|
988
963
|
end
|
|
989
964
|
|
|
990
|
-
@d.all.
|
|
965
|
+
@d.all.must_equal [
|
|
991
966
|
{:name => 'abc', :value => 1},
|
|
992
967
|
{:name => 'def', :value => 2}
|
|
993
968
|
]
|
|
994
969
|
end
|
|
995
970
|
|
|
996
|
-
|
|
971
|
+
it "#insert_ignore should add the IGNORE keyword when inserting" do
|
|
997
972
|
@d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
|
|
998
973
|
|
|
999
974
|
check_sqls do
|
|
1000
|
-
DB.sqls.
|
|
975
|
+
DB.sqls.must_equal [
|
|
1001
976
|
SQL_BEGIN,
|
|
1002
977
|
"INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
1003
978
|
SQL_COMMIT
|
|
1004
979
|
]
|
|
1005
980
|
end
|
|
1006
981
|
|
|
1007
|
-
@d.all.
|
|
982
|
+
@d.all.must_equal [
|
|
1008
983
|
{:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
|
|
1009
984
|
]
|
|
1010
985
|
end
|
|
1011
986
|
|
|
1012
|
-
|
|
987
|
+
it "#insert_ignore should add the IGNORE keyword for single inserts" do
|
|
1013
988
|
@d.insert_ignore.insert(:name => 'ghi')
|
|
1014
989
|
check_sqls do
|
|
1015
|
-
DB.sqls.
|
|
990
|
+
DB.sqls.must_equal ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
|
|
1016
991
|
end
|
|
1017
|
-
@d.all.
|
|
992
|
+
@d.all.must_equal [{:name => 'ghi', :value => nil}]
|
|
1018
993
|
end
|
|
1019
994
|
|
|
1020
|
-
|
|
995
|
+
it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
|
|
1021
996
|
@d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
|
|
1022
997
|
|
|
1023
998
|
check_sqls do
|
|
1024
|
-
DB.sqls.
|
|
999
|
+
DB.sqls.must_equal [
|
|
1025
1000
|
"SELECT * FROM `items` LIMIT 1",
|
|
1026
1001
|
SQL_BEGIN,
|
|
1027
1002
|
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
|
|
@@ -1029,25 +1004,25 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
1029
1004
|
]
|
|
1030
1005
|
end
|
|
1031
1006
|
|
|
1032
|
-
@d.all.
|
|
1007
|
+
@d.all.must_equal [
|
|
1033
1008
|
{:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
|
|
1034
1009
|
]
|
|
1035
1010
|
end
|
|
1036
1011
|
|
|
1037
|
-
|
|
1012
|
+
it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
|
|
1038
1013
|
@d.on_duplicate_key_update(:value).import([:name,:value],
|
|
1039
1014
|
[['abc', 1], ['def',2]]
|
|
1040
1015
|
)
|
|
1041
1016
|
|
|
1042
1017
|
check_sqls do
|
|
1043
|
-
DB.sqls.
|
|
1018
|
+
DB.sqls.must_equal [
|
|
1044
1019
|
SQL_BEGIN,
|
|
1045
1020
|
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
|
|
1046
1021
|
SQL_COMMIT
|
|
1047
1022
|
]
|
|
1048
1023
|
end
|
|
1049
1024
|
|
|
1050
|
-
@d.all.
|
|
1025
|
+
@d.all.must_equal [
|
|
1051
1026
|
{:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
|
|
1052
1027
|
]
|
|
1053
1028
|
end
|
|
@@ -1063,16 +1038,16 @@ describe "MySQL::Dataset#update and related methods" do
|
|
|
1063
1038
|
DB.drop_table?(:items)
|
|
1064
1039
|
end
|
|
1065
1040
|
|
|
1066
|
-
|
|
1041
|
+
it "#update_ignore should not raise error where normal update would fail" do
|
|
1067
1042
|
@d.insert(:name => 'cow', :value => 0)
|
|
1068
1043
|
@d.insert(:name => 'cat', :value => 1)
|
|
1069
|
-
proc{@d.where(:value => 1).update(:name => 'cow')}.
|
|
1044
|
+
proc{@d.where(:value => 1).update(:name => 'cow')}.must_raise(Sequel::UniqueConstraintViolation)
|
|
1070
1045
|
DB.sqls.clear
|
|
1071
1046
|
@d.update_ignore.where(:value => 1).update(:name => 'cow')
|
|
1072
1047
|
check_sqls do
|
|
1073
|
-
DB.sqls.
|
|
1048
|
+
DB.sqls.must_equal ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
|
|
1074
1049
|
end
|
|
1075
|
-
@d.order(:name).all.
|
|
1050
|
+
@d.order(:name).all.must_equal [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
|
|
1076
1051
|
end
|
|
1077
1052
|
end
|
|
1078
1053
|
|
|
@@ -1086,14 +1061,14 @@ describe "MySQL::Dataset#replace" do
|
|
|
1086
1061
|
DB.drop_table?(:items)
|
|
1087
1062
|
end
|
|
1088
1063
|
|
|
1089
|
-
|
|
1064
|
+
it "should use default values if they exist" do
|
|
1090
1065
|
DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
|
|
1091
1066
|
@d.replace
|
|
1092
|
-
@d.all.
|
|
1067
|
+
@d.all.must_equal [{:id=>1, :value=>2}]
|
|
1093
1068
|
@d.replace([])
|
|
1094
|
-
@d.all.
|
|
1069
|
+
@d.all.must_equal [{:id=>1, :value=>2}]
|
|
1095
1070
|
@d.replace({})
|
|
1096
|
-
@d.all.
|
|
1071
|
+
@d.all.must_equal [{:id=>1, :value=>2}]
|
|
1097
1072
|
end
|
|
1098
1073
|
end
|
|
1099
1074
|
|
|
@@ -1102,15 +1077,15 @@ describe "MySQL::Dataset#complex_expression_sql" do
|
|
|
1102
1077
|
@d = DB.dataset
|
|
1103
1078
|
end
|
|
1104
1079
|
|
|
1105
|
-
|
|
1106
|
-
@d.literal(Sequel.join([:x, :y])).
|
|
1107
|
-
@d.literal(Sequel.join([:x, :y], ' ')).
|
|
1108
|
-
@d.literal(Sequel.join([Sequel.function(:x, :y), 1, Sequel.lit('z')], Sequel.subscript(:y, 1))).
|
|
1080
|
+
it "should handle string concatenation with CONCAT if more than one record" do
|
|
1081
|
+
@d.literal(Sequel.join([:x, :y])).must_equal "CONCAT(`x`, `y`)"
|
|
1082
|
+
@d.literal(Sequel.join([:x, :y], ' ')).must_equal "CONCAT(`x`, ' ', `y`)"
|
|
1083
|
+
@d.literal(Sequel.join([Sequel.function(:x, :y), 1, Sequel.lit('z')], Sequel.subscript(:y, 1))).must_equal "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
|
|
1109
1084
|
end
|
|
1110
1085
|
|
|
1111
|
-
|
|
1112
|
-
@d.literal(Sequel.join([:x])).
|
|
1113
|
-
@d.literal(Sequel.join([:x], ' ')).
|
|
1086
|
+
it "should handle string concatenation as simple string if just one record" do
|
|
1087
|
+
@d.literal(Sequel.join([:x])).must_equal "`x`"
|
|
1088
|
+
@d.literal(Sequel.join([:x], ' ')).must_equal "`x`"
|
|
1114
1089
|
end
|
|
1115
1090
|
end
|
|
1116
1091
|
|
|
@@ -1122,22 +1097,22 @@ describe "MySQL::Dataset#calc_found_rows" do
|
|
|
1122
1097
|
DB.drop_table?(:items)
|
|
1123
1098
|
end
|
|
1124
1099
|
|
|
1125
|
-
|
|
1126
|
-
DB[:items].select(:a).calc_found_rows.limit(1).sql.
|
|
1100
|
+
it "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
|
|
1101
|
+
DB[:items].select(:a).calc_found_rows.limit(1).sql.must_equal \
|
|
1127
1102
|
'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
|
|
1128
1103
|
end
|
|
1129
1104
|
|
|
1130
|
-
|
|
1105
|
+
it "should count matching rows disregarding LIMIT clause" do
|
|
1131
1106
|
DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
|
|
1132
1107
|
DB.sqls.clear
|
|
1133
1108
|
|
|
1134
1109
|
DB.synchronize do
|
|
1135
|
-
DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.
|
|
1136
|
-
DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.
|
|
1110
|
+
DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.must_equal [{:a => 1}]
|
|
1111
|
+
DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.must_equal [{:rows => 2 }]
|
|
1137
1112
|
end
|
|
1138
1113
|
|
|
1139
1114
|
check_sqls do
|
|
1140
|
-
DB.sqls.
|
|
1115
|
+
DB.sqls.must_equal [
|
|
1141
1116
|
'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
|
|
1142
1117
|
'SELECT FOUND_ROWS() AS `rows`',
|
|
1143
1118
|
]
|
|
@@ -1157,46 +1132,46 @@ if DB.adapter_scheme == :mysql or DB.adapter_scheme == :jdbc or DB.adapter_schem
|
|
|
1157
1132
|
DB.execute('DROP PROCEDURE test_sproc')
|
|
1158
1133
|
end
|
|
1159
1134
|
|
|
1160
|
-
|
|
1135
|
+
it "should be callable on the database object" do
|
|
1161
1136
|
DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
|
|
1162
1137
|
DB[:items].delete
|
|
1163
1138
|
DB[:items].insert(:value=>1)
|
|
1164
|
-
DB[:items].count.
|
|
1139
|
+
DB[:items].count.must_equal 1
|
|
1165
1140
|
DB.call_sproc(:test_sproc)
|
|
1166
|
-
DB[:items].count.
|
|
1141
|
+
DB[:items].count.must_equal 0
|
|
1167
1142
|
end
|
|
1168
1143
|
|
|
1169
1144
|
# Mysql2 doesn't support stored procedures that return result sets, probably because
|
|
1170
1145
|
# CLIENT_MULTI_RESULTS is not set.
|
|
1171
1146
|
unless DB.adapter_scheme == :mysql2
|
|
1172
|
-
|
|
1147
|
+
it "should be callable on the dataset object" do
|
|
1173
1148
|
DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
|
|
1174
1149
|
DB[:items].delete
|
|
1175
1150
|
@d = DB[:items]
|
|
1176
|
-
@d.call_sproc(:select, :test_sproc, 3).
|
|
1151
|
+
@d.call_sproc(:select, :test_sproc, 3).must_equal []
|
|
1177
1152
|
@d.insert(:value=>1)
|
|
1178
|
-
@d.call_sproc(:select, :test_sproc, 4).
|
|
1153
|
+
@d.call_sproc(:select, :test_sproc, 4).must_equal [{:id=>nil, :value=>1, :b=>4}]
|
|
1179
1154
|
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
1180
|
-
@d.call_sproc(:select, :test_sproc, 3).
|
|
1155
|
+
@d.call_sproc(:select, :test_sproc, 3).must_equal [{:id=>nil, :value=>2, :b=>6}]
|
|
1181
1156
|
end
|
|
1182
1157
|
|
|
1183
|
-
|
|
1158
|
+
it "should be callable on the dataset object with multiple arguments" do
|
|
1184
1159
|
DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
|
|
1185
1160
|
DB[:items].delete
|
|
1186
1161
|
@d = DB[:items]
|
|
1187
|
-
@d.call_sproc(:select, :test_sproc, 3, 4).
|
|
1162
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).must_equal []
|
|
1188
1163
|
@d.insert(:value=>1)
|
|
1189
|
-
@d.call_sproc(:select, :test_sproc, 4, 5).
|
|
1164
|
+
@d.call_sproc(:select, :test_sproc, 4, 5).must_equal [{:id=>nil, :value=>1, :b=>4, :d=>5}]
|
|
1190
1165
|
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
1191
|
-
@d.call_sproc(:select, :test_sproc, 3, 4).
|
|
1166
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).must_equal [{:id=>nil, :value=>2, :b=>6, :d => 8}]
|
|
1192
1167
|
end
|
|
1193
1168
|
end
|
|
1194
1169
|
|
|
1195
|
-
|
|
1170
|
+
it "should deal with nil values" do
|
|
1196
1171
|
DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
|
|
1197
1172
|
DB[:items].delete
|
|
1198
1173
|
DB.call_sproc(:test_sproc, :args=>[1, nil])
|
|
1199
|
-
DB[:items].all.
|
|
1174
|
+
DB[:items].all.must_equal [{:id=>1, :value=>nil}]
|
|
1200
1175
|
end
|
|
1201
1176
|
end
|
|
1202
1177
|
end
|
|
@@ -1207,29 +1182,29 @@ if DB.adapter_scheme == :mysql
|
|
|
1207
1182
|
DB.convert_invalid_date_time = false
|
|
1208
1183
|
end
|
|
1209
1184
|
|
|
1210
|
-
|
|
1185
|
+
it "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
|
|
1211
1186
|
DB.convert_invalid_date_time = false
|
|
1212
|
-
proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.
|
|
1213
|
-
proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.
|
|
1214
|
-
proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.
|
|
1187
|
+
proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.must_raise(Sequel::InvalidValue)
|
|
1188
|
+
proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.must_raise(Sequel::InvalidValue)
|
|
1189
|
+
proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.must_raise(Sequel::InvalidValue)
|
|
1215
1190
|
end
|
|
1216
1191
|
|
|
1217
|
-
|
|
1192
|
+
it "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
|
|
1218
1193
|
DB.convert_invalid_date_time = nil
|
|
1219
|
-
DB["SELECT CAST('0000-00-00' AS date)"].single_value.
|
|
1220
|
-
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.
|
|
1221
|
-
DB["SELECT CAST('25:00:00' AS time)"].single_value.
|
|
1194
|
+
DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
|
|
1195
|
+
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
|
|
1196
|
+
DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
|
|
1222
1197
|
DB.convert_invalid_date_time = :nil
|
|
1223
|
-
DB["SELECT CAST('0000-00-00' AS date)"].single_value.
|
|
1224
|
-
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.
|
|
1225
|
-
DB["SELECT CAST('25:00:00' AS time)"].single_value.
|
|
1198
|
+
DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
|
|
1199
|
+
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
|
|
1200
|
+
DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
|
|
1226
1201
|
end
|
|
1227
1202
|
|
|
1228
|
-
|
|
1203
|
+
it "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
|
|
1229
1204
|
DB.convert_invalid_date_time = :string
|
|
1230
|
-
DB["SELECT CAST('0000-00-00' AS date)"].single_value.
|
|
1231
|
-
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.
|
|
1232
|
-
DB["SELECT CAST('25:00:00' AS time)"].single_value.
|
|
1205
|
+
DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal '0000-00-00'
|
|
1206
|
+
DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal '0000-00-00 00:00:00'
|
|
1207
|
+
DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal '25:00:00'
|
|
1233
1208
|
end
|
|
1234
1209
|
end
|
|
1235
1210
|
|
|
@@ -1247,40 +1222,40 @@ if DB.adapter_scheme == :mysql
|
|
|
1247
1222
|
DB.drop_table?(:a, :b)
|
|
1248
1223
|
end
|
|
1249
1224
|
|
|
1250
|
-
|
|
1251
|
-
@ds.all.
|
|
1225
|
+
it "should combine all results by default" do
|
|
1226
|
+
@ds.all.must_equal [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
|
|
1252
1227
|
end
|
|
1253
1228
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1229
|
+
it "should work with Database#run" do
|
|
1230
|
+
DB.run('SELECT * FROM a; SELECT * FROM b')
|
|
1231
|
+
DB.run('SELECT * FROM a; SELECT * FROM b')
|
|
1257
1232
|
end
|
|
1258
1233
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
DB[:a].select_order_map(:a).
|
|
1262
|
-
DB[:b].all.
|
|
1234
|
+
it "should work with Database#run and other statements" do
|
|
1235
|
+
DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')
|
|
1236
|
+
DB[:a].select_order_map(:a).must_equal [1, 1]
|
|
1237
|
+
DB[:b].all.must_equal []
|
|
1263
1238
|
end
|
|
1264
1239
|
|
|
1265
|
-
|
|
1266
|
-
@ds.split_multiple_result_sets.all.
|
|
1240
|
+
it "should split results returned into arrays if split_multiple_result_sets is used" do
|
|
1241
|
+
@ds.split_multiple_result_sets.all.must_equal [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
|
|
1267
1242
|
end
|
|
1268
1243
|
|
|
1269
|
-
|
|
1244
|
+
it "should have regular row_procs work when splitting multiple result sets" do
|
|
1270
1245
|
@ds.row_proc = proc{|x| x[x.keys.first] *= 2; x}
|
|
1271
|
-
@ds.split_multiple_result_sets.all.
|
|
1246
|
+
@ds.split_multiple_result_sets.all.must_equal [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
|
|
1272
1247
|
end
|
|
1273
1248
|
|
|
1274
|
-
|
|
1275
|
-
@ds.split_multiple_result_sets.columns.
|
|
1249
|
+
it "should use the columns from the first result set when splitting result sets" do
|
|
1250
|
+
@ds.split_multiple_result_sets.columns.must_equal [:a]
|
|
1276
1251
|
end
|
|
1277
1252
|
|
|
1278
|
-
|
|
1279
|
-
proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.
|
|
1253
|
+
it "should not allow graphing a dataset that splits multiple statements" do
|
|
1254
|
+
proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.must_raise(Sequel::Error)
|
|
1280
1255
|
end
|
|
1281
1256
|
|
|
1282
|
-
|
|
1283
|
-
proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.
|
|
1257
|
+
it "should not allow splitting a graphed dataset" do
|
|
1258
|
+
proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.must_raise(Sequel::Error)
|
|
1284
1259
|
end
|
|
1285
1260
|
end
|
|
1286
1261
|
end
|
|
@@ -1300,12 +1275,12 @@ if DB.adapter_scheme == :mysql2
|
|
|
1300
1275
|
DB.drop_table?(:a)
|
|
1301
1276
|
end
|
|
1302
1277
|
|
|
1303
|
-
|
|
1304
|
-
@ds.map(:a).
|
|
1278
|
+
it "should correctly stream results" do
|
|
1279
|
+
@ds.map(:a).must_equal((0...1000).to_a)
|
|
1305
1280
|
end
|
|
1306
1281
|
|
|
1307
|
-
|
|
1308
|
-
3.times{@ds.each{|r| break r[:a]}.
|
|
1282
|
+
it "should correctly handle early returning when streaming results" do
|
|
1283
|
+
3.times{@ds.each{|r| break r[:a]}.must_equal 0}
|
|
1309
1284
|
end
|
|
1310
1285
|
end
|
|
1311
1286
|
end
|