UNPKG

azurite

Version:

An open source Azure Storage API compatible server

203 lines 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const sequelize_1 = require("sequelize"); const AllExtentsAsyncIterator_1 = tslib_1.__importDefault(require("./AllExtentsAsyncIterator")); // tslint:disable: max-classes-per-file class ExtentsModel extends sequelize_1.Model { } /** * A SQL based extent metadata storage implementation based on Sequelize. * Refer to CONTRIBUTION.md for how to setup SQL database environment. * * @export * @class SqlExtentMetadataStore * @implements {IExtentMetadataStore} */ class SqlExtentMetadataStore { /** * Creates an instance of SqlExtentMetadataStore. * * @param {string} connectionURI For example, "postgres://user:pass@example.com:5432/dbname" * @param {SequelizeOptions} [sequelizeOptions] * @memberof SqlBlobMetadataStore */ constructor(connectionURI, sequelizeOptions) { this.initialized = false; this.closed = false; // Enable encrypt connection for SQL Server if (connectionURI.startsWith("mssql") && sequelizeOptions) { sequelizeOptions.dialectOptions = sequelizeOptions.dialectOptions || {}; sequelizeOptions.dialectOptions.options = sequelizeOptions.dialectOptions.options || {}; sequelizeOptions.dialectOptions.options.encrypt = true; } this.sequelize = new sequelize_1.Sequelize(connectionURI, sequelizeOptions); } async init() { await this.sequelize.authenticate(); ExtentsModel.init({ id: { type: "VARCHAR(255)", primaryKey: true }, locationId: { allowNull: false, type: "VARCHAR(255)" }, path: { type: "VARCHAR(255)" }, size: { allowNull: false, type: sequelize_1.BIGINT.UNSIGNED }, lastModifiedInMS: { allowNull: false, type: sequelize_1.BIGINT.UNSIGNED } }, { sequelize: this.sequelize, modelName: "Extents", timestamps: false }); // TODO: Remove this part which only for test. await this.sequelize.sync(); this.initialized = true; } isInitialized() { return this.initialized; } async close() { await this.sequelize.close(); this.closed = true; } isClosed() { return this.closed; } async clean() { // TODO: Implement cleanup in database } /** * 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) { return ExtentsModel.upsert({ ...extent }) .then(() => { return; }) .catch((err) => { // console.log(`SqlExtentMetadataStore.updateExtent() upsert err:${err}`); throw err; }); } /** * * List extents. * @param {string} [id] * @param {number} [maxResults] * @param {(number | undefined)} [marker] * @param {Date} [queryTime] * @param {number} [protectTimeInMs] * @returns {(Promise<[IExtentModel[], number | undefined]>)} * @memberof SqlExtentMetadataStore */ async listExtents(id, maxResults, marker, queryTime, protectTimeInMs) { const query = {}; if (id !== undefined) { query.id = id; // console.log(`SqlExtentMetadataStore.listExtents() query ${id}`); } if (maxResults === undefined) { maxResults = 5000; } if (protectTimeInMs === undefined) { protectTimeInMs = 0; } if (queryTime !== undefined) { query.lastModifiedInMS = { [sequelize_1.Op.lt]: queryTime.getTime() - protectTimeInMs }; } if (marker !== undefined) { query.id = { [sequelize_1.Op.gt]: marker }; } const modelConvert = (extentsModel) => { const getId = this.getModelValue(extentsModel, "id", true); return { id: getId, locationId: this.getModelValue(extentsModel, "locationId", true), path: this.getModelValue(extentsModel, "path") || getId, size: this.getModelValue(extentsModel, "size", true), lastModifiedInMS: this.getModelValue(extentsModel, "lastModifiedInMS", true) }; }; return ExtentsModel.findAll({ limit: maxResults, where: query, order: [["id", "ASC"]] }).then((res) => { if (res.length < maxResults) { return [res.map((val) => modelConvert(val)), undefined]; } else { const tailItem = res[res.length - 1]; const nextMarker = this.getModelValue(tailItem, "id", true); return [res.map((val) => modelConvert(val)), nextMarker]; } }); } /** * Delete the extent metadata from DB with the extentId. * * @param {string} extentId * @returns {Promise<void>} * @memberof IExtentMetadata */ async deleteExtent(extentId) { return ExtentsModel.destroy({ where: { id: extentId } }).then(() => { return; }); } /** * Get the locationId for a given extentId. * * @param {string} extentId * @returns {Promise<string>} * @memberof IExtentMetadata */ async getExtentLocationId(extentId) { return ExtentsModel.findOne({ where: { id: extentId } }).then((res) => { if (res === null || res === undefined) { throw Error(`SqlExtentMetadataStore:getExtentLocationId() Error. Extent not exists.`); } const locationId = this.getModelValue(res, "locationId", true); return locationId; }); } iteratorExtents() { return new AllExtentsAsyncIterator_1.default(this); } getModelValue(model, key, isRequired) { const value = model.get(key); if (value === undefined && isRequired === true) { // tslint:disable-next-line:max-line-length throw new Error(`SqlBlobMetadataStore:getModelValue() error. ${key} is required but value from database model is undefined.`); } return value; } } exports.default = SqlExtentMetadataStore; //# sourceMappingURL=SqlExtentMetadataStore.js.map