diff --git a/api-client/deno.json b/api-client/deno.json index 82b2023..7ea3508 100644 --- a/api-client/deno.json +++ b/api-client/deno.json @@ -3,7 +3,7 @@ "@preact/signals": "npm:@preact/signals@^2.9.0" }, "name": "@01edu/api-client", - "version": "0.2.2", + "version": "0.2.3", "license": "MIT", "exports": { ".": "./mod.ts" }, "compilerOptions": { diff --git a/api/deno.json b/api/deno.json index dde8484..274cb9e 100644 --- a/api/deno.json +++ b/api/deno.json @@ -4,7 +4,7 @@ "@std/http": "jsr:@std/http@^1.0.25" }, "name": "@01edu/api", - "version": "0.2.2", + "version": "0.2.3", "license": "MIT", "exports": { "./context": "./context.ts", diff --git a/db/deno.json b/db/deno.json index 5a194e1..e6911ea 100644 --- a/db/deno.json +++ b/db/deno.json @@ -1,10 +1,10 @@ { "imports": { - "@db/sqlite": "jsr:@db/sqlite@^0.13.0", + "@db/sqlite": "jsr:@cd/sqlite@^0.13.1", "@std/assert": "jsr:@std/assert@^1.0.19" }, "name": "@01edu/db", - "version": "0.2.2", + "version": "0.2.3", "license": "MIT", "exports": { ".": "./mod.ts", diff --git a/db/mod.ts b/db/mod.ts index a645f13..4f50fc9 100644 --- a/db/mod.ts +++ b/db/mod.ts @@ -7,10 +7,9 @@ */ import { assertEquals } from '@std/assert/equals' -import { Database } from '@db/sqlite' -import type { BindParameters, BindValue, Statement } from '@db/sqlite' +import { Database, type BindParameters, type BindValue } from '@db/sqlite' import type { Expand, MatchKeys, UnionToIntersection } from '@01edu/types' -import type { ExplainRow, Metric, Sql, StatementStatus } from '@01edu/types/db' +import type { ExplainRow, Metric, Sql } from '@01edu/types/db' import { respond } from '@01edu/api/response' import { APP_ENV, DISABLE_QUERY_METRICS, ENV } from '@01edu/api/env' @@ -419,7 +418,17 @@ export const sql: Sql = < duration: 0, max: 0, get status() { - return readStmtStatus(stmt) + return { + fullscanStep: stmt.statusFullscanStep(), + sort: stmt.statusSort(), + autoindex: stmt.statusAutoindex(), + vmStep: stmt.statusVmStep(), + reprepare: stmt.statusReprepare(), + run: stmt.statusRun(), + filterHit: stmt.statusFilterHit(), + filterMiss: stmt.statusFilterMiss(), + memused: stmt.statusMemused(), + } }, } @@ -510,82 +519,3 @@ export const sqlCheck = ( return ((params: T) => value(params)?.[0] === 1) } -let readStmtStatus = ( - _: Statement>, -): StatementStatus => ({ - fullscanStep: 0, - sort: 0, - autoindex: 0, - vmStep: 0, - reprepare: 0, - run: 0, - filterMiss: 0, - filterHit: 0, -}) - -if (!DISABLE_QUERY_METRICS) { - const defaultSqliteLibPath = (): string => { - switch (Deno.build.os) { - case 'darwin': - return 'libsqlite3.dylib' - case 'linux': - return 'libsqlite3.so' - case 'windows': - return 'sqlite3.dll' - default: - throw new Error(`Unsupported OS: ${Deno.build.os}`) - } - } - - const sqliteLibPath = Deno.env.get('SQLITE3_LIB_PATH') ?? - defaultSqliteLibPath() - const lib = Deno.dlopen(sqliteLibPath, { - sqlite3_stmt_status: { - parameters: ['pointer', 'i32', 'i32'], - result: 'i32', - }, - }) - const { sqlite3_stmt_status } = lib.symbols - - // These match SQLite's documented SQLITE_STMTSTATUS_* constants. - // https://sqlite.org/c3ref/c_stmtstatus_counter.html - const SQLITE_STMTSTATUS_FULLSCAN_STEP = 1 - const SQLITE_STMTSTATUS_SORT = 2 - const SQLITE_STMTSTATUS_AUTOINDEX = 3 - const SQLITE_STMTSTATUS_VM_STEP = 4 - const SQLITE_STMTSTATUS_REPREPARE = 5 - const SQLITE_STMTSTATUS_RUN = 6 - const SQLITE_STMTSTATUS_FILTER_MISS = 7 - const SQLITE_STMTSTATUS_FILTER_HIT = 8 - const SQLITE_STMTSTATUS_MEMUSED = 99 - - type StmtStatusOp = - | typeof SQLITE_STMTSTATUS_FULLSCAN_STEP - | typeof SQLITE_STMTSTATUS_SORT - | typeof SQLITE_STMTSTATUS_AUTOINDEX - | typeof SQLITE_STMTSTATUS_VM_STEP - | typeof SQLITE_STMTSTATUS_REPREPARE - | typeof SQLITE_STMTSTATUS_RUN - | typeof SQLITE_STMTSTATUS_FILTER_MISS - | typeof SQLITE_STMTSTATUS_FILTER_HIT - | typeof SQLITE_STMTSTATUS_MEMUSED - - const stmtStatus = ( - stmt: Statement>, - op: StmtStatusOp, - ): number => sqlite3_stmt_status(stmt.unsafeHandle, op, 0) - - readStmtStatus = ( - stmt: Statement>, - ): StatementStatus => ({ - fullscanStep: stmtStatus(stmt, SQLITE_STMTSTATUS_FULLSCAN_STEP), - sort: stmtStatus(stmt, SQLITE_STMTSTATUS_SORT), - autoindex: stmtStatus(stmt, SQLITE_STMTSTATUS_AUTOINDEX), - vmStep: stmtStatus(stmt, SQLITE_STMTSTATUS_VM_STEP), - reprepare: stmtStatus(stmt, SQLITE_STMTSTATUS_REPREPARE), - run: stmtStatus(stmt, SQLITE_STMTSTATUS_RUN), - filterMiss: stmtStatus(stmt, SQLITE_STMTSTATUS_FILTER_MISS), - filterHit: stmtStatus(stmt, SQLITE_STMTSTATUS_FILTER_HIT), - // memUsed: stmtStatus(stmt, SQLITE_STMTSTATUS_MEMUSED), unsupported for some reason - }) -} diff --git a/deno.lock b/deno.lock index 51888db..cfe3224 100644 --- a/deno.lock +++ b/deno.lock @@ -1,8 +1,8 @@ { "version": "5", "specifiers": { + "jsr:@cd/sqlite@~0.13.1": "0.13.1", "jsr:@david/code-block-writer@^13.0.3": "13.0.3", - "jsr:@db/sqlite@0.13": "0.13.0", "jsr:@deno/dnt@~0.42.3": "0.42.3", "jsr:@denosaurs/plug@1": "1.1.0", "jsr:@std/assert@^1.0.19": "1.0.19", @@ -32,8 +32,8 @@ "@david/code-block-writer@13.0.3": { "integrity": "f98c77d320f5957899a61bfb7a9bead7c6d83ad1515daee92dbacc861e13bb7f" }, - "@db/sqlite@0.13.0": { - "integrity": "4545c635e0b3d4ddfdc0f2240f932f24b8ad0178e9c2e3a0f9403e7b18ae2fb5", + "@cd/sqlite@0.13.1": { + "integrity": "b1399921167e28857f15ad2728759d83b28471d6571a4a9ef8cb434fa0a8a9fe", "dependencies": [ "jsr:@denosaurs/plug", "jsr:@std/path@1.0" @@ -447,7 +447,7 @@ }, "db": { "dependencies": [ - "jsr:@db/sqlite@0.13", + "jsr:@cd/sqlite@~0.13.1", "jsr:@std/assert@^1.0.19" ] }, @@ -459,7 +459,7 @@ }, "types": { "dependencies": [ - "jsr:@db/sqlite@0.13" + "jsr:@cd/sqlite@~0.13.1" ] } } diff --git a/types/db.d.ts b/types/db.d.ts index 49cf916..3b6457c 100644 --- a/types/db.d.ts +++ b/types/db.d.ts @@ -59,6 +59,8 @@ export type StatementStatus = { filterHit: number /** The corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of times that the Bloom filter returned a find, and thus the join step had to be processed as normal. */ filterMiss: number + /** This is the approximate number of bytes of heap memory used to store the prepared statement. This value is not a counter. */ + memused: number } /** diff --git a/types/deno.json b/types/deno.json index ddfac6e..cdf9c21 100644 --- a/types/deno.json +++ b/types/deno.json @@ -1,9 +1,9 @@ { "imports": { - "@db/sqlite": "jsr:@db/sqlite@^0.13.0" + "@db/sqlite": "jsr:@cd/sqlite@^0.13.1" }, "name": "@01edu/types", - "version": "0.2.2", + "version": "0.2.3", "license": "MIT", "exports": { ".": "./mod.d.ts",