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
JavaScript
"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