quadkit-sql 0.0.42__tar.gz → 0.0.44__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 (442) hide show
  1. quadkit_sql-0.0.44/.gitignore +24 -0
  2. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/PKG-INFO +1 -1
  3. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/pyproject.toml +1 -7
  4. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/audit_store.py +1 -1
  5. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/seeder.py +1 -1
  6. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/type_map.py +1 -1
  7. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/database_repository.py.jinja2 +5 -4
  8. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/entity_model.py.jinja2 +3 -6
  9. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/seeder.py.jinja2 +3 -3
  10. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/di/_registration.py +2 -2
  11. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/di/provider.py +1 -1
  12. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/manager/_alembic.py +36 -7
  13. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/orchestrator.py +1 -1
  14. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/database_service.py +1 -1
  15. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/builder.py +1 -1
  16. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/resilience/__init__.py +1 -1
  17. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/resilience/core.py +7 -7
  18. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/conftest.py +6 -6
  19. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_migrations.py +14 -0
  20. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/backends/test_cockroachdb_backend.py +11 -0
  21. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/backends/test_postgres_connection.py +3 -0
  22. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_entity_model_generator.py +1 -1
  23. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_type_map.py +2 -2
  24. quadkit_sql-0.0.44/tests/unit/migrations/test_alembic_config_path_separator.py +107 -0
  25. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mysql_backend_scenario.py +8 -5
  26. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_round25_hardening.py +1 -0
  27. quadkit_sql-0.0.42/.gitignore +0 -214
  28. quadkit_sql-0.0.42/docs/ARCHITECTURE.md +0 -337
  29. quadkit_sql-0.0.42/docs/BACKENDS.md +0 -151
  30. quadkit_sql-0.0.42/docs/CONFIGURATION.md +0 -169
  31. quadkit_sql-0.0.42/docs/GUIDE.md +0 -288
  32. quadkit_sql-0.0.42/docs/HOWTOS.md +0 -208
  33. quadkit_sql-0.0.42/docs/QUICKSTART.md +0 -77
  34. quadkit_sql-0.0.42/docs/TROUBLESHOOTING.md +0 -155
  35. quadkit_sql-0.0.42/tests/unit/test_db_search_backends.py +0 -350
  36. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/LICENSE +0 -0
  37. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/NOTICE +0 -0
  38. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/README.md +0 -0
  39. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/alembic.ini +0 -0
  40. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/example.yaml +0 -0
  41. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/py.typed +0 -0
  42. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/__init__.py +0 -0
  43. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/abstractions/__init__.py +0 -0
  44. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/abstractions/connection.py +0 -0
  45. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/abstractions/py.typed +0 -0
  46. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/__init__.py +0 -0
  47. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/contributor.py +0 -0
  48. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/handlers/__init__.py +0 -0
  49. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/handlers/migration_status.py +0 -0
  50. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/handlers/pool_utilization.py +0 -0
  51. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/handlers/query_stats.py +0 -0
  52. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/pages/__init__.py +0 -0
  53. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/pages/migrations.py +0 -0
  54. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/pages/overview.py +0 -0
  55. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/pages/queries.py +0 -0
  56. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/admin/widgets/__init__.py +0 -0
  57. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/api/__init__.py +0 -0
  58. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/api/engine.py +0 -0
  59. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/api/protocols.py +0 -0
  60. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/audit/__init__.py +0 -0
  61. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/audit/mixin.py +0 -0
  62. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/audit/py.typed +0 -0
  63. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/__init__.py +0 -0
  64. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/_postgres_connection.py +0 -0
  65. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/_ssl.py +0 -0
  66. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/cockroachdb.py +0 -0
  67. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/mysql/__init__.py +0 -0
  68. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/mysql/_connection.py +0 -0
  69. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/mysql/_pool.py +0 -0
  70. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/mysql/_shims.py +0 -0
  71. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/postgres.py +0 -0
  72. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/py.typed +0 -0
  73. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/sqlite/__init__.py +0 -0
  74. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/sqlite/_connection.py +0 -0
  75. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/sqlite/_pool.py +0 -0
  76. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backends/sqlite/_shims.py +0 -0
  77. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backup/__init__.py +0 -0
  78. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backup/backup_manager.py +0 -0
  79. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backup/maintenance.py +0 -0
  80. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/backup/py.typed +0 -0
  81. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/__init__.py +0 -0
  82. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/checks.py +0 -0
  83. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/commands.py +0 -0
  84. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/contributor.py +0 -0
  85. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/doctor.py +0 -0
  86. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/__init__.py +0 -0
  87. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/base.py +0 -0
  88. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/database_repository.py +0 -0
  89. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/entity_migration.py +0 -0
  90. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/entity_model.py +0 -0
  91. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/filter.py +0 -0
  92. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/health_check.py +0 -0
  93. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/generators/service.py +0 -0
  94. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/manager.py +0 -0
  95. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/shell.py +0 -0
  96. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/entity_migration.py.jinja2 +0 -0
  97. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/filter.py.jinja2 +0 -0
  98. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/health_check.py.jinja2 +0 -0
  99. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/cli/templates/service.py.jinja2 +0 -0
  100. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/config.py +0 -0
  101. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/constants.py +0 -0
  102. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/context/__init__.py +0 -0
  103. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/context/db_context.py +0 -0
  104. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/context/keys.py +0 -0
  105. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/context/manager.py +0 -0
  106. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/context/tasks.py +0 -0
  107. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/decorators.py +0 -0
  108. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/di/__init__.py +0 -0
  109. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/di/py.typed +0 -0
  110. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/events.py +0 -0
  111. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/exceptions.py +0 -0
  112. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/hooks.py +0 -0
  113. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/identifiers.py +0 -0
  114. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/lib/__init__.py +0 -0
  115. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/lib/helpers.py +0 -0
  116. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/lib/retry.py +0 -0
  117. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/logging/__init__.py +0 -0
  118. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/logging/loggers.py +0 -0
  119. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/managers/__init__.py +0 -0
  120. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/managers/manager.py +0 -0
  121. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/mappers/__init__.py +0 -0
  122. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/mappers/base.py +0 -0
  123. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/mappers/domain_mapper.py +0 -0
  124. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/mappers/py.typed +0 -0
  125. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/middleware/__init__.py +0 -0
  126. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/middleware/base.py +0 -0
  127. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/middleware/builtins.py +0 -0
  128. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/middleware/models.py +0 -0
  129. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/middleware/pipeline.py +0 -0
  130. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/__init__.py +0 -0
  131. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/api.py +0 -0
  132. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/base.py +0 -0
  133. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/engine.py +0 -0
  134. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/generator.py +0 -0
  135. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/introspector.py +0 -0
  136. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/manager/__init__.py +0 -0
  137. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/manager/_simple.py +0 -0
  138. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/model_analyzer.py +0 -0
  139. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/py.typed +0 -0
  140. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/runner.py +0 -0
  141. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/migrations/types.py +0 -0
  142. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/module.py +0 -0
  143. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/__init__.py +0 -0
  144. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/__init__.py +0 -0
  145. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/facade.py +0 -0
  146. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/health.py +0 -0
  147. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/pool.py +0 -0
  148. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/query.py +0 -0
  149. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/database_monitor/transaction.py +0 -0
  150. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/metrics.py +0 -0
  151. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/py.typed +0 -0
  152. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/monitoring/query_analyzer.py +0 -0
  153. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/orm.pyi +0 -0
  154. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/outbox/__init__.py +0 -0
  155. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/outbox/publisher.py +0 -0
  156. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/outbox/store.py +0 -0
  157. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pagination/__init__.py +0 -0
  158. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pagination/cursor.py +0 -0
  159. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pagination/offset.py +0 -0
  160. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/performance/__init__.py +0 -0
  161. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/performance/batch_processor.py +0 -0
  162. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/performance/engine_pragmas.py +0 -0
  163. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/performance/statement_cache.py +0 -0
  164. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pool/__init__.py +0 -0
  165. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pool/connection.py +0 -0
  166. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pool/py.typed +0 -0
  167. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/pool/replica.py +0 -0
  168. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/protocols.py +0 -0
  169. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/__init__.py +0 -0
  170. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/_connection_mixin.py +0 -0
  171. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/_health_mixin.py +0 -0
  172. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/_lazy.py +0 -0
  173. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/_query_mixin.py +0 -0
  174. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/base_provider.py +0 -0
  175. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/connection_manager.py +0 -0
  176. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/crud_operations.py +0 -0
  177. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/health_monitor.py +0 -0
  178. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/mysql_provider.py +0 -0
  179. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/postgres_provider.py +0 -0
  180. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/py.typed +0 -0
  181. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/query_builder_manager.py +0 -0
  182. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/query_executor.py +0 -0
  183. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/schema_manager.py +0 -0
  184. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/sqlite_provider.py +0 -0
  185. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/providers/transaction_manager.py +0 -0
  186. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/py.typed +0 -0
  187. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/__init__.py +0 -0
  188. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/_sql_build_mixin.py +0 -0
  189. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/_sql_core_mixin.py +0 -0
  190. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/_sql_join_aggregate_mixin.py +0 -0
  191. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/_sql_where_mixin.py +0 -0
  192. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/admin_builder.py +0 -0
  193. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/compiler.py +0 -0
  194. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/cursor.py +0 -0
  195. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/operators.py +0 -0
  196. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/sql_builder.py +0 -0
  197. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/query/sql_types.py +0 -0
  198. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/__init__.py +0 -0
  199. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/_advanced_mixin.py +0 -0
  200. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/_filter_mixin.py +0 -0
  201. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/_read_mixin.py +0 -0
  202. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/_rls_mixin.py +0 -0
  203. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/_write_mixin.py +0 -0
  204. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/append_log.py +0 -0
  205. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/base.py +0 -0
  206. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/cached.py +0 -0
  207. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/cursor.py +0 -0
  208. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/decorators.py +0 -0
  209. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/filter_objects.py +0 -0
  210. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/filters.py +0 -0
  211. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/generic_repository.py +0 -0
  212. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/py.typed +0 -0
  213. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/repositories/scopes.py +0 -0
  214. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/row_level_security.py +0 -0
  215. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/schema/__init__.py +0 -0
  216. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/schema/descriptors.py +0 -0
  217. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/schema/field_types.py +0 -0
  218. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/schema/hooks.py +0 -0
  219. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/schema/model.py +0 -0
  220. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/search/__init__.py +0 -0
  221. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/search/full_text.py +0 -0
  222. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/seeds/__init__.py +0 -0
  223. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/seeds/api.py +0 -0
  224. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/seeds/factory.py +0 -0
  225. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/seeds/manager.py +0 -0
  226. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/seeds/py.typed +0 -0
  227. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/specification/__init__.py +0 -0
  228. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/specification/memory.py +0 -0
  229. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/specification/sql.py +0 -0
  230. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/storage/__init__.py +0 -0
  231. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/storage/postgres.py +0 -0
  232. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/stores/__init__.py +0 -0
  233. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/stores/locks.py +0 -0
  234. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/stores/secrets.py +0 -0
  235. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/stores/state.py +0 -0
  236. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/types.py +0 -0
  237. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/__init__.py +0 -0
  238. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/base.py +0 -0
  239. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/decorators.py +0 -0
  240. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/identity_map.py +0 -0
  241. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/manager.py +0 -0
  242. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/py.typed +0 -0
  243. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/simple/__init__.py +0 -0
  244. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/simple/_operations.py +0 -0
  245. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/unit_of_work/simple/_uow.py +0 -0
  246. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/validation/__init__.py +0 -0
  247. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/validation/protocols.py +0 -0
  248. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/src/quadkit/sql/validation/py.typed +0 -0
  249. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/fixtures/test.db +0 -0
  250. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_add_previous_passwords_migration.py +0 -0
  251. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_apply_previous_passwords_migration.py +0 -0
  252. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_monitoring_metrics.py +0 -0
  253. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_monitoring_slow_query.py +0 -0
  254. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_postgres_provider_lifecycle.py +0 -0
  255. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_postgres_repository_compliance.py +0 -0
  256. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_provider_resilience_integration.py +0 -0
  257. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/integration/test_sqlite_provider_integration.py +0 -0
  258. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/__init__.py +0 -0
  259. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/handlers/__init__.py +0 -0
  260. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/handlers/test_migration_status.py +0 -0
  261. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/handlers/test_pool_utilization.py +0 -0
  262. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/handlers/test_query_stats.py +0 -0
  263. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/test_audit_store.py +0 -0
  264. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/test_queries_page.py +0 -0
  265. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/admin/test_sql_contributor.py +0 -0
  266. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/audit/test_audit_repository_mixin.py +0 -0
  267. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/__init__.py +0 -0
  268. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_entity_migration_generator.py +0 -0
  269. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_generators_contract.py +0 -0
  270. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_health_generator.py +0 -0
  271. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_repository_generator_staged.py +0 -0
  272. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/cli/test_service_generator.py +0 -0
  273. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/context/test_db_context.py +0 -0
  274. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/di/test_config_alignment.py +0 -0
  275. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/migrations/test_migration_model_analyzer.py +0 -0
  276. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/migrations/test_simple_migration_manager.py +0 -0
  277. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/outbox/__init__.py +0 -0
  278. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/outbox/test_outbox_publisher.py +0 -0
  279. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/outbox/test_outbox_store.py +0 -0
  280. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/performance/test_batch_processor.py +0 -0
  281. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/performance/test_engine_pragmas.py +0 -0
  282. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/providers/test_connection_mixin.py +0 -0
  283. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/providers/test_health_monitor.py +0 -0
  284. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/providers/test_query_builder_manager.py +0 -0
  285. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/providers/test_query_mixin.py +0 -0
  286. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/__init__.py +0 -0
  287. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_async_builder_identifier_safety.py +0 -0
  288. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_core_mixin_dml.py +0 -0
  289. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_join_aggregate_rendering.py +0 -0
  290. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_predicate_compiler.py +0 -0
  291. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_query_operators.py +0 -0
  292. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_sort_whitelist.py +0 -0
  293. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_sql_build_mixin.py +0 -0
  294. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/query/test_sql_query_builder.py +0 -0
  295. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/__init__.py +0 -0
  296. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_advanced_mixin.py +0 -0
  297. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_filter_mixin.py +0 -0
  298. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_filter_objects.py +0 -0
  299. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_read_mixin.py +0 -0
  300. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_rls_mixin.py +0 -0
  301. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_tenant_scoping_read.py +0 -0
  302. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_write_mixin_core.py +0 -0
  303. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_write_mixin_optimistic.py +0 -0
  304. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/repositories/test_write_mixin_tenant_scoping.py +0 -0
  305. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/schema/test_descriptors.py +0 -0
  306. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/schema/test_field_types.py +0 -0
  307. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/stores/test_db_lock_secret_stores.py +0 -0
  308. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_api.py +0 -0
  309. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_append_log.py +0 -0
  310. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_backup_manager.py +0 -0
  311. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_backup_models.py +0 -0
  312. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_backup_strategy.py +0 -0
  313. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_base_provider_pool.py +0 -0
  314. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_base_provider_query.py +0 -0
  315. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_base_provider_table_exists.py +0 -0
  316. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_base_provider_transaction_rollback_logging.py +0 -0
  317. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_cached_repository.py +0 -0
  318. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_cli_contributor.py +0 -0
  319. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_config_quadkit_db.py +0 -0
  320. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_connection_lifecycle_regressions.py +0 -0
  321. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_connection_pool_base.py +0 -0
  322. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_connection_pool_validation.py +0 -0
  323. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_crud_json_binding.py +0 -0
  324. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_maintenance.py +0 -0
  325. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_connection_pool.py +0 -0
  326. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_facade.py +0 -0
  327. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_health.py +0 -0
  328. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_health_checker.py +0 -0
  329. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_more.py +0 -0
  330. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_pool.py +0 -0
  331. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_query.py +0 -0
  332. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_monitor_transactions.py +0 -0
  333. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_provider.py +0 -0
  334. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_database_provider_multi.py +0 -0
  335. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_constants.py +0 -0
  336. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_context_propagation.py +0 -0
  337. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_exceptions.py +0 -0
  338. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_full_text.py +0 -0
  339. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_module.py +0 -0
  340. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_protocols.py +0 -0
  341. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_query_types.py +0 -0
  342. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_db_types.py +0 -0
  343. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_domain_mapper.py +0 -0
  344. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_domain_mapper_extended.py +0 -0
  345. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_domain_mapper_more.py +0 -0
  346. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_driver_errors.py +0 -0
  347. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_driver_monitoring_integration.py +0 -0
  348. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_drivers_smoke.py +0 -0
  349. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_exception_hierarchy_scenario.py +0 -0
  350. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_exceptions_quadkit_db.py +0 -0
  351. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_execute_commit_regression.py +0 -0
  352. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_filter_objects.py +0 -0
  353. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_generic_repository_counts.py +0 -0
  354. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_generic_repository_mapping.py +0 -0
  355. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_generic_repository_reads.py +0 -0
  356. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_generic_repository_writes.py +0 -0
  357. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_identity_map.py +0 -0
  358. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_instrumentation_db.py +0 -0
  359. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mappers.py +0 -0
  360. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mappers_base.py +0 -0
  361. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mappers_simple.py +0 -0
  362. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_metrics_collector.py +0 -0
  363. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_definitions.py +0 -0
  364. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_generator.py +0 -0
  365. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_generator_extra.py +0 -0
  366. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_manager.py +0 -0
  367. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_manager_behaviour.py +0 -0
  368. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migration_runner.py +0 -0
  369. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migrations_api.py +0 -0
  370. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migrations_apply_migration.py +0 -0
  371. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migrations_manager.py +0 -0
  372. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_migrations_rollback_recording_logs.py +0 -0
  373. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_model_analyzer.py +0 -0
  374. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mysql_driver_connection.py +0 -0
  375. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mysql_driver_health.py +0 -0
  376. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mysql_driver_pool.py +0 -0
  377. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_mysql_driver_resilience.py +0 -0
  378. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_named_database_config.py +0 -0
  379. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_package_hooks_p2.py +0 -0
  380. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_package_structure_p0.py +0 -0
  381. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_package_structure_p1.py +0 -0
  382. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_pool.py +0 -0
  383. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_postgres_driver_connection.py +0 -0
  384. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_postgres_driver_health.py +0 -0
  385. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_postgres_driver_pool.py +0 -0
  386. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_postgres_driver_resilience.py +0 -0
  387. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_protocol_validation.py +0 -0
  388. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_provider_connection.py +0 -0
  389. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_provider_health_check_error_logs.py +0 -0
  390. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_provider_instrumentation_edgecases.py +0 -0
  391. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_provider_resilience.py +0 -0
  392. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_provider_scoped_cleanup.py +0 -0
  393. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query.py +0 -0
  394. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query_log_single_emission.py +0 -0
  395. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query_logger_backends.py +0 -0
  396. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query_logger_entry_base.py +0 -0
  397. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query_logger_integration.py +0 -0
  398. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_query_middleware.py +0 -0
  399. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_redis_lock.py +0 -0
  400. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_redis_secrets.py +0 -0
  401. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_redis_state.py +0 -0
  402. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_replica_pool.py +0 -0
  403. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_repository_failures.py +0 -0
  404. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_repository_hooks.py +0 -0
  405. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_repository_reads.py +0 -0
  406. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_repository_uuid_params.py +0 -0
  407. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_repository_writes.py +0 -0
  408. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_request_context_query_logging.py +0 -0
  409. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_resilience.py +0 -0
  410. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_round41_hardening.py +0 -0
  411. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_schema_model.py +0 -0
  412. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_scoped_unit_of_work.py +0 -0
  413. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_seed_manager.py +0 -0
  414. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_simple_connection_pool.py +0 -0
  415. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_simple_transaction_manager.py +0 -0
  416. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_smoke_sqlalchemy.py +0 -0
  417. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sort_whitelist.py +0 -0
  418. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_specification_identifier_safety.py +0 -0
  419. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_specification_memory_scenario.py +0 -0
  420. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sql_config.py +0 -0
  421. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sql_constants.py +0 -0
  422. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sql_exceptions.py +0 -0
  423. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sql_hooks_runtime.py +0 -0
  424. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sql_types.py +0 -0
  425. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_driver_connection.py +0 -0
  426. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_driver_detailed.py +0 -0
  427. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_driver_health.py +0 -0
  428. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_driver_pool.py +0 -0
  429. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_driver_resilience.py +0 -0
  430. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_provider.py +0 -0
  431. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_provider_fixture.py +0 -0
  432. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_sqlite_stale_file.py +0 -0
  433. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_statement_cache.py +0 -0
  434. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_testing.py +0 -0
  435. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_threads_teardown.py +0 -0
  436. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_transaction_manager_task_isolation.py +0 -0
  437. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_unit_of_work_commit.py +0 -0
  438. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_unit_of_work_operations.py +0 -0
  439. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_uow_base.py +0 -0
  440. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/test_uow_lifecycle_hooks.py +0 -0
  441. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/unit_of_work/__init__.py +0 -0
  442. {quadkit_sql-0.0.42 → quadkit_sql-0.0.44}/tests/unit/unit_of_work/test_uow_outbox.py +0 -0
@@ -0,0 +1,24 @@
1
+ # Generated public-repository ignore rules.
2
+ # Private monorepo paths are intentionally not referenced here.
3
+
4
+ __pycache__/
5
+ *.py[cod]
6
+ *.so
7
+ *.egg-info/
8
+ .venv/
9
+ venv/
10
+ .env
11
+ .env.*
12
+ !.env.example
13
+ .pytest_cache/
14
+ .ruff_cache/
15
+ .mypy_cache/
16
+ .coverage
17
+ coverage.xml
18
+ htmlcov/
19
+ build/
20
+ dist/
21
+ *.log
22
+ .DS_Store
23
+ .idea/
24
+ .vscode/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: quadkit-sql
3
- Version: 0.0.42
3
+ Version: 0.0.44
4
4
  Summary: SQL database abstractions for Quadkit Framework — Postgres, MySQL, SQLite with migrations, repositories, and query building
5
5
  Project-URL: Homepage, https://dbtinoy-.github.io/quadkit
6
6
  Project-URL: Repository, https://github.com/dbtinoy-/quadkit
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "quadkit-sql"
9
- version = "0.0.42"
9
+ version = "0.0.44"
10
10
  description = "SQL database abstractions for Quadkit Framework — Postgres, MySQL, SQLite with migrations, repositories, and query building"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.11"
@@ -99,9 +99,6 @@ Documentation = "https://dbtinoy-.github.io/quadkit"
99
99
  Issues = "https://github.com/dbtinoy-/quadkit/issues"
100
100
  Changelog = "https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md"
101
101
 
102
- [project.entry-points."quadkit.admin.contributors"]
103
- sql = "quadkit.sql.admin.contributor:SqlAdminContributor"
104
-
105
102
  [project.entry-points."quadkit.providers"]
106
103
  database = "quadkit.sql.di.provider:DatabaseProvider"
107
104
 
@@ -181,9 +178,6 @@ overrides = [
181
178
  [tool.uv.sources.quadkit]
182
179
  workspace = true
183
180
 
184
- [tool.uv.sources.quadkit-admin]
185
- workspace = true
186
-
187
181
  [tool.uv.sources.quadkit-testing]
188
182
  workspace = true
189
183
 
@@ -60,7 +60,7 @@ class SqlAdminAuditLogStore:
60
60
  session is registered), and it does not commit — commit semantics
61
61
  belong to the session owner (e.g. the request pipeline or unit of
62
62
  work). For transactional audit entries, defer writes to the UoW's
63
- commit via :class:`~quadkit.admin.audit.uow_writer.UowAuditWriter`.
63
+ commit via :class:`~the optional provider module`.
64
64
 
65
65
  Usage (opt-in at app level): register a provider that binds
66
66
  ``AdminAuditLoggerProtocol`` to this store with an injected session,
@@ -120,7 +120,7 @@ class SeederGenerator(GeneratorBase):
120
120
  if lowered_type in {"bool", "boolean"}:
121
121
  return "True"
122
122
  if lowered_type in {"date", "datetime"}:
123
- return "datetime.now(timezone.utc)"
123
+ return "clock.now()"
124
124
  if lowered_type == "uuid":
125
125
  return '"550e8400-e29b-41d4-a716-446655440000"'
126
126
  if "json" in lowered_type:
@@ -156,7 +156,7 @@ def sa_type(field_type: str) -> str:
156
156
  #: Imports every generated model needs, merged with annotation-driven ones so
157
157
  #: the rendered module never repeats a module on two lines.
158
158
  BASE_IMPORTS: tuple[tuple[str, tuple[str, ...]], ...] = (
159
- ("datetime", ("datetime", "timezone")),
159
+ ("datetime", ("datetime",)),
160
160
  ("pydantic", ("BaseModel", "ConfigDict", "Field")),
161
161
  )
162
162
 
@@ -4,8 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any
6
6
  import uuid as _uuid
7
- from datetime import datetime as _datetime, timezone as _timezone
8
-
7
+ {% if needs_datetime %}from datetime import datetime
8
+ {% endif %}
9
+ from quadkit import clock
9
10
  from quadkit.contracts import DatabaseProviderProtocol
10
11
 
11
12
  from quadkit.sql.repositories.generic_repository import GenericRepository
@@ -53,7 +54,7 @@ class {{ repo_name }}Repository:
53
54
  def _prepare(self, data: dict[str, Any]) -> dict[str, Any]:
54
55
  row = dict(data)
55
56
  row.setdefault("{{ key_field }}", _uuid.uuid4().hex)
56
- now = _datetime.now(_timezone.utc).isoformat()
57
+ now = clock.now().isoformat()
57
58
  row.setdefault("created_at", now)
58
59
  row["updated_at"] = now
59
60
  return row
@@ -84,7 +85,7 @@ class {{ repo_name }}Repository:
84
85
  row = {
85
86
  **data,
86
87
  "{{ key_field }}": key,
87
- "updated_at": _datetime.now(_timezone.utc).isoformat(),
88
+ "updated_at": clock.now().isoformat(),
88
89
  }
89
90
  await self._provider.execute_update(
90
91
  "{{ table_name }}", row, '"{{ key_field }}" = ?', [key]
@@ -10,6 +10,7 @@ from __future__ import annotations
10
10
  import uuid
11
11
  {% for line in import_lines %}{{ line }}
12
12
  {% endfor %}
13
+ from quadkit import clock
13
14
 
14
15
  class {{ entity_name }}(BaseModel):
15
16
  """{{ entity_name }} entity."""
@@ -17,12 +18,8 @@ class {{ entity_name }}(BaseModel):
17
18
  model_config = ConfigDict(from_attributes=True)
18
19
 
19
20
  id: str = Field(default_factory=lambda: uuid.uuid4().hex)
20
- created_at: datetime = Field(
21
- default_factory=lambda: datetime.now(timezone.utc)
22
- )
23
- updated_at: datetime = Field(
24
- default_factory=lambda: datetime.now(timezone.utc)
25
- )
21
+ created_at: datetime = Field(default_factory=clock.now)
22
+ updated_at: datetime = Field(default_factory=clock.now)
26
23
  {%- for field in fields %}
27
24
  {{ field.name }}: {{ field.py_type }}{% if not field.required %} | None = None{% endif %}
28
25
  {%- endfor %}
@@ -2,9 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from datetime import datetime, timezone
6
5
  from typing import Any
7
6
 
7
+ from quadkit import clock
8
8
  from quadkit.contracts import DatabaseProviderProtocol
9
9
  from quadkit.sql import SimpleUnitOfWork
10
10
 
@@ -14,8 +14,8 @@ SEED_DATA: list[dict[str, Any]] = [
14
14
  {%- for field in fields %}
15
15
  "{{ field.name }}": {{ field.sample_value }},
16
16
  {%- endfor %}
17
- "created_at": datetime.now(timezone.utc),
18
- "updated_at": datetime.now(timezone.utc),
17
+ "created_at": clock.now(),
18
+ "updated_at": clock.now(),
19
19
  },
20
20
  ]
21
21
 
@@ -186,8 +186,8 @@ class _DatabaseRegistrationMixin:
186
186
 
187
187
  _warn_alembic_missing()
188
188
 
189
- # Database-backed search backends have moved to quadkit-search
190
- # (`quadkit.search.backends.mysql` / `quadkit.search.backends.postgres`).
189
+ # Database-backed search backends have moved to the optional provider
190
+ # (`the optional provider module` / `the optional provider module`).
191
191
  # SearchProvider is responsible for
192
192
  # resolving DatabaseProviderProtocol from the container and registering
193
193
  # the appropriate DatabaseSearchBackendProtocol singleton. DatabaseProvider
@@ -178,7 +178,7 @@ class DatabaseProvider(_DatabaseRegistrationMixin, Provider):
178
178
  except Exception: # noqa: BLE001 — optional tracing wiring degrades on any resolution failure
179
179
  logger.debug("trace_provider_unavailable")
180
180
 
181
- # Wire optional resilience pipeline factory (provided by quadkit-resilience).
181
+ # Wire optional resilience pipeline factory (provided by the optional provider).
182
182
  resilience = self._db_provider.resilience_handler
183
183
  if resilience._pipeline_factory is None:
184
184
  from quadkit.contracts.infra.resilience import (
@@ -56,6 +56,20 @@ except ImportError: # pragma: no cover - availability checked at runtime
56
56
  ALEMBIC_AVAILABLE = False
57
57
 
58
58
 
59
+ def _packaged_alembic_ini() -> Path:
60
+ """Return the ``alembic.ini`` that sits beside the package source.
61
+
62
+ An installed wheel carries no such file, so callers fall back to a path
63
+ they own when this is absent.
64
+
65
+ Returns:
66
+ Path to the workspace ``alembic.ini`` (which need not exist).
67
+ """
68
+ # parents[4] lands in src/, where `command.init()` writes a template ini;
69
+ # parents[5] is the package root that ships the real file.
70
+ return Path(__file__).resolve().parents[5] / "alembic.ini"
71
+
72
+
59
73
  class AlembicManager:
60
74
  """Alembic migration manager facade for Quadkit DB.
61
75
 
@@ -129,14 +143,17 @@ class AlembicManager:
129
143
 
130
144
  def _create_alembic_config(self) -> Config:
131
145
  """Create and configure Alembic Config object."""
132
- # Package root (packages/quadkit-sql/) — parents[4] would land in
133
- # src/, where `command.init()` then writes a template alembic.ini.
134
- package_root = Path(__file__).resolve().parents[5]
135
146
  config = Config()
136
- if (package_root / "alembic.ini").exists():
137
- config.config_file_name = str(package_root / "alembic.ini")
138
- # else: installed (non-workspace) layout with no packaged ini — leave
139
- # config_file_name unset so Alembic uses programmatic options only.
147
+ packaged_ini = _packaged_alembic_ini()
148
+ if packaged_ini.exists():
149
+ config.config_file_name = str(packaged_ini)
150
+ else:
151
+ # Installed wheel: `alembic.ini` lives at the package root, which
152
+ # sits outside the wheel, so there is no packaged ini to reference.
153
+ # `command.init()` asserts on `config_file_name`, so point it at
154
+ # the directory this manager already owns; `init()` writes the
155
+ # generated ini there, and only while that directory is empty.
156
+ config.config_file_name = str(self.migrations_path / "alembic.ini")
140
157
  config.set_main_option("script_location", str(self.migrations_path))
141
158
  # Strip +aiosqlite/+asyncpg for Alembic which is sync
142
159
  self.connection_string = self.database_url
@@ -147,6 +164,18 @@ class AlembicManager:
147
164
 
148
165
  config.set_main_option("sqlalchemy.url", self.connection_string)
149
166
  config.set_main_option("version_locations", str(self.script_location))
167
+ # `path_separator` must be set in the same breath as
168
+ # `version_locations`: alembic >= 1.16 deprecates splitting the value
169
+ # without it, and this manager sets `version_locations`
170
+ # programmatically. The packaged `alembic.ini` carries
171
+ # `path_separator = os`, so a *workspace* checkout never saw the
172
+ # warning -- but an *installed* layout resolves without that file and
173
+ # hit the legacy fallback on every boot. Setting it here makes the
174
+ # two layouts behave identically instead of leaving the guarantee to a
175
+ # file that ships only in the repo.
176
+ config.set_main_option("path_separator", "os")
177
+ # User overrides last, so `alembic_config={"path_separator": ":"}`
178
+ # still wins for a project that needs the legacy character.
150
179
  for key, value in self.alembic_config.items():
151
180
  config.set_main_option(key, str(value))
152
181
  return config
@@ -134,7 +134,7 @@ class MigrationOrchestrator:
134
134
  "package": "app",
135
135
  "path": self.base_path / "migrations",
136
136
  "dependencies": [
137
- "quadkit-admin",
137
+ "the optional provider",
138
138
  "quadkit-events",
139
139
  "quadkit-tasks",
140
140
  ],
@@ -204,7 +204,7 @@ class DatabaseService(_ConnectionMixin, _QueryMixin, _HealthMixin):
204
204
 
205
205
  raise ConfigurationError(
206
206
  "MongoDB URLs are not supported by quadkit-sql. "
207
- "Use quadkit-nosql instead: from quadkit.nosql import NoSQLProvider"
207
+ "Use the optional provider instead: from the optional provider module import NoSQLProvider"
208
208
  )
209
209
 
210
210
  from quadkit.sql.lib import infer_provider_type_from_url
@@ -189,7 +189,7 @@ class SearchQueryBuilder(QueryBuilder):
189
189
  makes the intent of passing a raw :data:`FilterExpression` explicit
190
190
  (rather than letting callers use the more generic :meth:`filter` alias).
191
191
 
192
- Search-extension packages (``quadkit-search``, ``quadkit-sql``) accept
192
+ Search-extension packages (``the optional provider``, ``quadkit-sql``) accept
193
193
  a :class:`SearchQueryBuilder` or a plain :class:`QueryBuilder` and compile
194
194
  the resulting :class:`Query` to backend-specific query syntax via
195
195
  ``FilterCompilerProtocol``.
@@ -1,7 +1,7 @@
1
1
  """Resilience primitives for database operations.
2
2
 
3
3
  Provides a resilience handler that wraps database operations with circuit
4
- breaker, retry with backoff, and timeout when ``quadkit-resilience`` is
4
+ breaker, retry with backoff, and timeout when ``the optional provider`` is
5
5
  installed. Falls back to a no-op pass-through when absent.
6
6
  """
7
7
 
@@ -1,14 +1,14 @@
1
1
  """Database resilience primitives.
2
2
 
3
3
  When a :class:`~quadkit.contracts.resilience.ResiliencePipelineFactory` is
4
- injected (provided by ``quadkit-resilience``), builds real circuit-breaker /
4
+ injected (provided by ``the optional provider``), builds real circuit-breaker /
5
5
  retry pipelines with database-specific defaults. When ``None`` is injected
6
- (or ``quadkit-resilience`` is not installed), a lightweight no-op pass-through
6
+ (or ``the optional provider`` is not installed), a lightweight no-op pass-through
7
7
  is used instead — so ``quadkit-sql`` has **no** hard runtime dependency on the
8
8
  resilience extension.
9
9
 
10
10
  Cross-extension communication follows the contracts + DI pattern from
11
- ``AGENTS.md``. ``quadkit-sql`` never imports from ``quadkit-resilience``
11
+ ``AGENTS.md``. ``quadkit-sql`` never imports from ``the optional provider``
12
12
  directly; it only consumes the :class:`~quadkit.contracts.resilience.ResiliencePipelineFactory`
13
13
  protocol resolved through the container.
14
14
  """
@@ -51,7 +51,7 @@ DB_RETRYABLE_EXCEPTIONS = (
51
51
 
52
52
 
53
53
  class _NoOpPipeline:
54
- """Pass-through pipeline used when quadkit-resilience is not installed."""
54
+ """Pass-through pipeline used when the optional provider is not installed."""
55
55
 
56
56
  async def execute(
57
57
  self, func: Callable[..., Awaitable[T]], *args: Any, **kwargs: Any
@@ -67,7 +67,7 @@ class DatabaseResilienceHandler:
67
67
  injected by the DI container. When a factory is present it builds real
68
68
  circuit-breaker / retry pipelines with database-specific defaults. When
69
69
  ``None`` is passed a lightweight no-op pipeline is used, so ``quadkit-sql``
70
- has no hard runtime dependency on ``quadkit-resilience``.
70
+ has no hard runtime dependency on ``the optional provider``.
71
71
  """
72
72
 
73
73
  def __init__(
@@ -77,7 +77,7 @@ class DatabaseResilienceHandler:
77
77
  """Initialise the resilience handler.
78
78
 
79
79
  Args:
80
- pipeline_factory: Optional factory provided by ``quadkit-resilience``
80
+ pipeline_factory: Optional factory provided by ``the optional provider``
81
81
  via the DI container. Pass ``None`` for no-op behaviour.
82
82
  """
83
83
  self._pipeline_factory = pipeline_factory
@@ -194,7 +194,7 @@ async def retry_call(
194
194
  The return value of *func* on a successful attempt.
195
195
 
196
196
  Raises:
197
- :class:`~quadkit.resilience.errors.RetryExhaustedError`: When all
197
+ :class:`~the optional provider module`: When all
198
198
  attempts are exhausted.
199
199
  Any exception raised by *func* that is not in ``config.retry_on``.
200
200
  """
@@ -14,17 +14,17 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
14
14
 
15
15
  # ensure local packages are importable when running tests directly
16
16
  # this mirrors the similar logic in other quadkit packages and is
17
- # intentionally simple so that pytest can find `quadkit.sql`,
18
- # `quadkit.contracts` and `quadkit.resilience` even though they live
19
- # outside the tests directory during development.
17
+ # intentionally simple so that pytest can find `quadkit.sql` and
18
+ # `quadkit.contracts` even though they live outside the tests
19
+ # directory during development.
20
20
  PROJECT_ROOT = os.path.abspath(os.path.join(BASE_DIR, ".."))
21
21
  sys.path.insert(0, os.path.join(PROJECT_ROOT, "src"))
22
22
  sys.path.insert(0, os.path.join(PROJECT_ROOT, "..", "quadkit-contracts", "src"))
23
23
 
24
24
  # Import TestEnvironment lazily inside the fixture to avoid importing
25
25
  # optional test utilities (e.g., admin mocks) at module import time which
26
- # may pull in optional packages like quadkit.admin that are not available
27
- # in all test environments.
26
+ # may pull in optional packages that are not available in all test
27
+ # environments.
28
28
 
29
29
  # The fixtures the test suite expects (clean_database, seeded_database, etc.)
30
30
  # are provided by quadkit.testing.fixtures.db; import them lazily below in
@@ -87,7 +87,7 @@ async def test_bed():
87
87
 
88
88
  Importing `TestEnvironment` lazily ensures we don't try to import heavy
89
89
  admin/testing modules at collection time (which can pull optional
90
- dependencies like `quadkit.admin`). If `quadkit.testing` isn't
90
+ dependencies that are not installed). If `quadkit.testing` isn't
91
91
  available in this environment, skip the dependent tests gracefully.
92
92
  """
93
93
  try:
@@ -230,6 +230,20 @@ class TestAlembicManager:
230
230
  assert "issues" in result
231
231
  assert isinstance(result["issues"], list)
232
232
 
233
+ def test_config_names_the_migrations_dir_without_a_packaged_ini(
234
+ self, connection_string, temp_dir, monkeypatch
235
+ ):
236
+ """An installed wheel ships no `alembic.ini`, so the config names the
237
+ directory the manager owns instead of leaving the name unset."""
238
+ from quadkit.sql.migrations.manager import _alembic
239
+
240
+ monkeypatch.setattr(
241
+ _alembic, "_packaged_alembic_ini", lambda: temp_dir / "alembic.ini"
242
+ )
243
+ manager = AlembicManager(connection_string, temp_dir)
244
+
245
+ assert manager.config.config_file_name == str(temp_dir / "alembic.ini")
246
+
233
247
 
234
248
  @pytest.mark.skipif(not ALEMBIC_AVAILABLE, reason="Alembic is not installed")
235
249
  class TestMigrationUtilities:
@@ -2,8 +2,11 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import importlib.util
5
6
  from unittest.mock import AsyncMock, patch
6
7
 
8
+ import pytest
9
+
7
10
  from quadkit.contracts.core import HealthCheckResult, HealthStatus
8
11
  from quadkit.sql.backends.cockroachdb import (
9
12
  CockroachDBConnection,
@@ -11,7 +14,12 @@ from quadkit.sql.backends.cockroachdb import (
11
14
  )
12
15
  from quadkit.sql.backends.postgres import PostgresConnectionPool
13
16
 
17
+ requires_asyncpg = pytest.mark.skipif(
18
+ importlib.util.find_spec("asyncpg") is None, reason="asyncpg is not installed"
19
+ )
20
+
14
21
 
22
+ @requires_asyncpg
15
23
  class TestDefaults:
16
24
  def test_constructor_defaults(self) -> None:
17
25
  conn = CockroachDBConnection()
@@ -45,6 +53,7 @@ class TestDsnNormalisation:
45
53
  assert CockroachDBConnection._normalize_dsn(dsn) == dsn # noqa: SLF001
46
54
 
47
55
 
56
+ @requires_asyncpg
48
57
  class TestCreatePool:
49
58
  async def test_server_settings_injected(self) -> None:
50
59
  captured: dict[str, object] = {}
@@ -91,6 +100,7 @@ class TestCreatePool:
91
100
  assert captured["server_settings"]["application_name"] == "quadkit-cockroachdb"
92
101
 
93
102
 
103
+ @requires_asyncpg
94
104
  class TestHealthCheckComponent:
95
105
  async def test_component_replaced(self) -> None:
96
106
  conn = CockroachDBConnection()
@@ -115,6 +125,7 @@ class TestHealthCheckComponent:
115
125
  assert fake_result.component == "database"
116
126
 
117
127
 
128
+ @requires_asyncpg
118
129
  class TestFactory:
119
130
  def test_defaults_without_dsn(self) -> None:
120
131
  pool = create_cockroachdb_pool()
@@ -97,11 +97,13 @@ class TestExecute:
97
97
  await pc.execute("BROKEN")
98
98
 
99
99
  async def test_generic_error_becomes_connection_error(self) -> None:
100
+ pytest.importorskip("asyncpg")
100
101
  pc, _ = _conn_results({("execute", "X"): OSError("socket gone")})
101
102
  with pytest.raises(DatabaseConnectionError, match="Connection error"):
102
103
  await pc.execute("X")
103
104
 
104
105
  async def test_timeout_maps_to_connection_error(self) -> None:
106
+ pytest.importorskip("asyncpg")
105
107
  pc, _ = _conn_results({("execute", "X"): DatabaseTimeoutError("slow")})
106
108
  with pytest.raises(DatabaseConnectionError, match="Connection error"):
107
109
  await pc.execute("X")
@@ -127,6 +129,7 @@ class TestFetchOne:
127
129
  await pc.fetch_one("B")
128
130
 
129
131
  async def test_generic_error_becomes_query_error(self) -> None:
132
+ pytest.importorskip("asyncpg")
130
133
  pc, _ = _conn_results({("fetchrow", "B"): OSError("down")})
131
134
  with pytest.raises(QueryError, match="Unexpected Postgres error"):
132
135
  await pc.fetch_one("B")
@@ -82,7 +82,7 @@ def test_unknown_type_falls_back_to_str(tmp_path: Path) -> None:
82
82
  def test_required_imports_are_emitted_and_merged(tmp_path: Path) -> None:
83
83
  """Constrained annotations bring their imports, each module once."""
84
84
  source = _render(tmp_path, "day:date,at:time,meta:json,email:email,site:url")
85
- assert "from datetime import date, datetime, time, timezone" in source
85
+ assert "from datetime import date, datetime, time" in source
86
86
  assert "from typing import Any" in source
87
87
  assert "from pydantic import AnyHttpUrl, BaseModel, ConfigDict, EmailStr, Field" in (
88
88
  source
@@ -44,7 +44,7 @@ def test_render_imports_merges_base_and_annotation_imports() -> None:
44
44
  """Base imports are always present and each module appears once."""
45
45
  lines = render_imports(["date", "time", "dict[str, Any]", "EmailStr"])
46
46
 
47
- assert "from datetime import date, datetime, time, timezone" in lines
47
+ assert "from datetime import date, datetime, time" in lines
48
48
  assert "from pydantic import AnyHttpUrl" not in lines
49
49
  assert "from pydantic import BaseModel, ConfigDict, EmailStr, Field" in lines
50
50
  assert "from typing import Any" in lines
@@ -54,7 +54,7 @@ def test_render_imports_merges_base_and_annotation_imports() -> None:
54
54
  def test_render_imports_without_annotations() -> None:
55
55
  """A plain entity needs only the base imports."""
56
56
  assert render_imports([]) == [
57
- "from datetime import datetime, timezone",
57
+ "from datetime import datetime",
58
58
  "from pydantic import BaseModel, ConfigDict, Field",
59
59
  ]
60
60
 
@@ -0,0 +1,107 @@
1
+ """`AlembicManager` builds a config alembic does not deprecate.
2
+
3
+ These tests use the **real** ``alembic.config.Config`` on purpose.
4
+ ``tests/unit/test_migrations_manager.py`` patches ``Config`` out, so it can
5
+ assert which options the manager *asks* for but never what alembic *does*
6
+ with them -- which is why the regression below survived there.
7
+
8
+ The regression: the manager sets ``version_locations`` programmatically, and
9
+ alembic >= 1.16 deprecates splitting that value unless ``path_separator`` is
10
+ also set. A workspace checkout hid it, because ``_create_alembic_config``
11
+ finds the packaged ``alembic.ini`` (which carries ``path_separator = os``)
12
+ and sets ``config_file_name``. An installed layout -- the wheel a generated
13
+ project resolves from PyPI -- has no packaged ini, so every boot fell back to
14
+ legacy splitting and emitted the deprecation.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import pathlib
20
+ import warnings
21
+
22
+ from alembic.script import ScriptDirectory
23
+ import pytest
24
+
25
+ from quadkit.sql.migrations.manager import AlembicManager
26
+ from quadkit.sql.migrations.manager._alembic import _packaged_alembic_ini
27
+
28
+ _DEPRECATION = "path_separator"
29
+
30
+
31
+ @pytest.fixture
32
+ def migrations_dir(tmp_path: pathlib.Path) -> pathlib.Path:
33
+ """A directory shaped enough for ``ScriptDirectory`` to load it."""
34
+ root = tmp_path / "migrations"
35
+ (root / "versions").mkdir(parents=True)
36
+ (root / "env.py").write_text("")
37
+ (root / "script.py.mako").write_text("")
38
+ return root
39
+
40
+
41
+ @pytest.fixture
42
+ def installed_layout(monkeypatch: pytest.MonkeyPatch):
43
+ """Hide the packaged ``alembic.ini``, as an installed wheel does.
44
+
45
+ Only that filename is hidden; every other path answers normally, so the
46
+ manager still finds the migrations directory under ``tmp_path``.
47
+ """
48
+ real_exists = pathlib.Path.exists
49
+
50
+ def fake_exists(self: pathlib.Path) -> bool:
51
+ if self.name == "alembic.ini":
52
+ return False
53
+ return real_exists(self)
54
+
55
+ monkeypatch.setattr(pathlib.Path, "exists", fake_exists)
56
+
57
+
58
+ def test_installed_layout_emits_no_path_separator_deprecation(
59
+ migrations_dir: pathlib.Path, installed_layout: None
60
+ ) -> None:
61
+ """The case a generated project actually runs: no packaged ini."""
62
+ assert not _packaged_alembic_ini().exists(), (
63
+ "fixture did not hide the packaged ini; the test would pass vacuously"
64
+ )
65
+ manager = AlembicManager("sqlite:///x.db", migrations_path=str(migrations_dir))
66
+
67
+ with warnings.catch_warnings(record=True) as caught:
68
+ warnings.simplefilter("always")
69
+ ScriptDirectory.from_config(manager.config)
70
+
71
+ offenders = [str(w.message) for w in caught if _DEPRECATION in str(w.message)]
72
+ assert not offenders, f"alembic still deprecates the config: {offenders}"
73
+
74
+
75
+ def test_version_locations_still_resolves_in_both_layouts(
76
+ migrations_dir: pathlib.Path,
77
+ ) -> None:
78
+ """``path_separator`` must not cost us the value it governs.
79
+
80
+ Guards the near-miss this fix had: setting the separator while dropping
81
+ ``version_locations`` leaves alembic with *no* version path at all, and
82
+ the deprecation assertion above would still pass -- silently, because
83
+ there is then nothing to split.
84
+ """
85
+ manager = AlembicManager("sqlite:///x.db", migrations_path=str(migrations_dir))
86
+ script = ScriptDirectory.from_config(manager.config)
87
+
88
+ assert script.version_locations == (str(migrations_dir / "versions"),) or list(
89
+ script.version_locations
90
+ ) == [str(migrations_dir / "versions")]
91
+
92
+
93
+ def test_path_separator_defaults_to_os(migrations_dir: pathlib.Path) -> None:
94
+ manager = AlembicManager("sqlite:///x.db", migrations_path=str(migrations_dir))
95
+ assert manager.config.get_main_option("path_separator") == "os"
96
+
97
+
98
+ def test_explicit_alembic_config_overrides_the_default(
99
+ migrations_dir: pathlib.Path,
100
+ ) -> None:
101
+ """The default is a floor, not a ceiling -- callers keep the last word."""
102
+ manager = AlembicManager(
103
+ "sqlite:///x.db",
104
+ migrations_path=str(migrations_dir),
105
+ alembic_config={"path_separator": ":"},
106
+ )
107
+ assert manager.config.get_main_option("path_separator") == ":"
@@ -1,9 +1,9 @@
1
1
  """Scenario coverage for the MySQL backend with an injected fake driver.
2
2
 
3
- The real ``aiomysql`` package is installed in this environment, but the
4
- pool/connection logic is exercised against an in-memory fake client
5
- (injected into the module-level ``aiomysql`` references) so no database
6
- server is required. Covers pool creation (success, failure, retry
3
+ The optional ``aiomysql`` driver is imported when present (the module skips
4
+ otherwise), and the pool/connection logic is exercised against an in-memory
5
+ fake client (injected into the module-level ``aiomysql`` references) so no
6
+ database server is required. Covers pool creation (success, failure, retry
7
7
  exhaustion), connection acquisition (plain + circuit breaker), health
8
8
  checks (healthy/cached/unhealthy paths), statistics, shutdown, and the
9
9
  ``MySQLConnection`` query surface with error mapping and monitoring.
@@ -15,9 +15,12 @@ import asyncio
15
15
  from contextlib import asynccontextmanager
16
16
  from typing import Any, Self
17
17
 
18
- import aiomysql
19
18
  import pytest
20
19
 
20
+ pytest.importorskip("aiomysql")
21
+
22
+ import aiomysql
23
+
21
24
  from quadkit.contracts.core import HealthStatus
22
25
  from quadkit.contracts.exceptions.resilience import RetryExhaustedError
23
26
  from quadkit.contracts.infra.resilience import RetryConfig
@@ -286,6 +286,7 @@ class TestHealthCheckerNeverRaises:
286
286
  class TestPostgresAutoCreate:
287
287
  @pytest.mark.asyncio
288
288
  async def test_autocreate_driver_error_wrapped(self, monkeypatch: pytest.MonkeyPatch) -> None:
289
+ pytest.importorskip("asyncpg")
289
290
  import asyncpg
290
291
 
291
292
  from quadkit.sql.providers.postgres_provider import PostgresProvider