Add opt-in slow SQL and database diagnostics

This commit is contained in:
2026-10-06 13:56:27 -04:00
parent dd2fe2cc7a
commit 8e948c07d9
7 changed files with 80 additions and 1 deletions
+32
View File
@@ -0,0 +1,32 @@
import Database from 'better-sqlite3';
import { afterEach, expect, it, vi } from 'vitest';
import { timeStatement } from '../../src/lib/server/db/slow-statements.js';
afterEach(() => vi.restoreAllMocks());
it('preserves results and errors, logs slow query shapes without values', () => {
const db = new Database(':memory:');
const log = vi.spyOn(console, 'warn').mockImplementation(() => {});
vi.spyOn(performance, 'now').mockReturnValueOnce(0).mockReturnValueOnce(21)
.mockReturnValueOnce(30).mockReturnValueOnce(31).mockReturnValueOnce(40).mockReturnValueOnce(62);
try {
const query = timeStatement(db.prepare("SELECT ? AS value, 'private''literal' AS literal"), "SELECT ? AS value, 'private''literal' AS literal", 20);
expect(query.get('secret')).toEqual({ value: 'secret', literal: "private'literal" });
expect(query.all('other')).toHaveLength(1);
expect(() => query.get()).toThrow();
expect(log).toHaveBeenCalledTimes(2);
expect(log.mock.calls[0]).toEqual(['[sql]', { ms: 21, method: 'get', sql: 'SELECT ? AS value, ? AS literal' }]);
expect(JSON.stringify(log.mock.calls)).not.toMatch(/secret|private|other/);
} finally { db.close(); }
});
it('does not wrap statements when disabled or invalid', () => {
const db = new Database(':memory:');
try {
const statement = db.prepare('SELECT 1');
const get = statement.get;
for (const threshold of [0, -1, NaN, Infinity]) {
expect(timeStatement(statement, 'SELECT 1', threshold).get).toBe(get);
}
} finally { db.close(); }
});