From 10a2aa610ebb24d4a29723c9c5b5252f1d02d39a Mon Sep 17 00:00:00 2001
From: man-of-fox <31039526+man-of-fox@users.noreply.github.com>
Date: Wed, 19 May 2021 14:48:36 +0200
Subject: [PATCH] dynamic database name
Feature: database name can be dynamicaly provided as string oder context variable on "mongo in" and "mongo out"
---
storage/mongodb/66-mongodb.html | 110 +++++++++++-
storage/mongodb/66-mongodb.js | 299 +++++++++++++++++++++++---------
storage/mongodb/package.json | 46 ++---
3 files changed, 350 insertions(+), 105 deletions(-)
diff --git a/storage/mongodb/66-mongodb.html b/storage/mongodb/66-mongodb.html
index b1201b1d..fb4f97d8 100644
--- a/storage/mongodb/66-mongodb.html
+++ b/storage/mongodb/66-mongodb.html
@@ -51,7 +51,7 @@
topology: {value: "direct", required: true},
connectOptions: {value: "", required: false},
port: {value: 27017, required: true},
- db: {value: "", required: true},
+ db: {value: "", required: false},
name: {value: ""}
},
credentials: {
@@ -74,11 +74,53 @@
});
+
+
+
+
+
+
+
diff --git a/storage/mongodb/66-mongodb.js b/storage/mongodb/66-mongodb.js
index 4b635193..ab2ed09a 100644
--- a/storage/mongodb/66-mongodb.js
+++ b/storage/mongodb/66-mongodb.js
@@ -18,6 +18,7 @@ module.exports = function(RED) {
//console.log(this);
var clustered = (this.topology !== "direct") || false;
+ var dyndb = (!this.db || this.db.length === 0) || false;
var url = "mongodb://";
if (this.topology === "dnscluster") {
@@ -34,9 +35,11 @@ module.exports = function(RED) {
url += this.user+":"+this.password+"@";
}
if (clustered) {
- url += this.hostname + "/" + this.db
+ url += this.hostname + "/";
+ if (!dyndb) url += this.db;
} else {
- url += this.hostname + ":" + this.port + "/" + this.db;
+ url += this.hostname + ":" + this.port + "/";
+ if (!dyndb) url += this.db;
}
if (this.connectOptions){
url += "?" + this.connectOptions;
@@ -63,6 +66,8 @@ module.exports = function(RED) {
function MongoOutNode(n) {
RED.nodes.createNode(this,n);
this.collection = n.collection;
+ this.dbname = n.dbname;
+ this.dbnameType = n.dbnameType;
this.mongodb = n.mongodb;
this.payonly = n.payonly || false;
this.upsert = n.upsert || false;
@@ -84,7 +89,20 @@ module.exports = function(RED) {
else {
node.status({fill:"green",shape:"dot",text:RED._("mongodb.status.connected")});
node.client = client;
- var db = client.db();
+ var db = null;
+ if (node.dbname && node.dbname.length > 0) {
+ if (node.dbnameType === 'msg' || node.dbnameType === 'flow' || node.dbnameType === 'global') {
+ var result_dbname = RED.util.evaluateNodeProperty(node.dbname);
+ node.log("use db " + result_dbname + " from " + node.dbnameType + "." + node.dbname);
+ db = client.db(result_dbname);
+ } else {
+ node.log("use db " + result_dbname + " from " + node.dbname);
+ db = client.db(node.dbname)
+ }
+ } else {
+ db = client.db()
+ }
+ node.log("active db " + db);
//console.log( db);
noerror = true;
var coll;
@@ -194,6 +212,8 @@ module.exports = function(RED) {
function MongoInNode(n) {
RED.nodes.createNode(this,n);
this.collection = n.collection;
+ this.dbname = n.dbname;
+ this.dbnameType = n.dbnameType;
this.mongodb = n.mongodb;
this.operation = n.operation || "find";
this.mongoConfig = RED.nodes.getNode(this.mongodb);
@@ -201,6 +221,125 @@ module.exports = function(RED) {
var node = this;
var noerror = true;
+ function getDbname(node,msg,done) {
+ if (node.dbnameType === 'str') {
+ done(node.dbname, msg);
+ } else {
+ RED.util.evaluateNodeProperty(node.dbname,node.dbnameType,node,msg,(err,value) => {
+ if (err) {
+ done(undefined,msg);
+ } else {
+ done(value,msg);
+ }
+ });
+ }
+ }
+
+ var connectToServer = function() {
+ console.log("connecting: " + node.mongoConfig.url);
+ MongoClient.connect(node.mongoConfig.url, function(err,client) {
+ if (err) {
+ node.status({fill:"red",shape:"ring",text:RED._("mongodb.status.error")});
+ if (noerror) { node.error(err); }
+ noerror = false;
+ node.tout = setTimeout(connectToDB, 10000);
+ }
+ else {
+ node.status({fill:"green",shape:"dot",text:RED._("mongodb.status.connected")});
+ node.client = client;
+ noerror = true;
+ var coll;
+ node.on("input", function(msg) {
+ getDbname(node, msg, function(result_dbname, msg) {
+ var db;
+ if (typeof(result_dbname) !== 'unundefined') {
+ node.log("use db " + result_dbname);
+ db = client.db(result_dbname);
+ } else {
+ node.log("use db from url " + node.mongoConfig.url);
+ db = client.db();
+ }
+ if (!node.collection) {
+ if (msg.collection) {
+ coll = db.collection(msg.collection);
+ }
+ else {
+ node.error(RED._("mongodb.errors.nocollection"));
+ return;
+ }
+ }
+ else {
+ coll = db.collection(node.collection);
+ }
+ var selector;
+ if (node.operation === "find") {
+ msg.projection = msg.projection || {};
+ selector = ensureValidSelectorObject(msg.payload);
+ var limit = msg.limit;
+ if (typeof limit === "string" && !isNaN(limit)) {
+ limit = Number(limit);
+ } else if (typeof limit === "undefined") {
+ limit = 0;
+ }
+ var skip = msg.skip;
+ if (typeof skip === "string" && !isNaN(skip)) {
+ skip = Number(skip);
+ } else if (typeof skip === "undefined") {
+ skip = 0;
+ }
+
+ coll.find(selector).project(msg.projection).sort(msg.sort).limit(limit).skip(skip).toArray(function(err, items) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ msg.payload = items;
+ delete msg.projection;
+ delete msg.sort;
+ delete msg.limit;
+ delete msg.skip;
+ node.send(msg);
+ }
+ });
+ }
+ else if (node.operation === "count") {
+ selector = ensureValidSelectorObject(msg.payload);
+ coll.count(selector, function(err, count) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ msg.payload = count;
+ node.send(msg);
+ }
+ });
+ }
+ else if (node.operation === "aggregate") {
+ msg.payload = (Array.isArray(msg.payload)) ? msg.payload : [];
+ coll.aggregate(msg.payload, function(err, cursor) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ cursor.toArray(function(cursorError, cursorDocs) {
+ //console.log(cursorDocs);
+ if (cursorError) {
+ node.error(cursorError);
+ }
+ else {
+ msg.payload = cursorDocs;
+ node.send(msg);
+ }
+ });
+ }
+ });
+ }
+ });
+ });
+ }
+ });
+ }
+
var connectToDB = function() {
console.log("connecting: " + node.mongoConfig.url);
MongoClient.connect(node.mongoConfig.url, function(err,client) {
@@ -213,85 +352,89 @@ module.exports = function(RED) {
else {
node.status({fill:"green",shape:"dot",text:RED._("mongodb.status.connected")});
node.client = client;
- var db = client.db();
noerror = true;
var coll;
node.on("input", function(msg) {
- if (!node.collection) {
- if (msg.collection) {
- coll = db.collection(msg.collection);
- }
- else {
- node.error(RED._("mongodb.errors.nocollection"));
- return;
- }
- }
- else {
- coll = db.collection(node.collection);
- }
- var selector;
- if (node.operation === "find") {
- msg.projection = msg.projection || {};
- selector = ensureValidSelectorObject(msg.payload);
- var limit = msg.limit;
- if (typeof limit === "string" && !isNaN(limit)) {
- limit = Number(limit);
- } else if (typeof limit === "undefined") {
- limit = 0;
- }
- var skip = msg.skip;
- if (typeof skip === "string" && !isNaN(skip)) {
- skip = Number(skip);
- } else if (typeof skip === "undefined") {
- skip = 0;
- }
+ getDbname(node, msg, function(result_dbname, msg) {
+ var db;
+ if (typeof(result_dbname) !== 'unundefined') db = client.db(result_dbname);
+ else db = client.db();
+ if (!node.collection) {
+ if (msg.collection) {
+ coll = db.collection(msg.collection);
+ }
+ else {
+ node.error(RED._("mongodb.errors.nocollection"));
+ return;
+ }
+ }
+ else {
+ coll = db.collection(node.collection);
+ }
+ var selector;
+ if (node.operation === "find") {
+ msg.projection = msg.projection || {};
+ selector = ensureValidSelectorObject(msg.payload);
+ var limit = msg.limit;
+ if (typeof limit === "string" && !isNaN(limit)) {
+ limit = Number(limit);
+ } else if (typeof limit === "undefined") {
+ limit = 0;
+ }
+ var skip = msg.skip;
+ if (typeof skip === "string" && !isNaN(skip)) {
+ skip = Number(skip);
+ } else if (typeof skip === "undefined") {
+ skip = 0;
+ }
- coll.find(selector).project(msg.projection).sort(msg.sort).limit(limit).skip(skip).toArray(function(err, items) {
- if (err) {
- node.error(err);
- }
- else {
- msg.payload = items;
- delete msg.projection;
- delete msg.sort;
- delete msg.limit;
- delete msg.skip;
- node.send(msg);
- }
- });
- }
- else if (node.operation === "count") {
- selector = ensureValidSelectorObject(msg.payload);
- coll.count(selector, function(err, count) {
- if (err) {
- node.error(err);
- }
- else {
- msg.payload = count;
- node.send(msg);
- }
- });
- }
- else if (node.operation === "aggregate") {
- msg.payload = (Array.isArray(msg.payload)) ? msg.payload : [];
- coll.aggregate(msg.payload, function(err, cursor) {
- if (err) {
- node.error(err);
- }
- else {
- cursor.toArray(function(cursorError, cursorDocs) {
- //console.log(cursorDocs);
- if (cursorError) {
- node.error(cursorError);
- }
- else {
- msg.payload = cursorDocs;
- node.send(msg);
- }
- });
- }
- });
- }
+ coll.find(selector).project(msg.projection).sort(msg.sort).limit(limit).skip(skip).toArray(function(err, items) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ msg.payload = items;
+ delete msg.projection;
+ delete msg.sort;
+ delete msg.limit;
+ delete msg.skip;
+ node.send(msg);
+ }
+ });
+ }
+ else if (node.operation === "count") {
+ selector = ensureValidSelectorObject(msg.payload);
+ coll.count(selector, function(err, count) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ msg.payload = count;
+ node.send(msg);
+ }
+ });
+ }
+ else if (node.operation === "aggregate") {
+ msg.payload = (Array.isArray(msg.payload)) ? msg.payload : [];
+ coll.aggregate(msg.payload, function(err, cursor) {
+ if (err) {
+ node.error(err);
+ }
+ else {
+ cursor.toArray(function(cursorError, cursorDocs) {
+ //console.log(cursorDocs);
+ if (cursorError) {
+ node.error(cursorError);
+ }
+ else {
+ msg.payload = cursorDocs;
+ node.send(msg);
+ }
+ });
+ }
+ });
+ }
+ });
});
}
});
diff --git a/storage/mongodb/package.json b/storage/mongodb/package.json
index aaa8ee79..3c3775d4 100644
--- a/storage/mongodb/package.json
+++ b/storage/mongodb/package.json
@@ -1,27 +1,27 @@
{
- "name" : "node-red-node-mongodb",
- "version" : "0.2.5",
- "description" : "Node-RED nodes to talk to a Mongo database",
- "dependencies" : {
- "mongodb" : "^3.6.3"
- },
- "repository" : {
- "type":"git",
- "url":"https://github.com/node-red/node-red-nodes/tree/master/storage/mongodb"
- },
- "license": "Apache-2.0",
- "keywords": [ "node-red", "mongodb" ],
- "node-red" : {
- "nodes" : {
- "mongo": "66-mongodb.js"
- }
- },
- "author": {
- "name": "Dave Conway-Jones",
- "email": "ceejay@vnet.ibm.com",
- "url": "http://nodered.org"
- },
- "contributors": [
+ "name": "node-red-node-mongodb",
+ "version": "0.2.6",
+ "description": "Node-RED nodes to talk to a Mongo database",
+ "dependencies": {
+ "mongodb": "^3.6.3"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/tree/master/storage/mongodb"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "mongodb" ],
+ "node-red": {
+ "nodes": {
+ "mongo": "66-mongodb.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ },
+ "contributors": [
{
"name": "Ross Cruickshank",
"email": "ross@vnet.ibm.com"