Fix prepared statements to prepare once at init
This commit is contained in:
parent
596b0fd013
commit
76a81666a2
1 changed files with 61 additions and 64 deletions
125
src/db.ts
125
src/db.ts
|
|
@ -5,6 +5,21 @@ import type { Device, OutputLog, Prompt, Session } from "./types";
|
|||
|
||||
let db: Database;
|
||||
|
||||
// Prepared statements - initialized once in initDb()
|
||||
let createDeviceStmt: ReturnType<Database["prepare"]>;
|
||||
let getDeviceBySecretStmt: ReturnType<Database["prepare"]>;
|
||||
let updateLastSeenStmt: ReturnType<Database["prepare"]>;
|
||||
let createSessionStmt: ReturnType<Database["prepare"]>;
|
||||
let getSessionStmt: ReturnType<Database["prepare"]>;
|
||||
let endSessionStmt: ReturnType<Database["prepare"]>;
|
||||
let getActiveSessionsStmt: ReturnType<Database["prepare"]>;
|
||||
let createPromptStmt: ReturnType<Database["prepare"]>;
|
||||
let getPromptStmt: ReturnType<Database["prepare"]>;
|
||||
let respondToPromptStmt: ReturnType<Database["prepare"]>;
|
||||
let getPendingPromptsStmt: ReturnType<Database["prepare"]>;
|
||||
let appendOutputStmt: ReturnType<Database["prepare"]>;
|
||||
let getSessionOutputStmt: ReturnType<Database["prepare"]>;
|
||||
|
||||
export function initDb(path = "claude-remote.db"): Database {
|
||||
db = new Database(path);
|
||||
|
||||
|
|
@ -47,126 +62,108 @@ export function initDb(path = "claude-remote.db"): Database {
|
|||
);
|
||||
`);
|
||||
|
||||
// Prepare all statements once
|
||||
createDeviceStmt = db.prepare(
|
||||
"INSERT INTO devices (secret, name, created_at, last_seen) VALUES (?, ?, ?, ?) RETURNING *",
|
||||
);
|
||||
getDeviceBySecretStmt = db.prepare("SELECT * FROM devices WHERE secret = ?");
|
||||
updateLastSeenStmt = db.prepare(
|
||||
"UPDATE devices SET last_seen = ? WHERE id = ?",
|
||||
);
|
||||
createSessionStmt = db.prepare(
|
||||
"INSERT INTO sessions (device_id, started_at, cwd, command) VALUES (?, ?, ?, ?) RETURNING *",
|
||||
);
|
||||
getSessionStmt = db.prepare("SELECT * FROM sessions WHERE id = ?");
|
||||
endSessionStmt = db.prepare("UPDATE sessions SET ended_at = ? WHERE id = ?");
|
||||
getActiveSessionsStmt = db.prepare(
|
||||
"SELECT * FROM sessions WHERE ended_at IS NULL ORDER BY started_at DESC",
|
||||
);
|
||||
createPromptStmt = db.prepare(
|
||||
"INSERT INTO prompts (session_id, created_at, prompt_text) VALUES (?, ?, ?) RETURNING *",
|
||||
);
|
||||
getPromptStmt = db.prepare("SELECT * FROM prompts WHERE id = ?");
|
||||
respondToPromptStmt = db.prepare(
|
||||
"UPDATE prompts SET response = ?, responded_at = ? WHERE id = ?",
|
||||
);
|
||||
getPendingPromptsStmt = db.prepare(
|
||||
"SELECT * FROM prompts WHERE response IS NULL ORDER BY created_at ASC",
|
||||
);
|
||||
appendOutputStmt = db.prepare(
|
||||
"INSERT INTO output_log (session_id, timestamp, line) VALUES (?, ?, ?)",
|
||||
);
|
||||
getSessionOutputStmt = db.prepare(
|
||||
"SELECT * FROM output_log WHERE session_id = ? ORDER BY timestamp ASC",
|
||||
);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
// Device functions
|
||||
|
||||
const createDeviceStmt = () =>
|
||||
db.prepare(
|
||||
"INSERT INTO devices (secret, name, created_at, last_seen) VALUES (?, ?, ?, ?) RETURNING *",
|
||||
);
|
||||
|
||||
export function createDevice(
|
||||
secret: string,
|
||||
name: string | null = null,
|
||||
): Device {
|
||||
const now = Date.now();
|
||||
return createDeviceStmt().get(secret, name, now, now) as Device;
|
||||
return createDeviceStmt.get(secret, name, now, now) as Device;
|
||||
}
|
||||
|
||||
const getDeviceBySecretStmt = () =>
|
||||
db.prepare("SELECT * FROM devices WHERE secret = ?");
|
||||
|
||||
export function getDeviceBySecret(secret: string): Device | null {
|
||||
return (getDeviceBySecretStmt().get(secret) as Device) ?? null;
|
||||
return (getDeviceBySecretStmt.get(secret) as Device) ?? null;
|
||||
}
|
||||
|
||||
const updateLastSeenStmt = () =>
|
||||
db.prepare("UPDATE devices SET last_seen = ? WHERE id = ?");
|
||||
|
||||
export function updateLastSeen(deviceId: number): void {
|
||||
updateLastSeenStmt().run(Date.now(), deviceId);
|
||||
updateLastSeenStmt.run(Date.now(), deviceId);
|
||||
}
|
||||
|
||||
// Session functions
|
||||
|
||||
const createSessionStmt = () =>
|
||||
db.prepare(
|
||||
"INSERT INTO sessions (device_id, started_at, cwd, command) VALUES (?, ?, ?, ?) RETURNING *",
|
||||
);
|
||||
|
||||
export function createSession(
|
||||
deviceId: number,
|
||||
cwd: string | null = null,
|
||||
command: string | null = null,
|
||||
): Session {
|
||||
const now = Date.now();
|
||||
return createSessionStmt().get(deviceId, now, cwd, command) as Session;
|
||||
return createSessionStmt.get(deviceId, now, cwd, command) as Session;
|
||||
}
|
||||
|
||||
const getSessionStmt = () => db.prepare("SELECT * FROM sessions WHERE id = ?");
|
||||
|
||||
export function getSession(sessionId: number): Session | null {
|
||||
return (getSessionStmt().get(sessionId) as Session) ?? null;
|
||||
return (getSessionStmt.get(sessionId) as Session) ?? null;
|
||||
}
|
||||
|
||||
const endSessionStmt = () =>
|
||||
db.prepare("UPDATE sessions SET ended_at = ? WHERE id = ?");
|
||||
|
||||
export function endSession(sessionId: number): void {
|
||||
endSessionStmt().run(Date.now(), sessionId);
|
||||
endSessionStmt.run(Date.now(), sessionId);
|
||||
}
|
||||
|
||||
const getActiveSessionsStmt = () =>
|
||||
db.prepare(
|
||||
"SELECT * FROM sessions WHERE ended_at IS NULL ORDER BY started_at DESC",
|
||||
);
|
||||
|
||||
export function getActiveSessions(): Session[] {
|
||||
return getActiveSessionsStmt().all() as Session[];
|
||||
return getActiveSessionsStmt.all() as Session[];
|
||||
}
|
||||
|
||||
// Prompt functions
|
||||
|
||||
const createPromptStmt = () =>
|
||||
db.prepare(
|
||||
"INSERT INTO prompts (session_id, created_at, prompt_text) VALUES (?, ?, ?) RETURNING *",
|
||||
);
|
||||
|
||||
export function createPrompt(sessionId: number, promptText: string): Prompt {
|
||||
const now = Date.now();
|
||||
return createPromptStmt().get(sessionId, now, promptText) as Prompt;
|
||||
return createPromptStmt.get(sessionId, now, promptText) as Prompt;
|
||||
}
|
||||
|
||||
const getPromptStmt = () => db.prepare("SELECT * FROM prompts WHERE id = ?");
|
||||
|
||||
export function getPrompt(promptId: number): Prompt | null {
|
||||
return (getPromptStmt().get(promptId) as Prompt) ?? null;
|
||||
return (getPromptStmt.get(promptId) as Prompt) ?? null;
|
||||
}
|
||||
|
||||
const respondToPromptStmt = () =>
|
||||
db.prepare("UPDATE prompts SET response = ?, responded_at = ? WHERE id = ?");
|
||||
|
||||
export function respondToPrompt(promptId: number, response: string): void {
|
||||
respondToPromptStmt().run(response, Date.now(), promptId);
|
||||
respondToPromptStmt.run(response, Date.now(), promptId);
|
||||
}
|
||||
|
||||
const getPendingPromptsStmt = () =>
|
||||
db.prepare(
|
||||
"SELECT * FROM prompts WHERE response IS NULL ORDER BY created_at ASC",
|
||||
);
|
||||
|
||||
export function getPendingPrompts(): Prompt[] {
|
||||
return getPendingPromptsStmt().all() as Prompt[];
|
||||
return getPendingPromptsStmt.all() as Prompt[];
|
||||
}
|
||||
|
||||
// OutputLog functions
|
||||
|
||||
const appendOutputStmt = () =>
|
||||
db.prepare(
|
||||
"INSERT INTO output_log (session_id, timestamp, line) VALUES (?, ?, ?)",
|
||||
);
|
||||
|
||||
export function appendOutput(sessionId: number, line: string): void {
|
||||
appendOutputStmt().run(sessionId, Date.now(), line);
|
||||
appendOutputStmt.run(sessionId, Date.now(), line);
|
||||
}
|
||||
|
||||
const getSessionOutputStmt = () =>
|
||||
db.prepare(
|
||||
"SELECT * FROM output_log WHERE session_id = ? ORDER BY timestamp ASC",
|
||||
);
|
||||
|
||||
export function getSessionOutput(sessionId: number): OutputLog[] {
|
||||
return getSessionOutputStmt().all(sessionId) as OutputLog[];
|
||||
return getSessionOutputStmt.all(sessionId) as OutputLog[];
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue