{"filter":false,"title":"IAbstractStore.ts","tooltip":"/src/IAbstractStore.ts","undoManager":{"mark":46,"position":46,"stack":[[{"start":{"row":0,"column":0},"end":{"row":491,"column":1},"action":"insert","lines":["class FileSystemStore {","    private logger: Logger;","    private defaultOptions: Options = new Options({","        ddbb_path: 'db',","        collection_extension: 'json',","        sync: false","    });","    ","    options: Options = new Options();","    ","    constructor(options: Options = new Options()) {","        this.options = _.assign(this.defaultOptions, options);","        ","        // Create a new Logger instance with the logging options, if received ","        if (this.options.log) {","            this.logger = Logger.getInstance(this.options.log);","        } else {","            this.logger = Logger.instance;","        }","        ","        this.logger.debug(`Database will be in \"${this.options.ddbb_path}\" folder`);","        ","        // Ensure the existence of the main database directory (force sync)","        let created = this.ensureDirectorySync();   // when recursive -> this.options.ddbb_path","        this.logger.debug(`Directory \"${created}\" created`);","    }","    ","    /***************","     *   PRIVATE   *","     ***************/","    ","    private handleError(error: Error) {","        this.logger.throw(error);","    }","    ","    // TODO: Recursive","    private ensureDirectorySync(path: String = \"\", root: String = this.options.ddbb_path): String & Promise<String> {","        let dirPath = `${root}/${path}`;","        ","        try {","            fs.mkdirSync(dirPath);","            ","            return dirPath;","        } catch(error) {","            return this.handleError(error);","        }","    }","    ","    private ensureDirectory(path: String, root: String = this.options.ddbb_path): String & Promise<String> {","        let dirPath = `${root}/${path}`;","        ","        return new Promise((resolve, reject) => {","            if (this.options.sync) {","                return this.ensureDirectorySync(path, root);","            } else {","                fs.mkdir(dirPath, (error) => {","                    if (error) {","                        reject(error);","                    } else {","                        resolve(dirPath);","                    }","                });","            }","        });","    }","    ","    private existsFile(filename: String): boolean & Promise<boolean> {","        var exists = false;","        ","        if (this.options.sync) {","            try {","                let file = fs.readFileSync(filename);  ","                ","                if (!_.isNil(file)) {","                    var stats = fs.statSync(filename);","                    ","                    exists = stats.isFile();","                }","            } catch (error) {","                this.logger.debug(`File \"${filename}\" doesn't exist`);","            } finally {","                return exists;","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.readFile(filename, (error, file) => {","                    if (error || _.isNil(file)) {","                        reject(error || new Error(`File \"${filename}\" doesn't exist`));","                    } else {","                        fs.stat(filename, (error, stats) => {","                            if (error) {","                                reject(error);","                            } else {","                                resolve(stats.isFile());","                            }","                        });","                    }","                });","            });","        }","    }","    ","    private createFile(path: String): boolean & Promise<boolean> {","        return this.writeFile(path);","    }","    ","    private writeFile(path: String, content: String = \"\"): boolean & Promise<boolean> {","        if (this.options.sync) {","            try {","                fs.writeFileSync(path, content);","                ","                return true;","            } catch(error) {","                this.handleError(error);","                ","                return false;","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.writeFile(path, content, error => {","                    if (error) {","                        reject(error);","                    } else {","                        resolve(true);","                    }","                });","            });","        }","    }","    ","    private persist(collectionPath: String, documents: Object[]): boolean & Promise<boolean> {","        let docs = \"\";","        ","        for (let i = 0; i < documents.length; i++) {","            docs += JSON.stringify(documents[i]) + \"\\n\";","        }","        ","        if (this.options.sync) {","            let persisted = this.writeFile(collectionPath, docs);","    ","            if (persisted) {","                this.logger.debug(\"Documents persisted in the file system\");","            } else {","                this.logger.debug(\"Documents not persisted in the file system\");","            }","            ","            return persisted;","        } else {","            return new Promise((resolve, reject) => {","                this.writeFile(collectionPath, docs)","                    .then(persisted => {","                        this.logger.debug(\"Documents persisted in the file system\");","                        ","                        resolve(true);","                    })","                    .catch(error => {","                        this.logger.debug(\"Documents not persisted in the file system\");","                        ","                        reject(error);","                    });","            });","        }","    }","    ","    private readFile(path: String): Object & Promise<Object> {","        if (this.options.sync) {","            try {","                return fs.readFileSync(path);","            } catch(error) {","                return this.handleError(error);","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.readFile(path, (error, file) => {","                    if (error || _.isNil(file)) {","                        reject(error || new Error(`File \"${path}\" doesn't exist`));","                    } else {","                        this.logger.debug(`Collection \"${path}\" readed from the file system`);","                        ","                        resolve(file);","                    }","                });","            });","        }","    }","    ","    /***************","     *    UTILS    *","     ***************/","     ","    /**","     * Get the path of the collection file","     *","     * @method FileSystemStore#getCollectionPath","     * ","     * @param {String} ddbb_name - Name of the database","     * @param {String} coll_name - Name of the collection","     *","     * @return {String} - The path of the file","     */","    getCollectionPath(ddbb_name: String, coll_name: String): String {","        if (_.isNil(ddbb_name)) throw new Error(\"Parameter 'ddbb_name' is required\");","        if (_.isNil(coll_name)) throw new Error(\"Parameter 'coll_name' is required\");","        ","        return `${this.options.ddbb_path}/${ddbb_name}/${coll_name}.${this.options.collection_extension}`;","    }","    ","    /***************","     * COLLECTIONS *","     ***************/","     ","    /**","     * Receives a \"createCollection\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~createCollection","     * ","     * @listens MongoPortable~createCollection","     * ","     * @param {Object} event - Information of the event","     * ","     * @param {Object} event.connection - Information about the current database connection","     * @param {Object} event.collection - Information about the collection created","     * ","     * @return {boolean|Promise<boolean>} - True if the collection was created","     */","    createCollection(event): boolean & Promise<boolean> {","        this.logger.debug('#createCollection');","        ","        var coll_path = this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name);","        ","        if (this.options.sync) {","            if (!this.existsFile(coll_path)) {","                return this.createFile(coll_path);","            }","        } else {","            return new Promise((resolve, reject) => {","                this.existsFile(coll_path)","                    .then(exists => {","                        resolve(exists);","                    })","                    .catch(error => {","                        reject(error);","                    });","            });","        }","    }","    ","    /**********","     * CREATE *","     **********/","    ","    /**","     * Receives a \"insert\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~insert","     * ","     * @listens MongoPortable~insert","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @param {Object} event.collection - Information about the collection","     * @param {Object} event.doc - Information about the document inserted","     * ","     * @return {boolean|Promise<boolean>} - True if the collection was inserted","     */","    insert(event): boolean & Promise<boolean> {","        this.logger.debug('#insert');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    // TODO","    save(event) {","        this.logger.debug('#save');","    }","    ","    /**********","     *  READ  *","     **********/","    ","    // TODO","    all(event) {","        this.logger.debug('#all');","    }","    ","    /**","     * Receives a \"find\" event from MongoPortable, fetching the info of the collection file","     *","     * @method FileSystemStore~find","     * ","     * @listens MongoPortable~find","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.fields - The fields showed in the query","     * ","     * @return {Object|Promise<Object>} - An object with the document and indexes","     */","    find(event): Object & Promise<Object> {","        this.logger.debug('#find');","        ","        let parseLines = (file, cb?: Function) => {","            let docs = [];","            let indexes = {};","            ","            let lines = file.toString().split(\"\\n\");","            ","            // FIXME Workaround...","            for (let i = 0; i < lines.length; i++) {","                let doc = lines[i];","                ","                if (doc.trim() !== '') {","                    docs.push(JSON.parse(doc));","                    indexes[JSON.parse(doc)._id] = i;","                }","            }","            ","            event.collection.docs = docs;","            event.collection.doc_indexes = indexes;","            ","            if (cb) {","                cb(docs, indexes);","            } else {","                return { documents: docs, indexes };","            }","        };","        ","        if (this.options.sync) {","            let file = this.readFile(this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name));","            ","            parseLines(file);","        } else {","            return new Promise((resolve, reject) => {","                this.readFile(this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name))","                    .then(file => {","                        parseLines(file, (documents, indexes) => {","                            resolve({ documents, indexes });","                        });","                    })","                    .catch(error => {","                        reject(error);","                    });","            });","        }","        ","        ","        ","        /**/","        // var _docs = _.cloneDeep(event.collection.docs);","        // var _idxs = _.cloneDeep(event.collection.doc_indexes);","        ","        // for (collDocs) {","        //     let doc;","            ","        //     if (!_.hasIn(_idx, doc._id)) {","        //         add(doc);","        //     } else {","        //         update(doc);","        //     }","        // }","        /**/","        ","        // var docs = [];","        ","        // for (var i = 0; i < collDocs.length; i++) {","        //     var doc = collDocs[i];","            ","        //     docs.push(doc);","        //     event.collection.doc_indexes[doc._id] = i;","        // }","        ","        // if (docs.length !== )","        ","        // for (let key in event.collection.doc_indexes) {","            ","        // }","        ","        ","    }","    ","    /**","     * Receives a \"findOne\" event from MongoPortable, fetching the info of the collection file","     *","     * @method FileSystemStore~findOne","     * ","     * @listens MongoPortable~findOne","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.fields - The fields showed in the query","     * ","     * @return {Object|Promise<Object>} - An object with the document and indexes","     */","    findOne (event): Object & Promise<Object> {","        this.logger.debug('#findOne');","        ","        // FIXME When we can do a line-per-line file search, change this","        return this.find(event);","    }","    ","    /**********","     * UPDATE *","     **********/","    ","    /**","     * Receives an \"update\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~update","     * ","     * @listens MongoPortable~update","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.modifier - The modifier used in the query","     * @property {Object} event.docs - The updated/inserted documents information","     * ","     * @return {boolean|Promise<boolean>} - True if the documents were updated","     */","    update(event): boolean & Promise<boolean>  {","        this.logger.debug('#update');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    /**********","     * DELETE *","     **********/","    ","    /**","     * Receives an \"remove\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~remove","     * ","     * @listens MongoPortable~remove","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.docs - The deleted documents information","     * ","     * @return {boolean|Promise<boolean>} - True if the documents were removed","     */","    remove(event): boolean & Promise<boolean> {","        this.logger.debug('#remove');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    /**********","     * OTHERS *","     **********/","    // TODO","    ensureIndex(event){","        this.logger.debug('#ensureIndex');","    }","    ","    // TODO","    backup(event){","        this.logger.debug('#backup');","    }","    ","    // TODO","    backups(event){","        this.logger.debug('#backups');","    }","    ","    // TODO","    removeBackup(event){","        this.logger.debug('#removeBackup');","    }","    ","    // TODO","    restore(event){","        this.logger.debug('#restore');","    }","}"],"id":1}],[{"start":{"row":0,"column":0},"end":{"row":0,"column":5},"action":"remove","lines":["class"],"id":2},{"start":{"row":0,"column":0},"end":{"row":0,"column":1},"action":"insert","lines":["i"]}],[{"start":{"row":0,"column":1},"end":{"row":0,"column":2},"action":"insert","lines":["n"],"id":3}],[{"start":{"row":0,"column":2},"end":{"row":0,"column":3},"action":"insert","lines":["t"],"id":4}],[{"start":{"row":0,"column":3},"end":{"row":0,"column":4},"action":"insert","lines":["e"],"id":5}],[{"start":{"row":0,"column":4},"end":{"row":0,"column":5},"action":"insert","lines":["r"],"id":6}],[{"start":{"row":0,"column":5},"end":{"row":0,"column":6},"action":"insert","lines":["f"],"id":7}],[{"start":{"row":0,"column":6},"end":{"row":0,"column":7},"action":"insert","lines":["a"],"id":8}],[{"start":{"row":0,"column":7},"end":{"row":0,"column":8},"action":"insert","lines":["c"],"id":9}],[{"start":{"row":0,"column":8},"end":{"row":0,"column":9},"action":"insert","lines":["e"],"id":10}],[{"start":{"row":0,"column":10},"end":{"row":0,"column":25},"action":"remove","lines":["FileSystemStore"],"id":11},{"start":{"row":0,"column":10},"end":{"row":0,"column":24},"action":"insert","lines":["IAbstractStore"]}],[{"start":{"row":1,"column":0},"end":{"row":26,"column":0},"action":"remove","lines":["    private logger: Logger;","    private defaultOptions: Options = new Options({","        ddbb_path: 'db',","        collection_extension: 'json',","        sync: false","    });","    ","    options: Options = new Options();","    ","    constructor(options: Options = new Options()) {","        this.options = _.assign(this.defaultOptions, options);","        ","        // Create a new Logger instance with the logging options, if received ","        if (this.options.log) {","            this.logger = Logger.getInstance(this.options.log);","        } else {","            this.logger = Logger.instance;","        }","        ","        this.logger.debug(`Database will be in \"${this.options.ddbb_path}\" folder`);","        ","        // Ensure the existence of the main database directory (force sync)","        let created = this.ensureDirectorySync();   // when recursive -> this.options.ddbb_path","        this.logger.debug(`Directory \"${created}\" created`);","    }",""],"id":12}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    ",""],"id":13}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    /***************",""],"id":14}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["     *   PRIVATE   *",""],"id":15}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["     ***************/",""],"id":16}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    ",""],"id":17}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    private handleError(error: Error) {",""],"id":18}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        this.logger.throw(error);",""],"id":19}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    }",""],"id":20}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    ",""],"id":21}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    // TODO: Recursive",""],"id":22}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    private ensureDirectorySync(path: String = \"\", root: String = this.options.ddbb_path): String & Promise<String> {",""],"id":23}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        let dirPath = `${root}/${path}`;",""],"id":24}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        ",""],"id":25}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        try {",""],"id":26}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["            fs.mkdirSync(dirPath);",""],"id":27}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["            ",""],"id":28}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["            return dirPath;",""],"id":29}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        } catch(error) {",""],"id":30}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["            return this.handleError(error);",""],"id":31}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["        }",""],"id":32}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["    }",""],"id":33}],[{"start":{"row":1,"column":0},"end":{"row":143,"column":0},"action":"remove","lines":["    ","    private ensureDirectory(path: String, root: String = this.options.ddbb_path): String & Promise<String> {","        let dirPath = `${root}/${path}`;","        ","        return new Promise((resolve, reject) => {","            if (this.options.sync) {","                return this.ensureDirectorySync(path, root);","            } else {","                fs.mkdir(dirPath, (error) => {","                    if (error) {","                        reject(error);","                    } else {","                        resolve(dirPath);","                    }","                });","            }","        });","    }","    ","    private existsFile(filename: String): boolean & Promise<boolean> {","        var exists = false;","        ","        if (this.options.sync) {","            try {","                let file = fs.readFileSync(filename);  ","                ","                if (!_.isNil(file)) {","                    var stats = fs.statSync(filename);","                    ","                    exists = stats.isFile();","                }","            } catch (error) {","                this.logger.debug(`File \"${filename}\" doesn't exist`);","            } finally {","                return exists;","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.readFile(filename, (error, file) => {","                    if (error || _.isNil(file)) {","                        reject(error || new Error(`File \"${filename}\" doesn't exist`));","                    } else {","                        fs.stat(filename, (error, stats) => {","                            if (error) {","                                reject(error);","                            } else {","                                resolve(stats.isFile());","                            }","                        });","                    }","                });","            });","        }","    }","    ","    private createFile(path: String): boolean & Promise<boolean> {","        return this.writeFile(path);","    }","    ","    private writeFile(path: String, content: String = \"\"): boolean & Promise<boolean> {","        if (this.options.sync) {","            try {","                fs.writeFileSync(path, content);","                ","                return true;","            } catch(error) {","                this.handleError(error);","                ","                return false;","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.writeFile(path, content, error => {","                    if (error) {","                        reject(error);","                    } else {","                        resolve(true);","                    }","                });","            });","        }","    }","    ","    private persist(collectionPath: String, documents: Object[]): boolean & Promise<boolean> {","        let docs = \"\";","        ","        for (let i = 0; i < documents.length; i++) {","            docs += JSON.stringify(documents[i]) + \"\\n\";","        }","        ","        if (this.options.sync) {","            let persisted = this.writeFile(collectionPath, docs);","    ","            if (persisted) {","                this.logger.debug(\"Documents persisted in the file system\");","            } else {","                this.logger.debug(\"Documents not persisted in the file system\");","            }","            ","            return persisted;","        } else {","            return new Promise((resolve, reject) => {","                this.writeFile(collectionPath, docs)","                    .then(persisted => {","                        this.logger.debug(\"Documents persisted in the file system\");","                        ","                        resolve(true);","                    })","                    .catch(error => {","                        this.logger.debug(\"Documents not persisted in the file system\");","                        ","                        reject(error);","                    });","            });","        }","    }","    ","    private readFile(path: String): Object & Promise<Object> {","        if (this.options.sync) {","            try {","                return fs.readFileSync(path);","            } catch(error) {","                return this.handleError(error);","            }","        } else {","            return new Promise((resolve, reject) => {","                fs.readFile(path, (error, file) => {","                    if (error || _.isNil(file)) {","                        reject(error || new Error(`File \"${path}\" doesn't exist`));","                    } else {","                        this.logger.debug(`Collection \"${path}\" readed from the file system`);","                        ","                        resolve(file);","                    }","                });","            });","        }","    }","    ","    /***************","     *    UTILS    *","     ***************/",""],"id":34}],[{"start":{"row":1,"column":0},"end":{"row":2,"column":0},"action":"remove","lines":["     ",""],"id":35}],[{"start":{"row":1,"column":0},"end":{"row":18,"column":0},"action":"remove","lines":["    /**","     * Get the path of the collection file","     *","     * @method FileSystemStore#getCollectionPath","     * ","     * @param {String} ddbb_name - Name of the database","     * @param {String} coll_name - Name of the collection","     *","     * @return {String} - The path of the file","     */","    getCollectionPath(ddbb_name: String, coll_name: String): String {","        if (_.isNil(ddbb_name)) throw new Error(\"Parameter 'ddbb_name' is required\");","        if (_.isNil(coll_name)) throw new Error(\"Parameter 'coll_name' is required\");","        ","        return `${this.options.ddbb_path}/${ddbb_name}/${coll_name}.${this.options.collection_extension}`;","    }","    ",""],"id":36}],[{"start":{"row":1,"column":0},"end":{"row":19,"column":0},"action":"remove","lines":["    /***************","     * COLLECTIONS *","     ***************/","     ","    /**","     * Receives a \"createCollection\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~createCollection","     * ","     * @listens MongoPortable~createCollection","     * ","     * @param {Object} event - Information of the event","     * ","     * @param {Object} event.connection - Information about the current database connection","     * @param {Object} event.collection - Information about the collection created","     * ","     * @return {boolean|Promise<boolean>} - True if the collection was created","     */",""],"id":37}],[{"start":{"row":1,"column":29},"end":{"row":1,"column":36},"action":"remove","lines":["boolean"],"id":38}],[{"start":{"row":1,"column":29},"end":{"row":1,"column":30},"action":"remove","lines":[" "],"id":39}],[{"start":{"row":1,"column":29},"end":{"row":1,"column":30},"action":"remove","lines":["&"],"id":40}],[{"start":{"row":1,"column":29},"end":{"row":1,"column":30},"action":"remove","lines":[" "],"id":41}],[{"start":{"row":1,"column":26},"end":{"row":1,"column":27},"action":"insert","lines":[":"],"id":42}],[{"start":{"row":1,"column":27},"end":{"row":1,"column":28},"action":"insert","lines":[" "],"id":43}],[{"start":{"row":1,"column":28},"end":{"row":1,"column":29},"action":"insert","lines":["a"],"id":44}],[{"start":{"row":1,"column":29},"end":{"row":1,"column":30},"action":"insert","lines":["n"],"id":45}],[{"start":{"row":1,"column":30},"end":{"row":1,"column":31},"action":"insert","lines":["y"],"id":46}],[{"start":{"row":0,"column":0},"end":{"row":267,"column":1},"action":"remove","lines":["interface IAbstractStore {","    createCollection(event: any): Promise<boolean> {","        this.logger.debug('#createCollection');","        ","        var coll_path = this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name);","        ","        if (this.options.sync) {","            if (!this.existsFile(coll_path)) {","                return this.createFile(coll_path);","            }","        } else {","            return new Promise((resolve, reject) => {","                this.existsFile(coll_path)","                    .then(exists => {","                        resolve(exists);","                    })","                    .catch(error => {","                        reject(error);","                    });","            });","        }","    }","    ","    /**********","     * CREATE *","     **********/","    ","    /**","     * Receives a \"insert\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~insert","     * ","     * @listens MongoPortable~insert","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @param {Object} event.collection - Information about the collection","     * @param {Object} event.doc - Information about the document inserted","     * ","     * @return {boolean|Promise<boolean>} - True if the collection was inserted","     */","    insert(event): boolean & Promise<boolean> {","        this.logger.debug('#insert');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    // TODO","    save(event) {","        this.logger.debug('#save');","    }","    ","    /**********","     *  READ  *","     **********/","    ","    // TODO","    all(event) {","        this.logger.debug('#all');","    }","    ","    /**","     * Receives a \"find\" event from MongoPortable, fetching the info of the collection file","     *","     * @method FileSystemStore~find","     * ","     * @listens MongoPortable~find","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.fields - The fields showed in the query","     * ","     * @return {Object|Promise<Object>} - An object with the document and indexes","     */","    find(event): Object & Promise<Object> {","        this.logger.debug('#find');","        ","        let parseLines = (file, cb?: Function) => {","            let docs = [];","            let indexes = {};","            ","            let lines = file.toString().split(\"\\n\");","            ","            // FIXME Workaround...","            for (let i = 0; i < lines.length; i++) {","                let doc = lines[i];","                ","                if (doc.trim() !== '') {","                    docs.push(JSON.parse(doc));","                    indexes[JSON.parse(doc)._id] = i;","                }","            }","            ","            event.collection.docs = docs;","            event.collection.doc_indexes = indexes;","            ","            if (cb) {","                cb(docs, indexes);","            } else {","                return { documents: docs, indexes };","            }","        };","        ","        if (this.options.sync) {","            let file = this.readFile(this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name));","            ","            parseLines(file);","        } else {","            return new Promise((resolve, reject) => {","                this.readFile(this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name))","                    .then(file => {","                        parseLines(file, (documents, indexes) => {","                            resolve({ documents, indexes });","                        });","                    })","                    .catch(error => {","                        reject(error);","                    });","            });","        }","        ","        ","        ","        /**/","        // var _docs = _.cloneDeep(event.collection.docs);","        // var _idxs = _.cloneDeep(event.collection.doc_indexes);","        ","        // for (collDocs) {","        //     let doc;","            ","        //     if (!_.hasIn(_idx, doc._id)) {","        //         add(doc);","        //     } else {","        //         update(doc);","        //     }","        // }","        /**/","        ","        // var docs = [];","        ","        // for (var i = 0; i < collDocs.length; i++) {","        //     var doc = collDocs[i];","            ","        //     docs.push(doc);","        //     event.collection.doc_indexes[doc._id] = i;","        // }","        ","        // if (docs.length !== )","        ","        // for (let key in event.collection.doc_indexes) {","            ","        // }","        ","        ","    }","    ","    /**","     * Receives a \"findOne\" event from MongoPortable, fetching the info of the collection file","     *","     * @method FileSystemStore~findOne","     * ","     * @listens MongoPortable~findOne","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.fields - The fields showed in the query","     * ","     * @return {Object|Promise<Object>} - An object with the document and indexes","     */","    findOne (event): Object & Promise<Object> {","        this.logger.debug('#findOne');","        ","        // FIXME When we can do a line-per-line file search, change this","        return this.find(event);","    }","    ","    /**********","     * UPDATE *","     **********/","    ","    /**","     * Receives an \"update\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~update","     * ","     * @listens MongoPortable~update","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.modifier - The modifier used in the query","     * @property {Object} event.docs - The updated/inserted documents information","     * ","     * @return {boolean|Promise<boolean>} - True if the documents were updated","     */","    update(event): boolean & Promise<boolean>  {","        this.logger.debug('#update');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    /**********","     * DELETE *","     **********/","    ","    /**","     * Receives an \"remove\" event from MongoPortable, syncronizing the collection file with the new info","     *","     * @method FileSystemStore~remove","     * ","     * @listens MongoPortable~remove","     * ","     * @param {Object} event - Arguments from the event","     * ","     * @property {Object} event.collection - Information about the collection","     * @property {Object} event.selector - The selection of the query","     * @property {Object} event.docs - The deleted documents information","     * ","     * @return {boolean|Promise<boolean>} - True if the documents were removed","     */","    remove(event): boolean & Promise<boolean> {","        this.logger.debug('#remove');","        ","        return this.persist(","            this.getCollectionPath(event.collection.fullName.split('.')[0], event.collection.name),","            event.collection.docs","        );","    }","    ","    /**********","     * OTHERS *","     **********/","    // TODO","    ensureIndex(event){","        this.logger.debug('#ensureIndex');","    }","    ","    // TODO","    backup(event){","        this.logger.debug('#backup');","    }","    ","    // TODO","    backups(event){","        this.logger.debug('#backups');","    }","    ","    // TODO","    removeBackup(event){","        this.logger.debug('#removeBackup');","    }","    ","    // TODO","    restore(event){","        this.logger.debug('#restore');","    }","}"],"id":47},{"start":{"row":0,"column":0},"end":{"row":26,"column":1},"action":"insert","lines":["export interface IAbstractStore {","\tcreateCollection(event): boolean | Promise<boolean>;","\t","    insert(event): boolean | Promise<boolean>;","    ","    save(event): object | Promise<object>;","","    all(event): object | Promise<object>;","    ","    find(event): object | Promise<object>;","    ","    findOne (event): object | Promise<object>;","    ","    update(event): boolean | Promise<boolean>;","    ","    remove(event): boolean | Promise<boolean>;","    ","    ensureIndex(event): object | Promise<object>;","    ","    backup(event): object | Promise<object>;","    ","    backups(event): object | Promise<object>;","    ","    removeBackup(event): object | Promise<object>;","    ","    restore(event): object | Promise<object>;","}"]}]]},"ace":{"folds":[],"scrolltop":260,"scrollleft":0,"selection":{"start":{"row":26,"column":1},"end":{"row":26,"column":1},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":16,"state":"start","mode":"ace/mode/typescript"}},"timestamp":1508856982508,"hash":"90507e263cf94910696f75747ec714b530735fbf"}