|
| 1 | +--- |
| 2 | +"@objectstack/service-datasource": patch |
| 3 | +--- |
| 4 | + |
| 5 | +fix(service-datasource): a `pool` block on a `memory` datasource is rejected, not dropped in silence (#5931) |
| 6 | + |
| 7 | +#5714 made a `pool` block the driver cannot honour a loud authoring error, but |
| 8 | +its ruling was scoped to the two sqlite arms — `memory` kept dropping it. The |
| 9 | +`memory` arm hands `InMemoryDriver` nothing but `buildMemoryConfig(spec)`, which |
| 10 | +reads `spec.config` and never `spec.pool`, so a sized pool reached nothing and |
| 11 | +said nothing. Measured through the real factory: |
| 12 | + |
| 13 | +```text |
| 14 | +memory + pool{min:3,max:9} driver config {"persistence":false} pool undefined |
| 15 | +sqlite + pool{min:3,max:9} rejected (since #5714) |
| 16 | +postgres + pool{min:3,max:9} knex config.pool {"min":3,"max":9} live {min:3,max:9} |
| 17 | +``` |
| 18 | + |
| 19 | +`memory` now joins `POOL_UNSUPPORTED_DRIVER_IDS`, so the same three doors that |
| 20 | +already rejected sqlite reject it: the Setup wizard's create/update, the |
| 21 | +boot-time auto-connect pre-pass, and the driver factory itself. |
| 22 | + |
| 23 | +**Behaviour change.** A datasource declaring `driver: 'memory'` (or `inmemory` / |
| 24 | +`in-memory` / `mingo`) together with a non-empty `pool` block used to load and |
| 25 | +run; it now throws at whichever door it arrives through. The fix is the one edit |
| 26 | +the message names — delete the `pool` block. Nothing is lost by deleting it: it |
| 27 | +configured nothing before. An absent or empty `pool` is unchanged, and every |
| 28 | +`memory` datasource without one builds exactly as it did. No declaration in this |
| 29 | +repo, the example apps included, carried the combination. |
| 30 | + |
| 31 | +**Its own explanation, not SQLite's.** SQLite is rejected because a second |
| 32 | +connection to `:memory:` opens a separate, empty database, so sizing the pool |
| 33 | +would split one datasource across several stores. That reasoning is false for |
| 34 | +`memory`: there is no connection at all — the store is a plain data structure in |
| 35 | +this process — so the message says that instead. Telling an author their driver |
| 36 | +picked a connection strategy for them would send them looking for a knob that |
| 37 | +does not exist. Reasons are now keyed by driver id, which makes an arm joining |
| 38 | +the set without writing one a type error. |
| 39 | + |
| 40 | +Maintainer ruling 2026-08-07, which also set the default for the next sister |
| 41 | +arm: when a declared key is silently dropped on one arm and an earlier ruling |
| 42 | +already made it a loud authoring error on a sibling, the new arm joins the |
| 43 | +existing rejection set rather than queueing for a ruling of its own — unless the |
| 44 | +original rationale was measured to be arm-specific. |
| 45 | + |
| 46 | +No API surface is added — `POOL_UNSUPPORTED_DRIVER_IDS`, |
| 47 | +`driverReadsDeclaredPool`, `unsupportedPoolIssue`, `unsupportedPoolMessage` and |
| 48 | +`assertDatasourcePoolSupported` keep the signatures #5714 published, and the |
| 49 | +sqlite arms' rejection text is byte-for-byte unchanged. |
0 commit comments