dblift 3.3.4__tar.gz → 3.4.0__tar.gz
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.
- {dblift-3.3.4 → dblift-3.4.0}/PKG-INFO +1 -1
- {dblift-3.3.4 → dblift-3.4.0}/api/client.py +63 -3
- {dblift-3.3.4 → dblift-3.4.0}/cli/_command_handlers.py +10 -1
- {dblift-3.3.4 → dblift-3.4.0}/cli/_config_helpers.py +0 -1
- {dblift-3.3.4 → dblift-3.4.0}/cli/_parser_setup.py +46 -20
- {dblift-3.3.4 → dblift-3.4.0}/cli/db_utils.py +78 -78
- {dblift-3.3.4 → dblift-3.4.0}/cli/extensions.py +0 -1
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/_shared.py +0 -3
- {dblift-3.3.4 → dblift-3.4.0}/cli/main.py +63 -13
- dblift-3.4.0/cli/premium_manifest.py +28 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/database_config.py +3 -7
- {dblift-3.3.4 → dblift-3.4.0}/config/dblift_config.py +4 -51
- {dblift-3.3.4 → dblift-3.4.0}/config/property_registry.py +0 -6
- {dblift-3.3.4 → dblift-3.4.0}/core/constants.py +0 -28
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/index_extractor.py +4 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/__init__.py +7 -21
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_formatters.py +25 -21
- dblift-3.4.0/core/logger/formatters/__init__.py +13 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/_formatter_impl.py +2 -8
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/log.py +2 -7
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/results.py +1 -1
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/clean_summary.py +1 -9
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/base_command.py +9 -1
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/baseline_command.py +1 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/clean_command.py +1 -67
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/import_flyway_command.py +37 -1
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/migrate_command.py +11 -1
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/repair_command.py +12 -9
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/undo_command.py +15 -4
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/execution_engine.py +42 -53
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/migration_executor.py +2 -2
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/base_executor.py +2 -40
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/executor_factory.py +12 -29
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/python_executor.py +47 -70
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/sql_executor.py +0 -40
- dblift-3.4.0/core/migration/formats/format_detector.py +110 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/formats/migration_format.py +0 -20
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/history/migration_history_manager.py +10 -173
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/journals/migration_journal.py +0 -64
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/migration.py +80 -4
- dblift-3.4.0/core/migration/rules/migration_rules.py +140 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/migration_script_manager.py +58 -42
- dblift-3.4.0/core/migration/scripting/undo_script_generator/_helpers.py +36 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/sql_analyzer.py +1 -266
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/sql_execution_service.py +28 -7
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_data_service.py +0 -273
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_display_state.py +0 -6
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state_manager.py +24 -4
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state_service.py +1 -24
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/__init__.py +1 -3
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/data_collector.py +14 -39
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/migration_ui.py +1 -114
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/table_renderer.py +2 -99
- dblift-3.4.0/core/normalization/__init__.py +7 -0
- {dblift-3.3.4/cli → dblift-3.4.0/core}/premium_manifest.py +27 -3
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/__init__.py +0 -2
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/alter_generator_factory.py +0 -10
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/formatter.py +1 -18
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/dialect.py +1 -48
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/index.py +0 -24
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/procedure.py +0 -41
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table_options.py +0 -15
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/base_statement_parser.py +11 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/base_tokenizer.py +53 -25
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_checksum_validator.py +12 -2
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_flyway_compatibility.py +40 -5
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_migration_filter.py +4 -1
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_strict_mode_validator.py +5 -2
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/migration_validator.py +65 -37
- {dblift-3.3.4 → dblift-3.4.0}/db/base_quirks.py +31 -6
- {dblift-3.3.4 → dblift-3.4.0}/db/constants.py +0 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/error.py +24 -165
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_history_manager.py +37 -41
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_query_executor.py +0 -99
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_schema_operations.py +0 -59
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/sqlalchemy_dialect.py +1 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/sqlalchemy_url.py +2 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/history_manager.py +18 -6
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/query_executor.py +0 -20
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/history_manager.py +0 -39
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/schema_operations.py +0 -446
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/db2_regex_parser.py +53 -22
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/parser_config.py +337 -233
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/provider.py +11 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/quirks.py +9 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/duckdb_regex_parser.py +0 -16
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/provider.py +26 -12
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/history_manager.py +0 -128
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/provider.py +3 -2
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/history_manager.py +12 -5
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/schema_operations.py +0 -79
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_parser.py +0 -35
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_tokenizer.py +2 -3
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/provider.py +39 -21
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/quirks.py +10 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/parser_config.py +0 -12
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -20
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/schema_operations.py +59 -4
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/provider.py +48 -3
- dblift-3.4.0/db/plugins/postgresql/search_path.py +51 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/sqlalchemy_url.py +3 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/provider.py +4 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/provider.py +2 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/sqlite_regex_parser.py +1 -100
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/provider.py +32 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +8 -12
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/provider.py +20 -1
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/quirks.py +21 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/history_manager.py +7 -3
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/schema_operations.py +37 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/provider_capabilities.py +5 -6
- {dblift-3.3.4 → dblift-3.4.0}/db/provider_interfaces.py +27 -30
- {dblift-3.3.4 → dblift-3.4.0}/db/provider_registry.py +1 -42
- {dblift-3.3.4 → dblift-3.4.0}/db/sqlalchemy_provider.py +89 -1
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/PKG-INFO +1 -1
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/SOURCES.txt +2 -15
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/_engine.py +1 -7
- {dblift-3.3.4 → dblift-3.4.0}/pyproject.toml +2 -42
- dblift-3.3.4/core/logger/formatters/__init__.py +0 -30
- dblift-3.3.4/core/migration/formats/format_detector.py +0 -204
- dblift-3.3.4/core/migration/rules/migration_rules.py +0 -145
- dblift-3.3.4/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -485
- dblift-3.3.4/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -319
- dblift-3.3.4/core/migration/scripting/undo_script_generator/_helpers.py +0 -555
- dblift-3.3.4/core/migration/state/migration_formatter.py +0 -215
- dblift-3.3.4/core/migration/ui/display_formatters.py +0 -251
- dblift-3.3.4/core/migration/ui/migration_analyzer.py +0 -259
- dblift-3.3.4/core/normalization/__init__.py +0 -35
- dblift-3.3.4/core/normalization/dependency_resolver.py +0 -444
- dblift-3.3.4/core/normalization/identifier_normalizer.py +0 -297
- dblift-3.3.4/core/normalization/object_orderer.py +0 -230
- dblift-3.3.4/core/normalization/type_mapper.py +0 -210
- dblift-3.3.4/core/normalization/type_mappings.py +0 -89
- dblift-3.3.4/core/sql_generator/alter_generator.py +0 -64
- dblift-3.3.4/core/state/sql_script_formatter.py +0 -144
- dblift-3.3.4/db/error_handler.py +0 -349
- dblift-3.3.4/db/plugins/base_undo_manager.py +0 -126
- dblift-3.3.4/db/plugins/oracle/parser/parser_config.py +0 -330
- {dblift-3.3.4 → dblift-3.4.0}/LICENSE +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/README.md +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/_cli_support.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/_client_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/_client_operations.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/_engine_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/async_client.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/events.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/migrations.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/api/py.typed +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/_constants.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/_output.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/commands/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/commands/config_command.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/baseline.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/clean.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/import_flyway.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/info.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/migrate.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/repair.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/undo.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/validate.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/_credential_masking.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/_subclasses/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/_subclasses/dummy_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/_url_builder_mixin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/config_builder.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/errors.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_cache.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_provider_base.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_registry.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_resolver.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_secrets_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/dialect_boundary.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/exceptions.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_column_enricher.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_partition_enricher.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_schema_orchestrator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_utils.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_vendor_property_applier.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/base_introspector.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/base_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/column_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/constraint_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/misc_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/procedure_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/sequence_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/table_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/trigger_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/view_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/introspector_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/result.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/schema_introspector.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_base.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_protocols.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/introspection/version_detector.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_base.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_levels.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_multi.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/_null.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/console.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/formatter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/htmlformatter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/jsonformatter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/templates/oldreport.html +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/logger/templates/report.html +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/_type_match.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/_script_events.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/info_command.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/validate_command.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/encoding.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/migration_helpers.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/placeholder_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/transaction_policy.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/formats/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/history/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/journals/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/placeholders/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/placeholders/placeholder_service.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/rules/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_models.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/execution_statement.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/statement_splitter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/migration/version_utils.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/normalization/type_constants.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/normalization/type_normalizer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/capabilities.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/client_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/event_listeners.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/feature_loading.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/introspection.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/license_info.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/runtime_checks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/sql_generators.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/seams/tier_resolver.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/base_alter_generator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/base_generator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/basic_table_ddl_generator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/dependency_analyzer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/diff_converters/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/diff_converters/base_converter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/generator_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/options.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/script_organizer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/sql_generator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/sql_statement.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/table_ddl_render.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_parse_result.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_column.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_constraint.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_object.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_statement.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/base.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/constraint_validator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/database_link.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/event.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/extension.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/feature_gates.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/foreign_data_wrapper.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/foreign_server.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/linked_server.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/module.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/package.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/partition.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/sequence.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/server_info.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/synonym.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table_canonicalizer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/trigger.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/user_defined_type.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/view.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/view_options.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/_partition_handler.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/_sqlglot_builders.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/common/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/common/base_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/dialects/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/dialects/base_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/enhanced_regex_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/hybrid_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_context.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_factory.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_interface.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/sqlglot_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/tokens.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/unified_regex_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_sql_syntax_validator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/state/sql_statement.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/database_url_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/metadata_helpers.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/row_access.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/string_utils.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/core/utils/url_masking.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/base_provider.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/dml_analysis.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/exceptions.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/feature_gate.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/native_connection_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/object_naming.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/_pg_compatible.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/alloydb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/alloydb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/aurora_postgresql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/aurora_postgresql/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_snapshot_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/citus/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/citus/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/provider.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/provider.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/parser_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/provider.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/schema_operations.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/parser_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/neon/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/neon/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/history.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/introspection.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/locking.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/dbms_output.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_comments.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_object_extractor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_plsql_block.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_sqlplus.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/_provider_query_executor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/parser_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/quirks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/introspection/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/parser_config.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlalchemy_url.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/supabase/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/supabase/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/timescaledb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/timescaledb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/yugabytedb/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/plugins/yugabytedb/plugin.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/db/value_utils.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/dependency_links.txt +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/entry_points.txt +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/requires.txt +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/top_level.txt +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/_client.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/apps.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/checks.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/__init__.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_info.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_migrate.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_validate.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/fastapi.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/flask.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/integrations/opentelemetry.py +0 -0
- {dblift-3.3.4 → dblift-3.4.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dblift
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0
|
|
4
4
|
Summary: A database migration tool that supports multiple databases with native Python drivers
|
|
5
5
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -39,6 +39,8 @@ from core.logger.results import (
|
|
|
39
39
|
ValidateResult,
|
|
40
40
|
)
|
|
41
41
|
from core.migration.executor.migration_executor import MigrationExecutor
|
|
42
|
+
from core.premium_manifest import PREMIUM_COMMANDS, UPGRADE_URL, render_upsell
|
|
43
|
+
from core.seams.capabilities import CapabilityDeniedError
|
|
42
44
|
from core.seams.event_listeners import attach_registered_listeners
|
|
43
45
|
from core.seams.feature_loading import load_feature_extensions
|
|
44
46
|
from db.base_provider import BaseProvider
|
|
@@ -48,6 +50,42 @@ __all__ = ["DBLiftClient"]
|
|
|
48
50
|
|
|
49
51
|
_F = TypeVar("_F", bound=Callable[..., Any])
|
|
50
52
|
|
|
53
|
+
# Paid-tier commands that have a corresponding OSS-visible DBLiftClient
|
|
54
|
+
# method name (issue #753). Keyed by ``api_method`` so
|
|
55
|
+
# ``_make_premium_stub_method`` can look up the right upsell text per stub.
|
|
56
|
+
_PREMIUM_COMMANDS_BY_API_METHOD = {
|
|
57
|
+
cmd.api_method: cmd for cmd in PREMIUM_COMMANDS if cmd.api_method is not None
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _make_premium_stub_method(api_method_name: str) -> Callable[..., Any]:
|
|
62
|
+
"""Build a paid-tier stub method for the OSS ``DBLiftClient``.
|
|
63
|
+
|
|
64
|
+
Mirrors the CLI's ``_make_premium_stub_handler``
|
|
65
|
+
(``cli/_command_handlers.py``): rather than the method being entirely
|
|
66
|
+
absent (a bare ``AttributeError`` on call), it exists, accepts
|
|
67
|
+
whatever arguments a paid caller would pass, and raises
|
|
68
|
+
``CapabilityDeniedError`` with the same upsell message the CLI shows
|
|
69
|
+
for the equivalent command. Not decorated with ``@_with_client_emitter``
|
|
70
|
+
— it never runs an operation, so there is nothing to bind an emitter
|
|
71
|
+
around (see ``EXPECTED_DECORATED_OPERATIONS`` in
|
|
72
|
+
``tests/unit/api/test_public_api_surface.py``).
|
|
73
|
+
"""
|
|
74
|
+
cmd = _PREMIUM_COMMANDS_BY_API_METHOD[api_method_name]
|
|
75
|
+
|
|
76
|
+
def _stub(self: "DBLiftClient", *args: Any, **kwargs: Any) -> Any:
|
|
77
|
+
raise CapabilityDeniedError(render_upsell(cmd))
|
|
78
|
+
|
|
79
|
+
_stub.__name__ = api_method_name
|
|
80
|
+
_stub.__doc__ = (
|
|
81
|
+
f"Paid-tier stub: '{cmd.name}' is a dblift {cmd.edition} command, "
|
|
82
|
+
f"not available in the open-source edition.\n\n"
|
|
83
|
+
f"Raises:\n"
|
|
84
|
+
f" CapabilityDeniedError: always, with an upgrade message. "
|
|
85
|
+
f"See {UPGRADE_URL}."
|
|
86
|
+
)
|
|
87
|
+
return _stub
|
|
88
|
+
|
|
51
89
|
|
|
52
90
|
def _with_client_emitter(method: _F) -> _F:
|
|
53
91
|
"""Bind ``self.events`` as the active emitter for the duration of *method*.
|
|
@@ -259,6 +297,7 @@ class DBLiftClient:
|
|
|
259
297
|
"dry_run": dry_run,
|
|
260
298
|
"show_sql": show_sql,
|
|
261
299
|
"tags": tags,
|
|
300
|
+
"dialect": getattr(self, "dialect", None),
|
|
262
301
|
},
|
|
263
302
|
)
|
|
264
303
|
|
|
@@ -294,6 +333,7 @@ class DBLiftClient:
|
|
|
294
333
|
"provider": self.provider,
|
|
295
334
|
"history_manager": self.executor.history_manager,
|
|
296
335
|
"log": self.logger,
|
|
336
|
+
"dialect": getattr(self, "dialect", None),
|
|
297
337
|
},
|
|
298
338
|
)
|
|
299
339
|
else:
|
|
@@ -302,6 +342,7 @@ class DBLiftClient:
|
|
|
302
342
|
{
|
|
303
343
|
"error": getattr(result, "error_message", None),
|
|
304
344
|
"target_version": target_version,
|
|
345
|
+
"dialect": getattr(self, "dialect", None),
|
|
305
346
|
},
|
|
306
347
|
)
|
|
307
348
|
|
|
@@ -312,6 +353,7 @@ class DBLiftClient:
|
|
|
312
353
|
{
|
|
313
354
|
"error": str(e),
|
|
314
355
|
"target_version": target_version,
|
|
356
|
+
"dialect": getattr(self, "dialect", None),
|
|
315
357
|
},
|
|
316
358
|
)
|
|
317
359
|
raise
|
|
@@ -406,7 +448,7 @@ class DBLiftClient:
|
|
|
406
448
|
ValidateResult with validation status
|
|
407
449
|
"""
|
|
408
450
|
self._guard_scripts_dir_kwarg(kwargs)
|
|
409
|
-
self.events.emit(EventType.VALIDATION_STARTED, {})
|
|
451
|
+
self.events.emit(EventType.VALIDATION_STARTED, {"dialect": getattr(self, "dialect", None)})
|
|
410
452
|
|
|
411
453
|
try:
|
|
412
454
|
result = self.executor.validate(
|
|
@@ -421,11 +463,17 @@ class DBLiftClient:
|
|
|
421
463
|
**kwargs,
|
|
422
464
|
)
|
|
423
465
|
|
|
424
|
-
self.events.emit(
|
|
466
|
+
self.events.emit(
|
|
467
|
+
EventType.VALIDATION_COMPLETED,
|
|
468
|
+
{"result": result, "dialect": getattr(self, "dialect", None)},
|
|
469
|
+
)
|
|
425
470
|
|
|
426
471
|
return result
|
|
427
472
|
except Exception as e:
|
|
428
|
-
self.events.emit(
|
|
473
|
+
self.events.emit(
|
|
474
|
+
EventType.VALIDATION_FAILED,
|
|
475
|
+
{"error": str(e), "dialect": getattr(self, "dialect", None)},
|
|
476
|
+
)
|
|
429
477
|
raise
|
|
430
478
|
|
|
431
479
|
@_with_client_emitter
|
|
@@ -823,6 +871,18 @@ class DBLiftClient:
|
|
|
823
871
|
)
|
|
824
872
|
raise
|
|
825
873
|
|
|
874
|
+
# Paid-tier stubs (issue #753): visible on the OSS class so
|
|
875
|
+
# ``hasattr``/``dir()`` finds them, mirroring the CLI's premium command
|
|
876
|
+
# stubs. Calling any of these raises ``CapabilityDeniedError`` with an
|
|
877
|
+
# upsell message instead of a bare ``AttributeError``. Deliberately not
|
|
878
|
+
# decorated with ``@_with_client_emitter`` — see
|
|
879
|
+
# ``_make_premium_stub_method`` above.
|
|
880
|
+
diff = _make_premium_stub_method("diff")
|
|
881
|
+
export_schema = _make_premium_stub_method("export_schema")
|
|
882
|
+
snapshot = _make_premium_stub_method("snapshot")
|
|
883
|
+
plan = _make_premium_stub_method("plan")
|
|
884
|
+
preflight = _make_premium_stub_method("preflight")
|
|
885
|
+
|
|
826
886
|
@classmethod
|
|
827
887
|
def from_config(
|
|
828
888
|
cls,
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
7
7
|
|
|
8
|
+
from cli._constants import EXIT_LICENSE_REQUIRED
|
|
8
9
|
from cli.extensions import load_command_handlers, load_terminal_commands
|
|
9
10
|
from cli.handlers._shared import ( # noqa: F401
|
|
10
11
|
_MIGRATION_FILENAME_RE,
|
|
@@ -23,6 +24,7 @@ from cli.handlers.repair import _handle_repair
|
|
|
23
24
|
from cli.handlers.undo import _handle_undo
|
|
24
25
|
from cli.handlers.validate import _handle_validate
|
|
25
26
|
from cli.premium_manifest import PremiumCommand, premium_stub_index, render_upsell
|
|
27
|
+
from core.seams.capabilities import CapabilityDeniedError
|
|
26
28
|
from core.seams.tier_resolver import resolve_tier
|
|
27
29
|
|
|
28
30
|
_COMMAND_HANDLERS: Dict[str, Callable[[CliCommandContext], Tuple[bool, Any]]] = {
|
|
@@ -104,7 +106,14 @@ def execute_single_command(
|
|
|
104
106
|
# pure-OSS install no resolver is registered and this is ``None``.
|
|
105
107
|
license_tier=resolve_tier(args),
|
|
106
108
|
)
|
|
107
|
-
|
|
109
|
+
try:
|
|
110
|
+
return handler(ctx)
|
|
111
|
+
except CapabilityDeniedError as e:
|
|
112
|
+
# Capability rejections map to the same exit code as premium stubs so
|
|
113
|
+
# scripts/CI can branch on entitlement without parsing stderr.
|
|
114
|
+
message = str(e).strip() or "This command requires a license that is not available."
|
|
115
|
+
log.error(message)
|
|
116
|
+
raise SystemExit(EXIT_LICENSE_REQUIRED) from e
|
|
108
117
|
|
|
109
118
|
|
|
110
119
|
def _validate_migrate_options(cmd_args: Any, parser: Any) -> None:
|
|
@@ -252,10 +252,6 @@ def _add_diff_and_target_options(
|
|
|
252
252
|
migrate_parser.add_argument("--target-version", help="Target version to migrate to")
|
|
253
253
|
undo_parser.add_argument("--target-version", help="Target version to roll back to")
|
|
254
254
|
validate_parser.add_argument("--target-version", help="Validate migrations up to this version")
|
|
255
|
-
# Validate specific options
|
|
256
|
-
validate_parser.add_argument(
|
|
257
|
-
"--skip-validation", action="store_true", help="Skip validation checks"
|
|
258
|
-
)
|
|
259
255
|
# Migrate specific options
|
|
260
256
|
migrate_parser.add_argument(
|
|
261
257
|
"--validate-only",
|
|
@@ -340,21 +336,51 @@ def create_parser(
|
|
|
340
336
|
exit_on_error: bool = True, suppress_errors: bool = False
|
|
341
337
|
) -> argparse.ArgumentParser:
|
|
342
338
|
"""Create and configure the argument parser for DBLift CLI."""
|
|
339
|
+
# Shared parent for the 4 db-connection flags. It is attached both to the
|
|
340
|
+
# root parser (so `dblift --db-url ... migrate` keeps working) and to the
|
|
341
|
+
# migrate/info/validate/undo subparsers (so the flags are documented in
|
|
342
|
+
# their --help output, not just the root's). ``default=argparse.SUPPRESS``
|
|
343
|
+
# is required for that dual attachment: argparse's subparser dispatch
|
|
344
|
+
# (``_SubParsersAction.__call__``) always parses the subcommand's
|
|
345
|
+
# remaining args into a *fresh* namespace and then copies every one of its
|
|
346
|
+
# dests onto the outer namespace — so a subparser-local default of ``None``
|
|
347
|
+
# would silently overwrite a value already parsed at the root level
|
|
348
|
+
# (e.g. `dblift --db-url X migrate` with no --db-url after "migrate").
|
|
349
|
+
# SUPPRESS keeps the dest off the subnamespace entirely when the flag
|
|
350
|
+
# isn't repeated after the subcommand, so the root-parsed value survives.
|
|
351
|
+
#
|
|
352
|
+
# Side effect: because this same parent is used on the root parser too,
|
|
353
|
+
# ``database_url``/``database_username``/``database_password``/
|
|
354
|
+
# ``database_schema`` may be entirely ABSENT from ``args`` (not merely
|
|
355
|
+
# ``None``) for ANY subcommand — not just migrate/info/validate/undo —
|
|
356
|
+
# whenever the flag isn't passed anywhere on the command line. Any new
|
|
357
|
+
# code reading these must use ``hasattr``/``getattr(..., None)`` (as
|
|
358
|
+
# ``cli/_config_helpers.py`` already does); a bare ``args.database_url``
|
|
359
|
+
# will raise ``AttributeError`` when unset. See
|
|
360
|
+
# tests/unit/cli/test_parser_invariants.py::
|
|
361
|
+
# test_db_flags_absent_from_namespace_when_unset_for_non_db_subcommand.
|
|
343
362
|
db_parent = argparse.ArgumentParser(add_help=False)
|
|
344
|
-
db_parent.add_argument(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
db_parent.add_argument(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
363
|
+
db_parent.add_argument(
|
|
364
|
+
"--db-url", dest="database_url", default=argparse.SUPPRESS, help="Database URL"
|
|
365
|
+
)
|
|
366
|
+
db_parent.add_argument(
|
|
367
|
+
"--db-username",
|
|
368
|
+
dest="database_username",
|
|
369
|
+
default=argparse.SUPPRESS,
|
|
370
|
+
help="Database username",
|
|
371
|
+
)
|
|
372
|
+
db_parent.add_argument(
|
|
373
|
+
"--db-password",
|
|
374
|
+
dest="database_password",
|
|
375
|
+
default=argparse.SUPPRESS,
|
|
376
|
+
help="Database password",
|
|
377
|
+
)
|
|
378
|
+
db_parent.add_argument(
|
|
379
|
+
"--db-schema", dest="database_schema", default=argparse.SUPPRESS, help="Database schema"
|
|
380
|
+
)
|
|
355
381
|
parser_kwargs: Dict[str, Any] = {
|
|
356
382
|
"description": "dblift: Database migration tool",
|
|
357
|
-
"parents": [
|
|
383
|
+
"parents": [db_parent],
|
|
358
384
|
}
|
|
359
385
|
if not exit_on_error:
|
|
360
386
|
parser_kwargs["exit_on_error"] = False
|
|
@@ -454,22 +480,22 @@ def create_parser(
|
|
|
454
480
|
migrate_parser = subparsers.add_parser(
|
|
455
481
|
"migrate",
|
|
456
482
|
help="Apply migrations",
|
|
457
|
-
parents=[_history, _strict, _filter],
|
|
483
|
+
parents=[_history, _strict, _filter, db_parent],
|
|
458
484
|
)
|
|
459
485
|
info_parser = subparsers.add_parser(
|
|
460
486
|
"info",
|
|
461
487
|
help="Show migration information",
|
|
462
|
-
parents=[_history, _strict, _filter],
|
|
488
|
+
parents=[_history, _strict, _filter, db_parent],
|
|
463
489
|
)
|
|
464
490
|
validate_parser = subparsers.add_parser(
|
|
465
491
|
"validate",
|
|
466
492
|
help="Validate migration scripts",
|
|
467
|
-
parents=[_history, _strict, _filter],
|
|
493
|
+
parents=[_history, _strict, _filter, db_parent],
|
|
468
494
|
)
|
|
469
495
|
undo_parser = subparsers.add_parser(
|
|
470
496
|
"undo",
|
|
471
497
|
help="Rollback migrations",
|
|
472
|
-
parents=[_history, _strict, _filter],
|
|
498
|
+
parents=[_history, _strict, _filter, db_parent],
|
|
473
499
|
)
|
|
474
500
|
clean_parser = subparsers.add_parser(
|
|
475
501
|
"clean",
|
|
@@ -259,96 +259,96 @@ def check_connection(args: argparse.Namespace) -> int:
|
|
|
259
259
|
logger = DbliftLogger(
|
|
260
260
|
logfile_dir=log_dir, format=_log_format, log_file_pattern=_log_file_pattern
|
|
261
261
|
)
|
|
262
|
-
|
|
263
|
-
# Create config from arguments
|
|
264
262
|
try:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
config.database
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
_url_optional_for_path = _quirks.url_optional_when_file_path_given
|
|
276
|
-
_has_connection_identifier = _quirks.has_connection_identifier(config.database)
|
|
277
|
-
_has_endpoint = getattr(config.database, "account_endpoint", None)
|
|
278
|
-
if (
|
|
279
|
-
not config.database.url
|
|
280
|
-
and not (_url_optional_for_path and _has_path)
|
|
281
|
-
and not _has_endpoint
|
|
282
|
-
and (not config.database.type or not _has_connection_identifier)
|
|
283
|
-
):
|
|
284
|
-
error_message = (
|
|
285
|
-
"Missing required connection parameters. Either provide --db-url or --config."
|
|
263
|
+
# Create config from arguments
|
|
264
|
+
try:
|
|
265
|
+
config = load_config(getattr(args, "config", None), args)
|
|
266
|
+
|
|
267
|
+
# Check if we have enough information to connect.
|
|
268
|
+
# SQLite can use a file path, not a server/URL.
|
|
269
|
+
# CosmosDB uses account_endpoint, not url/server.
|
|
270
|
+
_db_type_lower = (config.database.type or "").lower()
|
|
271
|
+
_has_path = getattr(config.database, "path", None) or getattr(
|
|
272
|
+
config.database, "database", None
|
|
286
273
|
)
|
|
274
|
+
_quirks = ProviderRegistry.get_quirks(_db_type_lower)
|
|
275
|
+
_url_optional_for_path = _quirks.url_optional_when_file_path_given
|
|
276
|
+
_has_connection_identifier = _quirks.has_connection_identifier(config.database)
|
|
277
|
+
_has_endpoint = getattr(config.database, "account_endpoint", None)
|
|
278
|
+
if (
|
|
279
|
+
not config.database.url
|
|
280
|
+
and not (_url_optional_for_path and _has_path)
|
|
281
|
+
and not _has_endpoint
|
|
282
|
+
and (not config.database.type or not _has_connection_identifier)
|
|
283
|
+
):
|
|
284
|
+
error_message = "Missing required connection parameters. Either provide --db-url or --config."
|
|
285
|
+
out.error(error_message)
|
|
286
|
+
results["error"] = error_message
|
|
287
|
+
print_connection_results(results, out)
|
|
288
|
+
return 1
|
|
289
|
+
|
|
290
|
+
results["connection_info"]["config_source"] = "Created from provided parameters"
|
|
291
|
+
except Exception as e:
|
|
292
|
+
out.error(f"Error creating configuration: {str(e)}")
|
|
293
|
+
results["error"] = str(e)
|
|
294
|
+
print_connection_results(results, out)
|
|
295
|
+
return 1
|
|
296
|
+
|
|
297
|
+
# Validate database type
|
|
298
|
+
if not config.database.type:
|
|
299
|
+
error_message = "Missing database type. Please provide --db-type or a configuration with database type."
|
|
287
300
|
out.error(error_message)
|
|
288
301
|
results["error"] = error_message
|
|
289
302
|
print_connection_results(results, out)
|
|
290
303
|
return 1
|
|
291
304
|
|
|
292
|
-
|
|
293
|
-
except Exception as e:
|
|
294
|
-
out.error(f"Error creating configuration: {str(e)}")
|
|
295
|
-
results["error"] = str(e)
|
|
296
|
-
print_connection_results(results, out)
|
|
297
|
-
return 1
|
|
305
|
+
db_type = config.database.type.lower()
|
|
298
306
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
db_type = config.database.type.lower()
|
|
307
|
+
# Create database provider via registry (DIP — no concrete plugin imports)
|
|
308
|
+
try:
|
|
309
|
+
provider: Any = ProviderRegistry.create_provider(config, logger)
|
|
310
|
+
except ValueError as e:
|
|
311
|
+
results["error"] = str(e)
|
|
312
|
+
print_connection_results(results, out)
|
|
313
|
+
return 1
|
|
308
314
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
315
|
+
# Test connection. Format known driver errors as a one-line message so the CLI doesn't
|
|
316
|
+
# dump a Python traceback to stderr on e.g. connection refused / auth failure.
|
|
317
|
+
try:
|
|
318
|
+
provider.create_connection()
|
|
319
|
+
except Exception as connection_error:
|
|
320
|
+
friendly = _format_connection_error(connection_error, db_type)
|
|
321
|
+
out.error(friendly)
|
|
322
|
+
results["error"] = friendly
|
|
323
|
+
print_connection_results(results, out)
|
|
324
|
+
if getattr(args, "log_level", "info") == "debug":
|
|
325
|
+
traceback.print_exc()
|
|
326
|
+
return 1
|
|
316
327
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
328
|
+
try:
|
|
329
|
+
# Get database version and URL before updating results
|
|
330
|
+
version = provider.get_database_version()
|
|
331
|
+
database_url = get_provider_display_url(provider, config) or config.database.url
|
|
332
|
+
|
|
333
|
+
# Update results atomically once all operations succeed
|
|
334
|
+
results["success"] = True
|
|
335
|
+
results["connection_info"]["database_url"] = (
|
|
336
|
+
mask_database_url(database_url) if database_url else database_url
|
|
337
|
+
)
|
|
338
|
+
results["connection_info"]["db_type"] = db_type
|
|
339
|
+
schema = getattr(config.database, "schema", None)
|
|
340
|
+
if schema:
|
|
341
|
+
results["connection_info"]["schema"] = schema
|
|
342
|
+
results["database_info"]["version"] = version
|
|
343
|
+
finally:
|
|
344
|
+
# Close connection even if get_database_version/display URL lookup raises
|
|
345
|
+
provider.close()
|
|
346
|
+
|
|
347
|
+
# Print results in requested format
|
|
325
348
|
print_connection_results(results, out)
|
|
326
|
-
|
|
327
|
-
traceback.print_exc()
|
|
328
|
-
return 1
|
|
329
|
-
|
|
330
|
-
try:
|
|
331
|
-
# Get database version and URL before updating results
|
|
332
|
-
version = provider.get_database_version()
|
|
333
|
-
database_url = get_provider_display_url(provider, config) or config.database.url
|
|
334
|
-
|
|
335
|
-
# Update results atomically once all operations succeed
|
|
336
|
-
results["success"] = True
|
|
337
|
-
results["connection_info"]["database_url"] = (
|
|
338
|
-
mask_database_url(database_url) if database_url else database_url
|
|
339
|
-
)
|
|
340
|
-
results["connection_info"]["db_type"] = db_type
|
|
341
|
-
schema = getattr(config.database, "schema", None)
|
|
342
|
-
if schema:
|
|
343
|
-
results["connection_info"]["schema"] = schema
|
|
344
|
-
results["database_info"]["version"] = version
|
|
349
|
+
return 0
|
|
345
350
|
finally:
|
|
346
|
-
|
|
347
|
-
provider.close()
|
|
348
|
-
|
|
349
|
-
# Print results in requested format
|
|
350
|
-
print_connection_results(results, out)
|
|
351
|
-
return 0
|
|
351
|
+
logger.close()
|
|
352
352
|
|
|
353
353
|
except Exception as e:
|
|
354
354
|
out.error(f"Error testing connection: {str(e)}")
|
|
@@ -8,7 +8,6 @@ from typing import Any, Callable, Dict
|
|
|
8
8
|
COMMAND_ENTRY_POINT_GROUP = "dblift.commands"
|
|
9
9
|
HANDLER_ENTRY_POINT_GROUP = "dblift.command_handlers"
|
|
10
10
|
TERMINAL_ENTRY_POINT_GROUP = "dblift.terminal_commands"
|
|
11
|
-
CommandExtension = Callable[[ArgumentParser], None]
|
|
12
11
|
CommandHandler = Callable[[Any], tuple[bool, Any]]
|
|
13
12
|
TerminalCommand = Callable[[Any], int]
|
|
14
13
|
|
|
@@ -73,9 +73,6 @@ class ConfigOnlyClient:
|
|
|
73
73
|
config: Any
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
ValidateSqlConfigClient = ConfigOnlyClient
|
|
77
|
-
|
|
78
|
-
|
|
79
76
|
def _set_command_completed(log: Any, result: Any, command_type: str) -> None:
|
|
80
77
|
"""Helper to report command completion to the logger (eliminates SMELL-04 duplication)."""
|
|
81
78
|
if result is None:
|
|
@@ -25,16 +25,6 @@ from cli._command_handlers import ( # noqa: F401
|
|
|
25
25
|
PREMIUM_STUB_COMMANDS,
|
|
26
26
|
CliCommandContext,
|
|
27
27
|
_extract_version_filters,
|
|
28
|
-
_handle_baseline,
|
|
29
|
-
_handle_clean,
|
|
30
|
-
_handle_import_flyway,
|
|
31
|
-
_handle_info,
|
|
32
|
-
_handle_migrate,
|
|
33
|
-
_handle_repair,
|
|
34
|
-
_handle_undo,
|
|
35
|
-
_handle_validate,
|
|
36
|
-
_minimal_result,
|
|
37
|
-
_set_command_completed,
|
|
38
28
|
_validate_migrate_options,
|
|
39
29
|
execute_single_command,
|
|
40
30
|
)
|
|
@@ -195,6 +185,41 @@ class _CliContext:
|
|
|
195
185
|
license_info: Optional[Any] = None
|
|
196
186
|
|
|
197
187
|
|
|
188
|
+
def _resolve_core_version() -> Optional[str]:
|
|
189
|
+
"""Return the installed ``dblift`` core distribution version.
|
|
190
|
+
|
|
191
|
+
In a dev checkout, ``importlib.metadata.version("dblift")`` scans
|
|
192
|
+
``sys.path`` for ANY distribution metadata matching the name "dblift" —
|
|
193
|
+
it does not verify that metadata belongs to the code actually executing,
|
|
194
|
+
so a stale or shadowing install elsewhere on ``sys.path`` can win over the
|
|
195
|
+
running source. The bundled ``__init__.py`` at the project root is the
|
|
196
|
+
freshest, least ambiguous ground truth for "what version is this code",
|
|
197
|
+
so it is tried first. Under a frozen build, though, the filesystem layout
|
|
198
|
+
is unreliable, so the walk is skipped entirely and ``importlib.metadata``
|
|
199
|
+
is used instead.
|
|
200
|
+
"""
|
|
201
|
+
from importlib.metadata import PackageNotFoundError
|
|
202
|
+
from importlib.metadata import version as _version
|
|
203
|
+
|
|
204
|
+
if not getattr(sys, "frozen", False):
|
|
205
|
+
try:
|
|
206
|
+
init_file = _project_root / "__init__.py"
|
|
207
|
+
if init_file.exists():
|
|
208
|
+
with open(init_file, "r", encoding="utf-8") as f:
|
|
209
|
+
for line in f:
|
|
210
|
+
if line.startswith("__version__"):
|
|
211
|
+
parts = line.split("=", 1)
|
|
212
|
+
if len(parts) == 2:
|
|
213
|
+
return parts[1].strip().strip('"').strip("'")
|
|
214
|
+
except Exception:
|
|
215
|
+
pass
|
|
216
|
+
|
|
217
|
+
try:
|
|
218
|
+
return _version("dblift")
|
|
219
|
+
except PackageNotFoundError:
|
|
220
|
+
return None
|
|
221
|
+
|
|
222
|
+
|
|
198
223
|
def _format_version() -> str:
|
|
199
224
|
"""Render the ``--version`` output.
|
|
200
225
|
|
|
@@ -216,7 +241,7 @@ def _format_version() -> str:
|
|
|
216
241
|
except PackageNotFoundError:
|
|
217
242
|
return None
|
|
218
243
|
|
|
219
|
-
core =
|
|
244
|
+
core = _resolve_core_version()
|
|
220
245
|
pro = _get("dblift-pro")
|
|
221
246
|
enterprise = _get("dblift-enterprise")
|
|
222
247
|
|
|
@@ -346,6 +371,27 @@ def _parse_argv_and_load_config(argv: List[str]) -> _CliContext:
|
|
|
346
371
|
|
|
347
372
|
sys.exit(run_config_command(args))
|
|
348
373
|
|
|
374
|
+
# A handler marked ``_dblift_zero_config_command`` needs no project
|
|
375
|
+
# config at all (e.g. a paid `license` command checking
|
|
376
|
+
# ~/.dblift/license.key — nothing to do with a database). Unlike the
|
|
377
|
+
# `config`/`db` short-circuits above, OSS can't spell the command name
|
|
378
|
+
# here: only core/premium_manifest.py may name a paid-edition command.
|
|
379
|
+
# So this is driven purely by a handler attribute, read generically off
|
|
380
|
+
# whatever's registered for the command — same pattern as
|
|
381
|
+
# ``_dblift_config_only_client``/``_dblift_skip_secret_resolution``.
|
|
382
|
+
# Single-command only: firing on ``commands[0]`` unconditionally would
|
|
383
|
+
# silently drop the rest of a chained invocation (e.g. `dblift license
|
|
384
|
+
# migrate`) instead of running it. A chained zero-config command falls
|
|
385
|
+
# through to the normal config-requiring pipeline instead — consistent
|
|
386
|
+
# with how ``_build_command_client`` already gates its own
|
|
387
|
+
# single-command-only optimization the same way.
|
|
388
|
+
if len(commands) == 1 and _command_handler_attr(
|
|
389
|
+
commands[0], "_dblift_zero_config_command", False
|
|
390
|
+
):
|
|
391
|
+
handler = _COMMAND_HANDLERS[commands[0]]
|
|
392
|
+
success, _payload = handler(CliCommandContext(args=args))
|
|
393
|
+
sys.exit(0 if success else 1)
|
|
394
|
+
|
|
349
395
|
log = LogFactory.get_log("Dblift")
|
|
350
396
|
parser = create_parser()
|
|
351
397
|
# Validate log format before any config load so bogus --log-format fails with argparse
|
|
@@ -495,8 +541,7 @@ def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
|
|
|
495
541
|
if placeholders:
|
|
496
542
|
ctx.log.debug(f"Using placeholders: {placeholders}")
|
|
497
543
|
|
|
498
|
-
ctx.config.
|
|
499
|
-
if getattr(ctx.args, "strict", False):
|
|
544
|
+
if getattr(ctx.config, "strict_mode", False) or getattr(ctx.args, "strict_mode", False):
|
|
500
545
|
ctx.config.strict_mode = True
|
|
501
546
|
ctx.log.info(
|
|
502
547
|
"Strict mode is enabled. All migrations will be validated against strict rules."
|
|
@@ -577,6 +622,11 @@ def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
|
|
|
577
622
|
_close_logs(ctx.log)
|
|
578
623
|
return 1 if any_command_failed else 0
|
|
579
624
|
|
|
625
|
+
except SystemExit:
|
|
626
|
+
# CapabilityDeniedError (and other intentional exits) re-raise
|
|
627
|
+
# SystemExit with a dedicated code; flush logs then propagate.
|
|
628
|
+
_close_logs(ctx.log)
|
|
629
|
+
raise
|
|
580
630
|
except Exception as e:
|
|
581
631
|
ctx.log.error(f"Unexpected error: {str(e)}")
|
|
582
632
|
ctx.log.error_with_exception("Command execution failed", e)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Backward-compatible re-export of the premium-command catalog.
|
|
2
|
+
|
|
3
|
+
The catalog itself lives in ``core/premium_manifest.py`` now — both
|
|
4
|
+
``cli/`` and ``api/`` need it, and the ``cli-is-topmost`` .importlinter
|
|
5
|
+
contract forbids ``api`` from importing ``cli``, so it moved to a layer
|
|
6
|
+
both can reach. This module keeps ``from cli.premium_manifest import ...``
|
|
7
|
+
working unchanged for existing CLI code and tests.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from core.premium_manifest import (
|
|
13
|
+
PREMIUM_COMMANDS,
|
|
14
|
+
UPGRADE_URL,
|
|
15
|
+
PremiumCommand,
|
|
16
|
+
premium_commands_missing_from,
|
|
17
|
+
premium_stub_index,
|
|
18
|
+
render_upsell,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"PREMIUM_COMMANDS",
|
|
23
|
+
"UPGRADE_URL",
|
|
24
|
+
"PremiumCommand",
|
|
25
|
+
"premium_commands_missing_from",
|
|
26
|
+
"premium_stub_index",
|
|
27
|
+
"render_upsell",
|
|
28
|
+
]
|
|
@@ -9,7 +9,6 @@ from config._url_builder_mixin import UrlBuilderMixin
|
|
|
9
9
|
|
|
10
10
|
# Constants will be ported separately if needed
|
|
11
11
|
DEFAULT_CONNECTION_TIMEOUT_SECONDS = 30
|
|
12
|
-
ORACLE_DEFAULT_PORT = 1521
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
def _detect_dialect_from_url(url: str) -> str:
|
|
@@ -361,7 +360,9 @@ def _resolve_config_or_stub(
|
|
|
361
360
|
return config_class
|
|
362
361
|
if data.get("_allow_incomplete"):
|
|
363
362
|
return _build_incomplete_stub(data, db_type)
|
|
364
|
-
|
|
363
|
+
if db_type:
|
|
364
|
+
raise ValueError(f"Unsupported database type: {db_type}")
|
|
365
|
+
raise ValueError(f"Unsupported database type: {data.get('url', '')!r}")
|
|
365
366
|
|
|
366
367
|
|
|
367
368
|
def _instantiate_config(
|
|
@@ -381,11 +382,6 @@ class BaseDatabaseConfig(UrlBuilderMixin, ABC):
|
|
|
381
382
|
# Registry of database types to their config classes
|
|
382
383
|
_registry: ClassVar[Dict[str, Type["BaseDatabaseConfig"]]] = {}
|
|
383
384
|
|
|
384
|
-
@staticmethod
|
|
385
|
-
def _safe_str(value: Optional[str], default: str = "") -> str:
|
|
386
|
-
"""Safely handle optional string values."""
|
|
387
|
-
return value if value is not None else default
|
|
388
|
-
|
|
389
385
|
# Common parameters across all database types
|
|
390
386
|
type: str
|
|
391
387
|
url: str = ""
|