1314However, you should know that SQLite has much more limited
15support for altering existing tables as compared to other databases.
16Often it's easier to create new tables with the schema you want, and then
17copy the data over. */
reactHonoExampleindex.ts1 match
1import { parseProject, readFile, serveFile } from "https://esm.town/v/std/utils/index.ts";
2import { Hono } from "npm:hono";
3import { getMessages, insertMessage } from "./database/queries.ts";
45const app = new Hono();
sqliteExplorerAppREADME.md1 match
30- [ ] add triggers to sidebar
31- [ ] add upload from SQL, CSV and JSON
32- [ ] add ability to connect to a non-val town Turso database
33- [x] fix wonky sidebar separator height problem (thanks to @stevekrouse)
34- [x] make result tables scrollable
critprocess_definitions.ts1 match
29type: "text",
30mapsTo: "incidentType",
31placeholder: "e.g., Unplanned database downtime",
32},
33{
1import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
2import logger from '../utils/logger.ts';
3import { DatabaseError } from '../utils/error-handler.ts';
45// Create a logger for database operations
6const log = logger.createLogger('Database');
78// Table names - use versioning to allow for schema changes
12const EXAMPLES_TABLE = "abuse_analyzer_examples_v1";
1314// Types for our database entities
15export interface Session {
16id: string;
5051/**
52* Initialize database tables
53*/
54export async function initDatabase(): Promise<void> {
55try {
56log.info("Initializing database tables");
57
58// Create sessions table
109`);
110
111log.info("Database tables initialized successfully");
112} catch (error) {
113log.error("Failed to initialize database tables:", error);
114throw new DatabaseError("Failed to initialize database", error instanceof Error ? error : undefined);
115}
116}
140} catch (error) {
141log.error(`Failed to create session "${title}":`, error);
142throw new DatabaseError("Failed to create session", error instanceof Error ? error : undefined);
143}
144}
163} catch (error) {
164log.error(`Failed to get session ${id}:`, error);
165throw new DatabaseError("Failed to get session", error instanceof Error ? error : undefined);
166}
167}
182} catch (error) {
183log.error(`Failed to update session timestamp ${id}:`, error);
184throw new DatabaseError("Failed to update session timestamp", error instanceof Error ? error : undefined);
185}
186}
199} catch (error) {
200log.error("Failed to get all sessions:", error);
201throw new DatabaseError("Failed to get all sessions", error instanceof Error ? error : undefined);
202}
203}
218} catch (error) {
219log.error(`Failed to update session title ${id}:`, error);
220throw new DatabaseError("Failed to update session title", error instanceof Error ? error : undefined);
221}
222}
259} catch (error) {
260log.error(`Failed to delete session ${id}:`, error);
261throw new DatabaseError("Failed to delete session", error instanceof Error ? error : undefined);
262}
263}
293} catch (error) {
294log.error(`Failed to add message to session ${session_id}:`, error);
295throw new DatabaseError("Failed to add message", error instanceof Error ? error : undefined);
296}
297}
311} catch (error) {
312log.error(`Failed to get messages for session ${session_id}:`, error);
313throw new DatabaseError("Failed to get session messages", error instanceof Error ? error : undefined);
314}
315}
355} catch (error) {
356log.error(`Failed to get threaded messages for session ${session_id}:`, error);
357throw new DatabaseError("Failed to get threaded messages", error instanceof Error ? error : undefined);
358}
359}
385} catch (error) {
386log.error(`Failed to add pattern to session ${session_id}:`, error);
387throw new DatabaseError("Failed to add pattern", error instanceof Error ? error : undefined);
388}
389}
403} catch (error) {
404log.error(`Failed to get patterns for session ${session_id}:`, error);
405throw new DatabaseError("Failed to get session patterns", error instanceof Error ? error : undefined);
406}
407}
426} catch (error) {
427log.error(`Failed to get pattern ${pattern_id}:`, error);
428throw new DatabaseError("Failed to get pattern", error instanceof Error ? error : undefined);
429}
430}
444} catch (error) {
445log.error(`Failed to get patterns by type for session ${session_id}:`, error);
446throw new DatabaseError("Failed to get patterns by type", error instanceof Error ? error : undefined);
447}
448}
479} catch (error) {
480log.error(`Failed to add example to pattern ${pattern_id}:`, error);
481throw new DatabaseError("Failed to add example", error instanceof Error ? error : undefined);
482}
483}
497} catch (error) {
498log.error(`Failed to get examples for pattern ${pattern_id}:`, error);
499throw new DatabaseError("Failed to get pattern examples", error instanceof Error ? error : undefined);
500}
501}
519} catch (error) {
520log.error(`Failed to get pattern with examples ${pattern_id}:`, error);
521throw new DatabaseError("Failed to get pattern with examples", error instanceof Error ? error : undefined);
522}
523}
544} catch (error) {
545log.error(`Failed to get patterns with examples for session ${session_id}:`, error);
546throw new DatabaseError("Failed to get session patterns with examples", error instanceof Error ? error : undefined);
547}
548}
con-juanerror-handler.ts4 matches
1617/**
18* Error for database operations
19*/
20export class DatabaseError extends AppError {
21public originalError?: Error;
22
23constructor(message: string, originalError?: Error) {
24super(message);
25this.name = 'DatabaseError';
26this.originalError = originalError;
27}
118export default {
119AppError,
120DatabaseError,
121APIError,
122AnalysisError,
10- Tests for edge cases and error handling
1112- **database.test.ts**: Tests for database operations
13- Tests for CRUD operations on all tables
14- Tests for recursive queries and threaded conversations
13- `static-file-server.ts`: Static file server for the frontend
1415- **database/**: Database operations
16- `index.ts`: SQLite database operations for sessions, messages, patterns, and examples
1718- **utils/**: Utility functions
32- `processAIResponse`: Processes the AI response into a structured format
3334### Database
3536The database module provides functions for storing and retrieving data from SQLite. It uses recursive common table expressions (CTEs) to handle threaded conversations.
3738Key tables:
con-juanchat-api.test.ts4 matches
1import { assertEquals, assertExists } from "https://deno.land/std/testing/asserts.ts";
2import * as db from "../src/database/index.ts";
34/**
6*
7* These tests verify the functionality of the chat API operations.
8* They test the database operations that the API relies on.
9*/
1014let testPatternId: number;
1516// Setup: Initialize database
17Deno.test("ChatAPI - Setup", async () => {
18await db.initDatabase();
19});
20
con-juandatabase.test.ts20 matches
1import { assertEquals, assertExists, assertNotEquals } from "https://deno.land/std/testing/asserts.ts";
2import * as db from "../src/database/index.ts";
34/**
5* Database module tests
6*
7* These tests verify the functionality of the database operations.
8* They should be run in sequence as they build on each other.
9*/
15let testExampleId: number;
1617Deno.test("Database - Initialize database", async () => {
18await db.initDatabase();
19// If no error is thrown, the test passes
20});
2122Deno.test("Database - Create session", async () => {
23const session = await db.createSession("Test Session");
24
31});
3233Deno.test("Database - Get session", async () => {
34const session = await db.getSession(testSessionId);
35
39});
4041Deno.test("Database - Update session title", async () => {
42await db.updateSessionTitle(testSessionId, "Updated Test Session");
43
46});
4748Deno.test("Database - Add message", async () => {
49const messageId = await db.addMessage(
50testSessionId,
59});
6061Deno.test("Database - Get session messages", async () => {
62const messages = await db.getSessionMessages(testSessionId);
63
68});
6970Deno.test("Database - Add pattern", async () => {
71const patternId = await db.addPattern(
72testSessionId,
84});
8586Deno.test("Database - Get pattern", async () => {
87const pattern = await db.getPattern(testPatternId);
88
94});
9596Deno.test("Database - Add example", async () => {
97const exampleId = await db.addExample(
98testPatternId,
107});
108109Deno.test("Database - Get pattern examples", async () => {
110const examples = await db.getPatternExamples(testPatternId);
111
116});
117118Deno.test("Database - Get pattern with examples", async () => {
119const pattern = await db.getPatternWithExamples(testPatternId);
120
124});
125126Deno.test("Database - Add threaded message", async () => {
127const threadedMessageId = await db.addMessage(
128testSessionId,
135});
136137Deno.test("Database - Get threaded messages", async () => {
138const messages = await db.getThreadedMessages(testSessionId, testMessageId);
139
144});
145146Deno.test("Database - Get session patterns with examples", async () => {
147const patterns = await db.getSessionPatternsWithExamples(testSessionId);
148
153});
154155Deno.test("Database - Get all sessions", async () => {
156const sessions = await db.getAllSessions();
157
164});
165166Deno.test("Database - Delete session", async () => {
167await db.deleteSession(testSessionId);
168