sql-middleware 0.7.0

Lightweight async wrappers for tokio-postgres, rusqlite, turso, and tiberius.
Documentation
# DRY Violations – Consolidated Plan

Prioritized, deduplicated actions to reduce DRY issues across backends and typed adapters. Ordered from quickest/lowest risk to higher effort/risk. Keep feature flags and public API intact; add tests where behavior could shift.

Priority criteria (in order of weight):
- Smallest change surface area and lowest risk of behavioral drift.
- Backend-local helpers before cross-cutting refactors.
- Fewer call sites/feature gates before many.
- Tests already covering the behavior before changes that would require new tests.

1. **Extract column-name helper**
   - Backends: all (shared query utilities used across variants).
   - Estimated LOC change: ~20-40.
   - **Addressed:** Implemented `query_utils::extract_column_names` and updated Postgres/MSSQL/SQLite/Turso call sites to use it.
   - Add `extract_column_names()` (or similar) to shared query utilities to replace repeated `.map(|c| c.name().to_string())`.
   - Low risk; unit-test column name extraction for one backend to cover the helper.

2. **Standardize affected-rows conversion**
   - Backends: postgres, mssql.
   - Estimated LOC change: ~15-30.
   - **Addressed:** Added `convert_affected_rows` helpers in `postgres/query.rs` and `mssql/query.rs`, reused in executor/transaction paths.
   - Introduce backend-local `convert_affected_rows()` helpers (e.g., in `postgres/query.rs`, `mssql/query.rs`) for `u64 -> usize` handling.
   - Validate with existing affected-rows assertions; minimal change surface.

3. **Consolidate Postgres prepared vs direct helpers**
   - Backends: postgres.
   - Estimated LOC change: ~30-60.
   - **Addressed:** Added shared internal `execute_query_rows`/`execute_dml_rows` helpers in `postgres/query.rs` and reused in prepared/direct variants.
   - Factor shared logic between `execute_query_on_client` and `execute_query_prepared_on_client`, plus `execute_dml_on_client` and `execute_dml_prepared_on_client`.
   - Keep error messages and `build_result_set` usage identical; add a unit test if behavior changes.

4. **Consolidate Turso prepare/execute select**
   - Backends: turso.
   - Estimated LOC change: ~25-50.
   - Create `prepare_and_execute_select()` in `query.rs` (or equivalent) and use in `executor.rs` and `transaction.rs`.
   - Add/adjust tests around Turso SELECT execution paths if coverage is light.

5. **Extract SQLite DML/SELECT helpers**
   - Backends: sqlite.
   - Estimated LOC change: ~30-60.
   - Add `execute_dml_internal()` and `execute_select_internal()` in `query.rs`, reused by query and transaction modules.
   - Run SQLite integration tests to confirm identical behavior.

6. **Macro for typed backend impls**
   - Backends: all typed backends (sqlite, postgres, mssql, turso).
   - Estimated LOC change: ~80-150.
   - **Addressed:** Added `typed::macros::impl_typed_backend` and replaced Postgres/SQLite/Turso impl blocks with macro invocations.
   - Generate repeated trait impls in `src/typed/impl_*` via a `macro_rules!` template (Queryable, TypedConnOps, BeginTx, TxConn).
   - Guard invocations with `#[cfg(feature = ...)]`; add unit tests for one backend to ensure generated impls behave as before.

7. **Async wrapper macro**
   - Backends: all (shared pattern).
   - Estimated LOC change: ~40-80.
   - Replace repetitive `async move { ... }` wrapper patterns with a small macro (keep trait signatures stable).
   - Rely on clippy/tests to confirm no regressions; consider `async_trait` only if signatures allow.

8. **Dispatch arm consolidation**
   - Backends: all enum-dispatch sites (respect feature flags for postgres, sqlite, mssql, turso).
   - Estimated LOC change: ~40-90.
   - Add macro/helper for enum dispatch match arms that only differ by backend call, preserving `#[cfg]` guards.
   - Smoke-test across enabled backends; ensure compile-gates are respected.

9. **Standardize typed connection error handling**
   - Backends: postgres, sqlite, turso typed modules (extendable to others as needed).
   - Estimated LOC change: ~30-60.
   - Introduce shared trait/macro in typed module for “take connection / already taken” error paths across postgres/sqlite/turso typed modules.
   - Add a small unit test to assert consistent error text/variant.

10. **Unify Drop rollback + test helpers**
   - Backends: all typed modules.
   - Estimated LOC change: ~50-100.
   - Extract shared Drop rollback logic and SKIP_DROP_ROLLBACK pattern into typed utilities; invoke from all typed modules.
   - Add tests for best-effort rollback on drop and skip behavior.

11. **Clean up Idle vs InTx duplication (per backend)**
   - Backends: all, applied within each backend module where duplication exists.
   - Estimated LOC change: ~60-120 per backend.
   - Factor shared logic (execute_batch, dml, select, begin/commit/rollback wrappers) into backend-local helpers.
   - Re-run backend-specific integration tests to confirm no behavioral drift.

12. **Transaction wrapper shape extraction**
   - Backends: all (Tx/Prepared shapes across postgres, sqlite, mssql, turso).
   - Estimated LOC change: ~90-180.
   - **Risk note:** Prefer a centralized shared module with all backends delegating to one Tx/Prepared abstraction for consistency, but this is high risk. It can flatten backend-specific semantics (prepare strategy, row-count conversions, error labeling), complicate lifetimes/ownership (e.g., Turso prepared statement handles, SQLite prepare_cached, MSSQL’s faux-prepared wrapper), and increase feature-gate complexity. It also likely alters public API shapes. Consider a phased approach if pursued.
   - Define a small trait/template capturing Tx/Prepared/execute/query shape; implement backend-specific internals.
   - Higher risk: ensure transactional semantics/tests stay intact across backends.

13. **Centralize parameter/result-set adapters**
   - Backends: all (with backend-specific hooks).
   - Estimated LOC change: ~120-250.
   - **Addressed:** Added shared adapters in `adapters::{params,result_set}` and refactored backend call sites to use them for conversion and column-count/result-set setup.
   - Build shared helpers for `RowValues -> driver params` and driver rows -> `ResultSet`, with backend hooks for internals.
   - Add focused tests comparing result-set output and parameter handling before/after.

14. **Auto-commit wrapper macro (optional)**
   - Backends: all typed modules (if pursued).
   - Estimated LOC change: ~80-160.
   - Evaluate macro for auto-commit pattern (take conn → begin → execute → commit → restore); proceed only if it reduces meaningful duplication without hiding behavior.
   - If adopted, add integration coverage for auto-commit flows per backend.

Testing guidance
- Run `cargo test` with relevant features (`sqlite,postgres,turso,mssql`) after each clustered change.
- Prefer small unit tests alongside helpers; keep integration tests for behavioral parity.