sequel 4.49.0 → 5.0.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 +70 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +3 -5
- data/doc/advanced_associations.rdoc +86 -163
- data/doc/association_basics.rdoc +197 -274
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +66 -43
- data/doc/code_order.rdoc +1 -8
- data/doc/core_extensions.rdoc +81 -56
- data/doc/dataset_basics.rdoc +8 -17
- data/doc/dataset_filtering.rdoc +81 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +73 -30
- data/doc/migration.rdoc +19 -36
- data/doc/model_dataset_method_design.rdoc +14 -17
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +10 -10
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +52 -70
- data/doc/opening_databases.rdoc +39 -32
- data/doc/postgresql.rdoc +48 -38
- data/doc/prepared_statements.rdoc +27 -22
- data/doc/querying.rdoc +173 -150
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/schema_modification.rdoc +63 -60
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +3 -5
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +18 -17
- data/doc/validations.rdoc +48 -45
- data/doc/virtual_rows.rdoc +87 -115
- data/lib/sequel.rb +1 -1
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- data/lib/sequel/adapters/jdbc.rb +13 -73
- data/lib/sequel/adapters/jdbc/db2.rb +8 -37
- data/lib/sequel/adapters/jdbc/derby.rb +4 -50
- data/lib/sequel/adapters/jdbc/h2.rb +4 -25
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -26
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -31
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
- data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
- data/lib/sequel/adapters/mock.rb +4 -30
- data/lib/sequel/adapters/mysql.rb +7 -44
- data/lib/sequel/adapters/mysql2.rb +5 -23
- data/lib/sequel/adapters/odbc.rb +0 -19
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -12
- data/lib/sequel/adapters/odbc/oracle.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +7 -13
- data/lib/sequel/adapters/postgres.rb +13 -57
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +11 -51
- data/lib/sequel/adapters/shared/db2.rb +3 -61
- data/lib/sequel/adapters/shared/mssql.rb +21 -157
- data/lib/sequel/adapters/shared/mysql.rb +23 -224
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +44 -259
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +12 -101
- data/lib/sequel/adapters/sqlanywhere.rb +4 -23
- data/lib/sequel/adapters/sqlite.rb +2 -19
- data/lib/sequel/adapters/tinytds.rb +5 -15
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -4
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
- data/lib/sequel/adapters/utils/replace.rb +0 -5
- data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
- data/lib/sequel/ast_transformer.rb +3 -94
- data/lib/sequel/connection_pool.rb +26 -28
- data/lib/sequel/connection_pool/sharded_single.rb +1 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
- data/lib/sequel/connection_pool/single.rb +0 -2
- data/lib/sequel/connection_pool/threaded.rb +94 -110
- data/lib/sequel/core.rb +42 -101
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/database/connecting.rb +23 -60
- data/lib/sequel/database/dataset.rb +6 -9
- data/lib/sequel/database/dataset_defaults.rb +4 -48
- data/lib/sequel/database/features.rb +5 -4
- data/lib/sequel/database/logging.rb +2 -9
- data/lib/sequel/database/misc.rb +23 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +89 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/dataset.rb +18 -10
- data/lib/sequel/dataset/actions.rb +53 -107
- data/lib/sequel/dataset/dataset_module.rb +3 -15
- data/lib/sequel/dataset/features.rb +30 -30
- data/lib/sequel/dataset/graph.rb +40 -49
- data/lib/sequel/dataset/misc.rb +12 -37
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
- data/lib/sequel/dataset/prepared_statements.rb +23 -51
- data/lib/sequel/dataset/query.rb +71 -155
- data/lib/sequel/dataset/sql.rb +30 -225
- data/lib/sequel/deprecated.rb +18 -27
- data/lib/sequel/exceptions.rb +1 -17
- data/lib/sequel/extensions/_model_pg_row.rb +0 -7
- data/lib/sequel/extensions/_pretty_table.rb +1 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/connection_expiration.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +11 -11
- data/lib/sequel/extensions/core_extensions.rb +39 -49
- data/lib/sequel/extensions/core_refinements.rb +39 -45
- data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
- data/lib/sequel/extensions/date_arithmetic.rb +7 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/eval_inspect.rb +4 -11
- data/lib/sequel/extensions/freeze_datasets.rb +1 -69
- data/lib/sequel/extensions/from_block.rb +1 -35
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/identifier_mangling.rb +9 -19
- data/lib/sequel/extensions/implicit_subquery.rb +2 -2
- data/lib/sequel/extensions/inflector.rb +4 -4
- data/lib/sequel/extensions/migration.rb +23 -40
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
- data/lib/sequel/extensions/null_dataset.rb +2 -8
- data/lib/sequel/extensions/pagination.rb +1 -17
- data/lib/sequel/extensions/pg_array.rb +20 -189
- data/lib/sequel/extensions/pg_hstore.rb +11 -50
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_inet.rb +2 -15
- data/lib/sequel/extensions/pg_interval.rb +1 -20
- data/lib/sequel/extensions/pg_json.rb +7 -27
- data/lib/sequel/extensions/pg_loose_count.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +6 -121
- data/lib/sequel/extensions/pg_range_ops.rb +1 -3
- data/lib/sequel/extensions/pg_row.rb +5 -77
- data/lib/sequel/extensions/pg_row_ops.rb +2 -13
- data/lib/sequel/extensions/query.rb +3 -4
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/schema_dumper.rb +13 -13
- data/lib/sequel/extensions/select_remove.rb +3 -3
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/symbol_aref.rb +6 -20
- data/lib/sequel/model.rb +27 -62
- data/lib/sequel/model/associations.rb +128 -131
- data/lib/sequel/model/base.rb +171 -711
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +0 -3
- data/lib/sequel/model/exceptions.rb +2 -6
- data/lib/sequel/model/inflections.rb +1 -26
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/plugins/active_model.rb +2 -5
- data/lib/sequel/plugins/association_dependencies.rb +15 -15
- data/lib/sequel/plugins/association_pks.rb +14 -28
- data/lib/sequel/plugins/association_proxies.rb +6 -7
- data/lib/sequel/plugins/auto_validations.rb +4 -4
- data/lib/sequel/plugins/before_after_save.rb +0 -43
- data/lib/sequel/plugins/blacklist_security.rb +9 -8
- data/lib/sequel/plugins/boolean_readers.rb +3 -3
- data/lib/sequel/plugins/boolean_subsets.rb +2 -2
- data/lib/sequel/plugins/caching.rb +5 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
- data/lib/sequel/plugins/column_conflicts.rb +2 -2
- data/lib/sequel/plugins/column_select.rb +2 -2
- data/lib/sequel/plugins/composition.rb +15 -24
- data/lib/sequel/plugins/constraint_validations.rb +4 -3
- data/lib/sequel/plugins/csv_serializer.rb +13 -20
- data/lib/sequel/plugins/dataset_associations.rb +2 -2
- data/lib/sequel/plugins/def_dataset_method.rb +5 -5
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/finder.rb +16 -10
- data/lib/sequel/plugins/force_encoding.rb +1 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -106
- data/lib/sequel/plugins/input_transformer.rb +10 -11
- data/lib/sequel/plugins/insert_returning_select.rb +1 -9
- data/lib/sequel/plugins/instance_filters.rb +5 -5
- data/lib/sequel/plugins/instance_hooks.rb +7 -52
- data/lib/sequel/plugins/inverted_subsets.rb +3 -1
- data/lib/sequel/plugins/json_serializer.rb +19 -19
- data/lib/sequel/plugins/lazy_attributes.rb +1 -10
- data/lib/sequel/plugins/list.rb +6 -6
- data/lib/sequel/plugins/many_through_many.rb +11 -8
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +18 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +8 -2
- data/lib/sequel/plugins/pg_row.rb +2 -11
- data/lib/sequel/plugins/prepared_statements.rb +13 -66
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +7 -7
- data/lib/sequel/plugins/serialization.rb +15 -33
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +2 -8
- data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/static_cache.rb +8 -9
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/timestamps.rb +6 -7
- data/lib/sequel/plugins/touch.rb +4 -8
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +2 -2
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/update_or_create.rb +3 -3
- data/lib/sequel/plugins/update_refresh.rb +3 -3
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validation_class_methods.rb +10 -9
- data/lib/sequel/plugins/validation_contexts.rb +4 -4
- data/lib/sequel/plugins/validation_helpers.rb +26 -25
- data/lib/sequel/plugins/whitelist_security.rb +13 -9
- data/lib/sequel/plugins/xml_serializer.rb +24 -25
- data/lib/sequel/sql.rb +145 -276
- data/lib/sequel/timezones.rb +8 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapter_spec.rb +1 -1
- data/spec/adapters/db2_spec.rb +2 -103
- data/spec/adapters/mssql_spec.rb +89 -68
- data/spec/adapters/mysql_spec.rb +101 -480
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +312 -565
- data/spec/adapters/spec_helper.rb +12 -31
- data/spec/adapters/sqlanywhere_spec.rb +2 -77
- data/spec/adapters/sqlite_spec.rb +8 -146
- data/spec/bin_spec.rb +11 -16
- data/spec/core/connection_pool_spec.rb +173 -74
- data/spec/core/database_spec.rb +64 -244
- data/spec/core/dataset_spec.rb +81 -415
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +176 -4
- data/spec/core/object_graph_spec.rb +11 -60
- data/spec/core/placeholder_literalizer_spec.rb +1 -14
- data/spec/core/schema_generator_spec.rb +51 -40
- data/spec/core/schema_spec.rb +74 -77
- data/spec/core/spec_helper.rb +6 -24
- data/spec/core/version_spec.rb +1 -1
- data/spec/core_extensions_spec.rb +7 -83
- data/spec/core_model_spec.rb +2 -2
- data/spec/deprecation_helper.rb +2 -14
- data/spec/extensions/accessed_columns_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +2 -2
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +4 -59
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_literal_strings_spec.rb +1 -12
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +35 -1086
- data/spec/extensions/column_conflicts_spec.rb +1 -1
- data/spec/extensions/column_select_spec.rb +4 -4
- data/spec/extensions/columns_introspection_spec.rb +1 -1
- data/spec/extensions/columns_updated_spec.rb +1 -1
- data/spec/extensions/composition_spec.rb +1 -7
- data/spec/extensions/connection_expiration_spec.rb +3 -3
- data/spec/extensions/connection_validator_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
- data/spec/extensions/constraint_validations_spec.rb +1 -1
- data/spec/extensions/core_refinements_spec.rb +1 -3
- data/spec/extensions/csv_serializer_spec.rb +4 -9
- data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +2 -1
- data/spec/extensions/dataset_source_alias_spec.rb +1 -1
- data/spec/extensions/date_arithmetic_spec.rb +3 -3
- data/spec/extensions/def_dataset_method_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +8 -9
- data/spec/extensions/dirty_spec.rb +1 -1
- data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
- data/spec/extensions/eager_each_spec.rb +2 -2
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +1 -1
- data/spec/extensions/force_encoding_spec.rb +2 -5
- data/spec/extensions/freeze_datasets_spec.rb +1 -1
- data/spec/extensions/graph_each_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +1 -194
- data/spec/extensions/identifier_mangling_spec.rb +17 -170
- data/spec/extensions/implicit_subquery_spec.rb +1 -5
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/input_transformer_spec.rb +7 -2
- data/spec/extensions/insert_returning_select_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -95
- data/spec/extensions/inverted_subsets_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +1 -7
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +2 -2
- data/spec/extensions/modification_detection_spec.rb +1 -1
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +1 -29
- data/spec/extensions/null_dataset_spec.rb +1 -11
- data/spec/extensions/optimistic_locking_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +4 -1
- data/spec/extensions/pg_array_ops_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +3 -48
- data/spec/extensions/pg_enum_spec.rb +1 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +23 -32
- data/spec/extensions/pg_inet_ops_spec.rb +1 -1
- data/spec/extensions/pg_inet_spec.rb +1 -14
- data/spec/extensions/pg_interval_spec.rb +3 -13
- data/spec/extensions/pg_json_ops_spec.rb +1 -1
- data/spec/extensions/pg_json_spec.rb +1 -13
- data/spec/extensions/pg_loose_count_spec.rb +1 -1
- data/spec/extensions/pg_range_ops_spec.rb +1 -1
- data/spec/extensions/pg_range_spec.rb +3 -88
- data/spec/extensions/pg_row_ops_spec.rb +1 -1
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pg_row_spec.rb +1 -44
- data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +1 -1
- data/spec/extensions/round_timestamps_spec.rb +1 -5
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +1 -1
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +2 -14
- data/spec/extensions/server_block_spec.rb +1 -1
- data/spec/extensions/server_logging_spec.rb +2 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/shared_caching_spec.rb +1 -28
- data/spec/extensions/single_table_inheritance_spec.rb +2 -5
- data/spec/extensions/singular_table_names_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +5 -27
- data/spec/extensions/split_array_nil_spec.rb +1 -1
- data/spec/extensions/split_values_spec.rb +1 -1
- data/spec/extensions/sql_comments_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/subset_conditions_spec.rb +1 -1
- data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
- data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
- data/spec/extensions/table_select_spec.rb +4 -4
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +3 -3
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +1 -1
- data/spec/extensions/update_primary_key_spec.rb +4 -3
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +10 -12
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/extensions/validation_contexts_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +10 -44
- data/spec/extensions/whitelist_security_spec.rb +5 -5
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/guards_helper.rb +2 -1
- data/spec/integration/associations_test.rb +1 -23
- data/spec/integration/database_test.rb +7 -7
- data/spec/integration/dataset_test.rb +5 -47
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +4 -82
- data/spec/integration/plugin_test.rb +6 -22
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +6 -6
- data/spec/integration/spec_helper.rb +13 -21
- data/spec/integration/timezone_test.rb +5 -5
- data/spec/integration/transaction_test.rb +3 -55
- data/spec/integration/type_test.rb +9 -9
- data/spec/model/association_reflection_spec.rb +24 -9
- data/spec/model/associations_spec.rb +124 -303
- data/spec/model/base_spec.rb +18 -137
- data/spec/model/class_dataset_methods_spec.rb +2 -20
- data/spec/model/dataset_methods_spec.rb +1 -20
- data/spec/model/eager_loading_spec.rb +17 -11
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +15 -320
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +29 -121
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +8 -64
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- data/lib/sequel/adapters/do.rb +0 -166
- data/lib/sequel/adapters/do/mysql.rb +0 -69
- data/lib/sequel/adapters/do/postgres.rb +0 -46
- data/lib/sequel/adapters/do/sqlite3.rb +0 -41
- data/lib/sequel/adapters/jdbc/as400.rb +0 -92
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
- data/lib/sequel/adapters/odbc/progress.rb +0 -12
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -261
- data/lib/sequel/adapters/shared/informix.rb +0 -63
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift.rb +0 -169
- data/lib/sequel/adapters/swift/mysql.rb +0 -50
- data/lib/sequel/adapters/swift/postgres.rb +0 -49
- data/lib/sequel/adapters/swift/sqlite.rb +0 -48
- data/lib/sequel/adapters/utils/pg_types.rb +0 -4
- data/lib/sequel/dataset/mutation.rb +0 -98
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
- data/lib/sequel/extensions/filter_having.rb +0 -65
- data/lib/sequel/extensions/hash_aliases.rb +0 -51
- data/lib/sequel/extensions/meta_def.rb +0 -37
- data/lib/sequel/extensions/query_literals.rb +0 -86
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
- data/lib/sequel/extensions/set_overrides.rb +0 -82
- data/lib/sequel/no_core_ext.rb +0 -4
- data/lib/sequel/plugins/association_autoreloading.rb +0 -11
- data/lib/sequel/plugins/identifier_columns.rb +0 -49
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
- data/lib/sequel/plugins/schema.rb +0 -84
- data/lib/sequel/plugins/scissors.rb +0 -37
- data/spec/core/dataset_mutation_spec.rb +0 -253
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/filter_having_spec.rb +0 -42
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/hash_aliases_spec.rb +0 -26
- data/spec/extensions/identifier_columns_spec.rb +0 -19
- data/spec/extensions/meta_def_spec.rb +0 -35
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
- data/spec/extensions/query_literals_spec.rb +0 -185
- data/spec/extensions/schema_spec.rb +0 -123
- data/spec/extensions/scissors_spec.rb +0 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
- data/spec/extensions/set_overrides_spec.rb +0 -75
@@ -1,1048 +1,8 @@
|
|
1
|
-
|
1
|
+
require_relative "spec_helper"
|
2
2
|
|
3
3
|
describe "class_table_inheritance plugin" do
|
4
4
|
before do
|
5
|
-
@db = Sequel.mock(: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}], [:kind, {:type=>:string}]],
|
9
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
|
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
|
-
class ::Employee < Sequel::Model(@db)
|
27
|
-
def _save_refresh; @values[:id] = 1 end
|
28
|
-
def self.columns
|
29
|
-
dataset.columns
|
30
|
-
end
|
31
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
32
|
-
end
|
33
|
-
deprecated do
|
34
|
-
class ::Manager < Employee
|
35
|
-
one_to_many :staff_members, :class=>:Staff
|
36
|
-
end
|
37
|
-
class ::Executive < Manager
|
38
|
-
end
|
39
|
-
class ::Ceo < Executive
|
40
|
-
end
|
41
|
-
class ::Staff < Employee
|
42
|
-
many_to_one :manager
|
43
|
-
end
|
44
|
-
end
|
45
|
-
@ds = Employee.dataset
|
46
|
-
@db.sqls
|
47
|
-
end
|
48
|
-
after do
|
49
|
-
Object.send(:remove_const, :Ceo)
|
50
|
-
Object.send(:remove_const, :Executive)
|
51
|
-
Object.send(:remove_const, :Manager)
|
52
|
-
Object.send(:remove_const, :Staff)
|
53
|
-
Object.send(:remove_const, :Employee)
|
54
|
-
end
|
55
|
-
|
56
|
-
deprecated "should freeze CTI information when freezing model class" do
|
57
|
-
Employee.freeze
|
58
|
-
Employee.cti_models.frozen?.must_equal true
|
59
|
-
Employee.cti_tables.frozen?.must_equal true
|
60
|
-
Employee.cti_instance_dataset.frozen?.must_equal true
|
61
|
-
Employee.cti_table_columns.frozen?.must_equal true
|
62
|
-
Employee.cti_table_map.frozen?.must_equal true
|
63
|
-
end
|
64
|
-
|
65
|
-
deprecated "should support cti_key and cti_model_map" do
|
66
|
-
Employee.cti_key.must_equal Employee.sti_key
|
67
|
-
Employee.cti_model_map.must_equal Employee.sti_model_map
|
68
|
-
end
|
69
|
-
|
70
|
-
deprecated "should not attempt to use prepared statements" do
|
71
|
-
Manager.plugin :prepared_statements
|
72
|
-
Manager[1]
|
73
|
-
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1"]
|
74
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
|
75
|
-
@db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
|
76
|
-
@db.fetch = {:id=>1, :kind=>'Manager', :num_staff=>2}
|
77
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).refresh
|
78
|
-
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1"]
|
79
|
-
end
|
80
|
-
|
81
|
-
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
82
|
-
Executive.cti_base_model.must_equal Employee
|
83
|
-
end
|
84
|
-
|
85
|
-
deprecated "#cti_columns should be a mapping of table names to columns" do
|
86
|
-
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
87
|
-
end
|
88
|
-
|
89
|
-
deprecated "should have simple_table = nil for all subclasses" do
|
90
|
-
Manager.simple_table.must_be_nil
|
91
|
-
Executive.simple_table.must_be_nil
|
92
|
-
Ceo.simple_table.must_be_nil
|
93
|
-
Staff.simple_table.must_be_nil
|
94
|
-
end
|
95
|
-
|
96
|
-
deprecated "should have working row_proc if using set_dataset in subclass to remove columns" do
|
97
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
98
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
99
|
-
Manager[1].must_equal Ceo.load(:id=>1, :kind=>'Ceo')
|
100
|
-
end
|
101
|
-
|
102
|
-
deprecated "should use a joined dataset in subclasses" do
|
103
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
104
|
-
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
105
|
-
Executive.dataset.sql.must_equal '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)'
|
106
|
-
Ceo.dataset.sql.must_equal '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\'))'
|
107
|
-
Staff.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)'
|
108
|
-
end
|
109
|
-
|
110
|
-
deprecated "should return rows with the correct class based on the polymorphic_key value" do
|
111
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff]
|
112
|
-
end
|
113
|
-
|
114
|
-
deprecated "should return rows with the correct class based on the polymorphic_key value for subclasses" do
|
115
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}]).all.collect{|x| x.class}.must_equal [Manager, Executive, Ceo]
|
116
|
-
end
|
117
|
-
|
118
|
-
deprecated "should have refresh return all columns in subclass after loading from superclass" do
|
119
|
-
Employee.dataset = Employee.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo'}])
|
120
|
-
Ceo.dataset = Ceo.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2}])
|
121
|
-
a = Employee.first
|
122
|
-
a.class.must_equal Ceo
|
123
|
-
a.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo')
|
124
|
-
a.refresh.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2)
|
125
|
-
@db.sqls.must_equal ["SELECT * FROM employees LIMIT 1",
|
126
|
-
"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')) AND (executives.id = 1)) LIMIT 1"]
|
127
|
-
end
|
128
|
-
|
129
|
-
deprecated "should return rows with the current class if cti_key is nil" do
|
130
|
-
Employee.plugin(:class_table_inheritance)
|
131
|
-
Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee]
|
132
|
-
end
|
133
|
-
|
134
|
-
deprecated "should return rows with the current class if cti_key is nil in subclasses" do
|
135
|
-
Employee.plugin(:class_table_inheritance)
|
136
|
-
Object.send(:remove_const, :Executive)
|
137
|
-
Object.send(:remove_const, :Manager)
|
138
|
-
class ::Manager < Employee; end
|
139
|
-
class ::Executive < Manager; end
|
140
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}]).all.map{|x| x.class}.must_equal [Manager, Manager]
|
141
|
-
end
|
142
|
-
|
143
|
-
deprecated "should handle a model map with integer values" do
|
144
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo})
|
145
|
-
Object.send(:remove_const, :Ceo)
|
146
|
-
Object.send(:remove_const, :Executive)
|
147
|
-
Object.send(:remove_const, :Manager)
|
148
|
-
class ::Manager < Employee; end
|
149
|
-
class ::Executive < Manager; end
|
150
|
-
class ::Ceo < Executive; end
|
151
|
-
Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
152
|
-
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo]
|
153
|
-
Manager.dataset = Manager.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
154
|
-
Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive, Ceo]
|
155
|
-
end
|
156
|
-
|
157
|
-
deprecated "should fallback to the main class if the given class does not exist" do
|
158
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Blah'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Manager, Employee, Staff]
|
159
|
-
end
|
160
|
-
|
161
|
-
deprecated "should fallback to the main class if the given class does not exist in subclasses" do
|
162
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Blah'}]).all.map{|x| x.class}.must_equal [Manager, Executive, Ceo, Manager]
|
163
|
-
end
|
164
|
-
|
165
|
-
deprecated "should sets the model class name for the key when creating new parent class records" do
|
166
|
-
Employee.create
|
167
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
168
|
-
end
|
169
|
-
|
170
|
-
deprecated "should sets the model class name for the key when creating new subclass records" do
|
171
|
-
Ceo.create
|
172
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Ceo')",
|
173
|
-
"INSERT INTO managers (id) VALUES (1)",
|
174
|
-
"INSERT INTO executives (id) VALUES (1)"]
|
175
|
-
end
|
176
|
-
|
177
|
-
deprecated "should ignore existing cti_key value when creating new records" do
|
178
|
-
Employee.create(:kind=>'Manager')
|
179
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
180
|
-
end
|
181
|
-
|
182
|
-
deprecated "should ignore existing cti_key value in subclasses" do
|
183
|
-
Manager.create(:kind=>'Executive')
|
184
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
|
185
|
-
"INSERT INTO managers (id) VALUES (1)"]
|
186
|
-
end
|
187
|
-
|
188
|
-
deprecated "should handle validations on the type column field" do
|
189
|
-
o = Employee.new
|
190
|
-
def o.validate
|
191
|
-
errors.add(:kind, 'not present') unless kind
|
192
|
-
end
|
193
|
-
o.valid?.must_equal true
|
194
|
-
end
|
195
|
-
|
196
|
-
deprecated "should set the type column field even when not validating" do
|
197
|
-
Employee.new.save(:validate=>false)
|
198
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
199
|
-
end
|
200
|
-
|
201
|
-
deprecated "should allow specifying a map of names to tables to override implicit mapping" do
|
202
|
-
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
203
|
-
Staff.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)'
|
204
|
-
end
|
205
|
-
|
206
|
-
deprecated "should lazily load attributes for columns in subclass tables" do
|
207
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2)
|
208
|
-
m = Manager[1]
|
209
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1']
|
210
|
-
@db.fetch = {:num_managers=>3}
|
211
|
-
m.must_be_kind_of Ceo
|
212
|
-
m.num_managers.must_equal 3
|
213
|
-
@db.sqls.must_equal ['SELECT executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (executives.id = 1) LIMIT 1']
|
214
|
-
m.values.must_equal(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2, :num_managers=>3)
|
215
|
-
end
|
216
|
-
|
217
|
-
deprecated "should lazily load columns in middle classes correctly when loaded from parent class" do
|
218
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
219
|
-
@db.fetch = [[:num_staff=>2]]
|
220
|
-
e = Employee[1]
|
221
|
-
e.must_be_kind_of(Ceo)
|
222
|
-
@db.sqls.must_equal ["SELECT * FROM employees WHERE (id = 1) LIMIT 1"]
|
223
|
-
e.num_staff.must_equal 2
|
224
|
-
@db.sqls.must_equal ["SELECT managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1"]
|
225
|
-
end
|
226
|
-
|
227
|
-
deprecated "should eagerly load lazily columns in subclasses when loaded from parent class" do
|
228
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
229
|
-
@db.fetch = [[{:id=>1, :num_staff=>2}], [{:id=>1, :num_managers=>3}]]
|
230
|
-
e = Employee.all.first
|
231
|
-
e.must_be_kind_of(Ceo)
|
232
|
-
@db.sqls.must_equal ["SELECT * FROM employees"]
|
233
|
-
e.num_staff.must_equal 2
|
234
|
-
@db.sqls.must_equal ["SELECT managers.id, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id IN (1))"]
|
235
|
-
e.num_managers.must_equal 3
|
236
|
-
@db.sqls.must_equal ['SELECT executives.id, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (executives.id IN (1))']
|
237
|
-
end
|
238
|
-
|
239
|
-
deprecated "should include schema for columns for tables for ancestor classes" do
|
240
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
|
241
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
242
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
243
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
244
|
-
end
|
245
|
-
|
246
|
-
deprecated "should use the correct primary key (which should have the same name in all subclasses)" do
|
247
|
-
[Employee, Manager, Executive, Ceo, Staff].each{|c| c.primary_key.must_equal :id}
|
248
|
-
end
|
249
|
-
|
250
|
-
deprecated "should have table_name return the table name of the most specific table" do
|
251
|
-
Employee.table_name.must_equal :employees
|
252
|
-
Manager.table_name.must_equal :managers
|
253
|
-
Executive.table_name.must_equal :executives
|
254
|
-
Ceo.table_name.must_equal :executives
|
255
|
-
Staff.table_name.must_equal :staff
|
256
|
-
end
|
257
|
-
|
258
|
-
deprecated "should delete the correct rows from all tables when deleting" do
|
259
|
-
Ceo.load(:id=>1).delete
|
260
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
261
|
-
end
|
262
|
-
|
263
|
-
deprecated "should not allow deletion of frozen object" do
|
264
|
-
o = Ceo.load(:id=>1)
|
265
|
-
o.freeze
|
266
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
267
|
-
@db.sqls.must_equal []
|
268
|
-
end
|
269
|
-
|
270
|
-
deprecated "should insert the correct rows into all tables when inserting" do
|
271
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
272
|
-
sqls = @db.sqls
|
273
|
-
sqls.length.must_equal 3
|
274
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Ceo)', '(E|Ceo)'\)/)
|
275
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\)/)
|
276
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\)/)
|
277
|
-
end
|
278
|
-
|
279
|
-
deprecated "should insert the correct rows into all tables when inserting when insert_select is supported" do
|
280
|
-
[Executive, Manager, Employee].each do |klass|
|
281
|
-
klass.instance_variable_set(:@cti_instance_dataset, klass.cti_instance_dataset.with_extend do
|
282
|
-
def supports_insert_select?; true; end
|
283
|
-
def insert_select(v)
|
284
|
-
db.run(insert_sql(v) + " RETURNING *")
|
285
|
-
v.merge(:id=>1)
|
286
|
-
end
|
287
|
-
end)
|
288
|
-
end
|
289
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
290
|
-
sqls = @db.sqls
|
291
|
-
sqls.length.must_equal 3
|
292
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Ceo)', '(E|Ceo)'\) RETURNING \*/)
|
293
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\) RETURNING \*/)
|
294
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\) RETURNING \*/)
|
295
|
-
end
|
296
|
-
|
297
|
-
deprecated "should insert the correct rows into all tables with a given primary key" do
|
298
|
-
e = Ceo.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
299
|
-
e.id = 2
|
300
|
-
e.save
|
301
|
-
sqls = @db.sqls
|
302
|
-
sqls.length.must_equal 3
|
303
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind|id), (name|kind|id), (name|kind|id)\) VALUES \(('E'|'Ceo'|2), ('E'|'Ceo'|2), ('E'|'Ceo'|2)\)/)
|
304
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \(2, 2\)/)
|
305
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
306
|
-
end
|
307
|
-
|
308
|
-
deprecated "should update the correct rows in all tables when updating" do
|
309
|
-
Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
310
|
-
@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)"]
|
311
|
-
end
|
312
|
-
|
313
|
-
deprecated "should handle many_to_one relationships correctly" do
|
314
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
315
|
-
Staff.load(:manager_id=>3).manager.must_equal Ceo.load(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
316
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 3) LIMIT 1']
|
317
|
-
end
|
318
|
-
|
319
|
-
deprecated "should handle one_to_many relationships correctly" do
|
320
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)
|
321
|
-
Ceo.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)]
|
322
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id) WHERE (staff.manager_id = 3)']
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
describe "class_table_inheritance plugin without sti_key" do
|
327
|
-
before do
|
328
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
329
|
-
def @db.supports_schema_parsing?() true end
|
330
|
-
def @db.schema(table, opts={})
|
331
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}]],
|
332
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
|
333
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
334
|
-
:staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
335
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
336
|
-
end
|
337
|
-
@db.extend_datasets do
|
338
|
-
def columns
|
339
|
-
{[:employees]=>[:id, :name],
|
340
|
-
[:managers]=>[:id, :num_staff],
|
341
|
-
[:executives]=>[:id, :num_managers],
|
342
|
-
[:staff]=>[:id, :manager_id],
|
343
|
-
[:employees, :managers]=>[:id, :name, :num_staff],
|
344
|
-
[:employees, :managers, :executives]=>[:id, :name, :num_staff, :num_managers],
|
345
|
-
[:employees, :staff]=>[:id, :name, :manager_id],
|
346
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
347
|
-
end
|
348
|
-
end
|
349
|
-
class ::Employee < Sequel::Model(@db)
|
350
|
-
def _save_refresh; @values[:id] = 1 end
|
351
|
-
def self.columns
|
352
|
-
dataset.columns
|
353
|
-
end
|
354
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}
|
355
|
-
end
|
356
|
-
deprecated do
|
357
|
-
class ::Manager < Employee
|
358
|
-
one_to_many :staff_members, :class=>:Staff
|
359
|
-
end
|
360
|
-
class ::Executive < Manager
|
361
|
-
end
|
362
|
-
class ::Staff < Employee
|
363
|
-
many_to_one :manager
|
364
|
-
end
|
365
|
-
end
|
366
|
-
@ds = Employee.dataset
|
367
|
-
@db.sqls
|
368
|
-
end
|
369
|
-
after do
|
370
|
-
Object.send(:remove_const, :Executive)
|
371
|
-
Object.send(:remove_const, :Manager)
|
372
|
-
Object.send(:remove_const, :Staff)
|
373
|
-
Object.send(:remove_const, :Employee)
|
374
|
-
end
|
375
|
-
|
376
|
-
deprecated "should have simple_table = nil for all subclasses" do
|
377
|
-
Manager.simple_table.must_be_nil
|
378
|
-
Executive.simple_table.must_be_nil
|
379
|
-
Staff.simple_table.must_be_nil
|
380
|
-
end
|
381
|
-
|
382
|
-
deprecated "should have working row_proc if using set_dataset in subclass to remove columns" do
|
383
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
384
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1)
|
385
|
-
Manager[1].must_equal Manager.load(:id=>1)
|
386
|
-
end
|
387
|
-
|
388
|
-
deprecated "should use a dataset in subclasses" do
|
389
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
390
|
-
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
391
|
-
Executive.dataset.sql.must_equal '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)'
|
392
|
-
Staff.dataset.sql.must_equal 'SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)'
|
393
|
-
end
|
394
|
-
|
395
|
-
deprecated "should return rows with the current class if cti_key is nil" do
|
396
|
-
Employee.plugin(:class_table_inheritance)
|
397
|
-
Employee.dataset = Employee.dataset.with_fetch([{}])
|
398
|
-
Employee.first.class.must_equal Employee
|
399
|
-
end
|
400
|
-
|
401
|
-
|
402
|
-
deprecated "should include schema for columns for tables for ancestor classes" do
|
403
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string})
|
404
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
405
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
406
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
407
|
-
end
|
408
|
-
|
409
|
-
deprecated "should use the correct primary key (which should have the same name in all subclasses)" do
|
410
|
-
[Employee, Manager, Executive, Staff].each{|c| c.primary_key.must_equal :id}
|
411
|
-
end
|
412
|
-
|
413
|
-
deprecated "should have table_name return the table name of the most specific table" do
|
414
|
-
Employee.table_name.must_equal :employees
|
415
|
-
Manager.table_name.must_equal :managers
|
416
|
-
Executive.table_name.must_equal :executives
|
417
|
-
Staff.table_name.must_equal :staff
|
418
|
-
end
|
419
|
-
|
420
|
-
deprecated "should delete the correct rows from all tables when deleting" do
|
421
|
-
Executive.load(:id=>1).delete
|
422
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
423
|
-
end
|
424
|
-
|
425
|
-
deprecated "should not allow deletion of frozen object" do
|
426
|
-
o = Executive.load(:id=>1)
|
427
|
-
o.freeze
|
428
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
429
|
-
@db.sqls.must_equal []
|
430
|
-
end
|
431
|
-
|
432
|
-
deprecated "should insert the correct rows into all tables when inserting" do
|
433
|
-
Executive.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
434
|
-
sqls = @db.sqls
|
435
|
-
sqls.length.must_equal 3
|
436
|
-
sqls[0].must_match(/INSERT INTO employees \(name\) VALUES \('E'\)/)
|
437
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\)/)
|
438
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\)/)
|
439
|
-
end
|
440
|
-
|
441
|
-
deprecated "should insert the correct rows into all tables with a given primary key" do
|
442
|
-
e = Executive.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
443
|
-
e.id = 2
|
444
|
-
e.save
|
445
|
-
sqls = @db.sqls
|
446
|
-
sqls.length.must_equal 3
|
447
|
-
sqls[0].must_match(/INSERT INTO employees \((name|id), (name|id)\) VALUES \(('E'|2), ('E'|2)\)/)
|
448
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \(2, 2\)/)
|
449
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
450
|
-
end
|
451
|
-
|
452
|
-
deprecated "should update the correct rows in all tables when updating" do
|
453
|
-
Executive.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
454
|
-
@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)"]
|
455
|
-
end
|
456
|
-
|
457
|
-
deprecated "should handle many_to_one relationships correctly" do
|
458
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :num_staff=>3)
|
459
|
-
Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E', :num_staff=>3)
|
460
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 3) LIMIT 1']
|
461
|
-
end
|
462
|
-
|
463
|
-
deprecated "should handle one_to_many relationships correctly" do
|
464
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
|
465
|
-
Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
|
466
|
-
@db.sqls.must_equal ['SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id) WHERE (staff.manager_id = 3)']
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
describe "class_table_inheritance plugin with duplicate columns" do
|
471
|
-
before do
|
472
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
473
|
-
def @db.supports_schema_parsing?() true end
|
474
|
-
def @db.schema(table, opts={})
|
475
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
476
|
-
:managers=>[[:id, {:type=>:integer}], [:name, {:type=>:string}]],
|
477
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
478
|
-
end
|
479
|
-
@db.extend_datasets do
|
480
|
-
def columns
|
481
|
-
{[:employees]=>[:id, :name, :kind],
|
482
|
-
[:managers]=>[:id, :name],
|
483
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
484
|
-
end
|
485
|
-
end
|
486
|
-
class ::Employee < Sequel::Model(@db)
|
487
|
-
def _save_refresh; @values[:id] = 1 end
|
488
|
-
def self.columns
|
489
|
-
dataset.columns
|
490
|
-
end
|
491
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
492
|
-
end
|
493
|
-
deprecated do
|
494
|
-
class ::Manager < Employee; end
|
495
|
-
end
|
496
|
-
@ds = Employee.dataset
|
497
|
-
@db.sqls
|
498
|
-
end
|
499
|
-
after do
|
500
|
-
Object.send(:remove_const, :Manager)
|
501
|
-
Object.send(:remove_const, :Employee)
|
502
|
-
end
|
503
|
-
|
504
|
-
deprecated "should select names from both tables" do
|
505
|
-
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.name FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
506
|
-
end
|
507
|
-
end
|
508
|
-
|
509
|
-
describe "class_table_inheritance plugin with :alias option" do
|
510
|
-
before do
|
511
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
512
|
-
def @db.supports_schema_parsing?() true end
|
513
|
-
def @db.schema(table, opts={})
|
514
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
515
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
|
516
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
517
|
-
:staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
518
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
519
|
-
end
|
520
|
-
@db.extend_datasets do
|
521
|
-
def columns
|
522
|
-
{[:employees]=>[:id, :name, :kind],
|
523
|
-
[:managers]=>[:id, :num_staff],
|
524
|
-
[:executives]=>[:id, :num_managers],
|
525
|
-
[:staff]=>[:id, :manager_id],
|
526
|
-
[:employees, :managers]=>[:id, :name, :kind, :num_staff],
|
527
|
-
[:employees, :managers, :executives]=>[:id, :name, :kind, :num_staff, :num_managers],
|
528
|
-
[:employees, :staff]=>[:id, :name, :kind, :manager_id],
|
529
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
530
|
-
end
|
531
|
-
end
|
532
|
-
class ::Employee < Sequel::Model(@db)
|
533
|
-
def _save_refresh; @values[:id] = 1 end
|
534
|
-
def self.columns
|
535
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
536
|
-
end
|
537
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}, :alias=>:employees
|
538
|
-
end
|
539
|
-
class ::Manager < Employee
|
540
|
-
one_to_many :staff_members, :class=>:Staff
|
541
|
-
end
|
542
|
-
class ::Executive < Manager
|
543
|
-
end
|
544
|
-
class ::Ceo < Executive
|
545
|
-
end
|
546
|
-
class ::Staff < Employee
|
547
|
-
many_to_one :manager
|
548
|
-
end
|
549
|
-
@ds = Employee.dataset
|
550
|
-
@db.sqls
|
551
|
-
end
|
552
|
-
after do
|
553
|
-
Object.send(:remove_const, :Ceo)
|
554
|
-
Object.send(:remove_const, :Executive)
|
555
|
-
Object.send(:remove_const, :Manager)
|
556
|
-
Object.send(:remove_const, :Staff)
|
557
|
-
Object.send(:remove_const, :Employee)
|
558
|
-
end
|
559
|
-
|
560
|
-
it "should freeze CTI information when freezing model class" do
|
561
|
-
Employee.freeze
|
562
|
-
Employee.cti_models.frozen?.must_equal true
|
563
|
-
Employee.cti_tables.frozen?.must_equal true
|
564
|
-
Employee.cti_instance_dataset.frozen?.must_equal true
|
565
|
-
Employee.cti_table_columns.frozen?.must_equal true
|
566
|
-
Employee.cti_table_map.frozen?.must_equal true
|
567
|
-
end
|
568
|
-
|
569
|
-
it "should not attempt to use prepared statements" do
|
570
|
-
Manager.plugin :prepared_statements
|
571
|
-
Manager[1]
|
572
|
-
@db.sqls.must_equal ["SELECT id, name, kind, 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 (id = 1) LIMIT 1"]
|
573
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
|
574
|
-
@db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
|
575
|
-
@db.fetch = {:id=>1, :kind=>'Manager', :num_staff=>2}
|
576
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).refresh
|
577
|
-
@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"]
|
578
|
-
end
|
579
|
-
|
580
|
-
deprecated "#cti_base_model should be the model that loaded the plugin" do
|
581
|
-
Executive.cti_base_model.must_equal Employee
|
582
|
-
end
|
583
|
-
|
584
|
-
it "#cti_models.first should be the model that loaded the plugin" do
|
585
|
-
Executive.cti_models.first.must_equal Employee
|
586
|
-
end
|
587
|
-
|
588
|
-
deprecated "#cti_columns should be a mapping of table names to columns" do
|
589
|
-
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
590
|
-
end
|
591
|
-
|
592
|
-
it "should have simple_table = nil for all subclasses" do
|
593
|
-
Manager.simple_table.must_be_nil
|
594
|
-
Executive.simple_table.must_be_nil
|
595
|
-
Ceo.simple_table.must_be_nil
|
596
|
-
Staff.simple_table.must_be_nil
|
597
|
-
end
|
598
|
-
|
599
|
-
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
600
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
601
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
602
|
-
Manager[1].must_equal Ceo.load(:id=>1, :kind=>'Ceo')
|
603
|
-
end
|
604
|
-
|
605
|
-
it "should use a subquery in subclasses" do
|
606
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
607
|
-
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'
|
608
|
-
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'
|
609
|
-
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'
|
610
|
-
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'
|
611
|
-
end
|
612
|
-
|
613
|
-
it "should return rows with the correct class based on the polymorphic_key value" do
|
614
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff]
|
615
|
-
end
|
616
|
-
|
617
|
-
it "should return rows with the correct class based on the polymorphic_key value for subclasses" do
|
618
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}]).all.collect{|x| x.class}.must_equal [Manager, Executive, Ceo]
|
619
|
-
end
|
620
|
-
|
621
|
-
it "should have refresh return all columns in subclass after loading from superclass" do
|
622
|
-
Employee.dataset = Employee.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo'}])
|
623
|
-
Ceo.dataset = Ceo.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2}])
|
624
|
-
a = Employee.first
|
625
|
-
a.class.must_equal Ceo
|
626
|
-
a.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo')
|
627
|
-
a.refresh.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2)
|
628
|
-
@db.sqls.must_equal ["SELECT * FROM employees LIMIT 1",
|
629
|
-
"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"]
|
630
|
-
end
|
631
|
-
|
632
|
-
it "should return rows with the current class if cti_key is nil" do
|
633
|
-
Employee.plugin(:class_table_inheritance, :alias=>:employees)
|
634
|
-
Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee]
|
635
|
-
end
|
636
|
-
|
637
|
-
it "should return rows with the current class if cti_key is nil in subclasses" do
|
638
|
-
Employee.plugin(:class_table_inheritance, :alias=>:employees)
|
639
|
-
Object.send(:remove_const, :Executive)
|
640
|
-
Object.send(:remove_const, :Manager)
|
641
|
-
class ::Manager < Employee; end
|
642
|
-
class ::Executive < Manager; end
|
643
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}]).all.map{|x| x.class}.must_equal [Manager, Manager]
|
644
|
-
end
|
645
|
-
|
646
|
-
it "should handle a model map with integer values" do
|
647
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
648
|
-
Object.send(:remove_const, :Ceo)
|
649
|
-
Object.send(:remove_const, :Executive)
|
650
|
-
Object.send(:remove_const, :Manager)
|
651
|
-
class ::Manager < Employee; end
|
652
|
-
class ::Executive < Manager; end
|
653
|
-
class ::Ceo < Executive; end
|
654
|
-
Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
655
|
-
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo]
|
656
|
-
Manager.dataset = Manager.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
|
657
|
-
Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive, Ceo]
|
658
|
-
end
|
659
|
-
|
660
|
-
it "should fallback to the main class if the given class does not exist" do
|
661
|
-
@ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Blah'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Manager, Employee, Staff]
|
662
|
-
end
|
663
|
-
|
664
|
-
it "should fallback to the main class if the given class does not exist in subclasses" do
|
665
|
-
Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Blah'}]).all.map{|x| x.class}.must_equal [Manager, Executive, Ceo, Manager]
|
666
|
-
end
|
667
|
-
|
668
|
-
it "should sets the model class name for the key when creating new parent class records" do
|
669
|
-
Employee.create
|
670
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
671
|
-
end
|
672
|
-
|
673
|
-
it "should sets the model class name for the key when creating new subclass records" do
|
674
|
-
Ceo.create
|
675
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Ceo')",
|
676
|
-
"INSERT INTO managers (id) VALUES (1)",
|
677
|
-
"INSERT INTO executives (id) VALUES (1)"]
|
678
|
-
end
|
679
|
-
|
680
|
-
it "should sets the model class name for the key when creating new subclass records" do
|
681
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
682
|
-
Object.send(:remove_const, :Ceo)
|
683
|
-
Object.send(:remove_const, :Executive)
|
684
|
-
Object.send(:remove_const, :Manager)
|
685
|
-
class ::Manager < Employee; end
|
686
|
-
class ::Executive < Manager; end
|
687
|
-
class ::Ceo < Executive; end
|
688
|
-
Ceo.create
|
689
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')",
|
690
|
-
"INSERT INTO managers (id) VALUES (1)",
|
691
|
-
"INSERT INTO executives (id) VALUES (1)"]
|
692
|
-
end
|
693
|
-
|
694
|
-
it "should sets the model class name for the key when creating new subclass records" do
|
695
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
696
|
-
Object.send(:remove_const, :Ceo)
|
697
|
-
Object.send(:remove_const, :Executive)
|
698
|
-
Object.send(:remove_const, :Manager)
|
699
|
-
class ::Manager < Employee; end
|
700
|
-
class ::Executive < Employee; end
|
701
|
-
class ::Ceo < Employee; end
|
702
|
-
Ceo.create
|
703
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('3')"]
|
704
|
-
end
|
705
|
-
|
706
|
-
it "should not use a subquery for a class that doesn't join to a separate table" do
|
707
|
-
Employee.plugin(:class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo}, :alias=>:employees)
|
708
|
-
Object.send(:remove_const, :Ceo)
|
709
|
-
class ::Ceo < Employee; end
|
710
|
-
Ceo.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (3))'
|
711
|
-
end
|
712
|
-
|
713
|
-
it "should ignore existing cti_key value when creating new records" do
|
714
|
-
Employee.create(:kind=>'Manager')
|
715
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
716
|
-
end
|
717
|
-
|
718
|
-
it "should ignore existing cti_key value in subclasses" do
|
719
|
-
Manager.create(:kind=>'Executive')
|
720
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
|
721
|
-
"INSERT INTO managers (id) VALUES (1)"]
|
722
|
-
end
|
723
|
-
|
724
|
-
it "should handle validations on the type column field" do
|
725
|
-
o = Employee.new
|
726
|
-
def o.validate
|
727
|
-
errors.add(:kind, 'not present') unless kind
|
728
|
-
end
|
729
|
-
o.valid?.must_equal true
|
730
|
-
end
|
731
|
-
|
732
|
-
it "should set the type column field even when not validating" do
|
733
|
-
Employee.new.save(:validate=>false)
|
734
|
-
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
735
|
-
end
|
736
|
-
|
737
|
-
it "should allow specifying a map of names to tables to override implicit mapping" do
|
738
|
-
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'
|
739
|
-
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'
|
740
|
-
end
|
741
|
-
|
742
|
-
it "should lazily load attributes for columns in subclass tables" do
|
743
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2)
|
744
|
-
m = Manager[1]
|
745
|
-
@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']
|
746
|
-
@db.fetch = {:num_managers=>3}
|
747
|
-
m.must_be_kind_of Ceo
|
748
|
-
m.num_managers.must_equal 3
|
749
|
-
@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']
|
750
|
-
m.values.must_equal(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2, :num_managers=>3)
|
751
|
-
end
|
752
|
-
|
753
|
-
it "should lazily load columns in middle classes correctly when loaded from parent class" do
|
754
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
755
|
-
@db.fetch = [[:num_staff=>2]]
|
756
|
-
e = Employee[1]
|
757
|
-
e.must_be_kind_of(Ceo)
|
758
|
-
@db.sqls.must_equal ["SELECT * FROM employees WHERE (id = 1) LIMIT 1"]
|
759
|
-
e.num_staff.must_equal 2
|
760
|
-
@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"]
|
761
|
-
end
|
762
|
-
|
763
|
-
it "should eagerly load lazily columns in subclasses when loaded from parent class" do
|
764
|
-
Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
|
765
|
-
@db.fetch = [[{:id=>1, :num_staff=>2}], [{:id=>1, :num_managers=>3}]]
|
766
|
-
e = Employee.all.first
|
767
|
-
e.must_be_kind_of(Ceo)
|
768
|
-
@db.sqls.must_equal ["SELECT * FROM employees"]
|
769
|
-
e.num_staff.must_equal 2
|
770
|
-
@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))"]
|
771
|
-
e.num_managers.must_equal 3
|
772
|
-
@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))']
|
773
|
-
end
|
774
|
-
|
775
|
-
it "should include schema for columns for tables for ancestor classes" do
|
776
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
|
777
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
778
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
779
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
780
|
-
end
|
781
|
-
|
782
|
-
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
783
|
-
[Employee, Manager, Executive, Ceo, Staff].each{|c| c.primary_key.must_equal :id}
|
784
|
-
end
|
785
|
-
|
786
|
-
it "should have table_name return the table name of the most specific table" do
|
787
|
-
Employee.table_name.must_equal :employees
|
788
|
-
Manager.table_name.must_equal :employees
|
789
|
-
Executive.table_name.must_equal :employees
|
790
|
-
Ceo.table_name.must_equal :employees
|
791
|
-
Staff.table_name.must_equal :employees
|
792
|
-
end
|
793
|
-
|
794
|
-
it "should delete the correct rows from all tables when deleting" do
|
795
|
-
Ceo.load(:id=>1).delete
|
796
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
797
|
-
end
|
798
|
-
|
799
|
-
it "should not allow deletion of frozen object" do
|
800
|
-
o = Ceo.load(:id=>1)
|
801
|
-
o.freeze
|
802
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
803
|
-
@db.sqls.must_equal []
|
804
|
-
end
|
805
|
-
|
806
|
-
it "should insert the correct rows into all tables when inserting" do
|
807
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
808
|
-
sqls = @db.sqls
|
809
|
-
sqls.length.must_equal 3
|
810
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Ceo)', '(E|Ceo)'\)/)
|
811
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\)/)
|
812
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\)/)
|
813
|
-
end
|
814
|
-
|
815
|
-
it "should insert the correct rows into all tables when inserting when insert_select is supported" do
|
816
|
-
[Executive, Manager, Employee].each do |klass|
|
817
|
-
klass.instance_variable_set(:@cti_instance_dataset, klass.cti_instance_dataset.with_extend do
|
818
|
-
def supports_insert_select?; true; end
|
819
|
-
def insert_select(v)
|
820
|
-
db.run(insert_sql(v) + " RETURNING *")
|
821
|
-
v.merge(:id=>1)
|
822
|
-
end
|
823
|
-
end)
|
824
|
-
end
|
825
|
-
Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
826
|
-
sqls = @db.sqls
|
827
|
-
sqls.length.must_equal 3
|
828
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Ceo)', '(E|Ceo)'\) RETURNING \*/)
|
829
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\) RETURNING \*/)
|
830
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\) RETURNING \*/)
|
831
|
-
end
|
832
|
-
|
833
|
-
it "should insert the correct rows into all tables with a given primary key" do
|
834
|
-
e = Ceo.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
835
|
-
e.id = 2
|
836
|
-
e.save
|
837
|
-
sqls = @db.sqls
|
838
|
-
sqls.length.must_equal 3
|
839
|
-
sqls[0].must_match(/INSERT INTO employees \((name|kind|id), (name|kind|id), (name|kind|id)\) VALUES \(('E'|'Ceo'|2), ('E'|'Ceo'|2), ('E'|'Ceo'|2)\)/)
|
840
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \(2, 2\)/)
|
841
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
842
|
-
end
|
843
|
-
|
844
|
-
it "should update the correct rows in all tables when updating" do
|
845
|
-
Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
846
|
-
@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)"]
|
847
|
-
end
|
848
|
-
|
849
|
-
it "should handle many_to_one relationships correctly" do
|
850
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
851
|
-
Staff.load(:manager_id=>3).manager.must_equal Ceo.load(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
852
|
-
@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']
|
853
|
-
end
|
854
|
-
|
855
|
-
it "should handle one_to_many relationships correctly" do
|
856
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)
|
857
|
-
Ceo.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)]
|
858
|
-
@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)']
|
859
|
-
end
|
860
|
-
end
|
861
|
-
|
862
|
-
describe "class_table_inheritance plugin without sti_key with :alias option" do
|
863
|
-
before do
|
864
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
865
|
-
def @db.supports_schema_parsing?() true end
|
866
|
-
def @db.schema(table, opts={})
|
867
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}]],
|
868
|
-
:managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
|
869
|
-
:executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
|
870
|
-
:staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
|
871
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
872
|
-
end
|
873
|
-
@db.extend_datasets do
|
874
|
-
def columns
|
875
|
-
{[:employees]=>[:id, :name],
|
876
|
-
[:managers]=>[:id, :num_staff],
|
877
|
-
[:executives]=>[:id, :num_managers],
|
878
|
-
[:staff]=>[:id, :manager_id],
|
879
|
-
[:employees, :managers]=>[:id, :name, :num_staff],
|
880
|
-
[:employees, :managers, :executives]=>[:id, :name, :num_staff, :num_managers],
|
881
|
-
[:employees, :staff]=>[:id, :name, :manager_id],
|
882
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
883
|
-
end
|
884
|
-
end
|
885
|
-
class ::Employee < Sequel::Model(@db)
|
886
|
-
def _save_refresh; @values[:id] = 1 end
|
887
|
-
def self.columns
|
888
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
889
|
-
end
|
890
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}, :alias=>:employees
|
891
|
-
end
|
892
|
-
class ::Manager < Employee
|
893
|
-
one_to_many :staff_members, :class=>:Staff
|
894
|
-
end
|
895
|
-
class ::Executive < Manager
|
896
|
-
end
|
897
|
-
class ::Staff < Employee
|
898
|
-
many_to_one :manager
|
899
|
-
end
|
900
|
-
@ds = Employee.dataset
|
901
|
-
@db.sqls
|
902
|
-
end
|
903
|
-
after do
|
904
|
-
Object.send(:remove_const, :Executive)
|
905
|
-
Object.send(:remove_const, :Manager)
|
906
|
-
Object.send(:remove_const, :Staff)
|
907
|
-
Object.send(:remove_const, :Employee)
|
908
|
-
end
|
909
|
-
|
910
|
-
it "should have simple_table = nil for all subclasses" do
|
911
|
-
Manager.simple_table.must_be_nil
|
912
|
-
Executive.simple_table.must_be_nil
|
913
|
-
Staff.simple_table.must_be_nil
|
914
|
-
end
|
915
|
-
|
916
|
-
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
917
|
-
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
918
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>1)
|
919
|
-
Manager[1].must_equal Manager.load(:id=>1)
|
920
|
-
end
|
921
|
-
|
922
|
-
it "should use a joined dataset in subclasses" do
|
923
|
-
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
924
|
-
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 employees'
|
925
|
-
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 employees'
|
926
|
-
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 employees'
|
927
|
-
end
|
928
|
-
|
929
|
-
it "should return rows with the current class if cti_key is nil" do
|
930
|
-
Employee.plugin(:class_table_inheritance)
|
931
|
-
Employee.dataset = Employee.dataset.with_fetch([{}])
|
932
|
-
Employee.first.class.must_equal Employee
|
933
|
-
end
|
934
|
-
|
935
|
-
|
936
|
-
it "should include schema for columns for tables for ancestor classes" do
|
937
|
-
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string})
|
938
|
-
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
939
|
-
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
940
|
-
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
941
|
-
end
|
942
|
-
|
943
|
-
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
944
|
-
[Employee, Manager, Executive, Staff].each{|c| c.primary_key.must_equal :id}
|
945
|
-
end
|
946
|
-
|
947
|
-
it "should have table_name return the table name of the most specific table" do
|
948
|
-
Employee.table_name.must_equal :employees
|
949
|
-
Manager.table_name.must_equal :employees
|
950
|
-
Executive.table_name.must_equal :employees
|
951
|
-
Staff.table_name.must_equal :employees
|
952
|
-
end
|
953
|
-
|
954
|
-
it "should delete the correct rows from all tables when deleting" do
|
955
|
-
Executive.load(:id=>1).delete
|
956
|
-
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
957
|
-
end
|
958
|
-
|
959
|
-
it "should not allow deletion of frozen object" do
|
960
|
-
o = Executive.load(:id=>1)
|
961
|
-
o.freeze
|
962
|
-
proc{o.delete}.must_raise(Sequel::Error)
|
963
|
-
@db.sqls.must_equal []
|
964
|
-
end
|
965
|
-
|
966
|
-
it "should insert the correct rows into all tables when inserting" do
|
967
|
-
Executive.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
968
|
-
sqls = @db.sqls
|
969
|
-
sqls.length.must_equal 3
|
970
|
-
sqls[0].must_match(/INSERT INTO employees \(name\) VALUES \('E'\)/)
|
971
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\)/)
|
972
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\)/)
|
973
|
-
end
|
974
|
-
|
975
|
-
it "should insert the correct rows into all tables with a given primary key" do
|
976
|
-
e = Executive.new(:num_managers=>3, :num_staff=>2, :name=>'E')
|
977
|
-
e.id = 2
|
978
|
-
e.save
|
979
|
-
sqls = @db.sqls
|
980
|
-
sqls.length.must_equal 3
|
981
|
-
sqls[0].must_match(/INSERT INTO employees \((name|id), (name|id)\) VALUES \(('E'|2), ('E'|2)\)/)
|
982
|
-
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \(2, 2\)/)
|
983
|
-
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
984
|
-
end
|
985
|
-
|
986
|
-
it "should update the correct rows in all tables when updating" do
|
987
|
-
Executive.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
988
|
-
@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)"]
|
989
|
-
end
|
990
|
-
|
991
|
-
it "should handle many_to_one relationships correctly" do
|
992
|
-
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :num_staff=>3)
|
993
|
-
Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E', :num_staff=>3)
|
994
|
-
@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 employees WHERE (id = 3) LIMIT 1']
|
995
|
-
end
|
996
|
-
|
997
|
-
it "should handle one_to_many relationships correctly" do
|
998
|
-
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
|
999
|
-
Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
|
1000
|
-
@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 employees WHERE (employees.manager_id = 3)']
|
1001
|
-
end
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
describe "class_table_inheritance plugin with duplicate columns with :alias option" do
|
1005
|
-
before do
|
1006
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
1007
|
-
def @db.supports_schema_parsing?() true end
|
1008
|
-
def @db.schema(table, opts={})
|
1009
|
-
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
1010
|
-
:managers=>[[:id, {:type=>:integer}], [:name, {:type=>:string}]],
|
1011
|
-
}[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
|
1012
|
-
end
|
1013
|
-
@db.extend_datasets do
|
1014
|
-
def columns
|
1015
|
-
{[:employees]=>[:id, :name, :kind],
|
1016
|
-
[:managers]=>[:id, :name],
|
1017
|
-
}[opts[:from] + (opts[:join] || []).map{|x| x.table}]
|
1018
|
-
end
|
1019
|
-
end
|
1020
|
-
class ::Employee < Sequel::Model(@db)
|
1021
|
-
def _save_refresh; @values[:id] = 1 end
|
1022
|
-
def self.columns
|
1023
|
-
dataset.columns || dataset.opts[:from].first.expression.columns
|
1024
|
-
end
|
1025
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}, :alias=>:employees
|
1026
|
-
end
|
1027
|
-
deprecated do
|
1028
|
-
class ::Manager < Employee; end
|
1029
|
-
end
|
1030
|
-
@ds = Employee.dataset
|
1031
|
-
@db.sqls
|
1032
|
-
end
|
1033
|
-
after do
|
1034
|
-
Object.send(:remove_const, :Manager)
|
1035
|
-
Object.send(:remove_const, :Employee)
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
it "should select names from both tables" do
|
1039
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.name FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
|
1040
|
-
end
|
1041
|
-
end
|
1042
|
-
|
1043
|
-
describe "class_table_inheritance plugin with :alias option" do
|
1044
|
-
before do
|
1045
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
5
|
+
@db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
|
1046
6
|
def @db.supports_schema_parsing?() true end
|
1047
7
|
def @db.schema(table, opts={})
|
1048
8
|
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
|
@@ -1068,7 +28,7 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1068
28
|
def self.columns
|
1069
29
|
dataset.columns || dataset.opts[:from].first.expression.columns
|
1070
30
|
end
|
1071
|
-
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
31
|
+
plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
|
1072
32
|
end
|
1073
33
|
class ::Manager < Employee
|
1074
34
|
one_to_many :staff_members, :class=>:Staff
|
@@ -1100,27 +60,18 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1100
60
|
|
1101
61
|
it "should not attempt to use prepared statements" do
|
1102
62
|
Manager.plugin :prepared_statements
|
1103
|
-
Manager[1]
|
1104
|
-
@db.sqls.must_equal ["SELECT id, name, kind, 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 (id = 1) LIMIT 1"]
|
1105
63
|
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
|
1106
64
|
@db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
|
1107
|
-
@db.fetch = {:id=>1, :kind=>'Manager', :num_staff=>2}
|
1108
|
-
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).refresh
|
1109
|
-
@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"]
|
1110
|
-
end
|
1111
65
|
|
1112
|
-
|
1113
|
-
|
66
|
+
Employee.plugin :prepared_statements
|
67
|
+
Employee.load(:id=>2, :kind=>'Employee').save
|
68
|
+
@db.sqls.must_equal ["UPDATE employees SET kind = 'Employee' WHERE (id = 2)"]
|
1114
69
|
end
|
1115
70
|
|
1116
71
|
it "#cti_models.first should be the model that loaded the plugin" do
|
1117
72
|
Executive.cti_models.first.must_equal Employee
|
1118
73
|
end
|
1119
74
|
|
1120
|
-
deprecated "#cti_columns should be a mapping of table names to columns" do
|
1121
|
-
Executive.cti_columns.must_equal(:employees=>[:id, :name, :kind], :managers=>[:id, :num_staff], :executives=>[:id, :num_managers])
|
1122
|
-
end
|
1123
|
-
|
1124
75
|
it "should have simple_table = nil for all subclasses" do
|
1125
76
|
Manager.simple_table.must_be_nil
|
1126
77
|
Executive.simple_table.must_be_nil
|
@@ -1163,13 +114,13 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1163
114
|
"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"]
|
1164
115
|
end
|
1165
116
|
|
1166
|
-
it "should return rows with the current class if
|
1167
|
-
Employee.plugin
|
117
|
+
it "should return rows with the current class if sti_key is nil" do
|
118
|
+
Employee.plugin :class_table_inheritance
|
1168
119
|
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]
|
1169
120
|
end
|
1170
121
|
|
1171
|
-
it "should return rows with the current class if
|
1172
|
-
Employee.plugin
|
122
|
+
it "should return rows with the current class if sti_key is nil in subclasses" do
|
123
|
+
Employee.plugin :class_table_inheritance
|
1173
124
|
Object.send(:remove_const, :Executive)
|
1174
125
|
Object.send(:remove_const, :Manager)
|
1175
126
|
class ::Manager < Employee; end
|
@@ -1178,7 +129,7 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1178
129
|
end
|
1179
130
|
|
1180
131
|
it "should handle a model map with integer values" do
|
1181
|
-
Employee.plugin
|
132
|
+
Employee.plugin :class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo, 4=>:Intern}
|
1182
133
|
Object.send(:remove_const, :Intern)
|
1183
134
|
Object.send(:remove_const, :Ceo)
|
1184
135
|
Object.send(:remove_const, :Executive)
|
@@ -1218,12 +169,12 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1218
169
|
"INSERT INTO executives (id) VALUES (1)"]
|
1219
170
|
end
|
1220
171
|
|
1221
|
-
it "should ignore existing
|
172
|
+
it "should ignore existing sti_key value when creating new records" do
|
1222
173
|
Employee.create(:kind=>'Manager')
|
1223
174
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
1224
175
|
end
|
1225
176
|
|
1226
|
-
it "should ignore existing
|
177
|
+
it "should ignore existing sti_key value in subclasses" do
|
1227
178
|
Manager.create(:kind=>'Executive')
|
1228
179
|
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
|
1229
180
|
"INSERT INTO managers (id) VALUES (1)"]
|
@@ -1388,6 +339,12 @@ describe "class_table_inheritance plugin with :alias option" do
|
|
1388
339
|
@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)"]
|
1389
340
|
end
|
1390
341
|
|
342
|
+
it "should raise error if one of the updates does not update a single row" do
|
343
|
+
@db.numrows = [1, 0]
|
344
|
+
proc{Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')}.must_raise Sequel::NoExistingObject
|
345
|
+
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)"]
|
346
|
+
end
|
347
|
+
|
1391
348
|
it "should handle many_to_one relationships correctly" do
|
1392
349
|
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
1393
350
|
Staff.load(:manager_id=>3).manager.must_equal Ceo.load(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
|
@@ -1403,7 +360,7 @@ end
|
|
1403
360
|
|
1404
361
|
describe "class_table_inheritance plugin without sti_key with :alias option" do
|
1405
362
|
before do
|
1406
|
-
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
363
|
+
@db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
|
1407
364
|
def @db.supports_schema_parsing?() true end
|
1408
365
|
def @db.schema(table, opts={})
|
1409
366
|
{:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}]],
|
@@ -1429,7 +386,7 @@ describe "class_table_inheritance plugin without sti_key with :alias option" do
|
|
1429
386
|
def self.columns
|
1430
387
|
dataset.columns || dataset.opts[:from].first.expression.columns
|
1431
388
|
end
|
1432
|
-
plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}, :alias=>:
|
389
|
+
plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}, :alias=>:emps
|
1433
390
|
end
|
1434
391
|
class ::Manager < Employee
|
1435
392
|
one_to_many :staff_members, :class=>:Staff
|
@@ -1463,18 +420,17 @@ describe "class_table_inheritance plugin without sti_key with :alias option" do
|
|
1463
420
|
|
1464
421
|
it "should use a joined dataset in subclasses" do
|
1465
422
|
Employee.dataset.sql.must_equal 'SELECT * FROM employees'
|
1466
|
-
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
|
1467
|
-
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
|
1468
|
-
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
|
423
|
+
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'
|
424
|
+
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'
|
425
|
+
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'
|
1469
426
|
end
|
1470
427
|
|
1471
|
-
it "should return rows with the current class if
|
428
|
+
it "should return rows with the current class if sti_key is nil" do
|
1472
429
|
Employee.plugin(:class_table_inheritance)
|
1473
430
|
Employee.dataset = Employee.dataset.with_fetch([{}])
|
1474
431
|
Employee.first.class.must_equal Employee
|
1475
432
|
end
|
1476
433
|
|
1477
|
-
|
1478
434
|
it "should include schema for columns for tables for ancestor classes" do
|
1479
435
|
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string})
|
1480
436
|
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
@@ -1488,9 +444,9 @@ describe "class_table_inheritance plugin without sti_key with :alias option" do
|
|
1488
444
|
|
1489
445
|
it "should have table_name return the table name of the most specific table" do
|
1490
446
|
Employee.table_name.must_equal :employees
|
1491
|
-
Manager.table_name.must_equal :
|
1492
|
-
Executive.table_name.must_equal :
|
1493
|
-
Staff.table_name.must_equal :
|
447
|
+
Manager.table_name.must_equal :emps
|
448
|
+
Executive.table_name.must_equal :emps
|
449
|
+
Staff.table_name.must_equal :emps
|
1494
450
|
end
|
1495
451
|
|
1496
452
|
it "should delete the correct rows from all tables when deleting" do
|
@@ -1533,18 +489,18 @@ describe "class_table_inheritance plugin without sti_key with :alias option" do
|
|
1533
489
|
it "should handle many_to_one relationships correctly" do
|
1534
490
|
Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :num_staff=>3)
|
1535
491
|
Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E', :num_staff=>3)
|
1536
|
-
@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
|
492
|
+
@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']
|
1537
493
|
end
|
1538
494
|
|
1539
495
|
it "should handle one_to_many relationships correctly" do
|
1540
496
|
Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
|
1541
497
|
Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
|
1542
|
-
@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
|
498
|
+
@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)']
|
1543
499
|
end
|
1544
500
|
end
|
1545
501
|
|
1546
|
-
describe "class_table_inheritance plugin with duplicate columns
|
1547
|
-
|
502
|
+
describe "class_table_inheritance plugin with duplicate columns" do
|
503
|
+
it "should raise error" do
|
1548
504
|
@db = Sequel.mock(:autoid=>proc{|sql| 1})
|
1549
505
|
def @db.supports_schema_parsing?() true end
|
1550
506
|
def @db.schema(table, opts={})
|
@@ -1564,20 +520,13 @@ describe "class_table_inheritance plugin with duplicate columns with :alias opti
|
|
1564
520
|
def self.columns
|
1565
521
|
dataset.columns || dataset.opts[:from].first.expression.columns
|
1566
522
|
end
|
1567
|
-
plugin :class_table_inheritance
|
523
|
+
plugin :class_table_inheritance
|
1568
524
|
end
|
1569
|
-
|
1570
|
-
class ::Manager < Employee; end
|
1571
|
-
end
|
1572
|
-
@ds = Employee.dataset
|
1573
|
-
@db.sqls
|
525
|
+
proc{class ::Manager < Employee; end}.must_raise Sequel::Error
|
1574
526
|
end
|
1575
527
|
after do
|
1576
528
|
Object.send(:remove_const, :Manager)
|
1577
529
|
Object.send(:remove_const, :Employee)
|
1578
530
|
end
|
1579
|
-
|
1580
|
-
it "should select names from both tables" do
|
1581
|
-
Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.name FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
|
1582
|
-
end
|
1583
531
|
end
|
532
|
+
|