feat: implement Database Manager module with encryption, CRUD operations, and migration management
This commit is contained in:
11
src/databaseManager/migration/migration.module.ts
Normal file
11
src/databaseManager/migration/migration.module.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { forwardRef, Module } from "@nestjs/common";
|
||||
import { MigrationService } from "./migration.service";
|
||||
import { DatabaseModule } from "src/database/database.module";
|
||||
|
||||
@Module({
|
||||
imports: [forwardRef(() => DatabaseModule)],
|
||||
controllers: [],
|
||||
providers: [MigrationService],
|
||||
exports: [MigrationService],
|
||||
})
|
||||
export class MigrationModule {}
|
||||
95
src/databaseManager/migration/migration.service.ts
Normal file
95
src/databaseManager/migration/migration.service.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { IsNull, Not, Repository } from "typeorm";
|
||||
import { Migration } from "../entities/migration.entity";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { DatabaseManagerService } from "../database/database.manager.service";
|
||||
|
||||
@Injectable()
|
||||
export class MigrationService {
|
||||
constructor(
|
||||
@InjectRepository(Migration)
|
||||
private readonly migrationRepository: Repository<Migration>,
|
||||
@Inject(DatabaseManagerService)
|
||||
private readonly databaseService: DatabaseManagerService
|
||||
) {}
|
||||
|
||||
async create(
|
||||
up: string,
|
||||
down: string,
|
||||
databaseId: string
|
||||
): Promise<Migration> {
|
||||
const database = await this.databaseService.findById(databaseId);
|
||||
|
||||
if (!database) {
|
||||
throw new Error("Database not found");
|
||||
}
|
||||
|
||||
const migration = this.migrationRepository.create({
|
||||
up,
|
||||
down,
|
||||
database,
|
||||
});
|
||||
|
||||
return await this.migrationRepository.save(migration);
|
||||
}
|
||||
|
||||
async up(databaseId: string): Promise<Migration[]> {
|
||||
const database = await this.databaseService.findById(databaseId);
|
||||
|
||||
if (!database) {
|
||||
throw new Error("Database not found");
|
||||
}
|
||||
|
||||
const migrations = await this.migrationRepository.find({
|
||||
where: { database: { id: database.id }, appliedAt: null },
|
||||
order: { createdAt: "ASC" },
|
||||
});
|
||||
|
||||
const completedMigrations: Migration[] = [];
|
||||
|
||||
for (const migration of migrations) {
|
||||
try {
|
||||
await this.databaseService.runQuery(database.id, migration.up);
|
||||
migration.appliedAt = new Date();
|
||||
await this.migrationRepository.save(migration);
|
||||
completedMigrations.push(migration);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to apply migration ${migration.id}: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return completedMigrations;
|
||||
}
|
||||
|
||||
async down(databaseId: string): Promise<Migration[]> {
|
||||
const database = await this.databaseService.findById(databaseId);
|
||||
|
||||
if (!database) {
|
||||
throw new Error("Database not found");
|
||||
}
|
||||
|
||||
const migrations = await this.migrationRepository.find({
|
||||
where: { database: { id: database.id }, appliedAt: Not(IsNull()) },
|
||||
order: { appliedAt: "DESC" },
|
||||
});
|
||||
|
||||
const revertedMigrations: Migration[] = [];
|
||||
|
||||
for (const migration of migrations) {
|
||||
try {
|
||||
await this.databaseService.runQuery(database.id, migration.down);
|
||||
migration.appliedAt = null;
|
||||
await this.migrationRepository.save(migration);
|
||||
revertedMigrations.push(migration);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to revert migration ${migration.id}: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return revertedMigrations;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user