feat: implement Database Manager module with encryption, CRUD operations, and migration management

This commit is contained in:
lborv
2025-09-27 18:06:50 +03:00
parent 2f848137ed
commit 0d5b2830ed
24 changed files with 541 additions and 303 deletions

View 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 {}

View 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;
}
}