prisma with psotgresql
This commit is contained in:
134
src/database/prisma.service.ts
Normal file
134
src/database/prisma.service.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import {
|
||||
Injectable,
|
||||
OnModuleInit,
|
||||
OnModuleDestroy,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { PrismaPg } from '@prisma/adapter-pg';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
/**
|
||||
* Type definitions for Prisma event payloads
|
||||
*/
|
||||
interface QueryEvent {
|
||||
query: string;
|
||||
params: string;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
interface ErrorEvent {
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface WarnEvent {
|
||||
message: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prisma Service
|
||||
*
|
||||
* Manages the Prisma Client instance and database connection lifecycle.
|
||||
* Automatically connects on module initialization and disconnects on module destruction.
|
||||
*
|
||||
* This service should be used throughout the application to interact with the database.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PrismaService
|
||||
extends PrismaClient
|
||||
implements OnModuleInit, OnModuleDestroy
|
||||
{
|
||||
private readonly logger = new Logger(PrismaService.name);
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
const databaseUrl = configService.get<string>('DATABASE_URL');
|
||||
|
||||
if (!databaseUrl) {
|
||||
throw new Error('DATABASE_URL environment variable is not set');
|
||||
}
|
||||
|
||||
// Initialize PostgreSQL connection pool
|
||||
const pool = new Pool({ connectionString: databaseUrl });
|
||||
const adapter = new PrismaPg(pool);
|
||||
|
||||
// Initialize Prisma Client with the adapter
|
||||
super({
|
||||
adapter,
|
||||
log: [
|
||||
{ emit: 'event', level: 'query' },
|
||||
{ emit: 'event', level: 'error' },
|
||||
{ emit: 'event', level: 'warn' },
|
||||
],
|
||||
});
|
||||
|
||||
// Log database queries in development mode
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
this.$on('query' as never, (e: QueryEvent) => {
|
||||
this.logger.debug(`Query: ${e.query}`);
|
||||
this.logger.debug(`Params: ${e.params}`);
|
||||
this.logger.debug(`Duration: ${e.duration}ms`);
|
||||
});
|
||||
}
|
||||
|
||||
// Log errors and warnings
|
||||
|
||||
this.$on('error' as never, (e: ErrorEvent) => {
|
||||
this.logger.error(`Database error: ${e.message}`);
|
||||
});
|
||||
|
||||
this.$on('warn' as never, (e: WarnEvent) => {
|
||||
this.logger.warn(`Database warning: ${e.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the database when the module is initialized
|
||||
*/
|
||||
async onModuleInit() {
|
||||
try {
|
||||
await this.$connect();
|
||||
this.logger.log('Successfully connected to database');
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to connect to database', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the database when the module is destroyed
|
||||
*/
|
||||
async onModuleDestroy() {
|
||||
try {
|
||||
await this.$disconnect();
|
||||
this.logger.log('Successfully disconnected from database');
|
||||
} catch (error) {
|
||||
this.logger.error('Error disconnecting from database', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the database (useful for testing)
|
||||
* WARNING: This will delete all data from all tables
|
||||
*/
|
||||
async cleanDatabase() {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
throw new Error('Cannot clean database in production');
|
||||
}
|
||||
|
||||
const models = Reflect.ownKeys(this).filter(
|
||||
(key) => key[0] !== '_' && key[0] !== '$',
|
||||
);
|
||||
|
||||
return Promise.all(
|
||||
models.map((modelKey) => {
|
||||
const model = this[modelKey as keyof this];
|
||||
if (model && typeof model === 'object' && 'deleteMany' in model) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
||||
return (model as any).deleteMany();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user