lib/MongoManager.ts (111 lines of code) (raw):
import { URL } from 'url';
import { MongoClient, MongoError } from 'mongodb';
import factory from '../lib/Factory';
import { Host } from './HostsManager';
import { Server, ServerJSON, ServerErrorJSON } from './Server';
import { DatabaseJSON } from './Database';
import { Collection, CollectionJSON } from './Collection';
import { Utils } from './Utils';
export type Servers = (ServerJSON | ServerErrorJSON)[]
export class MongoManager {
private _servers: {
[name: string]: Server | MongoError;
} = {};
private async connect(host: Host) {
const urlStr = host.path.startsWith('mongodb')
? host.path
: `mongodb://${host.path}`;
const url = new URL(urlStr);
let hostname = url.host || host.path;
if (this._servers[hostname] instanceof Server) {
// Already connected
return;
}
try {
const client = new MongoClient(urlStr);
await client.connect();
const server = new Server(hostname, client);
this._servers[hostname] = server;
console.info(`[${hostname}] Connected to ${hostname}`);
await this.checkAuth(hostname);
} catch (err) {
console.error(`Error while connecting to ${hostname}:`, err.code, err.message);
this._servers[hostname] = err;
}
}
private getServer(name: string) {
const server = this._servers[name] || this._servers[`${name}:27017`];
if (!server) {
throw new Error('Server does not exist');
}
return server;
}
private async checkAuth(name: string) {
const server = this.getServer(name);
if (server instanceof Error) {
return;
}
try {
await server.toJson();
} catch (err) {
console.log(require('util').inspect(err, false, 20));
if (err.code == 13 && err.codeName == "Unauthorized") {
this._servers[name] = err;
}
}
}
async load() {
let hosts = await factory.hostsManager.getHosts();
await Promise.all(hosts.map((h) => this.connect(h)));
}
removeServer(name: string) {
delete this._servers[name];
}
async getServersJson(): Promise<Servers> {
const servers: Servers = [];
for (const [name, server] of Object.entries(this._servers)) {
if (server instanceof Error) {
servers.push({
name: name,
error: {
code: server.code,
name: server.name,
message: server.message
}
});
} else {
const json = await server.toJson();
servers.push(json);
}
}
Utils.fieldSort(servers, "name");
return servers;
}
async getDatabasesJson(serverName: string): Promise<DatabaseJSON[]> {
const server = this.getServer(serverName);
if (server instanceof Error) {
return [];
}
const json = await server.toJson();
return json.databases;
}
async getCollectionsJson(serverName: string, databaseName: string): Promise<CollectionJSON[]> {
const server = this.getServer(serverName);
if (server instanceof Error) {
return [];
}
const database = await server.database(databaseName);
if (!database) {
return [];
}
const json = await database.toJson();
return json.collections;
}
async getCollection(serverName: string, databaseName: string, collectionName: string): Promise<Collection | undefined> {
const server = this.getServer(serverName);
if (server instanceof Error) { return; }
const database = await server.database(databaseName);
if (!database) { return; }
const collection = await database.collection(collectionName);
return collection;
}
}