If you are abstracting the database provider, you can move up caching to the handler level. This will mean that we can use Google CacheService to cache queries before we even worry about which flavor of database we are using. In fact, I usually find that I add caching later as an afterthought, but implementing it up front makes everything a lot more straightforward to test.
var cacheHandler = new CacheHandler.CacheHandler(expiry,cacheSilo,false,false,CacheService.getUserCache(),"somecachecommunitykey");
Creating a key
Example
/**
* DataHandler.getObjectsByQuery()
* @param {object} queryOb some query object
* @param {object} queryParams additional query parameters (if available)
* @param {boolean} noCache whether to use cache
* @return {object} results from selected handler
**/
self.getObjectsByQuery = function (queryOb,queryParams,noCache) {
var cached;
if (!noCache) {
cached = cacheHandler.getCache(queryOb,queryParams);
}
if (cached) {
return self.makeResults(enums.CODE.CACHE,undefined,cached);
}
else {
var result = driver.getObjectsByQuery(queryOb,queryParams,noCache);
cacheHandler.putCache (result.dataResult,queryOb,queryParams);
return result;
}
};
var cacheHandler = new cCacheHandler.CacheHandler(enums.SETTINGS.CACHEEXPIRY,siloId+type.toString()+driverSpecific.toString(),false);
Here is the full code of the cache Handler
cCacheHandler created by GitJsonApi
https://github.com/brucemcpherson/cCacheHandler
0 forks.
1 stars.
0 open issues.
Recent commits:
- Update dependencies.md, GitHub
- Update README.md, GitHub
- updated by GasGit automation, Bruce McPherson
- updated by GasGit automation, Bruce McPherson
- updated by GasGit automation, Bruce McPherson
Walkthrough
/**
* cCacheHandler.generateCacheKey()
* @param {object,..} queryOb some objects.
* @return {string} some one way encrypted version of text
**/
self.generateCacheKey = function () {
var s = siloId;
for (var i = 0; i < arguments.length; i++) {
if(arguments[i]) {
s+= ((typeof arguments[i] === "object" ) ? JSON.stringify(arguments[i]) : arguments[i].toString()) + i.toString();
}
}
return Utilities.base64Encode( Utilities.computeDigest( Utilities.DigestAlgorithm.MD2, s));
}
var s = siloId;
for (var i = 0; i < arguments.length; i++) {
if(arguments[i]) {
s+= ((typeof arguments[i] === "object" ) ? JSON.stringify(arguments[i]) : arguments[i].toString()) + i.toString();
}
}
return Utilities.base64Encode( Utilities.computeDigest( Utilities.DigestAlgorithm.MD2, s));
getCache
/**
* cCacheHandler.getCache()
* @param {object,..} queryOb some objects/text from which to generate a key.
* @return {object} the object
**/
self.getCache = function (ob) {
// this is how i can pass on the variable number of args
var s = self.generateCacheKey.apply (null, Array.prototype.slice.call(arguments));
var o = cache.get (s);
return o ? JSON.parse(o) : null;
}
putCache()
* cCacheHandler.putCache()
* @param {object} ob data to put to cache
* @param {object,..} queryOb some objects/text from which to generate a key.
* @return {string} some one way encrypted version of text
**/
self.putCache = function (ob) {
// this is how i can pass on the variable number of args, minus the first one
var a= Array.prototype.slice.call(arguments);
a.shift();
var s = self.generateCacheKey.apply (null, a);
cache.put ( s,JSON.stringify(ob),expiry);
return s;
}
removeCache()
You will want to be able to invalidate a cache (for example if you delete or insert something). As usual we are using .call() and .apply() to play around with the arguments so we can pass them on to get a cache key.
/**
* cCacheHandler.removeCache()
* @param {object,..} ob data to put to cache
* @param {object,..} queryOb some objects/text from which to generate a key.
* @return {void}
**/
self.removeCache = function () {
// this is how i can pass on the variable number of args
var s = self.generateCacheKey.apply (null, Array.prototype.slice.call(arguments));
cache.remove(s);
}