| ... | ... | @@ -84,6 +84,36 @@ it.effect("shrinks the WAL file back to the size limit after a large write", () |
| 84 | 84 | ); |
| 85 | 85 | }); |
| 86 | 86 | |
| 87 | it.effect("collects planner statistics for an existing database on open", () => { |
| 88 | const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-sqlite-stats-")); |
| 89 | const dbPath = NodePath.join(tempDir, "state.sqlite"); |
| 90 | const persistence = () => |
| 91 | SqlitePersistence.layerFromPath(dbPath).pipe(Layer.provide(NodeServices.layer)); |
| 92 | |
| 93 | return Effect.gen(function* () { |
| 94 | yield* Effect.gen(function* () { |
| 95 | const sql = yield* SqlClient.SqlClient; |
| 96 | yield* sql`CREATE TABLE stats_probe(id INTEGER PRIMARY KEY, thread_id TEXT NOT NULL)`; |
| 97 | yield* sql`CREATE INDEX stats_probe_thread_idx ON stats_probe(thread_id)`; |
| 98 | yield* sql` |
| 99 | WITH RECURSIVE n(i) AS (SELECT 1 UNION ALL SELECT i + 1 FROM n WHERE i < 1000) |
| 100 | INSERT INTO stats_probe(thread_id) SELECT 'thread-' || (i % 10) FROM n |
| 101 | `; |
| 102 | }).pipe(Effect.provide(persistence())); |
| 103 | |
| 104 | // A database written before statistics existed gets them on the next open. |
| 105 | yield* Effect.gen(function* () { |
| 106 | const sql = yield* SqlClient.SqlClient; |
| 107 | const rows = yield* sql<{ readonly stat: string }>` |
| 108 | SELECT stat FROM sqlite_stat1 WHERE idx = 'stats_probe_thread_idx' |
| 109 | `; |
| 110 | assert.deepEqual([...rows], [{ stat: "1000 100" }]); |
| 111 | }).pipe(Effect.provide(persistence())); |
| 112 | }).pipe( |
| 113 | Effect.ensuring(Effect.sync(() => NodeFS.rmSync(tempDir, { recursive: true, force: true }))), |
| 114 | ); |
| 115 | }); |
| 116 | |
| 87 | 117 | it.effect("applies busy_timeout in the shared persistence setup", () => |
| 88 | 118 | Effect.gen(function* () { |
| 89 | 119 | const sql = yield* SqlClient.SqlClient; |