Repository navigation
Commit e826e77
refactor(driver-sql): put SqlDriver into facade form with the sql-driver codemod (sql-driver.ts 18,334 -> 10,979, body-identical) (#30139)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwB2J1rGmLUVawKQeMT3jK9KS)_
Part of #30105
## 维护者速读
- 改了什么:给 `scripts/codemod-split-sql-driver.mjs`(#29520 的试点脚本)加上
`engine.ts` / `protocol.ts` 已有的门面层,并重新生成 `sql-driver.ts`。`SqlDriver`
成为门面:158 个方法体移入 21 个无状态 facet 类(静态方法,`this` 是一个具名 host),类上各留一行
`.call(xHost.of(this), …)` 委派;私有方法的文档块随方法体移走(21
个),公开和受保护方法的文档块留在门面;状态全部留在门面。生成文件未手改。
- 为什么改:#29465 大文件拆分,裁决 6632500982 把门面形态(6624258595)扩展到本文件;`.d.ts` 门槛按
6624345766 取「公开面相等」。
- 风险与回滚:纯搬移。158/158 个方法体逐字节等于 base,撤销拆分逐字节重建 base 的 `sql-driver.ts`;两次
`--write` 输出树 sha256 相同。公开面 `.d.ts` 相等(对照抓到)。driver-sql 测试 base 与 head
都是 3,859 通过;turso、sqlite-wasm 两个子类驱动计数不变。回滚即 revert。
- 先看:① 「Facade reading」一节的 28 条例外(其中哪些是 codemod 限制、需另立卡);② codemod 的
`CLASS_HEAD_SECTION` 和新加的 `logDurabilityFailure` pin;③
`check-tenant-chokepoint.mjs` 新登记的 4 个模块。
- 两分钟验证:`pnpm install --frozen-lockfile` 后运行 `node
scripts/codemod-split-sql-driver.mjs --verify --base 21510bb`,预期
`158/158 moved bodies identical to base`、`sql-driver.ts 18334 -> 10979
lines`,退出码 0;`--self-test` 67 例通过;`node
scripts/check-facade-delegation-only.mjs` 退出码 0。
- 需要你做的:改动超过 3,000 行(+4,990 / −3,121,含生成文件),需您批准后落地,并在您定的窗口冻结
`sql-driver.ts`;本 PR 保持草稿。
Clause-②: no
Metadata-protocol: none
## What changes
- **`scripts/codemod-split-sql-driver.mjs`** gains the facade layer
`scripts/codemod-split-engine.mjs` carries (#30012, #30083):
- Each section module's moved bodies become the static methods of one
stateless facet class (`sql-driver-crud.ts` → `CrudFacet`), at class
indentation, unedited. Their `this` is one named host interface typed AS
the class members (`SqlDriver['x']`), so a private member is reached
like a public one.
- The stub on the class keeps its modifiers and signature byte-for-byte
(only `async` is dropped) and makes one call: `return
CrudFacet.x.call(crudHost.of(this), …)`. Each host is built once per
driver by a factory the class's static block installs into
`sql-driver-facet-hosts.ts` (types-only module). Methods go as closures
called on the driver at call time, so a subclass override or an instance
spy is still the one reached; `getBuilder` goes as a bound getter
(`BOUND_HOST_METHODS`) so `check-tenant-chokepoint` still counts the
binding in the moved body; fields and accessors go as getters, assigned
fields with a setter.
- Private statics the moved bodies read go through `SqlDriverStatics`,
which a facet module imports AS `SqlDriver`
(private-static-through-host, 6624174693).
- Docblock ownership (6624345766 item 1): a private method's docblock
moves with its body; a public or protected one stays on the facade and
the facet member carries a one-line placeholder pointing back.
- The members above the first banner form one more section, the class
head (`CLASS_HEAD_SECTION` → `sql-driver-class-head.ts`). Three sections
whose hand-series seam exists already take a `-section` suffix;
`sql-driver-deferred-ddl.ts` and `sql-driver-transactions-section.ts`
are new.
- No import prune: driver-sql compiles without `noUnusedLocals`, so an
import only a moved body reads stays, as the pilot left them.
- The pilot's `--dts` byte-equality reading is dropped: a facade cannot
meet it by construction (the bundled `.d.ts` prints every private
member). The bar is now the public-surface reading below, taken outside
`scripts/` (6441032442 item 3).
- `parameter-shadows` now fires only for a parameter named like the
stub's facet class or host variable (it freed 4 methods).
- One new `PATH_READER_PINS` row, `logDurabilityFailure` (see readers
below).
- `--self-test`: 67 cases in 5 pinned batteries (class-head section, the
bound getter and two banner refusals added; the import-prune battery
removed).
- **The generated split** is `--write` on the unsplit `sql-driver.ts` of
`21510bba` (the parent of the pilot's landing), unedited. 158/254
methods move into 21 facet modules; `sql-driver.ts` goes 18,334 → 10,979
lines (12,460 on `main`). The leaf `sql-driver-top-level.ts` is
byte-identical to `main`. `index.ts` re-exports none of the new modules.
- **`scripts/facade-delegation-registry.json`**: the `sql-driver.ts` /
`SqlDriver` facade row (card #30105) and 28 exception rows, all carded
#30020.
- **By-path readers** (6597555122 item 3):
- `check-durability-degradation-log-level` judges the two MySQL widening
catches that stay on the class (`migrateMysqlDatetimeColumns`,
`migrateMysqlTimeColumns`) by following `this.logDurabilityFailure(…)`
to its body in the same file. A one-call stub there cannot be followed,
so both read "swallowed, no log" (measured red). The helper is pinned to
stay rather than widening the gate's same-file helper walk across files;
the gate's readings are then equal to base.
- `check-tenant-chokepoint`'s `DECLARED_WATCH_HINTS` names the four new
`sql-driver-*.ts` modules (its self-test requires every scanned file to
be declared).
- Every other reader of `sql-driver.ts` by path (the `packages/cli`
generate pins, `check-keyed-text-bounds`,
`sql-driver-compile-refusal-seam.test.ts`, the liveness and checklist
anchors, the ADR anchors) reads text the codemod keeps on the class
through its existing pin and needle tables, and passes unchanged.
- **No changeset**, as #29598 and #30012 (both `skip-changeset`): no
published behaviour or surface changes.
## Tests
No test file changes. The suites below ran at base `f68b47ca` and at
head; the counts are equal.
| Suite | Base | Head |
|:--|:--|:--|
| driver-sql (`vitest run`) | 238 files passed, 12 skipped; 3,859
passed, 216 skipped | the same |
| driver-turso (subclasses `SqlDriver`) | 96 files; 2,496 passed, 34
skipped | 96 files; 2,496 passed, 34 skipped |
| driver-sqlite-wasm (subclasses `SqlDriver`) | 40 files; 750 passed |
40 files; 750 passed |
| cli by-path pins (9 files: generate-* pins,
`clean.operator-text-21418`) | 9 files; 131 passed | 9 files; 131 passed
|
| types / metadata / metadata-protocol by-path tests, spec
`check-liveness.test` | 22 / 11 / 28 / 74 passed | 22 / 11 / 28 / 74
passed |
## Acceptance notes
- Phase 0: this PR stays a draft. It is over the 3,000-line human-merge
threshold, so it lands on a maintainer approval, after `sql-driver.ts`
is frozen for a window. At landing the script runs on the latest
`main`'s unsplit text (regenerate, never rebase, ruling A on #29465).
- Codemod-limit exception rows the seat may card separately (the rest
are state-owning, #30020): the five accessors (the codemod moves
methods, not accessors); `rotateShards` / `ensureRotation` (a computed
parameter default stays in the byte-for-byte signature); the path-reader
pins (`ensureShardTable`, `initObjects`, `migrateMysqlDatetimeColumns`,
`migrateMysqlTimeColumns`, `resolveWithheldFilterRefusal`,
`createAuditTimestampColumn`, `varcharColumnChars`, `createColumn`,
`logDurabilityFailure`), which move once their readers read the facet
modules; and the `field-call: knex`, `inferred-return-type` and
`comment-in-parameters` stays.
- `dts-public.mjs`'s built-in `--private-control` fails on this dist: it
deletes the first `private x;` line but leaves that member's docblock,
which then attaches to the next (public) member. Dropping the whole
private member with its docblock passes (reading below).
## Verification
| Reading | Base | Head |
|:--|:--|:--|
| `sql-driver.ts` lines | 18,334 (`21510bba`) · 12,460 (`main`) |
**10,979** |
| Byte-identity (`--write`, and `--verify --base 21510bb`, exit 0) | |
158/158 bodies, 127/127 top-level declarations identical; undoing the
split rebuilds the base byte-for-byte |
| Determinism | | two `--write` runs: output tree sha256
`eab675141cad9efdb5217f65f044a246474c973777c575d9f5ee00b8c63d8154` both
times; regeneration reproduces the committed tree |
| `driver-sql typecheck` | exit 0 | exit 0 |
| `check:facade-delegation-only` (+ `--self-test` 36) | | exit 0:
`SqlDriver` 352 members, 244 delegations, 80 fields, 28 named exceptions
|
| `check:tenant-chokepoint` | 24 bindings, 21 read doors, 3 insert
builders, 4 tenant predicates, 0 D8 arms, 34 files | the same readings,
38 files |
| `check:durability-log-level` | 51 seams (9 propagating), 101 read
seams (13 discriminated) | the same; the output is byte-identical |
| `pnpm build` (whole repo, 119 tasks) | | exit 0 |
| `pnpm lint` | | exit 0 |
| `dispatch-gates --commands` (67) | | 67 run, every exit 0; `--ran`: 67
derived, 0 NOT-MEASURED, 0 UNRUN |
### `.d.ts`: ruling 6624345766 item 1, "public surface EQUAL"
Read with `dts-public.mjs` (project files `issue-29985/dts-public.mjs`,
sha256
`211b32062250606e658acd7fb8880e0079b4043121fb7b970c658b4b57bf5020`, the
reading #29985 used). driver-sql's `.d.ts` build is deterministic on
both sides (two builds each, byte-identical), so one pair is read.
| Reading | `index.d.ts` | `index.d.mts` |
|:--|:--|:--|
| raw (sha256 base `69d9162d…` / head `fac28979…`) | differs (private
members) | differs |
| private members cut, union order, second normalisation | **equal**
(106 / 106 statements) | **equal** |
| declared surface | equal | equal |
- The control that edits one public docblock is caught.
- Dropping one whole private member (`fileColumnsMovedDeclared` with its
docblock) passes.
- The facet classes and hosts do not appear in the `.d.ts`.
### Facade reading
| Facet | Members | Docblocks moved |
|:--|--:|--:|
| ClassHead | 12 | 6 |
| Lifecycle | 11 | 6 |
| Crud | 7 | 2 |
| SequenceSemantics | 23 | 3 |
| BulkOperations | 7 | 0 |
| TransactionsSection | 1 | 0 |
| Aggregation | 3 | 0 |
| Distinct | 1 | 0 |
| WindowFunctions | 1 | 0 |
| QueryPlan | 2 | 0 |
| SchemaSyncSection | 3 | 0 |
| Rotation | 9 | 0 |
| DeferredDdl | 3 | 0 |
| ManagedDrift | 8 | 0 |
| InternalHelpers | 7 | 0 |
| FilterHelpers | 30 | 3 |
| FieldMapping | 6 | 0 |
| WindowFunctionBuilder | 1 | 0 |
| ColumnCreation | 14 | 1 |
| DatabaseHelpers | 7 | 0 |
| SqliteSerialisation | 2 | 0 |
| **Total** | **158** | **21** |
The 28 exception rows (all #30020):
| Reason | Members |
|:--|:--|
| state: constructor logic, field / static initializers holding arrows |
`constructor`, `logger`, `static DIALECT_CONNECT_TIMEOUT` |
| accessor (codemod moves methods only) | `get supports`, `get
insertReturnsStoredRows`, `get dateGranularityCapabilities`, `get
supportsWalJournal`, `get dialectName` |
| a computed parameter default | `rotateShards`, `ensureRotation` |
| path-reader | `logDurabilityFailure`, `ensureShardTable`,
`initObjects`, `migrateMysqlDatetimeColumns`, `migrateMysqlTimeColumns`,
`resolveWithheldFilterRefusal`, `createAuditTimestampColumn`,
`varcharColumnChars`, `createColumn` |
| field-call: knex | `listPhysicalColumns`, `getBuilder`,
`explainUnkeyableTextColumn`, `explainHashShadowDuplicate` |
| inferred-return-type | `applyFilters`, `applyFilterCondition`,
`ensureDatabaseExists`, `createDatabase` |
| comment-in-parameters | `assertOperatorAppliesToColumn` |
The 78 hand-series stubs stay as they were (their modules are the hand
series', not facets) and read as delegations.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01WGufzhBZia3VxBbmZ7wCkS
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 07595c0 commit e826e77
26 files changed
Lines changed: 4990 additions & 3121 deletions
File tree
- packages/drivers/driver-sql/src
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
| 5 | + | |
| 6 | + | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
| 9 | + | |
9 | 10 | | |
10 | | - | |
11 | | - | |
12 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | 17 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
21 | 26 | | |
22 | | - | |
23 | | - | |
| 27 | + | |
| 28 | + | |
24 | 29 | | |
25 | 30 | | |
26 | 31 | | |
27 | 32 | | |
28 | 33 | | |
29 | 34 | | |
| 35 | + | |
30 | 36 | | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
34 | 40 | | |
35 | 41 | | |
36 | 42 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
41 | 48 | | |
42 | 49 | | |
43 | 50 | | |
44 | 51 | | |
45 | 52 | | |
46 | 53 | | |
47 | 54 | | |
| 55 | + | |
48 | 56 | | |
49 | 57 | | |
50 | 58 | | |
51 | 59 | | |
52 | 60 | | |
53 | 61 | | |
| 62 | + | |
54 | 63 | | |
55 | 64 | | |
56 | 65 | | |
| 66 | + | |
57 | 67 | | |
58 | 68 | | |
59 | 69 | | |
60 | 70 | | |
61 | | - | |
62 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
63 | 75 | | |
64 | 76 | | |
65 | 77 | | |
| |||
331 | 343 | | |
332 | 344 | | |
333 | 345 | | |
334 | | - | |
335 | | - | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
336 | 357 | | |
337 | 358 | | |
338 | 359 | | |
| |||
342 | 363 | | |
343 | 364 | | |
344 | 365 | | |
| 366 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
10 | 11 | | |
11 | | - | |
12 | | - | |
13 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
14 | 17 | | |
15 | 18 | | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
22 | 27 | | |
23 | | - | |
24 | | - | |
| 28 | + | |
| 29 | + | |
25 | 30 | | |
26 | 31 | | |
27 | 32 | | |
| |||
33 | 38 | | |
34 | 39 | | |
35 | 40 | | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
40 | 46 | | |
41 | 47 | | |
42 | 48 | | |
| |||
67 | 73 | | |
68 | 74 | | |
69 | 75 | | |
70 | | - | |
71 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
72 | 80 | | |
73 | 81 | | |
74 | 82 | | |
| |||
225 | 233 | | |
226 | 234 | | |
227 | 235 | | |
228 | | - | |
229 | | - | |
| 236 | + | |
| 237 | + | |
230 | 238 | | |
231 | 239 | | |
232 | 240 | | |
| |||
247 | 255 | | |
248 | 256 | | |
249 | 257 | | |
250 | | - | |
251 | | - | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
252 | 270 | | |
253 | 271 | | |
254 | 272 | | |
| |||
289 | 307 | | |
290 | 308 | | |
291 | 309 | | |
292 | | - | |
293 | | - | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
294 | 325 | | |
295 | 326 | | |
296 | 327 | | |
| |||
319 | 350 | | |
320 | 351 | | |
321 | 352 | | |
322 | | - | |
323 | | - | |
| 353 | + | |
| 354 | + | |
324 | 355 | | |
325 | 356 | | |
326 | 357 | | |
| |||
352 | 383 | | |
353 | 384 | | |
354 | 385 | | |
| 386 | + | |
0 commit comments