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
@@ -13,11 +13,11 @@ DB.create_table :test do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "A Informix database" do
|
16
|
-
|
16
|
+
it "should provide disconnect functionality" do
|
17
17
|
DB.execute("select user from dual")
|
18
|
-
DB.pool.size.
|
18
|
+
DB.pool.size.must_equal 1
|
19
19
|
DB.disconnect
|
20
|
-
DB.pool.size.
|
20
|
+
DB.pool.size.must_equal 0
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -27,28 +27,28 @@ describe "A Informix dataset" do
|
|
27
27
|
@d.delete # remove all records
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
@d.count.
|
30
|
+
it "should return the correct record count" do
|
31
|
+
@d.count.must_equal 0
|
32
32
|
@d << {:name => 'abc', :value => 123}
|
33
33
|
@d << {:name => 'abc', :value => 456}
|
34
34
|
@d << {:name => 'def', :value => 789}
|
35
|
-
@d.count.
|
35
|
+
@d.count.must_equal 3
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
@d.to_a.
|
38
|
+
it "should return the correct records" do
|
39
|
+
@d.to_a.must_equal []
|
40
40
|
@d << {:name => 'abc', :value => 123}
|
41
41
|
@d << {:name => 'abc', :value => 456}
|
42
42
|
@d << {:name => 'def', :value => 789}
|
43
43
|
|
44
|
-
@d.order(:value).to_a.
|
44
|
+
@d.order(:value).to_a.must_equal [
|
45
45
|
{:name => 'abc', :value => 123},
|
46
46
|
{:name => 'abc', :value => 456},
|
47
47
|
{:name => 'def', :value => 789}
|
48
48
|
]
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
it "should update records correctly" do
|
52
52
|
@d << {:name => 'abc', :value => 123}
|
53
53
|
@d << {:name => 'abc', :value => 456}
|
54
54
|
@d << {:name => 'def', :value => 789}
|
@@ -56,45 +56,45 @@ describe "A Informix dataset" do
|
|
56
56
|
|
57
57
|
# the third record should stay the same
|
58
58
|
# floating-point precision bullshit
|
59
|
-
@d[:name => 'def'][:value].
|
60
|
-
@d.filter(:value => 530).count.
|
59
|
+
@d[:name => 'def'][:value].must_equal 789
|
60
|
+
@d.filter(:value => 530).count.must_equal 2
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
it "should delete records correctly" do
|
64
64
|
@d << {:name => 'abc', :value => 123}
|
65
65
|
@d << {:name => 'abc', :value => 456}
|
66
66
|
@d << {:name => 'def', :value => 789}
|
67
67
|
@d.filter(:name => 'abc').delete
|
68
68
|
|
69
|
-
@d.count.
|
70
|
-
@d.first[:name].
|
69
|
+
@d.count.must_equal 1
|
70
|
+
@d.first[:name].must_equal 'def'
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
it "should be able to literalize booleans" do
|
74
|
+
@d.literal(true)
|
75
|
+
@d.literal(false)
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
it "should support transactions" do
|
79
79
|
DB.transaction do
|
80
80
|
@d << {:name => 'abc', :value => 1}
|
81
81
|
end
|
82
82
|
|
83
|
-
@d.count.
|
83
|
+
@d.count.must_equal 1
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
it "should support #first and #last" do
|
87
87
|
@d << {:name => 'abc', :value => 123}
|
88
88
|
@d << {:name => 'abc', :value => 456}
|
89
89
|
@d << {:name => 'def', :value => 789}
|
90
90
|
|
91
|
-
@d.order(:value).first.
|
92
|
-
@d.order(:value).last.
|
91
|
+
@d.order(:value).first.must_equal(:name => 'abc', :value => 123)
|
92
|
+
@d.order(:value).last.must_equal(:name => 'def', :value => 789)
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
it "should return last inserted id" do
|
96
96
|
first = @d.insert :name => 'abc', :value => 123
|
97
97
|
second = @d.insert :name => 'abc', :value => 123
|
98
|
-
(second - first).
|
98
|
+
(second - first).must_equal 1
|
99
99
|
end
|
100
100
|
end
|
data/spec/adapters/mssql_spec.rb
CHANGED
@@ -16,19 +16,19 @@ describe "A MSSQL database" do
|
|
16
16
|
@db = DB
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
it "should be able to read fractional part of timestamp" do
|
20
20
|
rs = @db["select getutcdate() as full_date, cast(datepart(millisecond, getutcdate()) as int) as milliseconds"].first
|
21
|
-
rs[:milliseconds].
|
21
|
+
rs[:milliseconds].must_equal rs[:full_date].usec/1000
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
it "should be able to write fractional part of timestamp" do
|
25
25
|
t = Time.utc(2001, 12, 31, 23, 59, 59, 997000)
|
26
|
-
(t.usec/1000).
|
26
|
+
(t.usec/1000).must_equal @db["select cast(datepart(millisecond, ?) as int) as milliseconds", t].get
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
it "should not raise an error when getting the server version" do
|
30
|
+
@db.server_version
|
31
|
+
@db.dataset.server_version
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -44,8 +44,8 @@ describe "A MSSQL database" do
|
|
44
44
|
@db.drop_table?(:test3)
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
@db.transaction{@db[:test3].nolock.all.
|
47
|
+
it "should work with NOLOCK" do
|
48
|
+
@db.transaction{@db[:test3].nolock.all.must_equal []}
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -61,12 +61,12 @@ describe "MSSQL" do
|
|
61
61
|
@db.drop_table?(:test3, :test4)
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
|
-
@db[:test3].cross_apply(@db[:test4].where(:test3__v3=>:test4__v4)).select_order_map([:v3, :v4]).
|
64
|
+
it "should should support CROSS APPLY" do
|
65
|
+
@db[:test3].cross_apply(@db[:test4].where(:test3__v3=>:test4__v4)).select_order_map([:v3, :v4]).must_equal [[1,1]]
|
66
66
|
end
|
67
67
|
|
68
|
-
|
69
|
-
@db[:test3].outer_apply(@db[:test4].where(:test3__v3=>:test4__v4)).select_order_map([:v3, :v4]).
|
68
|
+
it "should should support OUTER APPLY" do
|
69
|
+
@db[:test3].outer_apply(@db[:test4].where(:test3__v3=>:test4__v4)).select_order_map([:v3, :v4]).must_equal [[1,1], [2, nil]]
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -83,31 +83,29 @@ describe "MSSQL full_text_search" do
|
|
83
83
|
@db.drop_table?(:posts)
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
it "should support fulltext indexes and full_text_search" do
|
87
87
|
log do
|
88
88
|
@db.create_table(:posts){Integer :id, :null=>false; String :title; String :body; index :id, :name=>:fts_id_idx, :unique=>true; full_text_index :title, :key_index=>:fts_id_idx; full_text_index [:title, :body], :key_index=>:fts_id_idx}
|
89
89
|
@db[:posts].insert(:title=>'ruby rails', :body=>'y')
|
90
90
|
@db[:posts].insert(:title=>'sequel', :body=>'ruby')
|
91
91
|
@db[:posts].insert(:title=>'ruby scooby', :body=>'x')
|
92
92
|
|
93
|
-
@db[:posts].full_text_search(:title, 'rails').all.
|
94
|
-
@db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.
|
93
|
+
@db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
|
94
|
+
@db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
|
95
95
|
|
96
|
-
@db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').
|
97
|
-
@db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').
|
96
|
+
@db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
|
97
|
+
@db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end if false
|
101
101
|
|
102
102
|
describe "MSSQL Dataset#join_table" do
|
103
|
-
|
104
|
-
DB[:items].join(:categories, [:id]).sql.
|
105
|
-
'SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON ([CATEGORIES].[ID] = [ITEMS].[ID])'
|
103
|
+
it "should emulate the USING clause with ON" do
|
104
|
+
DB[:items].join(:categories, [:id]).sql.must_equal 'SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON ([CATEGORIES].[ID] = [ITEMS].[ID])'
|
106
105
|
['SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON (([CATEGORIES].[ID1] = [ITEMS].[ID1]) AND ([CATEGORIES].[ID2] = [ITEMS].[ID2]))',
|
107
106
|
'SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON (([CATEGORIES].[ID2] = [ITEMS].[ID2]) AND ([CATEGORIES].[ID1] = [ITEMS].[ID1]))'].
|
108
|
-
|
109
|
-
DB[:items___i].join(:categories___c, [:id]).sql.
|
110
|
-
'SELECT * FROM [ITEMS] AS [I] INNER JOIN [CATEGORIES] AS [C] ON ([C].[ID] = [I].[ID])'
|
107
|
+
must_include(DB[:items].join(:categories, [:id1, :id2]).sql)
|
108
|
+
DB[:items___i].join(:categories___c, [:id]).sql.must_equal 'SELECT * FROM [ITEMS] AS [I] INNER JOIN [CATEGORIES] AS [C] ON ([C].[ID] = [I].[ID])'
|
111
109
|
end
|
112
110
|
end
|
113
111
|
|
@@ -122,70 +120,58 @@ describe "MSSQL Dataset#output" do
|
|
122
120
|
@db.drop_table?(:items, :out)
|
123
121
|
end
|
124
122
|
|
125
|
-
|
126
|
-
@ds.output(nil, [:deleted__name, :deleted__value]).delete_sql.
|
127
|
-
|
128
|
-
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:deleted)]).delete_sql.should =~
|
129
|
-
/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].*/
|
123
|
+
it "should format OUTPUT clauses without INTO for DELETE statements" do
|
124
|
+
@ds.output(nil, [:deleted__name, :deleted__value]).delete_sql.must_match(/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\]/)
|
125
|
+
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:deleted)]).delete_sql.must_match(/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].*/)
|
130
126
|
end
|
131
127
|
|
132
|
-
|
133
|
-
@ds.output(:out, [:deleted__name, :deleted__value]).delete_sql.
|
134
|
-
|
135
|
-
@ds.output(:out, {:name => :deleted__name, :value => :deleted__value}).delete_sql.should =~
|
136
|
-
/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/
|
128
|
+
it "should format OUTPUT clauses with INTO for DELETE statements" do
|
129
|
+
@ds.output(:out, [:deleted__name, :deleted__value]).delete_sql.must_match(/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\] INTO \[OUT\]/)
|
130
|
+
@ds.output(:out, {:name => :deleted__name, :value => :deleted__value}).delete_sql.must_match(/DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/)
|
137
131
|
end
|
138
132
|
|
139
|
-
|
140
|
-
@ds.output(nil, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).
|
141
|
-
|
142
|
-
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).insert_sql(:name => "name", :value => 1).should =~
|
143
|
-
/INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].* VALUES \((N'name'|1), (N'name'|1)\)/
|
133
|
+
it "should format OUTPUT clauses without INTO for INSERT statements" do
|
134
|
+
@ds.output(nil, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).must_match(/INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] VALUES \((N'name'|1), (N'name'|1)\)/)
|
135
|
+
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).insert_sql(:name => "name", :value => 1).must_match(/INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].* VALUES \((N'name'|1), (N'name'|1)\)/)
|
144
136
|
end
|
145
137
|
|
146
|
-
|
147
|
-
@ds.output(:out, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).
|
148
|
-
|
149
|
-
@ds.output(:out, {:name => :inserted__name, :value => :inserted__value}).insert_sql(:name => "name", :value => 1).should =~
|
150
|
-
/INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) VALUES \((N'name'|1), (N'name'|1)\)/
|
138
|
+
it "should format OUTPUT clauses with INTO for INSERT statements" do
|
139
|
+
@ds.output(:out, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).must_match(/INSERT INTO \[ITEMS\] \((\[NAME\]|\[VALUE\]), (\[NAME\]|\[VALUE\])\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] INTO \[OUT\] VALUES \((N'name'|1), (N'name'|1)\)/)
|
140
|
+
@ds.output(:out, {:name => :inserted__name, :value => :inserted__value}).insert_sql(:name => "name", :value => 1).must_match(/INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) VALUES \((N'name'|1), (N'name'|1)\)/)
|
151
141
|
end
|
152
142
|
|
153
|
-
|
154
|
-
@ds.output(nil, [:inserted__name, :deleted__value]).update_sql(:value => 2).
|
155
|
-
|
156
|
-
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).update_sql(:value => 2).should =~
|
157
|
-
/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[INSERTED\].*/
|
143
|
+
it "should format OUTPUT clauses without INTO for UPDATE statements" do
|
144
|
+
@ds.output(nil, [:inserted__name, :deleted__value]).update_sql(:value => 2).must_match(/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\]/)
|
145
|
+
@ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).update_sql(:value => 2).must_match(/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[INSERTED\].*/)
|
158
146
|
end
|
159
147
|
|
160
|
-
|
161
|
-
@ds.output(:out, [:inserted__name, :deleted__value]).update_sql(:value => 2).
|
162
|
-
|
163
|
-
@ds.output(:out, {:name => :inserted__name, :value => :deleted__value}).update_sql(:value => 2).should =~
|
164
|
-
/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/
|
148
|
+
it "should format OUTPUT clauses with INTO for UPDATE statements" do
|
149
|
+
@ds.output(:out, [:inserted__name, :deleted__value]).update_sql(:value => 2).must_match(/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\] INTO \[OUT\]/)
|
150
|
+
@ds.output(:out, {:name => :inserted__name, :value => :deleted__value}).update_sql(:value => 2).must_match(/UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/)
|
165
151
|
end
|
166
152
|
|
167
|
-
|
153
|
+
it "should execute OUTPUT clauses in DELETE statements" do
|
168
154
|
@ds.insert(:name => "name", :value => 1)
|
169
155
|
@ds.output(:out, [:deleted__name, :deleted__value]).delete
|
170
|
-
@db[:out].all.
|
156
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}]
|
171
157
|
@ds.insert(:name => "name", :value => 2)
|
172
158
|
@ds.output(:out, {:name => :deleted__name, :value => :deleted__value}).delete
|
173
|
-
@db[:out].all.
|
159
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}, {:name => "name", :value => 2}]
|
174
160
|
end
|
175
161
|
|
176
|
-
|
162
|
+
it "should execute OUTPUT clauses in INSERT statements" do
|
177
163
|
@ds.output(:out, [:inserted__name, :inserted__value]).insert(:name => "name", :value => 1)
|
178
|
-
@db[:out].all.
|
164
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}]
|
179
165
|
@ds.output(:out, {:name => :inserted__name, :value => :inserted__value}).insert(:name => "name", :value => 2)
|
180
|
-
@db[:out].all.
|
166
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}, {:name => "name", :value => 2}]
|
181
167
|
end
|
182
168
|
|
183
|
-
|
169
|
+
it "should execute OUTPUT clauses in UPDATE statements" do
|
184
170
|
@ds.insert(:name => "name", :value => 1)
|
185
171
|
@ds.output(:out, [:inserted__name, :deleted__value]).update(:value => 2)
|
186
|
-
@db[:out].all.
|
172
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}]
|
187
173
|
@ds.output(:out, {:name => :inserted__name, :value => :deleted__value}).update(:value => 3)
|
188
|
-
@db[:out].all.
|
174
|
+
@db[:out].all.must_equal [{:name => "name", :value => 1}, {:name => "name", :value => 2}]
|
189
175
|
end
|
190
176
|
end
|
191
177
|
|
@@ -197,24 +183,24 @@ describe "MSSQL dataset using #with and #with_recursive" do
|
|
197
183
|
@ds2 = @ds.with_recursive(:t, @db[:x], @db[:t])
|
198
184
|
end
|
199
185
|
|
200
|
-
|
201
|
-
@ds1.update_sql(:x => :y).
|
202
|
-
@ds2.update_sql(:x => :y).
|
186
|
+
it "should prepend UPDATE statements with WITH clause" do
|
187
|
+
@ds1.update_sql(:x => :y).must_equal 'WITH [T] AS (SELECT * FROM [X]) UPDATE [T] SET [X] = [Y]'
|
188
|
+
@ds2.update_sql(:x => :y).must_equal 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) UPDATE [T] SET [X] = [Y]'
|
203
189
|
end
|
204
190
|
|
205
|
-
|
206
|
-
@ds1.filter(:y => 1).delete_sql.
|
207
|
-
@ds2.filter(:y => 1).delete_sql.
|
191
|
+
it "should prepend DELETE statements with WITH clause" do
|
192
|
+
@ds1.filter(:y => 1).delete_sql.must_equal 'WITH [T] AS (SELECT * FROM [X]) DELETE FROM [T] WHERE ([Y] = 1)'
|
193
|
+
@ds2.filter(:y => 1).delete_sql.must_equal 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) DELETE FROM [T] WHERE ([Y] = 1)'
|
208
194
|
end
|
209
195
|
|
210
|
-
|
211
|
-
@ds1.insert_sql(@db[:t]).
|
212
|
-
@ds2.insert_sql(@db[:t]).
|
196
|
+
it "should prepend INSERT statements with WITH clause" do
|
197
|
+
@ds1.insert_sql(@db[:t]).must_equal 'WITH [T] AS (SELECT * FROM [X]) INSERT INTO [T] SELECT * FROM [T]'
|
198
|
+
@ds2.insert_sql(@db[:t]).must_equal 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) INSERT INTO [T] SELECT * FROM [T]'
|
213
199
|
end
|
214
200
|
|
215
|
-
|
216
|
-
@db[:s].inner_join(@ds1).sql.
|
217
|
-
@ds1.inner_join(@db[:s].with(:s, @db[:y])).sql.
|
201
|
+
it "should move WITH clause on joined dataset to top level" do
|
202
|
+
@db[:s].inner_join(@ds1).sql.must_equal "WITH [T] AS (SELECT * FROM [X]) SELECT * FROM [S] INNER JOIN (SELECT * FROM [T]) AS [T1]"
|
203
|
+
@ds1.inner_join(@db[:s].with(:s, @db[:y])).sql.must_equal "WITH [T] AS (SELECT * FROM [X]), [S] AS (SELECT * FROM [Y]) SELECT * FROM [T] INNER JOIN (SELECT * FROM [S]) AS [T1]"
|
218
204
|
end
|
219
205
|
end
|
220
206
|
|
@@ -228,16 +214,16 @@ describe "MSSQL::Dataset#import" do
|
|
228
214
|
@db.drop_table?(:test)
|
229
215
|
end
|
230
216
|
|
231
|
-
|
217
|
+
it "#import should work correctly with an arbitrary output value" do
|
232
218
|
@db.create_table!(:test){primary_key :x; Integer :y}
|
233
|
-
@ds.output(nil, [:inserted__y, :inserted__x]).import([:y], [[3], [4]]).
|
234
|
-
@ds.all.
|
219
|
+
@ds.output(nil, [:inserted__y, :inserted__x]).import([:y], [[3], [4]]).must_equal [{:y=>3, :x=>1}, {:y=>4, :x=>2}]
|
220
|
+
@ds.all.must_equal [{:x=>1, :y=>3}, {:x=>2, :y=>4}]
|
235
221
|
end
|
236
222
|
|
237
|
-
|
223
|
+
it "should handle WITH statements" do
|
238
224
|
@db.create_table!(:test){Integer :x; Integer :y}
|
239
225
|
@db[:testx].with(:testx, @db[:test]).import([:x, :y], [[1, 2], [3, 4], [5, 6]], :slice => 2)
|
240
|
-
@ds.select_order_map([:x, :y]).
|
226
|
+
@ds.select_order_map([:x, :y]).must_equal [[1, 2], [3, 4], [5, 6]]
|
241
227
|
end
|
242
228
|
end
|
243
229
|
|
@@ -246,14 +232,12 @@ describe "MSSQL joined datasets" do
|
|
246
232
|
@db = DB
|
247
233
|
end
|
248
234
|
|
249
|
-
|
250
|
-
@db[:t1].inner_join(:t2, :t1__pk => :t2__pk).delete_sql.
|
251
|
-
"DELETE FROM [T1] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
|
235
|
+
it "should format DELETE statements" do
|
236
|
+
@db[:t1].inner_join(:t2, :t1__pk => :t2__pk).delete_sql.must_equal "DELETE FROM [T1] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
|
252
237
|
end
|
253
238
|
|
254
|
-
|
255
|
-
@db[:t1].inner_join(:t2, :t1__pk => :t2__pk).update_sql(:pk => :t2__pk).
|
256
|
-
"UPDATE [T1] SET [PK] = [T2].[PK] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
|
239
|
+
it "should format UPDATE statements" do
|
240
|
+
@db[:t1].inner_join(:t2, :t1__pk => :t2__pk).update_sql(:pk => :t2__pk).must_equal "UPDATE [T1] SET [PK] = [T2].[PK] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
|
257
241
|
end
|
258
242
|
end
|
259
243
|
|
@@ -270,13 +254,13 @@ describe "Offset support" do
|
|
270
254
|
@db.drop_table?(:i)
|
271
255
|
end
|
272
256
|
|
273
|
-
|
274
|
-
@ds.limit(2, 2).all.
|
257
|
+
it "should return correct rows" do
|
258
|
+
@ds.limit(2, 2).all.must_equal [{:id=>6, :parent_id=>3}, {:id=>8, :parent_id=>3}]
|
275
259
|
end
|
276
260
|
|
277
|
-
|
261
|
+
it "should not include offset column in hashes passed to row_proc" do
|
278
262
|
@ds.limit(2, 2).all
|
279
|
-
@hs.
|
263
|
+
@hs.must_equal [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}]
|
280
264
|
end
|
281
265
|
end
|
282
266
|
|
@@ -293,62 +277,62 @@ describe "Common Table Expressions" do
|
|
293
277
|
@db.drop_table?(:i1, :i2)
|
294
278
|
end
|
295
279
|
|
296
|
-
|
280
|
+
it "using #with should be able to update" do
|
297
281
|
@ds.insert(:id=>1)
|
298
282
|
@ds2.insert(:id=>2, :parent_id=>1)
|
299
283
|
@ds2.insert(:id=>3, :parent_id=>2)
|
300
284
|
@ds.with(:t, @ds2).filter(:id => @db[:t].select(:id)).update(:parent_id => @db[:t].filter(:id => :i1__id).select(:parent_id).limit(1))
|
301
|
-
@ds[:id => 1].
|
302
|
-
@ds[:id => 2].
|
303
|
-
@ds[:id => 3].
|
304
|
-
@ds[:id => 4].
|
285
|
+
@ds[:id => 1].must_equal(:id => 1, :parent_id => nil)
|
286
|
+
@ds[:id => 2].must_equal(:id => 2, :parent_id => 1)
|
287
|
+
@ds[:id => 3].must_equal(:id => 3, :parent_id => 2)
|
288
|
+
@ds[:id => 4].must_equal(:id => 4, :parent_id => 1)
|
305
289
|
end
|
306
290
|
|
307
|
-
|
291
|
+
it "using #with_recursive should be able to update" do
|
308
292
|
ds = @ds.with_recursive(:t, @ds.filter(:parent_id=>1).or(:id => 1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
309
293
|
ds.exclude(:id => @db[:t].select(:i)).update(:parent_id => 1)
|
310
|
-
@ds[:id => 1].
|
311
|
-
@ds[:id => 2].
|
312
|
-
@ds[:id => 5].
|
294
|
+
@ds[:id => 1].must_equal(:id => 1, :parent_id => nil)
|
295
|
+
@ds[:id => 2].must_equal(:id => 2, :parent_id => 1)
|
296
|
+
@ds[:id => 5].must_equal(:id => 5, :parent_id => 3)
|
313
297
|
end
|
314
298
|
|
315
|
-
|
299
|
+
it "using #with should be able to insert" do
|
316
300
|
@ds2.insert(:id=>7)
|
317
301
|
@ds.with(:t, @ds2).insert(@db[:t])
|
318
|
-
@ds[:id => 7].
|
302
|
+
@ds[:id => 7].must_equal(:id => 7, :parent_id => nil)
|
319
303
|
end
|
320
304
|
|
321
|
-
|
305
|
+
it "using #with_recursive should be able to insert" do
|
322
306
|
ds = @ds2.with_recursive(:t, @ds.filter(:parent_id=>1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
323
307
|
ds.insert @db[:t]
|
324
|
-
@ds2.all.
|
308
|
+
@ds2.all.must_equal [{:id => 3, :parent_id => 1}, {:id => 4, :parent_id => 1}, {:id => 5, :parent_id => 3}, {:id => 6, :parent_id => 5}]
|
325
309
|
end
|
326
310
|
|
327
|
-
|
311
|
+
it "using #with should be able to delete" do
|
328
312
|
@ds2.insert(:id=>6)
|
329
313
|
@ds2.insert(:id=>5)
|
330
314
|
@ds2.insert(:id=>4)
|
331
315
|
@ds.with(:t, @ds2).filter(:id => @db[:t].select(:id)).delete
|
332
|
-
@ds.all.
|
316
|
+
@ds.all.must_equal [{:id => 1, :parent_id => nil}, {:id => 2, :parent_id => nil}, {:id => 3, :parent_id => 1}]
|
333
317
|
end
|
334
318
|
|
335
|
-
|
319
|
+
it "using #with_recursive should be able to delete" do
|
336
320
|
@ds.insert(:id=>7, :parent_id=>2)
|
337
321
|
ds = @ds.with_recursive(:t, @ds.filter(:parent_id=>1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
338
322
|
ds.filter(:i1__id => @db[:t].select(:i)).delete
|
339
|
-
@ds.all.
|
323
|
+
@ds.all.must_equal [{:id => 1, :parent_id => nil}, {:id => 2, :parent_id => nil}, {:id => 7, :parent_id => 2}]
|
340
324
|
end
|
341
325
|
|
342
|
-
|
326
|
+
it "using #with should be able to import" do
|
343
327
|
@ds2.insert(:id=>7)
|
344
328
|
@ds.with(:t, @ds2).import [:id, :parent_id], @db[:t].select(:id, :parent_id)
|
345
|
-
@ds[:id => 7].
|
329
|
+
@ds[:id => 7].must_equal(:id => 7, :parent_id => nil)
|
346
330
|
end
|
347
331
|
|
348
|
-
|
332
|
+
it "using #with_recursive should be able to import" do
|
349
333
|
ds = @ds2.with_recursive(:t, @ds.filter(:parent_id=>1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
350
334
|
ds.import [:id, :parent_id], @db[:t].select(:i, :pi)
|
351
|
-
@ds2.all.
|
335
|
+
@ds2.all.must_equal [{:id => 3, :parent_id => 1}, {:id => 4, :parent_id => 1}, {:id => 5, :parent_id => 3}, {:id => 6, :parent_id => 5}]
|
352
336
|
end
|
353
337
|
end
|
354
338
|
|
@@ -367,31 +351,31 @@ describe "MSSSQL::Dataset#insert" do
|
|
367
351
|
@db.drop_table?(:test5, :test4)
|
368
352
|
end
|
369
353
|
|
370
|
-
|
371
|
-
@ds.disable_insert_output.insert_select(:value=>10).
|
354
|
+
it "should have insert_select return nil if disable_insert_output is used" do
|
355
|
+
@ds.disable_insert_output.insert_select(:value=>10).must_equal nil
|
372
356
|
end
|
373
357
|
|
374
|
-
|
358
|
+
it "should have insert_select return nil if the server version is not 2005+" do
|
375
359
|
def @ds.server_version() 8000760 end
|
376
|
-
@ds.insert_select(:value=>10).
|
360
|
+
@ds.insert_select(:value=>10).must_equal nil
|
377
361
|
end
|
378
362
|
|
379
|
-
|
363
|
+
it "should have insert_select insert the record and return the inserted record" do
|
380
364
|
h = @ds.insert_select(:value=>10)
|
381
|
-
h[:value].
|
382
|
-
@ds.first(:xid=>h[:xid])[:value].
|
365
|
+
h[:value].must_equal 10
|
366
|
+
@ds.first(:xid=>h[:xid])[:value].must_equal 10
|
383
367
|
end
|
384
368
|
|
385
|
-
cspecify "should allow large text and binary values", :odbc do
|
369
|
+
cspecify "should allow large text and binary values", [:odbc] do
|
386
370
|
blob = Sequel::SQL::Blob.new("0" * (65*1024))
|
387
371
|
@db[:test4].insert(:name => 'max varbinary test', :value => blob)
|
388
372
|
b = @db[:test4].where(:name => 'max varbinary test').get(:value)
|
389
|
-
b.length.
|
390
|
-
b.
|
373
|
+
b.length.must_equal blob.length
|
374
|
+
b.must_equal blob
|
391
375
|
end
|
392
376
|
|
393
|
-
|
394
|
-
DB[:test4].disable_insert_output.send(:simple_select_all?).
|
377
|
+
it "should play nicely with simple_select_all?" do
|
378
|
+
DB[:test4].disable_insert_output.send(:simple_select_all?).must_equal true
|
395
379
|
end
|
396
380
|
end
|
397
381
|
|
@@ -400,15 +384,15 @@ describe "MSSSQL::Dataset#into" do
|
|
400
384
|
@db = DB
|
401
385
|
end
|
402
386
|
|
403
|
-
|
404
|
-
@db[:t].into(:new).select_sql.
|
387
|
+
it "should format SELECT statement" do
|
388
|
+
@db[:t].into(:new).select_sql.must_equal "SELECT * INTO [NEW] FROM [T]"
|
405
389
|
end
|
406
390
|
|
407
|
-
|
391
|
+
it "should select rows into a new table" do
|
408
392
|
@db.create_table!(:t) {Integer :id; String :value}
|
409
393
|
@db[:t].insert(:id => 1, :value => "test")
|
410
394
|
@db << @db[:t].into(:new).select_sql
|
411
|
-
@db[:new].all.
|
395
|
+
@db[:new].all.must_equal [{:id => 1, :value => "test"}]
|
412
396
|
@db.drop_table?(:t, :new)
|
413
397
|
end
|
414
398
|
end
|
@@ -421,21 +405,21 @@ describe "A MSSQL database" do
|
|
421
405
|
@db.drop_table?(:a)
|
422
406
|
end
|
423
407
|
|
424
|
-
|
408
|
+
it "should handle many existing types for set_column_allow_null" do
|
425
409
|
@db.create_table!(:a){column :a, 'integer'}
|
426
410
|
@db.alter_table(:a){set_column_allow_null :a, false}
|
427
411
|
@db.create_table!(:a){column :a, 'decimal(24, 2)'}
|
428
412
|
@db.alter_table(:a){set_column_allow_null :a, false}
|
429
|
-
@db.schema(:a).first.last[:column_size].
|
430
|
-
@db.schema(:a).first.last[:scale].
|
413
|
+
@db.schema(:a).first.last[:column_size].must_equal 24
|
414
|
+
@db.schema(:a).first.last[:scale].must_equal 2
|
431
415
|
@db.create_table!(:a){column :a, 'decimal(10)'}
|
432
|
-
@db.schema(:a).first.last[:column_size].
|
433
|
-
@db.schema(:a).first.last[:scale].
|
416
|
+
@db.schema(:a).first.last[:column_size].must_equal 10
|
417
|
+
@db.schema(:a).first.last[:scale].must_equal 0
|
434
418
|
@db.alter_table(:a){set_column_allow_null :a, false}
|
435
419
|
@db.create_table!(:a){column :a, 'nchar(2)'}
|
436
420
|
@db.alter_table(:a){set_column_allow_null :a, false}
|
437
421
|
s = @db.schema(:a).first.last
|
438
|
-
(s[:max_chars] || s[:column_size]).
|
422
|
+
(s[:max_chars] || s[:column_size]).must_equal 2
|
439
423
|
end
|
440
424
|
end
|
441
425
|
|
@@ -444,16 +428,16 @@ describe "MSSQL::Database#rename_table" do
|
|
444
428
|
DB.drop_table?(:foo)
|
445
429
|
end
|
446
430
|
|
447
|
-
|
431
|
+
it "should work on non-schema bound tables which need escaping" do
|
448
432
|
DB.quote_identifiers = true
|
449
433
|
DB.create_table! :'foo bar' do
|
450
434
|
text :name
|
451
435
|
end
|
452
436
|
DB.drop_table? :foo
|
453
|
-
|
437
|
+
DB.rename_table 'foo bar', 'foo'
|
454
438
|
end
|
455
439
|
|
456
|
-
|
440
|
+
it "should work on schema bound tables" do
|
457
441
|
DB.execute(<<-SQL)
|
458
442
|
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'MY')
|
459
443
|
EXECUTE sp_executesql N'create schema MY'
|
@@ -461,26 +445,26 @@ describe "MSSQL::Database#rename_table" do
|
|
461
445
|
DB.create_table! :MY__foo do
|
462
446
|
text :name
|
463
447
|
end
|
464
|
-
|
465
|
-
|
448
|
+
DB.rename_table :MY__foo, :MY__bar
|
449
|
+
DB.rename_table :MY__bar, :foo
|
466
450
|
end
|
467
451
|
end
|
468
452
|
|
469
453
|
describe "MSSQL::Dataset#count" do
|
470
|
-
|
454
|
+
it "should work with a distinct query with an order clause" do
|
471
455
|
DB.create_table!(:items){String :name; Integer :value}
|
472
456
|
DB[:items].insert(:name => "name", :value => 1)
|
473
457
|
DB[:items].insert(:name => "name", :value => 1)
|
474
|
-
DB[:items].select(:name, :value).distinct.order(:name).count.
|
475
|
-
DB[:items].select(:name, :value).group(:name, :value).order(:name).count.
|
458
|
+
DB[:items].select(:name, :value).distinct.order(:name).count.must_equal 1
|
459
|
+
DB[:items].select(:name, :value).group(:name, :value).order(:name).count.must_equal 1
|
476
460
|
end
|
477
461
|
end
|
478
462
|
|
479
463
|
describe "MSSQL::Database#create_table" do
|
480
|
-
|
464
|
+
it "should support collate with various other column options" do
|
481
465
|
DB.create_table!(:items){ String :name, :size => 128, :collate => :sql_latin1_general_cp1_ci_as, :default => 'foo', :null => false, :unique => true}
|
482
466
|
DB[:items].insert
|
483
|
-
DB[:items].select_map(:name).
|
467
|
+
DB[:items].select_map(:name).must_equal ["foo"]
|
484
468
|
end
|
485
469
|
end
|
486
470
|
|
@@ -493,21 +477,21 @@ describe "MSSQL::Database#mssql_unicode_strings = false" do
|
|
493
477
|
DB.mssql_unicode_strings = true
|
494
478
|
end
|
495
479
|
|
496
|
-
|
480
|
+
it "should work correctly" do
|
497
481
|
DB.create_table!(:items){String :name}
|
498
|
-
DB[:items].mssql_unicode_strings.
|
482
|
+
DB[:items].mssql_unicode_strings.must_equal false
|
499
483
|
DB[:items].insert(:name=>'foo')
|
500
|
-
DB[:items].select_map(:name).
|
484
|
+
DB[:items].select_map(:name).must_equal ['foo']
|
501
485
|
end
|
502
486
|
|
503
|
-
|
487
|
+
it "should be overridable at the dataset level" do
|
504
488
|
DB.create_table!(:items){String :name}
|
505
489
|
ds = DB[:items]
|
506
|
-
ds.mssql_unicode_strings.
|
490
|
+
ds.mssql_unicode_strings.must_equal false
|
507
491
|
ds.mssql_unicode_strings = true
|
508
|
-
ds.mssql_unicode_strings.
|
492
|
+
ds.mssql_unicode_strings.must_equal true
|
509
493
|
ds.insert(:name=>'foo')
|
510
|
-
ds.select_map(:name).
|
494
|
+
ds.select_map(:name).must_equal ['foo']
|
511
495
|
end
|
512
496
|
end
|
513
497
|
|
@@ -526,11 +510,11 @@ describe "A MSSQL database adds index with include" do
|
|
526
510
|
@db.drop_table? @table_name
|
527
511
|
end
|
528
512
|
|
529
|
-
|
513
|
+
it "should be able add index with include" do
|
530
514
|
@db.alter_table @table_name do
|
531
515
|
add_index [:col1], :include => [:col2,:col3]
|
532
516
|
end
|
533
|
-
@db.indexes(@table_name).
|
517
|
+
@db.indexes(@table_name).keys.must_include("#{@table_name}_col1_index".to_sym)
|
534
518
|
end
|
535
519
|
end
|
536
520
|
|
@@ -543,10 +527,10 @@ describe "MSSQL::Database#drop_column with a schema" do
|
|
543
527
|
DB.run "drop schema test" rescue nil
|
544
528
|
end
|
545
529
|
|
546
|
-
|
530
|
+
it "drops columns with a default value" do
|
547
531
|
DB.create_table!(:test__items){ Integer :id; String :name, :default => 'widget' }
|
548
532
|
DB.drop_column(:test__items, :name)
|
549
|
-
DB[:test__items].columns.
|
533
|
+
DB[:test__items].columns.must_equal [:id]
|
550
534
|
end
|
551
535
|
end
|
552
536
|
|
@@ -576,7 +560,7 @@ describe "Database#foreign_key_list" do
|
|
576
560
|
DB.drop_table :items
|
577
561
|
end
|
578
562
|
it "should support typical foreign keys" do
|
579
|
-
DB.foreign_key_list(:prices).
|
563
|
+
DB.foreign_key_list(:prices).must_equal [{:name => :fk_prices_items,
|
580
564
|
:table => :items,
|
581
565
|
:columns => [:item_id],
|
582
566
|
:key => [:id],
|
@@ -584,7 +568,7 @@ describe "Database#foreign_key_list" do
|
|
584
568
|
:on_delete => :no_action }]
|
585
569
|
end
|
586
570
|
it "should support a foreign key with multiple columns" do
|
587
|
-
DB.foreign_key_list(:sales).
|
571
|
+
DB.foreign_key_list(:sales).must_equal [{:name => :fk_sales_prices,
|
588
572
|
:table => :prices,
|
589
573
|
:columns => [:price_item_id, :price_valid_from],
|
590
574
|
:key => [:item_id, :valid_from],
|
@@ -592,7 +576,7 @@ describe "Database#foreign_key_list" do
|
|
592
576
|
:on_delete => :cascade }]
|
593
577
|
end
|
594
578
|
|
595
|
-
|
579
|
+
describe "with multiple schemas" do
|
596
580
|
before(:all) do
|
597
581
|
DB.execute_ddl "create schema vendor"
|
598
582
|
DB.create_table! :vendor__vendors do
|
@@ -612,7 +596,7 @@ describe "Database#foreign_key_list" do
|
|
612
596
|
DB.execute_ddl "drop schema vendor"
|
613
597
|
end
|
614
598
|
it "should support mixed schema bound tables" do
|
615
|
-
DB.foreign_key_list(:vendor__mapping).sort_by{|h| h[:name].to_s}.
|
599
|
+
DB.foreign_key_list(:vendor__mapping).sort_by{|h| h[:name].to_s}.must_equal [{:name => :fk_mapping_item, :table => :items, :columns => [:item_id], :key => [:id], :on_update => :no_action, :on_delete => :no_action }, {:name => :fk_mapping_vendor, :table => Sequel.qualify(:vendor, :vendors), :columns => [:vendor_id], :key => [:id], :on_update => :no_action, :on_delete => :no_action }]
|
616
600
|
end
|
617
601
|
end
|
618
602
|
end
|
@@ -636,11 +620,11 @@ describe "MSSQL optimistic locking plugin" do
|
|
636
620
|
o = c.create(:name=>'test')
|
637
621
|
o2 = c.first
|
638
622
|
ts = o.timestamp
|
639
|
-
ts.
|
623
|
+
ts.wont_equal nil
|
640
624
|
o.name = 'test2'
|
641
625
|
o.save
|
642
|
-
o.timestamp.
|
643
|
-
proc{o2.save}.
|
626
|
+
o.timestamp.wont_equal ts
|
627
|
+
proc{o2.save}.must_raise(Sequel::NoExistingObject)
|
644
628
|
end
|
645
629
|
end unless DB.adapter_scheme == :odbc
|
646
630
|
|
@@ -659,24 +643,24 @@ describe "MSSQL Stored Procedure support" do
|
|
659
643
|
describe "with unnamed parameters" do
|
660
644
|
it "should return a hash of output variables" do
|
661
645
|
r = @db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, :output]})
|
662
|
-
r.
|
663
|
-
r.values_at(:var2, :var3).
|
646
|
+
r.must_be_kind_of(Hash)
|
647
|
+
r.values_at(:var2, :var3).must_equal [@now, '1']
|
664
648
|
end
|
665
649
|
|
666
650
|
it "should support typed output variables" do
|
667
|
-
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, [:output, 'int']]})[:var3].
|
651
|
+
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, [:output, 'int']]})[:var3].must_equal 1
|
668
652
|
end
|
669
653
|
|
670
654
|
it "should support named output variables" do
|
671
|
-
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, [:output, nil, 'output'], :output]})[:output].
|
655
|
+
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, [:output, nil, 'output'], :output]})[:output].must_equal @now
|
672
656
|
end
|
673
657
|
|
674
658
|
it "should return the number of Affected Rows" do
|
675
|
-
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, :output]})[:numrows].
|
659
|
+
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, :output]})[:numrows].must_equal 1
|
676
660
|
end
|
677
661
|
|
678
662
|
it "should return the Result Code" do
|
679
|
-
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, :output]})[:result].
|
663
|
+
@db.call_mssql_sproc(:SequelTest, {:args => [@now, 1, :output, :output]})[:result].must_equal 1
|
680
664
|
end
|
681
665
|
end
|
682
666
|
|
@@ -688,8 +672,8 @@ describe "MSSQL Stored Procedure support" do
|
|
688
672
|
'Output' => [:output, nil, 'output'],
|
689
673
|
'IntegerOutput' => [:output, nil, 'integer_output']
|
690
674
|
})
|
691
|
-
r.
|
692
|
-
r.values_at(:output, :integer_output).
|
675
|
+
r.must_be_kind_of(Hash)
|
676
|
+
r.values_at(:output, :integer_output).must_equal [@now, '1']
|
693
677
|
end
|
694
678
|
|
695
679
|
it "should support typed output variables" do
|
@@ -698,7 +682,7 @@ describe "MSSQL Stored Procedure support" do
|
|
698
682
|
'IntegerInput' => 1,
|
699
683
|
'Output' => [:output, nil, 'output'],
|
700
684
|
'IntegerOutput' => [:output, 'int', 'integer_output']
|
701
|
-
})[:integer_output].
|
685
|
+
})[:integer_output].must_equal 1
|
702
686
|
end
|
703
687
|
|
704
688
|
it "should return the number of Affected Rows" do
|
@@ -707,7 +691,7 @@ describe "MSSQL Stored Procedure support" do
|
|
707
691
|
'IntegerInput' => 1,
|
708
692
|
'Output' => [:output, nil, 'output'],
|
709
693
|
'IntegerOutput' => [:output, nil, 'integer_output']
|
710
|
-
})[:numrows].
|
694
|
+
})[:numrows].must_equal 1
|
711
695
|
end
|
712
696
|
|
713
697
|
it "should return the Result Code" do
|
@@ -716,7 +700,7 @@ describe "MSSQL Stored Procedure support" do
|
|
716
700
|
'IntegerInput' => 1,
|
717
701
|
'Output' => [:output, nil, 'output'],
|
718
702
|
'IntegerOutput' => [:output, nil, 'integer_output']
|
719
|
-
})[:result].
|
703
|
+
})[:result].must_equal 1
|
720
704
|
end
|
721
705
|
end
|
722
706
|
end unless DB.adapter_scheme == :odbc
|