import { MongoClient, Db, Collection } from 'mongodb'; import { config } from '../lib/config'; /** * Database wrapper with collection access directly on the db object. */ export class Database { private MONGO_URI: string; private MONGO_DBNAME: string; constructor(opts: { MONGO_URI?: string, MONGO_DBNAME?: string } = {}) { this.MONGO_URI = opts.MONGO_URI || config.mongoUrl; this.MONGO_DBNAME = opts.MONGO_DBNAME || config.mongoDbName; } private __client: MongoClient | null = null; private __db: Db | null = null; protected static __collectionNames = [ 'docs', ]; docs: Collection; private __promiseConnect: Promise | null = null; get isReady(): boolean { return this.__db !== null; } private attach() { for (const c of Database.__collectionNames) { this[c] = this.__db!.collection(c); } } collection(name: string): Collection { return this.__db!.collection(name); } command(command: Object): Promise { return this.__db!.command(command); } listShards(): Promise { return this.__db!.admin().command({ listShards: 1 }); } database(dbName?: string): Db | null { if (!dbName) { return this.__db; } return (this.__client) ? this.__client.db(dbName) : null ; } connect(): Promise { if (!this.__promiseConnect) { this.__promiseConnect = MongoClient.connect(this.MONGO_URI, { useNewUrlParser: true, }).then((client) => { this.__client = client; this.__db = this.__client.db(this.MONGO_DBNAME); this.attach(); return true; }).catch((err) => { console.error("Connection error", err); process.exit(1); return false; }); } return this.__promiseConnect; } onConnect(handler: () => void) { this.connect().then(handler); } async close() { if (this.__client) { await this.__client.close(); } } } const db = new Database(); export default db;