I am supporting CandidateX

CandidateX is a startup that focuses on creating inclusion-focused hiring solutions, designed to increase access to job opportunities for underestimated talent. Check them out if you have a few minutes to spare. They need visibility!

The DataHandler supports a host of backends. One of the problems with all the drivers being in that handler library is that when you create an app with say, a backend of sheets, it’s going to ask for a bunch of authorization to access a whole bunch of other services. For example, Fusion tables and so on – which can be confusing for the user. This library provides an alternative approach where the driver library is passed to the abstraction handler. This way, authorization is only sought for the specific driver(s) being used.

To use this method, you will need cDbAbstraction library (MHfCjPQlweartW45xYs6hFai_d-phDA33) along with the library reference of the driver(s) you want to use.

Remember that you do not need the DataHandler library with this method. Instead, you use its underlying cDbAbstraction library, plus only the specific driver libraries of your choice.

Getting a handler

Getting a handler is very straightforward.
  var handler = new cDbAbstraction.DbAbstraction ( driverLibraryReference , options) ;

Thereafter, the parameters are similar to those in DataHandler. Here’s an example of getting a sheet handler, where I’ve included a reference to DriverSheet and DriverDbAbstraction in my script.      var handler = new cDbAbstraction.DbAbstraction ( cDriverSheet, {        siloid: 'polymerdbab',                                dbid:'13ccFPXI0L8-ZViHlv8qoVspotUcnX8v0ZFeY4nUP574'      }); Note that the property names are all lower case – this is to align with the parameters in the DataHandler REST API 


By default caching is applied to all backends. If you are using a shared library, then the default cache is specific to the user of the library (the key is also encrypted). To change that behavior you can do any of these. 

  • pass a cache of your choice to the constructor (see Database caching for more info).
  • set the private parameter to false in order to use a public cache
  • use a cache community key in order to restrict any of these caches to a particular group of users.

 The example below restricts the cache scope to a specific user, using the cache belonging to the calling script (not the library).  var userStore = PropertiesService.getScriptProperties();/
  var creds = JSON.parse(userStore.getProperty('parseKeys'));
  var handler = new cDbAbstraction.DbAbstraction ( cDriverParse,  {
    "siloid": "polymerdbab",
    "dbid": creds.applicationID,
    "driverob": creds,
    "specificcache": CacheService.getUserCache()
  assert(handler.isHappy(), 'unable to get parse handler','handler'); 

This example could be used for public data where you want to leverage caching amongst all library users

  var handler = new cDbAbstraction.DbAbstraction ( cDriverParse,  {
    "siloid": "polymerdbab",
    "dbid": creds.applicationID,
    "driverob": creds,
    "private": false

This example could be used for community data where you want to leverage caching amongst a group of users who all know a hard to guess key – this is called a cache community key. Although we are using a public cache, the encrypted keys will be salted and only findable by handlers with the same community

 cache key 

    var handler = new cDbAbstraction.DbAbstraction ( cDriverParse, {
       "siloid": "polymerdbab",
       "dbid": creds.applicationID,
       "driverob": creds,
       "private": false,       "cachecommunity":"somehardtoguesscommunitykey"

Invalidating cache

Query results are cached against a hashed/encrypted version of the query. Being able to know if a cache entry is fresh is achieved as follows, and is completely automatic

  • When a query result is committed to cache, it is timestamped
  • When any update type operation is done to a silo/dbid combination, another cache entry with a longer expiry is written to cache.
  • Queries will first refer to cache before they go to the database backend. If a cache match is found, its timestamp is checked against the last update timestamp for this table. If the update is more recent, then the cache for that query is invalidated and the query is performed on the database.


The DataHandler class actually uses the DbAbstraction class. The only convenience it offers is that it already knows about all the supported libraries – the down side being that the calling program needs to authorize access to potentially unneeded libraries. The recommended approach is to use DbAbstraction. Here’ s how the data handler passes through its parameters to get a handle. Note that only a subset of the DbAbstraction options are supported by the DataHandler.          return new cDbAbstraction.DbAbstraction ( libraryReference , {            siloid: tableName,            expiry:optExpiry,            dbid:optDriverSpecific,                       driverob:optDriverOb,            disablecache:optDisableCache,            optout:optOptOut,            accesstoken:optAccessToken,            peanut:optPeanut,            randomsilo:optRandomSilo           });    

The code

is here

See  Database abstraction with google apps script for more on this.