Newer
Older
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var logger = require('./logging.js').logger;
Lloyd Hilaiel
committed
const config = require('./configuration.js');
Lloyd Hilaiel
committed
Lloyd Hilaiel
committed
var driver;
Lloyd Hilaiel
committed
var ready = false;
var waiting = [];
function checkReady() {
if (!ready) throw "database not ready. did you call open()?";
}
Lloyd Hilaiel
committed
// async break allow database path to be configured by calling code
Lloyd Hilaiel
committed
// a touch tricky cause client must set dbPath before releasing
Lloyd Hilaiel
committed
// control of the runloop
exports.open = function(cfg, cb) {
Lloyd Hilaiel
committed
if (cfg && cfg.driver) driverName = cfg.driver;
try {
driver = require('./db/' + driverName + '.js');
Lloyd Hilaiel
committed
} catch(e) {
var msg = "FATAL: couldn't find database driver: " + driverName;
console.log(msg);
throw msg + ": " + e.toString();
}
driver.open(cfg, function(error) {
Lloyd Hilaiel
committed
if (error) {
Lloyd Hilaiel
committed
if (cb) cb(error);
else {
Lloyd Hilaiel
committed
logger.error(error);
Lloyd Hilaiel
committed
process.exit(1);
}
} else {
ready = true;
waiting.forEach(function(f) { f() });
waiting = [];
if (cb) cb(null);
Lloyd Hilaiel
committed
}
});
};
Lloyd Hilaiel
committed
exports.close = function(cb) {
Lloyd Hilaiel
committed
checkReady();
Lloyd Hilaiel
committed
driver.close(function(err) {
ready = false;
Lloyd Hilaiel
committed
if (cb) cb(err);
});
};
Lloyd Hilaiel
committed
exports.closeAndRemove = function(cb) {
checkReady();
driver.closeAndRemove(function(err) {
ready = false;
if (cb) cb(err);
});
};
// accepts a function that will be invoked once the database is ready for transactions.
// this hook is important to pause the rest of application startup until async database
// connection establishment is complete.
Lloyd Hilaiel
committed
exports.onReady = function(f) {
setTimeout(function() {
if (ready) f();
else waiting.push(f);
}, 0);
};
Lloyd Hilaiel
committed
// these are read only database calls
Lloyd Hilaiel
committed
[
Lloyd Hilaiel
committed
'authForVerificationSecret',
'checkAuth',
'emailForVerificationSecret',
Lloyd Hilaiel
committed
'emailKnown',
Lloyd Hilaiel
committed
'emailToUID',
'emailType',
'emailIsVerified',
Lloyd Hilaiel
committed
'emailsBelongToSameAccount',
'lastPasswordReset',
Lloyd Hilaiel
committed
'haveVerificationSecret',
Lloyd Hilaiel
committed
'isStaged',
Lloyd Hilaiel
committed
'lastStaged',
Lloyd Hilaiel
committed
'listEmails',
Lloyd Hilaiel
committed
'userKnown',
Lloyd Hilaiel
committed
'userOwnsEmail',
Lloyd Hilaiel
committed
'verificationSecretForEmail'
Lloyd Hilaiel
committed
].forEach(function(fn) {
exports[fn] = function() {
checkReady();
driver[fn].apply(undefined, arguments);
};
});
// These are database calls that write. Database
// writing must be enabled on the process for them
// to work.
[
'stageUser',
'stageEmail',
Lloyd Hilaiel
committed
'completeCreateUser',
Lloyd Hilaiel
committed
'completeConfirmEmail',
Lloyd Hilaiel
committed
'completePasswordReset',
Lloyd Hilaiel
committed
'removeEmail',
Lloyd Hilaiel
committed
'cancelAccount',
Lloyd Hilaiel
committed
'updatePassword',
'createUserWithPrimaryEmail',
'addPrimaryEmailToAccount'
Lloyd Hilaiel
committed
].forEach(function(fn) {
exports[fn] = function() {
Lloyd Hilaiel
committed
if (!config.get('database').may_write) {
throw "this process may not write the database"
}
Lloyd Hilaiel
committed
checkReady();
driver[fn].apply(undefined, arguments);
};
Lloyd Hilaiel
committed
});
Lloyd Hilaiel
committed
exports.addTestUser = function() {
// would we like to check the environment here?
checkReady();
driver['addTestUser'].apply(undefined, arguments);