sequel 4.22.0 → 4.23.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -25,42 +25,9 @@ class Sequel::Database
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
require
|
29
|
-
|
30
|
-
RSPEC_EXAMPLE_GROUP.class_eval do
|
31
|
-
def log
|
32
|
-
begin
|
33
|
-
DB.loggers << Logger.new(STDOUT)
|
34
|
-
yield
|
35
|
-
ensure
|
36
|
-
DB.loggers.pop
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.cspecify(message, *checked, &block)
|
41
|
-
return specify(message, &block) if ENV['SEQUEL_NO_PENDING']
|
42
|
-
pending = false
|
43
|
-
checked.each do |c|
|
44
|
-
case c
|
45
|
-
when DB.adapter_scheme
|
46
|
-
pending = c
|
47
|
-
when Proc
|
48
|
-
pending = c if c.first.call(DB)
|
49
|
-
when Array
|
50
|
-
pending = c if c.first == DB.adapter_scheme && c.last == DB.call(DB)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
if pending
|
54
|
-
specify(message) do
|
55
|
-
method = RSPEC_SKIP_PENDING && !ENV['SEQUEL_NO_SKIP_PENDING'] ? :skip : :pending
|
56
|
-
send(method, "Not yet working on #{Array(pending).join(', ')}")
|
57
|
-
instance_eval(&block)
|
58
|
-
end
|
59
|
-
else
|
60
|
-
specify(message, &block)
|
61
|
-
end
|
62
|
-
end
|
28
|
+
require './spec/guards_helper'
|
63
29
|
|
30
|
+
class Minitest::HooksSpec
|
64
31
|
def check_sqls
|
65
32
|
yield unless ENV['SEQUEL_NO_CHECK_SQLS']
|
66
33
|
end
|
@@ -24,52 +24,52 @@ describe "Convert smallint to boolean" do
|
|
24
24
|
@db.drop_table(:booltest)
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
it "should consider smallint datatypes as boolean if set, but if not, as larger smallints" do
|
28
28
|
@db.create_table!(:booltest){column :b, 'smallint'; column :i, 'integer'}
|
29
|
-
@db.schema(:booltest, :reload=>true).first.last[:type].
|
30
|
-
@db.schema(:booltest, :reload=>true).first.last[:db_type].
|
29
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :boolean
|
30
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
31
31
|
|
32
32
|
Sequel::SqlAnywhere.convert_smallint_to_bool = false
|
33
33
|
@db2 = Sequel.connect(DB.url)
|
34
|
-
@db2.schema(:booltest, :reload=>true).first.last[:type].
|
35
|
-
@db2.schema(:booltest, :reload=>true).first.last[:db_type].
|
34
|
+
@db2.schema(:booltest, :reload=>true).first.last[:type].must_equal :integer
|
35
|
+
@db2.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
36
36
|
|
37
|
-
@db.schema(:booltest, :reload=>true).first.last[:type].
|
38
|
-
@db.schema(:booltest, :reload=>true).first.last[:db_type].
|
37
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :boolean
|
38
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
39
39
|
|
40
40
|
@db2.disconnect
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "datasets" do
|
44
|
-
|
44
|
+
it "should return smallints as bools and integers as integers when set" do
|
45
45
|
@ds.delete
|
46
46
|
@ds << {:b=>true, :i=>10}
|
47
|
-
@ds.all.
|
47
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
48
48
|
@ds.delete
|
49
49
|
@ds << {:b=>false, :i=>0}
|
50
|
-
@ds.all.
|
50
|
+
@ds.all.must_equal [{:b=>false, :i=>0}]
|
51
51
|
@ds.delete
|
52
52
|
@ds << {:b=>true, :i=>1}
|
53
|
-
@ds.all.
|
53
|
+
@ds.all.must_equal [{:b=>true, :i=>1}]
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
it "should return all smallints as integers when unset" do
|
57
57
|
Sequel::SqlAnywhere.convert_smallint_to_bool = false
|
58
58
|
@db2 = Sequel.connect(DB.url)
|
59
59
|
@ds2 = @db2[:booltest]
|
60
60
|
@ds2.delete
|
61
61
|
@ds2 << {:b=>true, :i=>10}
|
62
|
-
@ds2.all.
|
62
|
+
@ds2.all.must_equal [{:b=>1, :i=>10}]
|
63
63
|
@ds2.delete
|
64
64
|
@ds2 << {:b=>false, :i=>0}
|
65
|
-
@ds2.all.
|
65
|
+
@ds2.all.must_equal [{:b=>0, :i=>0}]
|
66
66
|
|
67
67
|
@ds2.delete
|
68
68
|
@ds2 << {:b=>1, :i=>10}
|
69
|
-
@ds2.all.
|
69
|
+
@ds2.all.must_equal [{:b=>1, :i=>10}]
|
70
70
|
@ds2.delete
|
71
71
|
@ds2 << {:b=>0, :i=>0}
|
72
|
-
@ds2.all.
|
72
|
+
@ds2.all.must_equal [{:b=>0, :i=>0}]
|
73
73
|
|
74
74
|
@db2.disconnect
|
75
75
|
end
|
@@ -84,45 +84,45 @@ describe "Convert smallint to boolean" do
|
|
84
84
|
@db.drop_table(:booltest)
|
85
85
|
end
|
86
86
|
|
87
|
-
|
88
|
-
@db.schema(:booltest, :reload=>true).first.last[:type].
|
89
|
-
@db.schema(:booltest, :reload=>true).first.last[:db_type].
|
87
|
+
it "should consider smallint datatypes as boolean if set, but not larger smallints" do
|
88
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :boolean
|
89
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
90
90
|
@db.convert_smallint_to_bool = false
|
91
|
-
@db.schema(:booltest, :reload=>true).first.last[:type].
|
92
|
-
@db.schema(:booltest, :reload=>true).first.last[:db_type].
|
91
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :integer
|
92
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
93
93
|
end
|
94
94
|
|
95
95
|
describe "datasets" do
|
96
|
-
|
96
|
+
it "should return smallints as bools and integers as integers when set" do
|
97
97
|
@ds = @db[:booltest]
|
98
98
|
@ds.delete
|
99
99
|
@ds << {:b=>true, :i=>10}
|
100
|
-
@ds.all.
|
100
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
101
101
|
@ds.delete
|
102
102
|
@ds << {:b=>false, :i=>0}
|
103
|
-
@ds.all.
|
103
|
+
@ds.all.must_equal [{:b=>false, :i=>0}]
|
104
104
|
@ds.delete
|
105
105
|
@ds << {:b=>true, :i=>1}
|
106
|
-
@ds.all.
|
106
|
+
@ds.all.must_equal [{:b=>true, :i=>1}]
|
107
107
|
end
|
108
108
|
|
109
|
-
|
109
|
+
it "should return all smallints as integers when unset" do
|
110
110
|
@db2 = Sequel.connect(DB.url)
|
111
111
|
@db2.convert_smallint_to_bool = false
|
112
112
|
@ds2 = @db2[:booltest]
|
113
113
|
@ds2.delete
|
114
114
|
@ds2 << {:b=>true, :i=>10}
|
115
|
-
@ds2.all.
|
115
|
+
@ds2.all.must_equal [{:b=>1, :i=>10}]
|
116
116
|
@ds2.delete
|
117
117
|
@ds2 << {:b=>false, :i=>0}
|
118
|
-
@ds2.all.
|
118
|
+
@ds2.all.must_equal [{:b=>0, :i=>0}]
|
119
119
|
|
120
120
|
@ds2.delete
|
121
121
|
@ds2 << {:b=>1, :i=>10}
|
122
|
-
@ds2.all.
|
122
|
+
@ds2.all.must_equal [{:b=>1, :i=>10}]
|
123
123
|
@ds2.delete
|
124
124
|
@ds2 << {:b=>0, :i=>0}
|
125
|
-
@ds2.all.
|
125
|
+
@ds2.all.must_equal [{:b=>0, :i=>0}]
|
126
126
|
|
127
127
|
@db2.disconnect
|
128
128
|
end
|
@@ -138,33 +138,33 @@ describe "Convert smallint to boolean" do
|
|
138
138
|
@db.drop_table(:booltest)
|
139
139
|
end
|
140
140
|
|
141
|
-
|
141
|
+
it "should return smallints as bools and integers as integers when set" do
|
142
142
|
@ds.delete
|
143
143
|
@ds << {:b=>true, :i=>10}
|
144
|
-
@ds.all.
|
144
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
145
145
|
@ds.delete
|
146
146
|
@ds << {:b=>false, :i=>0}
|
147
|
-
@ds.all.
|
147
|
+
@ds.all.must_equal [{:b=>false, :i=>0}]
|
148
148
|
@ds.delete
|
149
149
|
@ds << {:b=>true, :i=>1}
|
150
|
-
@ds.all.
|
150
|
+
@ds.all.must_equal [{:b=>true, :i=>1}]
|
151
151
|
end
|
152
152
|
|
153
|
-
|
153
|
+
it "should return all smallints as integers when unset" do
|
154
154
|
@ds.convert_smallint_to_bool = false
|
155
155
|
@ds.delete
|
156
156
|
@ds << {:b=>true, :i=>10}
|
157
|
-
@ds.all.
|
157
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
158
158
|
@ds.delete
|
159
159
|
@ds << {:b=>false, :i=>0}
|
160
|
-
@ds.all.
|
160
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
161
161
|
|
162
162
|
@ds.delete
|
163
163
|
@ds << {:b=>1, :i=>10}
|
164
|
-
@ds.all.
|
164
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
165
165
|
@ds.delete
|
166
166
|
@ds << {:b=>0, :i=>0}
|
167
|
-
@ds.all.
|
167
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|
@@ -9,151 +9,154 @@ describe "An SQLite database" do
|
|
9
9
|
end
|
10
10
|
after do
|
11
11
|
@db.drop_table?(:fk)
|
12
|
+
@db.auto_vacuum = :none
|
13
|
+
@db.run 'VACUUM'
|
12
14
|
@db.foreign_keys = @fk
|
13
15
|
@db.case_sensitive_like = true
|
14
16
|
@db.use_timestamp_timezones = false
|
15
17
|
Sequel.datetime_class = Time
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
it "should support getting setting pragma values" do
|
21
|
+
@db.pragma_set(:auto_vacuum, '0')
|
22
|
+
@db.run 'VACUUM'
|
23
|
+
@db.pragma_get(:auto_vacuum).to_s.must_equal '0'
|
24
|
+
@db.pragma_set(:auto_vacuum, '1')
|
25
|
+
@db.run 'VACUUM'
|
26
|
+
@db.pragma_get(:auto_vacuum).to_s.must_equal '1'
|
27
|
+
@db.pragma_set(:auto_vacuum, '2')
|
28
|
+
@db.run 'VACUUM'
|
29
|
+
@db.pragma_get(:auto_vacuum).to_s.must_equal '2'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should support getting and setting the auto_vacuum pragma" do
|
33
|
+
@db.auto_vacuum = :full
|
34
|
+
@db.run 'VACUUM'
|
35
|
+
@db.auto_vacuum.must_equal :full
|
36
|
+
@db.auto_vacuum = :incremental
|
37
|
+
@db.run 'VACUUM'
|
38
|
+
@db.auto_vacuum.must_equal :incremental
|
29
39
|
|
30
|
-
|
31
|
-
@db.auto_vacuum = :full
|
32
|
-
@db.auto_vacuum.should == :full
|
33
|
-
@db.auto_vacuum = :incremental
|
34
|
-
@db.auto_vacuum.should == :incremental
|
35
|
-
|
36
|
-
proc {@db.auto_vacuum = :invalid}.should raise_error(Sequel::Error)
|
37
|
-
end
|
40
|
+
proc {@db.auto_vacuum = :invalid}.must_raise(Sequel::Error)
|
38
41
|
end
|
39
42
|
|
40
|
-
|
43
|
+
it "should respect case sensitive like false" do
|
41
44
|
@db.case_sensitive_like = false
|
42
|
-
@db.get(Sequel.like('a', 'A')).to_s.
|
45
|
+
@db.get(Sequel.like('a', 'A')).to_s.must_equal '1'
|
43
46
|
end
|
44
47
|
|
45
|
-
|
48
|
+
it "should respect case sensitive like true" do
|
46
49
|
@db.case_sensitive_like = true
|
47
|
-
@db.get(Sequel.like('a', 'A')).to_s.
|
50
|
+
@db.get(Sequel.like('a', 'A')).to_s.must_equal '0'
|
48
51
|
end
|
49
52
|
|
50
|
-
|
51
|
-
@db.get(Sequel.cast('2012-10-20 11:12:13', Date)).
|
53
|
+
it "should support casting to Date by using the date function" do
|
54
|
+
@db.get(Sequel.cast('2012-10-20 11:12:13', Date)).must_equal '2012-10-20'
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
@db.get(Sequel.cast('2012-10-20', Time)).
|
56
|
-
@db.get(Sequel.cast('2012-10-20', DateTime)).
|
57
|
+
it "should support casting to Time or DateTime by using the datetime function" do
|
58
|
+
@db.get(Sequel.cast('2012-10-20', Time)).must_equal '2012-10-20 00:00:00'
|
59
|
+
@db.get(Sequel.cast('2012-10-20', DateTime)).must_equal '2012-10-20 00:00:00'
|
57
60
|
end
|
58
61
|
|
59
|
-
|
60
|
-
@db.sqlite_version.
|
62
|
+
it "should provide the SQLite version as an integer" do
|
63
|
+
@db.sqlite_version.must_be_kind_of(Integer)
|
61
64
|
end
|
62
65
|
|
63
|
-
|
64
|
-
(@db.sqlite_version >= 30619 ? [true, false] : [nil]).
|
66
|
+
it "should support setting and getting the foreign_keys pragma" do
|
67
|
+
(@db.sqlite_version >= 30619 ? [true, false] : [nil]).must_include(@db.foreign_keys)
|
65
68
|
@db.foreign_keys = true
|
66
69
|
@db.foreign_keys = false
|
67
70
|
end
|
68
71
|
|
69
|
-
|
72
|
+
it "should enforce foreign key integrity if foreign_keys pragma is set" do
|
70
73
|
@db.foreign_keys = true
|
71
74
|
@db.create_table!(:fk){primary_key :id; foreign_key :parent_id, :fk}
|
72
75
|
@db[:fk].insert(1, nil)
|
73
76
|
@db[:fk].insert(2, 1)
|
74
77
|
@db[:fk].insert(3, 3)
|
75
|
-
proc{@db[:fk].insert(4, 5)}.
|
78
|
+
proc{@db[:fk].insert(4, 5)}.must_raise(Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
|
76
79
|
end if DB.sqlite_version >= 30619
|
77
80
|
|
78
|
-
|
81
|
+
it "should not enforce foreign key integrity if foreign_keys pragma is unset" do
|
79
82
|
@db.foreign_keys = false
|
80
83
|
@db.create_table!(:fk){primary_key :id; foreign_key :parent_id, :fk}
|
81
84
|
@db[:fk].insert(1, 2)
|
82
|
-
@db[:fk].all.
|
85
|
+
@db[:fk].all.must_equal [{:id=>1, :parent_id=>2}]
|
83
86
|
end
|
84
87
|
|
85
|
-
|
88
|
+
it "should support a use_timestamp_timezones setting" do
|
86
89
|
@db.use_timestamp_timezones = true
|
87
90
|
@db.create_table!(:fk){Time :time}
|
88
91
|
@db[:fk].insert(Time.now)
|
89
|
-
@db[:fk].get(Sequel.cast(:time, String)).
|
92
|
+
@db[:fk].get(Sequel.cast(:time, String)).must_match(/[-+]\d\d\d\d\z/)
|
90
93
|
@db.use_timestamp_timezones = false
|
91
94
|
@db[:fk].delete
|
92
95
|
@db[:fk].insert(Time.now)
|
93
|
-
@db[:fk].get(Sequel.cast(:time, String)).
|
96
|
+
@db[:fk].get(Sequel.cast(:time, String)).wont_match(/[-+]\d\d\d\d\z/)
|
94
97
|
end
|
95
98
|
|
96
|
-
|
99
|
+
it "should provide a list of existing tables" do
|
97
100
|
@db.drop_table?(:fk)
|
98
|
-
@db.tables.
|
99
|
-
@db.tables.
|
101
|
+
@db.tables.must_be_kind_of(Array)
|
102
|
+
@db.tables.wont_include(:fk)
|
100
103
|
@db.create_table!(:fk){String :name}
|
101
|
-
@db.tables.
|
104
|
+
@db.tables.must_include(:fk)
|
102
105
|
end
|
103
106
|
|
104
|
-
|
107
|
+
it "should support getting and setting the synchronous pragma" do
|
105
108
|
@db.synchronous = :off
|
106
|
-
@db.synchronous.
|
109
|
+
@db.synchronous.must_equal :off
|
107
110
|
@db.synchronous = :normal
|
108
|
-
@db.synchronous.
|
111
|
+
@db.synchronous.must_equal :normal
|
109
112
|
@db.synchronous = :full
|
110
|
-
@db.synchronous.
|
113
|
+
@db.synchronous.must_equal :full
|
111
114
|
|
112
|
-
proc {@db.synchronous = :invalid}.
|
115
|
+
proc {@db.synchronous = :invalid}.must_raise(Sequel::Error)
|
113
116
|
end
|
114
117
|
|
115
|
-
|
118
|
+
it "should support getting and setting the temp_store pragma" do
|
116
119
|
@db.temp_store = :default
|
117
|
-
@db.temp_store.
|
120
|
+
@db.temp_store.must_equal :default
|
118
121
|
@db.temp_store = :file
|
119
|
-
@db.temp_store.
|
122
|
+
@db.temp_store.must_equal :file
|
120
123
|
@db.temp_store = :memory
|
121
|
-
@db.temp_store.
|
124
|
+
@db.temp_store.must_equal :memory
|
122
125
|
|
123
|
-
proc {@db.temp_store = :invalid}.
|
126
|
+
proc {@db.temp_store = :invalid}.must_raise(Sequel::Error)
|
124
127
|
end
|
125
128
|
|
126
|
-
cspecify "should support timestamps and datetimes and respect datetime_class", :do, :jdbc, :swift do
|
129
|
+
cspecify "should support timestamps and datetimes and respect datetime_class", [:do], [:jdbc], [:swift] do
|
127
130
|
@db.create_table!(:fk){timestamp :t; datetime :d}
|
128
131
|
@db.use_timestamp_timezones = true
|
129
132
|
t1 = Time.at(1)
|
130
133
|
@db[:fk] << {:t => t1, :d => t1}
|
131
|
-
@db[:fk].map(:t).
|
132
|
-
@db[:fk].map(:d).
|
134
|
+
@db[:fk].map(:t).must_equal [t1]
|
135
|
+
@db[:fk].map(:d).must_equal [t1]
|
133
136
|
Sequel.datetime_class = DateTime
|
134
137
|
t2 = Sequel.string_to_datetime(t1.iso8601)
|
135
|
-
@db[:fk].map(:t).
|
136
|
-
@db[:fk].map(:d).
|
138
|
+
@db[:fk].map(:t).must_equal [t2]
|
139
|
+
@db[:fk].map(:d).must_equal [t2]
|
137
140
|
end
|
138
141
|
|
139
|
-
|
142
|
+
it "should support sequential primary keys" do
|
140
143
|
@db.create_table!(:fk) {primary_key :id; text :name}
|
141
144
|
@db[:fk] << {:name => 'abc'}
|
142
145
|
@db[:fk] << {:name => 'def'}
|
143
146
|
@db[:fk] << {:name => 'ghi'}
|
144
|
-
@db[:fk].order(:name).all.
|
147
|
+
@db[:fk].order(:name).all.must_equal [
|
145
148
|
{:id => 1, :name => 'abc'},
|
146
149
|
{:id => 2, :name => 'def'},
|
147
150
|
{:id => 3, :name => 'ghi'}
|
148
151
|
]
|
149
152
|
end
|
150
153
|
|
151
|
-
|
154
|
+
it "should correctly parse the schema" do
|
152
155
|
@db.create_table!(:fk) {timestamp :t}
|
153
|
-
@db.schema(:fk, :reload=>true).
|
156
|
+
@db.schema(:fk, :reload=>true).must_equal [[:t, {:type=>:datetime, :allow_null=>true, :default=>nil, :ruby_default=>nil, :db_type=>"timestamp", :primary_key=>false}]]
|
154
157
|
end
|
155
158
|
|
156
|
-
|
159
|
+
it "should handle and return BigDecimal values for numeric columns" do
|
157
160
|
DB.create_table!(:fk){numeric :d}
|
158
161
|
d = DB[:fk]
|
159
162
|
d.insert(:d=>BigDecimal.new('80.0'))
|
@@ -161,8 +164,8 @@ describe "An SQLite database" do
|
|
161
164
|
d.insert(:d=>BigDecimal.new('Infinity'))
|
162
165
|
d.insert(:d=>BigDecimal.new('-Infinity'))
|
163
166
|
ds = d.all
|
164
|
-
ds.shift.
|
165
|
-
ds.map{|x| x[:d].to_s}.
|
167
|
+
ds.shift.must_equal(:d=>BigDecimal.new('80.0'))
|
168
|
+
ds.map{|x| x[:d].to_s}.must_equal %w'NaN Infinity -Infinity'
|
166
169
|
DB
|
167
170
|
end
|
168
171
|
end
|
@@ -179,11 +182,11 @@ describe "SQLite temporary views" do
|
|
179
182
|
@db.drop_table?(:items)
|
180
183
|
end
|
181
184
|
|
182
|
-
|
185
|
+
it "should be supported" do
|
183
186
|
@db.create_view(:items_view, @db[:items].where(:number=>10), :temp=>true)
|
184
|
-
@db[:items_view].map(:number).
|
187
|
+
@db[:items_view].map(:number).must_equal [10]
|
185
188
|
@db.disconnect
|
186
|
-
lambda{@db[:items_view].map(:number)}.
|
189
|
+
lambda{@db[:items_view].map(:number)}.must_raise(Sequel::DatabaseError)
|
187
190
|
end
|
188
191
|
end
|
189
192
|
|
@@ -201,76 +204,76 @@ describe "SQLite type conversion" do
|
|
201
204
|
@db.drop_table?(:items)
|
202
205
|
end
|
203
206
|
|
204
|
-
|
207
|
+
it "should handle integers in boolean columns" do
|
205
208
|
@db.create_table(:items){TrueClass :a}
|
206
209
|
@db[:items].insert(false)
|
207
|
-
@db[:items].select_map(:a).
|
208
|
-
@db[:items].select_map(Sequel.expr(:a)+:a).
|
210
|
+
@db[:items].select_map(:a).must_equal [false]
|
211
|
+
@db[:items].select_map(Sequel.expr(:a)+:a).must_equal [0]
|
209
212
|
@db[:items].update(:a=>true)
|
210
|
-
@db[:items].select_map(:a).
|
211
|
-
@db[:items].select_map(Sequel.expr(:a)+:a).
|
213
|
+
@db[:items].select_map(:a).must_equal [true]
|
214
|
+
@db[:items].select_map(Sequel.expr(:a)+:a).must_equal [2]
|
212
215
|
end
|
213
216
|
|
214
|
-
|
217
|
+
it "should handle integers/floats/strings/decimals in numeric/decimal columns" do
|
215
218
|
@db.create_table(:items){Numeric :a}
|
216
219
|
@db[:items].insert(100)
|
217
|
-
@db[:items].select_map(:a).
|
218
|
-
@db[:items].get(:a).
|
220
|
+
@db[:items].select_map(:a).must_equal [BigDecimal.new('100')]
|
221
|
+
@db[:items].get(:a).must_be_kind_of(BigDecimal)
|
219
222
|
|
220
223
|
@db[:items].update(:a=>100.1)
|
221
|
-
@db[:items].select_map(:a).
|
222
|
-
@db[:items].get(:a).
|
224
|
+
@db[:items].select_map(:a).must_equal [BigDecimal.new('100.1')]
|
225
|
+
@db[:items].get(:a).must_be_kind_of(BigDecimal)
|
223
226
|
|
224
227
|
@db[:items].update(:a=>'100.1')
|
225
|
-
@db[:items].select_map(:a).
|
226
|
-
@db[:items].get(:a).
|
228
|
+
@db[:items].select_map(:a).must_equal [BigDecimal.new('100.1')]
|
229
|
+
@db[:items].get(:a).must_be_kind_of(BigDecimal)
|
227
230
|
|
228
231
|
@db[:items].update(:a=>BigDecimal.new('100.1'))
|
229
|
-
@db[:items].select_map(:a).
|
230
|
-
@db[:items].get(:a).
|
232
|
+
@db[:items].select_map(:a).must_equal [BigDecimal.new('100.1')]
|
233
|
+
@db[:items].get(:a).must_be_kind_of(BigDecimal)
|
231
234
|
end
|
232
235
|
|
233
|
-
|
236
|
+
it "should handle integer/float date columns as julian date" do
|
234
237
|
@db.create_table(:items){Date :a}
|
235
238
|
i = 2455979
|
236
239
|
@db[:items].insert(i)
|
237
|
-
@db[:items].first.
|
240
|
+
@db[:items].first.must_equal(:a=>Date.jd(i))
|
238
241
|
@db[:items].update(:a=>2455979.1)
|
239
|
-
@db[:items].first.
|
242
|
+
@db[:items].first.must_equal(:a=>Date.jd(i))
|
240
243
|
end
|
241
244
|
|
242
|
-
|
245
|
+
it "should handle integer/float time columns as seconds" do
|
243
246
|
@db.create_table(:items){Time :a, :only_time=>true}
|
244
247
|
@db[:items].insert(3661)
|
245
|
-
@db[:items].first.
|
248
|
+
@db[:items].first.must_equal(:a=>Sequel::SQLTime.create(1, 1, 1))
|
246
249
|
@db[:items].update(:a=>3661.000001)
|
247
|
-
@db[:items].first.
|
250
|
+
@db[:items].first.must_equal(:a=>Sequel::SQLTime.create(1, 1, 1, 1))
|
248
251
|
end
|
249
252
|
|
250
|
-
|
253
|
+
it "should handle integer datetime columns as unix timestamp" do
|
251
254
|
@db.create_table(:items){DateTime :a}
|
252
255
|
i = 1329860756
|
253
256
|
@db[:items].insert(i)
|
254
|
-
@db[:items].first.
|
257
|
+
@db[:items].first.must_equal(:a=>Time.at(i))
|
255
258
|
Sequel.datetime_class = DateTime
|
256
|
-
@db[:items].first.
|
259
|
+
@db[:items].first.must_equal(:a=>DateTime.strptime(i.to_s, '%s'))
|
257
260
|
end
|
258
261
|
|
259
|
-
|
262
|
+
it "should handle float datetime columns as julian date" do
|
260
263
|
@db.create_table(:items){DateTime :a}
|
261
264
|
i = 2455979.5
|
262
265
|
@db[:items].insert(i)
|
263
|
-
@db[:items].first.
|
266
|
+
@db[:items].first.must_equal(:a=>Time.at(1329825600))
|
264
267
|
Sequel.datetime_class = DateTime
|
265
|
-
@db[:items].first.
|
268
|
+
@db[:items].first.must_equal(:a=>DateTime.jd(2455979.5))
|
266
269
|
end
|
267
270
|
|
268
|
-
|
271
|
+
it "should handle integer/float blob columns" do
|
269
272
|
@db.create_table(:items){File :a}
|
270
273
|
@db[:items].insert(1)
|
271
|
-
@db[:items].first.
|
274
|
+
@db[:items].first.must_equal(:a=>Sequel::SQL::Blob.new('1'))
|
272
275
|
@db[:items].update(:a=>'1.1')
|
273
|
-
@db[:items].first.
|
276
|
+
@db[:items].first.must_equal(:a=>Sequel::SQL::Blob.new(1.1.to_s))
|
274
277
|
end
|
275
278
|
end if DB.adapter_scheme == :sqlite
|
276
279
|
|
@@ -279,37 +282,37 @@ describe "An SQLite dataset" do
|
|
279
282
|
@d = DB[:items]
|
280
283
|
end
|
281
284
|
|
282
|
-
|
283
|
-
proc{@d.literal(Sequel.expr(:x).like(/a/))}.
|
284
|
-
proc{@d.literal(~Sequel.expr(:x).like(/a/))}.
|
285
|
-
proc{@d.literal(Sequel.expr(:x).like(/a/i))}.
|
286
|
-
proc{@d.literal(~Sequel.expr(:x).like(/a/i))}.
|
285
|
+
it "should raise errors if given a regexp pattern match" do
|
286
|
+
proc{@d.literal(Sequel.expr(:x).like(/a/))}.must_raise(Sequel::InvalidOperation)
|
287
|
+
proc{@d.literal(~Sequel.expr(:x).like(/a/))}.must_raise(Sequel::InvalidOperation)
|
288
|
+
proc{@d.literal(Sequel.expr(:x).like(/a/i))}.must_raise(Sequel::InvalidOperation)
|
289
|
+
proc{@d.literal(~Sequel.expr(:x).like(/a/i))}.must_raise(Sequel::InvalidOperation)
|
287
290
|
end
|
288
291
|
end
|
289
292
|
|
290
293
|
describe "An SQLite dataset AS clause" do
|
291
|
-
|
292
|
-
DB.literal(:c___a).
|
294
|
+
it "should use a string literal for :col___alias" do
|
295
|
+
DB.literal(:c___a).must_equal "`c` AS 'a'"
|
293
296
|
end
|
294
297
|
|
295
|
-
|
296
|
-
DB.literal(:t__c___a).
|
298
|
+
it "should use a string literal for :table__col___alias" do
|
299
|
+
DB.literal(:t__c___a).must_equal "`t`.`c` AS 'a'"
|
297
300
|
end
|
298
301
|
|
299
|
-
|
300
|
-
DB.literal(Sequel.as(:c, :a)).
|
302
|
+
it "should use a string literal for :column.as(:alias)" do
|
303
|
+
DB.literal(Sequel.as(:c, :a)).must_equal "`c` AS 'a'"
|
301
304
|
end
|
302
305
|
|
303
|
-
|
304
|
-
DB[:t].select(:c___a).sql.
|
306
|
+
it "should use a string literal in the SELECT clause" do
|
307
|
+
DB[:t].select(:c___a).sql.must_equal "SELECT `c` AS 'a' FROM `t`"
|
305
308
|
end
|
306
309
|
|
307
|
-
|
308
|
-
DB[:t___a].sql.
|
310
|
+
it "should use a string literal in the FROM clause" do
|
311
|
+
DB[:t___a].sql.must_equal "SELECT * FROM `t` AS 'a'"
|
309
312
|
end
|
310
313
|
|
311
|
-
|
312
|
-
DB[:t].join_table(:natural, :j, nil, :table_alias=>:a).sql.
|
314
|
+
it "should use a string literal in the JOIN clause" do
|
315
|
+
DB[:t].join_table(:natural, :j, nil, :table_alias=>:a).sql.must_equal "SELECT * FROM `t` NATURAL JOIN `j` AS 'a'"
|
313
316
|
end
|
314
317
|
end
|
315
318
|
|
@@ -327,21 +330,21 @@ describe "SQLite::Dataset#delete" do
|
|
327
330
|
@d << {:name => 'ghi', :value => 7.89}
|
328
331
|
end
|
329
332
|
|
330
|
-
|
331
|
-
@d.count.
|
332
|
-
@d.filter{value < 3}.delete.
|
333
|
-
@d.count.
|
333
|
+
it "should return the number of records affected when filtered" do
|
334
|
+
@d.count.must_equal 3
|
335
|
+
@d.filter{value < 3}.delete.must_equal 1
|
336
|
+
@d.count.must_equal 2
|
334
337
|
|
335
|
-
@d.filter{value < 3}.delete.
|
336
|
-
@d.count.
|
338
|
+
@d.filter{value < 3}.delete.must_equal 0
|
339
|
+
@d.count.must_equal 2
|
337
340
|
end
|
338
341
|
|
339
|
-
|
340
|
-
@d.count.
|
341
|
-
@d.delete.
|
342
|
-
@d.count.
|
342
|
+
it "should return the number of records affected when unfiltered" do
|
343
|
+
@d.count.must_equal 3
|
344
|
+
@d.delete.must_equal 3
|
345
|
+
@d.count.must_equal 0
|
343
346
|
|
344
|
-
@d.delete.
|
347
|
+
@d.delete.must_equal 0
|
345
348
|
end
|
346
349
|
end
|
347
350
|
|
@@ -359,12 +362,12 @@ describe "SQLite::Dataset#update" do
|
|
359
362
|
@d << {:name => 'ghi', :value => 7.89}
|
360
363
|
end
|
361
364
|
|
362
|
-
|
363
|
-
@d.filter(:name => 'abc').update(:value => 2).
|
365
|
+
it "should return the number of records affected" do
|
366
|
+
@d.filter(:name => 'abc').update(:value => 2).must_equal 1
|
364
367
|
|
365
|
-
@d.update(:value => 10).
|
368
|
+
@d.update(:value => 10).must_equal 3
|
366
369
|
|
367
|
-
@d.filter(:name => 'xxx').update(:value => 23).
|
370
|
+
@d.filter(:name => 'xxx').update(:value => 23).must_equal 0
|
368
371
|
end
|
369
372
|
end
|
370
373
|
|
@@ -389,21 +392,21 @@ describe "SQLite dataset" do
|
|
389
392
|
DB.drop_table?(:test, :items)
|
390
393
|
end
|
391
394
|
|
392
|
-
|
395
|
+
it "should be able to insert from a subquery" do
|
393
396
|
DB[:test] << @d
|
394
|
-
DB[:test].count.
|
395
|
-
DB[:test].select(:name, :value).order(:value).to_a.
|
397
|
+
DB[:test].count.must_equal 3
|
398
|
+
DB[:test].select(:name, :value).order(:value).to_a.must_equal \
|
396
399
|
@d.select(:name, :value).order(:value).to_a
|
397
400
|
end
|
398
401
|
|
399
|
-
|
400
|
-
DB[:test].explain.
|
402
|
+
it "should support #explain" do
|
403
|
+
DB[:test].explain.must_be_kind_of(String)
|
401
404
|
end
|
402
405
|
|
403
|
-
|
406
|
+
it "should have #explain work when identifier_output_method is modified" do
|
404
407
|
ds = DB[:test]
|
405
408
|
ds.identifier_output_method = :upcase
|
406
|
-
ds.explain.
|
409
|
+
ds.explain.must_be_kind_of(String)
|
407
410
|
end
|
408
411
|
end
|
409
412
|
|
@@ -419,38 +422,38 @@ describe "A SQLite database" do
|
|
419
422
|
@db.drop_table?(:test2)
|
420
423
|
end
|
421
424
|
|
422
|
-
|
425
|
+
it "should support add_column operations" do
|
423
426
|
@db.add_column :test2, :xyz, :text
|
424
427
|
|
425
|
-
@db[:test2].columns.
|
428
|
+
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
426
429
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz=>'000'}
|
427
|
-
@db[:test2].first.
|
430
|
+
@db[:test2].first.must_equal(:name => 'mmm', :value => 111, :xyz=>'000')
|
428
431
|
end
|
429
432
|
|
430
|
-
|
433
|
+
it "should support drop_column operations" do
|
431
434
|
@db.drop_column :test2, :value
|
432
|
-
@db[:test2].columns.
|
435
|
+
@db[:test2].columns.must_equal [:name]
|
433
436
|
@db[:test2] << {:name => 'mmm'}
|
434
|
-
@db[:test2].first.
|
437
|
+
@db[:test2].first.must_equal(:name => 'mmm')
|
435
438
|
end
|
436
439
|
|
437
|
-
|
440
|
+
it "should support drop_column operations in a transaction" do
|
438
441
|
@db.transaction{@db.drop_column :test2, :value}
|
439
|
-
@db[:test2].columns.
|
442
|
+
@db[:test2].columns.must_equal [:name]
|
440
443
|
@db[:test2] << {:name => 'mmm'}
|
441
|
-
@db[:test2].first.
|
444
|
+
@db[:test2].first.must_equal(:name => 'mmm')
|
442
445
|
end
|
443
446
|
|
444
|
-
|
447
|
+
it "should keep a composite primary key when dropping columns" do
|
445
448
|
@db.create_table!(:test2){Integer :a; Integer :b; Integer :c; primary_key [:a, :b]}
|
446
449
|
@db.drop_column :test2, :c
|
447
|
-
@db[:test2].columns.
|
450
|
+
@db[:test2].columns.must_equal [:a, :b]
|
448
451
|
@db[:test2] << {:a=>1, :b=>2}
|
449
452
|
@db[:test2] << {:a=>2, :b=>3}
|
450
|
-
proc{@db[:test2] << {:a=>2, :b=>3}}.
|
453
|
+
proc{@db[:test2] << {:a=>2, :b=>3}}.must_raise(Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
|
451
454
|
end
|
452
455
|
|
453
|
-
|
456
|
+
it "should keep column attributes when dropping a column" do
|
454
457
|
@db.create_table! :test3 do
|
455
458
|
primary_key :id
|
456
459
|
text :name
|
@@ -466,12 +469,12 @@ describe "A SQLite database" do
|
|
466
469
|
|
467
470
|
@db.drop_column :test3, :value
|
468
471
|
|
469
|
-
@db['PRAGMA table_info(?)', :test3][:id][:pk].to_i.
|
470
|
-
@db[:test3].select(:id).all.
|
472
|
+
@db['PRAGMA table_info(?)', :test3][:id][:pk].to_i.must_equal 1
|
473
|
+
@db[:test3].select(:id).all.must_equal [{:id => 1}, {:id => 3}]
|
471
474
|
end
|
472
475
|
|
473
476
|
if DB.foreign_keys
|
474
|
-
|
477
|
+
it "should keep foreign keys when dropping a column" do
|
475
478
|
@db.create_table! :test do
|
476
479
|
primary_key :id
|
477
480
|
String :name
|
@@ -489,47 +492,47 @@ describe "A SQLite database" do
|
|
489
492
|
@db.drop_column :test3, :value
|
490
493
|
|
491
494
|
@db[:test].filter(:name => 'bar').delete
|
492
|
-
@db[:test3][:name => 'def'][:test_id].
|
495
|
+
@db[:test3][:name => 'def'][:test_id].must_equal nil
|
493
496
|
|
494
497
|
@db[:test].filter(:name => 'foo').update(:id=>100)
|
495
|
-
@db[:test3][:name => 'abc'][:test_id].
|
498
|
+
@db[:test3][:name => 'abc'][:test_id].must_equal 100
|
496
499
|
|
497
500
|
@db.drop_table? :test, :test3
|
498
501
|
end
|
499
502
|
end
|
500
503
|
|
501
|
-
|
504
|
+
it "should support rename_column operations" do
|
502
505
|
@db[:test2].delete
|
503
506
|
@db.add_column :test2, :xyz, :text
|
504
507
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
|
505
508
|
|
506
|
-
@db[:test2].columns.
|
509
|
+
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
507
510
|
@db.rename_column :test2, :xyz, :zyx, :type => :text
|
508
|
-
@db[:test2].columns.
|
509
|
-
@db[:test2].first[:zyx].
|
510
|
-
@db[:test2].count.
|
511
|
+
@db[:test2].columns.must_equal [:name, :value, :zyx]
|
512
|
+
@db[:test2].first[:zyx].must_equal 'qqqq'
|
513
|
+
@db[:test2].count.must_equal 1
|
511
514
|
end
|
512
515
|
|
513
|
-
|
516
|
+
it "should preserve defaults when dropping or renaming columns" do
|
514
517
|
@db.create_table! :test3 do
|
515
518
|
String :s, :default=>'a'
|
516
519
|
Integer :i
|
517
520
|
end
|
518
521
|
|
519
522
|
@db[:test3].insert
|
520
|
-
@db[:test3].first[:s].
|
523
|
+
@db[:test3].first[:s].must_equal 'a'
|
521
524
|
@db[:test3].delete
|
522
525
|
@db.drop_column :test3, :i
|
523
526
|
@db[:test3].insert
|
524
|
-
@db[:test3].first[:s].
|
527
|
+
@db[:test3].first[:s].must_equal 'a'
|
525
528
|
@db[:test3].delete
|
526
529
|
@db.rename_column :test3, :s, :t
|
527
530
|
@db[:test3].insert
|
528
|
-
@db[:test3].first[:t].
|
531
|
+
@db[:test3].first[:t].must_equal 'a'
|
529
532
|
@db[:test3].delete
|
530
533
|
end
|
531
534
|
|
532
|
-
|
535
|
+
it "should handle quoted tables when dropping or renaming columns" do
|
533
536
|
@db.quote_identifiers = true
|
534
537
|
table_name = "T T"
|
535
538
|
@db.drop_table?(table_name)
|
@@ -539,15 +542,15 @@ describe "A SQLite database" do
|
|
539
542
|
end
|
540
543
|
|
541
544
|
@db.from(table_name).insert(:"s s"=>1, :"i i"=>2)
|
542
|
-
@db.from(table_name).all.
|
545
|
+
@db.from(table_name).all.must_equal [{:"s s"=>1, :"i i"=>2}]
|
543
546
|
@db.drop_column table_name, :"i i"
|
544
|
-
@db.from(table_name).all.
|
547
|
+
@db.from(table_name).all.must_equal [{:"s s"=>1}]
|
545
548
|
@db.rename_column table_name, :"s s", :"t t"
|
546
|
-
@db.from(table_name).all.
|
549
|
+
@db.from(table_name).all.must_equal [{:"t t"=>1}]
|
547
550
|
@db.drop_table?(table_name)
|
548
551
|
end
|
549
552
|
|
550
|
-
|
553
|
+
it "should choose a temporary table name that isn't already used when dropping or renaming columns" do
|
551
554
|
sqls = []
|
552
555
|
@db.loggers << (l=Class.new{%w'info error'.each{|m| define_method(m){|sql| sqls << sql}}}.new)
|
553
556
|
@db.tables.each{|t| @db.drop_table(t) if t.to_s =~ /test3/}
|
@@ -562,16 +565,16 @@ describe "A SQLite database" do
|
|
562
565
|
Integer :k
|
563
566
|
end
|
564
567
|
|
565
|
-
@db[:test3].columns.
|
566
|
-
@db[:test3_backup0].columns.
|
567
|
-
@db[:test3_backup1].columns.
|
568
|
+
@db[:test3].columns.must_equal [:h, :i]
|
569
|
+
@db[:test3_backup0].columns.must_equal [:j]
|
570
|
+
@db[:test3_backup1].columns.must_equal [:k]
|
568
571
|
sqls.clear
|
569
572
|
@db.drop_column(:test3, :i)
|
570
|
-
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup2/}.
|
571
|
-
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[01]/}.
|
572
|
-
@db[:test3].columns.
|
573
|
-
@db[:test3_backup0].columns.
|
574
|
-
@db[:test3_backup1].columns.
|
573
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup2/}.must_equal true
|
574
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[01]/}.must_equal false
|
575
|
+
@db[:test3].columns.must_equal [:h]
|
576
|
+
@db[:test3_backup0].columns.must_equal [:j]
|
577
|
+
@db[:test3_backup1].columns.must_equal [:k]
|
575
578
|
|
576
579
|
@db.create_table :test3_backup2 do
|
577
580
|
Integer :l
|
@@ -579,72 +582,72 @@ describe "A SQLite database" do
|
|
579
582
|
|
580
583
|
sqls.clear
|
581
584
|
@db.rename_column(:test3, :h, :i)
|
582
|
-
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup3/}.
|
583
|
-
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[012]/}.
|
584
|
-
@db[:test3].columns.
|
585
|
-
@db[:test3_backup0].columns.
|
586
|
-
@db[:test3_backup1].columns.
|
587
|
-
@db[:test3_backup2].columns.
|
585
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup3/}.must_equal true
|
586
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[012]/}.must_equal false
|
587
|
+
@db[:test3].columns.must_equal [:i]
|
588
|
+
@db[:test3_backup0].columns.must_equal [:j]
|
589
|
+
@db[:test3_backup1].columns.must_equal [:k]
|
590
|
+
@db[:test3_backup2].columns.must_equal [:l]
|
588
591
|
@db.loggers.delete(l)
|
589
592
|
@db.drop_table?(:test3, :test3_backup0, :test3_backup1, :test3_backup2)
|
590
593
|
end
|
591
594
|
|
592
|
-
|
595
|
+
it "should support add_index" do
|
593
596
|
@db.add_index :test2, :value, :unique => true
|
594
597
|
@db.add_index :test2, [:name, :value]
|
595
598
|
end
|
596
599
|
|
597
|
-
|
600
|
+
it "should support drop_index" do
|
598
601
|
@db.add_index :test2, :value, :unique => true
|
599
602
|
@db.drop_index :test2, :value
|
600
603
|
end
|
601
604
|
|
602
|
-
|
605
|
+
it "should keep applicable indexes when emulating schema methods" do
|
603
606
|
@db.create_table!(:a){Integer :a; Integer :b}
|
604
607
|
@db.add_index :a, :a
|
605
608
|
@db.add_index :a, :b
|
606
609
|
@db.add_index :a, [:b, :a]
|
607
610
|
@db.drop_column :a, :b
|
608
|
-
@db.indexes(:a).
|
611
|
+
@db.indexes(:a).must_equal(:a_a_index=>{:unique=>false, :columns=>[:a]})
|
609
612
|
end
|
610
613
|
|
611
|
-
|
614
|
+
it "should have support for various #transaction modes" do
|
612
615
|
sqls = []
|
613
616
|
@db.loggers << Class.new{%w'info error'.each{|m| define_method(m){|sql| sqls << sql}}}.new
|
614
617
|
|
615
618
|
@db.transaction(:mode => :immediate) do
|
616
|
-
sqls.last.
|
619
|
+
sqls.last.must_equal "BEGIN IMMEDIATE TRANSACTION"
|
617
620
|
end
|
618
621
|
@db.transaction(:mode => :exclusive) do
|
619
|
-
sqls.last.
|
622
|
+
sqls.last.must_equal "BEGIN EXCLUSIVE TRANSACTION"
|
620
623
|
end
|
621
624
|
@db.transaction(:mode => :deferred) do
|
622
|
-
sqls.last.
|
625
|
+
sqls.last.must_equal "BEGIN DEFERRED TRANSACTION"
|
623
626
|
end
|
624
627
|
@db.transaction do
|
625
|
-
sqls.last.
|
628
|
+
sqls.last.must_equal Sequel::Database::SQL_BEGIN
|
626
629
|
end
|
627
630
|
|
628
|
-
@db.transaction_mode.
|
631
|
+
@db.transaction_mode.must_equal nil
|
629
632
|
@db.transaction_mode = :immediate
|
630
|
-
@db.transaction_mode.
|
633
|
+
@db.transaction_mode.must_equal :immediate
|
631
634
|
@db.transaction do
|
632
|
-
sqls.last.
|
635
|
+
sqls.last.must_equal "BEGIN IMMEDIATE TRANSACTION"
|
633
636
|
end
|
634
637
|
@db.transaction(:mode => :exclusive) do
|
635
|
-
sqls.last.
|
638
|
+
sqls.last.must_equal "BEGIN EXCLUSIVE TRANSACTION"
|
636
639
|
end
|
637
640
|
|
638
|
-
proc {@db.transaction_mode = :invalid}.
|
641
|
+
proc {@db.transaction_mode = :invalid}.must_raise(Sequel::Error)
|
639
642
|
|
640
|
-
@db.transaction_mode.
|
641
|
-
proc {@db.transaction(:mode => :invalid) {}}.
|
643
|
+
@db.transaction_mode.must_equal :immediate
|
644
|
+
proc {@db.transaction(:mode => :invalid) {}}.must_raise(Sequel::Error)
|
642
645
|
end
|
643
646
|
|
644
|
-
|
647
|
+
it "should keep unique constraints when copying tables" do
|
645
648
|
@db.alter_table(:test2){add_unique_constraint :name}
|
646
649
|
@db.alter_table(:test2){drop_column :value}
|
647
650
|
@db[:test2].insert(:name=>'a')
|
648
|
-
proc{@db[:test2].insert(:name=>'a')}.
|
651
|
+
proc{@db[:test2].insert(:name=>'a')}.must_raise(Sequel::ConstraintViolation, Sequel::UniqueConstraintViolation)
|
649
652
|
end
|
650
653
|
end
|