sequel 5.20.0 → 5.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +398 -1922
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/doc/advanced_associations.rdoc +4 -4
- data/doc/association_basics.rdoc +80 -16
- data/doc/cheat_sheet.rdoc +6 -5
- data/doc/code_order.rdoc +10 -12
- data/doc/dataset_filtering.rdoc +17 -2
- data/doc/fork_safety.rdoc +84 -0
- data/doc/migration.rdoc +11 -5
- data/doc/model_dataset_method_design.rdoc +1 -1
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +10 -2
- data/doc/postgresql.rdoc +82 -3
- data/doc/querying.rdoc +4 -4
- 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.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.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/sharding.rdoc +2 -0
- data/doc/sql.rdoc +13 -1
- data/doc/testing.rdoc +20 -7
- data/doc/transactions.rdoc +0 -8
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +43 -35
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +11 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
- data/lib/sequel/adapters/jdbc.rb +24 -6
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +2 -3
- data/lib/sequel/adapters/odbc.rb +8 -6
- data/lib/sequel/adapters/oracle.rb +5 -4
- data/lib/sequel/adapters/postgres.rb +15 -9
- data/lib/sequel/adapters/shared/access.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +66 -21
- data/lib/sequel/adapters/shared/mysql.rb +27 -10
- data/lib/sequel/adapters/shared/oracle.rb +29 -23
- data/lib/sequel/adapters/shared/postgres.rb +271 -32
- data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
- data/lib/sequel/adapters/shared/sqlite.rb +161 -19
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +15 -2
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +4 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
- data/lib/sequel/connection_pool/single.rb +1 -1
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/core.rb +333 -319
- data/lib/sequel/database/connecting.rb +3 -4
- data/lib/sequel/database/logging.rb +7 -1
- data/lib/sequel/database/misc.rb +31 -12
- data/lib/sequel/database/query.rb +3 -1
- data/lib/sequel/database/schema_generator.rb +53 -51
- data/lib/sequel/database/schema_methods.rb +38 -23
- data/lib/sequel/database/transactions.rb +17 -18
- data/lib/sequel/dataset/actions.rb +14 -9
- data/lib/sequel/dataset/features.rb +16 -0
- data/lib/sequel/dataset/misc.rb +2 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +26 -9
- data/lib/sequel/dataset/sql.rb +76 -25
- data/lib/sequel/dataset.rb +4 -2
- data/lib/sequel/deprecated.rb +3 -1
- data/lib/sequel/exceptions.rb +2 -0
- data/lib/sequel/extensions/_pretty_table.rb +1 -2
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -2
- data/lib/sequel/extensions/connection_expiration.rb +2 -2
- data/lib/sequel/extensions/connection_validator.rb +2 -2
- data/lib/sequel/extensions/core_refinements.rb +2 -0
- data/lib/sequel/extensions/date_arithmetic.rb +36 -24
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/index_caching.rb +9 -7
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/integer64.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -3
- data/lib/sequel/extensions/named_timezones.rb +56 -8
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +5 -0
- data/lib/sequel/extensions/pg_array_ops.rb +14 -6
- data/lib/sequel/extensions/pg_enum.rb +11 -3
- data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +6 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +54 -2
- data/lib/sequel/extensions/pg_inet.rb +15 -5
- data/lib/sequel/extensions/pg_interval.rb +36 -8
- data/lib/sequel/extensions/pg_json.rb +387 -123
- data/lib/sequel/extensions/pg_json_ops.rb +238 -0
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_range.rb +17 -9
- data/lib/sequel/extensions/pg_range_ops.rb +2 -0
- data/lib/sequel/extensions/pg_row.rb +4 -2
- data/lib/sequel/extensions/pg_row_ops.rb +24 -0
- data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +24 -7
- data/lib/sequel/extensions/server_block.rb +18 -7
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
- data/lib/sequel/extensions/to_dot.rb +9 -3
- data/lib/sequel/model/associations.rb +356 -117
- data/lib/sequel/model/base.rb +107 -68
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +9 -3
- data/lib/sequel/model.rb +3 -1
- 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 +60 -18
- data/lib/sequel/plugins/association_proxies.rb +8 -2
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_validations.rb +39 -5
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -2
- data/lib/sequel/plugins/boolean_subsets.rb +4 -1
- data/lib/sequel/plugins/caching.rb +3 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +33 -28
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +7 -2
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +2 -1
- data/lib/sequel/plugins/csv_serializer.rb +28 -9
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +60 -22
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/json_serializer.rb +57 -35
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +108 -9
- data/lib/sequel/plugins/nested_attributes.rb +15 -3
- data/lib/sequel/plugins/pg_array_associations.rb +58 -41
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +91 -30
- data/lib/sequel/plugins/prepared_statements.rb +15 -12
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
- data/lib/sequel/plugins/rcte_tree.rb +43 -35
- data/lib/sequel/plugins/serialization.rb +8 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +11 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +22 -15
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/static_cache.rb +9 -4
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +1 -1
- data/lib/sequel/plugins/subclasses.rb +2 -0
- data/lib/sequel/plugins/throw_failures.rb +1 -1
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +9 -4
- data/lib/sequel/plugins/typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -1
- data/lib/sequel/plugins/validation_helpers.rb +18 -11
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +20 -5
- data/lib/sequel/timezones.rb +63 -17
- data/lib/sequel/version.rb +1 -1
- metadata +113 -381
- data/Rakefile +0 -151
- 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.37.0.txt +0 -50
- data/doc/release_notes/4.38.0.txt +0 -67
- data/doc/release_notes/4.39.0.txt +0 -127
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.40.0.txt +0 -179
- data/doc/release_notes/4.41.0.txt +0 -77
- data/doc/release_notes/4.42.0.txt +0 -221
- data/doc/release_notes/4.43.0.txt +0 -87
- data/doc/release_notes/4.44.0.txt +0 -125
- data/doc/release_notes/4.45.0.txt +0 -370
- data/doc/release_notes/4.46.0.txt +0 -404
- data/doc/release_notes/4.47.0.txt +0 -56
- data/doc/release_notes/4.48.0.txt +0 -293
- data/doc/release_notes/4.49.0.txt +0 -222
- 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/spec/adapter_spec.rb +0 -4
- data/spec/adapters/db2_spec.rb +0 -170
- data/spec/adapters/mssql_spec.rb +0 -804
- data/spec/adapters/mysql_spec.rb +0 -1065
- data/spec/adapters/oracle_spec.rb +0 -371
- data/spec/adapters/postgres_spec.rb +0 -4125
- data/spec/adapters/spec_helper.rb +0 -44
- data/spec/adapters/sqlanywhere_spec.rb +0 -97
- data/spec/adapters/sqlite_spec.rb +0 -652
- data/spec/bin_spec.rb +0 -278
- data/spec/core/connection_pool_spec.rb +0 -1250
- data/spec/core/database_spec.rb +0 -2865
- data/spec/core/dataset_spec.rb +0 -5515
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1455
- data/spec/core/mock_adapter_spec.rb +0 -722
- data/spec/core/object_graph_spec.rb +0 -336
- data/spec/core/placeholder_literalizer_spec.rb +0 -166
- data/spec/core/schema_generator_spec.rb +0 -214
- data/spec/core/schema_spec.rb +0 -1826
- data/spec/core/spec_helper.rb +0 -24
- data/spec/core/version_spec.rb +0 -14
- data/spec/core_extensions_spec.rb +0 -763
- data/spec/core_model_spec.rb +0 -2
- data/spec/core_spec.rb +0 -1
- data/spec/deprecation_helper.rb +0 -30
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -99
- data/spec/extensions/after_initialize_spec.rb +0 -28
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -125
- data/spec/extensions/association_pks_spec.rb +0 -423
- data/spec/extensions/association_proxies_spec.rb +0 -100
- data/spec/extensions/auto_literal_strings_spec.rb +0 -205
- data/spec/extensions/auto_validations_spec.rb +0 -229
- data/spec/extensions/blacklist_security_spec.rb +0 -95
- 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 -273
- data/spec/extensions/caller_logging_spec.rb +0 -52
- data/spec/extensions/class_table_inheritance_spec.rb +0 -750
- data/spec/extensions/column_conflicts_spec.rb +0 -75
- data/spec/extensions/column_select_spec.rb +0 -129
- data/spec/extensions/columns_introspection_spec.rb +0 -90
- data/spec/extensions/columns_updated_spec.rb +0 -35
- data/spec/extensions/composition_spec.rb +0 -248
- data/spec/extensions/connection_expiration_spec.rb +0 -151
- data/spec/extensions/connection_validator_spec.rb +0 -144
- data/spec/extensions/constant_sql_override_spec.rb +0 -24
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
- data/spec/extensions/constraint_validations_spec.rb +0 -439
- data/spec/extensions/core_refinements_spec.rb +0 -528
- data/spec/extensions/csv_serializer_spec.rb +0 -183
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -365
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -181
- data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
- data/spec/extensions/def_dataset_method_spec.rb +0 -100
- data/spec/extensions/defaults_setter_spec.rb +0 -150
- data/spec/extensions/delay_add_association_spec.rb +0 -73
- data/spec/extensions/dirty_spec.rb +0 -189
- data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
- data/spec/extensions/eager_each_spec.rb +0 -62
- data/spec/extensions/eager_graph_eager_spec.rb +0 -100
- 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/escaped_like_spec.rb +0 -40
- data/spec/extensions/eval_inspect_spec.rb +0 -81
- data/spec/extensions/finder_spec.rb +0 -260
- data/spec/extensions/force_encoding_spec.rb +0 -126
- data/spec/extensions/freeze_datasets_spec.rb +0 -31
- data/spec/extensions/graph_each_spec.rb +0 -113
- data/spec/extensions/hook_class_methods_spec.rb +0 -402
- data/spec/extensions/identifier_mangling_spec.rb +0 -201
- data/spec/extensions/implicit_subquery_spec.rb +0 -58
- data/spec/extensions/index_caching_spec.rb +0 -66
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -69
- data/spec/extensions/insert_returning_select_spec.rb +0 -72
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -246
- data/spec/extensions/integer64_spec.rb +0 -22
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -336
- data/spec/extensions/lazy_attributes_spec.rb +0 -183
- data/spec/extensions/list_spec.rb +0 -291
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2177
- data/spec/extensions/migration_spec.rb +0 -864
- data/spec/extensions/modification_detection_spec.rb +0 -93
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
- data/spec/extensions/named_timezones_spec.rb +0 -111
- data/spec/extensions/nested_attributes_spec.rb +0 -767
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -127
- data/spec/extensions/pagination_spec.rb +0 -116
- data/spec/extensions/pg_array_associations_spec.rb +0 -802
- data/spec/extensions/pg_array_ops_spec.rb +0 -144
- data/spec/extensions/pg_array_spec.rb +0 -398
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -172
- data/spec/extensions/pg_enum_spec.rb +0 -118
- data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
- data/spec/extensions/pg_hstore_spec.rb +0 -219
- data/spec/extensions/pg_inet_ops_spec.rb +0 -102
- data/spec/extensions/pg_inet_spec.rb +0 -72
- data/spec/extensions/pg_interval_spec.rb +0 -103
- data/spec/extensions/pg_json_ops_spec.rb +0 -289
- data/spec/extensions/pg_json_spec.rb +0 -262
- data/spec/extensions/pg_loose_count_spec.rb +0 -23
- data/spec/extensions/pg_range_ops_spec.rb +0 -60
- data/spec/extensions/pg_range_spec.rb +0 -519
- data/spec/extensions/pg_row_ops_spec.rb +0 -61
- data/spec/extensions/pg_row_plugin_spec.rb +0 -60
- data/spec/extensions/pg_row_spec.rb +0 -363
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
- data/spec/extensions/pg_timestamptz_spec.rb +0 -17
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
- data/spec/extensions/prepared_statements_spec.rb +0 -177
- data/spec/extensions/pretty_table_spec.rb +0 -123
- data/spec/extensions/query_spec.rb +0 -94
- data/spec/extensions/rcte_tree_spec.rb +0 -381
- data/spec/extensions/round_timestamps_spec.rb +0 -39
- data/spec/extensions/s_spec.rb +0 -60
- data/spec/extensions/schema_caching_spec.rb +0 -64
- data/spec/extensions/schema_dumper_spec.rb +0 -870
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -365
- data/spec/extensions/server_block_spec.rb +0 -97
- data/spec/extensions/server_logging_spec.rb +0 -45
- data/spec/extensions/sharding_spec.rb +0 -189
- data/spec/extensions/shared_caching_spec.rb +0 -151
- data/spec/extensions/single_table_inheritance_spec.rb +0 -347
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -18
- data/spec/extensions/spec_helper.rb +0 -63
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -57
- data/spec/extensions/sql_comments_spec.rb +0 -33
- data/spec/extensions/sql_expr_spec.rb +0 -59
- data/spec/extensions/static_cache_spec.rb +0 -471
- data/spec/extensions/string_agg_spec.rb +0 -90
- 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 -79
- data/spec/extensions/subset_conditions_spec.rb +0 -38
- data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
- data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
- data/spec/extensions/synchronize_sql_spec.rb +0 -124
- data/spec/extensions/table_select_spec.rb +0 -83
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/throw_failures_spec.rb +0 -74
- data/spec/extensions/timestamps_spec.rb +0 -209
- data/spec/extensions/to_dot_spec.rb +0 -153
- data/spec/extensions/touch_spec.rb +0 -226
- data/spec/extensions/tree_spec.rb +0 -334
- data/spec/extensions/typecast_on_load_spec.rb +0 -86
- data/spec/extensions/unlimited_update_spec.rb +0 -21
- data/spec/extensions/update_or_create_spec.rb +0 -83
- data/spec/extensions/update_primary_key_spec.rb +0 -105
- data/spec/extensions/update_refresh_spec.rb +0 -59
- data/spec/extensions/uuid_spec.rb +0 -101
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1040
- data/spec/extensions/validation_contexts_spec.rb +0 -31
- data/spec/extensions/validation_helpers_spec.rb +0 -525
- data/spec/extensions/whitelist_security_spec.rb +0 -157
- data/spec/extensions/xml_serializer_spec.rb +0 -213
- 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 -59
- data/spec/integration/associations_test.rb +0 -2597
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1981
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -262
- data/spec/integration/model_test.rb +0 -203
- data/spec/integration/plugin_test.rb +0 -2396
- data/spec/integration/prepared_statement_test.rb +0 -405
- data/spec/integration/schema_test.rb +0 -889
- data/spec/integration/spec_helper.rb +0 -65
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -603
- data/spec/integration/type_test.rb +0 -127
- data/spec/model/association_reflection_spec.rb +0 -803
- data/spec/model/associations_spec.rb +0 -4738
- data/spec/model/base_spec.rb +0 -875
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -198
- data/spec/model/eager_loading_spec.rb +0 -2377
- data/spec/model/hooks_spec.rb +0 -370
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -956
- data/spec/model/plugins_spec.rb +0 -429
- data/spec/model/record_spec.rb +0 -2118
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -220
- 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/sequel_warning.rb +0 -4
- data/spec/spec_config.rb +0 -12
|
@@ -1,750 +0,0 @@
|
|
|
1
|
-
require_relative "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe "class_table_inheritance plugin" do
|
|
4
|
-
before do
|
|
5
|
-
@db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
|
|
6
|
-
def @db.supports_schema_parsing?() true end
|
|
7
|
-
def @db.schema(table, opts={})
|
|
8
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string, :allow_null=>false}], [:kind, {:type=>:string}]],
|
|
9
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer, :allow_null=>false}] ],
|
|
10
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
|
11
|
-
:staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
|
12
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
13
|
-
end
|
|
14
|
-
@db.extend_datasets do
|
|
15
|
-
def columns
|
|
16
|
-
{[:employees]=>[:id, :name, :kind],
|
|
17
|
-
[:managers]=>[:id, :num_staff],
|
|
18
|
-
[:executives]=>[:id, :num_managers],
|
|
19
|
-
[:staff]=>[:id, :manager_id],
|
|
20
|
-
[:employees, :managers]=>[:id, :name, :kind, :num_staff],
|
|
21
|
-
[:employees, :managers, :executives]=>[:id, :name, :kind, :num_staff, :num_managers],
|
|
22
|
-
[:employees, :staff]=>[:id, :name, :kind, :manager_id],
|
|
23
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
base = Sequel::Model(@db)
|
|
27
|
-
base.plugin :auto_validations if @use_auto_validations
|
|
28
|
-
class ::Employee < base
|
|
29
|
-
def _save_refresh; @values[:id] = 1 end
|
|
30
|
-
def self.columns
|
|
31
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
32
|
-
end
|
|
33
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
|
34
|
-
end
|
|
35
|
-
class ::Manager < Employee
|
|
36
|
-
one_to_many :staff_members, :class=>:Staff
|
|
37
|
-
end
|
|
38
|
-
class ::Executive < Manager
|
|
39
|
-
end
|
|
40
|
-
class ::Ceo < Executive
|
|
41
|
-
end
|
|
42
|
-
class ::Staff < Employee
|
|
43
|
-
many_to_one :manager
|
|
44
|
-
end
|
|
45
|
-
class ::Intern < Employee
|
|
46
|
-
end
|
|
47
|
-
@ds = Employee.dataset
|
|
48
|
-
@db.sqls
|
|
49
|
-
end
|
|
50
|
-
after do
|
|
51
|
-
[:Intern, :Ceo, :Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "should freeze CTI information when freezing model class" do
|
|
55
|
-
Employee.freeze
|
|
56
|
-
Employee.cti_models.frozen?.must_equal true
|
|
57
|
-
Employee.cti_tables.frozen?.must_equal true
|
|
58
|
-
Employee.cti_instance_dataset.frozen?.must_equal true
|
|
59
|
-
Employee.cti_table_columns.frozen?.must_equal true
|
|
60
|
-
Employee.cti_table_map.frozen?.must_equal true
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "should not attempt to use prepared statements" do
|
|
64
|
-
Manager.plugin :prepared_statements
|
|
65
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
|
|
66
|
-
@db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
|
|
67
|
-
|
|
68
|
-
Employee.plugin :prepared_statements
|
|
69
|
-
Employee.load(:id=>2, :kind=>'Employee').save
|
|
70
|
-
@db.sqls.must_equal ["UPDATE employees SET kind = 'Employee' WHERE (id = 2)"]
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "#cti_models.first should be the model that loaded the plugin" do
|
|
74
|
-
Executive.cti_models.first.must_equal Employee
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it "should have simple_table = nil for all subclasses" do
|
|
78
|
-
Manager.simple_table.must_be_nil
|
|
79
|
-
Executive.simple_table.must_be_nil
|
|
80
|
-
Ceo.simple_table.must_be_nil
|
|
81
|
-
Staff.simple_table.must_be_nil
|
|
82
|
-
Intern.simple_table.must_be_nil
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
|
86
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
|
87
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
|
88
|
-
Manager[1].must_equal Ceo.load(:id=>1, :kind=>'Ceo')
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "should use a subquery in subclasses" do
|
|
92
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
|
93
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
|
|
94
|
-
Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees'
|
|
95
|
-
Ceo.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (employees.kind IN (\'Ceo\'))) AS employees'
|
|
96
|
-
Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees'
|
|
97
|
-
Intern.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (\'Intern\'))'
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it "should return rows with the correct class based on the polymorphic_key value" do
|
|
101
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff, Intern]
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "should return rows with the correct class based on the polymorphic_key value for subclasses" do
|
|
105
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}]).all.collect{|x| x.class}.must_equal [Manager, Executive, Ceo]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it "should have refresh return all columns in subclass after loading from superclass" do
|
|
109
|
-
Employee.dataset = Employee.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo'}])
|
|
110
|
-
Ceo.dataset = Ceo.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2}])
|
|
111
|
-
a = Employee.first
|
|
112
|
-
a.class.must_equal Ceo
|
|
113
|
-
a.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo')
|
|
114
|
-
a.refresh.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2)
|
|
115
|
-
@db.sqls.must_equal ["SELECT * FROM employees LIMIT 1",
|
|
116
|
-
"SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (employees.kind IN ('Ceo'))) AS employees WHERE (id = 1) LIMIT 1"]
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
describe "with auto_validations plugin" do
|
|
120
|
-
before(:all) do
|
|
121
|
-
@use_auto_validations = true
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "should work" do
|
|
125
|
-
e = Employee.new
|
|
126
|
-
e.valid?.must_equal false
|
|
127
|
-
e.errors.must_equal(:name=>["is not present"])
|
|
128
|
-
|
|
129
|
-
e = Manager.new
|
|
130
|
-
e.valid?.must_equal false
|
|
131
|
-
e.errors.must_equal(:name=>["is not present"], :num_staff=>["is not present"])
|
|
132
|
-
|
|
133
|
-
e = Executive.new
|
|
134
|
-
e.valid?.must_equal false
|
|
135
|
-
e.errors.must_equal(:name=>["is not present"], :num_staff=>["is not present"])
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
it "should return rows with the current class if sti_key is nil" do
|
|
140
|
-
Employee.plugin :class_table_inheritance
|
|
141
|
-
Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee, Employee]
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "should return rows with the current class if sti_key is nil in subclasses" do
|
|
145
|
-
Employee.plugin :class_table_inheritance
|
|
146
|
-
Object.send(:remove_const, :Executive)
|
|
147
|
-
Object.send(:remove_const, :Manager)
|
|
148
|
-
class ::Manager < Employee; end
|
|
149
|
-
class ::Executive < Manager; end
|
|
150
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}]).all.map{|x| x.class}.must_equal [Manager, Manager]
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it "should handle a model map with integer values" do
|
|
154
|
-
Employee.plugin :class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo, 4=>:Intern}
|
|
155
|
-
Object.send(:remove_const, :Intern)
|
|
156
|
-
Object.send(:remove_const, :Ceo)
|
|
157
|
-
Object.send(:remove_const, :Executive)
|
|
158
|
-
Object.send(:remove_const, :Manager)
|
|
159
|
-
class ::Intern < Employee; end
|
|
160
|
-
class ::Manager < Employee; end
|
|
161
|
-
class ::Executive < Manager; end
|
|
162
|
-
class ::Ceo < Executive; end
|
|
163
|
-
Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}, {:kind=>4}])
|
|
164
|
-
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo, Intern]
|
|
165
|
-
Manager.dataset = Manager.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
|
166
|
-
Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive, Ceo]
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
it "should fallback to the main class if the given class does not exist" do
|
|
170
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Blah'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Manager, Employee, Staff]
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
it "should fallback to the main class if the given class does not exist in subclasses" do
|
|
174
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Blah'}]).all.map{|x| x.class}.must_equal [Manager, Executive, Ceo, Manager]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
it "should sets the model class name for the key when creating new parent class records" do
|
|
178
|
-
Employee.create
|
|
179
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
it "should sets the model class name for the key when creating new class records for subclass without separate table" do
|
|
183
|
-
Intern.create
|
|
184
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Intern')"]
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it "should sets the model class name for the key when creating new subclass records" do
|
|
188
|
-
Ceo.create
|
|
189
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Ceo')",
|
|
190
|
-
"INSERT INTO managers (id) VALUES (1)",
|
|
191
|
-
"INSERT INTO executives (id) VALUES (1)"]
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
it "should ignore existing sti_key value when creating new records" do
|
|
195
|
-
Employee.create(:kind=>'Manager')
|
|
196
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it "should ignore existing sti_key value in subclasses" do
|
|
200
|
-
Manager.create(:kind=>'Executive')
|
|
201
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
|
|
202
|
-
"INSERT INTO managers (id) VALUES (1)"]
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
it "should handle validations on the type column field" do
|
|
206
|
-
o = Employee.new
|
|
207
|
-
def o.validate
|
|
208
|
-
errors.add(:kind, 'not present') unless kind
|
|
209
|
-
end
|
|
210
|
-
o.valid?.must_equal true
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
it "should set the type column field even when not validating" do
|
|
214
|
-
Employee.new.save(:validate=>false)
|
|
215
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
it "should allow specifying a map of names to tables to override implicit mapping" do
|
|
219
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
|
|
220
|
-
Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees'
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
it "should lazily load attributes for columns in subclass tables" do
|
|
224
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2)
|
|
225
|
-
m = Manager[1]
|
|
226
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1']
|
|
227
|
-
@db.fetch = {:num_managers=>3}
|
|
228
|
-
m.must_be_kind_of Ceo
|
|
229
|
-
m.num_managers.must_equal 3
|
|
230
|
-
@db.sqls.must_equal ['SELECT employees.num_managers FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees WHERE (employees.id = 1) LIMIT 1']
|
|
231
|
-
m.values.must_equal(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2, :num_managers=>3)
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
it "should lazily load columns in middle classes correctly when loaded from parent class" do
|
|
235
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
|
236
|
-
@db.fetch = [[:num_staff=>2]]
|
|
237
|
-
e = Employee[1]
|
|
238
|
-
e.must_be_kind_of(Ceo)
|
|
239
|
-
@db.sqls.must_equal ["SELECT * FROM employees WHERE (id = 1) LIMIT 1"]
|
|
240
|
-
e.num_staff.must_equal 2
|
|
241
|
-
@db.sqls.must_equal ["SELECT employees.num_staff FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (employees.id = 1) LIMIT 1"]
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
it "should eagerly load lazily columns in subclasses when loaded from parent class" do
|
|
245
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
|
246
|
-
@db.fetch = [[{:id=>1, :num_staff=>2}], [{:id=>1, :num_managers=>3}]]
|
|
247
|
-
e = Employee.all.first
|
|
248
|
-
e.must_be_kind_of(Ceo)
|
|
249
|
-
@db.sqls.must_equal ["SELECT * FROM employees"]
|
|
250
|
-
e.num_staff.must_equal 2
|
|
251
|
-
@db.sqls.must_equal ["SELECT employees.id, employees.num_staff FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (employees.id IN (1))"]
|
|
252
|
-
e.num_managers.must_equal 3
|
|
253
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.num_managers FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees WHERE (employees.id IN (1))']
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
it "should include schema for columns for tables for ancestor classes" do
|
|
257
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string, :allow_null=>false}, :kind=>{:type=>:string})
|
|
258
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string, :allow_null=>false}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer, :allow_null=>false})
|
|
259
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string, :allow_null=>false}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer, :allow_null=>false}, :num_managers=>{:type=>:integer})
|
|
260
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string, :allow_null=>false}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
|
261
|
-
Intern.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string, :allow_null=>false}, :kind=>{:type=>:string})
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
|
265
|
-
[Employee, Manager, Executive, Ceo, Staff, Intern].each{|c| c.primary_key.must_equal :id}
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
it "should have table_name return the table name of the most specific table" do
|
|
269
|
-
Employee.table_name.must_equal :employees
|
|
270
|
-
Manager.table_name.must_equal :employees
|
|
271
|
-
Executive.table_name.must_equal :employees
|
|
272
|
-
Ceo.table_name.must_equal :employees
|
|
273
|
-
Staff.table_name.must_equal :employees
|
|
274
|
-
Intern.table_name.must_equal :employees
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
it "should delete the correct rows from all tables when deleting" do
|
|
278
|
-
Employee.load(:id=>1).delete
|
|
279
|
-
@db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
|
|
280
|
-
|
|
281
|
-
Intern.load(:id=>1).delete
|
|
282
|
-
@db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
|
|
283
|
-
|
|
284
|
-
Ceo.load(:id=>1).delete
|
|
285
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
it "should not allow deletion of frozen object" do
|
|
289
|
-
[Ceo, Executive, Employee, Manager, Intern].each do |c|
|
|
290
|
-
o = c.load(:id=>1)
|
|
291
|
-
o.freeze
|
|
292
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
|
293
|
-
@db.sqls.must_equal []
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "should insert the correct rows into all tables when inserting into parent class" do
|
|
298
|
-
Employee.create(:name=>'E')
|
|
299
|
-
@db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Employee')"]
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
it "should insert the correct rows into all tables when inserting into subclass without separate table" do
|
|
303
|
-
Intern.create(:name=>'E')
|
|
304
|
-
@db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Intern')"]
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
it "should insert the correct rows into all tables when inserting" do
|
|
308
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
309
|
-
@db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Ceo')",
|
|
310
|
-
"INSERT INTO managers (id, num_staff) VALUES (1, 2)",
|
|
311
|
-
"INSERT INTO executives (id, num_managers) VALUES (1, 3)"]
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "should insert the correct rows into all tables when inserting when insert_select is supported" do
|
|
315
|
-
[Executive, Manager, Employee].each do |klass|
|
|
316
|
-
klass.instance_variable_set(:@cti_instance_dataset, klass.cti_instance_dataset.with_extend do
|
|
317
|
-
def supports_insert_select?; true; end
|
|
318
|
-
def insert_select(v)
|
|
319
|
-
db.run(insert_sql(v) + " RETURNING *")
|
|
320
|
-
v.merge(:id=>1)
|
|
321
|
-
end
|
|
322
|
-
end)
|
|
323
|
-
end
|
|
324
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
325
|
-
@db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Ceo') RETURNING *",
|
|
326
|
-
"INSERT INTO managers (id, num_staff) VALUES (1, 2) RETURNING *",
|
|
327
|
-
"INSERT INTO executives (id, num_managers) VALUES (1, 3) RETURNING *"]
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
it "should insert the correct rows into all tables with a given primary key" do
|
|
331
|
-
e = Ceo.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
332
|
-
e.id = 2
|
|
333
|
-
e.save
|
|
334
|
-
@db.sqls.must_equal ["INSERT INTO employees (id, name, kind) VALUES (2, 'E', 'Ceo')",
|
|
335
|
-
"INSERT INTO managers (id, num_staff) VALUES (2, 2)",
|
|
336
|
-
"INSERT INTO executives (id, num_managers) VALUES (2, 3)"]
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
it "should update the correct rows in all tables when updating parent class" do
|
|
340
|
-
Employee.load(:id=>2).update(:name=>'E')
|
|
341
|
-
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
it "should update the correct rows in all tables when updating subclass without separate table" do
|
|
345
|
-
Intern.load(:id=>2).update(:name=>'E')
|
|
346
|
-
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
it "should update the correct rows in all tables when updating" do
|
|
350
|
-
Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
351
|
-
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
it "should raise error if one of the updates does not update a single row" do
|
|
355
|
-
@db.numrows = [1, 0]
|
|
356
|
-
proc{Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')}.must_raise Sequel::NoExistingObject
|
|
357
|
-
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)"]
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
it "should handle many_to_one relationships correctly" do
|
|
361
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
|
362
|
-
Staff.load(:manager_id=>3).manager.must_equal Ceo.load(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
|
363
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 3) LIMIT 1']
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
it "should handle one_to_many relationships correctly" do
|
|
367
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)
|
|
368
|
-
Ceo.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)]
|
|
369
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees WHERE (employees.manager_id = 3)']
|
|
370
|
-
end
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
describe "class_table_inheritance plugin without sti_key with :alias option" do
|
|
374
|
-
before do
|
|
375
|
-
@db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
|
|
376
|
-
def @db.supports_schema_parsing?() true end
|
|
377
|
-
def @db.schema(table, opts={})
|
|
378
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}]],
|
|
379
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
|
|
380
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
|
381
|
-
:staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
|
382
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
383
|
-
end
|
|
384
|
-
@db.extend_datasets do
|
|
385
|
-
def columns
|
|
386
|
-
{[:employees]=>[:id, :name],
|
|
387
|
-
[:managers]=>[:id, :num_staff],
|
|
388
|
-
[:executives]=>[:id, :num_managers],
|
|
389
|
-
[:staff]=>[:id, :manager_id],
|
|
390
|
-
[:employees, :managers]=>[:id, :name, :num_staff],
|
|
391
|
-
[:employees, :managers, :executives]=>[:id, :name, :num_staff, :num_managers],
|
|
392
|
-
[:employees, :staff]=>[:id, :name, :manager_id],
|
|
393
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
394
|
-
end
|
|
395
|
-
end
|
|
396
|
-
class ::Employee < Sequel::Model(@db)
|
|
397
|
-
def _save_refresh; @values[:id] = 1 end
|
|
398
|
-
def self.columns
|
|
399
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
400
|
-
end
|
|
401
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}, :alias=>:emps
|
|
402
|
-
end
|
|
403
|
-
class ::Manager < Employee
|
|
404
|
-
one_to_many :staff_members, :class=>:Staff
|
|
405
|
-
end
|
|
406
|
-
class ::Executive < Manager
|
|
407
|
-
end
|
|
408
|
-
class ::Staff < Employee
|
|
409
|
-
many_to_one :manager
|
|
410
|
-
end
|
|
411
|
-
@ds = Employee.dataset
|
|
412
|
-
@db.sqls
|
|
413
|
-
end
|
|
414
|
-
after do
|
|
415
|
-
Object.send(:remove_const, :Executive)
|
|
416
|
-
Object.send(:remove_const, :Manager)
|
|
417
|
-
Object.send(:remove_const, :Staff)
|
|
418
|
-
Object.send(:remove_const, :Employee)
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
it "should have simple_table = nil for all subclasses" do
|
|
422
|
-
Manager.simple_table.must_be_nil
|
|
423
|
-
Executive.simple_table.must_be_nil
|
|
424
|
-
Staff.simple_table.must_be_nil
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
|
428
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
|
429
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1)
|
|
430
|
-
Manager[1].must_equal Manager.load(:id=>1)
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
it "should use a joined dataset in subclasses" do
|
|
434
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
|
435
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS emps'
|
|
436
|
-
Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS emps'
|
|
437
|
-
Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS emps'
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
it "should return rows with the current class if sti_key is nil" do
|
|
441
|
-
Employee.plugin(:class_table_inheritance)
|
|
442
|
-
Employee.dataset = Employee.dataset.with_fetch([{}])
|
|
443
|
-
Employee.first.class.must_equal Employee
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
it "should include schema for columns for tables for ancestor classes" do
|
|
447
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string})
|
|
448
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
|
449
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
|
450
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
|
454
|
-
[Employee, Manager, Executive, Staff].each{|c| c.primary_key.must_equal :id}
|
|
455
|
-
end
|
|
456
|
-
|
|
457
|
-
it "should have table_name return the table name of the most specific table" do
|
|
458
|
-
Employee.table_name.must_equal :employees
|
|
459
|
-
Manager.table_name.must_equal :emps
|
|
460
|
-
Executive.table_name.must_equal :emps
|
|
461
|
-
Staff.table_name.must_equal :emps
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
it "should delete the correct rows from all tables when deleting" do
|
|
465
|
-
Executive.load(:id=>1).delete
|
|
466
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
it "should not allow deletion of frozen object" do
|
|
470
|
-
o = Executive.load(:id=>1)
|
|
471
|
-
o.freeze
|
|
472
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
|
473
|
-
@db.sqls.must_equal []
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
it "should insert the correct rows into all tables when inserting" do
|
|
477
|
-
Executive.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
478
|
-
@db.sqls.must_equal ["INSERT INTO employees (name) VALUES ('E')",
|
|
479
|
-
"INSERT INTO managers (id, num_staff) VALUES (1, 2)",
|
|
480
|
-
"INSERT INTO executives (id, num_managers) VALUES (1, 3)"]
|
|
481
|
-
end
|
|
482
|
-
|
|
483
|
-
it "should insert the correct rows into all tables with a given primary key" do
|
|
484
|
-
e = Executive.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
485
|
-
e.id = 2
|
|
486
|
-
e.save
|
|
487
|
-
@db.sqls.must_equal ["INSERT INTO employees (id, name) VALUES (2, 'E')",
|
|
488
|
-
"INSERT INTO managers (id, num_staff) VALUES (2, 2)",
|
|
489
|
-
"INSERT INTO executives (id, num_managers) VALUES (2, 3)"]
|
|
490
|
-
end
|
|
491
|
-
|
|
492
|
-
it "should update the correct rows in all tables when updating" do
|
|
493
|
-
Executive.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
494
|
-
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
|
|
495
|
-
end
|
|
496
|
-
|
|
497
|
-
it "should handle many_to_one relationships correctly" do
|
|
498
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :num_staff=>3)
|
|
499
|
-
Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E', :num_staff=>3)
|
|
500
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS emps WHERE (id = 3) LIMIT 1']
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
it "should handle one_to_many relationships correctly" do
|
|
504
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
|
|
505
|
-
Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
|
|
506
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS emps WHERE (emps.manager_id = 3)']
|
|
507
|
-
end
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
describe "class_table_inheritance plugin with duplicate columns" do
|
|
511
|
-
it "should raise error if no columns are explicitly ignored" do
|
|
512
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
|
513
|
-
def @db.supports_schema_parsing?() true end
|
|
514
|
-
def @db.schema(table, opts={})
|
|
515
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
|
516
|
-
:managers=>[[:id, {:type=>:integer}], [:name, {:type=>:string}]],
|
|
517
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
518
|
-
end
|
|
519
|
-
@db.extend_datasets do
|
|
520
|
-
def columns
|
|
521
|
-
{[:employees]=>[:id, :name, :kind],
|
|
522
|
-
[:managers]=>[:id, :name],
|
|
523
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
524
|
-
end
|
|
525
|
-
end
|
|
526
|
-
class ::Employee < Sequel::Model(@db)
|
|
527
|
-
def _save_refresh; @values[:id] = 1 end
|
|
528
|
-
def self.columns
|
|
529
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
530
|
-
end
|
|
531
|
-
plugin :class_table_inheritance
|
|
532
|
-
end
|
|
533
|
-
proc{class ::Manager < Employee; end}.must_raise Sequel::Error
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
describe "with certain sub-class columns ignored" do
|
|
537
|
-
before do
|
|
538
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
|
539
|
-
def @db.supports_schema_parsing?() true end
|
|
540
|
-
def @db.schema(table, opts={})
|
|
541
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}], [:updated_at, {:type=>:datetime}]],
|
|
542
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}], [:updated_at, {:type=>:datetime}], [:another_duplicate_column, {:type=>:integer}]],
|
|
543
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}], [:updated_at, {:type=>:datetime}], [:another_duplicate_column, {:type=>:integer}]],
|
|
544
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
545
|
-
end
|
|
546
|
-
@db.extend_datasets do
|
|
547
|
-
def columns
|
|
548
|
-
{[:employees]=>[:id, :name, :kind, :updated_at],
|
|
549
|
-
[:managers]=>[:id, :num_staff, :updated_at, :another_duplicate_column],
|
|
550
|
-
[:executives]=>[:id, :num_managers, :updated_at, :another_duplicate_column],
|
|
551
|
-
[:employees, :managers]=>[:id, :name, :kind, :updated_at, :num_staff],
|
|
552
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
553
|
-
end
|
|
554
|
-
end
|
|
555
|
-
class ::Employee < Sequel::Model(@db)
|
|
556
|
-
def _save_refresh; @values[:id] = 1 end
|
|
557
|
-
def self.columns
|
|
558
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
559
|
-
end
|
|
560
|
-
plugin :class_table_inheritance, :ignore_subclass_columns=>[:updated_at]
|
|
561
|
-
end
|
|
562
|
-
class ::Manager < Employee
|
|
563
|
-
Manager.cti_ignore_subclass_columns.push(:another_duplicate_column)
|
|
564
|
-
end
|
|
565
|
-
class ::Executive < Manager; end
|
|
566
|
-
end
|
|
567
|
-
|
|
568
|
-
it "should not use the ignored column in a sub-class subquery" do
|
|
569
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
|
570
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, employees.updated_at, managers.num_staff, managers.another_duplicate_column FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
|
|
571
|
-
Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, employees.updated_at, managers.num_staff, managers.another_duplicate_column, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees'
|
|
572
|
-
end
|
|
573
|
-
|
|
574
|
-
it "should include schema for columns for tables for ancestor classes" do
|
|
575
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime})
|
|
576
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime}, :num_staff=>{:type=>:integer}, :another_duplicate_column=>{:type=>:integer})
|
|
577
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime}, :num_staff=>{:type=>:integer}, :another_duplicate_column=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
|
578
|
-
end
|
|
579
|
-
|
|
580
|
-
after do
|
|
581
|
-
Object.send(:remove_const, :Executive)
|
|
582
|
-
end
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
after do
|
|
586
|
-
Object.send(:remove_const, :Manager)
|
|
587
|
-
Object.send(:remove_const, :Employee)
|
|
588
|
-
end
|
|
589
|
-
end
|
|
590
|
-
|
|
591
|
-
describe "class_table_inheritance plugin with dataset defined with QualifiedIdentifier" do
|
|
592
|
-
before do
|
|
593
|
-
@db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
|
|
594
|
-
def @db.supports_schema_parsing?() true end
|
|
595
|
-
def @db.schema(table, opts={})
|
|
596
|
-
{Sequel[:hr][:employees]=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
|
597
|
-
Sequel[:hr][:managers]=>[[:id, {:type=>:integer}]],
|
|
598
|
-
Sequel[:hr][:staff]=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
|
599
|
-
Sequel[:hr][:executives]=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
|
600
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
601
|
-
end
|
|
602
|
-
@db.extend_datasets do
|
|
603
|
-
def columns
|
|
604
|
-
{[Sequel[:hr][:employees]]=>[:id, :name, :kind],
|
|
605
|
-
[Sequel[:hr][:managers]]=>[:id],
|
|
606
|
-
[Sequel[:hr][:staff]]=>[:id, :manager_id],
|
|
607
|
-
[Sequel[:hr][:employees], Sequel[:hr][:managers]]=>[:id, :name, :kind],
|
|
608
|
-
[Sequel[:hr][:employees], Sequel[:hr][:staff]]=>[:id, :name, :kind, :manager_id],
|
|
609
|
-
[Sequel[:hr][:employees], Sequel[:hr][:managers], Sequel[:hr][:executives]]=>[:id, :name, :kind, :manager_id, :num_managers],
|
|
610
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
611
|
-
end
|
|
612
|
-
end
|
|
613
|
-
end
|
|
614
|
-
after do
|
|
615
|
-
[:Manager, :Staff, :Employee, :Executive].each{|s| Object.send(:remove_const, s) if Object.const_defined?(s)}
|
|
616
|
-
end
|
|
617
|
-
|
|
618
|
-
describe "with table_map used to qualify subclasses" do
|
|
619
|
-
before do
|
|
620
|
-
::Employee = Class.new(Sequel::Model)
|
|
621
|
-
::Employee.db = @db
|
|
622
|
-
::Employee.set_dataset(Sequel[:hr][:employees])
|
|
623
|
-
class ::Employee
|
|
624
|
-
def _save_refresh; @values[:id] = 1 end
|
|
625
|
-
def self.columns
|
|
626
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
627
|
-
end
|
|
628
|
-
plugin :class_table_inheritance, :table_map=>{:Manager=>Sequel[:hr][:managers],:Staff=>Sequel[:hr][:staff]}
|
|
629
|
-
end
|
|
630
|
-
class ::Manager < Employee
|
|
631
|
-
one_to_many :staff_members, :class=>:Staff
|
|
632
|
-
end
|
|
633
|
-
class ::Staff < Employee
|
|
634
|
-
many_to_one :manager
|
|
635
|
-
end
|
|
636
|
-
end
|
|
637
|
-
|
|
638
|
-
it "should handle many_to_one relationships correctly" do
|
|
639
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E')
|
|
640
|
-
Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E')
|
|
641
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind FROM hr.employees INNER JOIN hr.managers ON (hr.managers.id = hr.employees.id)) AS employees WHERE (id = 3) LIMIT 1']
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
it "should handle one_to_many relationships correctly" do
|
|
645
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
|
|
646
|
-
Manager.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
|
|
647
|
-
@db.sqls.must_equal ['SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind, hr.staff.manager_id FROM hr.employees INNER JOIN hr.staff ON (hr.staff.id = hr.employees.id)) AS employees WHERE (employees.manager_id = 3)']
|
|
648
|
-
end
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
describe "without table_map or qualify_tables set" do
|
|
652
|
-
it "should use a non-qualified subquery in subclasses" do
|
|
653
|
-
def @db.schema(table, opts={})
|
|
654
|
-
{Sequel[:hr][:employees]=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
|
655
|
-
:managers=>[[:id, {:type=>:integer}]],
|
|
656
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
657
|
-
end
|
|
658
|
-
@db.extend_datasets do
|
|
659
|
-
def columns
|
|
660
|
-
{[Sequel[:hr][:employees]]=>[:id, :name, :kind],
|
|
661
|
-
[:managers]=>[:id],
|
|
662
|
-
[Sequel[:hr][:employees], :managers]=>[:id, :name, :kind]
|
|
663
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
|
664
|
-
end
|
|
665
|
-
end
|
|
666
|
-
::Employee = Class.new(Sequel::Model)
|
|
667
|
-
::Employee.db = @db
|
|
668
|
-
::Employee.set_dataset(Sequel[:hr][:employees])
|
|
669
|
-
class ::Employee
|
|
670
|
-
def _save_refresh; @values[:id] = 1 end
|
|
671
|
-
def self.columns
|
|
672
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
673
|
-
end
|
|
674
|
-
plugin :class_table_inheritance
|
|
675
|
-
end
|
|
676
|
-
class ::Manager < ::Employee
|
|
677
|
-
end
|
|
678
|
-
|
|
679
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM hr.employees'
|
|
680
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind FROM hr.employees INNER JOIN managers ON (managers.id = hr.employees.id)) AS employees'
|
|
681
|
-
end
|
|
682
|
-
end
|
|
683
|
-
|
|
684
|
-
describe "with qualify_tables option set" do
|
|
685
|
-
it "should use a subquery with the same qualifier in subclasses" do
|
|
686
|
-
::Employee = Class.new(Sequel::Model)
|
|
687
|
-
::Employee.db = @db
|
|
688
|
-
::Employee.set_dataset(Sequel[:hr][:employees])
|
|
689
|
-
class ::Employee
|
|
690
|
-
def _save_refresh; @values[:id] = 1 end
|
|
691
|
-
def self.columns
|
|
692
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
|
693
|
-
end
|
|
694
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>Sequel[:hr][:staff]}, qualify_tables: true
|
|
695
|
-
end
|
|
696
|
-
class ::Manager < ::Employee
|
|
697
|
-
one_to_many :staff_members, :class=>:Staff
|
|
698
|
-
end
|
|
699
|
-
class ::Staff < ::Employee
|
|
700
|
-
many_to_one :manager
|
|
701
|
-
end
|
|
702
|
-
class ::Executive < ::Manager
|
|
703
|
-
end
|
|
704
|
-
|
|
705
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM hr.employees'
|
|
706
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind FROM hr.employees INNER JOIN hr.managers ON (hr.managers.id = hr.employees.id)) AS employees'
|
|
707
|
-
Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind, hr.staff.manager_id FROM hr.employees INNER JOIN hr.staff ON (hr.staff.id = hr.employees.id)) AS employees'
|
|
708
|
-
Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT hr.employees.id, hr.employees.name, hr.employees.kind, hr.executives.num_managers FROM hr.employees INNER JOIN hr.managers ON (hr.managers.id = hr.employees.id) INNER JOIN hr.executives ON (hr.executives.id = hr.managers.id)) AS employees'
|
|
709
|
-
end
|
|
710
|
-
end
|
|
711
|
-
end
|
|
712
|
-
|
|
713
|
-
describe "class_table_inheritance plugin with schema_caching extension" do
|
|
714
|
-
before do
|
|
715
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
|
716
|
-
def @db.supports_schema_parsing?() true end
|
|
717
|
-
def @db.schema(table, opts={})
|
|
718
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
|
719
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}] ],
|
|
720
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
|
721
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
|
722
|
-
end
|
|
723
|
-
end
|
|
724
|
-
after do
|
|
725
|
-
[:Executive, :Manager, :Employee, :Staff].each{|s| Object.send(:remove_const, s) if Object.const_defined?(s)}
|
|
726
|
-
end
|
|
727
|
-
|
|
728
|
-
it "should not query for columns if the schema cache is present and a table_map is given" do
|
|
729
|
-
class ::Employee < Sequel::Model(@db)
|
|
730
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>:employees, :Manager=>:managers, :Executive=>:executives}
|
|
731
|
-
end
|
|
732
|
-
class ::Staff < Employee; end
|
|
733
|
-
class ::Manager < Employee; end
|
|
734
|
-
class ::Executive < Manager; end
|
|
735
|
-
Employee.columns.must_equal [:id, :name, :kind]
|
|
736
|
-
Staff.columns.must_equal [:id, :name, :kind]
|
|
737
|
-
Manager.columns.must_equal [:id, :name, :kind, :num_staff]
|
|
738
|
-
Executive.columns.must_equal [:id, :name, :kind, :num_staff, :num_managers]
|
|
739
|
-
@db.sqls.must_equal []
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
it "should not query for columns if the schema cache is present and no table_map is given" do
|
|
743
|
-
class ::Employee < Sequel::Model(@db)
|
|
744
|
-
plugin :class_table_inheritance
|
|
745
|
-
end
|
|
746
|
-
class ::Manager < Employee; end
|
|
747
|
-
class ::Executive < Manager; end
|
|
748
|
-
@db.sqls.must_equal []
|
|
749
|
-
end
|
|
750
|
-
end
|