As you all know, scriptDB, the handy little nosql database associated with each script, was deprecated some time ago. Most people will have already moved to an alternative. Some have moved to my database abstraction solution, which provides a noSQL layer to a selection of backend datastores and databases.
If you are like me (and I was a very heavy user of ScriptDB), you will still have a few projects around that are on ice because you didn't get round to converting them to something else. Looking through this web site, I found about 6 that I hadn't converted yet. It's fairly easy to move over to database abstraction, but where's the fun in that, when I could instead play around with creating a layer on top of db abstraction that looks just like the old scriptDB did. That way I don't have to do anything much to the old code - just add some libraries and pick a database platform.
So here it is - I'm calling it RipDB in honor of ScriptDB that has passed on to a better place. I've copied in the deprecated ScriptDB docs into this pages to preserve them for posterity in case they disappear sometime. Pretty much every method and property has been replicated as well as I could reverse engineer how I believe they used to work.
As a word of caution, I don't really recommend this approach for big data stores, but it's fine for all those small projects you didn't yet get round to converting. However, if you are using DriverScratch, DriverSheet, DriverDrive or even DriverProperties for small datastores (and that's all they are good for), you can wrap your entire script in a dbabstraction transaction (as long as you don't mind locking out other users for the duration) and it will all happen in memory and be super fast with automatic rollback. More about that later.
Regardless of the back end chosen you will automatically get the caching and locking built in to Database abstraction with google apps script
This is the only thing that really changes from your scriptDB code. Since we are using DB abstraction to fill in for ScriptDB, we just need to get a handler for our chosen database. As usual, for testing, I'm using DriverScratch to start with, as this avoids me having to clean up later.
Next we'll do the equivalent of the old ScriptDB.getMyDb(), which now looks like this
Of course we'll need to include the appropriate libraries - you'll need cDbAbstraction and whichever driver you choose. I'm taking cDriverScratch. You can find all the library dependencies listed here, or get all the source and info from github if you prefer. There's also a little test script here using a selection of backend platforms if you want to take a look at that.
And that's it. You can now use db as if it was a scriptDB class, but behind the scenes it will use Db abstraction along with whichever db platform you've chosen.
I've tried to religiously emulate the same classes, properties and methods as ScriptDB, but unfortunately it's no longer available to test against so let me know if things don't seem to work as before.
This is the ScriptDbMap that's returned from a save or load operation. Both methods are implemented as in the original below
Here's the test from the ScriptDb documentation, modified to use the dbAbstraction handler.
and the result
This is equivalent to the ScriptDbInstance class and all these methods are implemented - substituting my version for the returned objects
var db = new cRipDB.RipDB(handler);
Queries work the same way as with ScriptDB. A query returns a RipDbResult which is a simulation of a ScriptDbResult. In fact, just like ScriptDb, the query is not actually executed behind the scenes until the results are retrieved. This allows you to continue to add constraints to the the query in multiple operations.
These are simulations of a ScriptDbResult and are returned by a query. In fact, they really are the unexecuted query parameters which have been built up. Issuing a hasNext(), a next() or a getSize() all cause the query to be finally executed automatically. All of these methods have been implemented, with the exception of numeric sorting - which is not available on many of the backend abstracted platforms.
The Numeric parameter will be accepted, but ignored and lexical sorting will be done instead.
You can combine these - for example.
All of the constraints available in the RipDb class are implemented. Here's an example.
and of combined constraints
Count takes the same syntax as a query, but is executed right away, returning the integer count of matches
A couple of the batch methods return an array of MutationResults - essentially an array corresponding in length to the input array with a method to test if it worked. I've emulated this, but the results will be all false or all true. DbAbstraction doesn't have the concept of a partially successful operation - it's either all successful or all failed. It looks like this and you can use it the same way as the ScriptDB MutationResult class.
Since RipDb uses DbAbstraction behind the scenes, you can can mix dbAbstraction syntax with RipDb syntax -- for example - a common debug pattern like this:
can be achieved more simply and with more information by using the handler directly natively..
To avoid carrying around references to both the handler and the db, you can get the handler a db is using in order to be able to use it directly, like this.
As I mentioned previously, certain backends benefit from being part of the same transaction because everything happens in memory. To do that the pattern looks like this.
And of course, since the underlying platform is whatever you choose it to be the the data is available outside apps script or by interacting with DbAbstraction apps. Implementing this has been a lot of fun. I'd love your feedback on our G+ community.
Services > Desktop Liberation - the definitive resource for Google Apps Script and Microsoft Office automation > Database abstraction and Google Apps Script >