import { Integration, DatasourceFieldTypes, QueryTypes, } from "../definitions/datasource" import { IntegrationBase } from "./base/IntegrationBase" module MongoDBModule { const { MongoClient } = require("mongodb") interface MongoDBConfig { connectionString: string db: string } const SCHEMA: Integration = { docs: "https://github.com/mongodb/node-mongodb-native", friendlyName: "MongoDB", description: "MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.", datasource: { connectionString: { type: DatasourceFieldTypes.STRING, required: true, default: "mongodb://localhost:27017", }, db: { type: DatasourceFieldTypes.STRING, required: true, }, }, query: { create: { type: QueryTypes.JSON, }, read: { type: QueryTypes.JSON, }, update: { type: QueryTypes.JSON, }, delete: { type: QueryTypes.JSON, }, }, extra: { collection: { displayName: "Collection", type: DatasourceFieldTypes.STRING, required: true, }, actionTypes: { displayName: "Action Types", type: DatasourceFieldTypes.LIST, required: true, data: { read: ["find", "findOne", "findOneAndUpdate", "count", "distinct"], create: ["insertOne", "insertMany"], update: ["updateOne", "updateMany"], delete: ["deleteOne", "deleteMany"], }, }, }, } class MongoIntegration implements IntegrationBase { private config: MongoDBConfig private client: any constructor(config: MongoDBConfig) { this.config = config this.client = new MongoClient(config.connectionString) } async connect() { return this.client.connect() } async create(query: { json: object; extra: { [key: string]: string } }) { try { await this.connect() const db = this.client.db(this.config.db) const collection = db.collection(query.extra.collection) // For mongodb we add an extra actionType to specify // which method we want to call on the collection switch (query.extra.actionTypes) { case "insertOne": { return await collection.insertOne(query.json) } case "insertMany": { return await collection.insertOne(query.json).toArray() } default: { throw new Error( `actionType ${query.extra.actionTypes} does not exist on DB for create` ) } } } catch (err) { console.error("Error writing to mongodb", err) throw err } finally { await this.client.close() } } async read(query: { json: object; extra: { [key: string]: string } }) { try { await this.connect() const db = this.client.db(this.config.db) const collection = db.collection(query.extra.collection) switch (query.extra.actionTypes) { case "find": { return await collection.find(query.json).toArray() } case "findOne": { return await collection.findOne(query.json) } case "findOneAndUpdate": { return await collection.findOneAndUpdate(query.json) } case "count": { return await collection.countDocuments(query.json) } case "distinct": { return await collection.distinct(query.json) } default: { throw new Error( `actionType ${query.extra.actionTypes} does not exist on DB for read` ) } } } catch (err) { console.error("Error querying mongodb", err) throw err } finally { await this.client.close() } } async update(query: { json: object; extra: { [key: string]: string } }) { try { await this.connect() const db = this.client.db(this.config.db) const collection = db.collection(query.extra.collection) switch (query.extra.actionTypes) { case "updateOne": { return await collection.updateOne(query.json) } case "updateMany": { return await collection.updateMany(query.json).toArray() } default: { throw new Error( `actionType ${query.extra.actionTypes} does not exist on DB for update` ) } } } catch (err) { console.error("Error writing to mongodb", err) throw err } finally { await this.client.close() } } async delete(query: { json: object; extra: { [key: string]: string } }) { try { await this.connect() const db = this.client.db(this.config.db) const collection = db.collection(query.extra.collection) switch (query.extra.actionTypes) { case "deleteOne": { return await collection.deleteOne(query.json) } case "deleteMany": { return await collection.deleteMany(query.json).toArray() } default: { throw new Error( `actionType ${query.extra.actionTypes} does not exist on DB for delete` ) } } } catch (err) { console.error("Error writing to mongodb", err) throw err } finally { await this.client.close() } } } module.exports = { schema: SCHEMA, integration: MongoIntegration, } }