/**
* @module scripts
*/
const config = require('../config');
/**
* Utility to create reusable command line scripts.
*
* Extend this class to create a Node.js script using the BioPocket database
* that can be run either standalone or as part of another script.
*
* When running such a script from the command line, you basically want to go
* through these steps:
*
* * Open a connection to the database
* * Do the magic
* * Log success or failure
* * Close the connection to the database
* * Exit the process with an appropriate exit code
*
* But if you want to reuse that script in another "parent" script, you only
* want to run the "Do the magic" step, as the parent script will take care of
* the other steps.
*
* This is what this class allows with its `autoRun` function.
*
* @class
*/
class Script {
constructor() {
this.logger = config.logger('script');
}
/**
* Runs this script, performing the following actions:
*
* * Open a connection to the database.
* * Execute the `run` method.
* * Execute the `onSuccess` or `onFailure` callback depending on whether the
* `run` method was successful (throwing an error or returning a rejected
* promise will be considered a failure).
* * Close the connection to the database.
* * Exit the process with code 0 if the script was successful or 1 otherwise.
*
* If the `$NO_SCRIPT` environment variable is set, do not do anything. This
* allows this script to be reused by importing it and calling its `run`
* method manually, with the setup/teardown steps being handled by the parent
* script.
*
* @method
*/
autoRun() {
if (!process.env.NO_SCRIPT) {
Promise
.resolve()
.then(() => this.db.open())
.then(() => this.run())
.then(() => this.onSuccess())
.catch(err => this.onFailure(err))
.then(() => this.db.close(), () => this.db.close())
.then(() => this.exit());
}
}
/**
* Runs the script.
*
* This method should be overriden by subclasses to do the actual work.
*
* @method
*/
run() {
}
/**
* Called if the script succeeds.
*
* It logs an INFO message to the console by default.
*
* @method
*/
onSuccess() {
this.logger.info(`${this.constructor.name} successful`);
}
/**
* Called if the script fails.
*
* It logs a FATAL message to the console by default and sets the exit code of
* the script to 1 for when the `exit` method is called.
*
* @method
*/
onFailure(err) {
this.logger.fatal(err);
this.exitCode = 1;
}
/**
* Called when the script is done executing (successfully or not) and after
* closing the connection to the database.
*
* It exits the process with code 0, or with the value of the `exitCode`
* property (which is set to 1 by `onFailure`).
*
* @method
*/
exit() {
process.exit(this.exitCode || 0);
}
/**
* The application's database.
*/
get db() {
return require('../server/db');
}
}
module.exports = Script;