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
|
@@ -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
|