'use strict'; // @ts-ignore import * as schema from './templates/schema'; require('dotenv').config(); const MongoClient = require("mongodb/lib/mongo_client"); const MongoSchema = require('./extract-mongo-schema'); const jsonMerger = require("json-merger"); const mongoose = require('mongoose'); const autoBind = require( 'auto-bind' ); const process = require('process'); export default class MongoDBDatabaseDiscovery{ connectionString:string = null; constructor(MongoConfiguration) { if(!MongoConfiguration.USER.trim()) { this.connectionString = `mongodb://${MongoConfiguration.HOSTNAME}:${MongoConfiguration.PORT}`; } else { this.connectionString = `mongodb://${MongoConfiguration.USER}:${MongoConfiguration.PASSWORD}@${MongoConfiguration.HOSTNAME}:${MongoConfiguration.PORT}`; } autoBind( this ); } extractMongoDBSchema = async(dbName) => { //console.log(dbName) let extractedSchemas = {}; let schemaWithDatabaseNames = {}; let schemaWithDatabaseName = {}; let extractedSchema = await this.getExtractedSchema(dbName); schemaWithDatabaseName[dbName] = extractedSchema; //schemaWithDatabaseNames = jsonMerger.mergeObjects([schemaWithDatabaseNames, schemaWithDatabaseName]); //console.log(JSON.stringify(schemaWithDatabaseNames,null,4)); return (schemaWithDatabaseName); } //Get all database names getDatabases = async() => { const client = new MongoClient(this.connectionString, { useUnifiedTopology: true }); // useUnifiedTopology removes a warning return new Promise((resolve, reject) => { client.connect() .then(client => client.db().admin().listDatabases() // Returns a promise that will resolve to the list of databases ) .then(databases => { resolve(databases); }) .catch(error => { reject(error); }) .finally(() => client.close()); // Closing after getting the data }); } //Extracts the databasenames from the databases //refers to https://javascript.info/async-await getDatabaseNames = async (databases) => { let databaseNames = []; const result = await databases; for (var i = 0, len = result.databases.length; i < len; i++) { databaseNames.push(result.databases[i].name); //console.log(result.databases[i].name); } return databaseNames; } //Get the table names of from a specific database getExtractedSchema = async(dbName) => { let collectionList = null; let arrayList = null; const dontFollowFK = { __ANY__: {}, }; const outputFormat = 'json'; const includeSystem = null; const opts = { collectionList, arrayList, raw: null, limit: 10, dontFollowFK, }; let schema; let databaseEndpoint = this.connectionString + "/" + dbName + "?authSource=admin"; try { schema = await MongoSchema.extract(databaseEndpoint, opts); //console.log("Database: " + databaseEndpoint); //console.log(schema); //console.log(); } catch (error) { console.log(error); } finally {} return schema; } extractCustomer = async (MongoConfiguration, documentName, collectionName, columnNames) => { let connectionString=''; if(!MongoConfiguration.USER.trim()) { connectionString = `mongodb://${MongoConfiguration.HOSTNAME}:${MongoConfiguration.PORT}/${documentName}`; } else { connectionString = `mongodb://${MongoConfiguration.USER}:${MongoConfiguration.PASSWORD}@${MongoConfiguration.HOSTNAME}:${MongoConfiguration.PORT}/${documentName}?authSource=admin`; } //let connectionString = `mongodb://${MongoConfiguration.HOSTNAME}:${MongoConfiguration.PORT}/${documentName}`; await mongoose.connect(connectionString, {useNewUrlParser: true, useUnifiedTopology: true}); //console.log(connectionString); const db = mongoose.connection; const Schema = mongoose.Schema; //const ObjectId = Schema.ObjectId; const customerSchema = new Schema( //{ ProfileID: String }, {}, {collection: collectionName }, ); //https://stackoverflow.com/questions/19051041/cannot-overwrite-model-once-compiled-mongoose mongoose.models = {} const customer = mongoose.model('Customer', customerSchema); //check for whether the collection exists for(let column of columnNames) { let res = await this.checkCollectionExist(customer,column) ; if(!res) { console.log(column + " collection is not found"); process.exit(0); } } const result = await customer.find({},columnNames).select(columnNames); //console.log(JSON.stringify(result,null,3)); db.close(); return(result); } checkCollectionExist = async(customer, column) => { let result = await customer.findOne().exists(column,true); //console.log(result); if(!result) { return false; } return true; } } /**************** Main Entry Point ******************************************/ //Undo Comment to allow running from this file const MongoConfiguration = { HOSTNAME : 'localhost', PORT : '27017', ADMIN : 'admin', USER : '', PASSWORD : '', DATABASE : "Job_Network" }; /* let mongoDBDatabaseDiscovery = new MongoDBDatabaseDiscovery(MongoConfiguration); (async () => { //const databaseNames = await mongoDBDatabaseDiscovery.getDatabaseNames(databases); //console.log(databaseNames); const databaseName = 'Job_Network'; let extractedSchema = await mongoDBDatabaseDiscovery.getExtractedSchema(databaseName); extractedSchema = schema.insertTemplateToSchema(extractedSchema); //console.log(extractedSchema); // const extractedCustomers = await mongoDBDatabaseDiscovery // .extractCustomer(MongoConfiguration, 'Job_Network', 'profiles','_id') // //console.log(extractedCustomers) // for(let extractedCustomer of extractedCustomers) { // console.log(extractedCustomer['_id']); // } })(); */