import { BIGINT , Model , Op , Options as SequelizeOptions , Sequelize } from "sequelize" ; import AllExtentsAsyncIterator from "./AllExtentsAsyncIterator" ; import IExtentMetadataStore , { IExtentModel } from "./IExtentMetadataStore" ; class ExtentsModel extends Model { } export class implements IExtentMetadataStore export default class SqlExtentMetadataStore implements IExtentMetadataStore { private initialized : boolean = false ; private closed : boolean = false ; private readonly sequelize : Sequelize ; param { string } connectionURI param { SequelizeOptions } sequelizeOptions memberof public constructor ( connectionURI , sequelizeOptions ? ) { if ( connectionURI . startsWith ( "mssql" ) && sequelizeOptions ) { sequelizeOptions . dialectOptions = sequelizeOptions . dialectOptions || { } ; ( sequelizeOptions . dialectOptions as any ) . options = ( sequelizeOptions . dialectOptions as any ) . options || { } ; ( sequelizeOptions . dialectOptions as any ) . options . encrypt = true ; } this . sequelize = new Sequelize ( connectionURI , sequelizeOptions ) ; } public 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 : BIGINT . UNSIGNED } , lastModifiedInMS : { allowNull : false , type : BIGINT . UNSIGNED } } , { sequelize : this . sequelize , modelName : "Extents" , timestamps : false } ) ; this . sequelize . sync ( ) ; this . initialized = true ; } public isInitialized ( ) { return this . initialized ; } public async close ( ) { await this . sequelize . close ( ) ; this . closed = true ; } public isClosed ( ) { return this . closed ; } public async clean ( ) { } param { IExtentModel } extent returns { Promise < void > } memberof public async updateExtent ( extent ) { return ExtentsModel . upsert ( { ... extent } ) . then ( ( ) => { return ; } ) . catch ( ( err ) => { throw err ; } ) ; } param { string } id param { number } maxResults param { ( number | undefined ) } marker param { Date } queryTime param { number } protectTimeInMs returns { ( Promise < [ IExtentModel [ ] , number | undefined ] > ) } memberof public 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 . lastModifiedInMS = { [ Op . lt ] : queryTime . getTime ( ) - protectTimeInMs } ; } if ( marker !== undefined ) { query . id = { [ Op . gt ] : marker } ; } const modelConvert = ( extentsModel ) : IExtentModel => { const getId = this . getModelValue < string > ( extentsModel , "id" , true ) ; return { id : getId , locationId : this . getModelValue < string > ( extentsModel , "locationId" , true ) , path : this . getModelValue < string > ( extentsModel , "path" ) || getId , size : this . getModelValue < number > ( extentsModel , "size" , true ) , lastModifiedInMS : this . getModelValue < number > ( extentsModel , "lastModifiedInMS" , true ) } ; } ; return ExtentsModel . findAll ( { limit : maxResults , where : query as any , 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 < number > ( tailItem , "id" , true ) ; return [ res . map ( ( val ) => modelConvert ( val ) ) , nextMarker ] ; } } ) ; } param { string } extentId returns { Promise < void > } memberof public async deleteExtent ( extentId ) { return ExtentsModel . destroy ( { where : { id : extentId } } ) . then ( ( ) => { return ; } ) ; } param { string } extentId returns { Promise < string > } memberof public 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 < string > ( res , "locationId" , true ) ; return locationId ; } ) ; } public iteratorExtents ( ) { return new AllExtentsAsyncIterator ( this ) ; } private getModelValue < T > ( model , key ) ; private getModelValue < T > ( model , key , isRequired ) ; private getModelValue < T > ( model , key , isRequired ? ) { const value = model . get ( key ) as T | undefined ; if ( value === undefined && isRequired === true ) { throw new Error ( `SqlBlobMetadataStore:getModelValue() error. ${ key } is required but value from database model is undefined.` ) ; } return value ; } }