5858 *
5959 * ## The rows
6060 *
61- * - `memory`, `sqlite` (better-sqlite3), `sqlite-wasm` (sql.js): real
62- * drivers. `postgres` and `mysql`: real `driver-sql` instances, never
63- * connected; their dialect and bucket expression answer from the client
64- * config alone, and the spied doors mean no statement is sent.
61+ * - `sqlite` (better-sqlite3), `sqlite-wasm` (sql.js): real drivers.
62+ * `postgres` and `mysql`: real `driver-sql` instances, never connected;
63+ * their dialect and bucket expression answer from the client config alone,
64+ * and the spied doors mean no statement is sent.
65+ * - `memory`, by code path: `InMemoryDriver` declares `supports = {}`, so
66+ * the engine buckets every granularity in memory, and it has neither
67+ * `dialectName` nor `dateBucketSql`. The stand-in carries exactly that
68+ * surface. The real driver is not imported: a new consumer of
69+ * `@objectstack/driver-memory` is a maintainer ruling
70+ * (`check:driver-memory-census`), not a test's choice. #21647's own
71+ * measurement ran on the real driver, before and after this change.
6572 * - `mongodb`, by code path: `driver-mongodb` publishes
6673 * `queryDateGranularity` for every granularity
6774 * (`MONGODB_DATE_GRANULARITIES`), so the engine pushes the bucket into its
@@ -88,7 +95,6 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
8895import { ObjectQL } from '@objectstack/objectql' ;
8996import { SqlDriver } from '@objectstack/driver-sql' ;
9097import { SqliteWasmDriver } from '@objectstack/driver-sqlite-wasm' ;
91- import { InMemoryDriver } from '@objectstack/driver-memory' ;
9298import { BUILTIN_DRIVER_IDS , TimeUpdateInterval , type BuiltinDriverId , type Cube } from '@objectstack/spec/data' ;
9399import { declaredRefusalMessage } from '@objectstack/types' ;
94100import type { AnalyticsService } from '../analytics-service.js' ;
@@ -160,22 +166,32 @@ const releaseKnex = async (driver: EnumeratedDriver) => {
160166const sqliteDriver = ( ) =>
161167 new SqlDriver ( { client : 'better-sqlite3' , connection : { filename : ':memory:' } , useNullAsDefault : true } as any ) as unknown as EnumeratedDriver ;
162168
163- /** `driver-mongodb`'s surface on this pin's read path, by code path (see the header). */
164- const mongodbByCodePath = ( ) : EnumeratedDriver => ( {
165- name : 'os21647.mongodb-by-code-path' ,
169+ /**
170+ * A driver that runs no SQL, by code path: its `supports`, and the two data
171+ * doors, with no `dialectName` and no `dateBucketSql`. `find` answers `rows`.
172+ */
173+ const noSqlDriverByCodePath = ( name : string , supports : Record < string , unknown > , rows : unknown [ ] = [ ] ) : EnumeratedDriver => ( {
174+ name,
166175 version : '0.0.0' ,
167- supports : {
168- batchSchemaSync : true ,
169- queryDateGranularity : Object . fromEntries ( GRANULARITIES . map ( ( g ) => [ g , true ] ) ) ,
170- } ,
176+ supports,
171177 async connect ( ) { } ,
172178 async disconnect ( ) { } ,
173179 async aggregate ( ) { return [ ] ; } ,
174- async find ( ) { return [ ] ; } ,
180+ async find ( ) { return rows . map ( ( row ) => ( { ... ( row as object ) } ) ) ; } ,
175181} ) ;
176182
183+ /** `driver-memory`'s surface on this pin's read path, by code path (see the header). */
184+ const memoryByCodePath = ( rows : unknown [ ] = [ ] ) => noSqlDriverByCodePath ( 'os21647.memory-by-code-path' , { } , rows ) ;
185+
186+ /** `driver-mongodb`'s surface on this pin's read path, by code path (see the header). */
187+ const mongodbByCodePath = ( ) =>
188+ noSqlDriverByCodePath ( 'os21647.mongodb-by-code-path' , {
189+ batchSchemaSync : true ,
190+ queryDateGranularity : Object . fromEntries ( GRANULARITIES . map ( ( g ) => [ g , true ] ) ) ,
191+ } ) ;
192+
177193const DRIVER_ROWS = {
178- memory : [ { face : 'driver-memory' , build : ( ) => new InMemoryDriver ( ) as unknown as EnumeratedDriver } ] ,
194+ memory : [ { face : 'driver-memory, by code path ' , build : ( ) => memoryByCodePath ( ) } ] ,
179195 sqlite : [ { face : 'driver-sql, better-sqlite3' , build : sqliteDriver , release : releaseKnex } ] ,
180196 'sqlite-wasm' : [
181197 {
@@ -360,12 +376,13 @@ describe('[#21647] the echo of a date bucket: driver x timezone class x granular
360376} ) ;
361377
362378/**
363- * [#21647] The rows, on the real `driver-memory`: `/analytics/query` serves
364- * them with no `sql`, and the dry run refuses. The driver is only asked for
365- * rows; the engine buckets them in memory. d2 (20:00 UTC on 31 January) stays
366- * in January at UTC.
379+ * [#21647] The rows, on `driver-memory`'s surface (by code path, see the
380+ * header): `/analytics/query` serves them with no `sql`, and the dry run
381+ * refuses. The driver is only asked for rows, and the real engine buckets them
382+ * in memory. d2 (20:00 UTC on 31 January) stays in January at UTC. These are
383+ * the rows #21647 measured on the real driver.
367384 */
368- describe ( '[#21647] driver-memory, live : the query serves its rows with no `sql`, and the dry run refuses' , ( ) => {
385+ describe ( '[#21647] driver-memory\'s surface : the query serves its rows with no `sql`, and the dry run refuses' , ( ) => {
369386 const DEALS = [
370387 { id : 'd1' , closed_at : '2026-01-10T10:00:00.000Z' , amount : 20 } ,
371388 { id : 'd2' , closed_at : '2026-01-31T20:00:00.000Z' , amount : 7 } ,
@@ -380,17 +397,15 @@ describe('[#21647] driver-memory, live: the query serves its rows with no `sql`,
380397 const doors : string [ ] = [ ] ;
381398
382399 beforeAll ( async ( ) => {
383- const driver = new InMemoryDriver ( ) ;
400+ const driver = memoryByCodePath ( DEALS ) ;
384401 const aggregate = driver . aggregate . bind ( driver ) ;
385402 const find = driver . find . bind ( driver ) ;
386- ( driver as any ) . aggregate = async ( ...args : any [ ] ) => { doors . push ( 'aggregate' ) ; return ( aggregate as any ) ( ...args ) ; } ;
387- ( driver as any ) . find = async ( ...args : any [ ] ) => { doors . push ( 'find' ) ; return ( find as any ) ( ...args ) ; } ;
403+ driver . aggregate = async ( ...args : unknown [ ] ) => { doors . push ( 'aggregate' ) ; return aggregate ( ...args ) ; } ;
404+ driver . find = async ( ...args : unknown [ ] ) => { doors . push ( 'find' ) ; return find ( ...args ) ; } ;
388405 engine = new ObjectQL ( { logger : quiet } as any ) ;
389406 engine . registerDriver ( driver as any , true ) ;
390407 await engine . init ( ) ;
391408 engine . registry . registerObject ( DEAL_OBJECT as any ) ;
392- await engine . syncSchemas ( ) ;
393- for ( const row of DEALS ) await engine . insert ( DEAL , { ...row } as any ) ;
394409
395410 const registered : Record < string , unknown > = { } ;
396411 await new AnalyticsServicePlugin ( { cubes : CUBES , debugSql : true } as any ) . init ( {
0 commit comments