axiodb
Version:
The Pure JavaScript Alternative to SQLite. Embedded NoSQL database for Node.js with MongoDB-style queries, zero native dependencies, built-in InMemoryCache, and web GUI. Perfect for desktop apps, CLI tools, and embedded systems. No compilation, no platfor
211 lines • 11.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
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 Keys_1 = require("../../config/Keys/Keys");
const FileManager_1 = __importDefault(require("../../engine/Filesystem/FileManager"));
const Converter_helper_1 = __importDefault(require("../../Helper/Converter.helper"));
const response_helper_1 = __importDefault(require("../../Helper/response.helper"));
const ReadIndex_service_1 = require("../Index/ReadIndex.service");
const Searcher_utils_1 = __importDefault(require("../../utility/Searcher.utils"));
const BufferLoaderWithWorker_utils_1 = __importDefault(require("../../utility/BufferLoaderWithWorker.utils"));
class TransactionIndexManager {
constructor(collectionPath, transactionId, isEncrypted = false, encryptionKey) {
this.stagedIndexUpdates = new Map();
this.collectionPath = collectionPath;
this.transactionId = transactionId;
this.indexFolderPath = `${collectionPath}/indexes`;
this.indexMetaPath = `${this.indexFolderPath}/index.meta.json`;
this.FileManager = new FileManager_1.default();
this.Converter = new Converter_helper_1.default();
this.ResponseHelper = new response_helper_1.default();
this.ReadIndexService = new ReadIndex_service_1.ReadIndex(collectionPath);
this.isEncrypted = isEncrypted;
this.encryptionKey = encryptionKey;
}
resolveQueryToDocumentIds(query) {
return __awaiter(this, void 0, void 0, function* () {
try {
const fileNames = yield this.ReadIndexService.getFileFromIndex(query);
if (fileNames && fileNames.length > 0) {
const dataList = yield (0, BufferLoaderWithWorker_utils_1.default)(fileNames, this.encryptionKey, this.collectionPath, this.isEncrypted, true);
const searchedData = yield new Searcher_utils_1.default(dataList, true).find(query, "data");
return searchedData.map((item) => item.data.documentId);
}
const allFiles = yield this.getAllDocumentFiles();
const allData = yield (0, BufferLoaderWithWorker_utils_1.default)(allFiles, this.encryptionKey, this.collectionPath, this.isEncrypted, true);
const searchedData = yield new Searcher_utils_1.default(allData, true).find(query, "data");
return searchedData.map((item) => item.data.documentId);
}
catch (_a) {
return [];
}
});
}
stageIndexUpdates(operations) {
return __awaiter(this, void 0, void 0, function* () {
try {
const indexMetaContent = yield this.FileManager.ReadFile(this.indexMetaPath);
if (!indexMetaContent.status) {
return;
}
const indexMeta = this.Converter.ToObject(indexMetaContent.data);
for (const indexMetaEntry of indexMeta) {
const indexFilePath = indexMetaEntry.path;
const fieldName = indexMetaEntry.indexFieldName;
const indexContent = yield this.FileManager.ReadFile(indexFilePath);
if (!indexContent.status) {
continue;
}
const indexData = this.Converter.ToObject(indexContent.data);
const indexEntries = indexData.indexEntries || {};
for (const op of operations) {
if (op.type === 'INSERT' && op.data && op.documentId) {
if (Object.prototype.hasOwnProperty.call(op.data, fieldName)) {
const fieldValue = op.data[fieldName];
const fileName = `${op.documentId}${Keys_1.General.DBMS_File_EXT}`;
if (!indexEntries[fieldValue]) {
indexEntries[fieldValue] = [];
}
if (!indexEntries[fieldValue].includes(fileName)) {
indexEntries[fieldValue].push(fileName);
}
}
}
else if (op.type === 'UPDATE' && op.data && op.documentId && op.oldData) {
const oldFieldValue = op.oldData[fieldName];
const newFieldValue = op.data[fieldName];
const fileName = `${op.documentId}${Keys_1.General.DBMS_File_EXT}`;
if (oldFieldValue !== undefined && indexEntries[oldFieldValue]) {
indexEntries[oldFieldValue] = indexEntries[oldFieldValue].filter((f) => f !== fileName);
if (indexEntries[oldFieldValue].length === 0) {
delete indexEntries[oldFieldValue];
}
}
if (newFieldValue !== undefined) {
if (!indexEntries[newFieldValue]) {
indexEntries[newFieldValue] = [];
}
if (!indexEntries[newFieldValue].includes(fileName)) {
indexEntries[newFieldValue].push(fileName);
}
}
}
else if (op.type === 'DELETE' && op.documentId && op.oldData) {
if (Object.prototype.hasOwnProperty.call(op.oldData, fieldName)) {
const fieldValue = op.oldData[fieldName];
const fileName = `${op.documentId}${Keys_1.General.DBMS_File_EXT}`;
if (indexEntries[fieldValue]) {
indexEntries[fieldValue] = indexEntries[fieldValue].filter((f) => f !== fileName);
if (indexEntries[fieldValue].length === 0) {
delete indexEntries[fieldValue];
}
}
}
}
}
indexData.indexEntries = indexEntries;
this.stagedIndexUpdates.set(indexFilePath, indexData);
}
}
catch (_a) {
return;
}
});
}
commitIndexUpdates() {
return __awaiter(this, void 0, void 0, function* () {
try {
for (const [indexFilePath, indexData] of this.stagedIndexUpdates) {
const tempFilePath = `${indexFilePath}.tmp-${this.transactionId}`;
yield this.FileManager.WriteFile(tempFilePath, this.Converter.ToString(indexData));
const readResult = yield this.FileManager.ReadFile(tempFilePath);
if (!readResult.status) {
return this.ResponseHelper.Error("Failed to verify temp index file");
}
const fs = yield Promise.resolve().then(() => __importStar(require('fs/promises')));
yield fs.rename(tempFilePath, indexFilePath);
}
this.stagedIndexUpdates.clear();
return this.ResponseHelper.Success({ message: "Index updates committed" });
}
catch (error) {
return this.ResponseHelper.Error(error);
}
});
}
rollbackIndexUpdates() {
return __awaiter(this, void 0, void 0, function* () {
try {
for (const [indexFilePath] of this.stagedIndexUpdates) {
const tempFilePath = `${indexFilePath}.tmp-${this.transactionId}`;
const fileExists = yield this.FileManager.FileExists(tempFilePath);
if (fileExists.status) {
yield this.FileManager.DeleteFile(tempFilePath);
}
}
this.stagedIndexUpdates.clear();
}
catch (_a) {
return;
}
});
}
getAllDocumentFiles() {
return __awaiter(this, void 0, void 0, function* () {
try {
const fs = yield Promise.resolve().then(() => __importStar(require('fs/promises')));
const files = yield fs.readdir(this.collectionPath);
return files.filter((file) => file.endsWith(Keys_1.General.DBMS_File_EXT));
}
catch (_a) {
return [];
}
});
}
}
exports.default = TransactionIndexManager;
//# sourceMappingURL=TransactionIndexManager.service.js.map