sequel 3.21.0 → 3.39.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.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
|
2
2
|
|
|
3
|
-
Regexp.send(:include, Sequel::SQL::StringMethods)
|
|
4
|
-
String.send(:include, Sequel::SQL::StringMethods)
|
|
5
|
-
|
|
6
3
|
describe "Blockless Ruby Filters" do
|
|
7
4
|
before do
|
|
8
5
|
db = Sequel::Database.new
|
|
9
|
-
db.quote_identifiers = false
|
|
10
6
|
@d = db[:items]
|
|
11
7
|
def @d.l(*args, &block)
|
|
12
8
|
literal(filter_expr(*args, &block))
|
|
@@ -20,27 +16,22 @@ describe "Blockless Ruby Filters" do
|
|
|
20
16
|
@d.l(:x).should == 'x'
|
|
21
17
|
end
|
|
22
18
|
|
|
23
|
-
it "should support NOT via Symbol#~" do
|
|
24
|
-
@d.l(~:x).should == 'NOT x'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
19
|
it "should support qualified columns" do
|
|
28
20
|
@d.l(:x__y).should == 'x.y'
|
|
29
|
-
@d.l(~:x__y).should == 'NOT x.y'
|
|
30
21
|
end
|
|
31
22
|
|
|
32
23
|
it "should support NOT with SQL functions" do
|
|
33
|
-
@d.l(
|
|
34
|
-
@d.l(
|
|
35
|
-
@d.l(
|
|
36
|
-
@d.l(
|
|
24
|
+
@d.l(~Sequel.function(:is_blah)).should == 'NOT is_blah()'
|
|
25
|
+
@d.l(~Sequel.function(:is_blah, :x)).should == 'NOT is_blah(x)'
|
|
26
|
+
@d.l(~Sequel.function(:is_blah, :x__y)).should == 'NOT is_blah(x.y)'
|
|
27
|
+
@d.l(~Sequel.function(:is_blah, :x, :x__y)).should == 'NOT is_blah(x, x.y)'
|
|
37
28
|
end
|
|
38
29
|
|
|
39
30
|
it "should handle multiple ~" do
|
|
40
|
-
@d.l(
|
|
41
|
-
@d.l(
|
|
42
|
-
@d.l(~~(:x
|
|
43
|
-
@d.l(~~(:x
|
|
31
|
+
@d.l(~Sequel.~(:x)).should == 'x'
|
|
32
|
+
@d.l(~~Sequel.~(:x)).should == 'NOT x'
|
|
33
|
+
@d.l(~~Sequel.&(:x, :y)).should == '(x AND y)'
|
|
34
|
+
@d.l(~~Sequel.|(:x, :y)).should == '(x OR y)'
|
|
44
35
|
end
|
|
45
36
|
|
|
46
37
|
it "should support = via Hash" do
|
|
@@ -55,216 +46,109 @@ describe "Blockless Ruby Filters" do
|
|
|
55
46
|
it "should use = 't' and != 't' OR IS NULL if IS TRUE is not supported" do
|
|
56
47
|
@d.meta_def(:supports_is_true?){false}
|
|
57
48
|
@d.l(:x => true).should == "(x = 't')"
|
|
58
|
-
@d.l(~
|
|
49
|
+
@d.l(~Sequel.expr(:x => true)).should == "((x != 't') OR (x IS NULL))"
|
|
59
50
|
@d.l(:x => false).should == "(x = 'f')"
|
|
60
|
-
@d.l(~
|
|
51
|
+
@d.l(~Sequel.expr(:x => false)).should == "((x != 'f') OR (x IS NULL))"
|
|
61
52
|
end
|
|
62
53
|
|
|
63
|
-
it "should support != via Hash
|
|
64
|
-
@d.l(~
|
|
65
|
-
@d.l(~
|
|
66
|
-
@d.l(~
|
|
67
|
-
@d.l(~
|
|
68
|
-
@d.l(~
|
|
54
|
+
it "should support != via inverted Hash" do
|
|
55
|
+
@d.l(~Sequel.expr(:x => 100)).should == '(x != 100)'
|
|
56
|
+
@d.l(~Sequel.expr(:x => 'a')).should == '(x != \'a\')'
|
|
57
|
+
@d.l(~Sequel.expr(:x => true)).should == '(x IS NOT TRUE)'
|
|
58
|
+
@d.l(~Sequel.expr(:x => false)).should == '(x IS NOT FALSE)'
|
|
59
|
+
@d.l(~Sequel.expr(:x => nil)).should == '(x IS NOT NULL)'
|
|
69
60
|
end
|
|
70
61
|
|
|
71
62
|
it "should support ~ via Hash and Regexp (if supported by database)" do
|
|
63
|
+
def @d.supports_regexp?; true end
|
|
72
64
|
@d.l(:x => /blah/).should == '(x ~ \'blah\')'
|
|
73
65
|
end
|
|
74
66
|
|
|
75
|
-
it "should support !~ via Hash
|
|
76
|
-
@d.
|
|
67
|
+
it "should support !~ via inverted Hash and Regexp" do
|
|
68
|
+
def @d.supports_regexp?; true end
|
|
69
|
+
@d.l(~Sequel.expr(:x => /blah/)).should == '(x !~ \'blah\')'
|
|
77
70
|
end
|
|
78
71
|
|
|
79
|
-
it "should support
|
|
80
|
-
@d.l(:x
|
|
81
|
-
@d.l(:x
|
|
82
|
-
@d.l(:x.like('a', 'b')).should == '((x LIKE \'a\') OR (x LIKE \'b\'))'
|
|
83
|
-
@d.l(:x.like(/a/, /b/i)).should == '((x ~ \'a\') OR (x ~* \'b\'))'
|
|
84
|
-
@d.l(:x.like('a', /b/)).should == '((x LIKE \'a\') OR (x ~ \'b\'))'
|
|
85
|
-
|
|
86
|
-
@d.l('a'.like(:x)).should == "('a' LIKE x)"
|
|
87
|
-
@d.l('a'.like(:x, 'b')).should == "(('a' LIKE x) OR ('a' LIKE 'b'))"
|
|
88
|
-
@d.l('a'.like(:x, /b/)).should == "(('a' LIKE x) OR ('a' ~ 'b'))"
|
|
89
|
-
@d.l('a'.like(:x, /b/i)).should == "(('a' LIKE x) OR ('a' ~* 'b'))"
|
|
90
|
-
|
|
91
|
-
@d.l(/a/.like(:x)).should == "('a' ~ x)"
|
|
92
|
-
@d.l(/a/.like(:x, 'b')).should == "(('a' ~ x) OR ('a' ~ 'b'))"
|
|
93
|
-
@d.l(/a/.like(:x, /b/)).should == "(('a' ~ x) OR ('a' ~ 'b'))"
|
|
94
|
-
@d.l(/a/.like(:x, /b/i)).should == "(('a' ~ x) OR ('a' ~* 'b'))"
|
|
95
|
-
|
|
96
|
-
@d.l(/a/i.like(:x)).should == "('a' ~* x)"
|
|
97
|
-
@d.l(/a/i.like(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
98
|
-
@d.l(/a/i.like(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
99
|
-
@d.l(/a/i.like(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "should support NOT LIKE via Symbol#like and Symbol#~" do
|
|
103
|
-
@d.l(~:x.like('a')).should == '(x NOT LIKE \'a\')'
|
|
104
|
-
@d.l(~:x.like(/a/)).should == '(x !~ \'a\')'
|
|
105
|
-
@d.l(~:x.like('a', 'b')).should == '((x NOT LIKE \'a\') AND (x NOT LIKE \'b\'))'
|
|
106
|
-
@d.l(~:x.like(/a/, /b/i)).should == '((x !~ \'a\') AND (x !~* \'b\'))'
|
|
107
|
-
@d.l(~:x.like('a', /b/)).should == '((x NOT LIKE \'a\') AND (x !~ \'b\'))'
|
|
108
|
-
|
|
109
|
-
@d.l(~'a'.like(:x)).should == "('a' NOT LIKE x)"
|
|
110
|
-
@d.l(~'a'.like(:x, 'b')).should == "(('a' NOT LIKE x) AND ('a' NOT LIKE 'b'))"
|
|
111
|
-
@d.l(~'a'.like(:x, /b/)).should == "(('a' NOT LIKE x) AND ('a' !~ 'b'))"
|
|
112
|
-
@d.l(~'a'.like(:x, /b/i)).should == "(('a' NOT LIKE x) AND ('a' !~* 'b'))"
|
|
113
|
-
|
|
114
|
-
@d.l(~/a/.like(:x)).should == "('a' !~ x)"
|
|
115
|
-
@d.l(~/a/.like(:x, 'b')).should == "(('a' !~ x) AND ('a' !~ 'b'))"
|
|
116
|
-
@d.l(~/a/.like(:x, /b/)).should == "(('a' !~ x) AND ('a' !~ 'b'))"
|
|
117
|
-
@d.l(~/a/.like(:x, /b/i)).should == "(('a' !~ x) AND ('a' !~* 'b'))"
|
|
118
|
-
|
|
119
|
-
@d.l(~/a/i.like(:x)).should == "('a' !~* x)"
|
|
120
|
-
@d.l(~/a/i.like(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
121
|
-
@d.l(~/a/i.like(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
122
|
-
@d.l(~/a/i.like(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "should support ILIKE via Symbol#ilike" do
|
|
126
|
-
@d.l(:x.ilike('a')).should == '(x ILIKE \'a\')'
|
|
127
|
-
@d.l(:x.ilike(/a/)).should == '(x ~* \'a\')'
|
|
128
|
-
@d.l(:x.ilike('a', 'b')).should == '((x ILIKE \'a\') OR (x ILIKE \'b\'))'
|
|
129
|
-
@d.l(:x.ilike(/a/, /b/i)).should == '((x ~* \'a\') OR (x ~* \'b\'))'
|
|
130
|
-
@d.l(:x.ilike('a', /b/)).should == '((x ILIKE \'a\') OR (x ~* \'b\'))'
|
|
131
|
-
|
|
132
|
-
@d.l('a'.ilike(:x)).should == "('a' ILIKE x)"
|
|
133
|
-
@d.l('a'.ilike(:x, 'b')).should == "(('a' ILIKE x) OR ('a' ILIKE 'b'))"
|
|
134
|
-
@d.l('a'.ilike(:x, /b/)).should == "(('a' ILIKE x) OR ('a' ~* 'b'))"
|
|
135
|
-
@d.l('a'.ilike(:x, /b/i)).should == "(('a' ILIKE x) OR ('a' ~* 'b'))"
|
|
136
|
-
|
|
137
|
-
@d.l(/a/.ilike(:x)).should == "('a' ~* x)"
|
|
138
|
-
@d.l(/a/.ilike(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
139
|
-
@d.l(/a/.ilike(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
140
|
-
@d.l(/a/.ilike(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
141
|
-
|
|
142
|
-
@d.l(/a/i.ilike(:x)).should == "('a' ~* x)"
|
|
143
|
-
@d.l(/a/i.ilike(:x, 'b')).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
144
|
-
@d.l(/a/i.ilike(:x, /b/)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
145
|
-
@d.l(/a/i.ilike(:x, /b/i)).should == "(('a' ~* x) OR ('a' ~* 'b'))"
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
it "should support NOT ILIKE via Symbol#ilike and Symbol#~" do
|
|
149
|
-
@d.l(~:x.ilike('a')).should == '(x NOT ILIKE \'a\')'
|
|
150
|
-
@d.l(~:x.ilike(/a/)).should == '(x !~* \'a\')'
|
|
151
|
-
@d.l(~:x.ilike('a', 'b')).should == '((x NOT ILIKE \'a\') AND (x NOT ILIKE \'b\'))'
|
|
152
|
-
@d.l(~:x.ilike(/a/, /b/i)).should == '((x !~* \'a\') AND (x !~* \'b\'))'
|
|
153
|
-
@d.l(~:x.ilike('a', /b/)).should == '((x NOT ILIKE \'a\') AND (x !~* \'b\'))'
|
|
154
|
-
|
|
155
|
-
@d.l(~'a'.ilike(:x)).should == "('a' NOT ILIKE x)"
|
|
156
|
-
@d.l(~'a'.ilike(:x, 'b')).should == "(('a' NOT ILIKE x) AND ('a' NOT ILIKE 'b'))"
|
|
157
|
-
@d.l(~'a'.ilike(:x, /b/)).should == "(('a' NOT ILIKE x) AND ('a' !~* 'b'))"
|
|
158
|
-
@d.l(~'a'.ilike(:x, /b/i)).should == "(('a' NOT ILIKE x) AND ('a' !~* 'b'))"
|
|
159
|
-
|
|
160
|
-
@d.l(~/a/.ilike(:x)).should == "('a' !~* x)"
|
|
161
|
-
@d.l(~/a/.ilike(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
162
|
-
@d.l(~/a/.ilike(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
163
|
-
@d.l(~/a/.ilike(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
164
|
-
|
|
165
|
-
@d.l(~/a/i.ilike(:x)).should == "('a' !~* x)"
|
|
166
|
-
@d.l(~/a/i.ilike(:x, 'b')).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
167
|
-
@d.l(~/a/i.ilike(:x, /b/)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
168
|
-
@d.l(~/a/i.ilike(:x, /b/i)).should == "(('a' !~* x) AND ('a' !~* 'b'))"
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
it "should support negating ranges via Hash#~ and Range" do
|
|
172
|
-
@d.l(~{:x => 1..5}).should == '((x < 1) OR (x > 5))'
|
|
173
|
-
@d.l(~{:x => 1...5}).should == '((x < 1) OR (x >= 5))'
|
|
72
|
+
it "should support negating ranges" do
|
|
73
|
+
@d.l(~Sequel.expr(:x => 1..5)).should == '((x < 1) OR (x > 5))'
|
|
74
|
+
@d.l(~Sequel.expr(:x => 1...5)).should == '((x < 1) OR (x >= 5))'
|
|
174
75
|
end
|
|
175
76
|
|
|
176
|
-
it "should support negating
|
|
177
|
-
@d.l(~
|
|
178
|
-
@d.l(~
|
|
77
|
+
it "should support negating IN with Dataset or Array" do
|
|
78
|
+
@d.l(~Sequel.expr(:x => @d.select(:i))).should == '(x NOT IN (SELECT i FROM items))'
|
|
79
|
+
@d.l(~Sequel.expr(:x => [1,2,3])).should == '(x NOT IN (1, 2, 3))'
|
|
179
80
|
end
|
|
180
81
|
|
|
181
|
-
it "should
|
|
182
|
-
|
|
183
|
-
@d.l((:x * :y) < 100.01).should == '((x * y) < 100.01)'
|
|
184
|
-
@d.l((:x - :y/2) >= 100000000000000000000000000000000000).should == '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
|
185
|
-
@d.l((((:x - :y)/(:x + :y))*:z) <= 100).should == '((((x - y) / (x + y)) * z) <= 100)'
|
|
186
|
-
@d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
it "should not allow negation of string expressions" do
|
|
190
|
-
proc{~:x.sql_string}.should raise_error
|
|
191
|
-
proc{~([:x, :y].sql_string_join)}.should raise_error
|
|
82
|
+
it "should not add ~ method to string expressions" do
|
|
83
|
+
proc{~Sequel.expr(:x).sql_string}.should raise_error(NoMethodError)
|
|
192
84
|
end
|
|
193
85
|
|
|
194
|
-
it "should
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
86
|
+
it "should allow mathematical or string operations on true, false, or nil" do
|
|
87
|
+
@d.lit(Sequel.expr(:x) + 1).should == '(x + 1)'
|
|
88
|
+
@d.lit(Sequel.expr(:x) - true).should == "(x - 't')"
|
|
89
|
+
@d.lit(Sequel.expr(:x) / false).should == "(x / 'f')"
|
|
90
|
+
@d.lit(Sequel.expr(:x) * nil).should == '(x * NULL)'
|
|
91
|
+
@d.lit(Sequel.join([:x, nil])).should == '(x || NULL)'
|
|
200
92
|
end
|
|
201
93
|
|
|
202
|
-
it "should
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
proc{:x + ~:y.like('a')}.should raise_error(Sequel::Error)
|
|
211
|
-
proc{:x - ~:y.like(/a/)}.should raise_error(Sequel::Error)
|
|
212
|
-
proc{:x * ~:y.like(/a/i)}.should raise_error(Sequel::Error)
|
|
213
|
-
proc{[:x, ~:y.like(/a/i)].sql_string_join}.should raise_error(Sequel::Error)
|
|
94
|
+
it "should allow mathematical or string operations on boolean complex expressions" do
|
|
95
|
+
@d.lit(Sequel.expr(:x) + (Sequel.expr(:y) + 1)).should == '(x + y + 1)'
|
|
96
|
+
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y)).should == '(x - NOT y)'
|
|
97
|
+
@d.lit(Sequel.expr(:x) / (Sequel.expr(:y) & :z)).should == '(x / (y AND z))'
|
|
98
|
+
@d.lit(Sequel.expr(:x) * (Sequel.expr(:y) | :z)).should == '(x * (y OR z))'
|
|
99
|
+
@d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).should == "(x + (y LIKE 'a'))"
|
|
100
|
+
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).should == "(x - (y NOT LIKE 'a'))"
|
|
101
|
+
@d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).should == "(x || (y NOT LIKE 'a'))"
|
|
214
102
|
end
|
|
215
103
|
|
|
216
104
|
it "should support AND conditions via &" do
|
|
217
|
-
@d.l(:x & :y).should == '(x AND y)'
|
|
218
|
-
@d.l(:x.sql_boolean & :y).should == '(x AND y)'
|
|
219
|
-
@d.l(:x & :y & :z).should == '(x AND y AND z)'
|
|
220
|
-
@d.l(:x & {:y => :z}).should == '(x AND (y = z))'
|
|
221
|
-
@d.l(
|
|
222
|
-
@d.l(
|
|
223
|
-
@d.l((:x
|
|
224
|
-
@d.l(:x &
|
|
225
|
-
@d.l(~:x & :y).should == '(NOT x AND y)'
|
|
226
|
-
@d.l(~:x & ~:y).should == '(NOT x AND NOT y)'
|
|
105
|
+
@d.l(Sequel.expr(:x) & :y).should == '(x AND y)'
|
|
106
|
+
@d.l(Sequel.expr(:x).sql_boolean & :y).should == '(x AND y)'
|
|
107
|
+
@d.l(Sequel.expr(:x) & :y & :z).should == '(x AND y AND z)'
|
|
108
|
+
@d.l(Sequel.expr(:x) & {:y => :z}).should == '(x AND (y = z))'
|
|
109
|
+
@d.l((Sequel.expr(:x) + 200 < 0) & (Sequel.expr(:y) - 200 < 0)).should == '(((x + 200) < 0) AND ((y - 200) < 0))'
|
|
110
|
+
@d.l(Sequel.expr(:x) & ~Sequel.expr(:y)).should == '(x AND NOT y)'
|
|
111
|
+
@d.l(~Sequel.expr(:x) & :y).should == '(NOT x AND y)'
|
|
112
|
+
@d.l(~Sequel.expr(:x) & ~Sequel.expr(:y)).should == '(NOT x AND NOT y)'
|
|
227
113
|
end
|
|
228
114
|
|
|
229
115
|
it "should support OR conditions via |" do
|
|
230
|
-
@d.l(:x | :y).should == '(x OR y)'
|
|
231
|
-
@d.l(:x.sql_boolean | :y).should == '(x OR y)'
|
|
232
|
-
@d.l(:x | :y | :z).should == '(x OR y OR z)'
|
|
233
|
-
@d.l(:x | {:y => :z}).should == '(x OR (y = z))'
|
|
234
|
-
@d.l(
|
|
235
|
-
@d.l({:x => :a} | {:y => :z}).should == '((x = a) OR (y = z))'
|
|
236
|
-
@d.l((:x.sql_number > 200) | (:y.sql_number < 200)).should == '((x > 200) OR (y < 200))'
|
|
116
|
+
@d.l(Sequel.expr(:x) | :y).should == '(x OR y)'
|
|
117
|
+
@d.l(Sequel.expr(:x).sql_boolean | :y).should == '(x OR y)'
|
|
118
|
+
@d.l(Sequel.expr(:x) | :y | :z).should == '(x OR y OR z)'
|
|
119
|
+
@d.l(Sequel.expr(:x) | {:y => :z}).should == '(x OR (y = z))'
|
|
120
|
+
@d.l((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y).sql_number < 200)).should == '((x > 200) OR (y < 200))'
|
|
237
121
|
end
|
|
238
122
|
|
|
239
123
|
it "should support & | combinations" do
|
|
240
|
-
@d.l((:x | :y) & :z).should == '((x OR y) AND z)'
|
|
241
|
-
@d.l(:x | (:y & :z)).should == '(x OR (y AND z))'
|
|
242
|
-
@d.l((:x & :w) | (:y & :z)).should == '((x AND w) OR (y AND z))'
|
|
124
|
+
@d.l((Sequel.expr(:x) | :y) & :z).should == '((x OR y) AND z)'
|
|
125
|
+
@d.l(Sequel.expr(:x) | (Sequel.expr(:y) & :z)).should == '(x OR (y AND z))'
|
|
126
|
+
@d.l((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z)).should == '((x AND w) OR (y AND z))'
|
|
243
127
|
end
|
|
244
128
|
|
|
245
129
|
it "should support & | with ~" do
|
|
246
|
-
@d.l(~((:x | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
|
|
247
|
-
@d.l(~(:x | (:y & :z))).should == '(NOT x AND (NOT y OR NOT z))'
|
|
248
|
-
@d.l(~((:x & :w) | (:y & :z))).should == '((NOT x OR NOT w) AND (NOT y OR NOT z))'
|
|
249
|
-
@d.l(~((:x.sql_number > 200) | (:y & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
|
|
130
|
+
@d.l(~((Sequel.expr(:x) | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
|
|
131
|
+
@d.l(~(Sequel.expr(:x) | (Sequel.expr(:y) & :z))).should == '(NOT x AND (NOT y OR NOT z))'
|
|
132
|
+
@d.l(~((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z))).should == '((NOT x OR NOT w) AND (NOT y OR NOT z))'
|
|
133
|
+
@d.l(~((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y) & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
|
|
250
134
|
end
|
|
251
135
|
|
|
252
136
|
it "should support LiteralString" do
|
|
253
|
-
@d.l('x'
|
|
254
|
-
@d.l(~'x'
|
|
255
|
-
@d.l(~~'x'
|
|
256
|
-
@d.l(~(('x'
|
|
257
|
-
@d.l(~(:x | 'y'
|
|
258
|
-
@d.l(~('x'
|
|
259
|
-
@d.l(
|
|
260
|
-
@d.l(('x'
|
|
261
|
-
@d.l(~('x'
|
|
262
|
-
@d.l('x'.
|
|
263
|
-
@d.l('x'
|
|
264
|
-
@d.l(('x'
|
|
265
|
-
@d.l(('x'
|
|
266
|
-
@d.l(('z'
|
|
267
|
-
@d.l(~(((('x'
|
|
137
|
+
@d.l(Sequel.lit('x')).should == '(x)'
|
|
138
|
+
@d.l(~Sequel.lit('x')).should == 'NOT x'
|
|
139
|
+
@d.l(~~Sequel.lit('x')).should == 'x'
|
|
140
|
+
@d.l(~((Sequel.lit('x') | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
|
|
141
|
+
@d.l(~(Sequel.expr(:x) | Sequel.lit('y'))).should == '(NOT x AND NOT y)'
|
|
142
|
+
@d.l(~(Sequel.lit('x') & Sequel.lit('y'))).should == '(NOT x OR NOT y)'
|
|
143
|
+
@d.l(Sequel.expr(Sequel.lit('y') => Sequel.lit('z')) & Sequel.lit('x')).should == '((y = z) AND x)'
|
|
144
|
+
@d.l((Sequel.lit('x') > 200) & (Sequel.lit('y') < 200)).should == '((x > 200) AND (y < 200))'
|
|
145
|
+
@d.l(~(Sequel.lit('x') + 1 > 100)).should == '((x + 1) <= 100)'
|
|
146
|
+
@d.l(Sequel.lit('x').like('a')).should == '(x LIKE \'a\')'
|
|
147
|
+
@d.l(Sequel.lit('x') + 1 > 100).should == '((x + 1) > 100)'
|
|
148
|
+
@d.l((Sequel.lit('x') * :y) < 100.01).should == '((x * y) < 100.01)'
|
|
149
|
+
@d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).should == '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
|
150
|
+
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).should == '((z * (x / y / (x + y))) <= 100)'
|
|
151
|
+
@d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
|
|
268
152
|
end
|
|
269
153
|
|
|
270
154
|
it "should support hashes by ANDing the conditions" do
|
|
@@ -273,134 +157,71 @@ describe "Blockless Ruby Filters" do
|
|
|
273
157
|
@d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
|
|
274
158
|
end
|
|
275
159
|
|
|
276
|
-
it "should support sql_expr on hashes" do
|
|
277
|
-
@d.l({:x => 100, :y => 'a'}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x = 100)', '(y = \'a\')']
|
|
278
|
-
@d.l({:x => true, :y => false}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x IS TRUE)', '(y IS FALSE)']
|
|
279
|
-
@d.l({:x => nil, :y => [1,2,3]}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
it "should support sql_negate on hashes" do
|
|
283
|
-
@d.l({:x => 100, :y => 'a'}.sql_negate)[1...-1].split(' AND ').sort.should == ['(x != 100)', '(y != \'a\')']
|
|
284
|
-
@d.l({:x => true, :y => false}.sql_negate)[1...-1].split(' AND ').sort.should == ['(x IS NOT TRUE)', '(y IS NOT FALSE)']
|
|
285
|
-
@d.l({:x => nil, :y => [1,2,3]}.sql_negate)[1...-1].split(' AND ').sort.should == ['(x IS NOT NULL)', '(y NOT IN (1, 2, 3))']
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
it "should support ~ on hashes" do
|
|
289
|
-
@d.l(~{:x => 100, :y => 'a'})[1...-1].split(' OR ').sort.should == ['(x != 100)', '(y != \'a\')']
|
|
290
|
-
@d.l(~{:x => true, :y => false})[1...-1].split(' OR ').sort.should == ['(x IS NOT TRUE)', '(y IS NOT FALSE)']
|
|
291
|
-
@d.l(~{:x => nil, :y => [1,2,3]})[1...-1].split(' OR ').sort.should == ['(x IS NOT NULL)', '(y NOT IN (1, 2, 3))']
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
it "should support sql_or on hashes" do
|
|
295
|
-
@d.l({:x => 100, :y => 'a'}.sql_or)[1...-1].split(' OR ').sort.should == ['(x = 100)', '(y = \'a\')']
|
|
296
|
-
@d.l({:x => true, :y => false}.sql_or)[1...-1].split(' OR ').sort.should == ['(x IS TRUE)', '(y IS FALSE)']
|
|
297
|
-
@d.l({:x => nil, :y => [1,2,3]}.sql_or)[1...-1].split(' OR ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
|
|
298
|
-
end
|
|
299
|
-
|
|
300
160
|
it "should support arrays with all two pairs the same as hashes" do
|
|
301
161
|
@d.l([[:x, 100],[:y, 'a']]).should == '((x = 100) AND (y = \'a\'))'
|
|
302
162
|
@d.l([[:x, true], [:y, false]]).should == '((x IS TRUE) AND (y IS FALSE))'
|
|
303
163
|
@d.l([[:x, nil], [:y, [1,2,3]]]).should == '((x IS NULL) AND (y IN (1, 2, 3)))'
|
|
304
164
|
end
|
|
305
165
|
|
|
306
|
-
it "should support sql_expr on arrays with all two pairs" do
|
|
307
|
-
@d.l([[:x, 100],[:y, 'a']].sql_expr).should == '((x = 100) AND (y = \'a\'))'
|
|
308
|
-
@d.l([[:x, true], [:y, false]].sql_expr).should == '((x IS TRUE) AND (y IS FALSE))'
|
|
309
|
-
@d.l([[:x, nil], [:y, [1,2,3]]].sql_expr).should == '((x IS NULL) AND (y IN (1, 2, 3)))'
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
it "should support sql_negate on arrays with all two pairs" do
|
|
313
|
-
@d.l([[:x, 100],[:y, 'a']].sql_negate).should == '((x != 100) AND (y != \'a\'))'
|
|
314
|
-
@d.l([[:x, true], [:y, false]].sql_negate).should == '((x IS NOT TRUE) AND (y IS NOT FALSE))'
|
|
315
|
-
@d.l([[:x, nil], [:y, [1,2,3]]].sql_negate).should == '((x IS NOT NULL) AND (y NOT IN (1, 2, 3)))'
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
it "should support ~ on arrays with all two pairs" do
|
|
319
|
-
@d.l(~[[:x, 100],[:y, 'a']]).should == '((x != 100) OR (y != \'a\'))'
|
|
320
|
-
@d.l(~[[:x, true], [:y, false]]).should == '((x IS NOT TRUE) OR (y IS NOT FALSE))'
|
|
321
|
-
@d.l(~[[:x, nil], [:y, [1,2,3]]]).should == '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
it "should support sql_or on arrays with all two pairs" do
|
|
325
|
-
@d.l([[:x, 100],[:y, 'a']].sql_or).should == '((x = 100) OR (y = \'a\'))'
|
|
326
|
-
@d.l([[:x, true], [:y, false]].sql_or).should == '((x IS TRUE) OR (y IS FALSE))'
|
|
327
|
-
@d.l([[:x, nil], [:y, [1,2,3]]].sql_or).should == '((x IS NULL) OR (y IN (1, 2, 3)))'
|
|
328
|
-
end
|
|
329
|
-
|
|
330
166
|
it "should emulate columns for array values" do
|
|
331
|
-
@d.l([:x, :y]=>[[1,2], [3,4]]
|
|
167
|
+
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).should == '((x, y) IN ((1, 2), (3, 4)))'
|
|
332
168
|
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
|
|
333
169
|
end
|
|
334
170
|
|
|
335
171
|
it "should emulate multiple column in if not supported" do
|
|
336
172
|
@d.meta_def(:supports_multiple_column_in?){false}
|
|
337
|
-
@d.l([:x, :y]=>[[1,2], [3,4]]
|
|
173
|
+
@d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).should == '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
|
|
338
174
|
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '(((x = 1) AND (y = 2) AND (z = 5)) OR ((x = 3) AND (y = 4) AND (z = 6)))'
|
|
339
175
|
end
|
|
340
176
|
|
|
341
|
-
it "should support Array#sql_string_join for concatenation of SQL strings" do
|
|
342
|
-
@d.lit([:x].sql_string_join).should == '(x)'
|
|
343
|
-
@d.lit([:x].sql_string_join(', ')).should == '(x)'
|
|
344
|
-
@d.lit([:x, :y].sql_string_join).should == '(x || y)'
|
|
345
|
-
@d.lit([:x, :y].sql_string_join(', ')).should == "(x || ', ' || y)"
|
|
346
|
-
@d.lit([:x.sql_function(1), :y.sql_subscript(1)].sql_string_join).should == '(x(1) || y[1])'
|
|
347
|
-
@d.lit([:x.sql_function(1), 'y.z'.lit].sql_string_join(', ')).should == "(x(1) || ', ' || y.z)"
|
|
348
|
-
@d.lit([:x, 1, :y].sql_string_join).should == "(x || '1' || y)"
|
|
349
|
-
@d.lit([:x, 1, :y].sql_string_join(', ')).should == "(x || ', ' || '1' || ', ' || y)"
|
|
350
|
-
@d.lit([:x, 1, :y].sql_string_join(:y__z)).should == "(x || y.z || '1' || y.z || y)"
|
|
351
|
-
@d.lit([:x, 1, :y].sql_string_join(1)).should == "(x || '1' || '1' || '1' || y)"
|
|
352
|
-
@d.lit([:x, :y].sql_string_join('y.x || x.y'.lit)).should == "(x || y.x || x.y || y)"
|
|
353
|
-
@d.lit([[:x, :y].sql_string_join, [:a, :b].sql_string_join].sql_string_join).should == "(x || y || a || b)"
|
|
354
|
-
end
|
|
355
|
-
|
|
356
177
|
it "should support StringExpression#+ for concatenation of SQL strings" do
|
|
357
|
-
@d.lit(:x.sql_string + :y).should == '(x || y)'
|
|
358
|
-
@d.lit([:x]
|
|
359
|
-
@d.lit([:x, :z]
|
|
178
|
+
@d.lit(Sequel.expr(:x).sql_string + :y).should == '(x || y)'
|
|
179
|
+
@d.lit(Sequel.join([:x]) + :y).should == '(x || y)'
|
|
180
|
+
@d.lit(Sequel.join([:x, :z], ' ') + :y).should == "(x || ' ' || z || y)"
|
|
360
181
|
end
|
|
361
182
|
|
|
362
183
|
it "should be supported inside blocks" do
|
|
363
|
-
@d.l{[[:x, nil], [:y, [1,2,3]]]
|
|
364
|
-
@d.l{
|
|
365
|
-
@d.l{~(((('x'
|
|
366
|
-
@d.l{{:x => :a}
|
|
184
|
+
@d.l{Sequel.or([[:x, nil], [:y, [1,2,3]]])}.should == '((x IS NULL) OR (y IN (1, 2, 3)))'
|
|
185
|
+
@d.l{Sequel.~([[:x, nil], [:y, [1,2,3]]])}.should == '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
|
|
186
|
+
@d.l{~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)}.should == '((((x - y) / (x + y)) * z) > 100)'
|
|
187
|
+
@d.l{Sequel.&({:x => :a}, {:y => :z})}.should == '((x = a) AND (y = z))'
|
|
367
188
|
end
|
|
368
189
|
|
|
369
190
|
it "should support &, |, ^, ~, <<, and >> for NumericExpressions" do
|
|
370
|
-
@d.l(:x.sql_number & 1 > 100).should == '((x & 1) > 100)'
|
|
371
|
-
@d.l(:x.sql_number | 1 > 100).should == '((x | 1) > 100)'
|
|
372
|
-
@d.l(:x.sql_number ^ 1 > 100).should == '((x ^ 1) > 100)'
|
|
373
|
-
@d.l(
|
|
374
|
-
@d.l(:x.sql_number << 1 > 100).should == '((x << 1) > 100)'
|
|
375
|
-
@d.l(:x.sql_number >> 1 > 100).should == '((x >> 1) > 100)'
|
|
376
|
-
@d.l((:x + 1) & 1 > 100).should == '(((x + 1) & 1) > 100)'
|
|
377
|
-
@d.l((:x + 1) | 1 > 100).should == '(((x + 1) | 1) > 100)'
|
|
378
|
-
@d.l((:x + 1) ^ 1 > 100).should == '(((x + 1) ^ 1) > 100)'
|
|
379
|
-
@d.l(~(:x + 1) > 100).should == '(~(x + 1) > 100)'
|
|
380
|
-
@d.l((:x + 1) << 1 > 100).should == '(((x + 1) << 1) > 100)'
|
|
381
|
-
@d.l((:x + 1) >> 1 > 100).should == '(((x + 1) >> 1) > 100)'
|
|
382
|
-
@d.l((:x + 1) & (:x + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
|
|
191
|
+
@d.l(Sequel.expr(:x).sql_number & 1 > 100).should == '((x & 1) > 100)'
|
|
192
|
+
@d.l(Sequel.expr(:x).sql_number | 1 > 100).should == '((x | 1) > 100)'
|
|
193
|
+
@d.l(Sequel.expr(:x).sql_number ^ 1 > 100).should == '((x ^ 1) > 100)'
|
|
194
|
+
@d.l(~Sequel.expr(:x).sql_number > 100).should == '(~x > 100)'
|
|
195
|
+
@d.l(Sequel.expr(:x).sql_number << 1 > 100).should == '((x << 1) > 100)'
|
|
196
|
+
@d.l(Sequel.expr(:x).sql_number >> 1 > 100).should == '((x >> 1) > 100)'
|
|
197
|
+
@d.l((Sequel.expr(:x) + 1) & 1 > 100).should == '(((x + 1) & 1) > 100)'
|
|
198
|
+
@d.l((Sequel.expr(:x) + 1) | 1 > 100).should == '(((x + 1) | 1) > 100)'
|
|
199
|
+
@d.l((Sequel.expr(:x) + 1) ^ 1 > 100).should == '(((x + 1) ^ 1) > 100)'
|
|
200
|
+
@d.l(~(Sequel.expr(:x) + 1) > 100).should == '(~(x + 1) > 100)'
|
|
201
|
+
@d.l((Sequel.expr(:x) + 1) << 1 > 100).should == '(((x + 1) << 1) > 100)'
|
|
202
|
+
@d.l((Sequel.expr(:x) + 1) >> 1 > 100).should == '(((x + 1) >> 1) > 100)'
|
|
203
|
+
@d.l((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
|
|
383
204
|
end
|
|
384
205
|
|
|
385
|
-
it "should
|
|
386
|
-
|
|
206
|
+
it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
|
|
207
|
+
@d.lit((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + '2')).should == "((x + 1) & (x || '2'))"
|
|
387
208
|
end
|
|
388
209
|
|
|
389
|
-
it "should
|
|
390
|
-
|
|
210
|
+
it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
|
|
211
|
+
@d.l(Sequel.expr(:x) & (Sequel.expr(:x) + '2')).should == "(x AND (x || '2'))"
|
|
391
212
|
end
|
|
392
213
|
|
|
393
214
|
it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
|
|
394
|
-
proc{Sequel::SQL::BooleanExpression.invert(:x + 2)}.should raise_error(Sequel::Error)
|
|
215
|
+
proc{Sequel::SQL::BooleanExpression.invert(Sequel.expr(:x) + 2)}.should raise_error(Sequel::Error)
|
|
395
216
|
end
|
|
396
217
|
|
|
397
218
|
it "should return self on .lit" do
|
|
398
|
-
y = :x + 1
|
|
219
|
+
y = Sequel.expr(:x) + 1
|
|
399
220
|
y.lit.should == y
|
|
400
221
|
end
|
|
401
222
|
|
|
402
223
|
it "should return have .sql_literal operate like .to_s" do
|
|
403
|
-
y = :x + 1
|
|
224
|
+
y = Sequel.expr(:x) + 1
|
|
404
225
|
y.sql_literal(@d).should == '(x + 1)'
|
|
405
226
|
y.sql_literal(@d).should == y.to_s(@d)
|
|
406
227
|
y.sql_literal(@d).should == @d.literal(y)
|
|
@@ -416,68 +237,159 @@ describe "Blockless Ruby Filters" do
|
|
|
416
237
|
end
|
|
417
238
|
|
|
418
239
|
it "should support negation of SQL::Constants" do
|
|
419
|
-
@d.l(
|
|
420
|
-
@d.l(
|
|
421
|
-
@d.l(
|
|
422
|
-
@d.l(
|
|
423
|
-
@d.l(
|
|
424
|
-
@d.l(
|
|
240
|
+
@d.l(Sequel.~(:x => Sequel::NULL)).should == '(x IS NOT NULL)'
|
|
241
|
+
@d.l(Sequel.~(:x => Sequel::NOTNULL)).should == '(x IS NULL)'
|
|
242
|
+
@d.l(Sequel.~(:x => Sequel::TRUE)).should == '(x IS NOT TRUE)'
|
|
243
|
+
@d.l(Sequel.~(:x => Sequel::FALSE)).should == '(x IS NOT FALSE)'
|
|
244
|
+
@d.l(Sequel.~(:x => Sequel::SQLTRUE)).should == '(x IS NOT TRUE)'
|
|
245
|
+
@d.l(Sequel.~(:x => Sequel::SQLFALSE)).should == '(x IS NOT FALSE)'
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should support direct negation of SQL::Constants" do
|
|
249
|
+
@d.l({:x => ~Sequel::NULL}).should == '(x IS NOT NULL)'
|
|
250
|
+
@d.l({:x => ~Sequel::NOTNULL}).should == '(x IS NULL)'
|
|
251
|
+
@d.l({:x => ~Sequel::TRUE}).should == '(x IS FALSE)'
|
|
252
|
+
@d.l({:x => ~Sequel::FALSE}).should == '(x IS TRUE)'
|
|
253
|
+
@d.l({:x => ~Sequel::SQLTRUE}).should == '(x IS FALSE)'
|
|
254
|
+
@d.l({:x => ~Sequel::SQLFALSE}).should == '(x IS TRUE)'
|
|
425
255
|
end
|
|
426
256
|
|
|
257
|
+
it "should raise an error if trying to invert an invalid SQL::Constant" do
|
|
258
|
+
proc{~Sequel::CURRENT_DATE}.should raise_error(Sequel::Error)
|
|
259
|
+
end
|
|
260
|
+
|
|
427
261
|
it "should raise an error if trying to create an invalid complex expression" do
|
|
428
262
|
proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.should raise_error(Sequel::Error)
|
|
429
263
|
end
|
|
430
264
|
|
|
265
|
+
it "should use a string concatentation for + if given a string" do
|
|
266
|
+
@d.lit(Sequel.expr(:x) + '1').should == "(x || '1')"
|
|
267
|
+
@d.lit(Sequel.expr(:x) + '1' + '1').should == "(x || '1' || '1')"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should use an addition for + if given a literal string" do
|
|
271
|
+
@d.lit(Sequel.expr(:x) + Sequel.lit('1')).should == "(x + 1)"
|
|
272
|
+
@d.lit(Sequel.expr(:x) + Sequel.lit('1') + Sequel.lit('1')).should == "(x + 1 + 1)"
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
it "should use a bitwise operator for & and | if given an integer" do
|
|
276
|
+
@d.lit(Sequel.expr(:x) & 1).should == "(x & 1)"
|
|
277
|
+
@d.lit(Sequel.expr(:x) | 1).should == "(x | 1)"
|
|
278
|
+
@d.lit(Sequel.expr(:x) & 1 & 1).should == "(x & 1 & 1)"
|
|
279
|
+
@d.lit(Sequel.expr(:x) | 1 | 1).should == "(x | 1 | 1)"
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should allow adding a string to an integer expression" do
|
|
283
|
+
@d.lit(Sequel.expr(:x) + 1 + 'a').should == "(x + 1 + 'a')"
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it "should allow adding an integer to an string expression" do
|
|
287
|
+
@d.lit(Sequel.expr(:x) + 'a' + 1).should == "(x || 'a' || 1)"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "should allow adding a boolean to an integer expression" do
|
|
291
|
+
@d.lit(Sequel.expr(:x) + 1 + true).should == "(x + 1 + 't')"
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "should allow adding a boolean to an string expression" do
|
|
295
|
+
@d.lit(Sequel.expr(:x) + 'a' + true).should == "(x || 'a' || 't')"
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it "should allow using a boolean operation with an integer on an boolean expression" do
|
|
299
|
+
@d.lit(Sequel.expr(:x) & :a & 1).should == "(x AND a AND 1)"
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "should allow using a boolean operation with a string on an boolean expression" do
|
|
303
|
+
@d.lit(Sequel.expr(:x) & :a & 'a').should == "(x AND a AND 'a')"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
it "should allowing AND of boolean expression and literal string" do
|
|
307
|
+
@d.lit(Sequel.expr(:x) & :a & Sequel.lit('a')).should == "(x AND a AND a)"
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "should allowing + of integer expression and literal string" do
|
|
311
|
+
@d.lit(Sequel.expr(:x) + :a + Sequel.lit('a')).should == "(x + a + a)"
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
it "should allowing + of string expression and literal string" do
|
|
315
|
+
@d.lit(Sequel.expr(:x) + 'a' + Sequel.lit('a')).should == "(x || 'a' || a)"
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "should allow sql_{string,boolean,number} methods on numeric expressions" do
|
|
319
|
+
@d.lit((Sequel.expr(:x) + 1).sql_string + 'a').should == "((x + 1) || 'a')"
|
|
320
|
+
@d.lit((Sequel.expr(:x) + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
|
|
321
|
+
@d.lit((Sequel.expr(:x) + 1).sql_number + 'a').should == "(x + 1 + 'a')"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "should allow sql_{string,boolean,number} methods on string expressions" do
|
|
325
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
|
|
326
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
|
|
327
|
+
@d.lit((Sequel.expr(:x) + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should allow sql_{string,boolean,number} methods on boolean expressions" do
|
|
331
|
+
@d.lit((Sequel.expr(:x) & :y).sql_string + 'a').should == "((x AND y) || 'a')"
|
|
332
|
+
@d.lit((Sequel.expr(:x) & :y).sql_boolean & 1).should == "(x AND y AND 1)"
|
|
333
|
+
@d.lit((Sequel.expr(:x) & :y).sql_number + 'a').should == "((x AND y) + 'a')"
|
|
334
|
+
end
|
|
335
|
+
|
|
431
336
|
it "should raise an error if trying to literalize an invalid complex expression" do
|
|
432
|
-
ce = :x
|
|
337
|
+
ce = Sequel.+(:x, 1)
|
|
433
338
|
ce.instance_variable_set(:@op, :BANG)
|
|
434
339
|
proc{@d.lit(ce)}.should raise_error(Sequel::Error)
|
|
435
340
|
end
|
|
436
341
|
|
|
437
342
|
it "should support equality comparison of two expressions" do
|
|
438
|
-
e1 =
|
|
439
|
-
e2 =
|
|
343
|
+
e1 = ~Sequel.like(:comment, '%:hidden:%')
|
|
344
|
+
e2 = ~Sequel.like(:comment, '%:hidden:%')
|
|
440
345
|
e1.should == e2
|
|
441
346
|
end
|
|
442
|
-
|
|
443
|
-
if RUBY_VERSION < '1.9.0'
|
|
444
|
-
it "should not allow inequality operations on true, false, or nil" do
|
|
445
|
-
proc{:x > 1}.should_not raise_error
|
|
446
|
-
proc{:x < true}.should raise_error(Sequel::Error)
|
|
447
|
-
proc{:x >= false}.should raise_error(Sequel::Error)
|
|
448
|
-
proc{:x <= nil}.should raise_error(Sequel::Error)
|
|
449
|
-
end
|
|
450
347
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
348
|
+
it "should support expression filter methods on Datasets" do
|
|
349
|
+
d = @d.select(:a)
|
|
350
|
+
|
|
351
|
+
@d.lit(d + 1).should == '((SELECT a FROM items) + 1)'
|
|
352
|
+
@d.lit(d - 1).should == '((SELECT a FROM items) - 1)'
|
|
353
|
+
@d.lit(d * 1).should == '((SELECT a FROM items) * 1)'
|
|
354
|
+
@d.lit(d / 1).should == '((SELECT a FROM items) / 1)'
|
|
355
|
+
|
|
356
|
+
@d.lit(d => 1).should == '((SELECT a FROM items) = 1)'
|
|
357
|
+
@d.lit(Sequel.~(d => 1)).should == '((SELECT a FROM items) != 1)'
|
|
358
|
+
@d.lit(d > 1).should == '((SELECT a FROM items) > 1)'
|
|
359
|
+
@d.lit(d < 1).should == '((SELECT a FROM items) < 1)'
|
|
360
|
+
@d.lit(d >= 1).should == '((SELECT a FROM items) >= 1)'
|
|
361
|
+
@d.lit(d <= 1).should == '((SELECT a FROM items) <= 1)'
|
|
362
|
+
|
|
363
|
+
@d.lit(d.as(:b)).should == '(SELECT a FROM items) AS b'
|
|
364
|
+
|
|
365
|
+
@d.lit(d & :b).should == '((SELECT a FROM items) AND b)'
|
|
366
|
+
@d.lit(d | :b).should == '((SELECT a FROM items) OR b)'
|
|
367
|
+
@d.lit(~d).should == 'NOT (SELECT a FROM items)'
|
|
368
|
+
|
|
369
|
+
@d.lit(d.cast(Integer)).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
370
|
+
@d.lit(d.cast_numeric).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
371
|
+
@d.lit(d.cast_string).should == 'CAST((SELECT a FROM items) AS varchar(255))'
|
|
372
|
+
@d.lit(d.cast_numeric << :b).should == '(CAST((SELECT a FROM items) AS integer) << b)'
|
|
373
|
+
@d.lit(d.cast_string + :b).should == '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
|
|
374
|
+
|
|
375
|
+
@d.lit(d.extract(:year)).should == 'extract(year FROM (SELECT a FROM items))'
|
|
376
|
+
@d.lit(d.sql_boolean & :b).should == '((SELECT a FROM items) AND b)'
|
|
377
|
+
@d.lit(d.sql_number << :b).should == '((SELECT a FROM items) << b)'
|
|
378
|
+
@d.lit(d.sql_string + :b).should == '((SELECT a FROM items) || b)'
|
|
379
|
+
|
|
380
|
+
@d.lit(d.asc).should == '(SELECT a FROM items) ASC'
|
|
381
|
+
@d.lit(d.desc).should == '(SELECT a FROM items) DESC'
|
|
382
|
+
|
|
383
|
+
@d.lit(d.like(:b)).should == '((SELECT a FROM items) LIKE b)'
|
|
384
|
+
@d.lit(d.ilike(:b)).should == '((SELECT a FROM items) ILIKE b)'
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it "should handled emulated char_length function" do
|
|
388
|
+
@d.lit(Sequel.char_length(:a)).should == 'char_length(a)'
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "should handled emulated trim function" do
|
|
392
|
+
@d.lit(Sequel.trim(:a)).should == 'trim(a)'
|
|
481
393
|
end
|
|
482
394
|
end
|
|
483
395
|
|
|
@@ -553,7 +465,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
553
465
|
end
|
|
554
466
|
|
|
555
467
|
it "should support :frame=>:rows option for window function calls" do
|
|
556
|
-
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
|
|
468
|
+
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
557
469
|
end
|
|
558
470
|
|
|
559
471
|
it "should support :frame=>'some string' option for window function calls" do
|
|
@@ -565,7 +477,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
565
477
|
end
|
|
566
478
|
|
|
567
479
|
it "should support all these options together" do
|
|
568
|
-
@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS UNBOUNDED PRECEDING)'
|
|
480
|
+
@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
569
481
|
end
|
|
570
482
|
|
|
571
483
|
it "should raise an error if window functions are not supported" do
|
|
@@ -596,4 +508,448 @@ describe Sequel::SQL::VirtualRow do
|
|
|
596
508
|
Sequel::BasicObject.remove_methods!
|
|
597
509
|
@d.l{a > adsoiwemlsdaf2}.should == '("a" > "adsoiwemlsdaf2")'
|
|
598
510
|
end
|
|
511
|
+
|
|
512
|
+
it "should have operator methods defined that produce Sequel expression objects" do
|
|
513
|
+
@d.l{|o| o.&({:a=>1}, :b)}.should == '(("a" = 1) AND "b")'
|
|
514
|
+
@d.l{|o| o.|({:a=>1}, :b)}.should == '(("a" = 1) OR "b")'
|
|
515
|
+
@d.l{|o| o.+(1, :b) > 2}.should == '((1 + "b") > 2)'
|
|
516
|
+
@d.l{|o| o.-(1, :b) < 2}.should == '((1 - "b") < 2)'
|
|
517
|
+
@d.l{|o| o.*(1, :b) >= 2}.should == '((1 * "b") >= 2)'
|
|
518
|
+
@d.l{|o| o./(1, :b) <= 2}.should == '((1 / "b") <= 2)'
|
|
519
|
+
@d.l{|o| o.~(:a=>1)}.should == '("a" != 1)'
|
|
520
|
+
@d.l{|o| o.~([[:a, 1], [:b, 2]])}.should == '(("a" != 1) OR ("b" != 2))'
|
|
521
|
+
@d.l{|o| o.<(1, :b)}.should == '(1 < "b")'
|
|
522
|
+
@d.l{|o| o.>(1, :b)}.should == '(1 > "b")'
|
|
523
|
+
@d.l{|o| o.<=(1, :b)}.should == '(1 <= "b")'
|
|
524
|
+
@d.l{|o| o.>=(1, :b)}.should == '(1 >= "b")'
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it "should have have ` produce literal strings" do
|
|
528
|
+
@d.l{a > `some SQL`}.should == '("a" > some SQL)'
|
|
529
|
+
@d.l{|o| o.a > o.`('some SQL')}.should == '("a" > some SQL)' #`
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
describe "Sequel core extension replacements" do
|
|
534
|
+
before do
|
|
535
|
+
@db = Sequel::Database.new
|
|
536
|
+
@ds = @db.dataset
|
|
537
|
+
def @ds.supports_regexp?; true end
|
|
538
|
+
@o = Object.new
|
|
539
|
+
def @o.sql_literal(ds) 'foo' end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def l(arg, should)
|
|
543
|
+
@ds.literal(arg).should == should
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
it "Sequel.expr should return items wrapped in Sequel objects" do
|
|
547
|
+
Sequel.expr(1).should be_a_kind_of(Sequel::SQL::NumericExpression)
|
|
548
|
+
Sequel.expr('a').should be_a_kind_of(Sequel::SQL::StringExpression)
|
|
549
|
+
Sequel.expr(true).should be_a_kind_of(Sequel::SQL::BooleanExpression)
|
|
550
|
+
Sequel.expr(nil).should be_a_kind_of(Sequel::SQL::Wrapper)
|
|
551
|
+
Sequel.expr({1=>2}).should be_a_kind_of(Sequel::SQL::BooleanExpression)
|
|
552
|
+
Sequel.expr([[1, 2]]).should be_a_kind_of(Sequel::SQL::BooleanExpression)
|
|
553
|
+
Sequel.expr([1]).should be_a_kind_of(Sequel::SQL::Wrapper)
|
|
554
|
+
Sequel.expr{|o| o.should be_a_kind_of(Sequel::SQL::VirtualRow)}
|
|
555
|
+
Sequel.expr{self.should be_a_kind_of(Sequel::SQL::VirtualRow)}
|
|
556
|
+
Sequel.expr(:a).should be_a_kind_of(Sequel::SQL::Identifier)
|
|
557
|
+
Sequel.expr(:a__b).should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
|
|
558
|
+
Sequel.expr(:a___c).should be_a_kind_of(Sequel::SQL::AliasedExpression)
|
|
559
|
+
Sequel.expr(:a___c).expression.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
560
|
+
Sequel.expr(:a__b___c).should be_a_kind_of(Sequel::SQL::AliasedExpression)
|
|
561
|
+
Sequel.expr(:a__b___c).expression.should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
it "Sequel.expr should return an appropriate wrapped object" do
|
|
565
|
+
l(Sequel.expr(1) + 1, "(1 + 1)")
|
|
566
|
+
l(Sequel.expr('a') + 'b', "('a' || 'b')")
|
|
567
|
+
l(Sequel.expr(:b) & nil, "(b AND NULL)")
|
|
568
|
+
l(Sequel.expr(nil) & true, "(NULL AND 't')")
|
|
569
|
+
l(Sequel.expr(false) & true, "('f' AND 't')")
|
|
570
|
+
l(Sequel.expr(true) | false, "('t' OR 'f')")
|
|
571
|
+
l(Sequel.expr(@o) + 1, "(foo + 1)")
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
it "Sequel.expr should handle condition specifiers" do
|
|
575
|
+
l(Sequel.expr(:a=>1) & nil, "((a = 1) AND NULL)")
|
|
576
|
+
l(Sequel.expr([[:a, 1]]) & nil, "((a = 1) AND NULL)")
|
|
577
|
+
l(Sequel.expr([[:a, 1], [:b, 2]]) & nil, "((a = 1) AND (b = 2) AND NULL)")
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it "Sequel.expr should handle arrays that are not condition specifiers" do
|
|
581
|
+
l(Sequel.expr([1]), "(1)")
|
|
582
|
+
l(Sequel.expr([1, 2]), "(1, 2)")
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
it "Sequel.expr should treat blocks/procs as virtual rows and wrap the output" do
|
|
586
|
+
l(Sequel.expr{1} + 1, "(1 + 1)")
|
|
587
|
+
l(Sequel.expr{o__a} + 1, "(o.a + 1)")
|
|
588
|
+
l(Sequel.expr{[[:a, 1]]} & nil, "((a = 1) AND NULL)")
|
|
589
|
+
l(Sequel.expr{|v| @o} + 1, "(foo + 1)")
|
|
590
|
+
|
|
591
|
+
l(Sequel.expr(proc{1}) + 1, "(1 + 1)")
|
|
592
|
+
l(Sequel.expr(proc{o__a}) + 1, "(o.a + 1)")
|
|
593
|
+
l(Sequel.expr(proc{[[:a, 1]]}) & nil, "((a = 1) AND NULL)")
|
|
594
|
+
l(Sequel.expr(proc{|v| @o}) + 1, "(foo + 1)")
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
it "Sequel.expr should raise an error if given an argument and a block" do
|
|
598
|
+
proc{Sequel.expr(nil){}}.should raise_error(Sequel::Error)
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
it "Sequel.expr should raise an error if given neither an argument nor a block" do
|
|
602
|
+
proc{Sequel.expr}.should raise_error(Sequel::Error)
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
it "Sequel.expr should return existing Sequel expressions directly" do
|
|
606
|
+
o = Sequel.expr(1)
|
|
607
|
+
Sequel.expr(o).should equal(o)
|
|
608
|
+
o = Sequel.lit('1')
|
|
609
|
+
Sequel.expr(o).should equal(o)
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
it "Sequel.~ should invert the given object" do
|
|
613
|
+
l(Sequel.~(nil), 'NOT NULL')
|
|
614
|
+
l(Sequel.~(:a=>1), "(a != 1)")
|
|
615
|
+
l(Sequel.~([[:a, 1]]), "(a != 1)")
|
|
616
|
+
l(Sequel.~([[:a, 1], [:b, 2]]), "((a != 1) OR (b != 2))")
|
|
617
|
+
l(Sequel.~(Sequel.expr([[:a, 1], [:b, 2]]) & nil), "((a != 1) OR (b != 2) OR NOT NULL)")
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
it "Sequel.case should use a CASE expression" do
|
|
621
|
+
l(Sequel.case({:a=>1}, 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
|
|
622
|
+
l(Sequel.case({:a=>1}, 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
|
|
623
|
+
l(Sequel.case([[:a, 1]], 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
|
|
624
|
+
l(Sequel.case([[:a, 1]], 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
|
|
625
|
+
l(Sequel.case([[:a, 1], [:c, 3]], 2), "(CASE WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
|
|
626
|
+
l(Sequel.case([[:a, 1], [:c, 3]], 2, :b), "(CASE b WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it "Sequel.case should raise an error if not given a condition specifier" do
|
|
630
|
+
proc{Sequel.case(1, 2)}.should raise_error(Sequel::Error)
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
it "Sequel.value_list should use an SQL value list" do
|
|
634
|
+
l(Sequel.value_list([[1, 2]]), "((1, 2))")
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
it "Sequel.value_list raise an error if not given an array" do
|
|
638
|
+
proc{Sequel.value_list(1)}.should raise_error(Sequel::Error)
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
it "Sequel.negate should negate all entries in conditions specifier and join with AND" do
|
|
642
|
+
l(Sequel.negate(:a=>1), "(a != 1)")
|
|
643
|
+
l(Sequel.negate([[:a, 1]]), "(a != 1)")
|
|
644
|
+
l(Sequel.negate([[:a, 1], [:b, 2]]), "((a != 1) AND (b != 2))")
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
it "Sequel.negate should raise an error if not given a conditions specifier" do
|
|
648
|
+
proc{Sequel.negate(1)}.should raise_error(Sequel::Error)
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it "Sequel.or should join all entries in conditions specifier with OR" do
|
|
652
|
+
l(Sequel.or(:a=>1), "(a = 1)")
|
|
653
|
+
l(Sequel.or([[:a, 1]]), "(a = 1)")
|
|
654
|
+
l(Sequel.or([[:a, 1], [:b, 2]]), "((a = 1) OR (b = 2))")
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
it "Sequel.or should raise an error if not given a conditions specifier" do
|
|
658
|
+
proc{Sequel.or(1)}.should raise_error(Sequel::Error)
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
it "Sequel.join should should use SQL string concatenation to join array" do
|
|
662
|
+
l(Sequel.join([]), "''")
|
|
663
|
+
l(Sequel.join(['a']), "('a')")
|
|
664
|
+
l(Sequel.join(['a', 'b']), "('a' || 'b')")
|
|
665
|
+
l(Sequel.join(['a', 'b'], 'c'), "('a' || 'c' || 'b')")
|
|
666
|
+
l(Sequel.join([true, :b], :c), "('t' || c || b)")
|
|
667
|
+
l(Sequel.join([false, nil], Sequel.lit('c')), "('f' || c || NULL)")
|
|
668
|
+
l(Sequel.join([Sequel.expr('a'), Sequel.lit('d')], 'c'), "('a' || 'c' || d)")
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
it "Sequel.join should raise an error if not given an array" do
|
|
672
|
+
proc{Sequel.join(1)}.should raise_error(Sequel::Error)
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
it "Sequel.& should join all arguments given with AND" do
|
|
676
|
+
l(Sequel.&(:a), "(a)")
|
|
677
|
+
l(Sequel.&(:a, :b=>:c), "(a AND (b = c))")
|
|
678
|
+
l(Sequel.&(:a, {:b=>:c}, Sequel.lit('d')), "(a AND (b = c) AND d)")
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
it "Sequel.& should raise an error if given no arguments" do
|
|
682
|
+
proc{Sequel.&}.should raise_error(Sequel::Error)
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
it "Sequel.| should join all arguments given with OR" do
|
|
686
|
+
l(Sequel.|(:a), "(a)")
|
|
687
|
+
l(Sequel.|(:a, :b=>:c), "(a OR (b = c))")
|
|
688
|
+
l(Sequel.|(:a, {:b=>:c}, Sequel.lit('d')), "(a OR (b = c) OR d)")
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
it "Sequel.| should raise an error if given no arguments" do
|
|
692
|
+
proc{Sequel.|}.should raise_error(Sequel::Error)
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
it "Sequel.as should return an aliased expression" do
|
|
696
|
+
l(Sequel.as(:a, :b), "a AS b")
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
it "Sequel.cast should return a CAST expression" do
|
|
700
|
+
l(Sequel.cast(:a, :int), "CAST(a AS int)")
|
|
701
|
+
l(Sequel.cast(:a, Integer), "CAST(a AS integer)")
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
it "Sequel.cast_numeric should return a CAST expression treated as a number" do
|
|
705
|
+
l(Sequel.cast_numeric(:a), "CAST(a AS integer)")
|
|
706
|
+
l(Sequel.cast_numeric(:a, :int), "CAST(a AS int)")
|
|
707
|
+
l(Sequel.cast_numeric(:a) << 2, "(CAST(a AS integer) << 2)")
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
it "Sequel.cast_string should return a CAST expression treated as a string" do
|
|
711
|
+
l(Sequel.cast_string(:a), "CAST(a AS varchar(255))")
|
|
712
|
+
l(Sequel.cast_string(:a, :text), "CAST(a AS text)")
|
|
713
|
+
l(Sequel.cast_string(:a) + 'a', "(CAST(a AS varchar(255)) || 'a')")
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
it "Sequel.lit should return a literal string" do
|
|
717
|
+
l(Sequel.lit('a'), "a")
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
it "Sequel.lit should return the argument if given a single literal string" do
|
|
721
|
+
o = Sequel.lit('a')
|
|
722
|
+
Sequel.lit(o).should equal(o)
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
it "Sequel.lit should accept multiple arguments for a placeholder literal string" do
|
|
726
|
+
l(Sequel.lit('a = ?', 1), "a = 1")
|
|
727
|
+
l(Sequel.lit('? = ?', :a, 1), "a = 1")
|
|
728
|
+
l(Sequel.lit('a = :a', :a=>1), "a = 1")
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
it "Sequel.lit should work with an array for the placeholder string" do
|
|
732
|
+
l(Sequel.lit(['a = '], 1), "a = 1")
|
|
733
|
+
l(Sequel.lit(['', ' = '], :a, 1), "a = 1")
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
it "Sequel.blob should return an SQL::Blob" do
|
|
737
|
+
l(Sequel.blob('a'), "'a'")
|
|
738
|
+
Sequel.blob('a').should be_a_kind_of(Sequel::SQL::Blob)
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
it "Sequel.blob should return the given argument if given a blob" do
|
|
742
|
+
o = Sequel.blob('a')
|
|
743
|
+
Sequel.blob(o).should equal(o)
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
it "Sequel.qualify should return a qualified identifier" do
|
|
747
|
+
l(Sequel.qualify(:t, :c), "t.c")
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
it "Sequel.identifier should return an identifier" do
|
|
751
|
+
l(Sequel.identifier(:t__c), "t__c")
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
it "Sequel.asc should return an ASC ordered expression" do
|
|
755
|
+
l(Sequel.asc(:a), "a ASC")
|
|
756
|
+
l(Sequel.asc(:a, :nulls=>:first), "a ASC NULLS FIRST")
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
it "Sequel.desc should return a DESC ordered expression " do
|
|
760
|
+
l(Sequel.desc(:a), "a DESC")
|
|
761
|
+
l(Sequel.desc(:a, :nulls=>:last), "a DESC NULLS LAST")
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
it "Sequel.{+,-,*,/} should accept arguments and use the appropriate operator" do
|
|
765
|
+
%w'+ - * /'.each do |op|
|
|
766
|
+
l(Sequel.send(op, 1), '(1)')
|
|
767
|
+
l(Sequel.send(op, 1, 2), "(1 #{op} 2)")
|
|
768
|
+
l(Sequel.send(op, 1, 2, 3), "(1 #{op} 2 #{op} 3)")
|
|
769
|
+
end
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
it "Sequel.{+,-,*,/} should raise if given no arguments" do
|
|
773
|
+
%w'+ - * /'.each do |op|
|
|
774
|
+
proc{Sequel.send(op)}.should raise_error(Sequel::Error)
|
|
775
|
+
end
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
it "Sequel.like should use a LIKE expression" do
|
|
779
|
+
l(Sequel.like('a', 'b'), "('a' LIKE 'b')")
|
|
780
|
+
l(Sequel.like(:a, :b), "(a LIKE b)")
|
|
781
|
+
l(Sequel.like(:a, /b/), "(a ~ 'b')")
|
|
782
|
+
l(Sequel.like(:a, 'c', /b/), "((a LIKE 'c') OR (a ~ 'b'))")
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
it "Sequel.ilike should use an ILIKE expression" do
|
|
786
|
+
l(Sequel.ilike('a', 'b'), "('a' ILIKE 'b')")
|
|
787
|
+
l(Sequel.ilike(:a, :b), "(a ILIKE b)")
|
|
788
|
+
l(Sequel.ilike(:a, /b/), "(a ~* 'b')")
|
|
789
|
+
l(Sequel.ilike(:a, 'c', /b/), "((a ILIKE 'c') OR (a ~* 'b'))")
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
it "Sequel.subscript should use an SQL subscript" do
|
|
793
|
+
l(Sequel.subscript(:a, 1), 'a[1]')
|
|
794
|
+
l(Sequel.subscript(:a, 1, 2), 'a[1, 2]')
|
|
795
|
+
l(Sequel.subscript(:a, [1, 2]), 'a[1, 2]')
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
it "Sequel.function should return an SQL function" do
|
|
799
|
+
l(Sequel.function(:a), 'a()')
|
|
800
|
+
l(Sequel.function(:a, 1), 'a(1)')
|
|
801
|
+
l(Sequel.function(:a, :b, 2), 'a(b, 2)')
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
it "Sequel.extract should use a date/time extraction" do
|
|
805
|
+
l(Sequel.extract(:year, :a), 'extract(year FROM a)')
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
it "#* with no arguments should use a ColumnAll for Identifier and QualifiedIdentifier" do
|
|
809
|
+
l(Sequel.expr(:a).*, 'a.*')
|
|
810
|
+
l(Sequel.expr(:a__b).*, 'a.b.*')
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
it "SQL::Blob should be aliasable and castable by default" do
|
|
814
|
+
b = Sequel.blob('a')
|
|
815
|
+
l(b.as(:a), "'a' AS a")
|
|
816
|
+
l(b.cast(Integer), "CAST('a' AS integer)")
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
it "SQL::Blob should be convertable to a literal string by default" do
|
|
820
|
+
b = Sequel.blob('a ?')
|
|
821
|
+
l(b.lit, "a ?")
|
|
822
|
+
l(b.lit(1), "a 1")
|
|
823
|
+
end
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
describe "Sequel::SQL::Function#==" do
|
|
827
|
+
specify "should be true for functions with the same name and arguments, false otherwise" do
|
|
828
|
+
a = Sequel.function(:date, :t)
|
|
829
|
+
b = Sequel.function(:date, :t)
|
|
830
|
+
a.should == b
|
|
831
|
+
(a == b).should == true
|
|
832
|
+
c = Sequel.function(:date, :c)
|
|
833
|
+
a.should_not == c
|
|
834
|
+
(a == c).should == false
|
|
835
|
+
d = Sequel.function(:time, :c)
|
|
836
|
+
a.should_not == d
|
|
837
|
+
c.should_not == d
|
|
838
|
+
(a == d).should == false
|
|
839
|
+
(c == d).should == false
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
describe "Sequel::SQL::OrderedExpression" do
|
|
844
|
+
specify "should #desc" do
|
|
845
|
+
@oe = Sequel.asc(:column)
|
|
846
|
+
@oe.descending.should == false
|
|
847
|
+
@oe.desc.descending.should == true
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
specify "should #asc" do
|
|
851
|
+
@oe = Sequel.desc(:column)
|
|
852
|
+
@oe.descending.should == true
|
|
853
|
+
@oe.asc.descending.should == false
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
specify "should #invert" do
|
|
857
|
+
@oe = Sequel.desc(:column)
|
|
858
|
+
@oe.invert.descending.should == false
|
|
859
|
+
@oe.invert.invert.descending.should == true
|
|
860
|
+
end
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
describe "Expression" do
|
|
864
|
+
specify "should consider objects == only if they have the same attributes" do
|
|
865
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.should == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
866
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.should_not == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
867
|
+
|
|
868
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.should eql(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
|
|
869
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.should_not eql(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
|
|
870
|
+
end
|
|
871
|
+
|
|
872
|
+
specify "should use the same hash value for objects that have the same attributes" do
|
|
873
|
+
Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash.should == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
|
|
874
|
+
Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.hash.should_not == Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
|
|
875
|
+
|
|
876
|
+
h = {}
|
|
877
|
+
a = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
878
|
+
b = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
|
|
879
|
+
h[a] = 1
|
|
880
|
+
h[b] = 2
|
|
881
|
+
h[a].should == 2
|
|
882
|
+
h[b].should == 2
|
|
883
|
+
end
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
describe "Sequel::SQLTime" do
|
|
887
|
+
before do
|
|
888
|
+
@db = Sequel.mock
|
|
889
|
+
end
|
|
890
|
+
|
|
891
|
+
specify ".create should create from hour, minutes, seconds and optional microseconds" do
|
|
892
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3)).should == "'01:02:03.000000'"
|
|
893
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).should == "'01:02:03.500000'"
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
describe "Sequel::SQL::Wrapper" do
|
|
898
|
+
before do
|
|
899
|
+
@ds = Sequel.mock.dataset
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
specify "should wrap objects so they can be used by the Sequel DSL" do
|
|
903
|
+
o = Object.new
|
|
904
|
+
def o.sql_literal(ds) 'foo' end
|
|
905
|
+
s = Sequel::SQL::Wrapper.new(o)
|
|
906
|
+
@ds.literal(s).should == "foo"
|
|
907
|
+
@ds.literal(s+1).should == "(foo + 1)"
|
|
908
|
+
@ds.literal(s & true).should == "(foo AND 't')"
|
|
909
|
+
@ds.literal(s < 1).should == "(foo < 1)"
|
|
910
|
+
@ds.literal(s.sql_subscript(1)).should == "foo[1]"
|
|
911
|
+
@ds.literal(s.like('a')).should == "(foo LIKE 'a')"
|
|
912
|
+
@ds.literal(s.as(:a)).should == "foo AS a"
|
|
913
|
+
@ds.literal(s.cast(Integer)).should == "CAST(foo AS integer)"
|
|
914
|
+
@ds.literal(s.desc).should == "foo DESC"
|
|
915
|
+
@ds.literal(s.sql_string + '1').should == "(foo || '1')"
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
describe "Sequel::SQL::Blob#to_sequel_blob" do
|
|
920
|
+
specify "should return self" do
|
|
921
|
+
c = Sequel::SQL::Blob.new('a')
|
|
922
|
+
c.to_sequel_blob.should equal(c)
|
|
923
|
+
end
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
describe Sequel::SQL::Subscript do
|
|
927
|
+
before do
|
|
928
|
+
@s = Sequel::SQL::Subscript.new(:a, [1])
|
|
929
|
+
@ds = Sequel::Dataset.new(nil)
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
specify "should have | return a new non-nested subscript" do
|
|
933
|
+
s = (@s | 2)
|
|
934
|
+
s.should_not equal(@s)
|
|
935
|
+
@ds.literal(s).should == 'a[1, 2]'
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
specify "should have [] return a new nested subscript" do
|
|
939
|
+
s = @s[2]
|
|
940
|
+
s.should_not equal(@s)
|
|
941
|
+
@ds.literal(s).should == 'a[1][2]'
|
|
942
|
+
end
|
|
943
|
+
end
|
|
944
|
+
|
|
945
|
+
describe "Sequel.recursive_map" do
|
|
946
|
+
specify "should recursively convert an array using a callable" do
|
|
947
|
+
Sequel.recursive_map(['1'], proc{|s| s.to_i}).should == [1]
|
|
948
|
+
Sequel.recursive_map([['1']], proc{|s| s.to_i}).should == [[1]]
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
specify "should not call callable if value is nil" do
|
|
952
|
+
Sequel.recursive_map([nil], proc{|s| s.to_i}).should == [nil]
|
|
953
|
+
Sequel.recursive_map([[nil]], proc{|s| s.to_i}).should == [[nil]]
|
|
954
|
+
end
|
|
599
955
|
end
|