UNPKG

axiodb

Version:

A blazing-fast, lightweight, and scalable nodejs package based DBMS for modern application. Supports schemas, encryption, and advanced query capabilities.

300 lines 15.7 kB
"use strict"; /* eslint-disable @typescript-eslint/no-explicit-any */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Converter_helper_1 = __importDefault(require("../../Helper/Converter.helper")); const Crypto_helper_1 = require("../../Helper/Crypto.helper"); const response_helper_1 = __importDefault(require("../../Helper/response.helper")); const FileManager_1 = __importDefault(require("../../engine/Filesystem/FileManager")); const FolderManager_1 = __importDefault(require("../../engine/Filesystem/FolderManager")); // Import All Utility const Searcher_utils_1 = __importDefault(require("../../utility/Searcher.utils")); const SortData_utils_1 = __importDefault(require("../../utility/SortData.utils")); const cache_operation_1 = __importDefault(require("../../cache/cache.operation")); const Keys_1 = require("../../config/Keys/Keys"); const BufferLoaderWithWorker_utils_1 = __importDefault(require("../../utility/BufferLoaderWithWorker.utils")); /** * The DeleteOperation class is used to delete a document from a collection. * This class provides methods to delete a single document that matches the base query. */ class DeleteOperation { constructor(collectionName, path, baseQuery, isEncrypted = false, encryptionKey) { this.allDataWithFileName = []; this.collectionName = collectionName; this.path = path; this.baseQuery = baseQuery; this.isEncrypted = isEncrypted; this.encryptionKey = encryptionKey; this.sort = {}; this.ResponseHelper = new response_helper_1.default(); this.Converter = new Converter_helper_1.default(); if (this.isEncrypted === true) { if (!this.encryptionKey) { throw new Error("Encryption key must be provided when isEncrypted is true."); } this.cryptoInstance = new Crypto_helper_1.CryptoHelper(this.encryptionKey); } this.allDataWithFileName = []; // To store all data with file name } // Methods /** * Deletes a single document that matches the base query. * * This method: * 1. Loads all raw data from buffers * 2. Searches for documents matching the base query * 3. Selects the first matching document (applying sort if provided) * 4. Deletes the file associated with the selected document * * @returns {Promise<object>} A response object containing either: * - Success: { message: "Data deleted successfully", deleteData: object } * - Error: An error message if no data found or deletion fails * * @throws Will propagate any errors from underlying operations */ deleteOne() { return __awaiter(this, void 0, void 0, function* () { var _a; // if documentId is provided in the baseQuery then read the file with the documentId let ReadResponse; // Read Response Holder if (((_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.documentId) !== undefined) { const FilePath = [ `.${this.baseQuery.documentId}${Keys_1.General.DBMS_File_EXT}`, ]; ReadResponse = yield this.LoadAllBufferRawData(FilePath); } else { ReadResponse = yield this.LoadAllBufferRawData(); } if ("data" in ReadResponse) { const SearchedData = yield new Searcher_utils_1.default(ReadResponse.data).find(this.baseQuery, "data"); if (SearchedData.length === 0) { return this.ResponseHelper.Error("No data found with the specified query"); } let selectedFirstData = SearchedData[0]; // Select the first data let fileName = selectedFirstData === null || selectedFirstData === void 0 ? void 0 : selectedFirstData.fileName; // Get the file name // Sort the data if sort is provided then select the first data for deletion if (Object.keys(this.sort).length === 0) { selectedFirstData = SearchedData[0]; // Select the first data fileName = selectedFirstData === null || selectedFirstData === void 0 ? void 0 : selectedFirstData.fileName; // Get the file name } else { const Sorter = new SortData_utils_1.default(SearchedData, this.sort); const SortedData = yield Sorter.sort("data"); // Sort the data selectedFirstData = SortedData[0]; // Select the first data fileName = selectedFirstData === null || selectedFirstData === void 0 ? void 0 : selectedFirstData.fileName; // Get the file name } // Delete the file const deleteResponse = yield this.deleteFile(fileName); if ("data" in deleteResponse) { yield cache_operation_1.default.clearAllCache(); // clear the cache return this.ResponseHelper.Success({ message: "Data deleted successfully", deleteData: selectedFirstData === null || selectedFirstData === void 0 ? void 0 : selectedFirstData.data, }); } else { return this.ResponseHelper.Error("Failed to delete data"); } } else { return this.ResponseHelper.Error(ReadResponse); } }); } /** * Deletes multiple documents that match the base query. * * This method: * 1. Searches for documents matching the base query * 2. Deletes each matching file * 3. Returns success with the deleted data or an error * * @returns {Promise<SuccessInterface | ErrorInterface>} A promise that resolves to either: * - Success with a success message and the deleted data * - Error if: * - No matching data is found * - Any file deletion operation fails * - The initial buffer data loading fails */ deleteMany() { return __awaiter(this, void 0, void 0, function* () { const response = yield this.LoadAllBufferRawData(); if ("data" in response) { const SearchedData = yield new Searcher_utils_1.default(response.data).find(this.baseQuery, "data"); if (SearchedData.length === 0) { return this.ResponseHelper.Error("No data found with the specified query"); } // Delete all files for (let i = 0; i < SearchedData.length; i++) { const deleteResponse = yield this.deleteFile(SearchedData[i].fileName); if ("data" in deleteResponse) { continue; } else { return this.ResponseHelper.Error("Failed to delete data"); } } yield cache_operation_1.default.clearAllCache(); // clear the cache return this.ResponseHelper.Success({ message: "Data deleted successfully", deleteData: SearchedData.map((data) => data.data), }); } else { return this.ResponseHelper.Error(response); } }); } /** * Loads all buffer raw data from the specified directory. * * This method performs the following steps: * 1. Checks if the directory is locked. * 2. If the directory is not locked, it lists all files in the directory. * 3. Reads each file and decrypts the data if encryption is enabled. * 4. Stores the decrypted data in the `AllData` array. * 5. If the directory is locked, it unlocks the directory, reads the files, and then locks the directory again. * * @returns {Promise<SuccessInterface | ErrorInterface>} A promise that resolves to a success or error response. * * @throws {Error} Throws an error if any operation fails. */ LoadAllBufferRawData(documentIdDirectFile) { return __awaiter(this, void 0, void 0, function* () { try { // Check if Directory Locked or not const isLocked = yield new FolderManager_1.default().IsDirectoryLocked(this.path); if ("data" in isLocked) { // If Directory is not locked if (isLocked.data === false) { // Read List the data from the file const ReadResponse = yield new FolderManager_1.default().ListDirectory(this.path); if ("data" in ReadResponse) { // Store all files in DataFilesList const DataFilesList = documentIdDirectFile !== undefined ? documentIdDirectFile : ReadResponse.data; // Read all files from the directory const resultData = yield (0, BufferLoaderWithWorker_utils_1.default)(DataFilesList, this.cryptoInstance, this.path, this.isEncrypted, true); this.allDataWithFileName = resultData; // Store all data with file name return this.ResponseHelper.Success(resultData); } return this.ResponseHelper.Error("Failed to read directory"); } else { // if Directory is locked then unlock it const unlockResponse = yield new FolderManager_1.default().UnlockDirectory(this.path); if ("data" in unlockResponse) { // Read List the data from the file const ReadResponse = yield new FolderManager_1.default().ListDirectory(this.path); if ("data" in ReadResponse) { // Store all files in DataFilesList const DataFilesList = documentIdDirectFile !== undefined ? documentIdDirectFile : ReadResponse.data; // Read all files from the directory const resultData = yield (0, BufferLoaderWithWorker_utils_1.default)(DataFilesList, this.cryptoInstance, this.path, this.isEncrypted, true); this.allDataWithFileName = resultData; // Store all data with file name // Lock the directory after reading all files const lockResponse = yield new FolderManager_1.default().LockDirectory(this.path); if ("data" in lockResponse) { return this.ResponseHelper.Success(resultData); } else { return this.ResponseHelper.Error(`Failed to lock directory: ${this.path}`); } } return this.ResponseHelper.Error(`Failed to read directory: ${this.path}`); } else { return this.ResponseHelper.Error(`Failed to unlock directory: ${this.path}`); } } } else { return this.ResponseHelper.Error(isLocked); } } catch (error) { return this.ResponseHelper.Error(error); } }); } /** * Deletes a file from the specified path. * * This method checks if the directory is locked before attempting to delete the file. * If the directory is locked, it tries to unlock it, delete the file, and then lock it again. * * @param fileName - The name of the file to be deleted * @returns A response object indicating success or failure * Success response: { status: true, message: "File deleted successfully" } * Error response: { status: false, message: <error message> } * @private */ deleteFile(fileName) { return __awaiter(this, void 0, void 0, function* () { // Check if Directory Locked or not const isLocked = yield new FolderManager_1.default().IsDirectoryLocked(this.path); if ("data" in isLocked) { // If Directory is not locked if (isLocked.data === false) { const deleteResponse = yield new FileManager_1.default().DeleteFile(`${this.path}/${fileName}`); if ("data" in deleteResponse) { return this.ResponseHelper.Success("File deleted successfully"); } else { return this.ResponseHelper.Error("Failed to delete file"); } } else { const unlockResponse = yield new FolderManager_1.default().UnlockDirectory(this.path); if ("data" in unlockResponse) { const deleteResponse = yield new FileManager_1.default().DeleteFile(`${this.path}/${fileName}`); if ("data" in deleteResponse) { const lockResponse = yield new FolderManager_1.default().LockDirectory(this.path); if ("data" in lockResponse) { return this.ResponseHelper.Success("File deleted successfully"); } else { return this.ResponseHelper.Error("Failed to lock directory"); } } else { return this.ResponseHelper.Error("Failed to delete file"); } } else { return this.ResponseHelper.Error("Failed to unlock directory"); } } } else { return this.ResponseHelper.Error("Failed to delete file"); } }); } /** * to be sorted to the query * @param {object} sort - The sort to be set. * @returns {DeleteOperation} - An instance of the DeleteOperation class. */ Sort(sort) { this.sort = sort; return this; } } exports.default = DeleteOperation; //# sourceMappingURL=Delete.operation.js.map