From 02027bba625a598c55ba1a97f973b0881a0f597c Mon Sep 17 00:00:00 2001 From: "ethan.chen" Date: Thu, 8 Jan 2026 11:32:19 +0800 Subject: [PATCH] refactor: Improve database initialization script by separating CREATE TABLE and CREATE INDEX statements, enhancing error handling, and providing clearer logging --- scripts/init-db.ts | 76 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/scripts/init-db.ts b/scripts/init-db.ts index bd1b289..a249ac0 100644 --- a/scripts/init-db.ts +++ b/scripts/init-db.ts @@ -102,32 +102,84 @@ async function initDatabase() { console.log(`Reading schema from ${schemaPath}...`); const schema = readFileSync(schemaPath, "utf-8"); - // Split by semicolons and execute each statement - const statements = schema + // Split by semicolons and filter out comments and empty statements + const allStatements = schema .split(";") .map((s) => s.trim()) .filter((s) => s.length > 0 && !s.startsWith("--")); - console.log(`Executing ${statements.length} SQL statements...`); + // Separate CREATE TABLE and CREATE INDEX statements + const tableStatements: string[] = []; + const indexStatements: string[] = []; - for (const statement of statements) { + for (const statement of allStatements) { + const upperStatement = statement.toUpperCase().trim(); + if (upperStatement.startsWith("CREATE TABLE")) { + tableStatements.push(statement); + } else if (upperStatement.startsWith("CREATE INDEX")) { + indexStatements.push(statement); + } + } + + console.log( + `Found ${tableStatements.length} table(s) and ${indexStatements.length} index(es) to create` + ); + + // First, create all tables + console.log("\nCreating tables..."); + for (const statement of tableStatements) { if (statement) { try { - // Use postgres.unsafe() to execute raw SQL - await (sql as any).unsafe(statement); - console.log(`✓ Executed: ${statement.substring(0, 50)}...`); + await (sql as any).unsafe(statement + ";"); + const tableName = + statement.match( + /CREATE TABLE\s+(?:IF NOT EXISTS\s+)?(\w+)/i + )?.[1] || "unknown"; + console.log(`✓ Created table: ${tableName}`); } catch (error) { - // Check if it's a "already exists" error (which is OK) const errorMessage = (error as Error).message; if ( errorMessage.includes("already exists") || errorMessage.includes("duplicate") ) { - console.log( - `⚠ Skipped (already exists): ${statement.substring(0, 50)}...` - ); + const tableName = + statement.match( + /CREATE TABLE\s+(?:IF NOT EXISTS\s+)?(\w+)/i + )?.[1] || "unknown"; + console.log(`⚠ Table already exists: ${tableName}`); } else { - console.error(`✗ Error executing statement: ${errorMessage}`); + console.error(`✗ Error creating table: ${errorMessage}`); + console.error(` Statement: ${statement.substring(0, 100)}...`); + throw error; + } + } + } + } + + // Then, create all indexes + console.log("\nCreating indexes..."); + for (const statement of indexStatements) { + if (statement) { + try { + await (sql as any).unsafe(statement + ";"); + const indexName = + statement.match( + /CREATE INDEX\s+(?:IF NOT EXISTS\s+)?(\w+)/i + )?.[1] || "unknown"; + console.log(`✓ Created index: ${indexName}`); + } catch (error) { + const errorMessage = (error as Error).message; + if ( + errorMessage.includes("already exists") || + errorMessage.includes("duplicate") + ) { + const indexName = + statement.match( + /CREATE INDEX\s+(?:IF NOT EXISTS\s+)?(\w+)/i + )?.[1] || "unknown"; + console.log(`⚠ Index already exists: ${indexName}`); + } else { + console.error(`✗ Error creating index: ${errorMessage}`); console.error(` Statement: ${statement.substring(0, 100)}...`); throw error; }