Skip to content

[chore] Reorganize src/sql/executor.rs (4338 LOC) into src/sql/executor/ directory #116

@ujeenet

Description

@ujeenet

What

crates/rustango/src/sql/executor.rs is at 4338 lines mixing 8 distinct concerns (PG-only path, &Pool dispatch, &mut PoolTx ops, FromRow markers, pure projection, prefetch, ChunkedIter, get_or_create, traits, bind helpers). The file already has 5 hand-rolled // ===== section markers — a visible signal the author hit the same navigation pain.

Goal

Convert executor.rs into src/sql/executor/ directory with 12 files of 50–1100 LOC each. Public API stays bit-identical via pub use re-exports in mod.rs — zero downstream breakage.

Proposed layout

File LOC est Contents
mod.rs ~80 Re-export-only.
bind.rs ~250 bind_match! macro + bind_query family + per-dialect cell_to_sqlvalue decoders.
traits.rs ~600 All trait surface (Fetcher / FetcherPool / FetcherTx, Counter*, Updater*, Deleter, HasPkValue, LoadRelated*, MaybePgFromRow family, MaybePgScalar family).
pg.rs ~1100 PG-only path (&PgPool / &mut PgConnection) — insert(_on) / update(_on) / delete(_on) / select_rows(_on) / count_rows(_on) / bulk_* / raw_query(_on) / raw_execute(_on) / fetch_aggregate(_on) / transaction.
row_to_json.rs ~370 Tri-dialect dynamic-row decoders (row_to_json / _my / _sqlite / select_rows_as_json / select_one_row_as_json + augment_joined_columns_*).
pool.rs ~1100 &Pool dispatch — the canonical bi-dialect path. insert_pool / update_pool / delete_pool / count_rows_pool / bulk_*_pool / raw_*_pool / select_*_pool / fetch_aggregate_pool / fetch_paginated_pool / select_rows_pool_with_related + FetcherPool impl.
tx.rs ~370 PoolTx wrapper, transaction_pool, insert_tx / update_tx / delete_tx / select_rows_tx_with_related / FetcherTx impl.
values.rs ~310 Issue #22fetch_values_dict / fetch_values_list / fetch_values_flat + the three ValuesQuerySet::fetch bridge impls.
prefetch.rs ~330 annotate_count_children(_on/_pool) / fetch_with_prefetch(_on/_pool).
iter.rs ~165 ChunkedIter (issue #23).
get_or_create.rs ~140 get_or_create / update_or_create / ensure_pk_ordering.
page.rs ~50 Page<T> struct + inject_total_count.

Migration mechanics

Five-step plan, each step compiles + passes tests independently (git-bisect-able and reversible):

  1. Create mod.rs + traits.rs — move all trait defs first.
  2. Extract bind.rs — unblocks every other extraction.
  3. Extract pg.rs + row_to_json.rs — cleanest pure cut. After this, executor.rs is half-size.
  4. Extract pool.rs + tx.rs — the bi-dialect surface. Largest single cut.
  5. Extract values.rs + prefetch.rs + iter.rs + get_or_create.rs + page.rs — the leaf modules. Delete the now-empty executor.rs.

Run cargo test --workspace --all-features --no-run after each step.

Why not now

Doing this reorg invalidates every open PR's merge base. Trigger condition: empty open-PR queue between parity batches, or pair with a planned breaking-change release. Estimated 1-2 days of focused work.

Acceptance

  • cargo test --workspace --all-features passes with zero failures.
  • cargo test --no-default-features --features sqlite,tenancy (the litmus from CLAUDE.md) passes.
  • cargo doc --no-deps produces no broken intra-doc links.
  • No public API changes — rustdoc diff before/after is empty.
  • grep -rn 'sql::executor::' . returns zero results outside the executor dir.
  • Cookbook references that pointed at line numbers in old executor.rs are updated.

Related followup

writers.rs (2597 lines) probably wants the same treatment but lower priority — defer to a separate plan.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions