This section covers more complex applications of ScriptDB.
Storing dates
ScriptDB cannot store Date
objects directly; instead, you must store a
representation of the date and reconstruct it later. If you don't intend to
search based on dates, then you can store the numeric timestamp from the Date
object like this:
var date = new Date('1/1/2014');
var item = {
timestamp: date.getTime();
}
var record = db.save(item);
Then, to reconstitute the Date
:
var date = new Date(record.timestamp);
If you want to be able to query individual fields of the Date
object, you can
store it like so:
var date = new Date('1/1/2014');
var item = {
timestamp: date.getTime(); // To recreate the Date object later.
day: date.getDay(); // 0 is Sunday, 1 is Monday, etc.
date: date.getDate(); // Day of the month.
month: date.getMonth(); // 0 is January, 1 is February, etc.
year: date.getFullYear(); // Full 4-digit year.
// And so on.
}
var record = db.save(item);
Storing them that way would allow you to find all records where the date was a Monday, like so:
var mondayResults = db.query({day: 1});
Calling a library's database
If your script uses a library, you can write your code to call the library's ScriptDB instance instead of the current project's own instance. The following code shows how this is typically set up:
Library | Project that includes the library |
---|---|
function getDb() { return ScriptDb.getMyDb(); } |
function useLibraryDb() { var db = Library.getDb(); // Do stuff with the database. } |
Passing a database to a library
Alternately, you might want library code to use the current project's ScriptDB instance rather than the library own's instance. In this case, you can simply pass the current project's database to the library, like so:
Library | Project that includes the library |
---|---|
var db; // Global variable updated by setDb(). function setDb(externalDb) { db = externalDb; } function useDb() { // Do stuff with the database. } |
function passDbToLibrary() { var db = ScriptDb.getMyDb(); Library.setDb(db); } |
Simulating a table
Unlike some databases, ScriptDB does not provide multiple tables. Instead, you form logical subsets of your data.
To represent a distinct subset, use a unique key. For example, you could add
the key-value pair table: "employee"
to objects that represent employees.
There's nothing magical about the key name table
here; it's just a name
to demarcate your subsets.
For overlapping subsets (say, "people," some of whom are employees and some of
whom are customers), use a flag. For example, you might add the key-value
pairs table: "people", is_employee: true
to objects that represent employees.
Simulating transactions
ScriptDB doesn't have transactions in the normal relational database sense, but you can prevent concurrent access to the same ScriptDB instance using the Lock service, which was designed for this kind of use. For example, if you wanted to increment an object's count variable:
var id = 'ID_FOR_THE_OBJECT';
var lock = LockService.getPublicLock();
lock.waitLock(30000);
try {
var obj = db.load(id);
obj.count = obj.count + 1;
db.save(obj);
} finally { // Make sure the lock is released even if we blow up.
lock.releaseLock();
}
Syntax comparisons with SQL
Operation | SQL | ScriptDb |
---|---|---|
Insert |
INSERT INTO bar (a, b) VALUES (1, 'foo') |
db.save({table: 'bar', a: 1, b: 'foo'}) |
Update |
UPDATE bar SET a=5, b='baz' WHERE id='id' |
var item = db.load(id); item.a = 5; item.b = 'baz'; db.save(item); |
Delete |
DELETE FROM bar WHERE id='id' |
var item = db.load(id); db.remove(item); |
Lookup |
SELECT * FROM bar WHERE id = 'id'; |
db.load(id) |
Query |
SELECT * FROM bar WHERE a=1 AND foo='baz' |
db.query({table: 'bar', a: 1, foo: 'baz'}) |
Query |
SELECT * FROM bar WHERE foo IN('baz', 'qux') |
db.query({ table:'bar', foo: db.anyOf(['baz', 'qux']) }) |