import Datastore = require ( "nedb" ) ; import fs = require ( 'fs' ) ; import mkdir from 'mkdir-recursive' ; import path from "path" ; import { CONSTANTS } from "./statics" ; export class NedbError extends Error { public errorType : string ; public key : string ; public message : string ; } export interface IReturn { data : object | object [ ] ; error : NedbError ; } export interface IUpdateReturn { error : NedbError ; numAffected : number ; affectedDocuments : object [ ] ; upsert : boolean ; } export interface IRemoveReturn { error : NedbError ; numRemoved : number ; } export interface IQueryParameters { sort ? : object ; skip ? : number ; limit ? : number ; } export interface IUpdateParameters { upsert ? : boolean ; multi ? : boolean ; } export class export class Database { private datastore : Datastore ; private filename : string ; private filenameWithoutPath : string ; private filePath : string ; constructor ( filename , subPath , basePath ) { this . filePath = path . join ( basePath , subPath ) ; if ( ! fs . existsSync ( this . filePath ) ) { mkdir . mkdirSync ( this . filePath ) ; } this . filenameWithoutPath = filename + CONSTANTS . DB_FILE_EXTENSION ; this . filename = path . join ( this . filePath , this . filenameWithoutPath ) ; this . datastore = new Datastore ( { filename : this . filename , timestampData : true } ) ; } returns { Promise < void > } memberof public async loadAsync ( ) { return new Promise ( ( resolve , reject ) => { this . datastore . loadDatabase ( function ( err ) { if ( ! err ) { resolve ( ) ; } else { reject ( err ) ; } } ) ; } ) ; } returns { Promise < void > } memberof public async compactAsync ( ) { return new Promise < void > ( ( resolve ) => { this . datastore . persistence . compactDatafile ( ) ; this . datastore . on ( "compaction.done" , function ( ) { resolve ( ) ; } ) ; } ) ; } param { ( object | object [ ] ) } objectsToInsert returns { Promise < IReturn > } memberof public async insertAsync ( objectsToInsert ) { return new Promise < IReturn > ( ( resolve ) => { this . datastore . insert ( objectsToInsert , function ( err , ret ) { resolve ( { data : ret , error : err as NedbError , } as IReturn ) ; } ) ; } ) ; } returns { string } memberof public getFilename ( ) { return this . filename ; } returns { string } memberof public getFilenameWithoutPath ( ) { return this . filenameWithoutPath ; } returns { string } memberof public getFilepath ( ) { return this . filePath ; } param queryToUpdate param updateWith { s param params public async updateAsync ( queryToUpdate , updateWith , params ? ) { updateWith = { $set : updateWith } ; const options = { multi : params && params . multi || true , upsert : params && params . upsert || false , returnUpdatedDocs : true , } ; return new Promise < IUpdateReturn > ( ( resolve ) => { this . datastore . update ( queryToUpdate , updateWith , options , function ( err , numAffected , affectedDocuments , upsert ) { resolve ( { error : err as NedbError , numAffected , affectedDocuments , upsert , } as IUpdateReturn ) ; } ) ; } ) ; } param query param fieldsToReturn param params public async queryAsync ( query , fieldsToReturn , params ? ) { Object . keys ( fieldsToReturn ) . forEach ( key => { fieldsToReturn [ key ] = + fieldsToReturn [ key ] ; } ) ; params = params && params || { sort : { createdAt : 1 } , } ; return new Promise < IReturn > ( ( resolve ) => { try { this . datastore . find ( query ) . projection ( fieldsToReturn ) . sort ( params . sort ) . skip ( params . skip ) . limit ( params . limit ) . exec ( function ( err , ret ) { resolve ( { data : ret , error : err as NedbError , } as IReturn ) ; } ) ; } catch ( e ) { return { data : [ ] , error : null as NedbError } as IReturn ; } } ) ; } param queryToDelete param multi public async deleteAsync ( queryToDelete , multi = true ) { const params = { multi , } ; return new Promise < IRemoveReturn > ( ( resolve ) => { this . datastore . remove ( queryToDelete , params , function ( err , numRemoved ) { resolve ( { numRemoved , error : err as NedbError , } as IRemoveReturn ) ; } ) ; } ) ; } }