brief-20/backend/src/database/database.service.ts

98 lines
3.1 KiB
TypeScript

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import * as schema from './schema';
import { runMigrations } from './migrations/migrate';
@Injectable()
export class DatabaseService implements OnModuleInit, OnModuleDestroy {
private readonly pool: Pool;
private readonly db: ReturnType<typeof drizzle>;
constructor(private configService: ConfigService) {
// Create the PostgreSQL pool
const connectionString = this.getDatabaseConnectionString();
this.pool = new Pool({
connectionString,
});
// Create the Drizzle ORM instance
this.db = drizzle(this.pool, { schema });
}
async onModuleInit() {
// Log database connection
console.log('Connecting to database...');
// Test the connection
try {
const client = await this.pool.connect();
try {
await client.query('SELECT NOW()');
console.log('Database connection established successfully');
} finally {
client.release();
}
} catch (error) {
console.error('Failed to connect to database:', error.message);
throw error;
}
// Run migrations in all environments
const result = await runMigrations({ migrationsFolder: './src/database/migrations/sql' });
// In production, we want to fail if migrations fail
if (!result.success && this.configService.get('NODE_ENV') === 'production') {
throw result.error;
}
}
async onModuleDestroy() {
// Close the database connection
await this.pool.end();
console.log('Database connection closed');
}
// Get the database connection string from environment variables
private getDatabaseConnectionString(): string {
// First try to get the full DATABASE_URL
const databaseUrl = this.configService.get<string>('DATABASE_URL');
if (databaseUrl) {
return databaseUrl;
}
// If DATABASE_URL is not provided, construct it from individual variables
const password = this.configService.get<string>('POSTGRES_PASSWORD');
const username = this.configService.get<string>('POSTGRES_USER');
const host = this.configService.get<string>('POSTGRES_HOST');
const port = this.configService.get<string>('POSTGRES_PORT');
const database = this.configService.get<string>('POSTGRES_DB');
const missingVars: string[] = [];
if (!password) missingVars.push('POSTGRES_PASSWORD');
if (!username) missingVars.push('POSTGRES_USER');
if (!host) missingVars.push('POSTGRES_HOST');
if (!port) missingVars.push('POSTGRES_PORT');
if (!database) missingVars.push('POSTGRES_DB');
if (missingVars.length > 0) {
throw new Error(
`Database configuration is missing. Missing variables: ${missingVars.join(', ')}. Please check your .env file.`,
);
}
return `postgres://${username}:${password}@${host}:${port}/${database}`;
}
// Get the Drizzle ORM instance
getDb() {
return this.db;
}
// Get the PostgreSQL pool
getPool() {
return this.pool;
}
}