From fef4f96e78c3b887a772d8a6e42fd947182b27cf Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 18 Dec 2019 23:51:45 +0530 Subject: [PATCH] fix: frappe.db.getCachedValue - CacheManager - Use db.getCachedValue in doc.getFrom --- backends/database.js | 36 +++++++++++++++++++++++++++++++++--- model/document.js | 16 ++-------------- utils/cacheManager.js | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 utils/cacheManager.js diff --git a/backends/database.js b/backends/database.js index 1db436ac..b3724098 100644 --- a/backends/database.js +++ b/backends/database.js @@ -1,5 +1,6 @@ const frappe = require('frappejs'); const Observable = require('frappejs/utils/observable'); +const CacheManager = require('frappejs/utils/cacheManager'); const Knex = require('knex'); module.exports = class Database extends Observable { @@ -7,6 +8,7 @@ module.exports = class Database extends Observable { super(); this.initTypeMap(); this.connectionParams = {}; + this.cache = new CacheManager(); } connect() { @@ -326,7 +328,16 @@ module.exports = class Database extends Observable { return this.knex(doctype) .where('name', doc.name) - .update(formattedDoc); + .update(formattedDoc) + .then(() => { + let cacheKey = `${doctype}:${doc.name}`; + if (this.cache.hexists(cacheKey)) { + for (let fieldname in formattedDoc) { + let value = formattedDoc[fieldname]; + this.cache.hset(cacheKey, fieldname, value); + } + } + }); } runDeleteOtherChildren(field, parent, added) { @@ -364,7 +375,10 @@ module.exports = class Database extends Observable { let baseDoctype = meta.getBaseDocType(); await this.knex(baseDoctype) .update({ name: newName }) - .where('name', oldName); + .where('name', oldName) + .then(() => { + this.clearValueCache(doctype, oldName); + }); await frappe.db.commit(); this.triggerChange(doctype, newName); @@ -447,7 +461,10 @@ module.exports = class Database extends Observable { async deleteOne(doctype, name) { return this.knex(doctype) .where('name', name) - .delete(); + .delete() + .then(() => { + this.clearValueCache(doctype, name); + }); } deleteChildren(parenttype, parent) { @@ -493,6 +510,14 @@ module.exports = class Database extends Observable { return this.updateOne(doctype, doc); } + async getCachedValue(doctype, name, fieldname) { + let value = this.cache.hget(`${doctype}:${name}`, fieldname); + if (value == null) { + value = await this.getValue(doctype, name, fieldname); + } + return value; + } + getAll({ doctype, fields, @@ -609,6 +634,11 @@ module.exports = class Database extends Observable { } } + clearValueCache(doctype, name) { + let cacheKey = `${doctype}:${name}`; + this.cache.hclear(cacheKey); + } + getColumnType(field) { return this.typeMap[field.fieldtype]; } diff --git a/model/document.js b/model/document.js index d68d479f..8378d0b4 100644 --- a/model/document.js +++ b/model/document.js @@ -10,12 +10,6 @@ module.exports = class BaseDocument extends Observable { this.flags = {}; this.setup(); this.setValues(data); - - // clear fetch-values cache - frappe.db.on( - 'change', - params => (this.fetchValuesCache[`${params.doctype}:${params.name}`] = {}) - ); } setup() { @@ -545,15 +539,9 @@ module.exports = class BaseDocument extends Observable { .reduce((a, b) => a + b, 0); } - async getFrom(doctype, name, fieldname) { + getFrom(doctype, name, fieldname) { if (!name) return ''; - let _values = - this.fetchValuesCache[`${doctype}:${name}`] || - (this.fetchValuesCache[`${doctype}:${name}`] = {}); - if (!_values[fieldname]) { - _values[fieldname] = await frappe.db.getValue(doctype, name, fieldname); - } - return _values[fieldname]; + return frappe.db.getCachedValue(doctype, name, fieldname); } isNew() { diff --git a/utils/cacheManager.js b/utils/cacheManager.js new file mode 100644 index 00000000..52e949b1 --- /dev/null +++ b/utils/cacheManager.js @@ -0,0 +1,41 @@ +class CacheManager { + constructor() { + this.keyValueCache = {}; + this.hashCache = {}; + } + + getValue(key) { + return this.keyValueCache[key]; + } + + setValue(key, value) { + this.keyValueCache[key] = value; + } + + clearValue(key) { + this.keyValueCache[key] = null; + } + + hget(hashName, key) { + return (this.hashCache[hashName] || {})[key]; + } + + hset(hashName, key, value) { + this.hashCache[hashName] = this.hashCache[hashName] || {}; + this.hashCache[hashName][key] = value; + } + + hclear(hashName, key) { + if (key) { + (this.hashCache[hashName] || {})[key] = null; + } else { + this.hashCache[hashName] = {}; + } + } + + hexists(hashName) { + return this.hashCache[hashName] != null; + } +} + +module.exports = CacheManager;