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
|
@@ -20,51 +20,51 @@ describe "Sequel::Deprecated" do
|
|
|
20
20
|
@d.backtrace_filter = @prev_backtrace_filter
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
it "should output full messages to the given output" do
|
|
24
24
|
@d.deprecate("foo")
|
|
25
|
-
@output.
|
|
25
|
+
@output.must_equal ['foo']
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
it "should consider two arguments to be a method name and additional text" do
|
|
29
29
|
@d.deprecate("foo", "Use bar instead")
|
|
30
|
-
@output.
|
|
30
|
+
@output.must_equal ['foo is deprecated and will be removed in a future version of Sequel. Use bar instead.']
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
it "should include a prefix if set" do
|
|
34
34
|
@d.prefix = "DEPWARN: "
|
|
35
35
|
@d.deprecate("foo")
|
|
36
|
-
@output.
|
|
36
|
+
@output.must_equal ['DEPWARN: foo']
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
it "should not output anything if output is false" do
|
|
40
40
|
@d.output = false
|
|
41
|
-
|
|
41
|
+
@d.deprecate("foo")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
it "should include full backtrace if backtrace_filter is true" do
|
|
45
45
|
@d.backtrace_filter = true
|
|
46
46
|
@d.deprecate("foo")
|
|
47
|
-
@output.first.
|
|
48
|
-
(4..100).
|
|
47
|
+
@output.first.must_equal 'foo'
|
|
48
|
+
(4..100).must_include(@output.count)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
it "should include given lines of backtrace if backtrace_filter is an integer" do
|
|
52
52
|
@d.backtrace_filter = 1
|
|
53
53
|
@d.deprecate("foo")
|
|
54
|
-
@output.first.
|
|
55
|
-
@output.count.
|
|
54
|
+
@output.first.must_equal 'foo'
|
|
55
|
+
@output.count.must_equal 2
|
|
56
56
|
|
|
57
57
|
@output.clear
|
|
58
58
|
@d.backtrace_filter = 3
|
|
59
59
|
@d.deprecate("foo")
|
|
60
|
-
@output.first.
|
|
61
|
-
@output.count.
|
|
60
|
+
@output.first.must_equal 'foo'
|
|
61
|
+
@output.count.must_equal 4
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
it "should select backtrace lines if backtrace_filter is a proc" do
|
|
65
65
|
@d.backtrace_filter = lambda{|line, line_no| line_no < 3 && line =~ /./}
|
|
66
66
|
@d.deprecate("foo")
|
|
67
|
-
@output.first.
|
|
68
|
-
@output.count.
|
|
67
|
+
@output.first.must_equal 'foo'
|
|
68
|
+
@output.count.must_equal 4
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -13,416 +13,418 @@ describe "Blockless Ruby Filters" do
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "should support boolean columns directly" do
|
|
16
|
-
@d.l(:x).
|
|
16
|
+
@d.l(:x).must_equal 'x'
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it "should support qualified columns" do
|
|
20
|
-
@d.l(:x__y).
|
|
20
|
+
@d.l(:x__y).must_equal 'x.y'
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "should support NOT with SQL functions" do
|
|
24
|
-
@d.l(~Sequel.function(:is_blah)).
|
|
25
|
-
@d.l(~Sequel.function(:is_blah, :x)).
|
|
26
|
-
@d.l(~Sequel.function(:is_blah, :x__y)).
|
|
27
|
-
@d.l(~Sequel.function(:is_blah, :x, :x__y)).
|
|
24
|
+
@d.l(~Sequel.function(:is_blah)).must_equal 'NOT is_blah()'
|
|
25
|
+
@d.l(~Sequel.function(:is_blah, :x)).must_equal 'NOT is_blah(x)'
|
|
26
|
+
@d.l(~Sequel.function(:is_blah, :x__y)).must_equal 'NOT is_blah(x.y)'
|
|
27
|
+
@d.l(~Sequel.function(:is_blah, :x, :x__y)).must_equal 'NOT is_blah(x, x.y)'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "should handle multiple ~" do
|
|
31
|
-
@d.l(~Sequel.~(:x)).
|
|
32
|
-
@d.l(~~Sequel.~(:x)).
|
|
33
|
-
@d.l(~~Sequel.&(:x, :y)).
|
|
34
|
-
@d.l(~~Sequel.|(:x, :y)).
|
|
31
|
+
@d.l(~Sequel.~(:x)).must_equal 'x'
|
|
32
|
+
@d.l(~~Sequel.~(:x)).must_equal 'NOT x'
|
|
33
|
+
@d.l(~~Sequel.&(:x, :y)).must_equal '(x AND y)'
|
|
34
|
+
@d.l(~~Sequel.|(:x, :y)).must_equal '(x OR y)'
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "should support = via Hash" do
|
|
38
|
-
@d.l(:x => 100).
|
|
39
|
-
@d.l(:x => 'a').
|
|
40
|
-
@d.l(:x => true).
|
|
41
|
-
@d.l(:x => false).
|
|
42
|
-
@d.l(:x => nil).
|
|
43
|
-
@d.l(:x => [1,2,3]).
|
|
38
|
+
@d.l(:x => 100).must_equal '(x = 100)'
|
|
39
|
+
@d.l(:x => 'a').must_equal '(x = \'a\')'
|
|
40
|
+
@d.l(:x => true).must_equal '(x IS TRUE)'
|
|
41
|
+
@d.l(:x => false).must_equal '(x IS FALSE)'
|
|
42
|
+
@d.l(:x => nil).must_equal '(x IS NULL)'
|
|
43
|
+
@d.l(:x => [1,2,3]).must_equal '(x IN (1, 2, 3))'
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it "should use = 't' and != 't' OR IS NULL if IS TRUE is not supported" do
|
|
47
47
|
meta_def(@d, :supports_is_true?){false}
|
|
48
|
-
@d.l(:x => true).
|
|
49
|
-
@d.l(~Sequel.expr(:x => true)).
|
|
50
|
-
@d.l(:x => false).
|
|
51
|
-
@d.l(~Sequel.expr(:x => false)).
|
|
48
|
+
@d.l(:x => true).must_equal "(x = 't')"
|
|
49
|
+
@d.l(~Sequel.expr(:x => true)).must_equal "((x != 't') OR (x IS NULL))"
|
|
50
|
+
@d.l(:x => false).must_equal "(x = 'f')"
|
|
51
|
+
@d.l(~Sequel.expr(:x => false)).must_equal "((x != 'f') OR (x IS NULL))"
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
it "should support != via inverted Hash" do
|
|
55
|
-
@d.l(~Sequel.expr(:x => 100)).
|
|
56
|
-
@d.l(~Sequel.expr(:x => 'a')).
|
|
57
|
-
@d.l(~Sequel.expr(:x => true)).
|
|
58
|
-
@d.l(~Sequel.expr(:x => false)).
|
|
59
|
-
@d.l(~Sequel.expr(:x => nil)).
|
|
55
|
+
@d.l(~Sequel.expr(:x => 100)).must_equal '(x != 100)'
|
|
56
|
+
@d.l(~Sequel.expr(:x => 'a')).must_equal '(x != \'a\')'
|
|
57
|
+
@d.l(~Sequel.expr(:x => true)).must_equal '(x IS NOT TRUE)'
|
|
58
|
+
@d.l(~Sequel.expr(:x => false)).must_equal '(x IS NOT FALSE)'
|
|
59
|
+
@d.l(~Sequel.expr(:x => nil)).must_equal '(x IS NOT NULL)'
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it "should support = and similar operations via =~ method" do
|
|
63
|
-
@d.l{x =~ 100}.
|
|
64
|
-
@d.l{x =~ 'a'}.
|
|
65
|
-
@d.l{x =~ true}.
|
|
66
|
-
@d.l{x =~ false}.
|
|
67
|
-
@d.l{x =~ nil}.
|
|
68
|
-
@d.l{x =~ (1...5)}.
|
|
69
|
-
@d.l{x =~ [1,2,3]}.
|
|
63
|
+
@d.l{x =~ 100}.must_equal '(x = 100)'
|
|
64
|
+
@d.l{x =~ 'a'}.must_equal '(x = \'a\')'
|
|
65
|
+
@d.l{x =~ true}.must_equal '(x IS TRUE)'
|
|
66
|
+
@d.l{x =~ false}.must_equal '(x IS FALSE)'
|
|
67
|
+
@d.l{x =~ nil}.must_equal '(x IS NULL)'
|
|
68
|
+
@d.l{x =~ (1...5)}.must_equal '((x >= 1) AND (x < 5))'
|
|
69
|
+
@d.l{x =~ [1,2,3]}.must_equal '(x IN (1, 2, 3))'
|
|
70
70
|
|
|
71
71
|
def @d.supports_regexp?; true end
|
|
72
|
-
@d.l{x =~ /blah/}.
|
|
72
|
+
@d.l{x =~ /blah/}.must_equal '(x ~ \'blah\')'
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
if RUBY_VERSION >= '1.9'
|
|
76
76
|
it "should support != and similar inversions via !~ method" do
|
|
77
|
-
@d.l{x !~ 100}.
|
|
78
|
-
@d.l{x !~ 'a'}.
|
|
79
|
-
@d.l{x !~ true}.
|
|
80
|
-
@d.l{x !~ false}.
|
|
81
|
-
@d.l{x !~ nil}.
|
|
82
|
-
@d.l{x !~ (1...5)}.
|
|
83
|
-
@d.l{x !~ [1,2,3]}.
|
|
77
|
+
@d.l{x !~ 100}.must_equal '(x != 100)'
|
|
78
|
+
@d.l{x !~ 'a'}.must_equal '(x != \'a\')'
|
|
79
|
+
@d.l{x !~ true}.must_equal '(x IS NOT TRUE)'
|
|
80
|
+
@d.l{x !~ false}.must_equal '(x IS NOT FALSE)'
|
|
81
|
+
@d.l{x !~ nil}.must_equal '(x IS NOT NULL)'
|
|
82
|
+
@d.l{x !~ (1...5)}.must_equal '((x < 1) OR (x >= 5))'
|
|
83
|
+
@d.l{x !~ [1,2,3]}.must_equal '(x NOT IN (1, 2, 3))'
|
|
84
84
|
|
|
85
85
|
def @d.supports_regexp?; true end
|
|
86
|
-
@d.l{x !~ /blah/}.
|
|
86
|
+
@d.l{x !~ /blah/}.must_equal '(x !~ \'blah\')'
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
it "should support ~ via Hash and Regexp (if supported by database)" do
|
|
91
91
|
def @d.supports_regexp?; true end
|
|
92
|
-
@d.l(:x => /blah/).
|
|
92
|
+
@d.l(:x => /blah/).must_equal '(x ~ \'blah\')'
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
it "should support !~ via inverted Hash and Regexp" do
|
|
96
96
|
def @d.supports_regexp?; true end
|
|
97
|
-
@d.l(~Sequel.expr(:x => /blah/)).
|
|
97
|
+
@d.l(~Sequel.expr(:x => /blah/)).must_equal '(x !~ \'blah\')'
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it "should support negating ranges" do
|
|
101
|
-
@d.l(~Sequel.expr(:x => 1..5)).
|
|
102
|
-
@d.l(~Sequel.expr(:x => 1...5)).
|
|
101
|
+
@d.l(~Sequel.expr(:x => 1..5)).must_equal '((x < 1) OR (x > 5))'
|
|
102
|
+
@d.l(~Sequel.expr(:x => 1...5)).must_equal '((x < 1) OR (x >= 5))'
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
it "should support negating IN with Dataset or Array" do
|
|
106
|
-
@d.l(~Sequel.expr(:x => @d.select(:i))).
|
|
107
|
-
@d.l(~Sequel.expr(:x => [1,2,3])).
|
|
106
|
+
@d.l(~Sequel.expr(:x => @d.select(:i))).must_equal '(x NOT IN (SELECT i FROM items))'
|
|
107
|
+
@d.l(~Sequel.expr(:x => [1,2,3])).must_equal '(x NOT IN (1, 2, 3))'
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
it "should not add ~ method to string expressions" do
|
|
111
|
-
proc{~Sequel.expr(:x).sql_string}.
|
|
111
|
+
proc{~Sequel.expr(:x).sql_string}.must_raise(NoMethodError)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
it "should allow mathematical or string operations on true, false, or nil" do
|
|
115
|
-
@d.lit(Sequel.expr(:x) + 1).
|
|
116
|
-
@d.lit(Sequel.expr(:x) - true).
|
|
117
|
-
@d.lit(Sequel.expr(:x) / false).
|
|
118
|
-
@d.lit(Sequel.expr(:x) * nil).
|
|
119
|
-
@d.lit(Sequel.join([:x, nil])).
|
|
115
|
+
@d.lit(Sequel.expr(:x) + 1).must_equal '(x + 1)'
|
|
116
|
+
@d.lit(Sequel.expr(:x) - true).must_equal "(x - 't')"
|
|
117
|
+
@d.lit(Sequel.expr(:x) / false).must_equal "(x / 'f')"
|
|
118
|
+
@d.lit(Sequel.expr(:x) * nil).must_equal '(x * NULL)'
|
|
119
|
+
@d.lit(Sequel.join([:x, nil])).must_equal '(x || NULL)'
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "should allow mathematical or string operations on boolean complex expressions" do
|
|
123
|
-
@d.lit(Sequel.expr(:x) + (Sequel.expr(:y) + 1)).
|
|
124
|
-
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y)).
|
|
125
|
-
@d.lit(Sequel.expr(:x) / (Sequel.expr(:y) & :z)).
|
|
126
|
-
@d.lit(Sequel.expr(:x) * (Sequel.expr(:y) | :z)).
|
|
127
|
-
@d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).
|
|
128
|
-
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).
|
|
129
|
-
@d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).
|
|
123
|
+
@d.lit(Sequel.expr(:x) + (Sequel.expr(:y) + 1)).must_equal '(x + y + 1)'
|
|
124
|
+
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y)).must_equal '(x - NOT y)'
|
|
125
|
+
@d.lit(Sequel.expr(:x) / (Sequel.expr(:y) & :z)).must_equal '(x / (y AND z))'
|
|
126
|
+
@d.lit(Sequel.expr(:x) * (Sequel.expr(:y) | :z)).must_equal '(x * (y OR z))'
|
|
127
|
+
@d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).must_equal "(x + (y LIKE 'a' ESCAPE '\\'))"
|
|
128
|
+
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).must_equal "(x - (y NOT LIKE 'a' ESCAPE '\\'))"
|
|
129
|
+
@d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).must_equal "(x || (y NOT LIKE 'a' ESCAPE '\\'))"
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
it "should support AND conditions via &" do
|
|
133
|
-
@d.l(Sequel.expr(:x) & :y).
|
|
134
|
-
@d.l(Sequel.expr(:x).sql_boolean & :y).
|
|
135
|
-
@d.l(Sequel.expr(:x) & :y & :z).
|
|
136
|
-
@d.l(Sequel.expr(:x) & {:y => :z}).
|
|
137
|
-
@d.l((Sequel.expr(:x) + 200 < 0) & (Sequel.expr(:y) - 200 < 0)).
|
|
138
|
-
@d.l(Sequel.expr(:x) & ~Sequel.expr(:y)).
|
|
139
|
-
@d.l(~Sequel.expr(:x) & :y).
|
|
140
|
-
@d.l(~Sequel.expr(:x) & ~Sequel.expr(:y)).
|
|
133
|
+
@d.l(Sequel.expr(:x) & :y).must_equal '(x AND y)'
|
|
134
|
+
@d.l(Sequel.expr(:x).sql_boolean & :y).must_equal '(x AND y)'
|
|
135
|
+
@d.l(Sequel.expr(:x) & :y & :z).must_equal '(x AND y AND z)'
|
|
136
|
+
@d.l(Sequel.expr(:x) & {:y => :z}).must_equal '(x AND (y = z))'
|
|
137
|
+
@d.l((Sequel.expr(:x) + 200 < 0) & (Sequel.expr(:y) - 200 < 0)).must_equal '(((x + 200) < 0) AND ((y - 200) < 0))'
|
|
138
|
+
@d.l(Sequel.expr(:x) & ~Sequel.expr(:y)).must_equal '(x AND NOT y)'
|
|
139
|
+
@d.l(~Sequel.expr(:x) & :y).must_equal '(NOT x AND y)'
|
|
140
|
+
@d.l(~Sequel.expr(:x) & ~Sequel.expr(:y)).must_equal '(NOT x AND NOT y)'
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should support OR conditions via |" do
|
|
144
|
-
@d.l(Sequel.expr(:x) | :y).
|
|
145
|
-
@d.l(Sequel.expr(:x).sql_boolean | :y).
|
|
146
|
-
@d.l(Sequel.expr(:x) | :y | :z).
|
|
147
|
-
@d.l(Sequel.expr(:x) | {:y => :z}).
|
|
148
|
-
@d.l((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y).sql_number < 200)).
|
|
144
|
+
@d.l(Sequel.expr(:x) | :y).must_equal '(x OR y)'
|
|
145
|
+
@d.l(Sequel.expr(:x).sql_boolean | :y).must_equal '(x OR y)'
|
|
146
|
+
@d.l(Sequel.expr(:x) | :y | :z).must_equal '(x OR y OR z)'
|
|
147
|
+
@d.l(Sequel.expr(:x) | {:y => :z}).must_equal '(x OR (y = z))'
|
|
148
|
+
@d.l((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y).sql_number < 200)).must_equal '((x > 200) OR (y < 200))'
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
it "should support & | combinations" do
|
|
152
|
-
@d.l((Sequel.expr(:x) | :y) & :z).
|
|
153
|
-
@d.l(Sequel.expr(:x) | (Sequel.expr(:y) & :z)).
|
|
154
|
-
@d.l((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z)).
|
|
152
|
+
@d.l((Sequel.expr(:x) | :y) & :z).must_equal '((x OR y) AND z)'
|
|
153
|
+
@d.l(Sequel.expr(:x) | (Sequel.expr(:y) & :z)).must_equal '(x OR (y AND z))'
|
|
154
|
+
@d.l((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z)).must_equal '((x AND w) OR (y AND z))'
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
it "should support & | with ~" do
|
|
158
|
-
@d.l(~((Sequel.expr(:x) | :y) & :z)).
|
|
159
|
-
@d.l(~(Sequel.expr(:x) | (Sequel.expr(:y) & :z))).
|
|
160
|
-
@d.l(~((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z))).
|
|
161
|
-
@d.l(~((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y) & :z))).
|
|
158
|
+
@d.l(~((Sequel.expr(:x) | :y) & :z)).must_equal '((NOT x AND NOT y) OR NOT z)'
|
|
159
|
+
@d.l(~(Sequel.expr(:x) | (Sequel.expr(:y) & :z))).must_equal '(NOT x AND (NOT y OR NOT z))'
|
|
160
|
+
@d.l(~((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z))).must_equal '((NOT x OR NOT w) AND (NOT y OR NOT z))'
|
|
161
|
+
@d.l(~((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y) & :z))).must_equal '((x <= 200) AND (NOT y OR NOT z))'
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
it "should support LiteralString" do
|
|
165
|
-
@d.l(Sequel.lit('x')).
|
|
166
|
-
@d.l(~Sequel.lit('x')).
|
|
167
|
-
@d.l(~~Sequel.lit('x')).
|
|
168
|
-
@d.l(~((Sequel.lit('x') | :y) & :z)).
|
|
169
|
-
@d.l(~(Sequel.expr(:x) | Sequel.lit('y'))).
|
|
170
|
-
@d.l(~(Sequel.lit('x') & Sequel.lit('y'))).
|
|
171
|
-
@d.l(Sequel.expr(Sequel.lit('y') => Sequel.lit('z')) & Sequel.lit('x')).
|
|
172
|
-
@d.l((Sequel.lit('x') > 200) & (Sequel.lit('y') < 200)).
|
|
173
|
-
@d.l(~(Sequel.lit('x') + 1 > 100)).
|
|
174
|
-
@d.l(Sequel.lit('x').like('a')).
|
|
175
|
-
@d.l(Sequel.lit('x') + 1 > 100).
|
|
176
|
-
@d.l((Sequel.lit('x') * :y) < 100.01).
|
|
177
|
-
@d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).
|
|
178
|
-
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).
|
|
179
|
-
@d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).
|
|
165
|
+
@d.l(Sequel.lit('x')).must_equal '(x)'
|
|
166
|
+
@d.l(~Sequel.lit('x')).must_equal 'NOT x'
|
|
167
|
+
@d.l(~~Sequel.lit('x')).must_equal 'x'
|
|
168
|
+
@d.l(~((Sequel.lit('x') | :y) & :z)).must_equal '((NOT x AND NOT y) OR NOT z)'
|
|
169
|
+
@d.l(~(Sequel.expr(:x) | Sequel.lit('y'))).must_equal '(NOT x AND NOT y)'
|
|
170
|
+
@d.l(~(Sequel.lit('x') & Sequel.lit('y'))).must_equal '(NOT x OR NOT y)'
|
|
171
|
+
@d.l(Sequel.expr(Sequel.lit('y') => Sequel.lit('z')) & Sequel.lit('x')).must_equal '((y = z) AND x)'
|
|
172
|
+
@d.l((Sequel.lit('x') > 200) & (Sequel.lit('y') < 200)).must_equal '((x > 200) AND (y < 200))'
|
|
173
|
+
@d.l(~(Sequel.lit('x') + 1 > 100)).must_equal '((x + 1) <= 100)'
|
|
174
|
+
@d.l(Sequel.lit('x').like('a')).must_equal '(x LIKE \'a\' ESCAPE \'\\\')'
|
|
175
|
+
@d.l(Sequel.lit('x') + 1 > 100).must_equal '((x + 1) > 100)'
|
|
176
|
+
@d.l((Sequel.lit('x') * :y) < 100.01).must_equal '((x * y) < 100.01)'
|
|
177
|
+
@d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
|
178
|
+
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).must_equal '((z * (x / y / (x + y))) <= 100)'
|
|
179
|
+
@d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
it "should support hashes by ANDing the conditions" do
|
|
183
|
-
@d.l(:x => 100, :y => 'a')[1...-1].split(' AND ').sort.
|
|
184
|
-
@d.l(:x => true, :y => false)[1...-1].split(' AND ').sort.
|
|
185
|
-
@d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.
|
|
183
|
+
@d.l(:x => 100, :y => 'a')[1...-1].split(' AND ').sort.must_equal ['(x = 100)', '(y = \'a\')']
|
|
184
|
+
@d.l(:x => true, :y => false)[1...-1].split(' AND ').sort.must_equal ['(x IS TRUE)', '(y IS FALSE)']
|
|
185
|
+
@d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.must_equal ['(x IS NULL)', '(y IN (1, 2, 3))']
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
it "should support arrays with all two pairs the same as hashes" do
|
|
189
|
-
@d.l([[:x, 100],[:y, 'a']]).
|
|
190
|
-
@d.l([[:x, true], [:y, false]]).
|
|
191
|
-
@d.l([[:x, nil], [:y, [1,2,3]]]).
|
|
189
|
+
@d.l([[:x, 100],[:y, 'a']]).must_equal '((x = 100) AND (y = \'a\'))'
|
|
190
|
+
@d.l([[:x, true], [:y, false]]).must_equal '((x IS TRUE) AND (y IS FALSE))'
|
|
191
|
+
@d.l([[:x, nil], [:y, [1,2,3]]]).must_equal '((x IS NULL) AND (y IN (1, 2, 3)))'
|
|
192
192
|
end
|
|
193
193
|
|
|
194
194
|
it "should emulate columns for array values" do
|
|
195
|
-
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).
|
|
196
|
-
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).
|
|
195
|
+
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).must_equal '((x, y) IN ((1, 2), (3, 4)))'
|
|
196
|
+
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).must_equal '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
it "should emulate multiple column in if not supported" do
|
|
200
200
|
meta_def(@d, :supports_multiple_column_in?){false}
|
|
201
|
-
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).
|
|
202
|
-
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).
|
|
201
|
+
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).must_equal '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
|
|
202
|
+
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).must_equal '(((x = 1) AND (y = 2) AND (z = 5)) OR ((x = 3) AND (y = 4) AND (z = 6)))'
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
it "should support StringExpression#+ for concatenation of SQL strings" do
|
|
206
|
-
@d.lit(Sequel.expr(:x).sql_string + :y).
|
|
207
|
-
@d.lit(Sequel.join([:x]) + :y).
|
|
208
|
-
@d.lit(Sequel.join([:x, :z], ' ') + :y).
|
|
206
|
+
@d.lit(Sequel.expr(:x).sql_string + :y).must_equal '(x || y)'
|
|
207
|
+
@d.lit(Sequel.join([:x]) + :y).must_equal '(x || y)'
|
|
208
|
+
@d.lit(Sequel.join([:x, :z], ' ') + :y).must_equal "(x || ' ' || z || y)"
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it "should be supported inside blocks" do
|
|
212
|
-
@d.l{Sequel.or([[:x, nil], [:y, [1,2,3]]])}.
|
|
213
|
-
@d.l{Sequel.~([[:x, nil], [:y, [1,2,3]]])}.
|
|
214
|
-
@d.l{~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)}.
|
|
215
|
-
@d.l{Sequel.&({:x => :a}, {:y => :z})}.
|
|
212
|
+
@d.l{Sequel.or([[:x, nil], [:y, [1,2,3]]])}.must_equal '((x IS NULL) OR (y IN (1, 2, 3)))'
|
|
213
|
+
@d.l{Sequel.~([[:x, nil], [:y, [1,2,3]]])}.must_equal '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
|
|
214
|
+
@d.l{~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)}.must_equal '((((x - y) / (x + y)) * z) > 100)'
|
|
215
|
+
@d.l{Sequel.&({:x => :a}, {:y => :z})}.must_equal '((x = a) AND (y = z))'
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
it "should support &, |, ^, ~, <<, and >> for NumericExpressions" do
|
|
219
|
-
@d.l(Sequel.expr(:x).sql_number & 1 > 100).
|
|
220
|
-
@d.l(Sequel.expr(:x).sql_number | 1 > 100).
|
|
221
|
-
@d.l(Sequel.expr(:x).sql_number ^ 1 > 100).
|
|
222
|
-
@d.l(~Sequel.expr(:x).sql_number > 100).
|
|
223
|
-
@d.l(Sequel.expr(:x).sql_number << 1 > 100).
|
|
224
|
-
@d.l(Sequel.expr(:x).sql_number >> 1 > 100).
|
|
225
|
-
@d.l((Sequel.expr(:x) + 1) & 1 > 100).
|
|
226
|
-
@d.l((Sequel.expr(:x) + 1) | 1 > 100).
|
|
227
|
-
@d.l((Sequel.expr(:x) + 1) ^ 1 > 100).
|
|
228
|
-
@d.l(~(Sequel.expr(:x) + 1) > 100).
|
|
229
|
-
@d.l((Sequel.expr(:x) + 1) << 1 > 100).
|
|
230
|
-
@d.l((Sequel.expr(:x) + 1) >> 1 > 100).
|
|
231
|
-
@d.l((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + 2) > 100).
|
|
219
|
+
@d.l(Sequel.expr(:x).sql_number & 1 > 100).must_equal '((x & 1) > 100)'
|
|
220
|
+
@d.l(Sequel.expr(:x).sql_number | 1 > 100).must_equal '((x | 1) > 100)'
|
|
221
|
+
@d.l(Sequel.expr(:x).sql_number ^ 1 > 100).must_equal '((x ^ 1) > 100)'
|
|
222
|
+
@d.l(~Sequel.expr(:x).sql_number > 100).must_equal '(~x > 100)'
|
|
223
|
+
@d.l(Sequel.expr(:x).sql_number << 1 > 100).must_equal '((x << 1) > 100)'
|
|
224
|
+
@d.l(Sequel.expr(:x).sql_number >> 1 > 100).must_equal '((x >> 1) > 100)'
|
|
225
|
+
@d.l((Sequel.expr(:x) + 1) & 1 > 100).must_equal '(((x + 1) & 1) > 100)'
|
|
226
|
+
@d.l((Sequel.expr(:x) + 1) | 1 > 100).must_equal '(((x + 1) | 1) > 100)'
|
|
227
|
+
@d.l((Sequel.expr(:x) + 1) ^ 1 > 100).must_equal '(((x + 1) ^ 1) > 100)'
|
|
228
|
+
@d.l(~(Sequel.expr(:x) + 1) > 100).must_equal '(~(x + 1) > 100)'
|
|
229
|
+
@d.l((Sequel.expr(:x) + 1) << 1 > 100).must_equal '(((x + 1) << 1) > 100)'
|
|
230
|
+
@d.l((Sequel.expr(:x) + 1) >> 1 > 100).must_equal '(((x + 1) >> 1) > 100)'
|
|
231
|
+
@d.l((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + 2) > 100).must_equal '(((x + 1) & (x + 2)) > 100)'
|
|
232
232
|
end
|
|
233
233
|
|
|
234
234
|
it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
|
|
235
|
-
@d.lit((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + '2')).
|
|
235
|
+
@d.lit((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + '2')).must_equal "((x + 1) & (x || '2'))"
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
|
|
239
|
-
@d.l(Sequel.expr(:x) & (Sequel.expr(:x) + '2')).
|
|
239
|
+
@d.l(Sequel.expr(:x) & (Sequel.expr(:x) + '2')).must_equal "(x AND (x || '2'))"
|
|
240
240
|
end
|
|
241
241
|
|
|
242
242
|
it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
|
|
243
|
-
proc{Sequel::SQL::BooleanExpression.invert(Sequel.expr(:x) + 2)}.
|
|
243
|
+
proc{Sequel::SQL::BooleanExpression.invert(Sequel.expr(:x) + 2)}.must_raise(Sequel::Error)
|
|
244
244
|
end
|
|
245
245
|
|
|
246
246
|
it "should return self on .lit" do
|
|
247
247
|
y = Sequel.expr(:x) + 1
|
|
248
|
-
y.lit.
|
|
248
|
+
y.lit.must_equal y
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
it "should return have .sql_literal return the literal SQL for the expression" do
|
|
252
252
|
y = Sequel.expr(:x) + 1
|
|
253
|
-
y.sql_literal(@d).
|
|
254
|
-
y.sql_literal(@d).
|
|
253
|
+
y.sql_literal(@d).must_equal '(x + 1)'
|
|
254
|
+
y.sql_literal(@d).must_equal @d.literal(y)
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
it "should support SQL::Constants" do
|
|
258
|
-
@d.l({:x => Sequel::NULL}).
|
|
259
|
-
@d.l({:x => Sequel::NOTNULL}).
|
|
260
|
-
@d.l({:x => Sequel::TRUE}).
|
|
261
|
-
@d.l({:x => Sequel::FALSE}).
|
|
262
|
-
@d.l({:x => Sequel::SQLTRUE}).
|
|
263
|
-
@d.l({:x => Sequel::SQLFALSE}).
|
|
258
|
+
@d.l({:x => Sequel::NULL}).must_equal '(x IS NULL)'
|
|
259
|
+
@d.l({:x => Sequel::NOTNULL}).must_equal '(x IS NOT NULL)'
|
|
260
|
+
@d.l({:x => Sequel::TRUE}).must_equal '(x IS TRUE)'
|
|
261
|
+
@d.l({:x => Sequel::FALSE}).must_equal '(x IS FALSE)'
|
|
262
|
+
@d.l({:x => Sequel::SQLTRUE}).must_equal '(x IS TRUE)'
|
|
263
|
+
@d.l({:x => Sequel::SQLFALSE}).must_equal '(x IS FALSE)'
|
|
264
264
|
end
|
|
265
265
|
|
|
266
266
|
it "should support negation of SQL::Constants" do
|
|
267
|
-
@d.l(Sequel.~(:x => Sequel::NULL)).
|
|
268
|
-
@d.l(Sequel.~(:x => Sequel::NOTNULL)).
|
|
269
|
-
@d.l(Sequel.~(:x => Sequel::TRUE)).
|
|
270
|
-
@d.l(Sequel.~(:x => Sequel::FALSE)).
|
|
271
|
-
@d.l(Sequel.~(:x => Sequel::SQLTRUE)).
|
|
272
|
-
@d.l(Sequel.~(:x => Sequel::SQLFALSE)).
|
|
267
|
+
@d.l(Sequel.~(:x => Sequel::NULL)).must_equal '(x IS NOT NULL)'
|
|
268
|
+
@d.l(Sequel.~(:x => Sequel::NOTNULL)).must_equal '(x IS NULL)'
|
|
269
|
+
@d.l(Sequel.~(:x => Sequel::TRUE)).must_equal '(x IS NOT TRUE)'
|
|
270
|
+
@d.l(Sequel.~(:x => Sequel::FALSE)).must_equal '(x IS NOT FALSE)'
|
|
271
|
+
@d.l(Sequel.~(:x => Sequel::SQLTRUE)).must_equal '(x IS NOT TRUE)'
|
|
272
|
+
@d.l(Sequel.~(:x => Sequel::SQLFALSE)).must_equal '(x IS NOT FALSE)'
|
|
273
273
|
end
|
|
274
274
|
|
|
275
275
|
it "should support direct negation of SQL::Constants" do
|
|
276
|
-
@d.l({:x => ~Sequel::NULL}).
|
|
277
|
-
@d.l({:x => ~Sequel::NOTNULL}).
|
|
278
|
-
@d.l({:x => ~Sequel::TRUE}).
|
|
279
|
-
@d.l({:x => ~Sequel::FALSE}).
|
|
280
|
-
@d.l({:x => ~Sequel::SQLTRUE}).
|
|
281
|
-
@d.l({:x => ~Sequel::SQLFALSE}).
|
|
276
|
+
@d.l({:x => ~Sequel::NULL}).must_equal '(x IS NOT NULL)'
|
|
277
|
+
@d.l({:x => ~Sequel::NOTNULL}).must_equal '(x IS NULL)'
|
|
278
|
+
@d.l({:x => ~Sequel::TRUE}).must_equal '(x IS FALSE)'
|
|
279
|
+
@d.l({:x => ~Sequel::FALSE}).must_equal '(x IS TRUE)'
|
|
280
|
+
@d.l({:x => ~Sequel::SQLTRUE}).must_equal '(x IS FALSE)'
|
|
281
|
+
@d.l({:x => ~Sequel::SQLFALSE}).must_equal '(x IS TRUE)'
|
|
282
282
|
end
|
|
283
283
|
|
|
284
284
|
it "should raise an error if trying to invert an invalid SQL::Constant" do
|
|
285
|
-
proc{~Sequel::CURRENT_DATE}.
|
|
285
|
+
proc{~Sequel::CURRENT_DATE}.must_raise(Sequel::Error)
|
|
286
286
|
end
|
|
287
287
|
|
|
288
288
|
it "should raise an error if trying to create an invalid complex expression" do
|
|
289
|
-
proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.
|
|
289
|
+
proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.must_raise(Sequel::Error)
|
|
290
290
|
end
|
|
291
291
|
|
|
292
292
|
it "should use a string concatentation for + if given a string" do
|
|
293
|
-
@d.lit(Sequel.expr(:x) + '1').
|
|
294
|
-
@d.lit(Sequel.expr(:x) + '1' + '1').
|
|
293
|
+
@d.lit(Sequel.expr(:x) + '1').must_equal "(x || '1')"
|
|
294
|
+
@d.lit(Sequel.expr(:x) + '1' + '1').must_equal "(x || '1' || '1')"
|
|
295
295
|
end
|
|
296
296
|
|
|
297
297
|
it "should use an addition for + if given a literal string" do
|
|
298
|
-
@d.lit(Sequel.expr(:x) + Sequel.lit('1')).
|
|
299
|
-
@d.lit(Sequel.expr(:x) + Sequel.lit('1') + Sequel.lit('1')).
|
|
298
|
+
@d.lit(Sequel.expr(:x) + Sequel.lit('1')).must_equal "(x + 1)"
|
|
299
|
+
@d.lit(Sequel.expr(:x) + Sequel.lit('1') + Sequel.lit('1')).must_equal "(x + 1 + 1)"
|
|
300
300
|
end
|
|
301
301
|
|
|
302
302
|
it "should use a bitwise operator for & and | if given an integer" do
|
|
303
|
-
@d.lit(Sequel.expr(:x) & 1).
|
|
304
|
-
@d.lit(Sequel.expr(:x) | 1).
|
|
305
|
-
@d.lit(Sequel.expr(:x) & 1 & 1).
|
|
306
|
-
@d.lit(Sequel.expr(:x) | 1 | 1).
|
|
303
|
+
@d.lit(Sequel.expr(:x) & 1).must_equal "(x & 1)"
|
|
304
|
+
@d.lit(Sequel.expr(:x) | 1).must_equal "(x | 1)"
|
|
305
|
+
@d.lit(Sequel.expr(:x) & 1 & 1).must_equal "(x & 1 & 1)"
|
|
306
|
+
@d.lit(Sequel.expr(:x) | 1 | 1).must_equal "(x | 1 | 1)"
|
|
307
307
|
end
|
|
308
308
|
|
|
309
309
|
it "should allow adding a string to an integer expression" do
|
|
310
|
-
@d.lit(Sequel.expr(:x) + 1 + 'a').
|
|
310
|
+
@d.lit(Sequel.expr(:x) + 1 + 'a').must_equal "(x + 1 + 'a')"
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
it "should allow adding an integer to an string expression" do
|
|
314
|
-
@d.lit(Sequel.expr(:x) + 'a' + 1).
|
|
314
|
+
@d.lit(Sequel.expr(:x) + 'a' + 1).must_equal "(x || 'a' || 1)"
|
|
315
315
|
end
|
|
316
316
|
|
|
317
317
|
it "should allow adding a boolean to an integer expression" do
|
|
318
|
-
@d.lit(Sequel.expr(:x) + 1 + true).
|
|
318
|
+
@d.lit(Sequel.expr(:x) + 1 + true).must_equal "(x + 1 + 't')"
|
|
319
319
|
end
|
|
320
320
|
|
|
321
321
|
it "should allow adding a boolean to an string expression" do
|
|
322
|
-
@d.lit(Sequel.expr(:x) + 'a' + true).
|
|
322
|
+
@d.lit(Sequel.expr(:x) + 'a' + true).must_equal "(x || 'a' || 't')"
|
|
323
323
|
end
|
|
324
324
|
|
|
325
325
|
it "should allow using a boolean operation with an integer on an boolean expression" do
|
|
326
|
-
@d.lit(Sequel.expr(:x) & :a & 1).
|
|
326
|
+
@d.lit(Sequel.expr(:x) & :a & 1).must_equal "(x AND a AND 1)"
|
|
327
327
|
end
|
|
328
328
|
|
|
329
329
|
it "should allow using a boolean operation with a string on an boolean expression" do
|
|
330
|
-
@d.lit(Sequel.expr(:x) & :a & 'a').
|
|
330
|
+
@d.lit(Sequel.expr(:x) & :a & 'a').must_equal "(x AND a AND 'a')"
|
|
331
331
|
end
|
|
332
332
|
|
|
333
333
|
it "should allowing AND of boolean expression and literal string" do
|
|
334
|
-
@d.lit(Sequel.expr(:x) & :a & Sequel.lit('a')).
|
|
334
|
+
@d.lit(Sequel.expr(:x) & :a & Sequel.lit('a')).must_equal "(x AND a AND a)"
|
|
335
335
|
end
|
|
336
336
|
|
|
337
337
|
it "should allowing + of integer expression and literal string" do
|
|
338
|
-
@d.lit(Sequel.expr(:x) + :a + Sequel.lit('a')).
|
|
338
|
+
@d.lit(Sequel.expr(:x) + :a + Sequel.lit('a')).must_equal "(x + a + a)"
|
|
339
339
|
end
|
|
340
340
|
|
|
341
341
|
it "should allowing + of string expression and literal string" do
|
|
342
|
-
@d.lit(Sequel.expr(:x) + 'a' + Sequel.lit('a')).
|
|
342
|
+
@d.lit(Sequel.expr(:x) + 'a' + Sequel.lit('a')).must_equal "(x || 'a' || a)"
|
|
343
343
|
end
|
|
344
344
|
|
|
345
345
|
it "should allow sql_{string,boolean,number} methods on numeric expressions" do
|
|
346
|
-
@d.lit((Sequel.expr(:x) + 1).sql_string + 'a').
|
|
347
|
-
@d.lit((Sequel.expr(:x) + 1).sql_boolean & 1).
|
|
348
|
-
@d.lit((Sequel.expr(:x) + 1).sql_number + 'a').
|
|
346
|
+
@d.lit((Sequel.expr(:x) + 1).sql_string + 'a').must_equal "((x + 1) || 'a')"
|
|
347
|
+
@d.lit((Sequel.expr(:x) + 1).sql_boolean & 1).must_equal "((x + 1) AND 1)"
|
|
348
|
+
@d.lit((Sequel.expr(:x) + 1).sql_number + 'a').must_equal "(x + 1 + 'a')"
|
|
349
349
|
end
|
|
350
350
|
|
|
351
351
|
it "should allow sql_{string,boolean,number} methods on string expressions" do
|
|
352
|
-
@d.lit((Sequel.expr(:x) + 'a').sql_string + 'a').
|
|
353
|
-
@d.lit((Sequel.expr(:x) + 'a').sql_boolean & 1).
|
|
354
|
-
@d.lit((Sequel.expr(:x) + 'a').sql_number + 'a').
|
|
352
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_string + 'a').must_equal "(x || 'a' || 'a')"
|
|
353
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_boolean & 1).must_equal "((x || 'a') AND 1)"
|
|
354
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_number + 'a').must_equal "((x || 'a') + 'a')"
|
|
355
355
|
end
|
|
356
356
|
|
|
357
357
|
it "should allow sql_{string,boolean,number} methods on boolean expressions" do
|
|
358
|
-
@d.lit((Sequel.expr(:x) & :y).sql_string + 'a').
|
|
359
|
-
@d.lit((Sequel.expr(:x) & :y).sql_boolean & 1).
|
|
360
|
-
@d.lit((Sequel.expr(:x) & :y).sql_number + 'a').
|
|
358
|
+
@d.lit((Sequel.expr(:x) & :y).sql_string + 'a').must_equal "((x AND y) || 'a')"
|
|
359
|
+
@d.lit((Sequel.expr(:x) & :y).sql_boolean & 1).must_equal "(x AND y AND 1)"
|
|
360
|
+
@d.lit((Sequel.expr(:x) & :y).sql_number + 'a').must_equal "((x AND y) + 'a')"
|
|
361
361
|
end
|
|
362
362
|
|
|
363
363
|
it "should raise an error if trying to literalize an invalid complex expression" do
|
|
364
364
|
ce = Sequel.+(:x, 1)
|
|
365
365
|
ce.instance_variable_set(:@op, :BANG)
|
|
366
|
-
proc{@d.lit(ce)}.
|
|
366
|
+
proc{@d.lit(ce)}.must_raise(Sequel::InvalidOperation)
|
|
367
367
|
end
|
|
368
368
|
|
|
369
369
|
it "should support equality comparison of two expressions" do
|
|
370
370
|
e1 = ~Sequel.like(:comment, '%:hidden:%')
|
|
371
371
|
e2 = ~Sequel.like(:comment, '%:hidden:%')
|
|
372
|
-
e1.
|
|
372
|
+
e1.must_equal e2
|
|
373
373
|
end
|
|
374
374
|
|
|
375
375
|
it "should support expression filter methods on Datasets" do
|
|
376
376
|
d = @d.select(:a)
|
|
377
377
|
|
|
378
|
-
@d.lit(d + 1).
|
|
379
|
-
@d.lit(d - 1).
|
|
380
|
-
@d.lit(d * 1).
|
|
381
|
-
@d.lit(d / 1).
|
|
378
|
+
@d.lit(d + 1).must_equal '((SELECT a FROM items) + 1)'
|
|
379
|
+
@d.lit(d - 1).must_equal '((SELECT a FROM items) - 1)'
|
|
380
|
+
@d.lit(d * 1).must_equal '((SELECT a FROM items) * 1)'
|
|
381
|
+
@d.lit(d / 1).must_equal '((SELECT a FROM items) / 1)'
|
|
382
382
|
|
|
383
|
-
@d.lit(d => 1).
|
|
384
|
-
@d.lit(Sequel.~(d => 1)).
|
|
385
|
-
@d.lit(d > 1).
|
|
386
|
-
@d.lit(d < 1).
|
|
387
|
-
@d.lit(d >= 1).
|
|
388
|
-
@d.lit(d <= 1).
|
|
383
|
+
@d.lit(d => 1).must_equal '((SELECT a FROM items) = 1)'
|
|
384
|
+
@d.lit(Sequel.~(d => 1)).must_equal '((SELECT a FROM items) != 1)'
|
|
385
|
+
@d.lit(d > 1).must_equal '((SELECT a FROM items) > 1)'
|
|
386
|
+
@d.lit(d < 1).must_equal '((SELECT a FROM items) < 1)'
|
|
387
|
+
@d.lit(d >= 1).must_equal '((SELECT a FROM items) >= 1)'
|
|
388
|
+
@d.lit(d <= 1).must_equal '((SELECT a FROM items) <= 1)'
|
|
389
389
|
|
|
390
|
-
@d.lit(d.as(:b)).
|
|
390
|
+
@d.lit(d.as(:b)).must_equal '(SELECT a FROM items) AS b'
|
|
391
391
|
|
|
392
|
-
@d.lit(d & :b).
|
|
393
|
-
@d.lit(d | :b).
|
|
394
|
-
@d.lit(~d).
|
|
392
|
+
@d.lit(d & :b).must_equal '((SELECT a FROM items) AND b)'
|
|
393
|
+
@d.lit(d | :b).must_equal '((SELECT a FROM items) OR b)'
|
|
394
|
+
@d.lit(~d).must_equal 'NOT (SELECT a FROM items)'
|
|
395
395
|
|
|
396
|
-
@d.lit(d.cast(Integer)).
|
|
397
|
-
@d.lit(d.cast_numeric).
|
|
398
|
-
@d.lit(d.cast_string).
|
|
399
|
-
@d.lit(d.cast_numeric << :b).
|
|
400
|
-
@d.lit(d.cast_string + :b).
|
|
396
|
+
@d.lit(d.cast(Integer)).must_equal 'CAST((SELECT a FROM items) AS integer)'
|
|
397
|
+
@d.lit(d.cast_numeric).must_equal 'CAST((SELECT a FROM items) AS integer)'
|
|
398
|
+
@d.lit(d.cast_string).must_equal 'CAST((SELECT a FROM items) AS varchar(255))'
|
|
399
|
+
@d.lit(d.cast_numeric << :b).must_equal '(CAST((SELECT a FROM items) AS integer) << b)'
|
|
400
|
+
@d.lit(d.cast_string + :b).must_equal '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
|
|
401
401
|
|
|
402
|
-
@d.lit(d.extract(:year)).
|
|
403
|
-
@d.lit(d.sql_boolean & :b).
|
|
404
|
-
@d.lit(d.sql_number << :b).
|
|
405
|
-
@d.lit(d.sql_string + :b).
|
|
402
|
+
@d.lit(d.extract(:year)).must_equal 'extract(year FROM (SELECT a FROM items))'
|
|
403
|
+
@d.lit(d.sql_boolean & :b).must_equal '((SELECT a FROM items) AND b)'
|
|
404
|
+
@d.lit(d.sql_number << :b).must_equal '((SELECT a FROM items) << b)'
|
|
405
|
+
@d.lit(d.sql_string + :b).must_equal '((SELECT a FROM items) || b)'
|
|
406
406
|
|
|
407
|
-
@d.lit(d.asc).
|
|
408
|
-
@d.lit(d.desc).
|
|
407
|
+
@d.lit(d.asc).must_equal '(SELECT a FROM items) ASC'
|
|
408
|
+
@d.lit(d.desc).must_equal '(SELECT a FROM items) DESC'
|
|
409
409
|
|
|
410
|
-
@d.lit(d.like(:b)).
|
|
411
|
-
@d.lit(d.ilike(:b)).
|
|
410
|
+
@d.lit(d.like(:b)).must_equal '((SELECT a FROM items) LIKE b ESCAPE \'\\\')'
|
|
411
|
+
@d.lit(d.ilike(:b)).must_equal '(UPPER((SELECT a FROM items)) LIKE UPPER(b) ESCAPE \'\\\')'
|
|
412
412
|
end
|
|
413
413
|
|
|
414
414
|
it "should handled emulated char_length function" do
|
|
415
|
-
@d.lit(Sequel.char_length(:a)).
|
|
415
|
+
@d.lit(Sequel.char_length(:a)).must_equal 'char_length(a)'
|
|
416
416
|
end
|
|
417
417
|
|
|
418
418
|
it "should handled emulated trim function" do
|
|
419
|
-
@d.lit(Sequel.trim(:a)).
|
|
419
|
+
@d.lit(Sequel.trim(:a)).must_equal 'trim(a)'
|
|
420
420
|
end
|
|
421
421
|
|
|
422
422
|
it "should handled emulated function where only name is emulated" do
|
|
423
423
|
dsc = Class.new(Sequel::Dataset)
|
|
424
|
+
efm = dsc::EMULATED_FUNCTION_MAP.dup
|
|
424
425
|
dsc::EMULATED_FUNCTION_MAP[:trim] = :foo
|
|
425
|
-
dsc.new(@d.db).literal(Sequel.trim(:a)).
|
|
426
|
+
dsc.new(@d.db).literal(Sequel.trim(:a)).must_equal 'foo(a)'
|
|
427
|
+
dsc::EMULATED_FUNCTION_MAP.replace(efm)
|
|
426
428
|
end
|
|
427
429
|
|
|
428
430
|
it "should handled emulated function needing full emulation" do
|
|
@@ -432,7 +434,7 @@ describe "Blockless Ruby Filters" do
|
|
|
432
434
|
sql << "#{f.name}FOO(lower(#{f.args.first}))"
|
|
433
435
|
end
|
|
434
436
|
end
|
|
435
|
-
dsc.new(@d.db).literal(Sequel.trim(:a)).
|
|
437
|
+
dsc.new(@d.db).literal(Sequel.trim(:a)).must_equal 'trimFOO(lower(a))'
|
|
436
438
|
end
|
|
437
439
|
end
|
|
438
440
|
|
|
@@ -448,174 +450,174 @@ describe Sequel::SQL::VirtualRow do
|
|
|
448
450
|
end
|
|
449
451
|
|
|
450
452
|
it "should treat methods without arguments as identifiers" do
|
|
451
|
-
@d.l{column}.
|
|
453
|
+
@d.l{column}.must_equal '"column"'
|
|
452
454
|
end
|
|
453
455
|
|
|
454
456
|
it "should treat methods without arguments that have embedded double underscores as qualified identifiers" do
|
|
455
|
-
@d.l{table__column}.
|
|
457
|
+
@d.l{table__column}.must_equal '"table"."column"'
|
|
456
458
|
end
|
|
457
459
|
|
|
458
460
|
it "should treat methods with arguments as functions with the arguments" do
|
|
459
|
-
@d.l{function(arg1, 10, 'arg3')}.
|
|
461
|
+
@d.l{function(arg1, 10, 'arg3')}.must_equal 'function("arg1", 10, \'arg3\')'
|
|
460
462
|
end
|
|
461
463
|
|
|
462
464
|
it "should treat methods with a block and no arguments as a function call with no arguments" do
|
|
463
|
-
@d.l{version{}}.
|
|
465
|
+
@d.l{version{}}.must_equal 'version()'
|
|
464
466
|
end
|
|
465
467
|
|
|
466
468
|
it "should treat methods with a block and a leading argument :* as a function call with the SQL wildcard" do
|
|
467
|
-
@d.l{count(:*){}}.
|
|
469
|
+
@d.l{count(:*){}}.must_equal 'count(*)'
|
|
468
470
|
end
|
|
469
471
|
|
|
470
472
|
it "should support * method on functions to raise error if function already has an argument" do
|
|
471
|
-
proc{@d.l{count(1).*}}.
|
|
473
|
+
proc{@d.l{count(1).*}}.must_raise(Sequel::Error)
|
|
472
474
|
end
|
|
473
475
|
|
|
474
476
|
it "should support * method on functions to use * as the argument" do
|
|
475
|
-
@d.l{count{}.*}.
|
|
476
|
-
@d.literal(Sequel.expr{sum(1) * 2}).
|
|
477
|
+
@d.l{count{}.*}.must_equal 'count(*)'
|
|
478
|
+
@d.literal(Sequel.expr{sum(1) * 2}).must_equal '(sum(1) * 2)'
|
|
477
479
|
end
|
|
478
480
|
|
|
479
481
|
it "should treat methods with a block and a leading argument :distinct as a function call with DISTINCT and the additional method arguments" do
|
|
480
|
-
@d.l{count(:distinct, column1){}}.
|
|
481
|
-
@d.l{count(:distinct, column1, column2){}}.
|
|
482
|
+
@d.l{count(:distinct, column1){}}.must_equal 'count(DISTINCT "column1")'
|
|
483
|
+
@d.l{count(:distinct, column1, column2){}}.must_equal 'count(DISTINCT "column1", "column2")'
|
|
482
484
|
end
|
|
483
485
|
|
|
484
486
|
it "should support distinct methods on functions to use DISTINCT before the arguments" do
|
|
485
|
-
@d.l{count(column1).distinct}.
|
|
486
|
-
@d.l{count(column1, column2).distinct}.
|
|
487
|
+
@d.l{count(column1).distinct}.must_equal 'count(DISTINCT "column1")'
|
|
488
|
+
@d.l{count(column1, column2).distinct}.must_equal 'count(DISTINCT "column1", "column2")'
|
|
487
489
|
end
|
|
488
490
|
|
|
489
491
|
it "should raise an error if an unsupported argument is used with a block" do
|
|
490
|
-
proc{@d.where{count(:blah){}}}.
|
|
492
|
+
proc{@d.where{count(:blah){}}}.must_raise(Sequel::Error)
|
|
491
493
|
end
|
|
492
494
|
|
|
493
495
|
it "should treat methods with a block and a leading argument :over as a window function call" do
|
|
494
|
-
@d.l{rank(:over){}}.
|
|
496
|
+
@d.l{rank(:over){}}.must_equal 'rank() OVER ()'
|
|
495
497
|
end
|
|
496
498
|
|
|
497
499
|
it "should support :partition options for window function calls" do
|
|
498
|
-
@d.l{rank(:over, :partition=>column1){}}.
|
|
499
|
-
@d.l{rank(:over, :partition=>[column1, column2]){}}.
|
|
500
|
+
@d.l{rank(:over, :partition=>column1){}}.must_equal 'rank() OVER (PARTITION BY "column1")'
|
|
501
|
+
@d.l{rank(:over, :partition=>[column1, column2]){}}.must_equal 'rank() OVER (PARTITION BY "column1", "column2")'
|
|
500
502
|
end
|
|
501
503
|
|
|
502
504
|
it "should support :args options for window function calls" do
|
|
503
|
-
@d.l{avg(:over, :args=>column1){}}.
|
|
504
|
-
@d.l{avg(:over, :args=>[column1, column2]){}}.
|
|
505
|
+
@d.l{avg(:over, :args=>column1){}}.must_equal 'avg("column1") OVER ()'
|
|
506
|
+
@d.l{avg(:over, :args=>[column1, column2]){}}.must_equal 'avg("column1", "column2") OVER ()'
|
|
505
507
|
end
|
|
506
508
|
|
|
507
509
|
it "should support :order option for window function calls" do
|
|
508
|
-
@d.l{rank(:over, :order=>column1){}}.
|
|
509
|
-
@d.l{rank(:over, :order=>[column1, column2]){}}.
|
|
510
|
+
@d.l{rank(:over, :order=>column1){}}.must_equal 'rank() OVER (ORDER BY "column1")'
|
|
511
|
+
@d.l{rank(:over, :order=>[column1, column2]){}}.must_equal 'rank() OVER (ORDER BY "column1", "column2")'
|
|
510
512
|
end
|
|
511
513
|
|
|
512
514
|
it "should support :window option for window function calls" do
|
|
513
|
-
@d.l{rank(:over, :window=>:win){}}.
|
|
515
|
+
@d.l{rank(:over, :window=>:win){}}.must_equal 'rank() OVER ("win")'
|
|
514
516
|
end
|
|
515
517
|
|
|
516
518
|
it "should support :*=>true option for window function calls" do
|
|
517
|
-
@d.l{count(:over, :* =>true){}}.
|
|
519
|
+
@d.l{count(:over, :* =>true){}}.must_equal 'count(*) OVER ()'
|
|
518
520
|
end
|
|
519
521
|
|
|
520
522
|
it "should support :frame=>:all option for window function calls" do
|
|
521
|
-
@d.l{rank(:over, :frame=>:all){}}.
|
|
523
|
+
@d.l{rank(:over, :frame=>:all){}}.must_equal 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)'
|
|
522
524
|
end
|
|
523
525
|
|
|
524
526
|
it "should support :frame=>:rows option for window function calls" do
|
|
525
|
-
@d.l{rank(:over, :frame=>:rows){}}.
|
|
527
|
+
@d.l{rank(:over, :frame=>:rows){}}.must_equal 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
526
528
|
end
|
|
527
529
|
|
|
528
530
|
it "should support :frame=>'some string' option for window function calls" do
|
|
529
|
-
@d.l{rank(:over, :frame=>'RANGE BETWEEN 3 PRECEDING AND CURRENT ROW'){}}.
|
|
531
|
+
@d.l{rank(:over, :frame=>'RANGE BETWEEN 3 PRECEDING AND CURRENT ROW'){}}.must_equal 'rank() OVER (RANGE BETWEEN 3 PRECEDING AND CURRENT ROW)'
|
|
530
532
|
end
|
|
531
533
|
|
|
532
534
|
it "should raise an error if an invalid :frame option is used" do
|
|
533
|
-
proc{@d.l{rank(:over, :frame=>:blah){}}}.
|
|
535
|
+
proc{@d.l{rank(:over, :frame=>:blah){}}}.must_raise(Sequel::Error)
|
|
534
536
|
end
|
|
535
537
|
|
|
536
538
|
it "should support all these options together" do
|
|
537
|
-
@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.
|
|
539
|
+
@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.must_equal 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
538
540
|
end
|
|
539
541
|
|
|
540
542
|
it "should support over method on functions to create window functions" do
|
|
541
|
-
@d.l{rank{}.over}.
|
|
542
|
-
@d.l{sum(c).over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}.
|
|
543
|
+
@d.l{rank{}.over}.must_equal 'rank() OVER ()'
|
|
544
|
+
@d.l{sum(c).over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}.must_equal 'sum("c") OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
543
545
|
end
|
|
544
546
|
|
|
545
547
|
it "should support over method with a Window argument" do
|
|
546
|
-
@d.l{sum(c).over(Sequel::SQL::Window.new(:partition=>a, :order=>b, :window=>:win, :frame=>:rows))}.
|
|
548
|
+
@d.l{sum(c).over(Sequel::SQL::Window.new(:partition=>a, :order=>b, :window=>:win, :frame=>:rows))}.must_equal 'sum("c") OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
547
549
|
end
|
|
548
550
|
|
|
549
551
|
it "should raise error if over is called on a function that already has a window " do
|
|
550
|
-
proc{@d.l{rank{}.over.over}}.
|
|
552
|
+
proc{@d.l{rank{}.over.over}}.must_raise(Sequel::Error)
|
|
551
553
|
end
|
|
552
554
|
|
|
553
555
|
it "should raise an error if window functions are not supported" do
|
|
554
556
|
class << @d; remove_method :supports_window_functions? end
|
|
555
557
|
meta_def(@d, :supports_window_functions?){false}
|
|
556
|
-
proc{@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}}.
|
|
557
|
-
proc{Sequel.mock.dataset.filter{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.sql}.
|
|
558
|
+
proc{@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}}.must_raise(Sequel::Error)
|
|
559
|
+
proc{Sequel.mock.dataset.filter{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.sql}.must_raise(Sequel::Error)
|
|
558
560
|
end
|
|
559
561
|
|
|
560
562
|
it "should handle lateral function calls" do
|
|
561
|
-
@d.l{rank{}.lateral}.
|
|
563
|
+
@d.l{rank{}.lateral}.must_equal 'LATERAL rank()'
|
|
562
564
|
end
|
|
563
565
|
|
|
564
566
|
it "should handle ordered-set and hypothetical-set function calls" do
|
|
565
|
-
@d.l{mode{}.within_group(:a)}.
|
|
566
|
-
@d.l{mode{}.within_group(:a, :b)}.
|
|
567
|
+
@d.l{mode{}.within_group(:a)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a")'
|
|
568
|
+
@d.l{mode{}.within_group(:a, :b)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a", "b")'
|
|
567
569
|
end
|
|
568
570
|
|
|
569
571
|
it "should handle filtered aggregate function calls" do
|
|
570
|
-
@d.l{count{}.*.filter(:a, :b)}.
|
|
571
|
-
@d.l{count{}.*.filter(:a=>1)}.
|
|
572
|
-
@d.l{count{}.*.filter{b > 1}}.
|
|
573
|
-
@d.l{count{}.*.filter(:a=>1){b > 1}}.
|
|
572
|
+
@d.l{count{}.*.filter(:a, :b)}.must_equal 'count(*) FILTER (WHERE ("a" AND "b"))'
|
|
573
|
+
@d.l{count{}.*.filter(:a=>1)}.must_equal 'count(*) FILTER (WHERE ("a" = 1))'
|
|
574
|
+
@d.l{count{}.*.filter{b > 1}}.must_equal 'count(*) FILTER (WHERE ("b" > 1))'
|
|
575
|
+
@d.l{count{}.*.filter(:a=>1){b > 1}}.must_equal 'count(*) FILTER (WHERE (("a" = 1) AND ("b" > 1)))'
|
|
574
576
|
end
|
|
575
577
|
|
|
576
578
|
it "should handle fitlered ordered-set and hypothetical-set function calls" do
|
|
577
|
-
@d.l{mode{}.within_group(:a).filter(:a=>1)}.
|
|
579
|
+
@d.l{mode{}.within_group(:a).filter(:a=>1)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a") FILTER (WHERE ("a" = 1))'
|
|
578
580
|
end
|
|
579
581
|
|
|
580
582
|
it "should handle function calls with ordinality" do
|
|
581
|
-
@d.l{foo{}.with_ordinality}.
|
|
583
|
+
@d.l{foo{}.with_ordinality}.must_equal 'foo() WITH ORDINALITY'
|
|
582
584
|
end
|
|
583
585
|
|
|
584
586
|
it "should support function method on identifiers to create functions" do
|
|
585
|
-
@d.l{rank.function}.
|
|
586
|
-
@d.l{sum.function(c)}.
|
|
587
|
-
@d.l{sum.function(c, 1)}.
|
|
587
|
+
@d.l{rank.function}.must_equal 'rank()'
|
|
588
|
+
@d.l{sum.function(c)}.must_equal 'sum("c")'
|
|
589
|
+
@d.l{sum.function(c, 1)}.must_equal 'sum("c", 1)'
|
|
588
590
|
end
|
|
589
591
|
|
|
590
592
|
it "should support function method on qualified identifiers to create functions" do
|
|
591
|
-
@d.l{sch__rank.function}.
|
|
592
|
-
@d.l{sch__sum.function(c)}.
|
|
593
|
-
@d.l{sch__sum.function(c, 1)}.
|
|
594
|
-
@d.l{Sequel.qualify(sch__sum, :x__y).function(c, 1)}.
|
|
593
|
+
@d.l{sch__rank.function}.must_equal 'sch.rank()'
|
|
594
|
+
@d.l{sch__sum.function(c)}.must_equal 'sch.sum("c")'
|
|
595
|
+
@d.l{sch__sum.function(c, 1)}.must_equal 'sch.sum("c", 1)'
|
|
596
|
+
@d.l{Sequel.qualify(sch__sum, :x__y).function(c, 1)}.must_equal 'sch.sum.x.y("c", 1)'
|
|
595
597
|
end
|
|
596
598
|
|
|
597
599
|
it "should handle quoted function names" do
|
|
598
600
|
def @d.supports_quoted_function_names?; true; end
|
|
599
|
-
@d.l{rank.function}.
|
|
600
|
-
@d.l{sch__rank.function}.
|
|
601
|
+
@d.l{rank.function}.must_equal '"rank"()'
|
|
602
|
+
@d.l{sch__rank.function}.must_equal '"sch"."rank"()'
|
|
601
603
|
end
|
|
602
604
|
|
|
603
605
|
it "should quote function names if a quoted function is used and database supports quoted function names" do
|
|
604
606
|
def @d.supports_quoted_function_names?; true; end
|
|
605
|
-
@d.l{rank{}.quoted}.
|
|
606
|
-
@d.l{sch__rank{}.quoted}.
|
|
607
|
+
@d.l{rank{}.quoted}.must_equal '"rank"()'
|
|
608
|
+
@d.l{sch__rank{}.quoted}.must_equal '"sch__rank"()'
|
|
607
609
|
end
|
|
608
610
|
|
|
609
611
|
it "should not quote function names if an unquoted function is used" do
|
|
610
612
|
def @d.supports_quoted_function_names?; true; end
|
|
611
|
-
@d.l{rank.function.unquoted}.
|
|
612
|
-
@d.l{sch__rank.function.unquoted}.
|
|
613
|
+
@d.l{rank.function.unquoted}.must_equal 'rank()'
|
|
614
|
+
@d.l{sch__rank.function.unquoted}.must_equal 'sch.rank()'
|
|
613
615
|
end
|
|
614
616
|
|
|
615
617
|
it "should deal with classes without requiring :: prefix" do
|
|
616
|
-
@d.l{date < Date.today}.
|
|
617
|
-
@d.l{date < Sequel::CURRENT_DATE}.
|
|
618
|
-
@d.l{num < Math::PI.to_i}.
|
|
618
|
+
@d.l{date < Date.today}.must_equal "(\"date\" < '#{Date.today}')"
|
|
619
|
+
@d.l{date < Sequel::CURRENT_DATE}.must_equal "(\"date\" < CURRENT_DATE)"
|
|
620
|
+
@d.l{num < Math::PI.to_i}.must_equal "(\"num\" < 3)"
|
|
619
621
|
end
|
|
620
622
|
|
|
621
623
|
it "should deal with methods added to Object after requiring Sequel" do
|
|
@@ -623,7 +625,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
623
625
|
def adsoiwemlsdaf; 42; end
|
|
624
626
|
end
|
|
625
627
|
Sequel::BasicObject.remove_methods!
|
|
626
|
-
@d.l{a > adsoiwemlsdaf}.
|
|
628
|
+
@d.l{a > adsoiwemlsdaf}.must_equal '("a" > "adsoiwemlsdaf")'
|
|
627
629
|
end
|
|
628
630
|
|
|
629
631
|
it "should deal with private methods added to Kernel after requiring Sequel" do
|
|
@@ -632,27 +634,27 @@ describe Sequel::SQL::VirtualRow do
|
|
|
632
634
|
def adsoiwemlsdaf2; 42; end
|
|
633
635
|
end
|
|
634
636
|
Sequel::BasicObject.remove_methods!
|
|
635
|
-
@d.l{a > adsoiwemlsdaf2}.
|
|
637
|
+
@d.l{a > adsoiwemlsdaf2}.must_equal '("a" > "adsoiwemlsdaf2")'
|
|
636
638
|
end
|
|
637
639
|
|
|
638
640
|
it "should have operator methods defined that produce Sequel expression objects" do
|
|
639
|
-
@d.l{|o| o.&({:a=>1}, :b)}.
|
|
640
|
-
@d.l{|o| o.|({:a=>1}, :b)}.
|
|
641
|
-
@d.l{|o| o.+(1, :b) > 2}.
|
|
642
|
-
@d.l{|o| o.-(1, :b) < 2}.
|
|
643
|
-
@d.l{|o| o.*(1, :b) >= 2}.
|
|
644
|
-
@d.l{|o| o./(1, :b) <= 2}.
|
|
645
|
-
@d.l{|o| o.~(:a=>1)}.
|
|
646
|
-
@d.l{|o| o.~([[:a, 1], [:b, 2]])}.
|
|
647
|
-
@d.l{|o| o.<(1, :b)}.
|
|
648
|
-
@d.l{|o| o.>(1, :b)}.
|
|
649
|
-
@d.l{|o| o.<=(1, :b)}.
|
|
650
|
-
@d.l{|o| o.>=(1, :b)}.
|
|
641
|
+
@d.l{|o| o.&({:a=>1}, :b)}.must_equal '(("a" = 1) AND "b")'
|
|
642
|
+
@d.l{|o| o.|({:a=>1}, :b)}.must_equal '(("a" = 1) OR "b")'
|
|
643
|
+
@d.l{|o| o.+(1, :b) > 2}.must_equal '((1 + "b") > 2)'
|
|
644
|
+
@d.l{|o| o.-(1, :b) < 2}.must_equal '((1 - "b") < 2)'
|
|
645
|
+
@d.l{|o| o.*(1, :b) >= 2}.must_equal '((1 * "b") >= 2)'
|
|
646
|
+
@d.l{|o| o./(1, :b) <= 2}.must_equal '((1 / "b") <= 2)'
|
|
647
|
+
@d.l{|o| o.~(:a=>1)}.must_equal '("a" != 1)'
|
|
648
|
+
@d.l{|o| o.~([[:a, 1], [:b, 2]])}.must_equal '(("a" != 1) OR ("b" != 2))'
|
|
649
|
+
@d.l{|o| o.<(1, :b)}.must_equal '(1 < "b")'
|
|
650
|
+
@d.l{|o| o.>(1, :b)}.must_equal '(1 > "b")'
|
|
651
|
+
@d.l{|o| o.<=(1, :b)}.must_equal '(1 <= "b")'
|
|
652
|
+
@d.l{|o| o.>=(1, :b)}.must_equal '(1 >= "b")'
|
|
651
653
|
end
|
|
652
654
|
|
|
653
655
|
it "should have have ` produce literal strings" do
|
|
654
|
-
@d.l{a > `some SQL`}.
|
|
655
|
-
@d.l{|o| o.a > o.`('some SQL')}.
|
|
656
|
+
@d.l{a > `some SQL`}.must_equal '("a" > some SQL)'
|
|
657
|
+
@d.l{|o| o.a > o.`('some SQL')}.must_equal '("a" > some SQL)' #`
|
|
656
658
|
end
|
|
657
659
|
end
|
|
658
660
|
|
|
@@ -666,25 +668,25 @@ describe "Sequel core extension replacements" do
|
|
|
666
668
|
end
|
|
667
669
|
|
|
668
670
|
def l(arg, should)
|
|
669
|
-
@ds.literal(arg).
|
|
671
|
+
@ds.literal(arg).must_equal should
|
|
670
672
|
end
|
|
671
673
|
|
|
672
674
|
it "Sequel.expr should return items wrapped in Sequel objects" do
|
|
673
|
-
Sequel.expr(1).
|
|
674
|
-
Sequel.expr('a').
|
|
675
|
-
Sequel.expr(true).
|
|
676
|
-
Sequel.expr(nil).
|
|
677
|
-
Sequel.expr({1=>2}).
|
|
678
|
-
Sequel.expr([[1, 2]]).
|
|
679
|
-
Sequel.expr([1]).
|
|
680
|
-
Sequel.expr{|o| o.a}.
|
|
681
|
-
Sequel.expr{a}.
|
|
682
|
-
Sequel.expr(:a).
|
|
683
|
-
Sequel.expr(:a__b).
|
|
684
|
-
Sequel.expr(:a___c).
|
|
685
|
-
Sequel.expr(:a___c).expression.
|
|
686
|
-
Sequel.expr(:a__b___c).
|
|
687
|
-
Sequel.expr(:a__b___c).expression.
|
|
675
|
+
Sequel.expr(1).must_be_kind_of(Sequel::SQL::NumericExpression)
|
|
676
|
+
Sequel.expr('a').must_be_kind_of(Sequel::SQL::StringExpression)
|
|
677
|
+
Sequel.expr(true).must_be_kind_of(Sequel::SQL::BooleanExpression)
|
|
678
|
+
Sequel.expr(nil).must_be_kind_of(Sequel::SQL::Wrapper)
|
|
679
|
+
Sequel.expr({1=>2}).must_be_kind_of(Sequel::SQL::BooleanExpression)
|
|
680
|
+
Sequel.expr([[1, 2]]).must_be_kind_of(Sequel::SQL::BooleanExpression)
|
|
681
|
+
Sequel.expr([1]).must_be_kind_of(Sequel::SQL::Wrapper)
|
|
682
|
+
Sequel.expr{|o| o.a}.must_be_kind_of(Sequel::SQL::Identifier)
|
|
683
|
+
Sequel.expr{a}.must_be_kind_of(Sequel::SQL::Identifier)
|
|
684
|
+
Sequel.expr(:a).must_be_kind_of(Sequel::SQL::Identifier)
|
|
685
|
+
Sequel.expr(:a__b).must_be_kind_of(Sequel::SQL::QualifiedIdentifier)
|
|
686
|
+
Sequel.expr(:a___c).must_be_kind_of(Sequel::SQL::AliasedExpression)
|
|
687
|
+
Sequel.expr(:a___c).expression.must_be_kind_of(Sequel::SQL::Identifier)
|
|
688
|
+
Sequel.expr(:a__b___c).must_be_kind_of(Sequel::SQL::AliasedExpression)
|
|
689
|
+
Sequel.expr(:a__b___c).expression.must_be_kind_of(Sequel::SQL::QualifiedIdentifier)
|
|
688
690
|
end
|
|
689
691
|
|
|
690
692
|
it "Sequel.expr should return an appropriate wrapped object" do
|
|
@@ -726,18 +728,18 @@ describe "Sequel core extension replacements" do
|
|
|
726
728
|
end
|
|
727
729
|
|
|
728
730
|
it "Sequel.expr should raise an error if given an argument and a block" do
|
|
729
|
-
proc{Sequel.expr(nil){}}.
|
|
731
|
+
proc{Sequel.expr(nil){}}.must_raise(Sequel::Error)
|
|
730
732
|
end
|
|
731
733
|
|
|
732
734
|
it "Sequel.expr should raise an error if given neither an argument nor a block" do
|
|
733
|
-
proc{Sequel.expr}.
|
|
735
|
+
proc{Sequel.expr}.must_raise(Sequel::Error)
|
|
734
736
|
end
|
|
735
737
|
|
|
736
738
|
it "Sequel.expr should return existing Sequel expressions directly" do
|
|
737
739
|
o = Sequel.expr(1)
|
|
738
|
-
Sequel.expr(o).
|
|
740
|
+
Sequel.expr(o).must_be_same_as(o)
|
|
739
741
|
o = Sequel.lit('1')
|
|
740
|
-
Sequel.expr(o).
|
|
742
|
+
Sequel.expr(o).must_be_same_as(o)
|
|
741
743
|
end
|
|
742
744
|
|
|
743
745
|
it "Sequel.~ should invert the given object" do
|
|
@@ -758,7 +760,7 @@ describe "Sequel core extension replacements" do
|
|
|
758
760
|
end
|
|
759
761
|
|
|
760
762
|
it "Sequel.case should raise an error if not given a condition specifier" do
|
|
761
|
-
proc{Sequel.case(1, 2)}.
|
|
763
|
+
proc{Sequel.case(1, 2)}.must_raise(Sequel::Error)
|
|
762
764
|
end
|
|
763
765
|
|
|
764
766
|
it "Sequel.value_list should use an SQL value list" do
|
|
@@ -766,7 +768,7 @@ describe "Sequel core extension replacements" do
|
|
|
766
768
|
end
|
|
767
769
|
|
|
768
770
|
it "Sequel.value_list raise an error if not given an array" do
|
|
769
|
-
proc{Sequel.value_list(1)}.
|
|
771
|
+
proc{Sequel.value_list(1)}.must_raise(Sequel::Error)
|
|
770
772
|
end
|
|
771
773
|
|
|
772
774
|
it "Sequel.negate should negate all entries in conditions specifier and join with AND" do
|
|
@@ -776,7 +778,7 @@ describe "Sequel core extension replacements" do
|
|
|
776
778
|
end
|
|
777
779
|
|
|
778
780
|
it "Sequel.negate should raise an error if not given a conditions specifier" do
|
|
779
|
-
proc{Sequel.negate(1)}.
|
|
781
|
+
proc{Sequel.negate(1)}.must_raise(Sequel::Error)
|
|
780
782
|
end
|
|
781
783
|
|
|
782
784
|
it "Sequel.or should join all entries in conditions specifier with OR" do
|
|
@@ -786,7 +788,7 @@ describe "Sequel core extension replacements" do
|
|
|
786
788
|
end
|
|
787
789
|
|
|
788
790
|
it "Sequel.or should raise an error if not given a conditions specifier" do
|
|
789
|
-
proc{Sequel.or(1)}.
|
|
791
|
+
proc{Sequel.or(1)}.must_raise(Sequel::Error)
|
|
790
792
|
end
|
|
791
793
|
|
|
792
794
|
it "Sequel.join should should use SQL string concatenation to join array" do
|
|
@@ -800,7 +802,7 @@ describe "Sequel core extension replacements" do
|
|
|
800
802
|
end
|
|
801
803
|
|
|
802
804
|
it "Sequel.join should raise an error if not given an array" do
|
|
803
|
-
proc{Sequel.join(1)}.
|
|
805
|
+
proc{Sequel.join(1)}.must_raise(Sequel::Error)
|
|
804
806
|
end
|
|
805
807
|
|
|
806
808
|
it "Sequel.& should join all arguments given with AND" do
|
|
@@ -810,7 +812,7 @@ describe "Sequel core extension replacements" do
|
|
|
810
812
|
end
|
|
811
813
|
|
|
812
814
|
it "Sequel.& should raise an error if given no arguments" do
|
|
813
|
-
proc{Sequel.&}.
|
|
815
|
+
proc{Sequel.&}.must_raise(Sequel::Error)
|
|
814
816
|
end
|
|
815
817
|
|
|
816
818
|
it "Sequel.| should join all arguments given with OR" do
|
|
@@ -820,7 +822,7 @@ describe "Sequel core extension replacements" do
|
|
|
820
822
|
end
|
|
821
823
|
|
|
822
824
|
it "Sequel.| should raise an error if given no arguments" do
|
|
823
|
-
proc{Sequel.|}.
|
|
825
|
+
proc{Sequel.|}.must_raise(Sequel::Error)
|
|
824
826
|
end
|
|
825
827
|
|
|
826
828
|
it "Sequel.as should return an aliased expression" do
|
|
@@ -850,7 +852,7 @@ describe "Sequel core extension replacements" do
|
|
|
850
852
|
|
|
851
853
|
it "Sequel.lit should return the argument if given a single literal string" do
|
|
852
854
|
o = Sequel.lit('a')
|
|
853
|
-
Sequel.lit(o).
|
|
855
|
+
Sequel.lit(o).must_be_same_as(o)
|
|
854
856
|
end
|
|
855
857
|
|
|
856
858
|
it "Sequel.lit should accept multiple arguments for a placeholder literal string" do
|
|
@@ -866,12 +868,12 @@ describe "Sequel core extension replacements" do
|
|
|
866
868
|
|
|
867
869
|
it "Sequel.blob should return an SQL::Blob" do
|
|
868
870
|
l(Sequel.blob('a'), "'a'")
|
|
869
|
-
Sequel.blob('a').
|
|
871
|
+
Sequel.blob('a').must_be_kind_of(Sequel::SQL::Blob)
|
|
870
872
|
end
|
|
871
873
|
|
|
872
874
|
it "Sequel.blob should return the given argument if given a blob" do
|
|
873
875
|
o = Sequel.blob('a')
|
|
874
|
-
Sequel.blob(o).
|
|
876
|
+
Sequel.blob(o).must_be_same_as(o)
|
|
875
877
|
end
|
|
876
878
|
|
|
877
879
|
it "Sequel.deep_qualify should do a deep qualification into nested structors" do
|
|
@@ -906,7 +908,7 @@ describe "Sequel core extension replacements" do
|
|
|
906
908
|
|
|
907
909
|
it "Sequel.{+,-,*,/} should raise if given no arguments" do
|
|
908
910
|
%w'+ - * /'.each do |op|
|
|
909
|
-
proc{Sequel.send(op)}.
|
|
911
|
+
proc{Sequel.send(op)}.must_raise(Sequel::Error)
|
|
910
912
|
end
|
|
911
913
|
end
|
|
912
914
|
|
|
@@ -961,62 +963,62 @@ describe "Sequel core extension replacements" do
|
|
|
961
963
|
end
|
|
962
964
|
|
|
963
965
|
describe "Sequel::SQL::Function#==" do
|
|
964
|
-
|
|
966
|
+
it "should be true for functions with the same name and arguments, false otherwise" do
|
|
965
967
|
a = Sequel.function(:date, :t)
|
|
966
968
|
b = Sequel.function(:date, :t)
|
|
967
|
-
a.
|
|
968
|
-
(a == b).
|
|
969
|
+
a.must_equal b
|
|
970
|
+
(a == b).must_equal true
|
|
969
971
|
c = Sequel.function(:date, :c)
|
|
970
|
-
a.
|
|
971
|
-
(a == c).
|
|
972
|
+
a.wont_equal c
|
|
973
|
+
(a == c).must_equal false
|
|
972
974
|
d = Sequel.function(:time, :c)
|
|
973
|
-
a.
|
|
974
|
-
c.
|
|
975
|
-
(a == d).
|
|
976
|
-
(c == d).
|
|
975
|
+
a.wont_equal d
|
|
976
|
+
c.wont_equal d
|
|
977
|
+
(a == d).must_equal false
|
|
978
|
+
(c == d).must_equal false
|
|
977
979
|
end
|
|
978
980
|
end
|
|
979
981
|
|
|
980
982
|
describe "Sequel::SQL::OrderedExpression" do
|
|
981
|
-
|
|
983
|
+
it "should #desc" do
|
|
982
984
|
@oe = Sequel.asc(:column)
|
|
983
|
-
@oe.descending.
|
|
984
|
-
@oe.desc.descending.
|
|
985
|
+
@oe.descending.must_equal false
|
|
986
|
+
@oe.desc.descending.must_equal true
|
|
985
987
|
end
|
|
986
988
|
|
|
987
|
-
|
|
989
|
+
it "should #asc" do
|
|
988
990
|
@oe = Sequel.desc(:column)
|
|
989
|
-
@oe.descending.
|
|
990
|
-
@oe.asc.descending.
|
|
991
|
+
@oe.descending.must_equal true
|
|
992
|
+
@oe.asc.descending.must_equal false
|
|
991
993
|
end
|
|
992
994
|
|
|
993
|
-
|
|
995
|
+
it "should #invert" do
|
|
994
996
|
@oe = Sequel.desc(:column)
|
|
995
|
-
@oe.invert.descending.
|
|
996
|
-
@oe.invert.invert.descending.
|
|
997
|
+
@oe.invert.descending.must_equal false
|
|
998
|
+
@oe.invert.invert.descending.must_equal true
|
|
997
999
|
end
|
|
998
1000
|
end
|
|
999
1001
|
|
|
1000
1002
|
describe "Expression" do
|
|
1001
|
-
|
|
1002
|
-
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.
|
|
1003
|
-
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.
|
|
1003
|
+
it "should consider objects == only if they have the same attributes" do
|
|
1004
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.must_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
1005
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.wont_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
1004
1006
|
|
|
1005
|
-
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.
|
|
1006
|
-
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.
|
|
1007
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.must_equal(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
|
|
1008
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.wont_equal(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
|
|
1007
1009
|
end
|
|
1008
1010
|
|
|
1009
|
-
|
|
1010
|
-
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash.
|
|
1011
|
-
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.hash.
|
|
1011
|
+
it "should use the same hash value for objects that have the same attributes" do
|
|
1012
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash.must_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
|
|
1013
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.hash.wont_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
|
|
1012
1014
|
|
|
1013
1015
|
h = {}
|
|
1014
1016
|
a = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
1015
1017
|
b = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
1016
1018
|
h[a] = 1
|
|
1017
1019
|
h[b] = 2
|
|
1018
|
-
h[a].
|
|
1019
|
-
h[b].
|
|
1020
|
+
h[a].must_equal 2
|
|
1021
|
+
h[b].must_equal 2
|
|
1020
1022
|
end
|
|
1021
1023
|
end
|
|
1022
1024
|
|
|
@@ -1025,24 +1027,24 @@ describe "Sequel::SQLTime" do
|
|
|
1025
1027
|
@db = Sequel.mock
|
|
1026
1028
|
end
|
|
1027
1029
|
|
|
1028
|
-
|
|
1029
|
-
@db.literal(Sequel::SQLTime.create(1, 2, 3)).
|
|
1030
|
-
@db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).
|
|
1030
|
+
it ".create should create from hour, minutes, seconds and optional microseconds" do
|
|
1031
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3)).must_equal "'01:02:03.000000'"
|
|
1032
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).must_equal "'01:02:03.500000'"
|
|
1031
1033
|
end
|
|
1032
1034
|
|
|
1033
|
-
|
|
1034
|
-
Sequel::SQLTime.create(1, 2, 3).to_s.
|
|
1035
|
-
Sequel::SQLTime.create(1, 2, 3, 500000).to_s.
|
|
1035
|
+
it "#to_s should include hour, minute, and second by default" do
|
|
1036
|
+
Sequel::SQLTime.create(1, 2, 3).to_s.must_equal "01:02:03"
|
|
1037
|
+
Sequel::SQLTime.create(1, 2, 3, 500000).to_s.must_equal "01:02:03"
|
|
1036
1038
|
end
|
|
1037
1039
|
|
|
1038
|
-
|
|
1040
|
+
it "#to_s should handle arguments with super" do
|
|
1039
1041
|
t = Sequel::SQLTime.create(1, 2, 3)
|
|
1040
1042
|
begin
|
|
1041
1043
|
Time.now.to_s('%F')
|
|
1042
1044
|
rescue
|
|
1043
|
-
proc{t.to_s('%F')}.
|
|
1045
|
+
proc{t.to_s('%F')}.must_raise ArgumentError
|
|
1044
1046
|
else
|
|
1045
|
-
|
|
1047
|
+
t.to_s('%F')
|
|
1046
1048
|
end
|
|
1047
1049
|
end
|
|
1048
1050
|
end
|
|
@@ -1052,27 +1054,27 @@ describe "Sequel::SQL::Wrapper" do
|
|
|
1052
1054
|
@ds = Sequel.mock.dataset
|
|
1053
1055
|
end
|
|
1054
1056
|
|
|
1055
|
-
|
|
1057
|
+
it "should wrap objects so they can be used by the Sequel DSL" do
|
|
1056
1058
|
o = Object.new
|
|
1057
1059
|
def o.sql_literal(ds) 'foo' end
|
|
1058
1060
|
s = Sequel::SQL::Wrapper.new(o)
|
|
1059
|
-
@ds.literal(s).
|
|
1060
|
-
@ds.literal(s+1).
|
|
1061
|
-
@ds.literal(s & true).
|
|
1062
|
-
@ds.literal(s < 1).
|
|
1063
|
-
@ds.literal(s.sql_subscript(1)).
|
|
1064
|
-
@ds.literal(s.like('a')).
|
|
1065
|
-
@ds.literal(s.as(:a)).
|
|
1066
|
-
@ds.literal(s.cast(Integer)).
|
|
1067
|
-
@ds.literal(s.desc).
|
|
1068
|
-
@ds.literal(s.sql_string + '1').
|
|
1061
|
+
@ds.literal(s).must_equal "foo"
|
|
1062
|
+
@ds.literal(s+1).must_equal "(foo + 1)"
|
|
1063
|
+
@ds.literal(s & true).must_equal "(foo AND 't')"
|
|
1064
|
+
@ds.literal(s < 1).must_equal "(foo < 1)"
|
|
1065
|
+
@ds.literal(s.sql_subscript(1)).must_equal "foo[1]"
|
|
1066
|
+
@ds.literal(s.like('a')).must_equal "(foo LIKE 'a' ESCAPE '\\')"
|
|
1067
|
+
@ds.literal(s.as(:a)).must_equal "foo AS a"
|
|
1068
|
+
@ds.literal(s.cast(Integer)).must_equal "CAST(foo AS integer)"
|
|
1069
|
+
@ds.literal(s.desc).must_equal "foo DESC"
|
|
1070
|
+
@ds.literal(s.sql_string + '1').must_equal "(foo || '1')"
|
|
1069
1071
|
end
|
|
1070
1072
|
end
|
|
1071
1073
|
|
|
1072
1074
|
describe "Sequel::SQL::Blob#to_sequel_blob" do
|
|
1073
|
-
|
|
1075
|
+
it "should return self" do
|
|
1074
1076
|
c = Sequel::SQL::Blob.new('a')
|
|
1075
|
-
c.to_sequel_blob.
|
|
1077
|
+
c.to_sequel_blob.must_be_same_as(c)
|
|
1076
1078
|
end
|
|
1077
1079
|
end
|
|
1078
1080
|
|
|
@@ -1082,41 +1084,39 @@ describe Sequel::SQL::Subscript do
|
|
|
1082
1084
|
@ds = Sequel.mock.dataset
|
|
1083
1085
|
end
|
|
1084
1086
|
|
|
1085
|
-
|
|
1087
|
+
it "should have | return a new non-nested subscript" do
|
|
1086
1088
|
s = (@s | 2)
|
|
1087
|
-
|
|
1088
|
-
@ds.literal(s).should == 'a[1, 2]'
|
|
1089
|
+
@ds.literal(s).must_equal 'a[1, 2]'
|
|
1089
1090
|
end
|
|
1090
1091
|
|
|
1091
|
-
|
|
1092
|
+
it "should have [] return a new nested subscript" do
|
|
1092
1093
|
s = @s[2]
|
|
1093
|
-
|
|
1094
|
-
@ds.literal(s).should == 'a[1][2]'
|
|
1094
|
+
@ds.literal(s).must_equal 'a[1][2]'
|
|
1095
1095
|
end
|
|
1096
1096
|
end
|
|
1097
1097
|
|
|
1098
1098
|
describe Sequel::SQL::CaseExpression, "#with_merged_expression" do
|
|
1099
|
-
|
|
1099
|
+
it "should return self if it has no expression" do
|
|
1100
1100
|
c = Sequel.case({1=>0}, 3)
|
|
1101
|
-
c.with_merged_expression.
|
|
1101
|
+
c.with_merged_expression.must_be_same_as(c)
|
|
1102
1102
|
end
|
|
1103
1103
|
|
|
1104
|
-
|
|
1104
|
+
it "should merge expression into conditions if it has an expression" do
|
|
1105
1105
|
db = Sequel::Database.new
|
|
1106
1106
|
c = Sequel.case({1=>0}, 3, 4)
|
|
1107
|
-
db.literal(c.with_merged_expression).
|
|
1107
|
+
db.literal(c.with_merged_expression).must_equal db.literal(Sequel.case({{4=>1}=>0}, 3))
|
|
1108
1108
|
end
|
|
1109
1109
|
end
|
|
1110
1110
|
|
|
1111
1111
|
describe "Sequel.recursive_map" do
|
|
1112
|
-
|
|
1113
|
-
Sequel.recursive_map(['1'], proc{|s| s.to_i}).
|
|
1114
|
-
Sequel.recursive_map([['1']], proc{|s| s.to_i}).
|
|
1112
|
+
it "should recursively convert an array using a callable" do
|
|
1113
|
+
Sequel.recursive_map(['1'], proc{|s| s.to_i}).must_equal [1]
|
|
1114
|
+
Sequel.recursive_map([['1']], proc{|s| s.to_i}).must_equal [[1]]
|
|
1115
1115
|
end
|
|
1116
1116
|
|
|
1117
|
-
|
|
1118
|
-
Sequel.recursive_map([nil], proc{|s| s.to_i}).
|
|
1119
|
-
Sequel.recursive_map([[nil]], proc{|s| s.to_i}).
|
|
1117
|
+
it "should not call callable if value is nil" do
|
|
1118
|
+
Sequel.recursive_map([nil], proc{|s| s.to_i}).must_equal [nil]
|
|
1119
|
+
Sequel.recursive_map([[nil]], proc{|s| s.to_i}).must_equal [[nil]]
|
|
1120
1120
|
end
|
|
1121
1121
|
end
|
|
1122
1122
|
|
|
@@ -1135,38 +1135,38 @@ describe "Sequel.delay" do
|
|
|
1135
1135
|
end.new
|
|
1136
1136
|
end
|
|
1137
1137
|
|
|
1138
|
-
|
|
1138
|
+
it "should delay calling the block until literalization" do
|
|
1139
1139
|
ds = Sequel.mock[:b].where(:a=>Sequel.delay{@o.a})
|
|
1140
|
-
@o._a.
|
|
1141
|
-
ds.sql.
|
|
1142
|
-
@o._a.
|
|
1143
|
-
ds.sql.
|
|
1144
|
-
@o._a.
|
|
1140
|
+
@o._a.must_equal nil
|
|
1141
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a = 1)"
|
|
1142
|
+
@o._a.must_equal 1
|
|
1143
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a = 2)"
|
|
1144
|
+
@o._a.must_equal 2
|
|
1145
1145
|
end
|
|
1146
1146
|
|
|
1147
|
-
|
|
1147
|
+
it "should call the block with the current dataset if it accepts one argument" do
|
|
1148
1148
|
ds = Sequel.mock[:b].where(Sequel.delay{|x| x.first_source})
|
|
1149
|
-
ds.sql.
|
|
1150
|
-
ds.from(:c).sql.
|
|
1149
|
+
ds.sql.must_equal "SELECT * FROM b WHERE b"
|
|
1150
|
+
ds.from(:c).sql.must_equal "SELECT * FROM c WHERE c"
|
|
1151
1151
|
end
|
|
1152
1152
|
|
|
1153
|
-
|
|
1153
|
+
it "should have the condition specifier handling respect delayed evaluations" do
|
|
1154
1154
|
ds = Sequel.mock[:b].where(:a=>Sequel.delay{@o.b})
|
|
1155
|
-
ds.sql.
|
|
1155
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a IS NULL)"
|
|
1156
1156
|
@o.b = 1
|
|
1157
|
-
ds.sql.
|
|
1157
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a = 1)"
|
|
1158
1158
|
@o.b = [1, 2]
|
|
1159
|
-
ds.sql.
|
|
1159
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a IN (1, 2))"
|
|
1160
1160
|
end
|
|
1161
1161
|
|
|
1162
|
-
|
|
1162
|
+
it "should have the condition specifier handling call block with the current dataset if it accepts one argument" do
|
|
1163
1163
|
ds = Sequel.mock[:b].where(:a=>Sequel.delay{|x| x.first_source})
|
|
1164
|
-
ds.sql.
|
|
1165
|
-
ds.from(:c).sql.
|
|
1164
|
+
ds.sql.must_equal "SELECT * FROM b WHERE (a = b)"
|
|
1165
|
+
ds.from(:c).sql.must_equal "SELECT * FROM c WHERE (a = c)"
|
|
1166
1166
|
end
|
|
1167
1167
|
|
|
1168
|
-
|
|
1169
|
-
proc{Sequel.delay}.
|
|
1168
|
+
it "should raise if called without a block" do
|
|
1169
|
+
proc{Sequel.delay}.must_raise(Sequel::Error)
|
|
1170
1170
|
end
|
|
1171
1171
|
end
|
|
1172
1172
|
|
|
@@ -1183,18 +1183,18 @@ describe Sequel do
|
|
|
1183
1183
|
Sequel.send(:remove_const, :JSON)
|
|
1184
1184
|
end
|
|
1185
1185
|
|
|
1186
|
-
|
|
1187
|
-
Sequel.parse_json('[]').
|
|
1186
|
+
it ".parse_json should parse json correctly" do
|
|
1187
|
+
Sequel.parse_json('[]').must_equal ['[]', {:create_additions=>false}]
|
|
1188
1188
|
end
|
|
1189
1189
|
|
|
1190
|
-
|
|
1191
|
-
Sequel.json_parser_error_class.
|
|
1190
|
+
it ".json_parser_error_class should return the related parser error class" do
|
|
1191
|
+
Sequel.json_parser_error_class.must_equal Sequel
|
|
1192
1192
|
end
|
|
1193
1193
|
|
|
1194
|
-
|
|
1194
|
+
it ".object_to_json should return a json version of the object" do
|
|
1195
1195
|
o = Object.new
|
|
1196
1196
|
def o.to_json(*args); [1, args]; end
|
|
1197
|
-
Sequel.object_to_json(o, :foo).
|
|
1197
|
+
Sequel.object_to_json(o, :foo).must_equal [1, [:foo]]
|
|
1198
1198
|
end
|
|
1199
1199
|
end
|
|
1200
1200
|
|
|
@@ -1203,23 +1203,23 @@ describe "Sequel::LiteralString" do
|
|
|
1203
1203
|
@s = Sequel::LiteralString.new("? = ?")
|
|
1204
1204
|
end
|
|
1205
1205
|
|
|
1206
|
-
|
|
1207
|
-
@s.lit.
|
|
1206
|
+
it "should have lit return self if no arguments" do
|
|
1207
|
+
@s.lit.must_be_same_as(@s)
|
|
1208
1208
|
end
|
|
1209
1209
|
|
|
1210
|
-
|
|
1211
|
-
@s.lit(1, 2).
|
|
1212
|
-
Sequel.mock.literal(@s.lit(1, :a)).
|
|
1210
|
+
it "should have lit return self if return a placeholder literal string if arguments" do
|
|
1211
|
+
@s.lit(1, 2).must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
|
1212
|
+
Sequel.mock.literal(@s.lit(1, :a)).must_equal '1 = a'
|
|
1213
1213
|
end
|
|
1214
1214
|
|
|
1215
|
-
|
|
1216
|
-
@s.to_sequel_blob.
|
|
1217
|
-
@s.to_sequel_blob.
|
|
1215
|
+
it "should have to_sequel_blob convert to blob" do
|
|
1216
|
+
@s.to_sequel_blob.must_equal @s
|
|
1217
|
+
@s.to_sequel_blob.must_be_kind_of(Sequel::SQL::Blob)
|
|
1218
1218
|
end
|
|
1219
1219
|
end
|
|
1220
1220
|
|
|
1221
1221
|
describe "Sequel core extensions" do
|
|
1222
|
-
|
|
1223
|
-
Sequel.core_extensions?.
|
|
1222
|
+
it "should have Sequel.core_extensions? be false by default" do
|
|
1223
|
+
Sequel.core_extensions?.must_equal false
|
|
1224
1224
|
end
|
|
1225
1225
|
end
|