Session brief (scope, non-goals, pinned SQL type/number decisions, verification) + TDD plan + build_fixture.py (regenerates the sqlite golden; the committed db bytes need not reproduce — the golden compares the derived bundle).
4.6 KiB
4.6 KiB
I4 — SQL-kilde på MAF-siden (plan)
TDD (Iron Law: ingen produksjonskode uten rød test først). Ett ingest.py endres; ny konnektor
- dispatch + typet §5-rendering. Ren stdlib-tillegg (
os,sqlite3,contextlib.closing,urllib.parse.quote) → MAF-fri-guarden urørt.
Steg
S1 — Røde tester (skriv FØR impl)
tests/test_ingest_sql.py(konnektor +materialize-dispatch):- env-var usatt →
IngestError; env peker på manglende fil →IngestError. - typet rendering via tmp sqlite-db: INTEGER→decimal, REAL→
repr, TEXT→verbatim, NULL→"". floatintegral (4200.0) →"4200.0"(bevart, ikke"4200").- BLOB →
IngestError(never silent coercion);bool-guard (konstruér viaSELECT? sqlite gir int — dekkbytessom «other»; bool-guarden er defensiv, dekkes med en direkte_sql_value_to_text(True)-kall-assert). max_rowsoverskredet →IngestError.- read-only (A2): skrive-query mot ro-connection →
IngestError. - happy path:
sql-manifest → bundle med korrekt provenance + body.
- env-var usatt →
tests/test_ingest_sql_loadbearing.py(SQL-spesifikke sømmer, detach-RED):test_sql_generated_bundle_is_navigable_via_unchanged_okf(speiler seam 3:navigate_bundlebundle_contextmot SQL-generert bundle; RØD hvis index-linking detaches).
test_sql_null_renders_as_empty_not_none(§5-load-bearing: RØD hvis None→str()).test_sql_real_preserves_float_form(§5:4200.0→"4200.0"; RØD hvis int-coerced).test_sql_blob_fails_never_silent_coercion(§5: BLOB→IngestError; RØD hvis silent str).test_sql_manifest_mapping_to_verdict_is_rejected(§3-reservasjon fyrer påsql-source).
- Oppdater 2 eksisterende:
test_ingest_materialize.py::test_sql_source_has_no_connector_in_i2→ repekes tilhttp(test_http_source_has_no_connector— den gjenstående I6-avvisningen; sql eksekverer nå).test_ingest_manifest.py::test_sql_and_http_variants_validate— kommentar «sql → I4» oppdateres til atfile+sqleksekverer,http→I6.
- Kjør → RØD (read_sql finnes ikke; materialize avviser sql).
S2 — Implementasjon (ingest.py)
- Import:
os,sqlite3,from contextlib import closing,from urllib.parse import quote. _sql_value_to_text(value) -> str(rekkefølge: None → bool-guard → int → float → str → fail).read_sql(connection_ref, query, *, max_rows) -> tuple[list[str], list[list[str]]]: env-resolusjon → fil-eksistens → ro-connection (closing) →execute→ header fracursor.description→ streaming max_rows-tak →_sql_value_to_textper celle → wrapsqlite3.Error/WarningsomIngestError.materialize: erstattif not isinstance(..FileSource): raisemed dispatch:http→refuse (I6);file→root-resolusjon+read_csv;sql→read_sql. §8-logg per uttrekk.- Docstring-oppdatering: modul-docstring (SQL nå implementert, §5-tallregler pinnet);
render_tableparentes (SQL-verdier pre-konvertert til §5-tekst iread_sql). - Kjør → GRØNN (unit + loadbearing).
S3 — Golden-fixture
examples/ingest-golden-sql/:fixture/portefolje.sqlite— committet db (gen-script i denne prosjektmappa; schema i brief). Tabeller:costs(id INTEGER, item TEXT, amount REAL, note TEXT-nullable) med NULL +4200.0;meta(k TEXT, v TEXT) med pipe/backslash for escape-bevis.manifest.json—source.type:sql,connection_ref:"PORTEFOLJE_SQL_DSN", to uttrekk med ORDER BY.ingested-at.txt— fast timestamp.expected-bundle/— generert avmaterialize, HÅNDVERIFISERT mot §5 celle-for-celle, frosset.
tests/test_ingest_golden_sql.py— speilertest_ingest_golden.py; setter env-var til fixture-db (monkeypatch), asserterer bit-likhet + idempotent re-run.- Kjør → GRØNN.
S4 — Detach-bevis (hver ny load-bearing, revertert)
- null→str, float→int-cast, BLOB→str, index-link-detach, verdict-validator-fjern → bekreft RØD.
S5 — Full verifisering + commit
pytest -qgrønn · ruff+format+mypy grønne ·git diff --stat(okf/shared/run urørt) · MAF-fri-guard grønn.- Overskriv STATE.md (I4 levert, NESTE = I5 gated søsken). Commits (Conventional,
(I4)-scope): test(røde) → feat(impl) → test(golden+fixture) → docs(brief/plan) → evt. style(ruff). Push Forgejo.
Verifisering (plan som helhet)
Program-sluttkriteriets SQL-halvdel: golden bit-deterministisk fra delt spec, load-bearing røde ved detach, suite grønn uten nøkkel/nett, ingen artefakt påstår mer enn koden gjør (sqlite-fixture, ikke live-DB). Ingen §-endring i spec.