UNPKG

azurite

Version:

An open source Azure Storage API compatible server

194 lines 6.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const fs_1 = require("fs"); const lokijs_1 = tslib_1.__importDefault(require("lokijs")); const utils_1 = require("../utils/utils"); const AllExtentsAsyncIterator_1 = tslib_1.__importDefault(require("./AllExtentsAsyncIterator")); /** * This is a metadata source implementation for extent management based on loki DB. * * It contains following collection and documents: * * -- EXTENTS_COLLECTION // Collections maintain extents information, including extentID, mapped local file path * // Unique document properties: id, path * * @export * @class LokiExtentMetadata * @implements {IExtentMetadata} */ class LokiExtentMetadata { constructor(lokiDBPath, inMemory) { this.lokiDBPath = lokiDBPath; this.initialized = false; this.closed = true; this.EXTENTS_COLLECTION = "$EXTENTS_COLLECTION$"; this.db = new lokijs_1.default(lokiDBPath, inMemory ? { persistenceMethod: "memory" } : { persistenceMethod: "fs", autosave: true, autosaveInterval: 5000 }); } isInitialized() { return this.initialized; } isClosed() { return this.closed; } async init() { await new Promise((resolve, reject) => { (0, fs_1.stat)(this.lokiDBPath, (statError, stats) => { if (!statError) { this.db.loadDatabase({}, (dbError) => { if (dbError) { reject(dbError); } else { resolve(); } }); } else { // when DB file doesn't exist, ignore the error because following will re-create the file resolve(); } }); }); // Create EXTENTS_COLLECTION if not exists if (this.db.getCollection(this.EXTENTS_COLLECTION) === null) { this.db.addCollection(this.EXTENTS_COLLECTION, { indices: ["id"] }); } await new Promise((resolve, reject) => { this.db.saveDatabase((err) => { if (err) { reject(err); } else { resolve(); } }); }); this.initialized = true; this.closed = false; } /** * Close loki DB. * * @returns {Promise<void>} * @memberof LokiBlobDataStore */ async close() { await new Promise((resolve, reject) => { this.db.close((err) => { if (err) { reject(err); } else { resolve(); } }); }); this.closed = true; } /** * Clean LokiExtentMetadata. * * @returns {Promise<void>} * @memberof LokiExtentMetadata */ async clean() { if (this.isClosed()) { await (0, utils_1.rimrafAsync)(this.lokiDBPath); return; } throw new Error(`Cannot clean LokiExtentMetadata, it's not closed.`); } /** * Update the extent status in DB. A new item will be created if the extent does not exists. * * @param {IExtentModel} extent * @returns {Promise<void>} * @memberof LokiExtentMetadata */ async updateExtent(extent) { const coll = this.db.getCollection(this.EXTENTS_COLLECTION); const doc = coll.findOne({ id: extent.id }); if (!doc) { coll.insert(extent); return; } doc.size = extent.size; doc.LastModifyInMS = extent.lastModifiedInMS; coll.update(doc); } /** * List extents. * * @param {string} [id] * @param {number} [maxResults] * @param {number} [marker] * @param {Date} [queryTime] * @param {number} [protectTimeInMs] * @returns {(Promise<[IExtentModel[], number | undefined]>)} * @memberof LokiExtentMetadata */ async listExtents(id, maxResults, marker, queryTime, protectTimeInMs) { const query = {}; if (id !== undefined) { query.id = id; } if (maxResults === undefined) { maxResults = 5000; } if (protectTimeInMs === undefined) { protectTimeInMs = 0; } if (queryTime !== undefined) { query.LastModifyInMS = { $lt: queryTime.getTime() - protectTimeInMs }; } query.$loki = { $gt: marker }; const coll = this.db.getCollection(this.EXTENTS_COLLECTION); const docs = coll.chain().find(query).limit(maxResults).data(); if (docs.length < maxResults) { return [docs, undefined]; } else { const nextMarker = docs[docs.length - 1].$loki; return [docs, nextMarker]; } } /** * Delete the extent metadata from DB with the extentId. * * @param {string} extentId * @returns {Promise<void>} * @memberof IExtentMetadata */ async deleteExtent(extentId) { const coll = this.db.getCollection(this.EXTENTS_COLLECTION); return coll.findAndRemove({ id: extentId }); } iteratorExtents() { return new AllExtentsAsyncIterator_1.default(this); } /** * Get the persistencyId for a given extentId. * * @param {string} extentId * @returns {Promise<string>} * @memberof IExtentMetadata */ async getExtentLocationId(extentId) { const coll = this.db.getCollection(this.EXTENTS_COLLECTION); const doc = coll.findOne({ id: extentId }); return doc.locationId; } } exports.default = LokiExtentMetadata; //# sourceMappingURL=LokiExtentMetadataStore.js.map