sequel 3.21.0 → 3.36.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 +855 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -7
- data/Rakefile +42 -24
- data/bin/sequel +26 -8
- data/doc/active_record.rdoc +1 -0
- data/doc/advanced_associations.rdoc +171 -11
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +85 -552
- data/doc/model_hooks.rdoc +78 -27
- data/doc/object_model.rdoc +541 -0
- data/doc/opening_databases.rdoc +97 -50
- data/doc/prepared_statements.rdoc +40 -14
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +30 -4
- 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/schema_modification.rdoc +572 -0
- data/doc/sharding.rdoc +95 -3
- data/doc/testing.rdoc +129 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +51 -2
- 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 +1 -57
- 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 +47 -0
- data/lib/sequel/adapters/jdbc/derby.rb +287 -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 +29 -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 +58 -48
- 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 +265 -94
- data/lib/sequel/adapters/mock.rb +361 -0
- data/lib/sequel/adapters/mysql.rb +118 -222
- data/lib/sequel/adapters/mysql2.rb +58 -57
- data/lib/sequel/adapters/odbc/mssql.rb +15 -7
- 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 +356 -107
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +342 -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 +335 -118
- data/lib/sequel/adapters/shared/mysql.rb +340 -76
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +243 -45
- data/lib/sequel/adapters/shared/postgres.rb +524 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +265 -89
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +9 -12
- data/lib/sequel/adapters/swift/postgres.rb +9 -74
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +8 -7
- data/lib/sequel/adapters/tinytds.rb +161 -21
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -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 +28 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +38 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +118 -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 +150 -46
- data/lib/sequel/database/query.rb +215 -65
- data/lib/sequel/database/schema_generator.rb +64 -20
- data/lib/sequel/database/schema_methods.rb +212 -54
- data/lib/sequel/dataset/actions.rb +322 -85
- data/lib/sequel/dataset/features.rb +96 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +237 -44
- data/lib/sequel/dataset/sql.rb +698 -278
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
- data/lib/sequel/extensions/migration.rb +97 -11
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_inet.rb +89 -0
- data/lib/sequel/extensions/pg_json.rb +178 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query.rb +1 -1
- 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 +251 -37
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1187 -393
- data/lib/sequel/model/base.rb +578 -170
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- 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/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -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 +123 -8
- 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 +12 -2
- data/lib/sequel/plugins/many_through_many.rb +79 -28
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +139 -63
- data/lib/sequel/plugins/optimistic_locking.rb +8 -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 +29 -15
- data/lib/sequel/plugins/schema.rb +7 -2
- 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 +10 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- 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/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +526 -59
- data/lib/sequel/timezones.rb +57 -38
- 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 +142 -40
- data/spec/adapters/mysql_spec.rb +380 -234
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +1050 -212
- data/spec/adapters/spec_helper.rb +8 -5
- data/spec/adapters/sqlite_spec.rb +139 -27
- data/spec/core/connection_pool_spec.rb +196 -93
- data/spec/core/database_spec.rb +879 -510
- data/spec/core/dataset_spec.rb +1415 -1086
- data/spec/core/expression_filters_spec.rb +554 -109
- data/spec/core/mock_adapter_spec.rb +449 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +482 -38
- data/spec/core/spec_helper.rb +6 -48
- 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/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/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +69 -92
- data/spec/extensions/identity_map_spec.rb +131 -22
- 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 -6
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +48 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- 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 +251 -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 +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_inet_spec.rb +44 -0
- data/spec/extensions/pg_json_spec.rb +101 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -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 +168 -0
- data/spec/extensions/query_spec.rb +6 -0
- 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 +429 -22
- data/spec/extensions/schema_spec.rb +25 -21
- 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 +85 -43
- 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 +22 -61
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -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 +4 -7
- 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 +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- 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 +9 -3
- data/spec/integration/dataset_test.rb +605 -91
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +454 -143
- data/spec/integration/prepared_statement_test.rb +263 -128
- data/spec/integration/schema_test.rb +309 -43
- data/spec/integration/spec_helper.rb +40 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +18 -4
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +1067 -661
- data/spec/model/base_spec.rb +329 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +240 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +490 -232
- data/spec/model/spec_helper.rb +14 -71
- data/spec/model/validations_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- metadata +178 -80
|
@@ -6,7 +6,6 @@ String.send(:include, Sequel::SQL::StringMethods)
|
|
|
6
6
|
describe "Blockless Ruby Filters" do
|
|
7
7
|
before do
|
|
8
8
|
db = Sequel::Database.new
|
|
9
|
-
db.quote_identifiers = false
|
|
10
9
|
@d = db[:items]
|
|
11
10
|
def @d.l(*args, &block)
|
|
12
11
|
literal(filter_expr(*args, &block))
|
|
@@ -186,31 +185,26 @@ describe "Blockless Ruby Filters" do
|
|
|
186
185
|
@d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
|
|
187
186
|
end
|
|
188
187
|
|
|
189
|
-
it "should not
|
|
190
|
-
proc{~:x.sql_string}.should raise_error
|
|
191
|
-
proc{~([:x, :y].sql_string_join)}.should raise_error
|
|
188
|
+
it "should not add ~ method to string expressions" do
|
|
189
|
+
proc{~:x.sql_string}.should raise_error(NoMethodError)
|
|
192
190
|
end
|
|
193
191
|
|
|
194
|
-
it "should
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
192
|
+
it "should allow mathematical or string operations on true, false, or nil" do
|
|
193
|
+
@d.lit(:x + 1).should == '(x + 1)'
|
|
194
|
+
@d.lit(:x - true).should == "(x - 't')"
|
|
195
|
+
@d.lit(:x / false).should == "(x / 'f')"
|
|
196
|
+
@d.lit(:x * nil).should == '(x * NULL)'
|
|
197
|
+
@d.lit([:x, nil].sql_string_join).should == '(x || NULL)'
|
|
200
198
|
end
|
|
201
199
|
|
|
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)
|
|
200
|
+
it "should allow mathematical or string operations on boolean complex expressions" do
|
|
201
|
+
@d.lit(:x + (:y + 1)).should == '(x + y + 1)'
|
|
202
|
+
@d.lit(:x - ~:y).should == '(x - NOT y)'
|
|
203
|
+
@d.lit(:x / (:y & :z)).should == '(x / (y AND z))'
|
|
204
|
+
@d.lit(:x * (:y | :z)).should == '(x * (y OR z))'
|
|
205
|
+
@d.lit(:x + :y.like('a')).should == "(x + (y LIKE 'a'))"
|
|
206
|
+
@d.lit(:x - ~:y.like('a')).should == "(x - (y NOT LIKE 'a'))"
|
|
207
|
+
@d.lit([:x, ~:y.like('a')].sql_string_join).should == "(x || (y NOT LIKE 'a'))"
|
|
214
208
|
end
|
|
215
209
|
|
|
216
210
|
it "should support AND conditions via &" do
|
|
@@ -218,8 +212,6 @@ describe "Blockless Ruby Filters" do
|
|
|
218
212
|
@d.l(:x.sql_boolean & :y).should == '(x AND y)'
|
|
219
213
|
@d.l(:x & :y & :z).should == '(x AND y AND z)'
|
|
220
214
|
@d.l(:x & {:y => :z}).should == '(x AND (y = z))'
|
|
221
|
-
@d.l({:y => :z} & :x).should == '((y = z) AND x)'
|
|
222
|
-
@d.l({:x => :a} & {:y => :z}).should == '((x = a) AND (y = z))'
|
|
223
215
|
@d.l((:x + 200 < 0) & (:y - 200 < 0)).should == '(((x + 200) < 0) AND ((y - 200) < 0))'
|
|
224
216
|
@d.l(:x & ~:y).should == '(x AND NOT y)'
|
|
225
217
|
@d.l(~:x & :y).should == '(NOT x AND y)'
|
|
@@ -231,8 +223,6 @@ describe "Blockless Ruby Filters" do
|
|
|
231
223
|
@d.l(:x.sql_boolean | :y).should == '(x OR y)'
|
|
232
224
|
@d.l(:x | :y | :z).should == '(x OR y OR z)'
|
|
233
225
|
@d.l(:x | {:y => :z}).should == '(x OR (y = z))'
|
|
234
|
-
@d.l({:y => :z} | :x).should == '((y = z) OR x)'
|
|
235
|
-
@d.l({:x => :a} | {:y => :z}).should == '((x = a) OR (y = z))'
|
|
236
226
|
@d.l((:x.sql_number > 200) | (:y.sql_number < 200)).should == '((x > 200) OR (y < 200))'
|
|
237
227
|
end
|
|
238
228
|
|
|
@@ -273,60 +263,12 @@ describe "Blockless Ruby Filters" do
|
|
|
273
263
|
@d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
|
|
274
264
|
end
|
|
275
265
|
|
|
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
266
|
it "should support arrays with all two pairs the same as hashes" do
|
|
301
267
|
@d.l([[:x, 100],[:y, 'a']]).should == '((x = 100) AND (y = \'a\'))'
|
|
302
268
|
@d.l([[:x, true], [:y, false]]).should == '((x IS TRUE) AND (y IS FALSE))'
|
|
303
269
|
@d.l([[:x, nil], [:y, [1,2,3]]]).should == '((x IS NULL) AND (y IN (1, 2, 3)))'
|
|
304
270
|
end
|
|
305
271
|
|
|
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
272
|
it "should emulate columns for array values" do
|
|
331
273
|
@d.l([:x, :y]=>[[1,2], [3,4]].sql_array).should == '((x, y) IN ((1, 2), (3, 4)))'
|
|
332
274
|
@d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
|
|
@@ -338,21 +280,6 @@ describe "Blockless Ruby Filters" do
|
|
|
338
280
|
@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
281
|
end
|
|
340
282
|
|
|
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
283
|
it "should support StringExpression#+ for concatenation of SQL strings" do
|
|
357
284
|
@d.lit(:x.sql_string + :y).should == '(x || y)'
|
|
358
285
|
@d.lit([:x].sql_string_join + :y).should == '(x || y)'
|
|
@@ -382,12 +309,12 @@ describe "Blockless Ruby Filters" do
|
|
|
382
309
|
@d.l((:x + 1) & (:x + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
|
|
383
310
|
end
|
|
384
311
|
|
|
385
|
-
it "should
|
|
386
|
-
|
|
312
|
+
it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
|
|
313
|
+
@d.lit((:x + 1) & (:x + '2')).should == "((x + 1) & (x || '2'))"
|
|
387
314
|
end
|
|
388
315
|
|
|
389
|
-
it "should
|
|
390
|
-
|
|
316
|
+
it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
|
|
317
|
+
@d.l(:x & (:x + '2')).should == "(x AND (x || '2'))"
|
|
391
318
|
end
|
|
392
319
|
|
|
393
320
|
it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
|
|
@@ -424,10 +351,94 @@ describe "Blockless Ruby Filters" do
|
|
|
424
351
|
@d.l(~{:x => Sequel::SQLFALSE}).should == '(x IS NOT FALSE)'
|
|
425
352
|
end
|
|
426
353
|
|
|
354
|
+
it "should support direct negation of SQL::Constants" do
|
|
355
|
+
@d.l({:x => ~Sequel::NULL}).should == '(x IS NOT NULL)'
|
|
356
|
+
@d.l({:x => ~Sequel::NOTNULL}).should == '(x IS NULL)'
|
|
357
|
+
@d.l({:x => ~Sequel::TRUE}).should == '(x IS FALSE)'
|
|
358
|
+
@d.l({:x => ~Sequel::FALSE}).should == '(x IS TRUE)'
|
|
359
|
+
@d.l({:x => ~Sequel::SQLTRUE}).should == '(x IS FALSE)'
|
|
360
|
+
@d.l({:x => ~Sequel::SQLFALSE}).should == '(x IS TRUE)'
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "should raise an error if trying to invert an invalid SQL::Constant" do
|
|
364
|
+
proc{~Sequel::CURRENT_DATE}.should raise_error(Sequel::Error)
|
|
365
|
+
end
|
|
366
|
+
|
|
427
367
|
it "should raise an error if trying to create an invalid complex expression" do
|
|
428
368
|
proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.should raise_error(Sequel::Error)
|
|
429
369
|
end
|
|
430
370
|
|
|
371
|
+
it "should use a string concatentation for + if given a string" do
|
|
372
|
+
@d.lit(:x + '1').should == "(x || '1')"
|
|
373
|
+
@d.lit(:x + '1' + '1').should == "(x || '1' || '1')"
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "should use an addition for + if given a literal string" do
|
|
377
|
+
@d.lit(:x + '1'.lit).should == "(x + 1)"
|
|
378
|
+
@d.lit(:x + '1'.lit + '1'.lit).should == "(x + 1 + 1)"
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it "should use a bitwise operator for & and | if given an integer" do
|
|
382
|
+
@d.lit(:x & 1).should == "(x & 1)"
|
|
383
|
+
@d.lit(:x | 1).should == "(x | 1)"
|
|
384
|
+
@d.lit(:x & 1 & 1).should == "(x & 1 & 1)"
|
|
385
|
+
@d.lit(:x | 1 | 1).should == "(x | 1 | 1)"
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
it "should allow adding a string to an integer expression" do
|
|
389
|
+
@d.lit(:x + 1 + 'a').should == "(x + 1 + 'a')"
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "should allow adding an integer to an string expression" do
|
|
393
|
+
@d.lit(:x + 'a' + 1).should == "(x || 'a' || 1)"
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it "should allow adding a boolean to an integer expression" do
|
|
397
|
+
@d.lit(:x + 1 + true).should == "(x + 1 + 't')"
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
it "should allow adding a boolean to an string expression" do
|
|
401
|
+
@d.lit(:x + 'a' + true).should == "(x || 'a' || 't')"
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
it "should allow using a boolean operation with an integer on an boolean expression" do
|
|
405
|
+
@d.lit(:x & :a & 1).should == "(x AND a AND 1)"
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
it "should allow using a boolean operation with a string on an boolean expression" do
|
|
409
|
+
@d.lit(:x & :a & 'a').should == "(x AND a AND 'a')"
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
it "should allowing AND of boolean expression and literal string" do
|
|
413
|
+
@d.lit(:x & :a & 'a'.lit).should == "(x AND a AND a)"
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
it "should allowing + of integer expression and literal string" do
|
|
417
|
+
@d.lit(:x + :a + 'a'.lit).should == "(x + a + a)"
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it "should allowing + of string expression and literal string" do
|
|
421
|
+
@d.lit(:x + 'a' + 'a'.lit).should == "(x || 'a' || a)"
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
it "should allow sql_{string,boolean,number} methods on numeric expressions" do
|
|
425
|
+
@d.lit((:x + 1).sql_string + 'a').should == "((x + 1) || 'a')"
|
|
426
|
+
@d.lit((:x + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
|
|
427
|
+
@d.lit((:x + 1).sql_number + 'a').should == "(x + 1 + 'a')"
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
it "should allow sql_{string,boolean,number} methods on string expressions" do
|
|
431
|
+
@d.lit((:x + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
|
|
432
|
+
@d.lit((:x + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
|
|
433
|
+
@d.lit((:x + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
it "should allow sql_{string,boolean,number} methods on boolean expressions" do
|
|
437
|
+
@d.lit((:x & :y).sql_string + 'a').should == "((x AND y) || 'a')"
|
|
438
|
+
@d.lit((:x & :y).sql_boolean & 1).should == "(x AND y AND 1)"
|
|
439
|
+
@d.lit((:x & :y).sql_number + 'a').should == "((x AND y) + 'a')"
|
|
440
|
+
end
|
|
441
|
+
|
|
431
442
|
it "should raise an error if trying to literalize an invalid complex expression" do
|
|
432
443
|
ce = :x + 1
|
|
433
444
|
ce.instance_variable_set(:@op, :BANG)
|
|
@@ -439,26 +450,65 @@ describe "Blockless Ruby Filters" do
|
|
|
439
450
|
e2 = ~:comment.like('%:hidden:%')
|
|
440
451
|
e1.should == e2
|
|
441
452
|
end
|
|
453
|
+
|
|
454
|
+
it "should support expression filter methods on Datasets" do
|
|
455
|
+
d = @d.select(:a)
|
|
456
|
+
|
|
457
|
+
@d.lit(d + 1).should == '((SELECT a FROM items) + 1)'
|
|
458
|
+
@d.lit(d - 1).should == '((SELECT a FROM items) - 1)'
|
|
459
|
+
@d.lit(d * 1).should == '((SELECT a FROM items) * 1)'
|
|
460
|
+
@d.lit(d / 1).should == '((SELECT a FROM items) / 1)'
|
|
461
|
+
|
|
462
|
+
@d.lit(d => 1).should == '((SELECT a FROM items) = 1)'
|
|
463
|
+
@d.lit(~{d => 1}).should == '((SELECT a FROM items) != 1)'
|
|
464
|
+
@d.lit(d > 1).should == '((SELECT a FROM items) > 1)'
|
|
465
|
+
@d.lit(d < 1).should == '((SELECT a FROM items) < 1)'
|
|
466
|
+
@d.lit(d >= 1).should == '((SELECT a FROM items) >= 1)'
|
|
467
|
+
@d.lit(d <= 1).should == '((SELECT a FROM items) <= 1)'
|
|
468
|
+
|
|
469
|
+
@d.lit(d.as(:b)).should == '(SELECT a FROM items) AS b'
|
|
470
|
+
|
|
471
|
+
@d.lit(d & :b).should == '((SELECT a FROM items) AND b)'
|
|
472
|
+
@d.lit(d | :b).should == '((SELECT a FROM items) OR b)'
|
|
473
|
+
@d.lit(~d).should == 'NOT (SELECT a FROM items)'
|
|
474
|
+
|
|
475
|
+
@d.lit(d.cast(Integer)).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
476
|
+
@d.lit(d.cast_numeric).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
477
|
+
@d.lit(d.cast_string).should == 'CAST((SELECT a FROM items) AS varchar(255))'
|
|
478
|
+
@d.lit(d.cast_numeric << :b).should == '(CAST((SELECT a FROM items) AS integer) << b)'
|
|
479
|
+
@d.lit(d.cast_string + :b).should == '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
|
|
480
|
+
|
|
481
|
+
@d.lit(d.extract(:year)).should == 'extract(year FROM (SELECT a FROM items))'
|
|
482
|
+
@d.lit(d.sql_boolean & :b).should == '((SELECT a FROM items) AND b)'
|
|
483
|
+
@d.lit(d.sql_number << :b).should == '((SELECT a FROM items) << b)'
|
|
484
|
+
@d.lit(d.sql_string + :b).should == '((SELECT a FROM items) || b)'
|
|
485
|
+
|
|
486
|
+
@d.lit(d.asc).should == '(SELECT a FROM items) ASC'
|
|
487
|
+
@d.lit(d.desc).should == '(SELECT a FROM items) DESC'
|
|
488
|
+
|
|
489
|
+
@d.lit(d.like(:b)).should == '((SELECT a FROM items) LIKE b)'
|
|
490
|
+
@d.lit(d.ilike(:b)).should == '((SELECT a FROM items) ILIKE b)'
|
|
491
|
+
end
|
|
442
492
|
|
|
443
493
|
if RUBY_VERSION < '1.9.0'
|
|
444
494
|
it "should not allow inequality operations on true, false, or nil" do
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
495
|
+
@d.lit(:x > 1).should == "(x > 1)"
|
|
496
|
+
@d.lit(:x < true).should == "(x < 't')"
|
|
497
|
+
@d.lit(:x >= false).should == "(x >= 'f')"
|
|
498
|
+
@d.lit(:x <= nil).should == "(x <= NULL)"
|
|
449
499
|
end
|
|
450
500
|
|
|
451
501
|
it "should not allow inequality operations on boolean complex expressions" do
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
502
|
+
@d.lit(:x > (:y > 5)).should == "(x > (y > 5))"
|
|
503
|
+
@d.lit(:x < (:y < 5)).should == "(x < (y < 5))"
|
|
504
|
+
@d.lit(:x >= (:y >= 5)).should == "(x >= (y >= 5))"
|
|
505
|
+
@d.lit(:x <= (:y <= 5)).should == "(x <= (y <= 5))"
|
|
506
|
+
@d.lit(:x > {:y => nil}).should == "(x > (y IS NULL))"
|
|
507
|
+
@d.lit(:x < ~{:y => nil}).should == "(x < (y IS NOT NULL))"
|
|
508
|
+
@d.lit(:x >= {:y => 5}).should == "(x >= (y = 5))"
|
|
509
|
+
@d.lit(:x <= ~{:y => 5}).should == "(x <= (y != 5))"
|
|
510
|
+
@d.lit(:x >= {:y => [1,2,3]}).should == "(x >= (y IN (1, 2, 3)))"
|
|
511
|
+
@d.lit(:x <= ~{:y => [1,2,3]}).should == "(x <= (y NOT IN (1, 2, 3)))"
|
|
462
512
|
end
|
|
463
513
|
|
|
464
514
|
it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
|
|
@@ -553,7 +603,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
553
603
|
end
|
|
554
604
|
|
|
555
605
|
it "should support :frame=>:rows option for window function calls" do
|
|
556
|
-
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
|
|
606
|
+
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
557
607
|
end
|
|
558
608
|
|
|
559
609
|
it "should support :frame=>'some string' option for window function calls" do
|
|
@@ -565,7 +615,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
565
615
|
end
|
|
566
616
|
|
|
567
617
|
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)'
|
|
618
|
+
@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
619
|
end
|
|
570
620
|
|
|
571
621
|
it "should raise an error if window functions are not supported" do
|
|
@@ -596,4 +646,399 @@ describe Sequel::SQL::VirtualRow do
|
|
|
596
646
|
Sequel::BasicObject.remove_methods!
|
|
597
647
|
@d.l{a > adsoiwemlsdaf2}.should == '("a" > "adsoiwemlsdaf2")'
|
|
598
648
|
end
|
|
649
|
+
|
|
650
|
+
it "should have operator methods defined that produce Sequel expression objects" do
|
|
651
|
+
@d.l{|o| o.&({:a=>1}, :b)}.should == '(("a" = 1) AND "b")'
|
|
652
|
+
@d.l{|o| o.|({:a=>1}, :b)}.should == '(("a" = 1) OR "b")'
|
|
653
|
+
@d.l{|o| o.+(1, :b) > 2}.should == '((1 + "b") > 2)'
|
|
654
|
+
@d.l{|o| o.-(1, :b) < 2}.should == '((1 - "b") < 2)'
|
|
655
|
+
@d.l{|o| o.*(1, :b) >= 2}.should == '((1 * "b") >= 2)'
|
|
656
|
+
@d.l{|o| o./(1, :b) <= 2}.should == '((1 / "b") <= 2)'
|
|
657
|
+
@d.l{|o| o.~(:a=>1)}.should == '("a" != 1)'
|
|
658
|
+
@d.l{|o| o.~([[:a, 1], [:b, 2]])}.should == '(("a" != 1) OR ("b" != 2))'
|
|
659
|
+
@d.l{|o| o.<(1, :b)}.should == '(1 < "b")'
|
|
660
|
+
@d.l{|o| o.>(1, :b)}.should == '(1 > "b")'
|
|
661
|
+
@d.l{|o| o.<=(1, :b)}.should == '(1 <= "b")'
|
|
662
|
+
@d.l{|o| o.>=(1, :b)}.should == '(1 >= "b")'
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it "should have have ` produce literal strings" do
|
|
666
|
+
@d.l{a > `some SQL`}.should == '("a" > some SQL)'
|
|
667
|
+
@d.l{|o| o.a > o.`('some SQL')}.should == '("a" > some SQL)' #`
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
describe "Sequel core extension replacements" do
|
|
672
|
+
before do
|
|
673
|
+
@db = Sequel::Database.new
|
|
674
|
+
@o = Object.new
|
|
675
|
+
def @o.sql_literal(ds) 'foo' end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
def l(arg, should)
|
|
679
|
+
@db.literal(arg).should == should
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
it "Sequel.expr should return an appropriate wrapped object" do
|
|
683
|
+
l(Sequel.expr(1) + 1, "(1 + 1)")
|
|
684
|
+
l(Sequel.expr('a') + 'b', "('a' || 'b')")
|
|
685
|
+
l(Sequel.expr(:b) & nil, "(b AND NULL)")
|
|
686
|
+
l(Sequel.expr(nil) & true, "(NULL AND 't')")
|
|
687
|
+
l(Sequel.expr(false) & true, "('f' AND 't')")
|
|
688
|
+
l(Sequel.expr(true) | false, "('t' OR 'f')")
|
|
689
|
+
l(Sequel.expr(@o) + 1, "(foo + 1)")
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
it "Sequel.expr should handle condition specifiers" do
|
|
693
|
+
l(Sequel.expr(:a=>1) & nil, "((a = 1) AND NULL)")
|
|
694
|
+
l(Sequel.expr([[:a, 1]]) & nil, "((a = 1) AND NULL)")
|
|
695
|
+
l(Sequel.expr([[:a, 1], [:b, 2]]) & nil, "((a = 1) AND (b = 2) AND NULL)")
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
it "Sequel.expr should handle arrays that are not condition specifiers" do
|
|
699
|
+
l(Sequel.expr([1]), "(1)")
|
|
700
|
+
l(Sequel.expr([1, 2]), "(1, 2)")
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
it "Sequel.expr should treat blocks/procs as virtual rows and wrap the output" do
|
|
704
|
+
l(Sequel.expr{1} + 1, "(1 + 1)")
|
|
705
|
+
l(Sequel.expr{o__a} + 1, "(o.a + 1)")
|
|
706
|
+
l(Sequel.expr{[[:a, 1]]} & nil, "((a = 1) AND NULL)")
|
|
707
|
+
l(Sequel.expr{|v| @o} + 1, "(foo + 1)")
|
|
708
|
+
|
|
709
|
+
l(Sequel.expr(proc{1}) + 1, "(1 + 1)")
|
|
710
|
+
l(Sequel.expr(proc{o__a}) + 1, "(o.a + 1)")
|
|
711
|
+
l(Sequel.expr(proc{[[:a, 1]]}) & nil, "((a = 1) AND NULL)")
|
|
712
|
+
l(Sequel.expr(proc{|v| @o}) + 1, "(foo + 1)")
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
it "Sequel.expr should raise an error if given an argument and a block" do
|
|
716
|
+
proc{Sequel.expr(nil){}}.should raise_error(Sequel::Error)
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
it "Sequel.expr should raise an error if given neither an argument nor a block" do
|
|
720
|
+
proc{Sequel.expr}.should raise_error(Sequel::Error)
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
it "Sequel.expr should return existing Sequel expressions directly" do
|
|
724
|
+
o = Sequel.expr(1)
|
|
725
|
+
Sequel.expr(o).should equal(o)
|
|
726
|
+
o = Sequel.lit('1')
|
|
727
|
+
Sequel.expr(o).should equal(o)
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
it "Sequel.~ should invert the given object" do
|
|
731
|
+
l(Sequel.~(nil), 'NOT NULL')
|
|
732
|
+
l(Sequel.~(:a=>1), "(a != 1)")
|
|
733
|
+
l(Sequel.~([[:a, 1]]), "(a != 1)")
|
|
734
|
+
l(Sequel.~([[:a, 1], [:b, 2]]), "((a != 1) OR (b != 2))")
|
|
735
|
+
l(Sequel.~(Sequel.expr([[:a, 1], [:b, 2]]) & nil), "((a != 1) OR (b != 2) OR NOT NULL)")
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
it "Sequel.case should use a CASE expression" do
|
|
739
|
+
l(Sequel.case({:a=>1}, 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
|
|
740
|
+
l(Sequel.case({:a=>1}, 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
|
|
741
|
+
l(Sequel.case([[:a, 1]], 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
|
|
742
|
+
l(Sequel.case([[:a, 1]], 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
|
|
743
|
+
l(Sequel.case([[:a, 1], [:c, 3]], 2), "(CASE WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
|
|
744
|
+
l(Sequel.case([[:a, 1], [:c, 3]], 2, :b), "(CASE b WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
it "Sequel.case should raise an error if not given a condition specifier" do
|
|
748
|
+
proc{Sequel.case(1, 2)}.should raise_error(Sequel::Error)
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
it "Sequel.value_list should use an SQL value list" do
|
|
752
|
+
l(Sequel.value_list([[1, 2]]), "((1, 2))")
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
it "Sequel.value_list raise an error if not given an array" do
|
|
756
|
+
proc{Sequel.value_list(1)}.should raise_error(Sequel::Error)
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
it "Sequel.negate should negate all entries in conditions specifier and join with AND" do
|
|
760
|
+
l(Sequel.negate(:a=>1), "(a != 1)")
|
|
761
|
+
l(Sequel.negate([[:a, 1]]), "(a != 1)")
|
|
762
|
+
l(Sequel.negate([[:a, 1], [:b, 2]]), "((a != 1) AND (b != 2))")
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
it "Sequel.negate should raise an error if not given a conditions specifier" do
|
|
766
|
+
proc{Sequel.negate(1)}.should raise_error(Sequel::Error)
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
it "Sequel.or should join all entries in conditions specifier with OR" do
|
|
770
|
+
l(Sequel.or(:a=>1), "(a = 1)")
|
|
771
|
+
l(Sequel.or([[:a, 1]]), "(a = 1)")
|
|
772
|
+
l(Sequel.or([[:a, 1], [:b, 2]]), "((a = 1) OR (b = 2))")
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
it "Sequel.or should raise an error if not given a conditions specifier" do
|
|
776
|
+
proc{Sequel.or(1)}.should raise_error(Sequel::Error)
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
it "Sequel.join should should use SQL string concatenation to join array" do
|
|
780
|
+
l(Sequel.join([]), "''")
|
|
781
|
+
l(Sequel.join(['a']), "('a')")
|
|
782
|
+
l(Sequel.join(['a', 'b']), "('a' || 'b')")
|
|
783
|
+
l(Sequel.join(['a', 'b'], 'c'), "('a' || 'c' || 'b')")
|
|
784
|
+
l(Sequel.join([true, :b], :c), "('t' || c || b)")
|
|
785
|
+
l(Sequel.join([false, nil], Sequel.lit('c')), "('f' || c || NULL)")
|
|
786
|
+
l(Sequel.join([Sequel.expr('a'), Sequel.lit('d')], 'c'), "('a' || 'c' || d)")
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
it "Sequel.join should raise an error if not given an array" do
|
|
790
|
+
proc{Sequel.join(1)}.should raise_error(Sequel::Error)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
it "Sequel.& should join all arguments given with AND" do
|
|
794
|
+
l(Sequel.&(:a), "(a)")
|
|
795
|
+
l(Sequel.&(:a, :b=>:c), "(a AND (b = c))")
|
|
796
|
+
l(Sequel.&(:a, {:b=>:c}, Sequel.lit('d')), "(a AND (b = c) AND d)")
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
it "Sequel.& should raise an error if given no arguments" do
|
|
800
|
+
proc{Sequel.&}.should raise_error(Sequel::Error)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
it "Sequel.| should join all arguments given with OR" do
|
|
804
|
+
l(Sequel.|(:a), "(a)")
|
|
805
|
+
l(Sequel.|(:a, :b=>:c), "(a OR (b = c))")
|
|
806
|
+
l(Sequel.|(:a, {:b=>:c}, Sequel.lit('d')), "(a OR (b = c) OR d)")
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it "Sequel.| should raise an error if given no arguments" do
|
|
810
|
+
proc{Sequel.|}.should raise_error(Sequel::Error)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
it "Sequel.as should return an aliased expression" do
|
|
814
|
+
l(Sequel.as(:a, :b), "a AS b")
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
it "Sequel.cast should return a CAST expression" do
|
|
818
|
+
l(Sequel.cast(:a, :int), "CAST(a AS int)")
|
|
819
|
+
l(Sequel.cast(:a, Integer), "CAST(a AS integer)")
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
it "Sequel.cast_numeric should return a CAST expression treated as a number" do
|
|
823
|
+
l(Sequel.cast_numeric(:a), "CAST(a AS integer)")
|
|
824
|
+
l(Sequel.cast_numeric(:a, :int), "CAST(a AS int)")
|
|
825
|
+
l(Sequel.cast_numeric(:a) << 2, "(CAST(a AS integer) << 2)")
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
it "Sequel.cast_string should return a CAST expression treated as a string" do
|
|
829
|
+
l(Sequel.cast_string(:a), "CAST(a AS varchar(255))")
|
|
830
|
+
l(Sequel.cast_string(:a, :text), "CAST(a AS text)")
|
|
831
|
+
l(Sequel.cast_string(:a) + 'a', "(CAST(a AS varchar(255)) || 'a')")
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
it "Sequel.lit should return a literal string" do
|
|
835
|
+
l(Sequel.lit('a'), "a")
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
it "Sequel.lit should return the argument if given a single literal string" do
|
|
839
|
+
o = Sequel.lit('a')
|
|
840
|
+
Sequel.lit(o).should equal(o)
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
it "Sequel.lit should accept multiple arguments for a placeholder literal string" do
|
|
844
|
+
l(Sequel.lit('a = ?', 1), "a = 1")
|
|
845
|
+
l(Sequel.lit('? = ?', :a, 1), "a = 1")
|
|
846
|
+
l(Sequel.lit('a = :a', :a=>1), "a = 1")
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
it "Sequel.lit should work with an array for the placeholder string" do
|
|
850
|
+
l(Sequel.lit(['a = '], 1), "a = 1")
|
|
851
|
+
l(Sequel.lit(['', ' = '], :a, 1), "a = 1")
|
|
852
|
+
end
|
|
853
|
+
|
|
854
|
+
it "Sequel.blob should return an SQL::Blob" do
|
|
855
|
+
l(Sequel.blob('a'), "'a'")
|
|
856
|
+
Sequel.blob('a').should be_a_kind_of(Sequel::SQL::Blob)
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
it "Sequel.blob should return the given argument if given a blob" do
|
|
860
|
+
o = Sequel.blob('a')
|
|
861
|
+
Sequel.blob(o).should equal(o)
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
it "Sequel.qualify should return a qualified identifier" do
|
|
865
|
+
l(Sequel.qualify(:t, :c), "t.c")
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
it "Sequel.identifier should return an identifier" do
|
|
869
|
+
l(Sequel.identifier(:t__c), "t__c")
|
|
870
|
+
end
|
|
871
|
+
|
|
872
|
+
it "Sequel.asc should return an ASC ordered expression" do
|
|
873
|
+
l(Sequel.asc(:a), "a ASC")
|
|
874
|
+
l(Sequel.asc(:a, :nulls=>:first), "a ASC NULLS FIRST")
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
it "Sequel.desc should return a DESC ordered expression " do
|
|
878
|
+
l(Sequel.desc(:a), "a DESC")
|
|
879
|
+
l(Sequel.desc(:a, :nulls=>:last), "a DESC NULLS LAST")
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
it "Sequel.{+,-,*,/} should accept arguments and use the appropriate operator" do
|
|
883
|
+
%w'+ - * /'.each do |op|
|
|
884
|
+
l(Sequel.send(op, 1), '(1)')
|
|
885
|
+
l(Sequel.send(op, 1, 2), "(1 #{op} 2)")
|
|
886
|
+
l(Sequel.send(op, 1, 2, 3), "(1 #{op} 2 #{op} 3)")
|
|
887
|
+
end
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
it "Sequel.{+,-,*,/} should raise if given no arguments" do
|
|
891
|
+
%w'+ - * /'.each do |op|
|
|
892
|
+
proc{Sequel.send(op)}.should raise_error(Sequel::Error)
|
|
893
|
+
end
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
it "Sequel.like should use a LIKE expression" do
|
|
897
|
+
l(Sequel.like('a', 'b'), "('a' LIKE 'b')")
|
|
898
|
+
l(Sequel.like(:a, :b), "(a LIKE b)")
|
|
899
|
+
l(Sequel.like(:a, /b/), "(a ~ 'b')")
|
|
900
|
+
l(Sequel.like(:a, 'c', /b/), "((a LIKE 'c') OR (a ~ 'b'))")
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
it "Sequel.ilike should use an ILIKE expression" do
|
|
904
|
+
l(Sequel.ilike('a', 'b'), "('a' ILIKE 'b')")
|
|
905
|
+
l(Sequel.ilike(:a, :b), "(a ILIKE b)")
|
|
906
|
+
l(Sequel.ilike(:a, /b/), "(a ~* 'b')")
|
|
907
|
+
l(Sequel.ilike(:a, 'c', /b/), "((a ILIKE 'c') OR (a ~* 'b'))")
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
it "Sequel.subscript should use an SQL subscript" do
|
|
911
|
+
l(Sequel.subscript(:a, 1), 'a[1]')
|
|
912
|
+
l(Sequel.subscript(:a, 1, 2), 'a[1, 2]')
|
|
913
|
+
l(Sequel.subscript(:a, [1, 2]), 'a[1, 2]')
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
it "Sequel.function should return an SQL function" do
|
|
917
|
+
l(Sequel.function(:a), 'a()')
|
|
918
|
+
l(Sequel.function(:a, 1), 'a(1)')
|
|
919
|
+
l(Sequel.function(:a, :b, 2), 'a(b, 2)')
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
it "Sequel.extract should use a date/time extraction" do
|
|
923
|
+
l(Sequel.extract(:year, :a), 'extract(year FROM a)')
|
|
924
|
+
end
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
describe "Sequel::SQL::Function#==" do
|
|
928
|
+
specify "should be true for functions with the same name and arguments, false otherwise" do
|
|
929
|
+
a = :date.sql_function(:t)
|
|
930
|
+
b = :date.sql_function(:t)
|
|
931
|
+
a.should == b
|
|
932
|
+
(a == b).should == true
|
|
933
|
+
c = :date.sql_function(:c)
|
|
934
|
+
a.should_not == c
|
|
935
|
+
(a == c).should == false
|
|
936
|
+
d = :time.sql_function(:c)
|
|
937
|
+
a.should_not == d
|
|
938
|
+
c.should_not == d
|
|
939
|
+
(a == d).should == false
|
|
940
|
+
(c == d).should == false
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
describe "Sequel::SQL::OrderedExpression" do
|
|
945
|
+
specify "should #desc" do
|
|
946
|
+
@oe = Sequel.asc(:column)
|
|
947
|
+
@oe.descending.should == false
|
|
948
|
+
@oe.desc.descending.should == true
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
specify "should #asc" do
|
|
952
|
+
@oe = Sequel.desc(:column)
|
|
953
|
+
@oe.descending.should == true
|
|
954
|
+
@oe.asc.descending.should == false
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
specify "should #invert" do
|
|
958
|
+
@oe = Sequel.desc(:column)
|
|
959
|
+
@oe.invert.descending.should == false
|
|
960
|
+
@oe.invert.invert.descending.should == true
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
describe "Expression" do
|
|
965
|
+
specify "should consider objects == only if they have the same attributes" do
|
|
966
|
+
:column.qualify(:table).cast(:type).*(:numeric_column).asc.should == :column.qualify(:table).cast(:type).*(:numeric_column).asc
|
|
967
|
+
:other_column.qualify(:table).cast(:type).*(:numeric_column).asc.should_not == :column.qualify(:table).cast(:type).*(:numeric_column).asc
|
|
968
|
+
|
|
969
|
+
:column.qualify(:table).cast(:type).*(:numeric_column).asc.should eql(:column.qualify(:table).cast(:type).*(:numeric_column).asc)
|
|
970
|
+
:other_column.qualify(:table).cast(:type).*(:numeric_column).asc.should_not eql(:column.qualify(:table).cast(:type).*(:numeric_column).asc)
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
specify "should use the same hash value for objects that have the same attributes" do
|
|
974
|
+
:column.qualify(:table).cast(:type).*(:numeric_column).asc.hash.should == :column.qualify(:table).cast(:type).*(:numeric_column).asc.hash
|
|
975
|
+
:other_column.qualify(:table).cast(:type).*(:numeric_column).asc.hash.should_not == :column.qualify(:table).cast(:type).*(:numeric_column).asc.hash
|
|
976
|
+
|
|
977
|
+
h = {}
|
|
978
|
+
a = :column.qualify(:table).cast(:type).*(:numeric_column).asc
|
|
979
|
+
b = :column.qualify(:table).cast(:type).*(:numeric_column).asc
|
|
980
|
+
h[a] = 1
|
|
981
|
+
h[b] = 2
|
|
982
|
+
h[a].should == 2
|
|
983
|
+
h[b].should == 2
|
|
984
|
+
end
|
|
985
|
+
end
|
|
986
|
+
|
|
987
|
+
describe "Sequel::SQLTime" do
|
|
988
|
+
before do
|
|
989
|
+
@db = Sequel.mock
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
specify ".create should create from hour, minutes, seconds and optional microseconds" do
|
|
993
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3)).should == "'01:02:03.000000'"
|
|
994
|
+
@db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).should == "'01:02:03.500000'"
|
|
995
|
+
end
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
describe "Sequel::SQL::Wrapper" do
|
|
999
|
+
before do
|
|
1000
|
+
@ds = Sequel.mock.dataset
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
specify "should wrap objects so they can be used by the Sequel DSL" do
|
|
1004
|
+
o = Object.new
|
|
1005
|
+
def o.sql_literal(ds) 'foo' end
|
|
1006
|
+
s = Sequel::SQL::Wrapper.new(o)
|
|
1007
|
+
@ds.literal(s).should == "foo"
|
|
1008
|
+
@ds.literal(s+1).should == "(foo + 1)"
|
|
1009
|
+
@ds.literal(s & true).should == "(foo AND 't')"
|
|
1010
|
+
@ds.literal(s < 1).should == "(foo < 1)"
|
|
1011
|
+
@ds.literal(s.sql_subscript(1)).should == "foo[1]"
|
|
1012
|
+
@ds.literal(s.like('a')).should == "(foo LIKE 'a')"
|
|
1013
|
+
@ds.literal(s.as(:a)).should == "foo AS a"
|
|
1014
|
+
@ds.literal(s.cast(Integer)).should == "CAST(foo AS integer)"
|
|
1015
|
+
@ds.literal(s.desc).should == "foo DESC"
|
|
1016
|
+
@ds.literal(s.sql_string + '1').should == "(foo || '1')"
|
|
1017
|
+
end
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
describe "Sequel::SQL::Blob#to_sequel_blob" do
|
|
1021
|
+
specify "should return self" do
|
|
1022
|
+
c = Sequel::SQL::Blob.new('a')
|
|
1023
|
+
c.to_sequel_blob.should equal(c)
|
|
1024
|
+
end
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
describe Sequel::SQL::Subscript do
|
|
1028
|
+
before do
|
|
1029
|
+
@s = Sequel::SQL::Subscript.new(:a, [1])
|
|
1030
|
+
@ds = Sequel::Dataset.new(nil)
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
specify "should have | return a new non-nested subscript" do
|
|
1034
|
+
s = (@s | 2)
|
|
1035
|
+
s.should_not equal(@s)
|
|
1036
|
+
@ds.literal(s).should == 'a[1, 2]'
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
specify "should have [] return a new nested subscript" do
|
|
1040
|
+
s = @s[2]
|
|
1041
|
+
s.should_not equal(@s)
|
|
1042
|
+
@ds.literal(s).should == 'a[1][2]'
|
|
1043
|
+
end
|
|
599
1044
|
end
|