sequel 4.36.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG +548 -5749
- data/MIT-LICENSE +1 -1
- data/README.rdoc +265 -159
- data/bin/sequel +34 -12
- data/doc/advanced_associations.rdoc +228 -187
- data/doc/association_basics.rdoc +281 -291
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +86 -51
- data/doc/code_order.rdoc +25 -19
- data/doc/core_extensions.rdoc +104 -63
- data/doc/dataset_basics.rdoc +12 -21
- data/doc/dataset_filtering.rdoc +99 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/fork_safety.rdoc +84 -0
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +59 -51
- data/doc/model_dataset_method_design.rdoc +129 -0
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +12 -12
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +58 -68
- data/doc/opening_databases.rdoc +85 -95
- data/doc/postgresql.rdoc +263 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +189 -167
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.10.0.txt +84 -0
- data/doc/release_notes/5.11.0.txt +83 -0
- data/doc/release_notes/5.12.0.txt +141 -0
- data/doc/release_notes/5.13.0.txt +27 -0
- data/doc/release_notes/5.14.0.txt +63 -0
- data/doc/release_notes/5.15.0.txt +39 -0
- data/doc/release_notes/5.16.0.txt +110 -0
- data/doc/release_notes/5.17.0.txt +31 -0
- data/doc/release_notes/5.18.0.txt +69 -0
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.38.0.txt +28 -0
- data/doc/release_notes/5.39.0.txt +19 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/release_notes/5.8.0.txt +170 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/schema_modification.rdoc +95 -75
- data/doc/security.rdoc +109 -80
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +147 -122
- data/doc/testing.rdoc +43 -20
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +97 -18
- data/doc/validations.rdoc +52 -50
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel/adapters/ado/access.rb +15 -17
- data/lib/sequel/adapters/ado/mssql.rb +6 -15
- data/lib/sequel/adapters/ado.rb +150 -20
- data/lib/sequel/adapters/amalgalite.rb +11 -23
- data/lib/sequel/adapters/ibmdb.rb +47 -55
- data/lib/sequel/adapters/jdbc/db2.rb +29 -39
- data/lib/sequel/adapters/jdbc/derby.rb +58 -54
- data/lib/sequel/adapters/jdbc/h2.rb +93 -35
- data/lib/sequel/adapters/jdbc/hsqldb.rb +24 -31
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -20
- data/lib/sequel/adapters/jdbc/oracle.rb +22 -18
- data/lib/sequel/adapters/jdbc/postgresql.rb +69 -71
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +11 -23
- data/lib/sequel/adapters/jdbc/sqlite.rb +47 -11
- data/lib/sequel/adapters/jdbc/sqlserver.rb +34 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +22 -38
- data/lib/sequel/adapters/jdbc.rb +145 -130
- data/lib/sequel/adapters/mock.rb +100 -111
- data/lib/sequel/adapters/mysql.rb +114 -122
- data/lib/sequel/adapters/mysql2.rb +147 -63
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +8 -14
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/odbc.rb +20 -25
- data/lib/sequel/adapters/oracle.rb +50 -56
- data/lib/sequel/adapters/postgres.rb +305 -327
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +74 -78
- data/lib/sequel/adapters/shared/db2.rb +118 -71
- data/lib/sequel/adapters/shared/mssql.rb +301 -220
- data/lib/sequel/adapters/shared/mysql.rb +299 -217
- data/lib/sequel/adapters/shared/oracle.rb +226 -65
- data/lib/sequel/adapters/shared/postgres.rb +935 -395
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -126
- data/lib/sequel/adapters/shared/sqlite.rb +447 -173
- data/lib/sequel/adapters/sqlanywhere.rb +48 -35
- data/lib/sequel/adapters/sqlite.rb +156 -111
- data/lib/sequel/adapters/tinytds.rb +30 -38
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +3 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
- data/lib/sequel/adapters/utils/replace.rb +1 -4
- data/lib/sequel/adapters/utils/stored_procedures.rb +7 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +17 -89
- data/lib/sequel/connection_pool/sharded_single.rb +18 -15
- data/lib/sequel/connection_pool/sharded_threaded.rb +130 -111
- data/lib/sequel/connection_pool/single.rb +18 -13
- data/lib/sequel/connection_pool/threaded.rb +121 -120
- data/lib/sequel/connection_pool.rb +48 -29
- data/lib/sequel/core.rb +351 -301
- data/lib/sequel/database/connecting.rb +69 -57
- data/lib/sequel/database/dataset.rb +13 -5
- data/lib/sequel/database/dataset_defaults.rb +18 -102
- data/lib/sequel/database/features.rb +18 -4
- data/lib/sequel/database/logging.rb +12 -11
- data/lib/sequel/database/misc.rb +180 -122
- data/lib/sequel/database/query.rb +47 -27
- data/lib/sequel/database/schema_generator.rb +178 -84
- data/lib/sequel/database/schema_methods.rb +172 -97
- data/lib/sequel/database/transactions.rb +205 -44
- data/lib/sequel/database.rb +17 -2
- data/lib/sequel/dataset/actions.rb +339 -155
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +90 -35
- data/lib/sequel/dataset/graph.rb +80 -58
- data/lib/sequel/dataset/misc.rb +137 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +63 -25
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +530 -222
- data/lib/sequel/dataset/sql.rb +590 -368
- data/lib/sequel/dataset.rb +26 -16
- data/lib/sequel/deprecated.rb +12 -2
- data/lib/sequel/exceptions.rb +46 -16
- data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
- data/lib/sequel/extensions/_model_pg_row.rb +43 -0
- data/lib/sequel/extensions/_pretty_table.rb +2 -5
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +4 -3
- data/lib/sequel/extensions/connection_expiration.rb +20 -10
- data/lib/sequel/extensions/connection_validator.rb +11 -10
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +62 -39
- data/lib/sequel/extensions/core_extensions.rb +42 -48
- data/lib/sequel/extensions/core_refinements.rb +80 -59
- data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -4
- data/lib/sequel/extensions/date_arithmetic.rb +98 -39
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +21 -14
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +12 -15
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/freeze_datasets.rb +3 -0
- data/lib/sequel/extensions/from_block.rb +1 -34
- data/lib/sequel/extensions/graph_each.rb +4 -4
- data/lib/sequel/extensions/identifier_mangling.rb +180 -0
- data/lib/sequel/extensions/implicit_subquery.rb +48 -0
- data/lib/sequel/extensions/index_caching.rb +109 -0
- data/lib/sequel/extensions/inflector.rb +13 -5
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +17 -8
- data/lib/sequel/extensions/migration.rb +119 -78
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -82
- data/lib/sequel/extensions/null_dataset.rb +8 -8
- data/lib/sequel/extensions/pagination.rb +32 -29
- data/lib/sequel/extensions/pg_array.rb +221 -287
- data/lib/sequel/extensions/pg_array_ops.rb +17 -9
- data/lib/sequel/extensions/pg_enum.rb +63 -23
- data/lib/sequel/extensions/pg_extended_date_support.rb +241 -0
- data/lib/sequel/extensions/pg_hstore.rb +45 -54
- data/lib/sequel/extensions/pg_hstore_ops.rb +58 -6
- data/lib/sequel/extensions/pg_inet.rb +31 -12
- data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
- data/lib/sequel/extensions/pg_interval.rb +56 -29
- data/lib/sequel/extensions/pg_json.rb +417 -140
- data/lib/sequel/extensions/pg_json_ops.rb +270 -18
- data/lib/sequel/extensions/pg_loose_count.rb +4 -2
- data/lib/sequel/extensions/pg_multirange.rb +372 -0
- data/lib/sequel/extensions/pg_range.rb +131 -191
- data/lib/sequel/extensions/pg_range_ops.rb +42 -13
- data/lib/sequel/extensions/pg_row.rb +48 -81
- data/lib/sequel/extensions/pg_row_ops.rb +33 -14
- data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/query.rb +9 -7
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +60 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -1
- data/lib/sequel/extensions/schema_dumper.rb +71 -48
- data/lib/sequel/extensions/select_remove.rb +4 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +51 -27
- data/lib/sequel/extensions/split_array_nil.rb +4 -4
- data/lib/sequel/extensions/sql_comments.rb +119 -7
- data/lib/sequel/extensions/sql_expr.rb +2 -1
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +55 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/extensions/to_dot.rb +10 -4
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model/associations.rb +1006 -284
- data/lib/sequel/model/base.rb +560 -805
- data/lib/sequel/model/dataset_module.rb +11 -10
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +10 -3
- data/lib/sequel/model/exceptions.rb +8 -10
- data/lib/sequel/model/inflections.rb +7 -20
- data/lib/sequel/model/plugins.rb +114 -0
- data/lib/sequel/model.rb +32 -82
- data/lib/sequel/plugins/active_model.rb +30 -14
- data/lib/sequel/plugins/after_initialize.rb +1 -1
- data/lib/sequel/plugins/association_dependencies.rb +25 -18
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +147 -70
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +95 -28
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/before_after_save.rb +0 -42
- data/lib/sequel/plugins/blacklist_security.rb +21 -12
- data/lib/sequel/plugins/boolean_readers.rb +5 -5
- data/lib/sequel/plugins/boolean_subsets.rb +13 -8
- data/lib/sequel/plugins/caching.rb +25 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +179 -100
- data/lib/sequel/plugins/column_conflicts.rb +16 -3
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/column_select.rb +7 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +42 -26
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +20 -14
- data/lib/sequel/plugins/csv_serializer.rb +56 -35
- data/lib/sequel/plugins/dataset_associations.rb +40 -17
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +65 -10
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/dirty.rb +62 -24
- data/lib/sequel/plugins/eager_each.rb +3 -3
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/error_splitter.rb +17 -12
- data/lib/sequel/plugins/finder.rb +246 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/force_encoding.rb +7 -12
- data/lib/sequel/plugins/hook_class_methods.rb +37 -54
- data/lib/sequel/plugins/input_transformer.rb +18 -10
- data/lib/sequel/plugins/insert_conflict.rb +76 -0
- data/lib/sequel/plugins/insert_returning_select.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +10 -8
- data/lib/sequel/plugins/instance_hooks.rb +34 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +22 -13
- data/lib/sequel/plugins/json_serializer.rb +124 -64
- data/lib/sequel/plugins/lazy_attributes.rb +21 -14
- data/lib/sequel/plugins/list.rb +35 -21
- data/lib/sequel/plugins/many_through_many.rb +134 -21
- data/lib/sequel/plugins/modification_detection.rb +15 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +6 -5
- data/lib/sequel/plugins/nested_attributes.rb +61 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +103 -53
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +350 -0
- data/lib/sequel/plugins/pg_row.rb +5 -51
- data/lib/sequel/plugins/prepared_statements.rb +60 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +9 -4
- data/lib/sequel/plugins/rcte_tree.rb +68 -82
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +43 -46
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -2
- data/lib/sequel/plugins/sharding.rb +15 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +67 -28
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +11 -6
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +77 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +43 -10
- data/lib/sequel/plugins/subset_conditions.rb +15 -5
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +96 -12
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +20 -8
- data/lib/sequel/plugins/touch.rb +19 -8
- data/lib/sequel/plugins/tree.rb +62 -32
- data/lib/sequel/plugins/typecast_on_load.rb +12 -4
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +4 -4
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/plugins/update_refresh.rb +26 -15
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validate_associated.rb +18 -0
- data/lib/sequel/plugins/validation_class_methods.rb +38 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +57 -41
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +30 -31
- data/lib/sequel/sql.rb +471 -331
- data/lib/sequel/timezones.rb +78 -47
- data/lib/sequel/version.rb +7 -2
- data/lib/sequel.rb +1 -1
- metadata +217 -521
- data/Rakefile +0 -164
- data/doc/active_record.rdoc +0 -928
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.27.0.txt +0 -78
- data/doc/release_notes/4.28.0.txt +0 -57
- data/doc/release_notes/4.29.0.txt +0 -41
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.30.0.txt +0 -37
- data/doc/release_notes/4.31.0.txt +0 -57
- data/doc/release_notes/4.32.0.txt +0 -132
- data/doc/release_notes/4.33.0.txt +0 -88
- data/doc/release_notes/4.34.0.txt +0 -86
- data/doc/release_notes/4.35.0.txt +0 -130
- data/doc/release_notes/4.36.0.txt +0 -116
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/lib/sequel/adapters/cubrid.rb +0 -144
- data/lib/sequel/adapters/do/mysql.rb +0 -66
- data/lib/sequel/adapters/do/postgres.rb +0 -44
- data/lib/sequel/adapters/do/sqlite3.rb +0 -42
- data/lib/sequel/adapters/do.rb +0 -158
- data/lib/sequel/adapters/jdbc/as400.rb +0 -84
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -64
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -36
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -33
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -33
- data/lib/sequel/adapters/odbc/progress.rb +0 -10
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -247
- data/lib/sequel/adapters/shared/informix.rb +0 -54
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -152
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift/mysql.rb +0 -49
- data/lib/sequel/adapters/swift/postgres.rb +0 -47
- data/lib/sequel/adapters/swift/sqlite.rb +0 -49
- data/lib/sequel/adapters/swift.rb +0 -160
- data/lib/sequel/adapters/utils/pg_types.rb +0 -70
- data/lib/sequel/dataset/mutation.rb +0 -111
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -5
- data/lib/sequel/extensions/filter_having.rb +0 -63
- data/lib/sequel/extensions/hash_aliases.rb +0 -49
- data/lib/sequel/extensions/meta_def.rb +0 -35
- data/lib/sequel/extensions/query_literals.rb +0 -84
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -122
- data/lib/sequel/extensions/set_overrides.rb +0 -76
- data/lib/sequel/no_core_ext.rb +0 -3
- data/lib/sequel/plugins/association_autoreloading.rb +0 -9
- data/lib/sequel/plugins/identifier_columns.rb +0 -47
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -9
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -81
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -119
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -61
- data/lib/sequel/plugins/schema.rb +0 -82
- data/lib/sequel/plugins/scissors.rb +0 -35
- data/spec/adapter_spec.rb +0 -4
- data/spec/adapters/db2_spec.rb +0 -160
- data/spec/adapters/firebird_spec.rb +0 -411
- data/spec/adapters/informix_spec.rb +0 -100
- data/spec/adapters/mssql_spec.rb +0 -733
- data/spec/adapters/mysql_spec.rb +0 -1319
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3790
- data/spec/adapters/spec_helper.rb +0 -49
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -688
- data/spec/bin_spec.rb +0 -258
- data/spec/core/connection_pool_spec.rb +0 -1045
- data/spec/core/database_spec.rb +0 -2636
- data/spec/core/dataset_spec.rb +0 -5175
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1247
- data/spec/core/mock_adapter_spec.rb +0 -464
- data/spec/core/object_graph_spec.rb +0 -303
- data/spec/core/placeholder_literalizer_spec.rb +0 -163
- data/spec/core/schema_generator_spec.rb +0 -203
- data/spec/core/schema_spec.rb +0 -1676
- data/spec/core/spec_helper.rb +0 -34
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -699
- data/spec/core_model_spec.rb +0 -2
- data/spec/core_spec.rb +0 -1
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -85
- data/spec/extensions/after_initialize_spec.rb +0 -24
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -117
- data/spec/extensions/association_pks_spec.rb +0 -405
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/blacklist_security_spec.rb +0 -88
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/boolean_subsets_spec.rb +0 -47
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -444
- data/spec/extensions/column_conflicts_spec.rb +0 -60
- data/spec/extensions/column_select_spec.rb +0 -108
- data/spec/extensions/columns_introspection_spec.rb +0 -91
- data/spec/extensions/composition_spec.rb +0 -242
- data/spec/extensions/connection_expiration_spec.rb +0 -121
- data/spec/extensions/connection_validator_spec.rb +0 -127
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -288
- data/spec/extensions/constraint_validations_spec.rb +0 -389
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -180
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -343
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -167
- data/spec/extensions/defaults_setter_spec.rb +0 -102
- data/spec/extensions/delay_add_association_spec.rb +0 -74
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/duplicate_columns_handler_spec.rb +0 -110
- data/spec/extensions/eager_each_spec.rb +0 -66
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/eval_inspect_spec.rb +0 -73
- data/spec/extensions/filter_having_spec.rb +0 -40
- data/spec/extensions/force_encoding_spec.rb +0 -114
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/graph_each_spec.rb +0 -119
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/identifier_columns_spec.rb +0 -17
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -54
- data/spec/extensions/insert_returning_select_spec.rb +0 -46
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -276
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -304
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -278
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2172
- data/spec/extensions/meta_def_spec.rb +0 -21
- data/spec/extensions/migration_spec.rb +0 -728
- data/spec/extensions/modification_detection_spec.rb +0 -80
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
- data/spec/extensions/named_timezones_spec.rb +0 -108
- data/spec/extensions/nested_attributes_spec.rb +0 -697
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -65
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -128
- data/spec/extensions/pagination_spec.rb +0 -118
- data/spec/extensions/pg_array_associations_spec.rb +0 -736
- data/spec/extensions/pg_array_ops_spec.rb +0 -143
- data/spec/extensions/pg_array_spec.rb +0 -390
- data/spec/extensions/pg_enum_spec.rb +0 -92
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
- data/spec/extensions/pg_hstore_spec.rb +0 -206
- data/spec/extensions/pg_inet_ops_spec.rb +0 -101
- data/spec/extensions/pg_inet_spec.rb +0 -52
- data/spec/extensions/pg_interval_spec.rb +0 -76
- data/spec/extensions/pg_json_ops_spec.rb +0 -275
- data/spec/extensions/pg_json_spec.rb +0 -218
- data/spec/extensions/pg_loose_count_spec.rb +0 -17
- data/spec/extensions/pg_range_ops_spec.rb +0 -58
- data/spec/extensions/pg_range_spec.rb +0 -473
- data/spec/extensions/pg_row_ops_spec.rb +0 -60
- data/spec/extensions/pg_row_plugin_spec.rb +0 -62
- data/spec/extensions/pg_row_spec.rb +0 -360
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
- data/spec/extensions/prepared_statements_spec.rb +0 -103
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
- data/spec/extensions/pretty_table_spec.rb +0 -92
- data/spec/extensions/query_literals_spec.rb +0 -183
- data/spec/extensions/query_spec.rb +0 -102
- data/spec/extensions/rcte_tree_spec.rb +0 -392
- data/spec/extensions/round_timestamps_spec.rb +0 -43
- data/spec/extensions/schema_caching_spec.rb +0 -41
- data/spec/extensions/schema_dumper_spec.rb +0 -814
- data/spec/extensions/schema_spec.rb +0 -117
- data/spec/extensions/scissors_spec.rb +0 -26
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -362
- data/spec/extensions/server_block_spec.rb +0 -90
- data/spec/extensions/server_logging_spec.rb +0 -45
- data/spec/extensions/set_overrides_spec.rb +0 -61
- data/spec/extensions/sharding_spec.rb +0 -198
- data/spec/extensions/shared_caching_spec.rb +0 -175
- data/spec/extensions/single_table_inheritance_spec.rb +0 -297
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -17
- data/spec/extensions/spec_helper.rb +0 -71
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -22
- data/spec/extensions/sql_comments_spec.rb +0 -27
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_agg_spec.rb +0 -85
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -66
- data/spec/extensions/subset_conditions_spec.rb +0 -38
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -136
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -175
- data/spec/extensions/to_dot_spec.rb +0 -154
- data/spec/extensions/touch_spec.rb +0 -203
- data/spec/extensions/tree_spec.rb +0 -274
- data/spec/extensions/typecast_on_load_spec.rb +0 -80
- data/spec/extensions/unlimited_update_spec.rb +0 -20
- data/spec/extensions/update_or_create_spec.rb +0 -87
- data/spec/extensions/update_primary_key_spec.rb +0 -100
- data/spec/extensions/update_refresh_spec.rb +0 -53
- data/spec/extensions/uuid_spec.rb +0 -106
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1027
- data/spec/extensions/validation_helpers_spec.rb +0 -554
- data/spec/extensions/xml_serializer_spec.rb +0 -207
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/double_migration/001_create_sessions.rb +0 -9
- data/spec/files/double_migration/002_create_nodes.rb +0 -19
- data/spec/files/double_migration/003_3_create_users.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/empty_migration/001_create_sessions.rb +0 -9
- data/spec/files/empty_migration/002_create_nodes.rb +0 -0
- data/spec/files/empty_migration/003_3_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/reversible_migrations/006_reversible.rb +0 -10
- data/spec/files/reversible_migrations/007_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2506
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1858
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -262
- data/spec/integration/model_test.rb +0 -230
- data/spec/integration/plugin_test.rb +0 -2297
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -815
- data/spec/integration/spec_helper.rb +0 -56
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -406
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -565
- data/spec/model/associations_spec.rb +0 -4589
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -150
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2197
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -1097
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2162
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/model_no_assoc_spec.rb +0 -1
- data/spec/model_spec.rb +0 -1
- data/spec/plugin_spec.rb +0 -1
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
data/spec/core/database_spec.rb
DELETED
@@ -1,2636 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
2
|
-
|
3
|
-
describe "A new Database" do
|
4
|
-
before do
|
5
|
-
@db = Sequel::Database.new(1 => 2, :logger => 3)
|
6
|
-
end
|
7
|
-
after do
|
8
|
-
Sequel.quote_identifiers = false
|
9
|
-
Sequel.identifier_input_method = nil
|
10
|
-
Sequel.identifier_output_method = nil
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should receive options" do
|
14
|
-
@db.opts[1].must_equal 2
|
15
|
-
@db.opts[:logger].must_equal 3
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should set the logger from opts[:logger] and opts[:loggers]" do
|
19
|
-
@db.loggers.must_equal [3]
|
20
|
-
Sequel::Database.new(1 => 2, :loggers => 3).loggers.must_equal [3]
|
21
|
-
Sequel::Database.new(1 => 2, :loggers => [3]).loggers.must_equal [3]
|
22
|
-
Sequel::Database.new(1 => 2, :logger => 4, :loggers => 3).loggers.must_equal [4,3]
|
23
|
-
Sequel::Database.new(1 => 2, :logger => [4], :loggers => [3]).loggers.must_equal [4,3]
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should support :preconnect option to preconnect to database" do
|
27
|
-
@db.pool.size.must_equal 0
|
28
|
-
c = Class.new(Sequel::Database) do
|
29
|
-
def connect(_)
|
30
|
-
:connect
|
31
|
-
end
|
32
|
-
end
|
33
|
-
db = c.new(1 => 2, :logger => 3, :preconnect=>true)
|
34
|
-
db.pool.size.must_equal db.pool.max_size
|
35
|
-
db = c.new(1 => 2, :logger => 3, :preconnect=>:concurrently)
|
36
|
-
db.pool.size.must_equal db.pool.max_size
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should handle the default string column size" do
|
40
|
-
@db.default_string_column_size.must_equal 255
|
41
|
-
db = Sequel::Database.new(:default_string_column_size=>50)
|
42
|
-
db.default_string_column_size.must_equal 50
|
43
|
-
db.default_string_column_size = 2
|
44
|
-
db.default_string_column_size.must_equal 2
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should set the sql_log_level from opts[:sql_log_level]" do
|
48
|
-
Sequel::Database.new(1 => 2, :sql_log_level=>:debug).sql_log_level.must_equal :debug
|
49
|
-
Sequel::Database.new(1 => 2, :sql_log_level=>'debug').sql_log_level.must_equal :debug
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should create a connection pool" do
|
53
|
-
@db.pool.must_be_kind_of(Sequel::ConnectionPool)
|
54
|
-
@db.pool.max_size.must_equal 4
|
55
|
-
|
56
|
-
Sequel::Database.new(:max_connections => 10).pool.max_size.must_equal 10
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should have the connection pool use the connect method to get connections" do
|
60
|
-
cc = nil
|
61
|
-
d = Sequel::Database.new
|
62
|
-
meta_def(d, :connect){|c| 1234}
|
63
|
-
d.synchronize {|c| cc = c}
|
64
|
-
cc.must_equal 1234
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should respect the :single_threaded option" do
|
68
|
-
db = Sequel::Database.new(:single_threaded=>true){123}
|
69
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
70
|
-
db = Sequel::Database.new(:single_threaded=>'t'){123}
|
71
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
72
|
-
db = Sequel::Database.new(:single_threaded=>'1'){123}
|
73
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
74
|
-
db = Sequel::Database.new(:single_threaded=>false){123}
|
75
|
-
db.pool.must_be_kind_of(Sequel::ConnectionPool)
|
76
|
-
db = Sequel::Database.new(:single_threaded=>'f'){123}
|
77
|
-
db.pool.must_be_kind_of(Sequel::ConnectionPool)
|
78
|
-
db = Sequel::Database.new(:single_threaded=>'0'){123}
|
79
|
-
db.pool.must_be_kind_of(Sequel::ConnectionPool)
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should respect the :quote_identifiers option" do
|
83
|
-
db = Sequel::Database.new(:quote_identifiers=>false)
|
84
|
-
db.quote_identifiers?.must_equal false
|
85
|
-
db = Sequel::Database.new(:quote_identifiers=>true)
|
86
|
-
db.quote_identifiers?.must_equal true
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should upcase on input and downcase on output by default" do
|
90
|
-
db = Sequel::Database.new
|
91
|
-
db.send(:identifier_input_method_default).must_equal :upcase
|
92
|
-
db.send(:identifier_output_method_default).must_equal :downcase
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should respect the :identifier_input_method option" do
|
96
|
-
Sequel.identifier_input_method = nil
|
97
|
-
Sequel::Database.identifier_input_method.must_equal false
|
98
|
-
db = Sequel::Database.new(:identifier_input_method=>nil)
|
99
|
-
db.identifier_input_method.must_equal nil
|
100
|
-
db.identifier_input_method = :downcase
|
101
|
-
db.identifier_input_method.must_equal :downcase
|
102
|
-
db = Sequel::Database.new(:identifier_input_method=>:upcase)
|
103
|
-
db.identifier_input_method.must_equal :upcase
|
104
|
-
db.identifier_input_method = nil
|
105
|
-
db.identifier_input_method.must_equal nil
|
106
|
-
Sequel.identifier_input_method = :downcase
|
107
|
-
Sequel::Database.identifier_input_method.must_equal :downcase
|
108
|
-
db = Sequel::Database.new(:identifier_input_method=>nil)
|
109
|
-
db.identifier_input_method.must_equal nil
|
110
|
-
db.identifier_input_method = :upcase
|
111
|
-
db.identifier_input_method.must_equal :upcase
|
112
|
-
db = Sequel::Database.new(:identifier_input_method=>:upcase)
|
113
|
-
db.identifier_input_method.must_equal :upcase
|
114
|
-
db.identifier_input_method = nil
|
115
|
-
db.identifier_input_method.must_equal nil
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should respect the :identifier_output_method option" do
|
119
|
-
Sequel.identifier_output_method = nil
|
120
|
-
Sequel::Database.identifier_output_method.must_equal false
|
121
|
-
db = Sequel::Database.new(:identifier_output_method=>nil)
|
122
|
-
db.identifier_output_method.must_equal nil
|
123
|
-
db.identifier_output_method = :downcase
|
124
|
-
db.identifier_output_method.must_equal :downcase
|
125
|
-
db = Sequel::Database.new(:identifier_output_method=>:upcase)
|
126
|
-
db.identifier_output_method.must_equal :upcase
|
127
|
-
db.identifier_output_method = nil
|
128
|
-
db.identifier_output_method.must_equal nil
|
129
|
-
Sequel.identifier_output_method = :downcase
|
130
|
-
Sequel::Database.identifier_output_method.must_equal :downcase
|
131
|
-
db = Sequel::Database.new(:identifier_output_method=>nil)
|
132
|
-
db.identifier_output_method.must_equal nil
|
133
|
-
db.identifier_output_method = :upcase
|
134
|
-
db.identifier_output_method.must_equal :upcase
|
135
|
-
db = Sequel::Database.new(:identifier_output_method=>:upcase)
|
136
|
-
db.identifier_output_method.must_equal :upcase
|
137
|
-
db.identifier_output_method = nil
|
138
|
-
db.identifier_output_method.must_equal nil
|
139
|
-
end
|
140
|
-
|
141
|
-
it "should use the default Sequel.quote_identifiers value" do
|
142
|
-
Sequel.quote_identifiers = true
|
143
|
-
Sequel::Database.new({}).quote_identifiers?.must_equal true
|
144
|
-
Sequel.quote_identifiers = false
|
145
|
-
Sequel::Database.new({}).quote_identifiers?.must_equal false
|
146
|
-
Sequel::Database.quote_identifiers = true
|
147
|
-
Sequel::Database.new({}).quote_identifiers?.must_equal true
|
148
|
-
Sequel::Database.quote_identifiers = false
|
149
|
-
Sequel::Database.new({}).quote_identifiers?.must_equal false
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should use the default Sequel.identifier_input_method value" do
|
153
|
-
Sequel.identifier_input_method = :downcase
|
154
|
-
Sequel::Database.new({}).identifier_input_method.must_equal :downcase
|
155
|
-
Sequel.identifier_input_method = :upcase
|
156
|
-
Sequel::Database.new({}).identifier_input_method.must_equal :upcase
|
157
|
-
Sequel::Database.identifier_input_method = :downcase
|
158
|
-
Sequel::Database.new({}).identifier_input_method.must_equal :downcase
|
159
|
-
Sequel::Database.identifier_input_method = :upcase
|
160
|
-
Sequel::Database.new({}).identifier_input_method.must_equal :upcase
|
161
|
-
end
|
162
|
-
|
163
|
-
it "should use the default Sequel.identifier_output_method value" do
|
164
|
-
Sequel.identifier_output_method = :downcase
|
165
|
-
Sequel::Database.new({}).identifier_output_method.must_equal :downcase
|
166
|
-
Sequel.identifier_output_method = :upcase
|
167
|
-
Sequel::Database.new({}).identifier_output_method.must_equal :upcase
|
168
|
-
Sequel::Database.identifier_output_method = :downcase
|
169
|
-
Sequel::Database.new({}).identifier_output_method.must_equal :downcase
|
170
|
-
Sequel::Database.identifier_output_method = :upcase
|
171
|
-
Sequel::Database.new({}).identifier_output_method.must_equal :upcase
|
172
|
-
end
|
173
|
-
|
174
|
-
it "should respect the quote_indentifiers_default method if Sequel.quote_identifiers = nil" do
|
175
|
-
Sequel.quote_identifiers = nil
|
176
|
-
Sequel::Database.new({}).quote_identifiers?.must_equal true
|
177
|
-
x = Class.new(Sequel::Database){def quote_identifiers_default; false end}
|
178
|
-
x.new({}).quote_identifiers?.must_equal false
|
179
|
-
y = Class.new(Sequel::Database){def quote_identifiers_default; true end}
|
180
|
-
y.new({}).quote_identifiers?.must_equal true
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should respect the identifier_input_method_default method" do
|
184
|
-
class Sequel::Database
|
185
|
-
@identifier_input_method = nil
|
186
|
-
end
|
187
|
-
x = Class.new(Sequel::Database){def identifier_input_method_default; :downcase end}
|
188
|
-
x.new({}).identifier_input_method.must_equal :downcase
|
189
|
-
y = Class.new(Sequel::Database){def identifier_input_method_default; :camelize end}
|
190
|
-
y.new({}).identifier_input_method.must_equal :camelize
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should respect the identifier_output_method_default method if Sequel.identifier_output_method is not called" do
|
194
|
-
class Sequel::Database
|
195
|
-
@identifier_output_method = nil
|
196
|
-
end
|
197
|
-
x = Class.new(Sequel::Database){def identifier_output_method_default; :upcase end}
|
198
|
-
x.new({}).identifier_output_method.must_equal :upcase
|
199
|
-
y = Class.new(Sequel::Database){def identifier_output_method_default; :underscore end}
|
200
|
-
y.new({}).identifier_output_method.must_equal :underscore
|
201
|
-
end
|
202
|
-
|
203
|
-
it "should just use a :uri option for jdbc with the full connection string" do
|
204
|
-
db = Sequel::Database.stub(:adapter_class, Sequel::Database) do
|
205
|
-
Sequel.connect('jdbc:test://host/db_name')
|
206
|
-
end
|
207
|
-
db.must_be_kind_of(Sequel::Database)
|
208
|
-
db.opts[:uri].must_equal 'jdbc:test://host/db_name'
|
209
|
-
end
|
210
|
-
|
211
|
-
it "should just use a :uri option for do with the full connection string" do
|
212
|
-
db = Sequel::Database.stub(:adapter_class, Sequel::Database) do
|
213
|
-
Sequel.connect('do:test://host/db_name')
|
214
|
-
end
|
215
|
-
db.must_be_kind_of(Sequel::Database)
|
216
|
-
db.opts[:uri].must_equal 'do:test://host/db_name'
|
217
|
-
end
|
218
|
-
|
219
|
-
it "should populate :adapter option when using connection string" do
|
220
|
-
Sequel.connect('mock:/').opts[:adapter].must_equal "mock"
|
221
|
-
end
|
222
|
-
|
223
|
-
it "should respect the :keep_reference option for not keeping a reference in Sequel::DATABASES" do
|
224
|
-
db = Sequel.connect('mock:///?keep_reference=f')
|
225
|
-
Sequel::DATABASES.wont_include(db)
|
226
|
-
end
|
227
|
-
|
228
|
-
it 'should strip square brackets for ipv6 hosts' do
|
229
|
-
Sequel.connect('mock://[::1]').opts[:host].must_equal "::1"
|
230
|
-
end if RUBY_VERSION >= '1.9.3'
|
231
|
-
end
|
232
|
-
|
233
|
-
describe "Database#disconnect" do
|
234
|
-
it "should call pool.disconnect" do
|
235
|
-
d = Sequel::Database.new
|
236
|
-
p = d.pool
|
237
|
-
def p.disconnect(h)
|
238
|
-
raise unless h == {}
|
239
|
-
2
|
240
|
-
end
|
241
|
-
d.disconnect.must_equal 2
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
describe "Sequel.extension" do
|
246
|
-
it "should attempt to load the given extension" do
|
247
|
-
proc{Sequel.extension :blah}.must_raise(LoadError)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
describe "Database#log_info" do
|
252
|
-
before do
|
253
|
-
@o = Object.new
|
254
|
-
def @o.logs; @logs || []; end
|
255
|
-
def @o.to_ary; [self]; end
|
256
|
-
def @o.method_missing(*args); (@logs ||= []) << args; end
|
257
|
-
@db = Sequel::Database.new(:logger=>@o)
|
258
|
-
end
|
259
|
-
|
260
|
-
it "should log message at info level to all loggers" do
|
261
|
-
@db.log_info('blah')
|
262
|
-
@o.logs.must_equal [[:info, 'blah']]
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should log message with args at info level to all loggers" do
|
266
|
-
@db.log_info('blah', [1, 2])
|
267
|
-
@o.logs.must_equal [[:info, 'blah; [1, 2]']]
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
describe "Database#log_yield" do
|
272
|
-
before do
|
273
|
-
@o = Object.new
|
274
|
-
def @o.logs; @logs || []; end
|
275
|
-
def @o.warn(*args); (@logs ||= []) << [:warn] + args; end
|
276
|
-
def @o.method_missing(*args); (@logs ||= []) << args; end
|
277
|
-
def @o.to_ary; [self]; end
|
278
|
-
@db = Sequel::Database.new(:logger=>@o)
|
279
|
-
end
|
280
|
-
|
281
|
-
it "should yield to the passed block" do
|
282
|
-
a = nil
|
283
|
-
@db.log_yield('blah'){a = 1}
|
284
|
-
a.must_equal 1
|
285
|
-
end
|
286
|
-
|
287
|
-
it "should raise an exception if a block is not passed" do
|
288
|
-
proc{@db.log_yield('blah')}.must_raise LocalJumpError
|
289
|
-
end
|
290
|
-
|
291
|
-
it "should log message with duration at info level to all loggers" do
|
292
|
-
@db.log_yield('blah'){}
|
293
|
-
@o.logs.length.must_equal 1
|
294
|
-
@o.logs.first.length.must_equal 2
|
295
|
-
@o.logs.first.first.must_equal :info
|
296
|
-
@o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
|
297
|
-
end
|
298
|
-
|
299
|
-
it "should respect sql_log_level setting" do
|
300
|
-
@db.sql_log_level = :debug
|
301
|
-
@db.log_yield('blah'){}
|
302
|
-
@o.logs.length.must_equal 1
|
303
|
-
@o.logs.first.length.must_equal 2
|
304
|
-
@o.logs.first.first.must_equal :debug
|
305
|
-
@o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
|
306
|
-
end
|
307
|
-
|
308
|
-
it "should log message with duration at warn level if duration greater than log_warn_duration" do
|
309
|
-
@db.log_warn_duration = 0
|
310
|
-
@db.log_yield('blah'){}
|
311
|
-
@o.logs.length.must_equal 1
|
312
|
-
@o.logs.first.length.must_equal 2
|
313
|
-
@o.logs.first.first.must_equal :warn
|
314
|
-
@o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
|
315
|
-
end
|
316
|
-
|
317
|
-
it "should log message with duration at info level if duration less than log_warn_duration" do
|
318
|
-
@db.log_warn_duration = 1000
|
319
|
-
@db.log_yield('blah'){}
|
320
|
-
@o.logs.length.must_equal 1
|
321
|
-
@o.logs.first.length.must_equal 2
|
322
|
-
@o.logs.first.first.must_equal :info
|
323
|
-
@o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
|
324
|
-
end
|
325
|
-
|
326
|
-
it "should log message at error level if block raises an error" do
|
327
|
-
@db.log_warn_duration = 0
|
328
|
-
proc{@db.log_yield('blah'){raise Sequel::Error, 'adsf'}}.must_raise Sequel::Error
|
329
|
-
@o.logs.length.must_equal 1
|
330
|
-
@o.logs.first.length.must_equal 2
|
331
|
-
@o.logs.first.first.must_equal :error
|
332
|
-
@o.logs.first.last.must_match(/\ASequel::Error: adsf: blah\z/)
|
333
|
-
end
|
334
|
-
|
335
|
-
it "should include args with message if args passed" do
|
336
|
-
@db.log_yield('blah', [1, 2]){}
|
337
|
-
@o.logs.length.must_equal 1
|
338
|
-
@o.logs.first.length.must_equal 2
|
339
|
-
@o.logs.first.first.must_equal :info
|
340
|
-
@o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah; \[1, 2\]\z/)
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
describe "Database#log_connection_yield" do
|
345
|
-
before do
|
346
|
-
@o = Object.new
|
347
|
-
def @o.logs; @logs || []; end
|
348
|
-
def @o.to_ary; [self]; end
|
349
|
-
def @o.method_missing(*args); (@logs ||= []) << args; end
|
350
|
-
@conn = Object.new
|
351
|
-
@db = Sequel::Database.new(:logger=>@o)
|
352
|
-
end
|
353
|
-
|
354
|
-
it "should log SQL to the loggers" do
|
355
|
-
@db.log_connection_yield("some SQL", @conn){}
|
356
|
-
@o.logs.length.must_equal 1
|
357
|
-
@o.logs.first.length.must_equal 2
|
358
|
-
@o.logs.first.first.must_equal :info
|
359
|
-
@o.logs.first.last.must_match(/some SQL\z/)
|
360
|
-
@o.logs.first.last.wont_match(/\(conn: -?\d+\) some SQL\z/)
|
361
|
-
end
|
362
|
-
|
363
|
-
it "should include connection information when logging" do
|
364
|
-
@db.log_connection_info = true
|
365
|
-
@db.log_connection_yield("some SQL", @conn){}
|
366
|
-
@o.logs.length.must_equal 1
|
367
|
-
@o.logs.first.length.must_equal 2
|
368
|
-
@o.logs.first.first.must_equal :info
|
369
|
-
@o.logs.first.last.must_match(/\(conn: -?\d+\) some SQL\z/)
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
describe "Database#uri" do
|
374
|
-
before do
|
375
|
-
@c = Class.new(Sequel::Database) do
|
376
|
-
set_adapter_scheme :mau
|
377
|
-
end
|
378
|
-
|
379
|
-
@db = Sequel.connect('mau://user:pass@localhost:9876/maumau')
|
380
|
-
end
|
381
|
-
|
382
|
-
it "should return the connection URI for the database" do
|
383
|
-
@db.uri.must_equal 'mau://user:pass@localhost:9876/maumau'
|
384
|
-
end
|
385
|
-
|
386
|
-
it "should return nil if a connection uri was not used" do
|
387
|
-
Sequel.mock.uri.must_equal nil
|
388
|
-
end
|
389
|
-
|
390
|
-
it "should be aliased as #url" do
|
391
|
-
@db.url.must_equal 'mau://user:pass@localhost:9876/maumau'
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
describe "Database.adapter_scheme and #adapter_scheme" do
|
396
|
-
it "should return the database scheme" do
|
397
|
-
Sequel::Database.adapter_scheme.must_equal nil
|
398
|
-
|
399
|
-
@c = Class.new(Sequel::Database) do
|
400
|
-
set_adapter_scheme :mau
|
401
|
-
end
|
402
|
-
|
403
|
-
@c.adapter_scheme.must_equal :mau
|
404
|
-
@c.new({}).adapter_scheme.must_equal :mau
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
describe "Database#dataset" do
|
409
|
-
before do
|
410
|
-
@db = Sequel::Database.new
|
411
|
-
@ds = @db.dataset
|
412
|
-
end
|
413
|
-
|
414
|
-
it "should provide a blank dataset through #dataset" do
|
415
|
-
@ds.must_be_kind_of(Sequel::Dataset)
|
416
|
-
@ds.opts.must_equal({})
|
417
|
-
@ds.db.must_be_same_as(@db)
|
418
|
-
end
|
419
|
-
|
420
|
-
it "should provide a #from dataset" do
|
421
|
-
d = @db.from(:mau)
|
422
|
-
d.must_be_kind_of(Sequel::Dataset)
|
423
|
-
d.sql.must_equal 'SELECT * FROM mau'
|
424
|
-
|
425
|
-
e = @db[:miu]
|
426
|
-
e.must_be_kind_of(Sequel::Dataset)
|
427
|
-
e.sql.must_equal 'SELECT * FROM miu'
|
428
|
-
end
|
429
|
-
|
430
|
-
it "should provide a filtered #from dataset if a block is given" do
|
431
|
-
d = @db.from(:mau){x.sql_number > 100}
|
432
|
-
d.must_be_kind_of(Sequel::Dataset)
|
433
|
-
d.sql.must_equal 'SELECT * FROM mau WHERE (x > 100)'
|
434
|
-
end
|
435
|
-
|
436
|
-
it "should provide a #select dataset" do
|
437
|
-
d = @db.select(:a, :b, :c).from(:mau)
|
438
|
-
d.must_be_kind_of(Sequel::Dataset)
|
439
|
-
d.sql.must_equal 'SELECT a, b, c FROM mau'
|
440
|
-
end
|
441
|
-
|
442
|
-
it "should allow #select to take a block" do
|
443
|
-
d = @db.select(:a, :b){c}.from(:mau)
|
444
|
-
d.must_be_kind_of(Sequel::Dataset)
|
445
|
-
d.sql.must_equal 'SELECT a, b, c FROM mau'
|
446
|
-
end
|
447
|
-
end
|
448
|
-
|
449
|
-
describe "Database#dataset_class" do
|
450
|
-
before do
|
451
|
-
@db = Sequel::Database.new
|
452
|
-
@dsc = Class.new(Sequel::Dataset)
|
453
|
-
end
|
454
|
-
|
455
|
-
it "should have setter set the class to use to create datasets" do
|
456
|
-
@db.dataset_class = @dsc
|
457
|
-
ds = @db.dataset
|
458
|
-
ds.must_be_kind_of(@dsc)
|
459
|
-
ds.opts.must_equal({})
|
460
|
-
ds.db.must_be_same_as(@db)
|
461
|
-
end
|
462
|
-
|
463
|
-
it "should have getter return the class to use to create datasets" do
|
464
|
-
[@db.dataset_class, @db.dataset_class.superclass].must_include(Sequel::Dataset)
|
465
|
-
@db.dataset_class = @dsc
|
466
|
-
[@db.dataset_class, @db.dataset_class.superclass].must_include(@dsc)
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
describe "Database#extend_datasets" do
|
471
|
-
before do
|
472
|
-
@db = Sequel::Database.new
|
473
|
-
@m = Module.new{def foo() [3] end}
|
474
|
-
@m2 = Module.new{def foo() [4] + super end}
|
475
|
-
@db.extend_datasets(@m)
|
476
|
-
end
|
477
|
-
|
478
|
-
it "should clear a cached dataset" do
|
479
|
-
@db = Sequel::Database.new
|
480
|
-
@db.literal(1).must_equal '1'
|
481
|
-
@db.extend_datasets{def literal(v) '2' end}
|
482
|
-
@db.literal(1).must_equal '2'
|
483
|
-
end
|
484
|
-
|
485
|
-
it "should change the dataset class to a subclass the first time it is called" do
|
486
|
-
@db.dataset_class.superclass.must_equal Sequel::Dataset
|
487
|
-
end
|
488
|
-
|
489
|
-
it "should not create a subclass of the dataset class if called more than once" do
|
490
|
-
@db.extend_datasets(@m2)
|
491
|
-
@db.dataset_class.superclass.must_equal Sequel::Dataset
|
492
|
-
end
|
493
|
-
|
494
|
-
it "should make the dataset class include the module" do
|
495
|
-
@db.dataset_class.ancestors.must_include(@m)
|
496
|
-
@db.dataset_class.ancestors.wont_include(@m2)
|
497
|
-
@db.extend_datasets(@m2)
|
498
|
-
@db.dataset_class.ancestors.must_include(@m)
|
499
|
-
@db.dataset_class.ancestors.must_include(@m2)
|
500
|
-
end
|
501
|
-
|
502
|
-
it "should have datasets respond to the module's methods" do
|
503
|
-
@db.dataset.foo.must_equal [3]
|
504
|
-
@db.extend_datasets(@m2)
|
505
|
-
@db.dataset.foo.must_equal [4, 3]
|
506
|
-
end
|
507
|
-
|
508
|
-
it "should take a block and create a module from it to use" do
|
509
|
-
@db.dataset.foo.must_equal [3]
|
510
|
-
@db.extend_datasets{def foo() [5] + super end}
|
511
|
-
@db.dataset.foo.must_equal [5, 3]
|
512
|
-
end
|
513
|
-
|
514
|
-
it "should raise an error if both a module and a block are provided" do
|
515
|
-
proc{@db.extend_datasets(@m2){def foo() [5] + super end}}.must_raise(Sequel::Error)
|
516
|
-
end
|
517
|
-
|
518
|
-
it "should be able to override methods defined in the original Dataset class" do
|
519
|
-
@db.extend_datasets(Module.new{def select(*a, &block) super.order(*a, &block) end})
|
520
|
-
@db[:t].select(:a, :b).sql.must_equal 'SELECT a, b FROM t ORDER BY a, b'
|
521
|
-
end
|
522
|
-
|
523
|
-
it "should reapply settings if dataset_class is changed" do
|
524
|
-
c = Class.new(Sequel::Dataset)
|
525
|
-
@db.dataset_class = c
|
526
|
-
@db.dataset_class.superclass.must_equal c
|
527
|
-
@db.dataset_class.ancestors.must_include(@m)
|
528
|
-
@db.dataset.foo.must_equal [3]
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
describe "Database#disconnect_connection" do
|
533
|
-
it "should call close on the connection" do
|
534
|
-
o = Object.new
|
535
|
-
def o.close() @closed=true end
|
536
|
-
Sequel::Database.new.disconnect_connection(o)
|
537
|
-
o.instance_variable_get(:@closed).must_equal true
|
538
|
-
end
|
539
|
-
end
|
540
|
-
|
541
|
-
describe "Database#valid_connection?" do
|
542
|
-
it "should issue a query to validate the connection" do
|
543
|
-
db = Sequel.mock
|
544
|
-
db.synchronize{|c| db.valid_connection?(c)}.must_equal true
|
545
|
-
db.synchronize do |c|
|
546
|
-
def c.execute(*) raise Sequel::DatabaseError, "error" end
|
547
|
-
db.valid_connection?(c)
|
548
|
-
end.must_equal false
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
describe "Database#run" do
|
553
|
-
before do
|
554
|
-
@db = Sequel.mock(:servers=>{:s1=>{}})
|
555
|
-
end
|
556
|
-
|
557
|
-
it "should execute the code on the database" do
|
558
|
-
@db.run("DELETE FROM items")
|
559
|
-
@db.sqls.must_equal ["DELETE FROM items"]
|
560
|
-
end
|
561
|
-
|
562
|
-
it "should handle placeholder literal strings" do
|
563
|
-
@db.run(Sequel.lit("DELETE FROM ?", :items))
|
564
|
-
@db.sqls.must_equal ["DELETE FROM items"]
|
565
|
-
end
|
566
|
-
|
567
|
-
it "should return nil" do
|
568
|
-
@db.run("DELETE FROM items").must_equal nil
|
569
|
-
end
|
570
|
-
|
571
|
-
it "should accept options passed to execute_ddl" do
|
572
|
-
@db.run("DELETE FROM items", :server=>:s1)
|
573
|
-
@db.sqls.must_equal ["DELETE FROM items -- s1"]
|
574
|
-
end
|
575
|
-
end
|
576
|
-
|
577
|
-
describe "Database#<<" do
|
578
|
-
before do
|
579
|
-
@db = Sequel.mock
|
580
|
-
end
|
581
|
-
|
582
|
-
it "should execute the code on the database" do
|
583
|
-
@db << "DELETE FROM items"
|
584
|
-
@db.sqls.must_equal ["DELETE FROM items"]
|
585
|
-
end
|
586
|
-
|
587
|
-
it "should handle placeholder literal strings" do
|
588
|
-
@db << Sequel.lit("DELETE FROM ?", :items)
|
589
|
-
@db.sqls.must_equal ["DELETE FROM items"]
|
590
|
-
end
|
591
|
-
|
592
|
-
it "should be chainable" do
|
593
|
-
@db << "DELETE FROM items" << "DELETE FROM items2"
|
594
|
-
@db.sqls.must_equal ["DELETE FROM items", "DELETE FROM items2"]
|
595
|
-
end
|
596
|
-
end
|
597
|
-
|
598
|
-
describe "Database#synchronize" do
|
599
|
-
before do
|
600
|
-
@db = Sequel::Database.new(:max_connections => 1)
|
601
|
-
meta_def(@db, :connect){|c| 12345}
|
602
|
-
end
|
603
|
-
|
604
|
-
it "should wrap the supplied block in pool.hold" do
|
605
|
-
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
606
|
-
c1, c2 = nil
|
607
|
-
t1 = Thread.new{@db.synchronize{|c| c1 = c; q.push nil; q1.pop}; q.push nil}
|
608
|
-
q.pop
|
609
|
-
c1.must_equal 12345
|
610
|
-
t2 = Thread.new{@db.synchronize{|c| c2 = c; q2.push nil}}
|
611
|
-
@db.pool.available_connections.must_be :empty?
|
612
|
-
c2.must_equal nil
|
613
|
-
q1.push nil
|
614
|
-
q.pop
|
615
|
-
q2.pop
|
616
|
-
c2.must_equal 12345
|
617
|
-
t1.join
|
618
|
-
t2.join
|
619
|
-
end
|
620
|
-
end
|
621
|
-
|
622
|
-
describe "Database#test_connection" do
|
623
|
-
before do
|
624
|
-
@db = Sequel::Database.new
|
625
|
-
pr = proc{@test = rand(100)}
|
626
|
-
meta_def(@db, :connect){|c| pr.call}
|
627
|
-
end
|
628
|
-
|
629
|
-
it "should attempt to get a connection" do
|
630
|
-
@db.test_connection
|
631
|
-
@test.wont_equal nil
|
632
|
-
end
|
633
|
-
|
634
|
-
it "should return true if successful" do
|
635
|
-
@db.test_connection.must_equal true
|
636
|
-
end
|
637
|
-
|
638
|
-
it "should raise an error if the attempting to connect raises an error" do
|
639
|
-
def @db.connect(*) raise Sequel::Error end
|
640
|
-
proc{@db.test_connection}.must_raise(Sequel::DatabaseConnectionError)
|
641
|
-
end
|
642
|
-
end
|
643
|
-
|
644
|
-
describe "Database#table_exists?" do
|
645
|
-
it "should test existence by selecting a row from the table's dataset" do
|
646
|
-
db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
|
647
|
-
db.table_exists?(:a).must_equal false
|
648
|
-
db.sqls.must_equal ["SELECT NULL AS nil FROM a LIMIT 1"]
|
649
|
-
db.table_exists?(:b).must_equal true
|
650
|
-
db.table_exists?(:c).must_equal true
|
651
|
-
end
|
652
|
-
|
653
|
-
it "should use a savepoint if inside a transaction" do
|
654
|
-
db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
|
655
|
-
def db.supports_savepoints?; true end
|
656
|
-
db.transaction do
|
657
|
-
db.table_exists?(:a).must_equal false
|
658
|
-
end
|
659
|
-
db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "SELECT NULL AS nil FROM a LIMIT 1", "ROLLBACK TO SAVEPOINT autopoint_1", "COMMIT"]
|
660
|
-
db.table_exists?(:b).must_equal true
|
661
|
-
db.table_exists?(:c).must_equal true
|
662
|
-
end
|
663
|
-
end
|
664
|
-
|
665
|
-
DatabaseTransactionSpecs = shared_description do
|
666
|
-
it "should wrap the supplied block with BEGIN + COMMIT statements" do
|
667
|
-
@db.transaction{@db.execute 'DROP TABLE test;'}
|
668
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
669
|
-
end
|
670
|
-
|
671
|
-
it "should support transaction isolation levels" do
|
672
|
-
meta_def(@db, :supports_transaction_isolation_levels?){true}
|
673
|
-
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
674
|
-
@db.transaction(:isolation=>l){@db.run "DROP TABLE #{l}"}
|
675
|
-
end
|
676
|
-
@db.sqls.must_equal ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
677
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
678
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
679
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
680
|
-
end
|
681
|
-
|
682
|
-
it "should allow specifying a default transaction isolation level" do
|
683
|
-
meta_def(@db, :supports_transaction_isolation_levels?){true}
|
684
|
-
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
685
|
-
@db.transaction_isolation_level = l
|
686
|
-
@db.transaction{@db.run "DROP TABLE #{l}"}
|
687
|
-
end
|
688
|
-
@db.sqls.must_equal ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
689
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
690
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
691
|
-
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
692
|
-
end
|
693
|
-
|
694
|
-
it "should support :retry_on option for automatically retrying transactions" do
|
695
|
-
a = []
|
696
|
-
@db.transaction(:retry_on=>Sequel::DatabaseDisconnectError){a << 1; raise Sequel::DatabaseDisconnectError if a.length < 2}
|
697
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
|
698
|
-
a.must_equal [1, 1]
|
699
|
-
|
700
|
-
a = []
|
701
|
-
@db.transaction(:retry_on=>[Sequel::ConstraintViolation, Sequel::SerializationFailure]) do
|
702
|
-
a << 1
|
703
|
-
raise Sequel::SerializationFailure if a.length == 1
|
704
|
-
raise Sequel::ConstraintViolation if a.length == 2
|
705
|
-
end
|
706
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
|
707
|
-
a.must_equal [1, 1, 1]
|
708
|
-
end
|
709
|
-
|
710
|
-
it "should support :num_retries option for limiting the number of retry times" do
|
711
|
-
a = []
|
712
|
-
lambda do
|
713
|
-
@db.transaction(:num_retries=>1, :retry_on=>[Sequel::ConstraintViolation, Sequel::SerializationFailure]) do
|
714
|
-
a << 1
|
715
|
-
raise Sequel::SerializationFailure if a.length == 1
|
716
|
-
raise Sequel::ConstraintViolation if a.length == 2
|
717
|
-
end
|
718
|
-
end.must_raise(Sequel::ConstraintViolation)
|
719
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK']
|
720
|
-
a.must_equal [1, 1]
|
721
|
-
end
|
722
|
-
|
723
|
-
it "should support :num_retries=>nil option to retry indefinitely" do
|
724
|
-
a = []
|
725
|
-
lambda do
|
726
|
-
@db.transaction(:num_retries=>nil, :retry_on=>[Sequel::ConstraintViolation]) do
|
727
|
-
a << 1
|
728
|
-
raise Sequel::SerializationFailure if a.length >= 100
|
729
|
-
raise Sequel::ConstraintViolation
|
730
|
-
end
|
731
|
-
end.must_raise(Sequel::SerializationFailure)
|
732
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK'] * 100
|
733
|
-
a.must_equal [1] * 100
|
734
|
-
end
|
735
|
-
|
736
|
-
it "should support :before_retry option for invoking callback before retrying" do
|
737
|
-
a, errs, calls = [], [], []
|
738
|
-
retryer = proc{|n, err| calls << n; errs << err }
|
739
|
-
@db.transaction(:retry_on=>Sequel::DatabaseDisconnectError, :before_retry => retryer) do
|
740
|
-
a << 1; raise Sequel::DatabaseDisconnectError if a.length < 3
|
741
|
-
end
|
742
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
|
743
|
-
a.must_equal [1, 1, 1]
|
744
|
-
errs.count.must_equal 2
|
745
|
-
errs.each { |e| e.class.must_equal Sequel::DatabaseDisconnectError }
|
746
|
-
calls.must_equal [1, 2]
|
747
|
-
end
|
748
|
-
|
749
|
-
it "should raise an error if attempting to use :retry_on inside another transaction" do
|
750
|
-
proc{@db.transaction{@db.transaction(:retry_on=>Sequel::ConstraintViolation){}}}.must_raise(Sequel::Error)
|
751
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
752
|
-
end
|
753
|
-
|
754
|
-
it "should handle returning inside of the block by committing" do
|
755
|
-
def @db.ret_commit
|
756
|
-
transaction do
|
757
|
-
execute 'DROP TABLE test;'
|
758
|
-
return
|
759
|
-
end
|
760
|
-
end
|
761
|
-
@db.ret_commit
|
762
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
763
|
-
end
|
764
|
-
|
765
|
-
it "should issue ROLLBACK if an exception is raised, and re-raise" do
|
766
|
-
@db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
|
767
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
768
|
-
|
769
|
-
proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
|
770
|
-
end
|
771
|
-
|
772
|
-
it "should handle errors when sending BEGIN" do
|
773
|
-
ec = Class.new(StandardError)
|
774
|
-
meta_def(@db, :database_error_classes){[ec]}
|
775
|
-
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /BEGIN/ ? raise(ec, 'bad') : super(c, sql)}
|
776
|
-
begin
|
777
|
-
@db.transaction{@db.execute 'DROP TABLE test;'}
|
778
|
-
rescue Sequel::DatabaseError => e
|
779
|
-
end
|
780
|
-
e.wont_equal nil
|
781
|
-
e.wrapped_exception.must_be_kind_of(ec)
|
782
|
-
@db.sqls.must_equal ['ROLLBACK']
|
783
|
-
end
|
784
|
-
|
785
|
-
it "should handle errors when sending COMMIT" do
|
786
|
-
ec = Class.new(StandardError)
|
787
|
-
meta_def(@db, :database_error_classes){[ec]}
|
788
|
-
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /COMMIT/ ? raise(ec, 'bad') : super(c, sql)}
|
789
|
-
begin
|
790
|
-
@db.transaction{@db.execute 'DROP TABLE test;'}
|
791
|
-
rescue Sequel::DatabaseError => e
|
792
|
-
end
|
793
|
-
e.wont_equal nil
|
794
|
-
e.wrapped_exception.must_be_kind_of(ec)
|
795
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'ROLLBACK']
|
796
|
-
end
|
797
|
-
|
798
|
-
it "should raise original exception if there is an exception raised when rolling back" do
|
799
|
-
ec = Class.new(StandardError)
|
800
|
-
meta_def(@db, :database_error_classes){[ec]}
|
801
|
-
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /ROLLBACK/ ? raise(ec, 'bad') : super(c, sql)}
|
802
|
-
begin
|
803
|
-
@db.transaction{raise ArgumentError, 'asdf'}
|
804
|
-
rescue => e
|
805
|
-
end
|
806
|
-
e.must_be_kind_of(ArgumentError)
|
807
|
-
@db.sqls.must_equal ['BEGIN']
|
808
|
-
end
|
809
|
-
|
810
|
-
it "should issue ROLLBACK if Sequel::Rollback is called in the transaction" do
|
811
|
-
@db.transaction do
|
812
|
-
@db.drop_table(:a)
|
813
|
-
raise Sequel::Rollback
|
814
|
-
@db.drop_table(:b)
|
815
|
-
end
|
816
|
-
|
817
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
|
818
|
-
end
|
819
|
-
|
820
|
-
it "should have in_transaction? return true if inside a transaction" do
|
821
|
-
c = nil
|
822
|
-
@db.transaction{c = @db.in_transaction?}
|
823
|
-
c.must_equal true
|
824
|
-
end
|
825
|
-
|
826
|
-
it "should have in_transaction? handle sharding correctly" do
|
827
|
-
c = []
|
828
|
-
@db.transaction(:server=>:test){c << @db.in_transaction?}
|
829
|
-
@db.transaction(:server=>:test){c << @db.in_transaction?(:server=>:test)}
|
830
|
-
c.must_equal [false, true]
|
831
|
-
end
|
832
|
-
|
833
|
-
it "should have in_transaction? return false if not in a transaction" do
|
834
|
-
@db.in_transaction?.must_equal false
|
835
|
-
end
|
836
|
-
|
837
|
-
it "should return nil if Sequel::Rollback is called in the transaction" do
|
838
|
-
@db.transaction{raise Sequel::Rollback}.must_equal nil
|
839
|
-
end
|
840
|
-
|
841
|
-
it "should reraise Sequel::Rollback errors when using :rollback=>:reraise option is given" do
|
842
|
-
proc {@db.transaction(:rollback=>:reraise){raise Sequel::Rollback}}.must_raise(Sequel::Rollback)
|
843
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
844
|
-
proc {@db.transaction(:rollback=>:reraise){raise ArgumentError}}.must_raise(ArgumentError)
|
845
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
846
|
-
@db.transaction(:rollback=>:reraise){1}.must_equal 1
|
847
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
848
|
-
end
|
849
|
-
|
850
|
-
it "should always rollback if :rollback=>:always option is given" do
|
851
|
-
proc {@db.transaction(:rollback=>:always){raise ArgumentError}}.must_raise(ArgumentError)
|
852
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
853
|
-
@db.transaction(:rollback=>:always){raise Sequel::Rollback}.must_equal nil
|
854
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
855
|
-
@db.transaction(:rollback=>:always){1}.must_equal 1
|
856
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
857
|
-
catch(:foo) do
|
858
|
-
@db.transaction(:rollback=>:always){throw :foo}
|
859
|
-
end
|
860
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
861
|
-
end
|
862
|
-
|
863
|
-
it "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
864
|
-
meta_def(@db, :commit_transaction){raise ArgumentError}
|
865
|
-
lambda{@db.transaction{}}.must_raise(ArgumentError)
|
866
|
-
|
867
|
-
meta_def(@db, :database_error_classes){[ArgumentError]}
|
868
|
-
lambda{@db.transaction{}}.must_raise(Sequel::DatabaseError)
|
869
|
-
end
|
870
|
-
|
871
|
-
it "should be re-entrant" do
|
872
|
-
q, q1 = Queue.new, Queue.new
|
873
|
-
cc = nil
|
874
|
-
t = Thread.new do
|
875
|
-
@db.transaction {@db.transaction {@db.transaction {|c|
|
876
|
-
cc = c
|
877
|
-
q.pop
|
878
|
-
q1.push nil
|
879
|
-
q.pop
|
880
|
-
}}}
|
881
|
-
end
|
882
|
-
q.push nil
|
883
|
-
q1.pop
|
884
|
-
cc.must_be_kind_of(Sequel::Mock::Connection)
|
885
|
-
tr = @db.instance_variable_get(:@transactions)
|
886
|
-
tr.keys.must_equal [cc]
|
887
|
-
q.push nil
|
888
|
-
t.join
|
889
|
-
tr.must_be :empty?
|
890
|
-
end
|
891
|
-
|
892
|
-
it "should correctly handle nested transacation use with separate shards" do
|
893
|
-
@db.transaction do |c1|
|
894
|
-
@db.transaction(:server=>:test) do |c2|
|
895
|
-
c1.wont_equal c2
|
896
|
-
@db.execute 'DROP TABLE test;'
|
897
|
-
end
|
898
|
-
end
|
899
|
-
@db.sqls.must_equal ['BEGIN', 'BEGIN -- test', 'DROP TABLE test;', 'COMMIT -- test', 'COMMIT']
|
900
|
-
end
|
901
|
-
|
902
|
-
if (!defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby') and !RUBY_VERSION.start_with?('1.9')
|
903
|
-
it "should handle Thread#kill for transactions inside threads" do
|
904
|
-
q = Queue.new
|
905
|
-
q1 = Queue.new
|
906
|
-
t = Thread.new do
|
907
|
-
@db.transaction do
|
908
|
-
@db.execute 'DROP TABLE test'
|
909
|
-
q1.push nil
|
910
|
-
q.pop
|
911
|
-
@db.execute 'DROP TABLE test2'
|
912
|
-
end
|
913
|
-
end
|
914
|
-
q1.pop
|
915
|
-
t.kill
|
916
|
-
t.join
|
917
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
918
|
-
end
|
919
|
-
end
|
920
|
-
|
921
|
-
it "should raise an Error if after_commit or after_rollback is called without a block" do
|
922
|
-
proc{@db.after_commit}.must_raise(Sequel::Error)
|
923
|
-
proc{@db.after_rollback}.must_raise(Sequel::Error)
|
924
|
-
end
|
925
|
-
|
926
|
-
it "should have after_commit and after_rollback respect :server option" do
|
927
|
-
@db.transaction(:server=>:test){@db.after_commit(:server=>:test){@db.execute('foo', :server=>:test)}}
|
928
|
-
@db.sqls.must_equal ['BEGIN -- test', 'COMMIT -- test', 'foo -- test']
|
929
|
-
@db.transaction(:server=>:test){@db.after_rollback(:server=>:test){@db.execute('foo', :server=>:test)}; raise Sequel::Rollback}
|
930
|
-
@db.sqls.must_equal ['BEGIN -- test', 'ROLLBACK -- test', 'foo -- test']
|
931
|
-
end
|
932
|
-
|
933
|
-
it "should execute after_commit outside transactions" do
|
934
|
-
@db.after_commit{@db.execute('foo')}
|
935
|
-
@db.sqls.must_equal ['foo']
|
936
|
-
end
|
937
|
-
|
938
|
-
it "should ignore after_rollback outside transactions" do
|
939
|
-
@db.after_rollback{@db.execute('foo')}
|
940
|
-
@db.sqls.must_equal []
|
941
|
-
end
|
942
|
-
|
943
|
-
it "should support after_commit inside transactions" do
|
944
|
-
@db.transaction{@db.after_commit{@db.execute('foo')}}
|
945
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo']
|
946
|
-
end
|
947
|
-
|
948
|
-
it "should support after_rollback inside transactions" do
|
949
|
-
@db.transaction{@db.after_rollback{@db.execute('foo')}}
|
950
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
951
|
-
end
|
952
|
-
|
953
|
-
it "should have transaction inside after_commit work correctly" do
|
954
|
-
@db.transaction{@db.after_commit{@db.transaction{@db.execute('foo')}}}
|
955
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'BEGIN', 'foo', 'COMMIT']
|
956
|
-
end
|
957
|
-
|
958
|
-
it "should have transaction inside after_rollback work correctly" do
|
959
|
-
@db.transaction(:rollback=>:always){@db.after_rollback{@db.transaction{@db.execute('foo')}}}
|
960
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'foo', 'COMMIT']
|
961
|
-
end
|
962
|
-
|
963
|
-
it "should not call after_commit if the transaction rolls back" do
|
964
|
-
@db.transaction{@db.after_commit{@db.execute('foo')}; raise Sequel::Rollback}
|
965
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
966
|
-
end
|
967
|
-
|
968
|
-
it "should call after_rollback if the transaction rolls back" do
|
969
|
-
@db.transaction{@db.after_rollback{@db.execute('foo')}; raise Sequel::Rollback}
|
970
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo']
|
971
|
-
end
|
972
|
-
|
973
|
-
it "should call multiple after_commit blocks in order if called inside transactions" do
|
974
|
-
@db.transaction{@db.after_commit{@db.execute('foo')}; @db.after_commit{@db.execute('bar')}}
|
975
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo', 'bar']
|
976
|
-
end
|
977
|
-
|
978
|
-
it "should call multiple after_rollback blocks in order if called inside transactions" do
|
979
|
-
@db.transaction{@db.after_rollback{@db.execute('foo')}; @db.after_rollback{@db.execute('bar')}; raise Sequel::Rollback}
|
980
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo', 'bar']
|
981
|
-
end
|
982
|
-
|
983
|
-
it "should support after_commit inside nested transactions" do
|
984
|
-
@db.transaction{@db.transaction{@db.after_commit{@db.execute('foo')}}}
|
985
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo']
|
986
|
-
end
|
987
|
-
|
988
|
-
it "should support after_rollback inside nested transactions" do
|
989
|
-
@db.transaction{@db.transaction{@db.after_rollback{@db.execute('foo')}}; raise Sequel::Rollback}
|
990
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo']
|
991
|
-
end
|
992
|
-
|
993
|
-
it "should raise an error if you attempt to use after_commit inside a prepared transaction" do
|
994
|
-
meta_def(@db, :supports_prepared_transactions?){true}
|
995
|
-
proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{@db.execute('foo')}}}.must_raise(Sequel::Error)
|
996
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
997
|
-
end
|
998
|
-
|
999
|
-
it "should raise an error if you attempt to use after_rollback inside a prepared transaction" do
|
1000
|
-
meta_def(@db, :supports_prepared_transactions?){true}
|
1001
|
-
proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{@db.execute('foo')}}}.must_raise(Sequel::Error)
|
1002
|
-
@db.sqls.must_equal ['BEGIN', 'ROLLBACK']
|
1003
|
-
end
|
1004
|
-
end
|
1005
|
-
|
1006
|
-
describe "Database#transaction with savepoint support" do
|
1007
|
-
before do
|
1008
|
-
@db = Sequel.mock(:servers=>{:test=>{}})
|
1009
|
-
end
|
1010
|
-
|
1011
|
-
include DatabaseTransactionSpecs
|
1012
|
-
|
1013
|
-
it "should support :retry_on option for automatically retrying transactions when using :savepoint option" do
|
1014
|
-
a = []
|
1015
|
-
@db.transaction do
|
1016
|
-
@db.transaction(:retry_on=>Sequel::SerializationFailure, :savepoint=>true) do
|
1017
|
-
a << 1
|
1018
|
-
raise Sequel::SerializationFailure if a.length == 1
|
1019
|
-
end
|
1020
|
-
end
|
1021
|
-
@db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
|
1022
|
-
a.must_equal [1, 1]
|
1023
|
-
end
|
1024
|
-
|
1025
|
-
it "should automatically use a savepoint if :rollback=>:always given inside a transaction" do
|
1026
|
-
@db.transaction do
|
1027
|
-
@db.transaction(:rollback=>:always) do
|
1028
|
-
@db.get(1)
|
1029
|
-
end
|
1030
|
-
end
|
1031
|
-
@db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "SELECT 1 AS v LIMIT 1", "ROLLBACK TO SAVEPOINT autopoint_1", "COMMIT"]
|
1032
|
-
end
|
1033
|
-
|
1034
|
-
it "should support :retry_on option for automatically retrying transactions inside an :auto_savepoint transaction" do
|
1035
|
-
a = []
|
1036
|
-
@db.transaction(:auto_savepoint=>true) do
|
1037
|
-
@db.transaction(:retry_on=>Sequel::SerializationFailure) do
|
1038
|
-
a << 1
|
1039
|
-
raise Sequel::SerializationFailure if a.length == 1
|
1040
|
-
end
|
1041
|
-
end
|
1042
|
-
@db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
|
1043
|
-
a.must_equal [1, 1]
|
1044
|
-
end
|
1045
|
-
|
1046
|
-
it "should support after_commit inside savepoints" do
|
1047
|
-
@db.transaction do
|
1048
|
-
@db.after_commit{@db.execute('foo')}
|
1049
|
-
@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('bar')}}
|
1050
|
-
@db.after_commit{@db.execute('baz')}
|
1051
|
-
end
|
1052
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT', 'foo', 'bar', 'baz']
|
1053
|
-
end
|
1054
|
-
|
1055
|
-
it "should support after_rollback inside savepoints" do
|
1056
|
-
@db.transaction do
|
1057
|
-
@db.after_rollback{@db.execute('foo')}
|
1058
|
-
@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('bar')}}
|
1059
|
-
@db.after_rollback{@db.execute('baz')}
|
1060
|
-
raise Sequel::Rollback
|
1061
|
-
end
|
1062
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'ROLLBACK', 'foo', 'bar', 'baz']
|
1063
|
-
end
|
1064
|
-
|
1065
|
-
it "should raise an error if you attempt to use after_commit inside a savepoint in a prepared transaction" do
|
1066
|
-
meta_def(@db, :supports_prepared_transactions?){true}
|
1067
|
-
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('foo')}}}}.must_raise(Sequel::Error)
|
1068
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
1069
|
-
end
|
1070
|
-
|
1071
|
-
it "should raise an error if you attempt to use after_rollback inside a savepoint in a prepared transaction" do
|
1072
|
-
meta_def(@db, :supports_prepared_transactions?){true}
|
1073
|
-
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('foo')}}}}.must_raise(Sequel::Error)
|
1074
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
1075
|
-
end
|
1076
|
-
|
1077
|
-
it "should create savepoint if inside a transaction when :savepoint=>:only is used" do
|
1078
|
-
@db.transaction{@db.transaction(:savepoint=>:only){}}
|
1079
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1','RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1080
|
-
end
|
1081
|
-
|
1082
|
-
it "should not create transaction if not inside a transaction when :savepoint=>:only is used" do
|
1083
|
-
@db.transaction(:savepoint=>:only){}
|
1084
|
-
@db.sqls.must_equal []
|
1085
|
-
end
|
1086
|
-
end
|
1087
|
-
|
1088
|
-
describe "Database#transaction without savepoint support" do
|
1089
|
-
before do
|
1090
|
-
@db = Sequel.mock(:servers=>{:test=>{}})
|
1091
|
-
meta_def(@db, :supports_savepoints?){false}
|
1092
|
-
end
|
1093
|
-
|
1094
|
-
it "should not create savepoint if inside a transaction when :savepoint=>:only is used" do
|
1095
|
-
@db.transaction{@db.transaction(:savepoint=>:only){}}
|
1096
|
-
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
1097
|
-
end
|
1098
|
-
|
1099
|
-
it "should automatically use a savepoint if :rollback=>:always given inside a transaction" do
|
1100
|
-
proc do
|
1101
|
-
@db.transaction do
|
1102
|
-
@db.transaction(:rollback=>:always) do
|
1103
|
-
@db.get(1)
|
1104
|
-
end
|
1105
|
-
end
|
1106
|
-
end.must_raise Sequel::Error
|
1107
|
-
@db.sqls.must_equal ["BEGIN", "ROLLBACK"]
|
1108
|
-
end
|
1109
|
-
|
1110
|
-
include DatabaseTransactionSpecs
|
1111
|
-
end
|
1112
|
-
|
1113
|
-
describe "Sequel.transaction" do
|
1114
|
-
before do
|
1115
|
-
@sqls = []
|
1116
|
-
@db1 = Sequel.mock(:append=>'1', :sqls=>@sqls)
|
1117
|
-
@db2 = Sequel.mock(:append=>'2', :sqls=>@sqls)
|
1118
|
-
@db3 = Sequel.mock(:append=>'3', :sqls=>@sqls)
|
1119
|
-
end
|
1120
|
-
|
1121
|
-
it "should run the block inside transacitons on all three databases" do
|
1122
|
-
Sequel.transaction([@db1, @db2, @db3]){1}.must_equal 1
|
1123
|
-
@sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
it "should pass options to all the blocks" do
|
1127
|
-
Sequel.transaction([@db1, @db2, @db3], :rollback=>:always){1}.must_equal 1
|
1128
|
-
@sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
it "should handle Sequel::Rollback exceptions raised by the block to rollback on all databases" do
|
1132
|
-
Sequel.transaction([@db1, @db2, @db3]){raise Sequel::Rollback}.must_equal nil
|
1133
|
-
@sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
|
1134
|
-
end
|
1135
|
-
|
1136
|
-
it "should handle nested transactions" do
|
1137
|
-
Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3]){1}}.must_equal 1
|
1138
|
-
@sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
1139
|
-
end
|
1140
|
-
|
1141
|
-
it "should handle savepoints" do
|
1142
|
-
Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3], :savepoint=>true){1}}.must_equal 1
|
1143
|
-
@sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3',
|
1144
|
-
'SAVEPOINT autopoint_1 -- 1', 'SAVEPOINT autopoint_1 -- 2', 'SAVEPOINT autopoint_1 -- 3',
|
1145
|
-
'RELEASE SAVEPOINT autopoint_1 -- 3', 'RELEASE SAVEPOINT autopoint_1 -- 2', 'RELEASE SAVEPOINT autopoint_1 -- 1',
|
1146
|
-
'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
1147
|
-
end
|
1148
|
-
end
|
1149
|
-
|
1150
|
-
describe "Database#transaction with savepoints" do
|
1151
|
-
before do
|
1152
|
-
@db = Sequel.mock
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
it "should wrap the supplied block with BEGIN + COMMIT statements" do
|
1156
|
-
@db.transaction {@db.execute 'DROP TABLE test;'}
|
1157
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
it "should use savepoints if given the :savepoint option" do
|
1161
|
-
@db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}}
|
1162
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1163
|
-
end
|
1164
|
-
|
1165
|
-
it "should use savepoints if surrounding transaction uses :auto_savepoint option" do
|
1166
|
-
@db.transaction(:auto_savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}
|
1167
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1168
|
-
|
1169
|
-
@db.transaction(:auto_savepoint=>true){@db.transaction{@db.transaction{@db.execute 'DROP TABLE test;'}}}
|
1170
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1171
|
-
|
1172
|
-
@db.transaction(:auto_savepoint=>true){@db.transaction(:auto_savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}}
|
1173
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'SAVEPOINT autopoint_2', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_2', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1174
|
-
|
1175
|
-
@db.transaction{@db.transaction(:auto_savepoint=>true, :savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}}
|
1176
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'SAVEPOINT autopoint_2', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_2', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1177
|
-
end
|
1178
|
-
|
1179
|
-
it "should not use savepoints if surrounding transaction uses :auto_savepoint and current transaction uses :savepoint=>false option" do
|
1180
|
-
@db.transaction(:auto_savepoint=>true){@db.transaction(:savepoint=>false){@db.execute 'DROP TABLE test;'}}
|
1181
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1182
|
-
end
|
1183
|
-
|
1184
|
-
it "should not use a savepoint if no transaction is in progress" do
|
1185
|
-
@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}
|
1186
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1187
|
-
end
|
1188
|
-
|
1189
|
-
it "should reuse the current transaction if no :savepoint option is given" do
|
1190
|
-
@db.transaction{@db.transaction{@db.execute 'DROP TABLE test;'}}
|
1191
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1192
|
-
end
|
1193
|
-
|
1194
|
-
it "should handle returning inside of the block by committing" do
|
1195
|
-
def @db.ret_commit
|
1196
|
-
transaction do
|
1197
|
-
execute 'DROP TABLE test;'
|
1198
|
-
return
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
@db.ret_commit
|
1202
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1203
|
-
end
|
1204
|
-
|
1205
|
-
it "should handle returning inside of a savepoint by committing" do
|
1206
|
-
def @db.ret_commit
|
1207
|
-
transaction do
|
1208
|
-
transaction(:savepoint=>true) do
|
1209
|
-
execute 'DROP TABLE test;'
|
1210
|
-
return
|
1211
|
-
end
|
1212
|
-
end
|
1213
|
-
end
|
1214
|
-
@db.ret_commit
|
1215
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1216
|
-
end
|
1217
|
-
|
1218
|
-
it "should issue ROLLBACK if an exception is raised, and re-raise" do
|
1219
|
-
@db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
|
1220
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
1221
|
-
|
1222
|
-
proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
|
1223
|
-
end
|
1224
|
-
|
1225
|
-
it "should issue ROLLBACK SAVEPOINT if an exception is raised inside a savepoint, and re-raise" do
|
1226
|
-
@db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test'; raise RuntimeError}} rescue nil
|
1227
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test', 'ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
1228
|
-
|
1229
|
-
proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
|
1230
|
-
end
|
1231
|
-
|
1232
|
-
it "should issue ROLLBACK if Sequel::Rollback is raised in the transaction" do
|
1233
|
-
@db.transaction do
|
1234
|
-
@db.drop_table(:a)
|
1235
|
-
raise Sequel::Rollback
|
1236
|
-
@db.drop_table(:b)
|
1237
|
-
end
|
1238
|
-
|
1239
|
-
@db.sqls.must_equal ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
|
1240
|
-
end
|
1241
|
-
|
1242
|
-
it "should issue ROLLBACK SAVEPOINT if Sequel::Rollback is raised in a savepoint" do
|
1243
|
-
@db.transaction do
|
1244
|
-
@db.transaction(:savepoint=>true) do
|
1245
|
-
@db.drop_table(:a)
|
1246
|
-
raise Sequel::Rollback
|
1247
|
-
end
|
1248
|
-
@db.drop_table(:b)
|
1249
|
-
end
|
1250
|
-
|
1251
|
-
@db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE a', 'ROLLBACK TO SAVEPOINT autopoint_1', 'DROP TABLE b', 'COMMIT']
|
1252
|
-
end
|
1253
|
-
|
1254
|
-
it "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
1255
|
-
meta_def(@db, :commit_transaction){raise ArgumentError}
|
1256
|
-
lambda{@db.transaction{}}.must_raise(ArgumentError)
|
1257
|
-
lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.must_raise(ArgumentError)
|
1258
|
-
|
1259
|
-
meta_def(@db, :database_error_classes){[ArgumentError]}
|
1260
|
-
lambda{@db.transaction{}}.must_raise(Sequel::DatabaseError)
|
1261
|
-
lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.must_raise(Sequel::DatabaseError)
|
1262
|
-
end
|
1263
|
-
end
|
1264
|
-
|
1265
|
-
describe "A Database adapter with a scheme" do
|
1266
|
-
before do
|
1267
|
-
require 'sequel/adapters/mock'
|
1268
|
-
@ccc = Class.new(Sequel::Mock::Database)
|
1269
|
-
@ccc.send(:set_adapter_scheme, :ccc)
|
1270
|
-
end
|
1271
|
-
|
1272
|
-
it "should be registered in the ADAPTER_MAP" do
|
1273
|
-
Sequel::ADAPTER_MAP[:ccc].must_equal @ccc
|
1274
|
-
end
|
1275
|
-
|
1276
|
-
it "should give the database_type as the adapter scheme by default" do
|
1277
|
-
@ccc.new.database_type.must_equal :ccc
|
1278
|
-
end
|
1279
|
-
|
1280
|
-
it "should be instantiated when its scheme is specified" do
|
1281
|
-
c = Sequel::Database.connect('ccc://localhost/db')
|
1282
|
-
c.must_be_kind_of(@ccc)
|
1283
|
-
c.opts[:host].must_equal 'localhost'
|
1284
|
-
c.opts[:database].must_equal 'db'
|
1285
|
-
end
|
1286
|
-
|
1287
|
-
it "should be accessible through Sequel.connect" do
|
1288
|
-
c = Sequel.connect 'ccc://localhost/db'
|
1289
|
-
c.must_be_kind_of(@ccc)
|
1290
|
-
c.opts[:host].must_equal 'localhost'
|
1291
|
-
c.opts[:database].must_equal 'db'
|
1292
|
-
end
|
1293
|
-
|
1294
|
-
it "should be accessible through Sequel.connect via a block" do
|
1295
|
-
x = nil
|
1296
|
-
y = nil
|
1297
|
-
z = nil
|
1298
|
-
returnValue = 'anything'
|
1299
|
-
|
1300
|
-
p = proc do |c|
|
1301
|
-
c.must_be_kind_of(@ccc)
|
1302
|
-
c.opts[:host].must_equal 'localhost'
|
1303
|
-
c.opts[:database].must_equal 'db'
|
1304
|
-
z = y
|
1305
|
-
y = x
|
1306
|
-
x = c
|
1307
|
-
returnValue
|
1308
|
-
end
|
1309
|
-
|
1310
|
-
@ccc.class_eval do
|
1311
|
-
self::DISCONNECTS = []
|
1312
|
-
def disconnect
|
1313
|
-
self.class::DISCONNECTS << self
|
1314
|
-
end
|
1315
|
-
end
|
1316
|
-
Sequel::Database.connect('ccc://localhost/db', &p).must_equal returnValue
|
1317
|
-
@ccc::DISCONNECTS.must_equal [x]
|
1318
|
-
|
1319
|
-
Sequel.connect('ccc://localhost/db', &p).must_equal returnValue
|
1320
|
-
@ccc::DISCONNECTS.must_equal [y, x]
|
1321
|
-
|
1322
|
-
Sequel.send(:def_adapter_method, :ccc)
|
1323
|
-
Sequel.ccc('db', :host=>'localhost', &p).must_equal returnValue
|
1324
|
-
@ccc::DISCONNECTS.must_equal [z, y, x]
|
1325
|
-
class << Sequel; remove_method(:ccc) end
|
1326
|
-
end
|
1327
|
-
|
1328
|
-
it "should be accessible through Sequel.<adapter>" do
|
1329
|
-
Sequel.send(:def_adapter_method, :ccc)
|
1330
|
-
|
1331
|
-
# invalid parameters
|
1332
|
-
proc {Sequel.ccc('abc', 'def')}.must_raise(Sequel::Error)
|
1333
|
-
proc {Sequel.ccc(1)}.must_raise(Sequel::Error)
|
1334
|
-
|
1335
|
-
c = Sequel.ccc('mydb')
|
1336
|
-
c.must_be_kind_of(@ccc)
|
1337
|
-
c.opts.values_at(:adapter, :database, :adapter_class).must_equal [:ccc, 'mydb', @ccc]
|
1338
|
-
|
1339
|
-
c = Sequel.ccc('mydb', :host => 'localhost')
|
1340
|
-
c.must_be_kind_of(@ccc)
|
1341
|
-
c.opts.values_at(:adapter, :database, :host, :adapter_class).must_equal [:ccc, 'mydb', 'localhost', @ccc]
|
1342
|
-
|
1343
|
-
c = Sequel.ccc
|
1344
|
-
c.must_be_kind_of(@ccc)
|
1345
|
-
c.opts.values_at(:adapter, :adapter_class).must_equal [:ccc, @ccc]
|
1346
|
-
|
1347
|
-
c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
|
1348
|
-
c.must_be_kind_of(@ccc)
|
1349
|
-
c.opts.values_at(:adapter, :database, :host, :adapter_class).must_equal [:ccc, 'mydb', 'localhost', @ccc]
|
1350
|
-
class << Sequel; remove_method(:ccc) end
|
1351
|
-
end
|
1352
|
-
|
1353
|
-
it "should be accessible through Sequel.connect with options" do
|
1354
|
-
c = Sequel.connect(:adapter => :ccc, :database => 'mydb')
|
1355
|
-
c.must_be_kind_of(@ccc)
|
1356
|
-
c.opts[:adapter].must_equal :ccc
|
1357
|
-
end
|
1358
|
-
|
1359
|
-
it "should be accessible through Sequel.connect with URL parameters" do
|
1360
|
-
c = Sequel.connect 'ccc:///db?host=/tmp&user=test'
|
1361
|
-
c.must_be_kind_of(@ccc)
|
1362
|
-
c.opts[:host].must_equal '/tmp'
|
1363
|
-
c.opts[:database].must_equal 'db'
|
1364
|
-
c.opts[:user].must_equal 'test'
|
1365
|
-
end
|
1366
|
-
|
1367
|
-
it "should have URL parameters take precedence over fixed URL parts" do
|
1368
|
-
c = Sequel.connect 'ccc://localhost/db?host=a&database=b'
|
1369
|
-
c.must_be_kind_of(@ccc)
|
1370
|
-
c.opts[:host].must_equal 'a'
|
1371
|
-
c.opts[:database].must_equal 'b'
|
1372
|
-
end
|
1373
|
-
|
1374
|
-
it "should have hash options take predence over URL parameters or parts" do
|
1375
|
-
c = Sequel.connect 'ccc://localhost/db?host=/tmp', :host=>'a', :database=>'b', :user=>'c'
|
1376
|
-
c.must_be_kind_of(@ccc)
|
1377
|
-
c.opts[:host].must_equal 'a'
|
1378
|
-
c.opts[:database].must_equal 'b'
|
1379
|
-
c.opts[:user].must_equal 'c'
|
1380
|
-
end
|
1381
|
-
|
1382
|
-
it "should unescape values of URL parameters and parts" do
|
1383
|
-
c = Sequel.connect 'ccc:///d%5bb%5d?host=domain%5cinstance'
|
1384
|
-
c.must_be_kind_of(@ccc)
|
1385
|
-
c.opts[:database].must_equal 'd[b]'
|
1386
|
-
c.opts[:host].must_equal 'domain\\instance'
|
1387
|
-
end
|
1388
|
-
|
1389
|
-
it "should test the connection if test parameter is truthy" do
|
1390
|
-
@ccc.send(:define_method, :connect){}
|
1391
|
-
proc{Sequel.connect 'ccc:///d%5bb%5d?test=t'}.must_raise(Sequel::DatabaseConnectionError)
|
1392
|
-
proc{Sequel.connect 'ccc:///d%5bb%5d?test=1'}.must_raise(Sequel::DatabaseConnectionError)
|
1393
|
-
proc{Sequel.connect 'ccc:///d%5bb%5d', :test=>true}.must_raise(Sequel::DatabaseConnectionError)
|
1394
|
-
proc{Sequel.connect 'ccc:///d%5bb%5d', :test=>'t'}.must_raise(Sequel::DatabaseConnectionError)
|
1395
|
-
end
|
1396
|
-
|
1397
|
-
it "should not test the connection if test parameter is not truthy" do
|
1398
|
-
Sequel.connect 'ccc:///d%5bb%5d?test=f'
|
1399
|
-
Sequel.connect 'ccc:///d%5bb%5d?test=0'
|
1400
|
-
Sequel.connect 'ccc:///d%5bb%5d', :test=>false
|
1401
|
-
Sequel.connect 'ccc:///d%5bb%5d', :test=>'f'
|
1402
|
-
end
|
1403
|
-
end
|
1404
|
-
|
1405
|
-
describe "Sequel::Database.connect" do
|
1406
|
-
it "should raise an Error if not given a String or Hash" do
|
1407
|
-
proc{Sequel::Database.connect(nil)}.must_raise(Sequel::Error)
|
1408
|
-
proc{Sequel::Database.connect(Object.new)}.must_raise(Sequel::Error)
|
1409
|
-
end
|
1410
|
-
end
|
1411
|
-
|
1412
|
-
describe "An unknown database scheme" do
|
1413
|
-
it "should raise an error in Sequel::Database.connect" do
|
1414
|
-
proc {Sequel::Database.connect('ddd://localhost/db')}.must_raise(Sequel::AdapterNotFound)
|
1415
|
-
end
|
1416
|
-
|
1417
|
-
it "should raise an error in Sequel.connect" do
|
1418
|
-
proc {Sequel.connect('ddd://localhost/db')}.must_raise(Sequel::AdapterNotFound)
|
1419
|
-
end
|
1420
|
-
end
|
1421
|
-
|
1422
|
-
describe "A broken adapter (lib is there but the class is not)" do
|
1423
|
-
before do
|
1424
|
-
@fn = File.join(File.dirname(__FILE__), '../../lib/sequel/adapters/blah.rb')
|
1425
|
-
File.open(@fn,'a'){}
|
1426
|
-
end
|
1427
|
-
|
1428
|
-
after do
|
1429
|
-
File.delete(@fn)
|
1430
|
-
end
|
1431
|
-
|
1432
|
-
it "should raise an error" do
|
1433
|
-
proc {Sequel.connect('blah://blow')}.must_raise(Sequel::AdapterNotFound)
|
1434
|
-
end
|
1435
|
-
end
|
1436
|
-
|
1437
|
-
describe "Sequel::Database.load_adapter" do
|
1438
|
-
it "should not raise an error if subadapter does not exist" do
|
1439
|
-
Sequel::Database.load_adapter(:foo, :subdir=>'bar').must_equal nil
|
1440
|
-
end
|
1441
|
-
end
|
1442
|
-
|
1443
|
-
describe "A single threaded database" do
|
1444
|
-
after do
|
1445
|
-
Sequel::Database.single_threaded = false
|
1446
|
-
end
|
1447
|
-
|
1448
|
-
it "should use a SingleConnectionPool instead of a ConnectionPool" do
|
1449
|
-
db = Sequel::Database.new(:single_threaded => true){123}
|
1450
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
1451
|
-
end
|
1452
|
-
|
1453
|
-
it "should be constructable using :single_threaded => true option" do
|
1454
|
-
db = Sequel::Database.new(:single_threaded => true){123}
|
1455
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
1456
|
-
end
|
1457
|
-
|
1458
|
-
it "should be constructable using Database.single_threaded = true" do
|
1459
|
-
Sequel::Database.single_threaded = true
|
1460
|
-
db = Sequel::Database.new{123}
|
1461
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
1462
|
-
end
|
1463
|
-
|
1464
|
-
it "should be constructable using Sequel.single_threaded = true" do
|
1465
|
-
Sequel.single_threaded = true
|
1466
|
-
db = Sequel::Database.new{123}
|
1467
|
-
db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
|
1468
|
-
end
|
1469
|
-
end
|
1470
|
-
|
1471
|
-
describe "A single threaded database" do
|
1472
|
-
before do
|
1473
|
-
conn = 1234567
|
1474
|
-
@db = Sequel::Database.new(:single_threaded => true)
|
1475
|
-
meta_def(@db, :connect) do |c|
|
1476
|
-
conn += 1
|
1477
|
-
end
|
1478
|
-
end
|
1479
|
-
|
1480
|
-
it "should invoke connection_proc only once" do
|
1481
|
-
@db.pool.hold {|c| c.must_equal 1234568}
|
1482
|
-
@db.pool.hold {|c| c.must_equal 1234568}
|
1483
|
-
end
|
1484
|
-
|
1485
|
-
it "should disconnect correctly" do
|
1486
|
-
def @db.disconnect_connection(c); @dc = c end
|
1487
|
-
def @db.dc; @dc end
|
1488
|
-
x = nil
|
1489
|
-
@db.pool.hold{|c| x = c}
|
1490
|
-
@db.pool.hold{|c| c.must_equal x}
|
1491
|
-
@db.disconnect
|
1492
|
-
@db.dc.must_equal x
|
1493
|
-
end
|
1494
|
-
|
1495
|
-
it "should convert an Exception on connection into a DatabaseConnectionError" do
|
1496
|
-
db = Sequel::Database.new(:single_threaded => true, :servers=>{})
|
1497
|
-
def db.connect(*) raise Exception end
|
1498
|
-
proc {db.pool.hold {|c|}}.must_raise(Sequel::DatabaseConnectionError)
|
1499
|
-
end
|
1500
|
-
|
1501
|
-
it "should raise a DatabaseConnectionError if the connection proc returns nil" do
|
1502
|
-
db = Sequel.mock(:single_threaded => true, :servers=>{})
|
1503
|
-
def db.connect(*) end
|
1504
|
-
proc {db.pool.hold {|c|}}.must_raise(Sequel::DatabaseConnectionError)
|
1505
|
-
end
|
1506
|
-
end
|
1507
|
-
|
1508
|
-
describe "A database" do
|
1509
|
-
after do
|
1510
|
-
Sequel::Database.single_threaded = false
|
1511
|
-
end
|
1512
|
-
|
1513
|
-
it "should have single_threaded? respond to true if in single threaded mode" do
|
1514
|
-
db = Sequel::Database.new(:single_threaded => true){1234}
|
1515
|
-
db.must_be :single_threaded?
|
1516
|
-
|
1517
|
-
db = Sequel::Database.new(:max_options => 1)
|
1518
|
-
db.wont_be :single_threaded?
|
1519
|
-
|
1520
|
-
db = Sequel::Database.new
|
1521
|
-
db.wont_be :single_threaded?
|
1522
|
-
|
1523
|
-
Sequel::Database.single_threaded = true
|
1524
|
-
|
1525
|
-
db = Sequel::Database.new{123}
|
1526
|
-
db.must_be :single_threaded?
|
1527
|
-
|
1528
|
-
db = Sequel::Database.new(:max_options => 4){123}
|
1529
|
-
db.must_be :single_threaded?
|
1530
|
-
end
|
1531
|
-
|
1532
|
-
it "should be able to set loggers via the logger= and loggers= methods" do
|
1533
|
-
db = Sequel::Database.new
|
1534
|
-
s = "I'm a logger"
|
1535
|
-
db.logger = s
|
1536
|
-
db.loggers.must_equal [s]
|
1537
|
-
db.logger = nil
|
1538
|
-
db.loggers.must_equal []
|
1539
|
-
|
1540
|
-
db.loggers = [s]
|
1541
|
-
db.loggers.must_equal [s]
|
1542
|
-
db.loggers = []
|
1543
|
-
db.loggers.must_equal []
|
1544
|
-
|
1545
|
-
t = "I'm also a logger"
|
1546
|
-
db.loggers = [s, t]
|
1547
|
-
db.loggers.must_equal [s,t]
|
1548
|
-
end
|
1549
|
-
end
|
1550
|
-
|
1551
|
-
describe "Database#fetch" do
|
1552
|
-
before do
|
1553
|
-
@db = Sequel.mock(:fetch=>proc{|sql| {:sql => sql}})
|
1554
|
-
end
|
1555
|
-
|
1556
|
-
it "should create a dataset and invoke its fetch_rows method with the given sql" do
|
1557
|
-
sql = nil
|
1558
|
-
@db.fetch('select * from xyz') {|r| sql = r[:sql]}
|
1559
|
-
sql.must_equal 'select * from xyz'
|
1560
|
-
end
|
1561
|
-
|
1562
|
-
it "should format the given sql with any additional arguments" do
|
1563
|
-
sql = nil
|
1564
|
-
@db.fetch('select * from xyz where x = ? and y = ?', 15, 'abc') {|r| sql = r[:sql]}
|
1565
|
-
sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
|
1566
|
-
|
1567
|
-
@db.fetch('select name from table where name = ? or id in ?', 'aman', [3,4,7]) {|r| sql = r[:sql]}
|
1568
|
-
sql.must_equal "select name from table where name = 'aman' or id in (3, 4, 7)"
|
1569
|
-
end
|
1570
|
-
|
1571
|
-
it "should format the given sql with named arguments" do
|
1572
|
-
sql = nil
|
1573
|
-
@db.fetch('select * from xyz where x = :x and y = :y', :x=>15, :y=>'abc') {|r| sql = r[:sql]}
|
1574
|
-
sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
|
1575
|
-
end
|
1576
|
-
|
1577
|
-
it "should return the dataset if no block is given" do
|
1578
|
-
@db.fetch('select * from xyz').must_be_kind_of(Sequel::Dataset)
|
1579
|
-
|
1580
|
-
@db.fetch('select a from b').map {|r| r[:sql]}.must_equal ['select a from b']
|
1581
|
-
|
1582
|
-
@db.fetch('select c from d').inject([]) {|m, r| m << r; m}.must_equal \
|
1583
|
-
[{:sql => 'select c from d'}]
|
1584
|
-
end
|
1585
|
-
|
1586
|
-
it "should return a dataset that always uses the given sql for SELECTs" do
|
1587
|
-
ds = @db.fetch('select * from xyz')
|
1588
|
-
ds.select_sql.must_equal 'select * from xyz'
|
1589
|
-
ds.sql.must_equal 'select * from xyz'
|
1590
|
-
|
1591
|
-
ds.filter!{price.sql_number < 100}
|
1592
|
-
ds.select_sql.must_equal 'select * from xyz'
|
1593
|
-
ds.sql.must_equal 'select * from xyz'
|
1594
|
-
end
|
1595
|
-
end
|
1596
|
-
|
1597
|
-
|
1598
|
-
describe "Database#[]" do
|
1599
|
-
before do
|
1600
|
-
@db = Sequel.mock
|
1601
|
-
end
|
1602
|
-
|
1603
|
-
it "should return a dataset when symbols are given" do
|
1604
|
-
ds = @db[:items]
|
1605
|
-
ds.must_be_kind_of(Sequel::Dataset)
|
1606
|
-
ds.opts[:from].must_equal [:items]
|
1607
|
-
end
|
1608
|
-
|
1609
|
-
it "should return a dataset when a string is given" do
|
1610
|
-
@db.fetch = proc{|sql| {:sql=>sql}}
|
1611
|
-
sql = nil
|
1612
|
-
@db['select * from xyz where x = ? and y = ?', 15, 'abc'].each {|r| sql = r[:sql]}
|
1613
|
-
sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
|
1614
|
-
end
|
1615
|
-
end
|
1616
|
-
|
1617
|
-
describe "Database#inspect" do
|
1618
|
-
it "should include the class name and the connection url" do
|
1619
|
-
Sequel.connect('mock://foo/bar').inspect.must_equal '#<Sequel::Mock::Database: "mock://foo/bar">'
|
1620
|
-
end
|
1621
|
-
|
1622
|
-
it "should include the class name and the connection options if an options hash was given" do
|
1623
|
-
Sequel.connect(:adapter=>:mock).inspect.must_match(/#<Sequel::Mock::Database: \{:adapter=>:mock\}>/)
|
1624
|
-
end
|
1625
|
-
|
1626
|
-
it "should include the class name, uri, and connection options if uri and options hash was given" do
|
1627
|
-
Sequel.connect('mock://foo', :database=>'bar').inspect.must_match(/#<Sequel::Mock::Database: "mock:\/\/foo" \{:database=>"bar"\}>/)
|
1628
|
-
end
|
1629
|
-
end
|
1630
|
-
|
1631
|
-
describe "Database#get" do
|
1632
|
-
before do
|
1633
|
-
@db = Sequel.mock(:fetch=>{:a=>1})
|
1634
|
-
end
|
1635
|
-
|
1636
|
-
it "should use Dataset#get to get a single value" do
|
1637
|
-
@db.get(:a).must_equal 1
|
1638
|
-
@db.sqls.must_equal ['SELECT a LIMIT 1']
|
1639
|
-
|
1640
|
-
@db.get(Sequel.function(:version).as(:version))
|
1641
|
-
@db.sqls.must_equal ['SELECT version() AS version LIMIT 1']
|
1642
|
-
end
|
1643
|
-
|
1644
|
-
it "should accept a block" do
|
1645
|
-
@db.get{a}
|
1646
|
-
@db.sqls.must_equal ['SELECT a LIMIT 1']
|
1647
|
-
|
1648
|
-
@db.get{version(a).as(version)}
|
1649
|
-
@db.sqls.must_equal ['SELECT version(a) AS version LIMIT 1']
|
1650
|
-
end
|
1651
|
-
|
1652
|
-
it "should work when an alias cannot be determined" do
|
1653
|
-
@db.get(1).must_equal 1
|
1654
|
-
@db.sqls.must_equal ['SELECT 1 AS v LIMIT 1']
|
1655
|
-
end
|
1656
|
-
end
|
1657
|
-
|
1658
|
-
describe "Database#call" do
|
1659
|
-
it "should call the prepared statement with the given name" do
|
1660
|
-
db = Sequel.mock(:fetch=>{:id => 1, :x => 1})
|
1661
|
-
db[:items].prepare(:select, :select_all)
|
1662
|
-
db.call(:select_all).must_equal [{:id => 1, :x => 1}]
|
1663
|
-
db[:items].filter(:n=>:$n).prepare(:select, :select_n)
|
1664
|
-
db.call(:select_n, :n=>1).must_equal [{:id => 1, :x => 1}]
|
1665
|
-
db.sqls.must_equal ['SELECT * FROM items', 'SELECT * FROM items WHERE (n = 1)']
|
1666
|
-
end
|
1667
|
-
end
|
1668
|
-
|
1669
|
-
describe "Database#server_opts" do
|
1670
|
-
it "should return the general opts if no :servers option is used" do
|
1671
|
-
opts = {:host=>1, :database=>2}
|
1672
|
-
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 1
|
1673
|
-
end
|
1674
|
-
|
1675
|
-
it "should return the general opts if entry for the server is present in the :servers option" do
|
1676
|
-
opts = {:host=>1, :database=>2, :servers=>{}}
|
1677
|
-
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 1
|
1678
|
-
end
|
1679
|
-
|
1680
|
-
it "should return the general opts merged with the specific opts if given as a hash" do
|
1681
|
-
opts = {:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}}}
|
1682
|
-
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 3
|
1683
|
-
end
|
1684
|
-
|
1685
|
-
it "should return the sgeneral opts merged with the specific opts if given as a proc" do
|
1686
|
-
opts = {:host=>1, :database=>2, :servers=>{:server1=>proc{|db| {:host=>4}}}}
|
1687
|
-
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 4
|
1688
|
-
end
|
1689
|
-
|
1690
|
-
it "should raise an error if the specific opts is not a proc or hash" do
|
1691
|
-
opts = {:host=>1, :database=>2, :servers=>{:server1=>2}}
|
1692
|
-
proc{Sequel::Database.new(opts).send(:server_opts, :server1)}.must_raise(Sequel::Error)
|
1693
|
-
end
|
1694
|
-
|
1695
|
-
it "should return the general opts merged with given opts if given opts is a Hash" do
|
1696
|
-
opts = {:host=>1, :database=>2}
|
1697
|
-
Sequel::Database.new(opts).send(:server_opts, :host=>2)[:host].must_equal 2
|
1698
|
-
end
|
1699
|
-
end
|
1700
|
-
|
1701
|
-
describe "Database#add_servers" do
|
1702
|
-
before do
|
1703
|
-
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
|
1704
|
-
end
|
1705
|
-
|
1706
|
-
it "should add new servers to the connection pool" do
|
1707
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1708
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1709
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
|
1710
|
-
|
1711
|
-
@db.add_servers(:server2=>{:host=>6})
|
1712
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1713
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1714
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 6}
|
1715
|
-
|
1716
|
-
@db.disconnect
|
1717
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1718
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1719
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 6}
|
1720
|
-
end
|
1721
|
-
|
1722
|
-
it "should replace options for future connections to existing servers" do
|
1723
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1724
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1725
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
|
1726
|
-
|
1727
|
-
@db.add_servers(:default=>proc{{:host=>4}}, :server1=>{:host=>8})
|
1728
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1729
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1730
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
|
1731
|
-
|
1732
|
-
@db.disconnect
|
1733
|
-
@db.synchronize{|c| c.opts[:host].must_equal 4}
|
1734
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 8}
|
1735
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 4}
|
1736
|
-
end
|
1737
|
-
end
|
1738
|
-
|
1739
|
-
describe "Database#remove_servers" do
|
1740
|
-
before do
|
1741
|
-
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
|
1742
|
-
end
|
1743
|
-
|
1744
|
-
it "should remove servers from the connection pool" do
|
1745
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1746
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
|
1747
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 4}
|
1748
|
-
|
1749
|
-
@db.remove_servers(:server1, :server2)
|
1750
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1751
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 1}
|
1752
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
|
1753
|
-
end
|
1754
|
-
|
1755
|
-
it "should accept arrays of symbols" do
|
1756
|
-
@db.remove_servers([:server1, :server2])
|
1757
|
-
@db.synchronize{|c| c.opts[:host].must_equal 1}
|
1758
|
-
@db.synchronize(:server1){|c| c.opts[:host].must_equal 1}
|
1759
|
-
@db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
|
1760
|
-
end
|
1761
|
-
|
1762
|
-
it "should allow removal while connections are still open" do
|
1763
|
-
@db.synchronize do |c1|
|
1764
|
-
c1.opts[:host].must_equal 1
|
1765
|
-
@db.synchronize(:server1) do |c2|
|
1766
|
-
c2.opts[:host].must_equal 3
|
1767
|
-
@db.synchronize(:server2) do |c3|
|
1768
|
-
c3.opts[:host].must_equal 4
|
1769
|
-
@db.remove_servers(:server1, :server2)
|
1770
|
-
@db.synchronize(:server1) do |c4|
|
1771
|
-
c4.wont_equal c2
|
1772
|
-
c4.must_equal c1
|
1773
|
-
c4.opts[:host].must_equal 1
|
1774
|
-
@db.synchronize(:server2) do |c5|
|
1775
|
-
c5.wont_equal c3
|
1776
|
-
c5.must_equal c1
|
1777
|
-
c5.opts[:host].must_equal 1
|
1778
|
-
end
|
1779
|
-
end
|
1780
|
-
c3.opts[:host].must_equal 4
|
1781
|
-
end
|
1782
|
-
c2.opts[:host].must_equal 3
|
1783
|
-
end
|
1784
|
-
c1.opts[:host].must_equal 1
|
1785
|
-
end
|
1786
|
-
end
|
1787
|
-
end
|
1788
|
-
|
1789
|
-
describe "Database#each_server with do/jdbc adapter connection string without :adapter option" do
|
1790
|
-
it "should yield a separate database object for each server" do
|
1791
|
-
require 'sequel/adapters/mock'
|
1792
|
-
klass = Class.new(Sequel::Database)
|
1793
|
-
def klass.adapter_class(v)
|
1794
|
-
raise unless v == :jdbc
|
1795
|
-
Sequel::Mock::Database
|
1796
|
-
end
|
1797
|
-
@db = klass.connect('jdbc:blah:', :host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
|
1798
|
-
|
1799
|
-
hosts = []
|
1800
|
-
@db.each_server do |db|
|
1801
|
-
db.must_be_kind_of(Sequel::Database)
|
1802
|
-
db.wont_equal @db
|
1803
|
-
db.opts[:adapter_class].must_equal Sequel::Mock::Database
|
1804
|
-
db.opts[:database].must_equal 2
|
1805
|
-
hosts << db.opts[:host]
|
1806
|
-
end
|
1807
|
-
hosts.sort.must_equal [1, 3]
|
1808
|
-
end
|
1809
|
-
|
1810
|
-
it "should raise if not given a block" do
|
1811
|
-
proc{Sequel.mock.each_server}.must_raise(Sequel::Error)
|
1812
|
-
end
|
1813
|
-
end
|
1814
|
-
|
1815
|
-
describe "Database#each_server" do
|
1816
|
-
before do
|
1817
|
-
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
|
1818
|
-
end
|
1819
|
-
|
1820
|
-
it "should yield a separate database object for each server" do
|
1821
|
-
hosts = []
|
1822
|
-
@db.each_server do |db|
|
1823
|
-
db.must_be_kind_of(Sequel::Database)
|
1824
|
-
db.wont_equal @db
|
1825
|
-
db.opts[:adapter].must_equal :mock
|
1826
|
-
db.opts[:database].must_equal 2
|
1827
|
-
hosts << db.opts[:host]
|
1828
|
-
end
|
1829
|
-
hosts.sort.must_equal [1, 3, 4]
|
1830
|
-
end
|
1831
|
-
|
1832
|
-
it "should disconnect and remove entry from Sequel::DATABASES after use" do
|
1833
|
-
dbs = []
|
1834
|
-
dcs = []
|
1835
|
-
@db.each_server do |db|
|
1836
|
-
dbs << db
|
1837
|
-
Sequel::DATABASES.must_include(db)
|
1838
|
-
meta_def(db, :disconnect){dcs << db}
|
1839
|
-
end
|
1840
|
-
dbs.each do |db|
|
1841
|
-
Sequel::DATABASES.wont_include(db)
|
1842
|
-
end
|
1843
|
-
dbs.must_equal dcs
|
1844
|
-
end
|
1845
|
-
end
|
1846
|
-
|
1847
|
-
describe "Database#raise_error" do
|
1848
|
-
before do
|
1849
|
-
@db = Sequel.mock
|
1850
|
-
end
|
1851
|
-
|
1852
|
-
it "should reraise if the exception class is not in opts[:classes]" do
|
1853
|
-
e = Class.new(StandardError)
|
1854
|
-
proc{@db.send(:raise_error, e.new(''), :classes=>[])}.must_raise(e)
|
1855
|
-
end
|
1856
|
-
|
1857
|
-
it "should convert the exception to a DatabaseError if the exception class is in opts[:classes]" do
|
1858
|
-
proc{@db.send(:raise_error, Interrupt.new(''), :classes=>[Interrupt])}.must_raise(Sequel::DatabaseError)
|
1859
|
-
end
|
1860
|
-
|
1861
|
-
it "should convert the exception to a DatabaseError if opts[:classes] if not present" do
|
1862
|
-
proc{@db.send(:raise_error, Interrupt.new(''))}.must_raise(Sequel::DatabaseError)
|
1863
|
-
end
|
1864
|
-
|
1865
|
-
it "should convert the exception to a DatabaseDisconnectError if opts[:disconnect] is true" do
|
1866
|
-
proc{@db.send(:raise_error, Interrupt.new(''), :disconnect=>true)}.must_raise(Sequel::DatabaseDisconnectError)
|
1867
|
-
end
|
1868
|
-
|
1869
|
-
it "should convert the exception to an appropriate error if exception message matches regexp" do
|
1870
|
-
def @db.database_error_regexps
|
1871
|
-
{/foo/ => Sequel::DatabaseDisconnectError, /bar/ => Sequel::ConstraintViolation}
|
1872
|
-
end
|
1873
|
-
proc{@db.send(:raise_error, Interrupt.new('foo'))}.must_raise(Sequel::DatabaseDisconnectError)
|
1874
|
-
proc{@db.send(:raise_error, Interrupt.new('bar'))}.must_raise(Sequel::ConstraintViolation)
|
1875
|
-
end
|
1876
|
-
end
|
1877
|
-
|
1878
|
-
describe "Database#typecast_value" do
|
1879
|
-
before do
|
1880
|
-
@db = Sequel::Database.new
|
1881
|
-
end
|
1882
|
-
|
1883
|
-
it "should raise an InvalidValue when given an invalid value" do
|
1884
|
-
proc{@db.typecast_value(:integer, "13a")}.must_raise(Sequel::InvalidValue)
|
1885
|
-
proc{@db.typecast_value(:float, "4.e2")}.must_raise(Sequel::InvalidValue)
|
1886
|
-
proc{@db.typecast_value(:decimal, :invalid_value)}.must_raise(Sequel::InvalidValue)
|
1887
|
-
proc{@db.typecast_value(:date, Object.new)}.must_raise(Sequel::InvalidValue)
|
1888
|
-
proc{@db.typecast_value(:date, 'a')}.must_raise(Sequel::InvalidValue)
|
1889
|
-
proc{@db.typecast_value(:time, Date.new)}.must_raise(Sequel::InvalidValue)
|
1890
|
-
proc{@db.typecast_value(:datetime, 4)}.must_raise(Sequel::InvalidValue)
|
1891
|
-
end
|
1892
|
-
|
1893
|
-
it "should handle integers with leading 0 as base 10" do
|
1894
|
-
@db.typecast_value(:integer, "013").must_equal 13
|
1895
|
-
@db.typecast_value(:integer, "08").must_equal 8
|
1896
|
-
@db.typecast_value(:integer, "000013").must_equal 13
|
1897
|
-
@db.typecast_value(:integer, "000008").must_equal 8
|
1898
|
-
end
|
1899
|
-
|
1900
|
-
it "should handle integers with leading 0x as base 16" do
|
1901
|
-
@db.typecast_value(:integer, "0x013").must_equal 19
|
1902
|
-
@db.typecast_value(:integer, "0x80").must_equal 128
|
1903
|
-
end
|
1904
|
-
|
1905
|
-
it "should typecast blobs as as Sequel::SQL::Blob" do
|
1906
|
-
v = @db.typecast_value(:blob, "0x013")
|
1907
|
-
v.must_be_kind_of(Sequel::SQL::Blob)
|
1908
|
-
v.must_equal Sequel::SQL::Blob.new("0x013")
|
1909
|
-
@db.typecast_value(:blob, v).object_id.must_equal v.object_id
|
1910
|
-
end
|
1911
|
-
|
1912
|
-
it "should typecast boolean values to true, false, or nil" do
|
1913
|
-
@db.typecast_value(:boolean, false).must_equal false
|
1914
|
-
@db.typecast_value(:boolean, 0).must_equal false
|
1915
|
-
@db.typecast_value(:boolean, "0").must_equal false
|
1916
|
-
@db.typecast_value(:boolean, 'f').must_equal false
|
1917
|
-
@db.typecast_value(:boolean, 'false').must_equal false
|
1918
|
-
@db.typecast_value(:boolean, true).must_equal true
|
1919
|
-
@db.typecast_value(:boolean, 1).must_equal true
|
1920
|
-
@db.typecast_value(:boolean, '1').must_equal true
|
1921
|
-
@db.typecast_value(:boolean, 't').must_equal true
|
1922
|
-
@db.typecast_value(:boolean, 'true').must_equal true
|
1923
|
-
@db.typecast_value(:boolean, '').must_equal nil
|
1924
|
-
end
|
1925
|
-
|
1926
|
-
it "should typecast date values to Date" do
|
1927
|
-
@db.typecast_value(:date, Date.today).must_equal Date.today
|
1928
|
-
@db.typecast_value(:date, DateTime.now).must_equal Date.today
|
1929
|
-
@db.typecast_value(:date, Time.now).must_equal Date.today
|
1930
|
-
@db.typecast_value(:date, Date.today.to_s).must_equal Date.today
|
1931
|
-
@db.typecast_value(:date, :year=>Date.today.year, :month=>Date.today.month, :day=>Date.today.day).must_equal Date.today
|
1932
|
-
end
|
1933
|
-
|
1934
|
-
it "should have Sequel.application_to_database_timestamp convert to Sequel.database_timezone" do
|
1935
|
-
begin
|
1936
|
-
t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
|
1937
|
-
t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
|
1938
|
-
t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
|
1939
|
-
t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
|
1940
|
-
Sequel.application_timezone = :utc
|
1941
|
-
Sequel.database_timezone = :local
|
1942
|
-
Sequel.application_to_database_timestamp(t).must_equal t4
|
1943
|
-
Sequel.application_timezone = :local
|
1944
|
-
Sequel.database_timezone = :utc
|
1945
|
-
Sequel.application_to_database_timestamp(t2).must_equal t3
|
1946
|
-
ensure
|
1947
|
-
Sequel.default_timezone = nil
|
1948
|
-
end
|
1949
|
-
end
|
1950
|
-
|
1951
|
-
it "should have Database#to_application_timestamp convert values using the database's timezone" do
|
1952
|
-
begin
|
1953
|
-
t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
|
1954
|
-
t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
|
1955
|
-
t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
|
1956
|
-
t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
|
1957
|
-
Sequel.default_timezone = :utc
|
1958
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t
|
1959
|
-
Sequel.database_timezone = :local
|
1960
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t3
|
1961
|
-
Sequel.default_timezone = :local
|
1962
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t2
|
1963
|
-
Sequel.database_timezone = :utc
|
1964
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t4
|
1965
|
-
|
1966
|
-
Sequel.default_timezone = :utc
|
1967
|
-
@db.timezone = :local
|
1968
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t3
|
1969
|
-
Sequel.default_timezone = :local
|
1970
|
-
@db.timezone = :utc
|
1971
|
-
@db.to_application_timestamp('2011-01-02 03:04:05').must_equal t4
|
1972
|
-
ensure
|
1973
|
-
Sequel.default_timezone = nil
|
1974
|
-
end
|
1975
|
-
end
|
1976
|
-
|
1977
|
-
it "should typecast datetime values to Sequel.datetime_class with correct timezone handling" do
|
1978
|
-
t = Time.utc(2011, 1, 2, 3, 4, 5, 500000) # UTC Time
|
1979
|
-
t2 = Time.mktime(2011, 1, 2, 3, 4, 5, 500000) # Local Time
|
1980
|
-
t3 = Time.utc(2011, 1, 2, 3, 4, 5, 500000) - (t - t2) # Local Time in UTC Time
|
1981
|
-
t4 = Time.mktime(2011, 1, 2, 3, 4, 5, 500000) + (t - t2) # UTC Time in Local Time
|
1982
|
-
secs = defined?(Rational) ? Rational(11, 2) : 5.5
|
1983
|
-
r1 = defined?(Rational) ? Rational(t2.utc_offset, 86400) : t2.utc_offset/86400.0
|
1984
|
-
r2 = defined?(Rational) ? Rational((t - t2).to_i, 86400) : (t - t2).to_i/86400.0
|
1985
|
-
dt = DateTime.civil(2011, 1, 2, 3, 4, secs)
|
1986
|
-
dt2 = DateTime.civil(2011, 1, 2, 3, 4, secs, r1)
|
1987
|
-
dt3 = DateTime.civil(2011, 1, 2, 3, 4, secs) - r2
|
1988
|
-
dt4 = DateTime.civil(2011, 1, 2, 3, 4, secs, r1) + r2
|
1989
|
-
|
1990
|
-
t.must_equal t4
|
1991
|
-
t2.must_equal t3
|
1992
|
-
dt.must_equal dt4
|
1993
|
-
dt2.must_equal dt3
|
1994
|
-
|
1995
|
-
check = proc do |i, o|
|
1996
|
-
v = @db.typecast_value(:datetime, i)
|
1997
|
-
v.must_equal o
|
1998
|
-
if o.is_a?(Time)
|
1999
|
-
v.utc_offset.must_equal o.utc_offset
|
2000
|
-
else
|
2001
|
-
v.offset.must_equal o.offset
|
2002
|
-
end
|
2003
|
-
end
|
2004
|
-
@db.extend_datasets(Module.new{def supports_timestamp_timezones?; true; end})
|
2005
|
-
begin
|
2006
|
-
@db.typecast_value(:datetime, dt).must_equal t
|
2007
|
-
@db.typecast_value(:datetime, dt2).must_equal t2
|
2008
|
-
@db.typecast_value(:datetime, t).must_equal t
|
2009
|
-
@db.typecast_value(:datetime, t2).must_equal t2
|
2010
|
-
@db.typecast_value(:datetime, @db.literal(dt)[1...-1]).must_equal t
|
2011
|
-
@db.typecast_value(:datetime, dt.strftime('%F %T.%N')).must_equal t2
|
2012
|
-
@db.typecast_value(:datetime, Date.civil(2011, 1, 2)).must_equal Time.mktime(2011, 1, 2, 0, 0, 0)
|
2013
|
-
@db.typecast_value(:datetime, :year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000).must_equal t2
|
2014
|
-
|
2015
|
-
Sequel.datetime_class = DateTime
|
2016
|
-
@db.typecast_value(:datetime, dt).must_equal dt
|
2017
|
-
@db.typecast_value(:datetime, dt2).must_equal dt2
|
2018
|
-
@db.typecast_value(:datetime, t).must_equal dt
|
2019
|
-
@db.typecast_value(:datetime, t2).must_equal dt2
|
2020
|
-
@db.typecast_value(:datetime, @db.literal(dt)[1...-1]).must_equal dt
|
2021
|
-
@db.typecast_value(:datetime, dt.strftime('%F %T.%N')).must_equal dt
|
2022
|
-
@db.typecast_value(:datetime, Date.civil(2011, 1, 2)).must_equal DateTime.civil(2011, 1, 2, 0, 0, 0)
|
2023
|
-
@db.typecast_value(:datetime, :year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000).must_equal dt
|
2024
|
-
|
2025
|
-
Sequel.application_timezone = :utc
|
2026
|
-
Sequel.typecast_timezone = :local
|
2027
|
-
Sequel.datetime_class = Time
|
2028
|
-
check[dt, t]
|
2029
|
-
check[dt2, t3]
|
2030
|
-
check[t, t]
|
2031
|
-
check[t2, t3]
|
2032
|
-
check[@db.literal(dt)[1...-1], t]
|
2033
|
-
check[dt.strftime('%F %T.%N'), t3]
|
2034
|
-
check[Date.civil(2011, 1, 2), Time.utc(2011, 1, 2, 0, 0, 0)]
|
2035
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t3]
|
2036
|
-
|
2037
|
-
Sequel.datetime_class = DateTime
|
2038
|
-
check[dt, dt]
|
2039
|
-
check[dt2, dt3]
|
2040
|
-
check[t, dt]
|
2041
|
-
check[t2, dt3]
|
2042
|
-
check[@db.literal(dt)[1...-1], dt]
|
2043
|
-
check[dt.strftime('%F %T.%N'), dt3]
|
2044
|
-
check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0)]
|
2045
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt3]
|
2046
|
-
|
2047
|
-
Sequel.typecast_timezone = :utc
|
2048
|
-
Sequel.datetime_class = Time
|
2049
|
-
check[dt, t]
|
2050
|
-
check[dt2, t3]
|
2051
|
-
check[t, t]
|
2052
|
-
check[t2, t3]
|
2053
|
-
check[@db.literal(dt)[1...-1], t]
|
2054
|
-
check[dt.strftime('%F %T.%N'), t]
|
2055
|
-
check[Date.civil(2011, 1, 2), Time.utc(2011, 1, 2, 0, 0, 0)]
|
2056
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t]
|
2057
|
-
|
2058
|
-
Sequel.datetime_class = DateTime
|
2059
|
-
check[dt, dt]
|
2060
|
-
check[dt2, dt3]
|
2061
|
-
check[t, dt]
|
2062
|
-
check[t2, dt3]
|
2063
|
-
check[@db.literal(dt)[1...-1], dt]
|
2064
|
-
check[dt.strftime('%F %T.%N'), dt]
|
2065
|
-
check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0)]
|
2066
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt]
|
2067
|
-
|
2068
|
-
Sequel.application_timezone = :local
|
2069
|
-
Sequel.datetime_class = Time
|
2070
|
-
check[dt, t4]
|
2071
|
-
check[dt2, t2]
|
2072
|
-
check[t, t4]
|
2073
|
-
check[t2, t2]
|
2074
|
-
check[@db.literal(dt)[1...-1], t4]
|
2075
|
-
check[dt.strftime('%F %T.%N'), t4]
|
2076
|
-
check[Date.civil(2011, 1, 2), Time.local(2011, 1, 2, 0, 0, 0)]
|
2077
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t4]
|
2078
|
-
|
2079
|
-
Sequel.datetime_class = DateTime
|
2080
|
-
check[dt, dt4]
|
2081
|
-
check[dt2, dt2]
|
2082
|
-
check[t, dt4]
|
2083
|
-
check[t2, dt2]
|
2084
|
-
check[@db.literal(dt)[1...-1], dt4]
|
2085
|
-
check[dt.strftime('%F %T.%N'), dt4]
|
2086
|
-
check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0, r1)]
|
2087
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt4]
|
2088
|
-
|
2089
|
-
Sequel.typecast_timezone = :local
|
2090
|
-
Sequel.datetime_class = Time
|
2091
|
-
check[dt, t4]
|
2092
|
-
check[dt2, t2]
|
2093
|
-
check[t, t4]
|
2094
|
-
check[t2, t2]
|
2095
|
-
check[@db.literal(dt)[1...-1], t4]
|
2096
|
-
check[dt.strftime('%F %T.%N'), t2]
|
2097
|
-
check[Date.civil(2011, 1, 2), Time.local(2011, 1, 2, 0, 0, 0)]
|
2098
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t2]
|
2099
|
-
|
2100
|
-
Sequel.datetime_class = DateTime
|
2101
|
-
check[dt, dt4]
|
2102
|
-
check[dt2, dt2]
|
2103
|
-
check[t, dt4]
|
2104
|
-
check[t2, dt2]
|
2105
|
-
check[@db.literal(dt)[1...-1], dt4]
|
2106
|
-
check[dt.strftime('%F %T.%N'), dt2]
|
2107
|
-
check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0, r1)]
|
2108
|
-
check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt2]
|
2109
|
-
|
2110
|
-
ensure
|
2111
|
-
Sequel.default_timezone = nil
|
2112
|
-
Sequel.datetime_class = Time
|
2113
|
-
end
|
2114
|
-
end
|
2115
|
-
|
2116
|
-
it "should handle arrays when typecasting timestamps" do
|
2117
|
-
begin
|
2118
|
-
@db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14]).must_equal Time.local(2011, 10, 11, 12, 13, 14)
|
2119
|
-
@db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000]).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
|
2120
|
-
|
2121
|
-
Sequel.datetime_class = DateTime
|
2122
|
-
@db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14]).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
|
2123
|
-
@db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000]).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
|
2124
|
-
@db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000, (defined?(Rational) ? Rational(1, 2) : 0.5)]).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
|
2125
|
-
ensure
|
2126
|
-
Sequel.datetime_class = Time
|
2127
|
-
end
|
2128
|
-
end
|
2129
|
-
|
2130
|
-
it "should handle hashes when typecasting timestamps" do
|
2131
|
-
begin
|
2132
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14).must_equal Time.local(2011, 10, 11, 12, 13, 14)
|
2133
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
|
2134
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14).must_equal Time.local(2011, 10, 11, 12, 13, 14)
|
2135
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
|
2136
|
-
|
2137
|
-
Sequel.datetime_class = DateTime
|
2138
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
|
2139
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
|
2140
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
|
2141
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
|
2142
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :offset=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14, (defined?(Rational) ? Rational(1, 2) : 0.5))
|
2143
|
-
@db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000, :offset=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
|
2144
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'offset'=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14, (defined?(Rational) ? Rational(1, 2) : 0.5))
|
2145
|
-
@db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000, 'offset'=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
|
2146
|
-
ensure
|
2147
|
-
Sequel.datetime_class = Time
|
2148
|
-
end
|
2149
|
-
end
|
2150
|
-
|
2151
|
-
it "should typecast decimal values to BigDecimal" do
|
2152
|
-
[1.0, 1, '1.0', BigDecimal('1.0')].each do |i|
|
2153
|
-
v = @db.typecast_value(:decimal, i)
|
2154
|
-
v.must_be_kind_of(BigDecimal)
|
2155
|
-
v.must_equal BigDecimal.new('1.0')
|
2156
|
-
end
|
2157
|
-
end
|
2158
|
-
|
2159
|
-
it "should typecast float values to Float" do
|
2160
|
-
[1.0, 1, '1.0', BigDecimal('1.0')].each do |i|
|
2161
|
-
v = @db.typecast_value(:float, i)
|
2162
|
-
v.must_be_kind_of(Float)
|
2163
|
-
v.must_equal 1.0
|
2164
|
-
end
|
2165
|
-
end
|
2166
|
-
|
2167
|
-
it "should typecast string values to String" do
|
2168
|
-
[1.0, '1.0', Sequel.blob('1.0')].each do |i|
|
2169
|
-
v = @db.typecast_value(:string, i)
|
2170
|
-
v.must_be_instance_of(String)
|
2171
|
-
v.must_equal "1.0"
|
2172
|
-
end
|
2173
|
-
end
|
2174
|
-
|
2175
|
-
it "should raise errors when typecasting hash and array values to String" do
|
2176
|
-
[[], {}].each do |i|
|
2177
|
-
proc{@db.typecast_value(:string, i)}.must_raise(Sequel::InvalidValue)
|
2178
|
-
end
|
2179
|
-
end
|
2180
|
-
|
2181
|
-
it "should typecast time values to SQLTime" do
|
2182
|
-
t = Time.now
|
2183
|
-
st = Sequel::SQLTime.local(t.year, t.month, t.day, 1, 2, 3)
|
2184
|
-
[st, Time.utc(t.year, t.month, t.day, 1, 2, 3), Time.local(t.year, t.month, t.day, 1, 2, 3), '01:02:03', {:hour=>1, :minute=>2, :second=>3}].each do |i|
|
2185
|
-
v = @db.typecast_value(:time, i)
|
2186
|
-
v.must_be_instance_of(Sequel::SQLTime)
|
2187
|
-
v.must_equal st
|
2188
|
-
end
|
2189
|
-
end
|
2190
|
-
|
2191
|
-
it "should correctly handle time value conversion to SQLTime with fractional seconds" do
|
2192
|
-
t = Time.now
|
2193
|
-
st = Sequel::SQLTime.local(t.year, t.month, t.day, 1, 2, 3, 500000)
|
2194
|
-
t = Time.local(t.year, t.month, t.day, 1, 2, 3, 500000)
|
2195
|
-
@db.typecast_value(:time, t).must_equal st
|
2196
|
-
end
|
2197
|
-
|
2198
|
-
it "should have an underlying exception class available at wrapped_exception" do
|
2199
|
-
begin
|
2200
|
-
@db.typecast_value(:date, 'a')
|
2201
|
-
true.must_equal false
|
2202
|
-
rescue Sequel::InvalidValue => e
|
2203
|
-
e.wrapped_exception.must_be_kind_of(ArgumentError)
|
2204
|
-
end
|
2205
|
-
end
|
2206
|
-
|
2207
|
-
it "should include underlying exception class in #inspect" do
|
2208
|
-
begin
|
2209
|
-
@db.typecast_value(:date, 'a')
|
2210
|
-
true.must_equal false
|
2211
|
-
rescue Sequel::InvalidValue => e
|
2212
|
-
e.inspect.must_match(/\A#<Sequel::InvalidValue: ArgumentError: .*>\z/)
|
2213
|
-
end
|
2214
|
-
end
|
2215
|
-
end
|
2216
|
-
|
2217
|
-
describe "Database#blank_object?" do
|
2218
|
-
it "should return whether the object is considered blank" do
|
2219
|
-
db = Sequel::Database.new
|
2220
|
-
c = lambda{|meth, value| Class.new{define_method(meth){value}}.new}
|
2221
|
-
|
2222
|
-
db.send(:blank_object?, "").must_equal true
|
2223
|
-
db.send(:blank_object?, " ").must_equal true
|
2224
|
-
db.send(:blank_object?, nil).must_equal true
|
2225
|
-
db.send(:blank_object?, false).must_equal true
|
2226
|
-
db.send(:blank_object?, []).must_equal true
|
2227
|
-
db.send(:blank_object?, {}).must_equal true
|
2228
|
-
db.send(:blank_object?, c[:empty?, true]).must_equal true
|
2229
|
-
db.send(:blank_object?, c[:blank?, true]).must_equal true
|
2230
|
-
|
2231
|
-
db.send(:blank_object?, " a ").must_equal false
|
2232
|
-
db.send(:blank_object?, 1).must_equal false
|
2233
|
-
db.send(:blank_object?, 1.0).must_equal false
|
2234
|
-
db.send(:blank_object?, true).must_equal false
|
2235
|
-
db.send(:blank_object?, [1]).must_equal false
|
2236
|
-
db.send(:blank_object?, {1.0=>2.0}).must_equal false
|
2237
|
-
db.send(:blank_object?, c[:empty?, false]).must_equal false
|
2238
|
-
db.send(:blank_object?, c[:blank?, false]).must_equal false
|
2239
|
-
end
|
2240
|
-
end
|
2241
|
-
|
2242
|
-
describe "Database#schema_autoincrementing_primary_key?" do
|
2243
|
-
it "should indicate whether the parsed schema row indicates a primary key" do
|
2244
|
-
m = Sequel::Database.new.method(:schema_autoincrementing_primary_key?)
|
2245
|
-
m.call(:primary_key=>true, :auto_increment=>true).must_equal true
|
2246
|
-
m.call(:primary_key=>true, :auto_increment=>false).must_equal false
|
2247
|
-
m.call(:primary_key=>false).must_equal false
|
2248
|
-
end
|
2249
|
-
end
|
2250
|
-
|
2251
|
-
describe "Database#supports_schema_parsing?" do
|
2252
|
-
it "should be false by default" do
|
2253
|
-
Sequel::Database.new.supports_schema_parsing?.must_equal false
|
2254
|
-
end
|
2255
|
-
|
2256
|
-
it "should be true if the database implements schema_parse_table" do
|
2257
|
-
db = Sequel::Database.new
|
2258
|
-
def db.schema_parse_table(*) end
|
2259
|
-
db.supports_schema_parsing?.must_equal true
|
2260
|
-
end
|
2261
|
-
end
|
2262
|
-
|
2263
|
-
describe "Database#supports_foreign_key_parsing?" do
|
2264
|
-
it "should be false by default" do
|
2265
|
-
Sequel::Database.new.supports_foreign_key_parsing?.must_equal false
|
2266
|
-
end
|
2267
|
-
|
2268
|
-
it "should be true if the database implements foreign_key_list" do
|
2269
|
-
db = Sequel::Database.new
|
2270
|
-
def db.foreign_key_list(*) end
|
2271
|
-
db.supports_foreign_key_parsing?.must_equal true
|
2272
|
-
end
|
2273
|
-
end
|
2274
|
-
|
2275
|
-
describe "Database#supports_index_parsing?" do
|
2276
|
-
it "should be false by default" do
|
2277
|
-
Sequel::Database.new.supports_index_parsing?.must_equal false
|
2278
|
-
end
|
2279
|
-
|
2280
|
-
it "should be true if the database implements indexes" do
|
2281
|
-
db = Sequel::Database.new
|
2282
|
-
def db.indexes(*) end
|
2283
|
-
db.supports_index_parsing?.must_equal true
|
2284
|
-
end
|
2285
|
-
end
|
2286
|
-
|
2287
|
-
describe "Database#supports_table_listing?" do
|
2288
|
-
it "should be false by default" do
|
2289
|
-
Sequel::Database.new.supports_table_listing?.must_equal false
|
2290
|
-
end
|
2291
|
-
|
2292
|
-
it "should be true if the database implements tables" do
|
2293
|
-
db = Sequel::Database.new
|
2294
|
-
def db.tables(*) end
|
2295
|
-
db.supports_table_listing?.must_equal true
|
2296
|
-
end
|
2297
|
-
end
|
2298
|
-
|
2299
|
-
describe "Database#supports_view_listing?" do
|
2300
|
-
it "should be false by default" do
|
2301
|
-
Sequel::Database.new.supports_view_listing?.must_equal false
|
2302
|
-
end
|
2303
|
-
|
2304
|
-
it "should be true if the database implements views" do
|
2305
|
-
db = Sequel::Database.new
|
2306
|
-
def db.views(*) end
|
2307
|
-
db.supports_view_listing?.must_equal true
|
2308
|
-
end
|
2309
|
-
end
|
2310
|
-
|
2311
|
-
describe "Database#supports_deferrable_constraints?" do
|
2312
|
-
it "should be false by default" do
|
2313
|
-
Sequel::Database.new.supports_deferrable_constraints?.must_equal false
|
2314
|
-
end
|
2315
|
-
end
|
2316
|
-
|
2317
|
-
describe "Database#supports_deferrable_foreign_key_constraints?" do
|
2318
|
-
it "should be false by default" do
|
2319
|
-
Sequel::Database.new.supports_deferrable_foreign_key_constraints?.must_equal false
|
2320
|
-
end
|
2321
|
-
end
|
2322
|
-
|
2323
|
-
describe "Database#supports_transactional_ddl?" do
|
2324
|
-
it "should be false by default" do
|
2325
|
-
Sequel::Database.new.supports_transactional_ddl?.must_equal false
|
2326
|
-
end
|
2327
|
-
end
|
2328
|
-
|
2329
|
-
describe "Database#global_index_namespace?" do
|
2330
|
-
it "should be true by default" do
|
2331
|
-
Sequel::Database.new.global_index_namespace?.must_equal true
|
2332
|
-
end
|
2333
|
-
end
|
2334
|
-
|
2335
|
-
describe "Database#supports_savepoints?" do
|
2336
|
-
it "should be false by default" do
|
2337
|
-
Sequel::Database.new.supports_savepoints?.must_equal false
|
2338
|
-
end
|
2339
|
-
end
|
2340
|
-
|
2341
|
-
describe "Database#supports_views_with_check_option?" do
|
2342
|
-
it "should be false by default" do
|
2343
|
-
Sequel::Database.new.supports_views_with_check_option?.must_equal false
|
2344
|
-
end
|
2345
|
-
end
|
2346
|
-
|
2347
|
-
describe "Database#supports_views_with_local_check_option?" do
|
2348
|
-
it "should be false by default" do
|
2349
|
-
Sequel::Database.new.supports_views_with_local_check_option?.must_equal false
|
2350
|
-
end
|
2351
|
-
end
|
2352
|
-
|
2353
|
-
describe "Database#supports_savepoints_in_prepared_transactions?" do
|
2354
|
-
it "should be false by default" do
|
2355
|
-
Sequel::Database.new.supports_savepoints_in_prepared_transactions?.must_equal false
|
2356
|
-
end
|
2357
|
-
|
2358
|
-
it "should be true if both savepoints and prepared transactions are supported" do
|
2359
|
-
db = Sequel::Database.new
|
2360
|
-
meta_def(db, :supports_savepoints?){true}
|
2361
|
-
meta_def(db, :supports_prepared_transactions?){true}
|
2362
|
-
db.supports_savepoints_in_prepared_transactions?.must_equal true
|
2363
|
-
end
|
2364
|
-
end
|
2365
|
-
|
2366
|
-
describe "Database#supports_prepared_transactions?" do
|
2367
|
-
it "should be false by default" do
|
2368
|
-
Sequel::Database.new.supports_prepared_transactions?.must_equal false
|
2369
|
-
end
|
2370
|
-
end
|
2371
|
-
|
2372
|
-
describe "Database#supports_transaction_isolation_levels?" do
|
2373
|
-
it "should be false by default" do
|
2374
|
-
Sequel::Database.new.supports_transaction_isolation_levels?.must_equal false
|
2375
|
-
end
|
2376
|
-
end
|
2377
|
-
|
2378
|
-
describe "Database#input_identifier_meth" do
|
2379
|
-
it "should be the input_identifer method of a default dataset for this database" do
|
2380
|
-
db = Sequel::Database.new
|
2381
|
-
db.send(:input_identifier_meth).call(:a).must_equal 'a'
|
2382
|
-
db.identifier_input_method = :upcase
|
2383
|
-
db.send(:input_identifier_meth).call(:a).must_equal 'A'
|
2384
|
-
end
|
2385
|
-
end
|
2386
|
-
|
2387
|
-
describe "Database#output_identifier_meth" do
|
2388
|
-
it "should be the output_identifer method of a default dataset for this database" do
|
2389
|
-
db = Sequel::Database.new
|
2390
|
-
db.send(:output_identifier_meth).call('A').must_equal :A
|
2391
|
-
db.identifier_output_method = :downcase
|
2392
|
-
db.send(:output_identifier_meth).call('A').must_equal :a
|
2393
|
-
end
|
2394
|
-
end
|
2395
|
-
|
2396
|
-
describe "Database#metadata_dataset" do
|
2397
|
-
it "should be a dataset with the default settings for identifier_input_method and identifier_output_method" do
|
2398
|
-
ds = Sequel::Database.new.send(:metadata_dataset)
|
2399
|
-
ds.literal(:a).must_equal 'A'
|
2400
|
-
ds.send(:output_identifier, 'A').must_equal :a
|
2401
|
-
end
|
2402
|
-
end
|
2403
|
-
|
2404
|
-
describe "Database#column_schema_to_ruby_default" do
|
2405
|
-
it "should handle converting many default formats" do
|
2406
|
-
db = Sequel::Database.new
|
2407
|
-
p = lambda{|d,t| db.send(:column_schema_to_ruby_default, d, t)}
|
2408
|
-
p[nil, :integer].must_equal nil
|
2409
|
-
p[1, :integer].must_equal 1
|
2410
|
-
p['1', :integer].must_equal 1
|
2411
|
-
p['-1', :integer].must_equal(-1)
|
2412
|
-
p[1.0, :float].must_equal 1.0
|
2413
|
-
p['1.0', :float].must_equal 1.0
|
2414
|
-
p['-1.0', :float].must_equal(-1.0)
|
2415
|
-
p['1.0', :decimal].must_equal BigDecimal.new('1.0')
|
2416
|
-
p['-1.0', :decimal].must_equal BigDecimal.new('-1.0')
|
2417
|
-
p[true, :boolean].must_equal true
|
2418
|
-
p[false, :boolean].must_equal false
|
2419
|
-
p['1', :boolean].must_equal true
|
2420
|
-
p['0', :boolean].must_equal false
|
2421
|
-
p['true', :boolean].must_equal true
|
2422
|
-
p['false', :boolean].must_equal false
|
2423
|
-
p["'t'", :boolean].must_equal true
|
2424
|
-
p["'f'", :boolean].must_equal false
|
2425
|
-
p["'a'", :string].must_equal 'a'
|
2426
|
-
p["'a'", :blob].must_equal Sequel.blob('a')
|
2427
|
-
p["'a'", :blob].must_be_kind_of(Sequel::SQL::Blob)
|
2428
|
-
p["''", :string].must_equal ''
|
2429
|
-
p["'\\a''b'", :string].must_equal "\\a'b"
|
2430
|
-
p["'NULL'", :string].must_equal "NULL"
|
2431
|
-
p[Date.today, :date].must_equal Date.today
|
2432
|
-
p["'2009-10-29'", :date].must_equal Date.new(2009,10,29)
|
2433
|
-
p["CURRENT_TIMESTAMP", :date].must_equal Sequel::CURRENT_DATE
|
2434
|
-
p["CURRENT_DATE", :date].must_equal Sequel::CURRENT_DATE
|
2435
|
-
p["now()", :date].must_equal Sequel::CURRENT_DATE
|
2436
|
-
p["getdate()", :date].must_equal Sequel::CURRENT_DATE
|
2437
|
-
p["CURRENT_TIMESTAMP", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
|
2438
|
-
p["CURRENT_DATE", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
|
2439
|
-
p["now()", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
|
2440
|
-
p["getdate()", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
|
2441
|
-
p["'2009-10-29T10:20:30-07:00'", :datetime].must_equal DateTime.parse('2009-10-29T10:20:30-07:00')
|
2442
|
-
p["'2009-10-29 10:20:30'", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30')
|
2443
|
-
p["'10:20:30'", :time].must_equal Time.parse('10:20:30')
|
2444
|
-
p["NaN", :float].must_equal nil
|
2445
|
-
|
2446
|
-
db = Sequel.mock(:host=>'postgres')
|
2447
|
-
p["''::text", :string].must_equal ""
|
2448
|
-
p["'\\a''b'::character varying", :string].must_equal "\\a'b"
|
2449
|
-
p["'a'::bpchar", :string].must_equal "a"
|
2450
|
-
p["(-1)", :integer].must_equal(-1)
|
2451
|
-
p["(-1.0)", :float].must_equal(-1.0)
|
2452
|
-
p['(-1.0)', :decimal].must_equal BigDecimal.new('-1.0')
|
2453
|
-
p["'a'::bytea", :blob].must_equal Sequel.blob('a')
|
2454
|
-
p["'a'::bytea", :blob].must_be_kind_of(Sequel::SQL::Blob)
|
2455
|
-
p["'2009-10-29'::date", :date].must_equal Date.new(2009,10,29)
|
2456
|
-
p["'2009-10-29 10:20:30.241343'::timestamp without time zone", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30.241343')
|
2457
|
-
p["'10:20:30'::time without time zone", :time].must_equal Time.parse('10:20:30')
|
2458
|
-
|
2459
|
-
db = Sequel.mock(:host=>'mysql')
|
2460
|
-
p["\\a'b", :string].must_equal "\\a'b"
|
2461
|
-
p["a", :string].must_equal "a"
|
2462
|
-
p["NULL", :string].must_equal "NULL"
|
2463
|
-
p["-1", :float].must_equal(-1.0)
|
2464
|
-
p['-1', :decimal].must_equal BigDecimal.new('-1.0')
|
2465
|
-
p["2009-10-29", :date].must_equal Date.new(2009,10,29)
|
2466
|
-
p["2009-10-29 10:20:30", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30')
|
2467
|
-
p["10:20:30", :time].must_equal Time.parse('10:20:30')
|
2468
|
-
p["a", :enum].must_equal "a"
|
2469
|
-
p["a,b", :set].must_equal "a,b"
|
2470
|
-
|
2471
|
-
db = Sequel.mock(:host=>'mssql')
|
2472
|
-
p["(N'a')", :string].must_equal "a"
|
2473
|
-
p["((-12))", :integer].must_equal(-12)
|
2474
|
-
p["((12.1))", :float].must_equal 12.1
|
2475
|
-
p["((-12.1))", :decimal].must_equal BigDecimal.new('-12.1')
|
2476
|
-
end
|
2477
|
-
end
|
2478
|
-
|
2479
|
-
describe "Database extensions" do
|
2480
|
-
before(:all) do
|
2481
|
-
class << Sequel
|
2482
|
-
alias _extension extension
|
2483
|
-
remove_method :extension
|
2484
|
-
def extension(*)
|
2485
|
-
end
|
2486
|
-
end
|
2487
|
-
end
|
2488
|
-
after(:all) do
|
2489
|
-
class << Sequel
|
2490
|
-
remove_method :extension
|
2491
|
-
alias extension _extension
|
2492
|
-
remove_method :_extension
|
2493
|
-
end
|
2494
|
-
end
|
2495
|
-
before do
|
2496
|
-
@db = Sequel.mock
|
2497
|
-
end
|
2498
|
-
after do
|
2499
|
-
Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
|
2500
|
-
end
|
2501
|
-
|
2502
|
-
it "should be able to register an extension with a module have Database#extension extend the module" do
|
2503
|
-
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
|
2504
|
-
@db.extension(:foo).a.must_equal 1
|
2505
|
-
end
|
2506
|
-
|
2507
|
-
it "should be able to register an extension with a block and have Database#extension call the block" do
|
2508
|
-
@db.quote_identifiers = false
|
2509
|
-
Sequel::Database.register_extension(:foo){|db| db.quote_identifiers = true}
|
2510
|
-
@db.extension(:foo).quote_identifiers?.must_equal true
|
2511
|
-
end
|
2512
|
-
|
2513
|
-
it "should be able to register an extension with a callable and Database#extension call the callable" do
|
2514
|
-
@db.quote_identifiers = false
|
2515
|
-
Sequel::Database.register_extension(:foo, proc{|db| db.quote_identifiers = true})
|
2516
|
-
@db.extension(:foo).quote_identifiers?.must_equal true
|
2517
|
-
end
|
2518
|
-
|
2519
|
-
it "should be able to load multiple extensions in the same call" do
|
2520
|
-
@db.quote_identifiers = false
|
2521
|
-
@db.identifier_input_method = :downcase
|
2522
|
-
Sequel::Database.register_extension(:foo, proc{|db| db.quote_identifiers = true})
|
2523
|
-
Sequel::Database.register_extension(:bar, proc{|db| db.identifier_input_method = nil})
|
2524
|
-
@db.extension(:foo, :bar)
|
2525
|
-
@db.quote_identifiers?.must_equal true
|
2526
|
-
@db.identifier_input_method.must_equal nil
|
2527
|
-
end
|
2528
|
-
|
2529
|
-
it "should return the receiver" do
|
2530
|
-
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
|
2531
|
-
@db.extension(:foo).must_be_same_as(@db)
|
2532
|
-
end
|
2533
|
-
|
2534
|
-
it "should raise an Error if registering with both a module and a block" do
|
2535
|
-
proc{Sequel::Database.register_extension(:foo, Module.new){}}.must_raise(Sequel::Error)
|
2536
|
-
end
|
2537
|
-
|
2538
|
-
it "should raise an Error if attempting to load an incompatible extension" do
|
2539
|
-
proc{@db.extension(:foo2)}.must_raise(Sequel::Error)
|
2540
|
-
end
|
2541
|
-
|
2542
|
-
it "should be able to load an extension into all future Databases with Database.extension" do
|
2543
|
-
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
|
2544
|
-
Sequel::Database.register_extension(:bar, Module.new{def b; 2; end})
|
2545
|
-
Sequel::Database.extension(:foo, :bar)
|
2546
|
-
@db.wont_respond_to(:a)
|
2547
|
-
@db.wont_respond_to(:b)
|
2548
|
-
Sequel.mock.a.must_equal 1
|
2549
|
-
Sequel.mock.b.must_equal 2
|
2550
|
-
end
|
2551
|
-
end
|
2552
|
-
|
2553
|
-
describe "Database specific exception classes" do
|
2554
|
-
before do
|
2555
|
-
@db = Sequel.mock
|
2556
|
-
class << @db
|
2557
|
-
attr_accessor :sql_state
|
2558
|
-
|
2559
|
-
def database_exception_sqlstate(exception, opts={})
|
2560
|
-
@sql_state
|
2561
|
-
end
|
2562
|
-
end
|
2563
|
-
end
|
2564
|
-
|
2565
|
-
it "should use appropriate exception classes for given SQL states" do
|
2566
|
-
@db.fetch = ArgumentError
|
2567
|
-
@db.sql_state = '23502'
|
2568
|
-
proc{@db.get(:a)}.must_raise(Sequel::NotNullConstraintViolation)
|
2569
|
-
@db.sql_state = '23503'
|
2570
|
-
proc{@db.get(:a)}.must_raise(Sequel::ForeignKeyConstraintViolation)
|
2571
|
-
@db.sql_state = '23505'
|
2572
|
-
proc{@db.get(:a)}.must_raise(Sequel::UniqueConstraintViolation)
|
2573
|
-
@db.sql_state = '23513'
|
2574
|
-
proc{@db.get(:a)}.must_raise(Sequel::CheckConstraintViolation)
|
2575
|
-
@db.sql_state = '40001'
|
2576
|
-
proc{@db.get(:a)}.must_raise(Sequel::SerializationFailure)
|
2577
|
-
end
|
2578
|
-
end
|
2579
|
-
|
2580
|
-
describe "Database.after_initialize" do
|
2581
|
-
after do
|
2582
|
-
Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
|
2583
|
-
end
|
2584
|
-
|
2585
|
-
it "should allow a block to be run after each new instance is created" do
|
2586
|
-
Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
|
2587
|
-
db = Sequel.mock
|
2588
|
-
db.sql_log_level.must_equal :debug
|
2589
|
-
end
|
2590
|
-
|
2591
|
-
it "should allow multiple hooks to be registered" do
|
2592
|
-
Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
|
2593
|
-
Sequel::Database.after_initialize{|db| db.loggers << 11 }
|
2594
|
-
|
2595
|
-
db = Sequel.mock
|
2596
|
-
|
2597
|
-
db.sql_log_level.must_equal :debug
|
2598
|
-
db.loggers.must_include(11)
|
2599
|
-
end
|
2600
|
-
|
2601
|
-
it "should raise an error if registration is called without a block" do
|
2602
|
-
proc {
|
2603
|
-
Sequel::Database.after_initialize
|
2604
|
-
}.must_raise(Sequel::Error, /must provide block/i)
|
2605
|
-
end
|
2606
|
-
end
|
2607
|
-
|
2608
|
-
describe "Database#schema_type_class" do
|
2609
|
-
it "should return the class or array of classes for the given type symbol" do
|
2610
|
-
db = Sequel.mock
|
2611
|
-
{:string=>String, :integer=>Integer, :date=>Date, :datetime=>[Time, DateTime],
|
2612
|
-
:time=>Sequel::SQLTime, :boolean=>[TrueClass, FalseClass], :float=>Float, :decimal=>BigDecimal,
|
2613
|
-
:blob=>Sequel::SQL::Blob}.each do |sym, klass|
|
2614
|
-
db.schema_type_class(sym).must_equal klass
|
2615
|
-
end
|
2616
|
-
end
|
2617
|
-
end
|
2618
|
-
|
2619
|
-
describe "Database#execute_{dui,ddl,insert}" do
|
2620
|
-
before do
|
2621
|
-
@db = Sequel::Database.new
|
2622
|
-
def @db.execute(sql, opts={})
|
2623
|
-
(@sqls ||= []) << sql
|
2624
|
-
end
|
2625
|
-
def @db.sqls
|
2626
|
-
@sqls
|
2627
|
-
end
|
2628
|
-
end
|
2629
|
-
|
2630
|
-
it "should execute the SQL" do
|
2631
|
-
@db.execute_dui "DELETE FROM table"
|
2632
|
-
@db.execute_ddl "SET foo"
|
2633
|
-
@db.execute_insert "INSERT INTO table DEFAULT VALUES"
|
2634
|
-
@db.sqls.must_equal ["DELETE FROM table", "SET foo", "INSERT INTO table DEFAULT VALUES"]
|
2635
|
-
end
|
2636
|
-
end
|