dblift 2.2.0__tar.gz → 2.2.1__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 (435) hide show
  1. {dblift-2.2.0 → dblift-2.2.1}/PKG-INFO +1 -1
  2. dblift-2.2.1/api/__init__.py +16 -0
  3. {dblift-2.2.0 → dblift-2.2.1}/api/_client_operations.py +6 -2
  4. {dblift-2.2.0 → dblift-2.2.1}/api/client.py +9 -5
  5. {dblift-2.2.0 → dblift-2.2.1}/cli/_config_helpers.py +40 -11
  6. {dblift-2.2.0 → dblift-2.2.1}/cli/_output.py +2 -1
  7. {dblift-2.2.0 → dblift-2.2.1}/cli/_parser_setup.py +23 -5
  8. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/_shared.py +20 -10
  9. {dblift-2.2.0 → dblift-2.2.1}/cli/main.py +36 -11
  10. {dblift-2.2.0 → dblift-2.2.1}/config/database_config.py +3 -3
  11. {dblift-2.2.0 → dblift-2.2.1}/config/dblift_config.py +89 -5
  12. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/_registry.py +3 -2
  13. {dblift-2.2.0 → dblift-2.2.1}/core/dialect_boundary.py +9 -4
  14. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/_formatter_impl.py +1 -3
  15. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/htmlformatter.py +26 -14
  16. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/base_command.py +2 -2
  17. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/migrate_command.py +3 -0
  18. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/execution_engine.py +3 -0
  19. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/migration_executor.py +1 -1
  20. dblift-2.2.1/core/seams/capabilities.py +20 -0
  21. {dblift-2.2.0 → dblift-2.2.1}/core/seams/event_listeners.py +3 -2
  22. dblift-2.2.1/core/seams/feature_loading.py +66 -0
  23. {dblift-2.2.0 → dblift-2.2.1}/core/seams/introspection.py +1 -1
  24. dblift-2.2.1/core/seams/license_info.py +42 -0
  25. dblift-2.2.1/core/seams/runtime_checks.py +35 -0
  26. dblift-2.2.1/core/seams/sql_generators.py +42 -0
  27. dblift-2.2.1/core/seams/tier_resolver.py +59 -0
  28. dblift-2.2.1/core/sql_generator/__init__.py +42 -0
  29. dblift-2.2.1/core/sql_generator/alter/__init__.py +17 -0
  30. dblift-2.2.1/core/sql_generator/alter/alter_generator_factory.py +123 -0
  31. dblift-2.2.1/core/sql_generator/alter/base_alter_generator.py +169 -0
  32. dblift-2.2.1/core/sql_generator/alter_generator.py +64 -0
  33. dblift-2.2.1/core/sql_generator/base_generator.py +607 -0
  34. dblift-2.2.1/core/sql_generator/basic_table_ddl_generator.py +1034 -0
  35. dblift-2.2.1/core/sql_generator/dependency_analyzer.py +602 -0
  36. dblift-2.2.1/core/sql_generator/diff_converters/__init__.py +5 -0
  37. dblift-2.2.1/core/sql_generator/diff_converters/base_converter.py +36 -0
  38. dblift-2.2.1/core/sql_generator/formatter.py +112 -0
  39. dblift-2.2.1/core/sql_generator/generator_factory.py +188 -0
  40. dblift-2.2.1/core/sql_generator/options.py +59 -0
  41. dblift-2.2.1/core/sql_generator/script_organizer.py +307 -0
  42. dblift-2.2.1/core/sql_generator/sql_generator.py +50 -0
  43. dblift-2.2.1/core/sql_generator/sql_statement.py +5 -0
  44. dblift-2.2.1/core/sql_generator/table_ddl_render.py +61 -0
  45. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/event.py +14 -2
  46. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/extension.py +14 -2
  47. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/foreign_data_wrapper.py +12 -2
  48. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/foreign_server.py +14 -2
  49. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/index.py +14 -2
  50. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/package.py +14 -2
  51. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/procedure.py +14 -2
  52. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/sequence.py +21 -1
  53. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/synonym.py +14 -2
  54. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/table.py +32 -61
  55. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/trigger.py +12 -2
  56. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/user_defined_type.py +12 -2
  57. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/view.py +14 -2
  58. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/__init__.py +1 -1
  59. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/migration_validator.py +2 -2
  60. {dblift-2.2.0 → dblift-2.2.1}/db/base_quirks.py +22 -7
  61. {dblift-2.2.0 → dblift-2.2.1}/db/dml_analysis.py +1 -1
  62. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/query_executor.py +1 -1
  63. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/quirks.py +13 -6
  64. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/db2/schema_operations.py +10 -8
  65. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/provider.py +14 -8
  66. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/quirks.py +10 -5
  67. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/quirks.py +11 -6
  68. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/quirks.py +47 -38
  69. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/quirks.py +13 -9
  70. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/quirks.py +9 -5
  71. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/quirks.py +11 -7
  72. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/sqlalchemy_url.py +12 -1
  73. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/PKG-INFO +1 -1
  74. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/SOURCES.txt +23 -3
  75. {dblift-2.2.0 → dblift-2.2.1}/pyproject.toml +3 -1
  76. dblift-2.2.0/api/__init__.py +0 -12
  77. dblift-2.2.0/core/features.py +0 -123
  78. dblift-2.2.0/core/logger/formatters/diff_utils.py +0 -414
  79. dblift-2.2.0/core/normalization/data_type_normalizer.py +0 -5
  80. {dblift-2.2.0 → dblift-2.2.1}/LICENSE +0 -0
  81. {dblift-2.2.0 → dblift-2.2.1}/README.md +0 -0
  82. {dblift-2.2.0 → dblift-2.2.1}/api/_cli_support.py +0 -0
  83. {dblift-2.2.0 → dblift-2.2.1}/api/_client_factory.py +0 -0
  84. {dblift-2.2.0 → dblift-2.2.1}/api/_engine_config.py +0 -0
  85. {dblift-2.2.0 → dblift-2.2.1}/api/async_client.py +0 -0
  86. {dblift-2.2.0 → dblift-2.2.1}/api/events.py +0 -0
  87. {dblift-2.2.0 → dblift-2.2.1}/api/migrations.py +0 -0
  88. {dblift-2.2.0 → dblift-2.2.1}/api/py.typed +0 -0
  89. {dblift-2.2.0 → dblift-2.2.1}/cli/__init__.py +0 -0
  90. {dblift-2.2.0 → dblift-2.2.1}/cli/_command_handlers.py +0 -0
  91. {dblift-2.2.0 → dblift-2.2.1}/cli/_constants.py +0 -0
  92. {dblift-2.2.0 → dblift-2.2.1}/cli/commands/__init__.py +0 -0
  93. {dblift-2.2.0 → dblift-2.2.1}/cli/commands/config_command.py +0 -0
  94. {dblift-2.2.0 → dblift-2.2.1}/cli/db_utils.py +0 -0
  95. {dblift-2.2.0 → dblift-2.2.1}/cli/extensions.py +0 -0
  96. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/__init__.py +0 -0
  97. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/baseline.py +0 -0
  98. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/clean.py +0 -0
  99. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/import_flyway.py +0 -0
  100. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/info.py +0 -0
  101. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/migrate.py +0 -0
  102. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/repair.py +0 -0
  103. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/undo.py +0 -0
  104. {dblift-2.2.0 → dblift-2.2.1}/cli/handlers/validate.py +0 -0
  105. {dblift-2.2.0 → dblift-2.2.1}/config/__init__.py +0 -0
  106. {dblift-2.2.0 → dblift-2.2.1}/config/_credential_masking.py +0 -0
  107. {dblift-2.2.0 → dblift-2.2.1}/config/_subclasses/__init__.py +0 -0
  108. {dblift-2.2.0 → dblift-2.2.1}/config/_subclasses/dummy_config.py +0 -0
  109. {dblift-2.2.0 → dblift-2.2.1}/config/_url_builder_mixin.py +0 -0
  110. {dblift-2.2.0 → dblift-2.2.1}/config/config_builder.py +0 -0
  111. {dblift-2.2.0 → dblift-2.2.1}/config/errors.py +0 -0
  112. {dblift-2.2.0 → dblift-2.2.1}/config/property_registry.py +0 -0
  113. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/__init__.py +0 -0
  114. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/_cache.py +0 -0
  115. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/_provider_base.py +0 -0
  116. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/_resolver.py +0 -0
  117. {dblift-2.2.0 → dblift-2.2.1}/config/secrets/_secrets_config.py +0 -0
  118. {dblift-2.2.0 → dblift-2.2.1}/core/__init__.py +0 -0
  119. {dblift-2.2.0 → dblift-2.2.1}/core/constants.py +0 -0
  120. {dblift-2.2.0 → dblift-2.2.1}/core/exceptions.py +0 -0
  121. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/__init__.py +0 -0
  122. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/_column_enricher.py +0 -0
  123. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/_partition_enricher.py +0 -0
  124. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/_schema_orchestrator.py +0 -0
  125. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/_utils.py +0 -0
  126. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/_vendor_property_applier.py +0 -0
  127. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/base_introspector.py +0 -0
  128. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/__init__.py +0 -0
  129. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/base_extractor.py +0 -0
  130. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/column_extractor.py +0 -0
  131. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/constraint_extractor.py +0 -0
  132. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/index_extractor.py +0 -0
  133. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/misc_extractor.py +0 -0
  134. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/procedure_extractor.py +0 -0
  135. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/sequence_extractor.py +0 -0
  136. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/table_extractor.py +0 -0
  137. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/trigger_extractor.py +0 -0
  138. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/extractors/view_extractor.py +0 -0
  139. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/introspector_factory.py +0 -0
  140. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/result.py +0 -0
  141. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/schema_introspector.py +0 -0
  142. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/vendor_queries_base.py +0 -0
  143. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/vendor_queries_factory.py +0 -0
  144. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/vendor_queries_protocols.py +0 -0
  145. {dblift-2.2.0 → dblift-2.2.1}/core/introspection/version_detector.py +0 -0
  146. {dblift-2.2.0 → dblift-2.2.1}/core/logger/__init__.py +0 -0
  147. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_base.py +0 -0
  148. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_factory.py +0 -0
  149. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_formatters.py +0 -0
  150. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_levels.py +0 -0
  151. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_multi.py +0 -0
  152. {dblift-2.2.0 → dblift-2.2.1}/core/logger/_null.py +0 -0
  153. {dblift-2.2.0 → dblift-2.2.1}/core/logger/console.py +0 -0
  154. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/__init__.py +0 -0
  155. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/factory.py +0 -0
  156. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/formatter.py +0 -0
  157. {dblift-2.2.0 → dblift-2.2.1}/core/logger/formatters/jsonformatter.py +0 -0
  158. {dblift-2.2.0 → dblift-2.2.1}/core/logger/log.py +0 -0
  159. {dblift-2.2.0 → dblift-2.2.1}/core/logger/results.py +0 -0
  160. {dblift-2.2.0 → dblift-2.2.1}/core/migration/__init__.py +0 -0
  161. {dblift-2.2.0 → dblift-2.2.1}/core/migration/_type_match.py +0 -0
  162. {dblift-2.2.0 → dblift-2.2.1}/core/migration/clean_summary.py +0 -0
  163. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/__init__.py +0 -0
  164. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/_script_events.py +0 -0
  165. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/baseline_command.py +0 -0
  166. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/clean_command.py +0 -0
  167. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/import_flyway_command.py +0 -0
  168. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/info_command.py +0 -0
  169. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/repair_command.py +0 -0
  170. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/undo_command.py +0 -0
  171. {dblift-2.2.0 → dblift-2.2.1}/core/migration/commands/validate_command.py +0 -0
  172. {dblift-2.2.0 → dblift-2.2.1}/core/migration/encoding.py +0 -0
  173. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/__init__.py +0 -0
  174. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/migration_helpers.py +0 -0
  175. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/placeholder_manager.py +0 -0
  176. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executor/transaction_policy.py +0 -0
  177. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executors/__init__.py +0 -0
  178. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executors/base_executor.py +0 -0
  179. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executors/executor_factory.py +0 -0
  180. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executors/python_executor.py +0 -0
  181. {dblift-2.2.0 → dblift-2.2.1}/core/migration/executors/sql_executor.py +0 -0
  182. {dblift-2.2.0 → dblift-2.2.1}/core/migration/formats/__init__.py +0 -0
  183. {dblift-2.2.0 → dblift-2.2.1}/core/migration/formats/format_detector.py +0 -0
  184. {dblift-2.2.0 → dblift-2.2.1}/core/migration/formats/migration_format.py +0 -0
  185. {dblift-2.2.0 → dblift-2.2.1}/core/migration/history/__init__.py +0 -0
  186. {dblift-2.2.0 → dblift-2.2.1}/core/migration/history/migration_history_manager.py +0 -0
  187. {dblift-2.2.0 → dblift-2.2.1}/core/migration/journals/__init__.py +0 -0
  188. {dblift-2.2.0 → dblift-2.2.1}/core/migration/journals/migration_journal.py +0 -0
  189. {dblift-2.2.0 → dblift-2.2.1}/core/migration/migration.py +0 -0
  190. {dblift-2.2.0 → dblift-2.2.1}/core/migration/placeholders/__init__.py +0 -0
  191. {dblift-2.2.0 → dblift-2.2.1}/core/migration/placeholders/placeholder_service.py +0 -0
  192. {dblift-2.2.0 → dblift-2.2.1}/core/migration/rules/__init__.py +0 -0
  193. {dblift-2.2.0 → dblift-2.2.1}/core/migration/rules/migration_rules.py +0 -0
  194. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/__init__.py +0 -0
  195. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/migration_script_manager.py +0 -0
  196. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
  197. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -0
  198. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -0
  199. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
  200. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
  201. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_helpers.py +0 -0
  202. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_models.py +0 -0
  203. {dblift-2.2.0 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
  204. {dblift-2.2.0 → dblift-2.2.1}/core/migration/sql/__init__.py +0 -0
  205. {dblift-2.2.0 → dblift-2.2.1}/core/migration/sql/execution_statement.py +0 -0
  206. {dblift-2.2.0 → dblift-2.2.1}/core/migration/sql/sql_analyzer.py +0 -0
  207. {dblift-2.2.0 → dblift-2.2.1}/core/migration/sql/sql_execution_service.py +0 -0
  208. {dblift-2.2.0 → dblift-2.2.1}/core/migration/sql/statement_splitter.py +0 -0
  209. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/__init__.py +0 -0
  210. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_data_service.py +0 -0
  211. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_display_state.py +0 -0
  212. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_formatter.py +0 -0
  213. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_state.py +0 -0
  214. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_state_manager.py +0 -0
  215. {dblift-2.2.0 → dblift-2.2.1}/core/migration/state/migration_state_service.py +0 -0
  216. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/__init__.py +0 -0
  217. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/data_collector.py +0 -0
  218. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/display_formatters.py +0 -0
  219. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/migration_analyzer.py +0 -0
  220. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/migration_ui.py +0 -0
  221. {dblift-2.2.0 → dblift-2.2.1}/core/migration/ui/table_renderer.py +0 -0
  222. {dblift-2.2.0 → dblift-2.2.1}/core/migration/version_utils.py +0 -0
  223. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/__init__.py +0 -0
  224. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/dependency_resolver.py +0 -0
  225. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/identifier_normalizer.py +0 -0
  226. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/object_orderer.py +0 -0
  227. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/type_constants.py +0 -0
  228. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/type_mapper.py +0 -0
  229. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/type_mappings.py +0 -0
  230. {dblift-2.2.0 → dblift-2.2.1}/core/normalization/type_normalizer.py +0 -0
  231. {dblift-2.2.0 → dblift-2.2.1}/core/seams/__init__.py +0 -0
  232. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/__init__.py +0 -0
  233. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/_base_parse_result.py +0 -0
  234. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/_base_sql_column.py +0 -0
  235. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/_base_sql_constraint.py +0 -0
  236. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/_base_sql_object.py +0 -0
  237. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/_base_sql_statement.py +0 -0
  238. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/base.py +0 -0
  239. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/constraint_validator.py +0 -0
  240. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/database_link.py +0 -0
  241. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/dialect.py +0 -0
  242. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/linked_server.py +0 -0
  243. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/module.py +0 -0
  244. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/partition.py +0 -0
  245. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/table_canonicalizer.py +0 -0
  246. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/table_options.py +0 -0
  247. {dblift-2.2.0 → dblift-2.2.1}/core/sql_model/view_options.py +0 -0
  248. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/__init__.py +0 -0
  249. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/_partition_handler.py +0 -0
  250. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/_sqlglot_builders.py +0 -0
  251. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/base_statement_parser.py +0 -0
  252. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/base_tokenizer.py +0 -0
  253. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/common/__init__.py +0 -0
  254. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/common/base_parser.py +0 -0
  255. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/dialects/__init__.py +0 -0
  256. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/dialects/base_config.py +0 -0
  257. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/enhanced_regex_parser.py +0 -0
  258. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/hybrid_parser.py +0 -0
  259. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/parser_context.py +0 -0
  260. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/parser_factory.py +0 -0
  261. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/parser_interface.py +0 -0
  262. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/sqlglot_parser.py +0 -0
  263. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/tokens.py +0 -0
  264. {dblift-2.2.0 → dblift-2.2.1}/core/sql_parser/unified_regex_parser.py +0 -0
  265. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/_checksum_validator.py +0 -0
  266. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/_flyway_compatibility.py +0 -0
  267. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/_migration_filter.py +0 -0
  268. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/_sql_syntax_validator.py +0 -0
  269. {dblift-2.2.0 → dblift-2.2.1}/core/sql_validator/_strict_mode_validator.py +0 -0
  270. {dblift-2.2.0 → dblift-2.2.1}/core/state/sql_script_formatter.py +0 -0
  271. {dblift-2.2.0 → dblift-2.2.1}/core/state/sql_statement.py +0 -0
  272. {dblift-2.2.0 → dblift-2.2.1}/core/utils/__init__.py +0 -0
  273. {dblift-2.2.0 → dblift-2.2.1}/core/utils/database_url_parser.py +0 -0
  274. {dblift-2.2.0 → dblift-2.2.1}/core/utils/metadata_helpers.py +0 -0
  275. {dblift-2.2.0 → dblift-2.2.1}/core/utils/row_access.py +0 -0
  276. {dblift-2.2.0 → dblift-2.2.1}/core/utils/string_utils.py +0 -0
  277. {dblift-2.2.0 → dblift-2.2.1}/core/utils/url_masking.py +0 -0
  278. {dblift-2.2.0 → dblift-2.2.1}/db/__init__.py +0 -0
  279. {dblift-2.2.0 → dblift-2.2.1}/db/base_provider.py +0 -0
  280. {dblift-2.2.0 → dblift-2.2.1}/db/constants.py +0 -0
  281. {dblift-2.2.0 → dblift-2.2.1}/db/error.py +0 -0
  282. {dblift-2.2.0 → dblift-2.2.1}/db/error_handler.py +0 -0
  283. {dblift-2.2.0 → dblift-2.2.1}/db/exceptions.py +0 -0
  284. {dblift-2.2.0 → dblift-2.2.1}/db/native_connection_manager.py +0 -0
  285. {dblift-2.2.0 → dblift-2.2.1}/db/object_naming.py +0 -0
  286. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/__init__.py +0 -0
  287. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_history_manager.py +0 -0
  288. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_locking_manager.py +0 -0
  289. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_query_executor.py +0 -0
  290. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_schema_operations.py +0 -0
  291. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_snapshot_manager.py +0 -0
  292. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/base_undo_manager.py +0 -0
  293. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/__init__.py +0 -0
  294. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/config.py +0 -0
  295. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
  296. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
  297. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
  298. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/history_manager.py +0 -0
  299. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
  300. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
  301. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
  302. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/parser/__init__.py +0 -0
  303. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/parser/cosmosdb_regex_parser.py +0 -0
  304. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/plugin.py +0 -0
  305. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/provider.py +0 -0
  306. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/__init__.py +0 -0
  307. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_executor.py +0 -0
  308. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_executors.py +0 -0
  309. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_parsing.py +0 -0
  310. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_script_generation.py +0 -0
  311. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_translator.py +0 -0
  312. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_translators.py +0 -0
  313. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/__init__.py +0 -0
  314. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/config.py +0 -0
  315. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/db2/__init__.py +0 -0
  316. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/db2/history_manager.py +0 -0
  317. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/db2/locking_manager.py +0 -0
  318. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/introspection/__init__.py +0 -0
  319. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/parser/__init__.py +0 -0
  320. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/parser/db2_regex_parser.py +0 -0
  321. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/parser/parser_config.py +0 -0
  322. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/plugin.py +0 -0
  323. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/db2/sqlalchemy_url.py +0 -0
  324. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mariadb/__init__.py +0 -0
  325. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mariadb/plugin.py +0 -0
  326. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mariadb/provider.py +0 -0
  327. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mariadb/quirks.py +0 -0
  328. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/__init__.py +0 -0
  329. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/config.py +0 -0
  330. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/introspection/__init__.py +0 -0
  331. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/mysql/__init__.py +0 -0
  332. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/mysql/history_manager.py +0 -0
  333. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/mysql/locking_manager.py +0 -0
  334. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/mysql/schema_operations.py +0 -0
  335. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/parser/__init__.py +0 -0
  336. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
  337. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
  338. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
  339. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/parser/parser_config.py +0 -0
  340. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/plugin.py +0 -0
  341. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/provider.py +0 -0
  342. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/mysql/sqlalchemy_url.py +0 -0
  343. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/__init__.py +0 -0
  344. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/config.py +0 -0
  345. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/introspection/__init__.py +0 -0
  346. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
  347. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/oracle/__init__.py +0 -0
  348. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/oracle/dbms_output.py +0 -0
  349. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/oracle/history_manager.py +0 -0
  350. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/oracle/locking_manager.py +0 -0
  351. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/oracle/schema_operations.py +0 -0
  352. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/__init__.py +0 -0
  353. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/_comments.py +0 -0
  354. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/_object_extractor.py +0 -0
  355. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/_plsql_block.py +0 -0
  356. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/_sqlplus.py +0 -0
  357. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
  358. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_parser.py +0 -0
  359. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
  360. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_tokenizer.py +0 -0
  361. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/parser_config.py +0 -0
  362. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
  363. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/plugin.py +0 -0
  364. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/provider.py +0 -0
  365. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/oracle/sqlalchemy_url.py +0 -0
  366. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/__init__.py +0 -0
  367. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/_provider_query_executor.py +0 -0
  368. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/config.py +0 -0
  369. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/introspection/__init__.py +0 -0
  370. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/parser/__init__.py +0 -0
  371. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/parser/parser_config.py +0 -0
  372. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -0
  373. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
  374. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
  375. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/plugin.py +0 -0
  376. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/postgresql/__init__.py +0 -0
  377. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
  378. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
  379. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/postgresql/schema_operations.py +0 -0
  380. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/provider.py +0 -0
  381. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/postgresql/sqlalchemy_url.py +0 -0
  382. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/__init__.py +0 -0
  383. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/config.py +0 -0
  384. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/introspection/__init__.py +0 -0
  385. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/parser/__init__.py +0 -0
  386. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/parser/parser_config.py +0 -0
  387. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/parser/sqlite_regex_parser.py +0 -0
  388. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/plugin.py +0 -0
  389. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/provider.py +0 -0
  390. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
  391. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/__init__.py +0 -0
  392. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
  393. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
  394. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
  395. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
  396. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
  397. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/__init__.py +0 -0
  398. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/config.py +0 -0
  399. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/introspection/__init__.py +0 -0
  400. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/__init__.py +0 -0
  401. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/parser_config.py +0 -0
  402. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
  403. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
  404. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +0 -0
  405. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
  406. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/plugin.py +0 -0
  407. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/provider.py +0 -0
  408. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
  409. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/history_manager.py +0 -0
  410. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
  411. {dblift-2.2.0 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/schema_operations.py +0 -0
  412. {dblift-2.2.0 → dblift-2.2.1}/db/provider_capabilities.py +0 -0
  413. {dblift-2.2.0 → dblift-2.2.1}/db/provider_interfaces.py +0 -0
  414. {dblift-2.2.0 → dblift-2.2.1}/db/provider_registry.py +0 -0
  415. {dblift-2.2.0 → dblift-2.2.1}/db/sqlalchemy_provider.py +0 -0
  416. {dblift-2.2.0 → dblift-2.2.1}/db/value_utils.py +0 -0
  417. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/dependency_links.txt +0 -0
  418. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/entry_points.txt +0 -0
  419. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/requires.txt +0 -0
  420. {dblift-2.2.0 → dblift-2.2.1}/dblift.egg-info/top_level.txt +0 -0
  421. {dblift-2.2.0 → dblift-2.2.1}/integrations/__init__.py +0 -0
  422. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/__init__.py +0 -0
  423. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/_client.py +0 -0
  424. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/_engine.py +0 -0
  425. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/apps.py +0 -0
  426. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/checks.py +0 -0
  427. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/management/__init__.py +0 -0
  428. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/management/commands/__init__.py +0 -0
  429. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/management/commands/dblift_info.py +0 -0
  430. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/management/commands/dblift_migrate.py +0 -0
  431. {dblift-2.2.0 → dblift-2.2.1}/integrations/django/management/commands/dblift_validate.py +0 -0
  432. {dblift-2.2.0 → dblift-2.2.1}/integrations/fastapi.py +0 -0
  433. {dblift-2.2.0 → dblift-2.2.1}/integrations/flask.py +0 -0
  434. {dblift-2.2.0 → dblift-2.2.1}/integrations/opentelemetry.py +0 -0
  435. {dblift-2.2.0 → dblift-2.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dblift
3
- Version: 2.2.0
3
+ Version: 2.2.1
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
@@ -0,0 +1,16 @@
1
+ """Public API for DBLift library integration.
2
+
3
+ This module provides a clean Python API for using DBLift programmatically,
4
+ enabling integration with IDEs, CI/CD pipelines, and other development tools.
5
+ """
6
+
7
+ from api.client import DBLiftClient
8
+ from api.events import EventEmitter, EventType
9
+ from api.migrations import MigrationContext
10
+
11
+ __all__ = [ # noqa: F822
12
+ "DBLiftClient",
13
+ "EventEmitter",
14
+ "EventType",
15
+ "MigrationContext",
16
+ ]
@@ -1,4 +1,8 @@
1
- """Private operation helpers for OSS :mod:`api.client`."""
1
+ """Private operation helpers for :mod:`api.client`.
2
+
3
+ Keep large operation bodies out of ``DBLiftClient`` so the public client class
4
+ stays readable while preserving the same public methods and behavior.
5
+ """
2
6
 
3
7
  from __future__ import annotations
4
8
 
@@ -19,7 +23,7 @@ def _heuristic_statement_count_from_sql(sql_text: str) -> int:
19
23
 
20
24
 
21
25
  def _apply_sql_script_warning_scan(
22
- result: GenerateUndoScriptResult,
26
+ result: Union[Any, GenerateUndoScriptResult],
23
27
  sql_text: str,
24
28
  ) -> None:
25
29
  """Set manual-review flag and collect per-line warnings from generated SQL text."""
@@ -1,7 +1,6 @@
1
1
  """Main client for programmatic access to DBLift."""
2
2
 
3
3
  from functools import wraps
4
- from importlib import import_module
5
4
  from pathlib import Path
6
5
  from types import TracebackType
7
6
  from typing import (
@@ -25,10 +24,7 @@ from api._client_factory import (
25
24
  normalize_migrations_dirs,
26
25
  resolve_config_or_raise,
27
26
  )
28
- from api._client_operations import (
29
- generate_undo_script_operation,
30
- generate_undo_scripts_operation,
31
- )
27
+ from api._client_operations import generate_undo_script_operation, generate_undo_scripts_operation
32
28
  from api.events import EventEmitter, EventType, use_client_emitter
33
29
  from config import DbliftConfig
34
30
  from core.logger.results import (
@@ -44,6 +40,7 @@ from core.logger.results import (
44
40
  )
45
41
  from core.migration.executor.migration_executor import MigrationExecutor
46
42
  from core.seams.event_listeners import attach_registered_listeners
43
+ from core.seams.feature_loading import load_feature_extensions
47
44
  from db.base_provider import BaseProvider
48
45
  from db.provider_interfaces import ConnectionProvider, TransactionalProvider
49
46
 
@@ -119,6 +116,13 @@ class DBLiftClient:
119
116
  log_file: Optional log file path; omit to keep ``config`` values
120
117
  **kwargs: Additional configuration options
121
118
  """
119
+ # Feature registrations from installed add-on packages must load for
120
+ # every client construction path, not just CLI startup — otherwise the
121
+ # runtime-check and tier-resolver seams would silently no-op for
122
+ # API-only usage. Idempotent (module-level once-flag), so double-loading
123
+ # with the CLI's own call is harmless.
124
+ load_feature_extensions()
125
+
122
126
  # Resolve config before logger so defaults come from merged config (e.g. from file).
123
127
  config = resolve_config_or_raise(provider, config)
124
128
 
@@ -35,15 +35,37 @@ _SUBCOMMAND_BOOLEAN_FLAGS = frozenset(
35
35
  "--clean-disabled",
36
36
  "--clean-enabled",
37
37
  "--dry-run",
38
+ "--generate-sql",
39
+ "--ignore-unmanaged",
40
+ "--include-drops",
41
+ "--keep-container",
42
+ "--managed-only",
38
43
  "--mark-as-executed",
44
+ "--no-performance",
39
45
  "--show-sql",
46
+ "--rehearse-rollback",
47
+ "--skip-replay",
40
48
  "--skip-validation",
49
+ "--skip-validate-sql",
50
+ "--split-by-type",
41
51
  "--strict",
52
+ "--unmanaged-only",
42
53
  "--validate-only",
43
54
  }
44
55
  )
45
56
 
46
57
 
58
+ def _command_handler_attr(command: Optional[str], attr_name: str, default: Any = None) -> Any:
59
+ if not command:
60
+ return default
61
+ from cli._command_handlers import _COMMAND_HANDLERS
62
+
63
+ handler = _COMMAND_HANDLERS.get(command)
64
+ if handler is None:
65
+ return default
66
+ return getattr(handler, attr_name, default)
67
+
68
+
47
69
  def _extract_commands_from_argv(
48
70
  argv_list: List[str],
49
71
  available_commands: List[str],
@@ -257,16 +279,21 @@ def _load_and_merge_config(args: argparse.Namespace, log: Any) -> Any:
257
279
  db_overrides["schema"] = args.database_schema
258
280
 
259
281
  if db_overrides:
260
- # Resolve secret URIs in CLI overrides.
261
- from config.secrets._resolver import resolve_secret_refs
282
+ command = getattr(args, "command", None)
283
+ commands_list = getattr(args, "commands_list", None) or ([command] if command else [])
284
+ is_offline = len(commands_list) == 1 and bool(
285
+ _command_handler_attr(command, "_dblift_skip_secret_resolution", False)
286
+ )
287
+ if not is_offline:
288
+ from config.secrets._resolver import resolve_secret_refs
262
289
 
263
- try:
264
- db_overrides = resolve_secret_refs({"database": db_overrides}, config.secrets).get(
265
- "database", db_overrides
266
- )
267
- except SecretsResolutionError as e:
268
- print(f"Error: {e}", file=sys.stderr)
269
- sys.exit(1)
290
+ try:
291
+ db_overrides = resolve_secret_refs({"database": db_overrides}, config.secrets).get(
292
+ "database", db_overrides
293
+ )
294
+ except SecretsResolutionError as e:
295
+ print(f"Error: {e}", file=sys.stderr)
296
+ sys.exit(1)
270
297
  config.database = ConfigBuilder.merge_database_overrides(config.database, db_overrides)
271
298
 
272
299
  if log:
@@ -321,7 +348,7 @@ def _validate_db_config(
321
348
  if commands and commands[0] == "db":
322
349
  return
323
350
 
324
- migration_commands = [
351
+ migration_commands = {
325
352
  "migrate",
326
353
  "undo",
327
354
  "clean",
@@ -330,7 +357,9 @@ def _validate_db_config(
330
357
  "repair",
331
358
  "import-flyway",
332
359
  "baseline",
333
- ]
360
+ }
361
+ if _command_handler_attr(args.command, "_dblift_validate_db_config", False):
362
+ migration_commands.add(args.command)
334
363
  if args.command not in migration_commands:
335
364
  return
336
365
 
@@ -13,7 +13,8 @@ dispatch in ``cli/main.py`` re-derive the same predicate:
13
13
  else:
14
14
  ctx.log.info(payload) # routed through ConsoleLog
15
15
 
16
- That duplication has already caused banner-routing regressions. ADR-0005 added the
16
+ That duplication has already caused two regressions (PR 158 banner fix
17
+ + PR-01 machine-format scope). ADR-0005 added the
17
18
  `MACHINE_READABLE_FORMATS` set as a single source of truth; this
18
19
  module does the same for the *routing* decision itself.
19
20
 
@@ -116,6 +116,8 @@ def _add_registry_flags(parser: argparse.ArgumentParser) -> None:
116
116
  """
117
117
  from config.property_registry import PROPERTY_REGISTRY
118
118
 
119
+ deferred_specs = {"max_snapshots", "snapshot_table"}
120
+
119
121
  # Collect option strings across the WHOLE tree (root + every subparser), not
120
122
  # just the root parser. Many registry properties (e.g. --tags,
121
123
  # --target-version, --snapshot-table) intentionally live only on specific
@@ -137,6 +139,8 @@ def _add_registry_flags(parser: argparse.ArgumentParser) -> None:
137
139
  for spec in PROPERTY_REGISTRY:
138
140
  if spec.cli_only or spec.cli_exempt or "." in spec.name:
139
141
  continue
142
+ if spec.name in deferred_specs:
143
+ continue
140
144
  if spec.cli_aliases:
141
145
  continue # legacy flag (e.g. --table, --strict) already provides the surface
142
146
  if spec.cli in existing:
@@ -202,7 +206,7 @@ def _make_filter_parent() -> argparse.ArgumentParser:
202
206
 
203
207
  # NOTE: ``--target-version`` is intentionally NOT extracted into a parent
204
208
  # parser. Its help text is genuinely command-specific (migrate / undo /
205
- # diff each describe a different intent) and unifying it would degrade
209
+ # validate each describe a different intent) and unifying it would degrade
206
210
  # `--help` output. Each subparser adds it explicitly in
207
211
  # ``_add_diff_and_target_options`` so the user-facing string stays
208
212
  # accurate. See Bugbot review on PR-09.
@@ -232,13 +236,12 @@ def _add_baseline_options(baseline_parser: argparse.ArgumentParser) -> None:
232
236
 
233
237
 
234
238
  def _add_diff_and_target_options(
235
- diff_parser: argparse.ArgumentParser | None,
236
239
  migrate_parser: argparse.ArgumentParser,
237
240
  undo_parser: argparse.ArgumentParser,
238
241
  validate_parser: argparse.ArgumentParser,
239
242
  clean_parser: argparse.ArgumentParser,
240
243
  ) -> None:
241
- """Configure diff/migrate/undo/validate/clean subcommand-specific options.
244
+ """Configure migrate/undo/validate/clean subcommand-specific options.
242
245
 
243
246
  ``--target-version`` is added per-command (rather than via a shared
244
247
  parent parser) because each command has a meaningfully different
@@ -290,6 +293,21 @@ def _add_diff_and_target_options(
290
293
  )
291
294
 
292
295
 
296
+ def _register_builtin_command_parsers(
297
+ parser: argparse.ArgumentParser,
298
+ ) -> list[argparse.ArgumentParser]:
299
+ """Register first-party command parsers that remain in the OSS CLI."""
300
+ subparser_actions = [
301
+ action for action in parser._actions if isinstance(action, argparse._SubParsersAction)
302
+ ]
303
+ if not subparser_actions:
304
+ return []
305
+
306
+ registered: list[argparse.ArgumentParser] = []
307
+
308
+ return registered
309
+
310
+
293
311
  def create_parser(
294
312
  exit_on_error: bool = True, suppress_errors: bool = False
295
313
  ) -> argparse.ArgumentParser:
@@ -441,10 +459,10 @@ def create_parser(
441
459
  default="flyway_schema_history",
442
460
  help="Source Flyway schema history table name (default: flyway_schema_history)",
443
461
  )
444
- builtin_extension_parsers: list[argparse.ArgumentParser] = []
462
+ builtin_extension_parsers = _register_builtin_command_parsers(parser)
445
463
  # Configure arguments via extracted functions
446
464
  _add_baseline_options(baseline_parser)
447
- _add_diff_and_target_options(None, migrate_parser, undo_parser, validate_parser, clean_parser)
465
+ _add_diff_and_target_options(migrate_parser, undo_parser, validate_parser, clean_parser)
448
466
  # info --format option (JSON output for scripting)
449
467
  info_parser.add_argument(
450
468
  "--format",
@@ -12,11 +12,9 @@ from dataclasses import dataclass, field
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict, List, Optional
14
14
 
15
- from core.features import FeatureTier
16
-
17
- # Flyway-compatible migration filename patterns used to skip non-migration
18
- # SQL files when scanning a directory (e.g. leftover temp files, schema
19
- # dumps) so only intentional migration scripts are
15
+ # Flyway-compatible migration filename patterns — used by SQL-file validation to
16
+ # skip non-migration SQL files when scanning a directory (e.g. leftover
17
+ # temp files, schema dumps) so only intentional migration scripts are
20
18
  # checked. Explicitly-listed files are always validated regardless of name.
21
19
  _MIGRATION_FILENAME_RE = re.compile(
22
20
  r"^[VRUBvrub][\d_.]*__.*\.sql$",
@@ -61,9 +59,21 @@ class CliCommandContext:
61
59
  # Migration configuration
62
60
  placeholders: Dict[str, Any] = field(default_factory=dict)
63
61
  dir_recursive_map: Dict[Path, bool] = field(default_factory=dict)
64
- # License tier for feature-level gates. execute_single_command supplies
65
- # the real CLI-resolved tier; the default keeps direct handler tests terse.
66
- license_tier: FeatureTier = FeatureTier.ENTERPRISE
62
+ # License tier for feature-level gates. Opaque to OSS (see
63
+ # core.seams.tier_resolver) execute_single_command supplies the real
64
+ # CLI-resolved tier; paid-tier handler tests must pass their own tier
65
+ # explicitly since OSS no longer has a permissive default to fall back on.
66
+ license_tier: Any = None
67
+
68
+
69
+ @dataclass
70
+ class ConfigOnlyClient:
71
+ """Config-only stand-in for commands that do not need a live provider."""
72
+
73
+ config: Any
74
+
75
+
76
+ ValidateSqlConfigClient = ConfigOnlyClient
67
77
 
68
78
 
69
79
  def _set_command_completed(log: Any, result: Any, command_type: str) -> None:
@@ -92,7 +102,7 @@ def emit_rendered_output(
92
102
  ) -> None:
93
103
  """Dispatch a rendered command output to machine channel, logger, and/or file.
94
104
 
95
- Used by command handlers that follow the same machine/human/file
105
+ Shared by extension report handlers that follow the same machine/human/file
96
106
  dispatch pattern once the command-specific rendering is done.
97
107
  """
98
108
  if command_output.is_machine_format:
@@ -111,7 +121,7 @@ def emit_rendered_output(
111
121
 
112
122
 
113
123
  def _extract_version_filters(args: Any) -> tuple[Any, Any, Any, Any, Any]:
114
- """Extract version/tag filter arguments common to migrate, undo, validate, info, diff handlers.
124
+ """Extract version/tag filter arguments common to filtered migration handlers.
115
125
 
116
126
  Returns:
117
127
  Tuple (target_version, versions, exclude_versions, tags, exclude_tags),
@@ -50,13 +50,9 @@ from cli._config_helpers import ( # noqa: F401
50
50
  _validate_log_format_for_cli,
51
51
  )
52
52
  from cli._output import CommandOutput, from_args
53
- from cli._parser_setup import ( # noqa: F401
54
- _add_baseline_options,
55
- _add_diff_and_target_options,
56
- create_parser,
57
- parse_with_selective_errors,
58
- )
53
+ from cli._parser_setup import create_parser, parse_with_selective_errors
59
54
  from cli.extensions import load_terminal_commands
55
+ from core.seams.feature_loading import load_feature_extensions
60
56
 
61
57
  # Module-level placeholder; main() uses a local 'log' variable (no global declaration)
62
58
  log = None
@@ -102,16 +98,13 @@ _GLOBAL_ONLY_ARGS: List[str] = [
102
98
  "--quiet",
103
99
  "-q",
104
100
  "--no-progress",
105
- # Root-only value flags surfaced from the PropertySpec registry
106
- # (installed_by is added directly; max_snapshots is generated by
107
- # _add_registry_flags). They live only on the root parser, so — like the
101
+ # Root-only value flags. They live only on the root parser, so — like the
108
102
  # other root-only value flags above — they must be classified global or the
109
103
  # argv preprocessor relocates them past the subcommand token and the
110
104
  # subparser rejects them as "unrecognized arguments". Covered by
111
105
  # tests/unit/cli/test_global_only_args_completeness.py.
112
106
  "--installed-by",
113
107
  "--max-snapshots",
114
- "--snapshot-table",
115
108
  ]
116
109
 
117
110
  # Tool-level flag aliases for subcommands that take their own version-like
@@ -164,6 +157,7 @@ def main() -> None:
164
157
  from core.logger.console import install_rich_traceback
165
158
 
166
159
  install_rich_traceback()
160
+ load_feature_extensions()
167
161
 
168
162
  ctx = _parse_argv_and_load_config(sys.argv[1:])
169
163
  command_output = _setup_logging_and_output(ctx)
@@ -251,7 +245,8 @@ def _parse_argv_and_load_config(argv: List[str]) -> _CliContext:
251
245
  # Validate log format before any config load so bogus --log-format fails with argparse
252
246
  # UX (and so db/* commands are covered — _validate_db_config skips early for "db").
253
247
  _validate_log_format_for_cli(args, parser)
254
- # Attach the full command list so load_config can see chained invocations.
248
+ # Attach the full command list so config loading can distinguish
249
+ # single-command config-only flows from chained invocations.
255
250
  args.commands_list = commands
256
251
  config = None if commands[0] == "db" else _load_and_merge_config(args, log)
257
252
  _validate_db_config(args, config, parser, commands)
@@ -277,6 +272,15 @@ def _build_terminal_args(
277
272
  return args
278
273
 
279
274
 
275
+ def _command_handler_attr(command: Optional[str], attr_name: str, default: Any = None) -> Any:
276
+ if not command:
277
+ return default
278
+ handler = _COMMAND_HANDLERS.get(command)
279
+ if handler is None:
280
+ return default
281
+ return getattr(handler, attr_name, default)
282
+
283
+
280
284
  def _setup_logging_and_output(ctx: _CliContext) -> CommandOutput:
281
285
  """Phase 3: configure logging, build :class:`CommandOutput`.
282
286
 
@@ -306,12 +310,26 @@ def _setup_logging_and_output(ctx: _CliContext) -> CommandOutput:
306
310
  assert ctx.config is not None
307
311
  ctx.log = _configure_logging(ctx.args, ctx.config, ctx.parser)
308
312
 
313
+ _apply_configured_output_format(ctx)
314
+
309
315
  # Banner routing is centralised in :class:`cli._output.CommandOutput`
310
316
  # (ADR-0008 supersedes ADR-0005's suppression approach). Machine
311
317
  # mode routes the banner to stderr; human mode keeps it on stdout.
312
318
  return from_args(ctx.args)
313
319
 
314
320
 
321
+ def _apply_configured_output_format(ctx: _CliContext) -> None:
322
+ """Use handler-provided config defaults before top-level banner routing."""
323
+ if len(ctx.commands) != 1 or getattr(ctx.args, "format", None):
324
+ return
325
+ resolver = _command_handler_attr(ctx.commands[0], "_dblift_configured_output_format")
326
+ if not callable(resolver):
327
+ return
328
+ output_format = resolver(ctx.args, ctx.config)
329
+ if output_format:
330
+ ctx.args.format = output_format
331
+
332
+
315
333
  def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
316
334
  """Phase 4: build full workflow context and run the command loop.
317
335
 
@@ -362,6 +380,13 @@ def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
362
380
  # in base_command does not re-emit it (it also has no format awareness).
363
381
  if main_header:
364
382
  base_command._console_main_header_printed = True # type: ignore[attr-defined]
383
+ for command in ctx.commands:
384
+ handler = _COMMAND_HANDLERS.get(command)
385
+ if handler is None:
386
+ continue
387
+ command_module = sys.modules.get(handler.__module__)
388
+ if command_module is not None:
389
+ command_module._console_main_header_printed = True # type: ignore[attr-defined]
365
390
 
366
391
  for cmd_index, command in enumerate(ctx.commands):
367
392
  if len(ctx.commands) > 1 and cmd_index > 0:
@@ -199,9 +199,9 @@ def _apply_url_overrides(cls: Type["BaseDatabaseConfig"], data: Dict[str, Any])
199
199
  if url_lower.startswith("jdbc:"):
200
200
  raise ValueError("Legacy database URLs are no longer supported; use a SQLAlchemy URL")
201
201
  # _allow_incomplete is set when the URL could not be parsed (e.g. an
202
- # unresolved secret URI in offline mode). Skip hydration/inference so
203
- # an unresolved secret URI doesn't mutate fields before a connection
204
- # is opened.
202
+ # unresolved secret URI in offline mode). Skip hydration/inference so that
203
+ # `dblift plan` with `database.url: vault://...` doesn't mutate fields from
204
+ # the secret URI before a connection is opened.
205
205
  if data.get("_allow_incomplete"):
206
206
  return
207
207
  if ProviderRegistry.is_native_dialect(db_type):
@@ -25,6 +25,56 @@ _CONFIG_LOAD_EXC: Tuple[Type[Exception], ...] = (
25
25
  AttributeError,
26
26
  IndexError,
27
27
  )
28
+ _PAID_RAW_CONFIG_KEYS: Tuple[str, ...] = ("data_sets", "datasets", "validation")
29
+
30
+
31
+ # ``validate-sql`` only needs a dialect-typed DbliftConfig; connection is never opened.
32
+ # Placeholder database URLs satisfy :meth:`DbliftConfig.validate_complete_data` and are never
33
+ # used to connect in the validate-sql code path.
34
+ def _validate_sql_lint_filler(dialect: str) -> Dict[str, Any]:
35
+ """Minimal ``database:`` block for validate-sql (lint-only) when no real DB is configured.
36
+
37
+ Story 26-11: dialect normalisation + placeholder URL come from the
38
+ plugin registry / quirks. The earlier hardcoded
39
+ ``_VALIDATE_SQL_DIALECT_TO_DB``, ``_VALIDATE_SQL_PLACEHOLDER_URL``,
40
+ and ``_VALIDATE_SQL_DB_TO_DIALECT`` dicts are gone; adding a new
41
+ dialect with offline-lint support = override
42
+ ``lint_placeholder_url`` in its plugin quirks.py.
43
+ """
44
+ from db.provider_registry import ProviderRegistry
45
+
46
+ db_type = ProviderRegistry.canonical_dialect_name((dialect or "").strip().lower())
47
+ if not db_type:
48
+ return {}
49
+ quirks = ProviderRegistry.get_quirks(db_type)
50
+ placeholder = quirks.lint_placeholder_url
51
+ if not placeholder:
52
+ return {}
53
+ return {
54
+ "database": {
55
+ "type": db_type,
56
+ "url": placeholder,
57
+ "username": "dblift_validate_sql",
58
+ "password": "dblift_validate_sql",
59
+ }
60
+ }
61
+
62
+
63
+ def _validate_sql_effective_dialect(args: Any, config_data: Dict[str, Any]) -> Optional[str]:
64
+ """Resolve validate-sql dialect from CLI or config without defaulting."""
65
+ cli_dialect = getattr(args, "dialect", None)
66
+ if isinstance(cli_dialect, str) and cli_dialect.strip():
67
+ return cli_dialect.strip().lower()
68
+
69
+ database_config = config_data.get("database")
70
+ if isinstance(database_config, dict):
71
+ from db.provider_registry import ProviderRegistry
72
+
73
+ db_type = str(database_config.get("type") or "").strip().lower()
74
+ if db_type:
75
+ return ProviderRegistry.canonical_dialect_name(db_type) or db_type
76
+
77
+ return None
28
78
 
29
79
 
30
80
  def _placeholder_tokens(raw_placeholders: Any) -> List[str]:
@@ -79,6 +129,15 @@ def _resolve_env_placeholders(data: Any) -> Any:
79
129
  return data
80
130
 
81
131
 
132
+ def _extract_paid_raw_config(data: Dict[str, Any]) -> Dict[str, Any]:
133
+ paid_raw: Dict[str, Any] = {}
134
+ for key in _PAID_RAW_CONFIG_KEYS:
135
+ value = data.get(key)
136
+ if value is not None:
137
+ paid_raw[key] = value
138
+ return paid_raw
139
+
140
+
82
141
  def load_config(config_file_path: Optional[str], args: Optional[Any] = None) -> "DbliftConfig":
83
142
  """
84
143
  Load configuration from a file and override with command line arguments
@@ -119,13 +178,33 @@ def load_config(config_file_path: Optional[str], args: Optional[Any] = None) ->
119
178
  if args_dict:
120
179
  config_data = DbliftConfig.merge_config_data(config_data, args_dict)
121
180
 
181
+ # ``validate-sql`` does not need a real database, but static linting does
182
+ # need an explicit SQL dialect or a database type from config.
183
+ if args and getattr(args, "command", None) == "validate-sql":
184
+ dialect = _validate_sql_effective_dialect(args, config_data)
185
+ if not dialect:
186
+ raise ConfigurationError(
187
+ "validate-sql requires --dialect for offline validation when no database type is configured."
188
+ )
189
+ filler = _validate_sql_lint_filler(dialect)
190
+ if filler:
191
+ config_data = DbliftConfig.merge_config_data(filler, config_data)
192
+
122
193
  if not config_data:
123
194
  raise ConfigurationError(
124
195
  "No configuration source provided. Pass --config, --db-url, or set DBLIFT_DB_URL."
125
196
  )
126
197
 
127
- is_offline_cmd = False
198
+ command = getattr(args, "command", None) if args else None
199
+ commands_list = getattr(args, "commands_list", None) if args else None
200
+ if commands_list is None and command:
201
+ commands_list = [command]
202
+ is_offline_cmd = bool(
203
+ command in ("validate-sql", "plan") and commands_list and len(commands_list) == 1
204
+ )
128
205
  config = DbliftConfig.from_dict(config_data, resolve_secrets=not is_offline_cmd)
206
+ if config_file_path:
207
+ setattr(config, "_config_file_path", config_file_path)
129
208
  if args:
130
209
  installed_by = getattr(args, "installed_by", None)
131
210
  if installed_by:
@@ -431,13 +510,14 @@ class DbliftConfig:
431
510
  Args:
432
511
  data: Configuration dictionary
433
512
  resolve_secrets: When False, skip secret-URI resolution (used for
434
- offline commands that never open a DB connection and must not
435
- require secret-manager credentials to be available).
513
+ offline commands such as static SQL lint that never open a DB connection
514
+ and must not require secret-manager credentials to be available).
436
515
 
437
516
  Returns:
438
517
  A DbliftConfig instance
439
518
  """
440
519
  data = _resolve_env_placeholders(data or {})
520
+ paid_raw_config = _extract_paid_raw_config(data)
441
521
 
442
522
  if resolve_secrets:
443
523
  # Two-phase secret resolution:
@@ -483,7 +563,7 @@ class DbliftConfig:
483
563
  # Non-secret unparseable URLs are left as-is so _apply_url_overrides
484
564
  # raises a focused URL error immediately rather than producing a
485
565
  # silently broken config.
486
- # When secrets are not resolved (offline commands),
566
+ # When secrets are not resolved (offline commands like plan/validate-sql),
487
567
  # a secret URI in database.url must not be validated as a database URL — the
488
568
  # type may already be known from database.type but the URL is still raw.
489
569
  # This covers the case where database.type is set explicitly, which skips
@@ -614,6 +694,8 @@ class DbliftConfig:
614
694
  secrets=secrets_config,
615
695
  )
616
696
  config.log_dir = root_log_dir
697
+ if paid_raw_config:
698
+ setattr(config, "_paid_config_data", paid_raw_config)
617
699
  return config
618
700
 
619
701
  @staticmethod
@@ -922,7 +1004,9 @@ class DbliftConfig:
922
1004
  config_data = _resolve_env_placeholders(config_data)
923
1005
  if not config_data:
924
1006
  raise yaml.YAMLError("Empty or invalid YAML file")
925
- return cls.from_dict(config_data)
1007
+ config = cls.from_dict(config_data)
1008
+ setattr(config, "_config_file_path", str(config_file))
1009
+ return config
926
1010
  except FileNotFoundError:
927
1011
  raise FileNotFoundError(f"Config file not found: {config_file}")
928
1012
  except yaml.YAMLError as e:
@@ -1,12 +1,13 @@
1
1
  """Provider class registry — maps URI schemes to provider classes."""
2
2
 
3
- from importlib import import_module
4
3
  from importlib.metadata import entry_points
5
4
  from typing import Dict, Optional, Set, Type
6
5
 
7
6
  # Fixed set of known schemes — used for fast URI detection without requiring
8
7
  # providers to be registered first (avoids import-order sensitivity).
9
- KNOWN_SCHEMES: frozenset = frozenset()
8
+ KNOWN_SCHEMES: frozenset = frozenset(
9
+ ["vault", "aws-secrets", "aws-ssm", "azure-keyvault", "gcp-secrets"]
10
+ )
10
11
 
11
12
  # Populated by providers/__init__.py at import time.
12
13
  _providers: Dict[str, Type] = {}
@@ -56,7 +56,11 @@ override only the deltas.
56
56
  from __future__ import annotations
57
57
 
58
58
  import re
59
- from typing import Any, Optional, Protocol, runtime_checkable
59
+ from typing import TYPE_CHECKING, Any, Optional, Protocol, Type, runtime_checkable
60
+
61
+ if TYPE_CHECKING:
62
+ from core.sql_generator.alter.base_alter_generator import BaseAlterGenerator
63
+ from core.sql_generator.base_generator import BaseSqlGenerator
60
64
 
61
65
 
62
66
  @runtime_checkable
@@ -65,13 +69,14 @@ class DdlQuirks(Protocol):
65
69
 
66
70
  First hooks (story 26-3 first slice): the DDL generator class and
67
71
  the ALTER generator class for this dialect. Returning ``None``
68
- means no dialect-specific SQL renderer is available in OSS.
72
+ means the framework falls back to the dialect-agnostic
73
+ :class:`core.sql_generator.sql_generator.SqlGenerator`.
69
74
  """
70
75
 
71
- def ddl_generator_class(self) -> Optional[type[Any]]:
76
+ def ddl_generator_class(self) -> Optional[Type["BaseSqlGenerator"]]:
72
77
  """Return the dialect-specific DDL generator class, or ``None``."""
73
78
 
74
- def alter_generator_class(self) -> Optional[type[Any]]:
79
+ def alter_generator_class(self) -> Optional[Type["BaseAlterGenerator"]]:
75
80
  """Return the dialect-specific ALTER generator class, or ``None``."""
76
81
 
77
82
  def render_drop_for_object(
@@ -1,8 +1,6 @@
1
1
  """Core ``OutputFormatter`` implementation (non-diff format methods + orchestrator).
2
2
 
3
- The text-diff section helpers live in the ``_format_diff_*.py`` sibling
4
- modules and are mixed in here. The public ``formatter`` façade re-exports
5
- ``OutputFormatter`` so existing imports
3
+ The public ``formatter`` façade re-exports ``OutputFormatter`` so existing imports
6
4
  (``from core.logger.formatters.formatter import OutputFormatter``) keep
7
5
  working unchanged.
8
6