Refactor storage and file deletion logic

Adjusted the indentation and formatting across several files for better readability. Enhanced the file deletion logic to handle cases where a file is found in the database but not in storage, and to delete only from the database when there are multiple references.
This commit is contained in:
Mathis H (Avnyr) 2024-10-14 13:56:43 +02:00
parent 8686f0c27b
commit 1fc9185afc
Signed by: Mathis
GPG Key ID: DD9E0666A747D126
4 changed files with 83 additions and 30 deletions

View File

@ -73,7 +73,10 @@ export const FilesTable = pgTable("files", {
}) })
.notNull(), .notNull(),
groupId: p.uuid("group_id").default(null).references(() => FilesGroupTable.uuid), groupId: p
.uuid("group_id")
.default(null)
.references(() => FilesGroupTable.uuid),
fileSize: p.integer("file_size").notNull(), fileSize: p.integer("file_size").notNull(),

View File

@ -2,7 +2,8 @@ import { IncomingMessage } from "node:http";
import { import {
BadRequestException, BadRequestException,
Controller, Controller,
DefaultValuePipe, Delete, DefaultValuePipe,
Delete,
Get, Get,
HttpCode, HttpCode,
HttpStatus, HttpStatus,
@ -15,9 +16,9 @@ import {
Res, Res,
Response, Response,
StreamableFile, StreamableFile,
UseGuards UseGuards,
} from '@nestjs/common'; } from "@nestjs/common";
import { AdminGuard, InsertAdminState } from '../auth/auth.guard'; import { AdminGuard, InsertAdminState } from "../auth/auth.guard";
import { FilesService } from "./files.service"; import { FilesService } from "./files.service";
@Controller("files") @Controller("files")

View File

@ -67,12 +67,52 @@ export class FilesService {
}); });
} }
//TODO DELETE FILE /**
* Deletes a file from the storage and/or the database based on the provided file ID.
*
* @param {string} fileId - The unique identifier of the file to delete.
* @return {Promise<void>} A promise that resolves when the deletion process is complete.
* @throws {NotFoundException} If the file is not found in the database.
*/
public async deleteFile(fileId: string) { public async deleteFile(fileId: string) {
//get checksum for fileId //get checksum for fileId
const currentFileInDb = await this.database
.use()
.select()
.from(FilesTable)
.where(eq(FilesTable.uuid, fileId))
.prepare("findFileById")
.execute();
if (currentFileInDb.length === 0)
throw new NotFoundException("File not found in database");
//check if multiple entry for checksum //check if multiple entry for checksum
const sameFileInStorage = await this.database
.use()
.select()
.from(FilesTable)
.where(eq(FilesTable.checksum, currentFileInDb[0].checksum));
if (sameFileInStorage.length > 1) {
//if that the case then only remove the entry in database relative to fileId. //if that the case then only remove the entry in database relative to fileId.
await this.database
.use()
.delete(FilesTable)
.where(eq(FilesTable.uuid, fileId))
.execute();
}
if (sameFileInStorage.length === 1) {
//if there is one only entry then remove the file from the storage and the database. //if there is one only entry then remove the file from the storage and the database.
await this.database
.use()
.delete(FilesTable)
.where(eq(FilesTable.uuid, fileId))
.execute();
await this.storage.delete(
currentFileInDb[0].checksum,
currentFileInDb[0].extension,
currentFileInDb[0].isDocumentation,
);
}
} }
/** /**
@ -180,13 +220,14 @@ export class FilesService {
}) })
.returning(); .returning();
if (groupExists[0].uuid) { if (groupExists[0].uuid) {
await this.database.use() await this.database
.use()
.update(FilesTable) .update(FilesTable)
// @ts-ignore TODO FIX // @ts-ignore TODO FIX
.set({groupId: groupExists[0].uuid}) .set({ groupId: groupExists[0].uuid })
.where(eq(FilesTable.uuid, inserted[0].uuid)) .where(eq(FilesTable.uuid, inserted[0].uuid))
.prepare("addGroupToFile") .prepare("addGroupToFile")
.execute() .execute();
} }
console.log(inserted); console.log(inserted);

View File

@ -1,6 +1,6 @@
import * as console from "node:console"; import * as console from "node:console";
import * as crypto from "node:crypto"; import * as crypto from "node:crypto";
import { readFile, writeFile, rm } from "node:fs/promises"; import { readFile, rm, writeFile } from "node:fs/promises";
import { join } from "node:path"; import { join } from "node:path";
import { import {
BadRequestException, BadRequestException,
@ -59,11 +59,16 @@ export class StorageService {
* @param {string} currentMime - The MIME type to check for presence in all sets. * @param {string} currentMime - The MIME type to check for presence in all sets.
* @return {boolean} Returns true if the MIME type is found in all sets, otherwise false. * @return {boolean} Returns true if the MIME type is found in all sets, otherwise false.
*/ */
function checkMime(mimesForMachines: Map<string, Set<string>>, currentMime: string): boolean { function checkMime(
mimesForMachines: Map<string, Set<string>>,
currentMime: string,
): boolean {
let notFoundCount = 0; let notFoundCount = 0;
for (const mimesForMachine of mimesForMachines) { for (const mimesForMachine of mimesForMachines) {
const [key, set] = mimesForMachine const [key, set] = mimesForMachine;
if (!set.has(currentMime)) {notFoundCount++} if (!set.has(currentMime)) {
notFoundCount++;
}
} }
return notFoundCount === 0; return notFoundCount === 0;
} }
@ -73,7 +78,10 @@ export class StorageService {
// Array of MIMEs with possible duplicate field // Array of MIMEs with possible duplicate field
const _mimes: Array<string> = []; const _mimes: Array<string> = [];
const machinesMap: Map<string, Set<string>> = new Map<string, Set<string>>() const machinesMap: Map<string, Set<string>> = new Map<
string,
Set<string>
>();
// Fetching MIMEs for the associated machines // Fetching MIMEs for the associated machines
for (const machineId of machineIds) { for (const machineId of machineIds) {
console.debug(`Fetching mimeTypes for machine : ${machineId}`); console.debug(`Fetching mimeTypes for machine : ${machineId}`);
@ -97,12 +105,12 @@ export class StorageService {
); );
console.debug(`Total : ${_allowedMime.length}`); console.debug(`Total : ${_allowedMime.length}`);
// Append each MIME of a machine // Append each MIME of a machine
const tempSet = new Set<string>() const tempSet = new Set<string>();
for (const allowedMimeElement of _allowedMime) { for (const allowedMimeElement of _allowedMime) {
tempSet.add(allowedMimeElement.slug) tempSet.add(allowedMimeElement.slug);
} }
machinesMap.set(machineId, tempSet) machinesMap.set(machineId, tempSet);
tempSet.clear() tempSet.clear();
} }
//Store the MIMEs without duplicate //Store the MIMEs without duplicate
const mimeSet = new Set(_mimes); const mimeSet = new Set(_mimes);