diff --git a/.eslintignore b/.eslintignore index bd0ff0f1e0f4a72bf6188f302bc6d53226ff44cd..34c7cb27cf5ba69e475149455605b4d9c0da72b5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,5 +8,6 @@ app/lib/common.js app/lib/dal/drivers/*.js app/lib/dal/sqliteDAL/*.js app/lib/dal/sqliteDAL/index/*.js -test/blockchain/*.js -test/blockchain/lib/*.js \ No newline at end of file +app/lib/dal/fileDALs/*.js +test/*.js +test/**/*.js \ No newline at end of file diff --git a/.gitignore b/.gitignore index cc5097572d794214e2a8ae4d13d09d5ddbc1701e..c4cca1419073eb89a6e7b0017319bec510c3917e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,5 @@ app/lib/dto/*.js* app/lib/indexer.js* app/lib/dal/drivers/*.js* app/lib/dal/sqliteDAL/*.js* -app/lib/dal/sqliteDAL/index/*.js* \ No newline at end of file +app/lib/dal/sqliteDAL/index/*.js* +app/lib/dal/fileDALs/*.js* \ No newline at end of file diff --git a/app/lib/cfs.js b/app/lib/cfs.js deleted file mode 100644 index 4d8a55804e809c4277d8a54938d9c16f0b74da31..0000000000000000000000000000000000000000 --- a/app/lib/cfs.js +++ /dev/null @@ -1,246 +0,0 @@ -"use strict"; - -const _ = require('underscore'); -const co = require('co'); -const path = require('path'); - -const LOCAL_LEVEL = true; -const DEEP_WRITE = true; - -module.exports = function(rootPath, qfs, parent) { - return new CFSCore(rootPath, qfs, parent); -}; - -function CFSCore(rootPath, qfs, parent) { - - const that = this; - - this.parent = parent; - const deletedFolder = path.join(rootPath, '.deleted'); - let deletionFolderPromise; - - this.changeParent = (newParent) => this.parent = newParent; - - /** - * Creates the deletion folder before effective deletion. - * @returns {*|any|Promise<void>} Promise of creation. - */ - const createDeletionFolder = () => deletionFolderPromise || (deletionFolderPromise = that.makeTree('.deleted')); - - /** - * READ operation of CFS. Reads given file. May lead to tree traversal if file is not found. - * @param filePath Path to the file. - * @returns {*} Promise for file content. - */ - this.read = (filePath) => { - return co(function *() { - try { - const isDeleted = yield qfs.exists(path.join(deletedFolder, toRemoveFileName(filePath))); - if (isDeleted) { - // A deleted file must be considered non-existant - return null; - } - return yield qfs.read(path.join(rootPath, filePath)); - } catch (e) { - if (!that.parent) return null; - return that.parent.read(filePath); - } - }); - }; - - /** - * READ operation of CFS. Reads given file. May lead to tree traversal if file is not found. - * @param filePath Path to the file. - * @returns {*} Promise for file content. - */ - this.exists = (filePath) => { - return co(function *() { - try { - const isDeleted = yield qfs.exists(path.join(deletedFolder, toRemoveFileName(filePath))); - if (isDeleted) { - // A deleted file must be considered non-existant - return false; - } - let exists = yield qfs.exists(path.join(rootPath, filePath)); - if (!exists && that.parent) { - exists = that.parent.exists(filePath); - } - return exists; - } catch (e) { - if (!that.parent) return null; - return that.parent.exists(filePath); - } - }); - }; - - /** - * LIST operation of CFS. List files at given location. Tree traversal. - * @param ofPath Location folder to list files. - * @param localLevel Limit listing to local level. - * @returns {*} Promise of file names. - */ - this.list = (ofPath, localLevel) => { - const dirPath = path.normalize(ofPath); - return co(function *() { - let files = [], folder = path.join(rootPath, dirPath); - if (that.parent && !localLevel) { - files = yield that.parent.list(dirPath); - } - const hasDir = yield qfs.exists(folder); - if (hasDir) { - files = files.concat(yield qfs.list(folder)); - } - const hasDeletedFiles = yield qfs.exists(deletedFolder); - if (hasDeletedFiles) { - const deletedFiles = yield qfs.list(deletedFolder); - const deletedOfThisPath = deletedFiles.filter((f) => f.match(new RegExp('^' + toRemoveDirName(dirPath)))); - const locallyDeletedFiles = deletedOfThisPath.map((f) => f.replace(toRemoveDirName(dirPath), '') - .replace(/^__/, '')); - files = _.difference(files, locallyDeletedFiles); - } - return _.uniq(files); - }); - }; - - this.listLocal = (ofPath) => this.list(ofPath, LOCAL_LEVEL); - - /** - * WRITE operation of CFS. Writes the file in local Core. - * @param filePath Path to the file to write. - * @param content String content to write. - * @param deep Wether to make a deep write or not. - */ - this.write = (filePath, content, deep) => { - return co(function *() { - if (deep && that.parent) { - return that.parent.write(filePath, content, deep); - } - return qfs.write(path.join(rootPath, filePath), content); - }); - }; - - /** - * REMOVE operation of CFS. Set given file as removed. Logical deletion since physical won't work due to the algorithm of CFS. - * @param filePath File to set as removed. - * @param deep Wether to remove the file in the root core or not. - * @returns {*} Promise of removal. - */ - this.remove = (filePath, deep) => { - return co(function *() { - // Make a deep physical deletion - if (deep && that.parent) { - return that.parent.remove(filePath, deep); - } - // Not the root core, make a logical deletion instead of physical - if (that.parent) { - yield createDeletionFolder(); - return qfs.write(path.join(rootPath, '.deleted', toRemoveFileName(filePath)), ''); - } - // Root core: physical deletion - return qfs.remove(path.join(rootPath, filePath)); - }); - }; - - /** - * REMOVE operation of CFS. Set given file as removed. Logical deletion since physical won't work due to the algorithm of CFS. - * @param filePath File to set as removed. - * @returns {*} Promise of removal. - */ - this.removeDeep = (filePath) => this.remove(filePath, DEEP_WRITE); - - /** - * Create a directory tree. - * @param treePath Tree path to create. - */ - this.makeTree = (treePath) => co(function*(){ - // Note: qfs.makeTree does not work on windows, so we implement it manually - try { - let normalized = path.normalize(treePath); - let folders = normalized.split(path.sep); - let folder = rootPath; - for (let i = 0, len = folders.length; i < len; i++) { - folder = folder ? path.join(folder, folders[i]) : folders[i]; - let exists = yield qfs.exists(folder); - if (!exists) { - yield qfs.makeDirectory(folder); - } - } - } catch (e) { - if (e && e.code !== "EISDIR" && e.code !== "EEXIST") throw e; - } - }); - - /** - * Write JSON object to given file. - * @param filePath File path. - * @param content JSON content to stringify and write. - * @param deep Wether to make a deep write or not. - */ - this.writeJSON = (filePath, content, deep) => this.write(filePath, JSON.stringify(content, null, ' '), deep); - - /** - * Write JSON object to given file deeply in the core structure. - * @param filePath File path. - * @param content JSON content to stringify and write. - */ - this.writeJSONDeep = (filePath, content) => this.writeJSON(filePath, content, DEEP_WRITE); - - /** - * Read a file and parse its content as JSON. - * @param filePath File to read. - */ - this.readJSON = (filePath) => co(function*(){ - let data; - try { - data = yield that.read(filePath); - return JSON.parse(data); - } catch(err) { - if (data && err.message.match(/^Unexpected token {/)) { - // This is a bug thrown during Unit Tests with MEMORY_MODE true... - return JSON.parse(data.match(/^(.*)}{.*/)[1] + '}'); - } else if (err.message.match(/^Unexpected end of input/)) { - // Could not read, return empty object - return {}; - } - throw err; - } - }); - - /** - * Read contents of files at given path and parse it as JSON. - * @param dirPath Path to get the files' contents. - * @param localLevel Wether to read only local level or not. - */ - this.listJSON = (dirPath, localLevel) => this.list(dirPath, localLevel).then((files) => { - return co(function *() { - return yield files.map((f) => that.readJSON(path.join(dirPath, f))); - }); - }); - - /** - * Read contents of files at given LOCAL path and parse it as JSON. - * @param dirPath Path to get the files' contents. - */ - this.listJSONLocal = (dirPath) => this.listJSON(dirPath, LOCAL_LEVEL); - - /** - * Normalize the path of a dir to be used for file deletion matching. - * @param dirPath Directory path to normalize. - * @returns {string|ng.ILocationService|XML} Normalized dir path. - */ - function toRemoveDirName(dirPath) { - if (!dirPath.match(/\/$/)) { - dirPath += '/'; - } - return path.normalize(dirPath).replace(/\//g, '__').replace(/\\/g, '__'); - } - - /** - * Normalize the name of the deleted file. - * @param filePath Full path of the file, included file name. - * @returns {string|ng.ILocationService|XML} Normalized file name. - */ - function toRemoveFileName(filePath) { - return path.normalize(filePath).replace(/\//g, '__').replace(/\\/g, '__'); - } -} diff --git a/app/lib/dal/fileDAL.js b/app/lib/dal/fileDAL.js index f6fd59cf3cc08f8981b41278db6c9b5a16796d3c..eee97d92b59528ce9200c52c6faaf828f55f8825 100644 --- a/app/lib/dal/fileDAL.js +++ b/app/lib/dal/fileDAL.js @@ -10,9 +10,8 @@ const Merkle = require('../entity/merkle'); const Transaction = require('../entity/transaction'); const TransactionDTO = require('../dto/TransactionDTO').TransactionDTO const constants = require('../constants'); -const ConfDAL = require('./fileDALs/confDAL'); -const StatDAL = require('./fileDALs/statDAL'); -const CFSStorage = require('./fileDALs/AbstractCFS'); +const ConfDAL = require('./fileDALs/ConfDAL').ConfDAL +const StatDAL = require('./fileDALs/StatDAL').StatDAL module.exports = (params) => { return new FileDAL(params); @@ -29,12 +28,12 @@ function FileDAL(params) { this.wotb = params.wotb; // DALs - this.confDAL = new ConfDAL(rootPath, myFS, null, that, CFSStorage); + this.confDAL = new ConfDAL(rootPath, myFS, null, that) this.metaDAL = new (require('./sqliteDAL/MetaDAL').MetaDAL)(sqliteDriver); this.peerDAL = new (require('./sqliteDAL/PeerDAL').PeerDAL)(sqliteDriver); this.blockDAL = new (require('./sqliteDAL/BlockDAL').BlockDAL)(sqliteDriver); this.txsDAL = new (require('./sqliteDAL/TxsDAL').TxsDAL)(sqliteDriver); - this.statDAL = new StatDAL(rootPath, myFS, null, that, CFSStorage); + this.statDAL = new StatDAL(rootPath, myFS, null, that) this.idtyDAL = new (require('./sqliteDAL/IdentityDAL').IdentityDAL)(sqliteDriver); this.certDAL = new (require('./sqliteDAL/CertDAL').CertDAL)(sqliteDriver); this.msDAL = new (require('./sqliteDAL/MembershipDAL').MembershipDAL)(sqliteDriver); @@ -739,9 +738,9 @@ function FileDAL(params) { * STATISTICS **********************/ - this.loadStats = that.statDAL.loadStats; - this.getStat = that.statDAL.getStat; - this.pushStats = that.statDAL.pushStats; + this.loadStats = () => that.statDAL.loadStats(); + this.getStat = (name) => that.statDAL.getStat(name); + this.pushStats = (stats) => that.statDAL.pushStats(stats); this.cleanCaches = () => co(function *() { yield _.values(that.newDals).map((dal) => dal.cleanCache && dal.cleanCache()); diff --git a/app/lib/dal/fileDALs/AbstractCFS.js b/app/lib/dal/fileDALs/AbstractCFS.js deleted file mode 100644 index 141375e4902059958375ff0070868b3a334e44d5..0000000000000000000000000000000000000000 --- a/app/lib/dal/fileDALs/AbstractCFS.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Created by cgeek on 22/08/15. - */ - -const cfs = require('../../cfs'); - -module.exports = AbstractCFS; - -function AbstractCFS(rootPath, qioFS, parentDAL, localDAL) { - - "use strict"; - - this.coreFS = cfs(rootPath, qioFS, parentDAL); - this.dal = localDAL; -} diff --git a/app/lib/dal/fileDALs/AbstractCFS.ts b/app/lib/dal/fileDALs/AbstractCFS.ts new file mode 100644 index 0000000000000000000000000000000000000000..5336db81f783d353ab12e15240dc67c6b7a0ec5f --- /dev/null +++ b/app/lib/dal/fileDALs/AbstractCFS.ts @@ -0,0 +1,12 @@ +import {CFSCore} from "./CFSCore"; + +export class AbstractCFS { + + protected coreFS:CFSCore + dal:any + + constructor(rootPath:string, qioFS:any, parentDAL:CFSCore, localDAL:any) { + this.coreFS = new CFSCore(rootPath, qioFS, parentDAL) + this.dal = localDAL; + } +} diff --git a/app/lib/dal/fileDALs/CFSCore.ts b/app/lib/dal/fileDALs/CFSCore.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7d365c4aa75f02945aa3211ab48830ef981a70f --- /dev/null +++ b/app/lib/dal/fileDALs/CFSCore.ts @@ -0,0 +1,244 @@ +"use strict"; + +const _ = require('underscore'); +const path = require('path'); + +const LOCAL_LEVEL = true; +const DEEP_WRITE = true; + +export class CFSCore { + + private deletedFolder:string + private deletionFolderPromise: Promise<any> | null + private createDeletionFolder: () => Promise<any> | null + + constructor(private rootPath:string, private qfs:any, private parent:CFSCore | null) { + this.deletedFolder = path.join(rootPath, '.deleted') + this.deletionFolderPromise = null + + /** + * Creates the deletion folder before effective deletion. + * @returns {*|any|Promise<void>} Promise of creation. + */ + this.createDeletionFolder = () => this.deletionFolderPromise || (this.deletionFolderPromise = this.makeTree('.deleted')) + } + + changeParent(newParent:CFSCore) { + this.parent = newParent + } + + /** + * READ operation of CFS. Reads given file. May lead to tree traversal if file is not found. + * @param filePath Path to the file. + * @returns {*} Promise for file content. + */ + async read(filePath:string): Promise<string | null> { + try { + const isDeleted = await this.qfs.exists(path.join(this.deletedFolder, this.toRemoveFileName(filePath))); + if (isDeleted) { + // A deleted file must be considered non-existant + return null; + } + return await this.qfs.read(path.join(this.rootPath, filePath)); + } catch (e) { + if (!this.parent) return null; + return this.parent.read(filePath); + } + } + + /** + * READ operation of CFS. Reads given file. May lead to tree traversal if file is not found. + * @param filePath Path to the file. + * @returns {*} Promise for file content. + */ + async exists(filePath:string): Promise<boolean | null> { + try { + const isDeleted = await this.qfs.exists(path.join(this.deletedFolder, this.toRemoveFileName(filePath))); + if (isDeleted) { + // A deleted file must be considered non-existant + return false; + } + let exists = await this.qfs.exists(path.join(this.rootPath, filePath)); + if (!exists && this.parent) { + exists = this.parent.exists(filePath); + } + return exists; + } catch (e) { + if (!this.parent) return null; + return this.parent.exists(filePath); + } + } + + /** + * LIST operation of CFS. List files at given location. Tree traversal. + * @param ofPath Location folder to list files. + * @param localLevel Limit listing to local level. + * @returns {*} Promise of file names. + */ + async list(ofPath:string, localLevel = false): Promise<string[]> { + const dirPath = path.normalize(ofPath); + let files: string[] = [], folder = path.join(this.rootPath, dirPath); + if (this.parent && !localLevel) { + files = await this.parent.list(dirPath); + } + const hasDir = await this.qfs.exists(folder); + if (hasDir) { + files = files.concat(await this.qfs.list(folder)); + } + const hasDeletedFiles = await this.qfs.exists(this.deletedFolder); + if (hasDeletedFiles) { + const deletedFiles = await this.qfs.list(this.deletedFolder); + const deletedOfThisPath = deletedFiles.filter((f:string) => f.match(new RegExp('^' + this.toRemoveDirName(dirPath)))); + const locallyDeletedFiles = deletedOfThisPath.map((f:string) => f.replace(this.toRemoveDirName(dirPath), '') + .replace(/^__/, '')); + files = _.difference(files, locallyDeletedFiles); + } + return _.uniq(files); + }; + + listLocal(ofPath:string) { + return this.list(ofPath, LOCAL_LEVEL) + } + + /** + * WRITE operation of CFS. Writes the file in local Core. + * @param filePath Path to the file to write. + * @param content String content to write. + * @param deep Wether to make a deep write or not. + */ + async write(filePath:string, content:string, deep:boolean): Promise<void> { + if (deep && this.parent) { + return this.parent.write(filePath, content, deep); + } + return this.qfs.write(path.join(this.rootPath, filePath), content); + }; + + /** + * REMOVE operation of CFS. Set given file as removed. Logical deletion since physical won't work due to the algorithm of CFS. + * @param filePath File to set as removed. + * @param deep Wether to remove the file in the root core or not. + * @returns {*} Promise of removal. + */ + async remove(filePath:string, deep:boolean): Promise<void> { + // Make a deep physical deletion + if (deep && this.parent) { + return this.parent.remove(filePath, deep); + } + // Not the root core, make a logical deletion instead of physical + if (this.parent) { + await this.createDeletionFolder(); + return this.qfs.write(path.join(this.rootPath, '.deleted', this.toRemoveFileName(filePath)), ''); + } + // Root core: physical deletion + return this.qfs.remove(path.join(this.rootPath, filePath)); + } + + /** + * REMOVE operation of CFS. Set given file as removed. Logical deletion since physical won't work due to the algorithm of CFS. + * @param filePath File to set as removed. + * @returns {*} Promise of removal. + */ + removeDeep(filePath:string) { + return this.remove(filePath, DEEP_WRITE) + } + + /** + * Create a directory tree. + * @param treePath Tree path to create. + */ + async makeTree(treePath:string) { + // Note: qfs.makeTree does not work on windows, so we implement it manually + try { + let normalized = path.normalize(treePath); + let folders = normalized.split(path.sep); + let folder = this.rootPath; + for (let i = 0, len = folders.length; i < len; i++) { + folder = folder ? path.join(folder, folders[i]) : folders[i]; + let exists = await this.qfs.exists(folder); + if (!exists) { + await this.qfs.makeDirectory(folder); + } + } + } catch (e) { + if (e && e.code !== "EISDIR" && e.code !== "EEXIST") throw e; + } + } + + /** + * Write JSON object to given file. + * @param filePath File path. + * @param content JSON content to stringify and write. + * @param deep Wether to make a deep write or not. + */ + writeJSON(filePath:string, content:any, deep:boolean = false) { + return this.write(filePath, JSON.stringify(content, null, ' '), deep) + } + + /** + * Write JSON object to given file deeply in the core structure. + * @param filePath File path. + * @param content JSON content to stringify and write. + */ + writeJSONDeep(filePath:string, content:any) { + return this.writeJSON(filePath, content, DEEP_WRITE) + } + + /** + * Read a file and parse its content as JSON. + * @param filePath File to read. + */ + async readJSON(filePath:string) { + let data:any; + try { + data = await this.read(filePath); + return JSON.parse(data); + } catch(err) { + if (data && err.message.match(/^Unexpected token {/)) { + // This is a bug thrown during Unit Tests with MEMORY_MODE true... + return JSON.parse(data.match(/^(.*)}{.*/)[1] + '}'); + } else if (err.message.match(/^Unexpected end of input/)) { + // Could not read, return empty object + return {}; + } + throw err; + } + } + + /** + * Read contents of files at given path and parse it as JSON. + * @param dirPath Path to get the files' contents. + * @param localLevel Wether to read only local level or not. + */ + listJSON(dirPath:string, localLevel:boolean) { + return this.list(dirPath, localLevel).then(async (files) => Promise.all(files.map((f:string) => this.readJSON(path.join(dirPath, f))))) + } + + /** + * Read contents of files at given LOCAL path and parse it as JSON. + * @param dirPath Path to get the files' contents. + */ + listJSONLocal(dirPath:string) { + return this.listJSON(dirPath, LOCAL_LEVEL) + } + + /** + * Normalize the path of a dir to be used for file deletion matching. + * @param dirPath Directory path to normalize. + * @returns {string|ng.ILocationService|XML} Normalized dir path. + */ + private toRemoveDirName(dirPath:string) { + if (!dirPath.match(/\/$/)) { + dirPath += '/'; + } + return path.normalize(dirPath).replace(/\//g, '__').replace(/\\/g, '__'); + } + + /** + * Normalize the name of the deleted file. + * @param filePath Full path of the file, included file name. + * @returns {string|ng.ILocationService|XML} Normalized file name. + */ + private toRemoveFileName(filePath:string) { + return path.normalize(filePath).replace(/\//g, '__').replace(/\\/g, '__'); + } +} diff --git a/app/lib/dal/fileDALs/confDAL.js b/app/lib/dal/fileDALs/ConfDAL.ts similarity index 59% rename from app/lib/dal/fileDALs/confDAL.js rename to app/lib/dal/fileDALs/ConfDAL.ts index e9ab9b82a0f469a740e4b7a3750e8b734b2a88c7..0bb03f3c5e033ea7721a276185e708aa093ae41d 100644 --- a/app/lib/dal/fileDALs/confDAL.js +++ b/app/lib/dal/fileDALs/ConfDAL.ts @@ -1,27 +1,25 @@ -/** - * Created by cgeek on 22/08/15. - */ +import {CFSCore} from "./CFSCore"; +import {AbstractCFS} from "./AbstractCFS"; +import {ConfDTO} from "../../dto/ConfDTO"; const Configuration = require('../../entity/configuration'); -const co = require('co'); const _ = require('underscore'); -module.exports = ConfDAL; +export class ConfDAL extends AbstractCFS { -function ConfDAL(rootPath, qioFS, parentCore, localDAL, AbstractStorage) { + private logger:any - "use strict"; + constructor(rootPath:string, qioFS:any, parentCore:CFSCore|any, localDAL:any) { + super(rootPath, qioFS, parentCore, localDAL) + this.logger = require('../../logger')(this.dal.profile) + } - const that = this; + init() { + return Promise.resolve() + } - AbstractStorage.call(this, rootPath, qioFS, parentCore, localDAL); - - const logger = require('../../logger')(this.dal.profile); - - this.init = () => Promise.resolve(); - - this.getParameters = () => co(function *() { - const conf = yield that.loadConf(); + async getParameters() { + const conf = await this.loadConf() return { "currency": conf.currency, "c": parseFloat(conf.c), @@ -34,7 +32,7 @@ function ConfDAL(rootPath, qioFS, parentCore, localDAL, AbstractStorage) { "sigQty": parseInt(conf.sigQty,10), "idtyWindow": parseInt(conf.idtyWindow,10), "msWindow": parseInt(conf.msWindow,10), - "xpercent": parseFloat(conf.xpercent,10), + "xpercent": parseFloat(conf.xpercent), "msValidity": parseInt(conf.msValidity,10), "stepMax": parseInt(conf.stepMax,10), "medianTimeBlocks": parseInt(conf.medianTimeBlocks,10), @@ -44,19 +42,21 @@ function ConfDAL(rootPath, qioFS, parentCore, localDAL, AbstractStorage) { "udTime0": parseInt(conf.udTime0), "udReevalTime0": parseInt(conf.udReevalTime0), "dtReeval": parseInt(conf.dtReeval) - }; - }); + } + } - this.loadConf = () => co(function *() { - const data = yield that.coreFS.readJSON('conf.json'); + async loadConf() { + const data = await this.coreFS.readJSON('conf.json'); if (data) { return _(Configuration.statics.defaultConf()).extend(data); } else { // Silent error - logger.warn('No configuration loaded'); + this.logger.warn('No configuration loaded'); return {}; } - }); + } - this.saveConf = (confToSave) => that.coreFS.writeJSONDeep('conf.json', confToSave); + async saveConf(confToSave:ConfDTO) { + await this.coreFS.writeJSONDeep('conf.json', confToSave) + } } diff --git a/app/lib/dal/fileDALs/StatDAL.ts b/app/lib/dal/fileDALs/StatDAL.ts new file mode 100644 index 0000000000000000000000000000000000000000..26b191628b3977b95bc6dc5ec922a8cd3fd7b416 --- /dev/null +++ b/app/lib/dal/fileDALs/StatDAL.ts @@ -0,0 +1,37 @@ +import {AbstractCFS} from "./AbstractCFS"; +import {CFSCore} from "./CFSCore"; +const _ = require('underscore'); + +export class StatDAL extends AbstractCFS { + + constructor(rootPath:string, qioFS:any, parentDAL:CFSCore, localDAL:any) { + super(rootPath, qioFS, parentDAL, localDAL) + } + + init() { + return Promise.resolve() + } + + async loadStats() { + try { + return await this.coreFS.readJSON('stats.json') + } catch (e) { + return null; + } + } + + getStat(statName:string) { + return this.loadStats().then((stats:any) => (stats && stats[statName]) || { statName: statName, blocks: [], lastParsedBlock: -1 }) + } + + async pushStats(statsToPush:any) { + const stats = (await this.loadStats()) || {}; + _.keys(statsToPush).forEach(function(statName:string){ + if (!stats[statName]) { + stats[statName] = { blocks: [] }; + } + stats[statName].blocks = stats[statName].blocks.concat(statsToPush[statName].blocks); + }); + return this.coreFS.writeJSON('stats.json', stats) + } +} diff --git a/app/lib/dal/fileDALs/statDAL.js b/app/lib/dal/fileDALs/statDAL.js deleted file mode 100644 index 7e802893e25269df93574fe42b53d4b16020a381..0000000000000000000000000000000000000000 --- a/app/lib/dal/fileDALs/statDAL.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Created by cgeek on 22/08/15. - */ - -const co = require('co'); -const _ = require('underscore'); - -module.exports = StatDAL; - -function StatDAL(rootPath, qioFS, parentCore, localDAL, AbstractStorage) { - - "use strict"; - - const that = this; - - AbstractStorage.call(this, rootPath, qioFS, parentCore, localDAL); - - this.init = () => Promise.resolve(); - - this.loadStats = () => co(function*(){ - try { - return yield that.coreFS.readJSON('stats.json'); - } catch (e) { - return null; - } - }); - - this.getStat = (statName) => that.loadStats().then((stats) => (stats && stats[statName]) || { statName: statName, blocks: [], lastParsedBlock: -1 }); - - this.pushStats = (statsToPush) => co(function *() { - const stats = (yield that.loadStats()) || {}; - _.keys(statsToPush).forEach(function(statName){ - if (!stats[statName]) { - stats[statName] = { blocks: [] }; - } - stats[statName].blocks = stats[statName].blocks.concat(statsToPush[statName].blocks); - }); - return that.coreFS.writeJSON('stats.json', stats); - }); -} diff --git a/app/lib/system/directory.js b/app/lib/system/directory.js index f2fde3484e4537c60a6c8b9e4b65a8eeb356f2cc..7a968fcf1ec6b96830246dd53942f4ec8b6493fd 100644 --- a/app/lib/system/directory.js +++ b/app/lib/system/directory.js @@ -3,7 +3,7 @@ const co = require('co'); const opts = require('optimist').argv; const path = require('path'); -const cfs = require('../cfs'); +const CFSCore = require('../dal/fileDALs/CFSCore').CFSCore const Q = require('q'); const qfs = require('q-io/fs'); const fs = require('fs'); @@ -66,7 +66,7 @@ const dir = module.exports = { }), createHomeIfNotExists: (fileSystem, theHome) => co(function *() { - const fsHandler = cfs(theHome, fileSystem); + const fsHandler = new CFSCore(theHome, fileSystem); return fsHandler.makeTree(''); }) }; diff --git a/test/fast/cfs.js b/test/fast/cfs.js index daa55a40d78447d9720da492860d0a1533783a98..35944eb187c99e02e2123f7220e28632d23fe764 100644 --- a/test/fast/cfs.js +++ b/test/fast/cfs.js @@ -2,7 +2,7 @@ var assert = require('assert'); var co = require('co'); -var cfs = require('../../app/lib/cfs'); +var CFSCore = require('../../app/lib/dal/fileDALs/CFSCore').CFSCore; var mockFS = require('q-io/fs-mock')({ 'B5_a': { "A.json": '{ "text": "Content of A from B5_a" }' @@ -21,11 +21,11 @@ var mockFS = require('q-io/fs-mock')({ describe("CFS", () => { - var coreB3 = cfs('/B3', mockFS); - var coreB4 = cfs('/B4', mockFS, coreB3); - var coreB5 = cfs('/B5_a', mockFS, coreB4); + var coreB3 = new CFSCore('/B3', mockFS); + var coreB4 = new CFSCore('/B4', mockFS, coreB3); + var coreB5 = new CFSCore('/B5_a', mockFS, coreB4); - var rootCore = cfs('/OTHER', mockFS); + var rootCore = new CFSCore('/OTHER', mockFS); // ------------ Direct READ ------------