feat: implement database module and service with PostgreSQL integration and migrations support
This commit is contained in:
10
backend/src/database/database.module.ts
Normal file
10
backend/src/database/database.module.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
import { ConfigModule } from "@nestjs/config";
|
||||||
|
import { DatabaseService } from "./database.service";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
providers: [DatabaseService],
|
||||||
|
exports: [DatabaseService],
|
||||||
|
})
|
||||||
|
export class DatabaseModule {}
|
||||||
86
backend/src/database/database.service.ts
Normal file
86
backend/src/database/database.service.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Yidhra Studio. - All Rights Reserved
|
||||||
|
* Updated : 25/04/2025 10:52
|
||||||
|
*
|
||||||
|
* Unauthorized copying or redistribution of this file in source and binary forms via any medium
|
||||||
|
* is strictly prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Injectable, Logger, OnModuleDestroy, OnModuleInit} from "@nestjs/common";
|
||||||
|
import { ConfigService } from "@nestjs/config";
|
||||||
|
import { drizzle } from "drizzle-orm/node-postgres";
|
||||||
|
import { migrate } from "drizzle-orm/node-postgres/migrator";
|
||||||
|
import * as schema from "./schemas";
|
||||||
|
import {Pool} from "pg";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DatabaseService implements OnModuleInit, OnModuleDestroy {
|
||||||
|
private readonly logger = new Logger(DatabaseService.name);
|
||||||
|
private readonly pool!: Pool
|
||||||
|
public readonly db: ReturnType<typeof drizzle>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private configService: ConfigService
|
||||||
|
) {
|
||||||
|
// Create the PostgreSQL client
|
||||||
|
const connectionString = this.getDatabaseConnectionString();
|
||||||
|
this.pool = new Pool({ connectionString });
|
||||||
|
// Recreate drizzle with initialized pool
|
||||||
|
this.db = drizzle(this.pool, { schema });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async onModuleInit() {
|
||||||
|
try {
|
||||||
|
// Run migrations if in production mode
|
||||||
|
if (this.configService.get("NODE_ENV") === "production") {
|
||||||
|
this.logger.log("Running database migrations...");
|
||||||
|
await migrate(this.db, { migrationsFolder: ".migrations" });
|
||||||
|
this.logger.log("Database migrations completed successfully");
|
||||||
|
} else {
|
||||||
|
this.logger.debug("Skipping migrations in non-production environment");
|
||||||
|
}
|
||||||
|
this.logger.log("Database connection established successfully");
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error("Failed to initialize database connection", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onModuleDestroy() {
|
||||||
|
try {
|
||||||
|
// Close the database connection
|
||||||
|
await this.pool.end();
|
||||||
|
this.logger.log("Database connection closed successfully");
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error("Error closing database connection", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the database connection string from environment variables
|
||||||
|
private getDatabaseConnectionString(): string {
|
||||||
|
this.logger.debug('Getting database connection string from environment 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) {
|
||||||
|
const errorMessage = `Database configuration is missing. Missing variables: ${missingVars.join(", ")}. Please check your .env file.`;
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.debug(`Database connection configured for ${username}@${host}:${port}/${database}`);
|
||||||
|
return `postgres://${username}:${password}@${host}:${port}/${database}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user