init-db.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import { readFile } from 'node:fs/promises';
  2. import { Client } from 'pg';
  3. const adminConnectionString = process.env.DATABASE_ADMIN_URL || 'postgres://postgres:postgres@localhost:5432/postgres';
  4. const appDatabase = process.env.PGAPP_DATABASE || 'tihao_ai';
  5. const appUser = process.env.PGAPP_USER || 'tihao_ai_app';
  6. const appPassword = process.env.PGAPP_PASSWORD || 'tihao_ai_app';
  7. async function main(): Promise<void> {
  8. const admin = new Client({ connectionString: adminConnectionString });
  9. await admin.connect();
  10. await admin.query(`DO $$
  11. BEGIN
  12. IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${escapeLiteral(appUser)}') THEN
  13. CREATE ROLE ${quoteIdent(appUser)} LOGIN PASSWORD '${escapeLiteral(appPassword)}';
  14. END IF;
  15. END
  16. $$;`);
  17. const dbExists = await admin.query('SELECT 1 FROM pg_database WHERE datname = $1', [appDatabase]);
  18. if (dbExists.rowCount === 0) {
  19. await admin.query(`CREATE DATABASE ${quoteIdent(appDatabase)} OWNER ${quoteIdent(appUser)}`);
  20. }
  21. await admin.end();
  22. const schema = await readFile('server/db/schema.sql', 'utf-8');
  23. const app = new Client({ connectionString: process.env.DATABASE_URL || `postgres://${appUser}:${appPassword}@localhost:5432/${appDatabase}` });
  24. await app.connect();
  25. await app.query(schema);
  26. await app.end();
  27. console.log(`Database initialized: ${appDatabase}`);
  28. }
  29. function quoteIdent(value: string): string {
  30. return `"${value.replace(/"/g, '""')}"`;
  31. }
  32. function escapeLiteral(value: string): string {
  33. return value.replace(/'/g, "''");
  34. }
  35. main().catch((error) => {
  36. console.error(error);
  37. process.exit(1);
  38. });