"use strict"; import { defaultsDeep } from "lodash"; import * as rethinkdb from "rethinkdbdash"; import { AppLogger, logger as defaultLogger } from "../utils/Logger"; import { AppError } from "../errors"; import { loadConfig } from "my-nconf"; export class RethinkDB { private logger: any; private cluster_conf: any; private r: rethinkdb; private health = false; private static _instance; static get Instance() { if (!this._instance) { let c = loadConfig(); this._instance = new RethinkDB(c.get("rethinkdb_cluster")); } return this._instance; } constructor(_cluster_conf, _logger = defaultLogger) { let my = this; my.logger = _logger; my.cluster_conf = defaultsDeep({}, _cluster_conf, { authKey: "", buffer: 2, max: 5, servers: [ { host: "localhost", port: 28016 } ], discovery: false, silent: true, pool: true, cursor: false }); my.r = new rethinkdb(my.cluster_conf); my.r.getPoolMaster().on("healthy", function(healthy) { if (my.health == healthy) return; //nothing to do if (healthy === true) { my.logger.info( "RethinkDB cluster online @:", my.cluster_conf.servers ); } else { my.logger.error( new AppError( "No queries can be run.", "RethinkDBConnectionError" ) ); my.logger.error(my.cluster_conf); } my.health = healthy; }); my.patchmyR(); return my.r; } private patchmyR() { let my = this; my.r.ensure_db_exist = db_name => my.ensure_db_exist(db_name); my.r.ensure_table_exist = (db_name, table_name, options?) => my.ensure_table_exist(db_name, table_name, options); my.r.ensure_dbTable_exist = ( db_name, table_name, options?: { dbCreateOptions; tableCreateOptions } ) => my.ensure_dbTable_exist(db_name, table_name, options); } private async ensure_dbTable_exist( db_name, table_name, options: { dbCreateOptions; tableCreateOptions } = { dbCreateOptions: undefined, //place holder tableCreateOptions: undefined } ) { let db_res = await this.ensure_db_exist(db_name); let tb_res = await this.ensure_table_exist( db_name, table_name, options.tableCreateOptions ); return [db_res, tb_res]; } //https://rethinkdb.com/api/javascript/table_create/ private async ensure_db_exist(db_name) { let my = this; return await my.r .dbList() .contains(db_name) .do(function(databaseExists) { //logger.debug(databaseExists); return my.r.branch( databaseExists, { dbs_created: 0 }, my.r.dbCreate(db_name) ); }) .run(); } private async ensure_table_exist(db_name, table_name, options?) { let my = this; return await my.r .db(db_name) .tableList() .contains(table_name) .do(function(tableExists) { return my.r.branch( tableExists, { tables_created: 0 }, my.r.db(db_name).tableCreate(table_name, options) ); }) .run(); } }