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.
Files changed (481) hide show
  1. {dblift-3.3.4 → dblift-3.4.0}/PKG-INFO +1 -1
  2. {dblift-3.3.4 → dblift-3.4.0}/api/client.py +63 -3
  3. {dblift-3.3.4 → dblift-3.4.0}/cli/_command_handlers.py +10 -1
  4. {dblift-3.3.4 → dblift-3.4.0}/cli/_config_helpers.py +0 -1
  5. {dblift-3.3.4 → dblift-3.4.0}/cli/_parser_setup.py +46 -20
  6. {dblift-3.3.4 → dblift-3.4.0}/cli/db_utils.py +78 -78
  7. {dblift-3.3.4 → dblift-3.4.0}/cli/extensions.py +0 -1
  8. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/_shared.py +0 -3
  9. {dblift-3.3.4 → dblift-3.4.0}/cli/main.py +63 -13
  10. dblift-3.4.0/cli/premium_manifest.py +28 -0
  11. {dblift-3.3.4 → dblift-3.4.0}/config/database_config.py +3 -7
  12. {dblift-3.3.4 → dblift-3.4.0}/config/dblift_config.py +4 -51
  13. {dblift-3.3.4 → dblift-3.4.0}/config/property_registry.py +0 -6
  14. {dblift-3.3.4 → dblift-3.4.0}/core/constants.py +0 -28
  15. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/index_extractor.py +4 -0
  16. {dblift-3.3.4 → dblift-3.4.0}/core/logger/__init__.py +7 -21
  17. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_formatters.py +25 -21
  18. dblift-3.4.0/core/logger/formatters/__init__.py +13 -0
  19. {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/_formatter_impl.py +2 -8
  20. {dblift-3.3.4 → dblift-3.4.0}/core/logger/log.py +2 -7
  21. {dblift-3.3.4 → dblift-3.4.0}/core/logger/results.py +1 -1
  22. {dblift-3.3.4 → dblift-3.4.0}/core/migration/clean_summary.py +1 -9
  23. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/base_command.py +9 -1
  24. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/baseline_command.py +1 -0
  25. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/clean_command.py +1 -67
  26. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/import_flyway_command.py +37 -1
  27. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/migrate_command.py +11 -1
  28. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/repair_command.py +12 -9
  29. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/undo_command.py +15 -4
  30. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/execution_engine.py +42 -53
  31. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/migration_executor.py +2 -2
  32. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/base_executor.py +2 -40
  33. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/executor_factory.py +12 -29
  34. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/python_executor.py +47 -70
  35. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/sql_executor.py +0 -40
  36. dblift-3.4.0/core/migration/formats/format_detector.py +110 -0
  37. {dblift-3.3.4 → dblift-3.4.0}/core/migration/formats/migration_format.py +0 -20
  38. {dblift-3.3.4 → dblift-3.4.0}/core/migration/history/migration_history_manager.py +10 -173
  39. {dblift-3.3.4 → dblift-3.4.0}/core/migration/journals/migration_journal.py +0 -64
  40. {dblift-3.3.4 → dblift-3.4.0}/core/migration/migration.py +80 -4
  41. dblift-3.4.0/core/migration/rules/migration_rules.py +140 -0
  42. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/migration_script_manager.py +58 -42
  43. dblift-3.4.0/core/migration/scripting/undo_script_generator/_helpers.py +36 -0
  44. {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/sql_analyzer.py +1 -266
  45. {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/sql_execution_service.py +28 -7
  46. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_data_service.py +0 -273
  47. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_display_state.py +0 -6
  48. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state_manager.py +24 -4
  49. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state_service.py +1 -24
  50. {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/__init__.py +1 -3
  51. {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/data_collector.py +14 -39
  52. {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/migration_ui.py +1 -114
  53. {dblift-3.3.4 → dblift-3.4.0}/core/migration/ui/table_renderer.py +2 -99
  54. dblift-3.4.0/core/normalization/__init__.py +7 -0
  55. {dblift-3.3.4/cli → dblift-3.4.0/core}/premium_manifest.py +27 -3
  56. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/__init__.py +0 -2
  57. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/alter_generator_factory.py +0 -10
  58. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/formatter.py +1 -18
  59. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/dialect.py +1 -48
  60. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/index.py +0 -24
  61. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/procedure.py +0 -41
  62. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table_options.py +0 -15
  63. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/base_statement_parser.py +11 -0
  64. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/base_tokenizer.py +53 -25
  65. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_checksum_validator.py +12 -2
  66. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_flyway_compatibility.py +40 -5
  67. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_migration_filter.py +4 -1
  68. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_strict_mode_validator.py +5 -2
  69. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/migration_validator.py +65 -37
  70. {dblift-3.3.4 → dblift-3.4.0}/db/base_quirks.py +31 -6
  71. {dblift-3.3.4 → dblift-3.4.0}/db/constants.py +0 -1
  72. {dblift-3.3.4 → dblift-3.4.0}/db/error.py +24 -165
  73. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_history_manager.py +37 -41
  74. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_query_executor.py +0 -99
  75. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_schema_operations.py +0 -59
  76. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/sqlalchemy_dialect.py +1 -1
  77. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/sqlalchemy_url.py +2 -1
  78. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/history_manager.py +18 -6
  79. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/query_executor.py +0 -20
  80. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/history_manager.py +0 -39
  81. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/schema_operations.py +0 -446
  82. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/db2_regex_parser.py +53 -22
  83. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/parser_config.py +337 -233
  84. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/provider.py +11 -1
  85. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/quirks.py +9 -0
  86. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/duckdb_regex_parser.py +0 -16
  87. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/provider.py +26 -12
  88. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/history_manager.py +0 -128
  89. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/provider.py +3 -2
  90. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/history_manager.py +12 -5
  91. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/schema_operations.py +0 -79
  92. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_parser.py +0 -35
  93. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_tokenizer.py +2 -3
  94. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/provider.py +39 -21
  95. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/quirks.py +10 -0
  96. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/parser_config.py +0 -12
  97. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -20
  98. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/schema_operations.py +59 -4
  99. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/provider.py +48 -3
  100. dblift-3.4.0/db/plugins/postgresql/search_path.py +51 -0
  101. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/sqlalchemy_url.py +3 -1
  102. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/provider.py +4 -0
  103. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/provider.py +2 -1
  104. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/sqlite_regex_parser.py +1 -100
  105. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/provider.py +32 -0
  106. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +8 -12
  107. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/provider.py +20 -1
  108. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/quirks.py +21 -0
  109. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/history_manager.py +7 -3
  110. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/schema_operations.py +37 -0
  111. {dblift-3.3.4 → dblift-3.4.0}/db/provider_capabilities.py +5 -6
  112. {dblift-3.3.4 → dblift-3.4.0}/db/provider_interfaces.py +27 -30
  113. {dblift-3.3.4 → dblift-3.4.0}/db/provider_registry.py +1 -42
  114. {dblift-3.3.4 → dblift-3.4.0}/db/sqlalchemy_provider.py +89 -1
  115. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/PKG-INFO +1 -1
  116. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/SOURCES.txt +2 -15
  117. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/_engine.py +1 -7
  118. {dblift-3.3.4 → dblift-3.4.0}/pyproject.toml +2 -42
  119. dblift-3.3.4/core/logger/formatters/__init__.py +0 -30
  120. dblift-3.3.4/core/migration/formats/format_detector.py +0 -204
  121. dblift-3.3.4/core/migration/rules/migration_rules.py +0 -145
  122. dblift-3.3.4/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -485
  123. dblift-3.3.4/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -319
  124. dblift-3.3.4/core/migration/scripting/undo_script_generator/_helpers.py +0 -555
  125. dblift-3.3.4/core/migration/state/migration_formatter.py +0 -215
  126. dblift-3.3.4/core/migration/ui/display_formatters.py +0 -251
  127. dblift-3.3.4/core/migration/ui/migration_analyzer.py +0 -259
  128. dblift-3.3.4/core/normalization/__init__.py +0 -35
  129. dblift-3.3.4/core/normalization/dependency_resolver.py +0 -444
  130. dblift-3.3.4/core/normalization/identifier_normalizer.py +0 -297
  131. dblift-3.3.4/core/normalization/object_orderer.py +0 -230
  132. dblift-3.3.4/core/normalization/type_mapper.py +0 -210
  133. dblift-3.3.4/core/normalization/type_mappings.py +0 -89
  134. dblift-3.3.4/core/sql_generator/alter_generator.py +0 -64
  135. dblift-3.3.4/core/state/sql_script_formatter.py +0 -144
  136. dblift-3.3.4/db/error_handler.py +0 -349
  137. dblift-3.3.4/db/plugins/base_undo_manager.py +0 -126
  138. dblift-3.3.4/db/plugins/oracle/parser/parser_config.py +0 -330
  139. {dblift-3.3.4 → dblift-3.4.0}/LICENSE +0 -0
  140. {dblift-3.3.4 → dblift-3.4.0}/README.md +0 -0
  141. {dblift-3.3.4 → dblift-3.4.0}/api/__init__.py +0 -0
  142. {dblift-3.3.4 → dblift-3.4.0}/api/_cli_support.py +0 -0
  143. {dblift-3.3.4 → dblift-3.4.0}/api/_client_factory.py +0 -0
  144. {dblift-3.3.4 → dblift-3.4.0}/api/_client_operations.py +0 -0
  145. {dblift-3.3.4 → dblift-3.4.0}/api/_engine_config.py +0 -0
  146. {dblift-3.3.4 → dblift-3.4.0}/api/async_client.py +0 -0
  147. {dblift-3.3.4 → dblift-3.4.0}/api/events.py +0 -0
  148. {dblift-3.3.4 → dblift-3.4.0}/api/migrations.py +0 -0
  149. {dblift-3.3.4 → dblift-3.4.0}/api/py.typed +0 -0
  150. {dblift-3.3.4 → dblift-3.4.0}/cli/__init__.py +0 -0
  151. {dblift-3.3.4 → dblift-3.4.0}/cli/_constants.py +0 -0
  152. {dblift-3.3.4 → dblift-3.4.0}/cli/_output.py +0 -0
  153. {dblift-3.3.4 → dblift-3.4.0}/cli/commands/__init__.py +0 -0
  154. {dblift-3.3.4 → dblift-3.4.0}/cli/commands/config_command.py +0 -0
  155. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/__init__.py +0 -0
  156. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/baseline.py +0 -0
  157. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/clean.py +0 -0
  158. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/import_flyway.py +0 -0
  159. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/info.py +0 -0
  160. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/migrate.py +0 -0
  161. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/repair.py +0 -0
  162. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/undo.py +0 -0
  163. {dblift-3.3.4 → dblift-3.4.0}/cli/handlers/validate.py +0 -0
  164. {dblift-3.3.4 → dblift-3.4.0}/config/__init__.py +0 -0
  165. {dblift-3.3.4 → dblift-3.4.0}/config/_credential_masking.py +0 -0
  166. {dblift-3.3.4 → dblift-3.4.0}/config/_subclasses/__init__.py +0 -0
  167. {dblift-3.3.4 → dblift-3.4.0}/config/_subclasses/dummy_config.py +0 -0
  168. {dblift-3.3.4 → dblift-3.4.0}/config/_url_builder_mixin.py +0 -0
  169. {dblift-3.3.4 → dblift-3.4.0}/config/config_builder.py +0 -0
  170. {dblift-3.3.4 → dblift-3.4.0}/config/errors.py +0 -0
  171. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/__init__.py +0 -0
  172. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_cache.py +0 -0
  173. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_provider_base.py +0 -0
  174. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_registry.py +0 -0
  175. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_resolver.py +0 -0
  176. {dblift-3.3.4 → dblift-3.4.0}/config/secrets/_secrets_config.py +0 -0
  177. {dblift-3.3.4 → dblift-3.4.0}/core/__init__.py +0 -0
  178. {dblift-3.3.4 → dblift-3.4.0}/core/dialect_boundary.py +0 -0
  179. {dblift-3.3.4 → dblift-3.4.0}/core/exceptions.py +0 -0
  180. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/__init__.py +0 -0
  181. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_column_enricher.py +0 -0
  182. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_partition_enricher.py +0 -0
  183. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_schema_orchestrator.py +0 -0
  184. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_utils.py +0 -0
  185. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/_vendor_property_applier.py +0 -0
  186. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/base_introspector.py +0 -0
  187. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/__init__.py +0 -0
  188. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/base_extractor.py +0 -0
  189. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/column_extractor.py +0 -0
  190. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/constraint_extractor.py +0 -0
  191. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/misc_extractor.py +0 -0
  192. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/procedure_extractor.py +0 -0
  193. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/sequence_extractor.py +0 -0
  194. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/table_extractor.py +0 -0
  195. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/trigger_extractor.py +0 -0
  196. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/extractors/view_extractor.py +0 -0
  197. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/introspector_factory.py +0 -0
  198. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/result.py +0 -0
  199. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/schema_introspector.py +0 -0
  200. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_base.py +0 -0
  201. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_factory.py +0 -0
  202. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/vendor_queries_protocols.py +0 -0
  203. {dblift-3.3.4 → dblift-3.4.0}/core/introspection/version_detector.py +0 -0
  204. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_base.py +0 -0
  205. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_factory.py +0 -0
  206. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_levels.py +0 -0
  207. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_multi.py +0 -0
  208. {dblift-3.3.4 → dblift-3.4.0}/core/logger/_null.py +0 -0
  209. {dblift-3.3.4 → dblift-3.4.0}/core/logger/console.py +0 -0
  210. {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/factory.py +0 -0
  211. {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/formatter.py +0 -0
  212. {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/htmlformatter.py +0 -0
  213. {dblift-3.3.4 → dblift-3.4.0}/core/logger/formatters/jsonformatter.py +0 -0
  214. {dblift-3.3.4 → dblift-3.4.0}/core/logger/templates/oldreport.html +0 -0
  215. {dblift-3.3.4 → dblift-3.4.0}/core/logger/templates/report.html +0 -0
  216. {dblift-3.3.4 → dblift-3.4.0}/core/migration/__init__.py +0 -0
  217. {dblift-3.3.4 → dblift-3.4.0}/core/migration/_type_match.py +0 -0
  218. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/__init__.py +0 -0
  219. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/_script_events.py +0 -0
  220. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/info_command.py +0 -0
  221. {dblift-3.3.4 → dblift-3.4.0}/core/migration/commands/validate_command.py +0 -0
  222. {dblift-3.3.4 → dblift-3.4.0}/core/migration/encoding.py +0 -0
  223. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/__init__.py +0 -0
  224. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/migration_helpers.py +0 -0
  225. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/placeholder_manager.py +0 -0
  226. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executor/transaction_policy.py +0 -0
  227. {dblift-3.3.4 → dblift-3.4.0}/core/migration/executors/__init__.py +0 -0
  228. {dblift-3.3.4 → dblift-3.4.0}/core/migration/formats/__init__.py +0 -0
  229. {dblift-3.3.4 → dblift-3.4.0}/core/migration/history/__init__.py +0 -0
  230. {dblift-3.3.4 → dblift-3.4.0}/core/migration/journals/__init__.py +0 -0
  231. {dblift-3.3.4 → dblift-3.4.0}/core/migration/placeholders/__init__.py +0 -0
  232. {dblift-3.3.4 → dblift-3.4.0}/core/migration/placeholders/placeholder_service.py +0 -0
  233. {dblift-3.3.4 → dblift-3.4.0}/core/migration/rules/__init__.py +0 -0
  234. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/__init__.py +0 -0
  235. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
  236. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
  237. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
  238. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_models.py +0 -0
  239. {dblift-3.3.4 → dblift-3.4.0}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
  240. {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/__init__.py +0 -0
  241. {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/execution_statement.py +0 -0
  242. {dblift-3.3.4 → dblift-3.4.0}/core/migration/sql/statement_splitter.py +0 -0
  243. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/__init__.py +0 -0
  244. {dblift-3.3.4 → dblift-3.4.0}/core/migration/state/migration_state.py +0 -0
  245. {dblift-3.3.4 → dblift-3.4.0}/core/migration/version_utils.py +0 -0
  246. {dblift-3.3.4 → dblift-3.4.0}/core/normalization/type_constants.py +0 -0
  247. {dblift-3.3.4 → dblift-3.4.0}/core/normalization/type_normalizer.py +0 -0
  248. {dblift-3.3.4 → dblift-3.4.0}/core/seams/__init__.py +0 -0
  249. {dblift-3.3.4 → dblift-3.4.0}/core/seams/capabilities.py +0 -0
  250. {dblift-3.3.4 → dblift-3.4.0}/core/seams/client_factory.py +0 -0
  251. {dblift-3.3.4 → dblift-3.4.0}/core/seams/event_listeners.py +0 -0
  252. {dblift-3.3.4 → dblift-3.4.0}/core/seams/feature_loading.py +0 -0
  253. {dblift-3.3.4 → dblift-3.4.0}/core/seams/introspection.py +0 -0
  254. {dblift-3.3.4 → dblift-3.4.0}/core/seams/license_info.py +0 -0
  255. {dblift-3.3.4 → dblift-3.4.0}/core/seams/runtime_checks.py +0 -0
  256. {dblift-3.3.4 → dblift-3.4.0}/core/seams/sql_generators.py +0 -0
  257. {dblift-3.3.4 → dblift-3.4.0}/core/seams/tier_resolver.py +0 -0
  258. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/__init__.py +0 -0
  259. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/alter/base_alter_generator.py +0 -0
  260. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/base_generator.py +0 -0
  261. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/basic_table_ddl_generator.py +0 -0
  262. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/dependency_analyzer.py +0 -0
  263. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/diff_converters/__init__.py +0 -0
  264. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/diff_converters/base_converter.py +0 -0
  265. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/generator_factory.py +0 -0
  266. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/options.py +0 -0
  267. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/script_organizer.py +0 -0
  268. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/sql_generator.py +0 -0
  269. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/sql_statement.py +0 -0
  270. {dblift-3.3.4 → dblift-3.4.0}/core/sql_generator/table_ddl_render.py +0 -0
  271. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/__init__.py +0 -0
  272. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_parse_result.py +0 -0
  273. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_column.py +0 -0
  274. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_constraint.py +0 -0
  275. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_object.py +0 -0
  276. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/_base_sql_statement.py +0 -0
  277. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/base.py +0 -0
  278. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/constraint_validator.py +0 -0
  279. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/database_link.py +0 -0
  280. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/event.py +0 -0
  281. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/extension.py +0 -0
  282. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/feature_gates.py +0 -0
  283. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/foreign_data_wrapper.py +0 -0
  284. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/foreign_server.py +0 -0
  285. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/linked_server.py +0 -0
  286. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/module.py +0 -0
  287. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/package.py +0 -0
  288. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/partition.py +0 -0
  289. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/sequence.py +0 -0
  290. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/server_info.py +0 -0
  291. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/synonym.py +0 -0
  292. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table.py +0 -0
  293. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/table_canonicalizer.py +0 -0
  294. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/trigger.py +0 -0
  295. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/user_defined_type.py +0 -0
  296. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/view.py +0 -0
  297. {dblift-3.3.4 → dblift-3.4.0}/core/sql_model/view_options.py +0 -0
  298. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/__init__.py +0 -0
  299. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/_partition_handler.py +0 -0
  300. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/_sqlglot_builders.py +0 -0
  301. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/common/__init__.py +0 -0
  302. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/common/base_parser.py +0 -0
  303. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/dialects/__init__.py +0 -0
  304. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/dialects/base_config.py +0 -0
  305. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/enhanced_regex_parser.py +0 -0
  306. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/hybrid_parser.py +0 -0
  307. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_context.py +0 -0
  308. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_factory.py +0 -0
  309. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/parser_interface.py +0 -0
  310. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/sqlglot_parser.py +0 -0
  311. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/tokens.py +0 -0
  312. {dblift-3.3.4 → dblift-3.4.0}/core/sql_parser/unified_regex_parser.py +0 -0
  313. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/__init__.py +0 -0
  314. {dblift-3.3.4 → dblift-3.4.0}/core/sql_validator/_sql_syntax_validator.py +0 -0
  315. {dblift-3.3.4 → dblift-3.4.0}/core/state/sql_statement.py +0 -0
  316. {dblift-3.3.4 → dblift-3.4.0}/core/utils/__init__.py +0 -0
  317. {dblift-3.3.4 → dblift-3.4.0}/core/utils/database_url_parser.py +0 -0
  318. {dblift-3.3.4 → dblift-3.4.0}/core/utils/metadata_helpers.py +0 -0
  319. {dblift-3.3.4 → dblift-3.4.0}/core/utils/row_access.py +0 -0
  320. {dblift-3.3.4 → dblift-3.4.0}/core/utils/string_utils.py +0 -0
  321. {dblift-3.3.4 → dblift-3.4.0}/core/utils/url_masking.py +0 -0
  322. {dblift-3.3.4 → dblift-3.4.0}/db/__init__.py +0 -0
  323. {dblift-3.3.4 → dblift-3.4.0}/db/base_provider.py +0 -0
  324. {dblift-3.3.4 → dblift-3.4.0}/db/dml_analysis.py +0 -0
  325. {dblift-3.3.4 → dblift-3.4.0}/db/exceptions.py +0 -0
  326. {dblift-3.3.4 → dblift-3.4.0}/db/feature_gate.py +0 -0
  327. {dblift-3.3.4 → dblift-3.4.0}/db/native_connection_manager.py +0 -0
  328. {dblift-3.3.4 → dblift-3.4.0}/db/object_naming.py +0 -0
  329. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/__init__.py +0 -0
  330. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/_pg_compatible.py +0 -0
  331. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/alloydb/__init__.py +0 -0
  332. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/alloydb/plugin.py +0 -0
  333. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/aurora_postgresql/__init__.py +0 -0
  334. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/aurora_postgresql/plugin.py +0 -0
  335. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_locking_manager.py +0 -0
  336. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/base_snapshot_manager.py +0 -0
  337. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/citus/__init__.py +0 -0
  338. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/citus/plugin.py +0 -0
  339. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/__init__.py +0 -0
  340. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/plugin.py +0 -0
  341. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/provider.py +0 -0
  342. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cockroachdb/quirks.py +0 -0
  343. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/__init__.py +0 -0
  344. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/config.py +0 -0
  345. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
  346. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
  347. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
  348. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
  349. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
  350. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
  351. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/plugin.py +0 -0
  352. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/provider.py +0 -0
  353. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/cosmosdb/quirks.py +0 -0
  354. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/__init__.py +0 -0
  355. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/config.py +0 -0
  356. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/__init__.py +0 -0
  357. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/db2/locking_manager.py +0 -0
  358. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/introspection/__init__.py +0 -0
  359. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/parser/__init__.py +0 -0
  360. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/plugin.py +0 -0
  361. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/db2/sqlalchemy_url.py +0 -0
  362. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/__init__.py +0 -0
  363. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/config.py +0 -0
  364. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/__init__.py +0 -0
  365. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/parser/parser_config.py +0 -0
  366. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/plugin.py +0 -0
  367. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/quirks.py +0 -0
  368. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/duckdb/sqlalchemy_url.py +0 -0
  369. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/__init__.py +0 -0
  370. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/plugin.py +0 -0
  371. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/provider.py +0 -0
  372. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mariadb/quirks.py +0 -0
  373. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/__init__.py +0 -0
  374. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/config.py +0 -0
  375. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/introspection/__init__.py +0 -0
  376. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/__init__.py +0 -0
  377. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/locking_manager.py +0 -0
  378. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/mysql/schema_operations.py +0 -0
  379. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/__init__.py +0 -0
  380. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
  381. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
  382. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
  383. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/parser/parser_config.py +0 -0
  384. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/plugin.py +0 -0
  385. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/quirks.py +0 -0
  386. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/mysql/sqlalchemy_url.py +0 -0
  387. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/neon/__init__.py +0 -0
  388. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/neon/plugin.py +0 -0
  389. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/__init__.py +0 -0
  390. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/history.py +0 -0
  391. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/introspection.py +0 -0
  392. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/nosql_base/locking.py +0 -0
  393. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/__init__.py +0 -0
  394. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/config.py +0 -0
  395. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/introspection/__init__.py +0 -0
  396. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
  397. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/__init__.py +0 -0
  398. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/dbms_output.py +0 -0
  399. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/oracle/locking_manager.py +0 -0
  400. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/__init__.py +0 -0
  401. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_comments.py +0 -0
  402. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_object_extractor.py +0 -0
  403. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_plsql_block.py +0 -0
  404. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_sqlplus.py +0 -0
  405. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
  406. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
  407. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
  408. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/plugin.py +0 -0
  409. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/oracle/sqlalchemy_url.py +0 -0
  410. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/__init__.py +0 -0
  411. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/_provider_query_executor.py +0 -0
  412. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/config.py +0 -0
  413. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/introspection/__init__.py +0 -0
  414. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/__init__.py +0 -0
  415. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
  416. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
  417. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/plugin.py +0 -0
  418. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/__init__.py +0 -0
  419. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
  420. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
  421. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/postgresql/quirks.py +0 -0
  422. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/__init__.py +0 -0
  423. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/plugin.py +0 -0
  424. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/quirks.py +0 -0
  425. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/redshift/sqlalchemy_url.py +0 -0
  426. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/__init__.py +0 -0
  427. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/config.py +0 -0
  428. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/plugin.py +0 -0
  429. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/quirks.py +0 -0
  430. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/snowflake/sqlalchemy_url.py +0 -0
  431. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/__init__.py +0 -0
  432. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/config.py +0 -0
  433. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/introspection/__init__.py +0 -0
  434. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/__init__.py +0 -0
  435. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/parser/parser_config.py +0 -0
  436. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/plugin.py +0 -0
  437. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/quirks.py +0 -0
  438. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
  439. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/__init__.py +0 -0
  440. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
  441. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
  442. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
  443. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
  444. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
  445. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/__init__.py +0 -0
  446. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/config.py +0 -0
  447. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/introspection/__init__.py +0 -0
  448. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/__init__.py +0 -0
  449. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/parser_config.py +0 -0
  450. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
  451. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
  452. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
  453. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/plugin.py +0 -0
  454. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlalchemy_url.py +0 -0
  455. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
  456. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
  457. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/supabase/__init__.py +0 -0
  458. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/supabase/plugin.py +0 -0
  459. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/timescaledb/__init__.py +0 -0
  460. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/timescaledb/plugin.py +0 -0
  461. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/yugabytedb/__init__.py +0 -0
  462. {dblift-3.3.4 → dblift-3.4.0}/db/plugins/yugabytedb/plugin.py +0 -0
  463. {dblift-3.3.4 → dblift-3.4.0}/db/value_utils.py +0 -0
  464. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/dependency_links.txt +0 -0
  465. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/entry_points.txt +0 -0
  466. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/requires.txt +0 -0
  467. {dblift-3.3.4 → dblift-3.4.0}/dblift.egg-info/top_level.txt +0 -0
  468. {dblift-3.3.4 → dblift-3.4.0}/integrations/__init__.py +0 -0
  469. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/__init__.py +0 -0
  470. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/_client.py +0 -0
  471. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/apps.py +0 -0
  472. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/checks.py +0 -0
  473. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/__init__.py +0 -0
  474. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/__init__.py +0 -0
  475. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_info.py +0 -0
  476. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_migrate.py +0 -0
  477. {dblift-3.3.4 → dblift-3.4.0}/integrations/django/management/commands/dblift_validate.py +0 -0
  478. {dblift-3.3.4 → dblift-3.4.0}/integrations/fastapi.py +0 -0
  479. {dblift-3.3.4 → dblift-3.4.0}/integrations/flask.py +0 -0
  480. {dblift-3.3.4 → dblift-3.4.0}/integrations/opentelemetry.py +0 -0
  481. {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.4
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(EventType.VALIDATION_COMPLETED, {"result": result})
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(EventType.VALIDATION_FAILED, {"error": str(e)})
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
- return handler(ctx)
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:
@@ -45,7 +45,6 @@ _SUBCOMMAND_BOOLEAN_FLAGS = frozenset(
45
45
  "--show-sql",
46
46
  "--rehearse-rollback",
47
47
  "--skip-replay",
48
- "--skip-validation",
49
48
  "--skip-validate-sql",
50
49
  "--split-by-type",
51
50
  "--strict",
@@ -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("--db-url", dest="database_url", help="Database URL")
345
- db_parent.add_argument("--db-username", dest="database_username", help="Database username")
346
- db_parent.add_argument("--db-password", dest="database_password", help="Database password")
347
- db_parent.add_argument("--db-schema", dest="database_schema", help="Database schema")
348
- # Hidden copy for the root parser: flags are parsed globally but shown in
349
- # subcommand --help only.
350
- db_parent_hidden = argparse.ArgumentParser(add_help=False)
351
- db_parent_hidden.add_argument("--db-url", dest="database_url", help=argparse.SUPPRESS)
352
- db_parent_hidden.add_argument("--db-username", dest="database_username", help=argparse.SUPPRESS)
353
- db_parent_hidden.add_argument("--db-password", dest="database_password", help=argparse.SUPPRESS)
354
- db_parent_hidden.add_argument("--db-schema", dest="database_schema", help=argparse.SUPPRESS)
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": [db_parent_hidden],
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
- 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
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 = (
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
- results["connection_info"]["config_source"] = "Created from provided parameters"
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
- # Validate database type
300
- if not config.database.type:
301
- error_message = "Missing database type. Please provide --db-type or a configuration with database type."
302
- out.error(error_message)
303
- results["error"] = error_message
304
- print_connection_results(results, out)
305
- return 1
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
- # Create database provider via registry (DIP — no concrete plugin imports)
310
- try:
311
- provider: Any = ProviderRegistry.create_provider(config, logger)
312
- except ValueError as e:
313
- results["error"] = str(e)
314
- print_connection_results(results, out)
315
- return 1
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
- # Test connection. Format known driver errors as a one-line message so the CLI doesn't
318
- # dump a Python traceback to stderr on e.g. connection refused / auth failure.
319
- try:
320
- provider.create_connection()
321
- except Exception as connection_error:
322
- friendly = _format_connection_error(connection_error, db_type)
323
- out.error(friendly)
324
- results["error"] = friendly
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
- if getattr(args, "log_level", "info") == "debug":
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
- # Close connection even if get_database_version/display URL lookup raises
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 = _get("dblift")
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.journal_enabled = True
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
- raise ValueError(f"Unsupported database type: {db_type}")
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 = ""