From 44448bd3f0f4fbe9fe056b74e964ca18c032eebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Michelet?= Date: Mon, 4 Feb 2019 19:21:46 +0100 Subject: [PATCH 1/5] Updated mongodb nodes : Merged IN and OUT nodes + every operation emits an output with the query result or an error object Discussed in https://discourse.nodered.org/t/mongodb-node-improvements/4442 --- storage/mongodb/66-mongodb.html | 164 +++++------- storage/mongodb/66-mongodb.js | 425 +++++++++++++++----------------- 2 files changed, 256 insertions(+), 333 deletions(-) diff --git a/storage/mongodb/66-mongodb.html b/storage/mongodb/66-mongodb.html index f3180d656..57da9c6cc 100644 --- a/storage/mongodb/66-mongodb.html +++ b/storage/mongodb/66-mongodb.html @@ -1,5 +1,4 @@ - - - - - - - - - - - + \ No newline at end of file diff --git a/storage/mongodb/66-mongodb.js b/storage/mongodb/66-mongodb.js index a8f66f35a..d301bef54 100644 --- a/storage/mongodb/66-mongodb.js +++ b/storage/mongodb/66-mongodb.js @@ -1,272 +1,237 @@ +module.exports = function (RED) { + 'use strict' + const mongo = require('mongodb') + const ObjectID = require('mongodb').ObjectID + const MongoClient = mongo.MongoClient -module.exports = function(RED) { - "use strict"; - var mongo = require('mongodb'); - var ObjectID = require('mongodb').ObjectID; - var MongoClient = mongo.MongoClient; + function MongoConfigNode(n) { + RED.nodes.createNode(this, n) + this.hostname = n.hostname + this.port = n.port + this.db = n.db + this.name = n.name - function MongoNode(n) { - RED.nodes.createNode(this,n); - this.hostname = n.hostname; - this.port = n.port; - this.db = n.db; - this.name = n.name; - var url = "mongodb://"; + var url = 'mongodb://' if (this.credentials && this.credentials.user && this.credentials.password) { - url += this.credentials.user+":"+this.credentials.password+"@"; + url += this.credentials.user + ':' + this.credentials.password + '@' } - url += this.hostname+":"+this.port+"/"+this.db; + url += this.hostname + ':' + this.port + '/' + this.db - this.url = url; + this.url = url } - RED.nodes.registerType("mongodb",MongoNode,{ + RED.nodes.registerType('mongodb-config', MongoConfigNode, { credentials: { - user: {type:"text"}, - password: {type: "password"} + user: { type: 'text' }, + password: { type: 'password' } } - }); + }) function ensureValidSelectorObject(selector) { if (selector != null && (typeof selector != 'object' || Buffer.isBuffer(selector))) { - return {}; + return {} } - return selector; + return selector } - function MongoOutNode(n) { - RED.nodes.createNode(this,n); - this.collection = n.collection; - this.mongodb = n.mongodb; + function MongoNode(n) { + RED.nodes.createNode(this, n) + this.collection = n.collection + this.mongodb = n.mongodb this.payonly = n.payonly || false; + this.operation = n.operation || 'find' + this.mongoConfig = RED.nodes.getNode(this.mongodb) + this.status({ fill: 'grey', shape: 'ring', text: RED._('mongodb.status.connecting') }) + var node = this + var noerror = true this.upsert = n.upsert || false; this.multi = n.multi || false; - this.operation = n.operation; - this.mongoConfig = RED.nodes.getNode(this.mongodb); - this.status({fill:"grey",shape:"ring",text:RED._("mongodbstatus.connecting")}); - var node = this; - var noerror = true; - var connectToDB = function() { - MongoClient.connect(node.mongoConfig.url, function(err, db) { - 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.clientDb = db; - noerror = true; - var coll; - if (node.collection) { - coll = db.collection(node.collection); - } - node.on("input",function(msg) { - if (!node.collection) { - if (msg.collection) { - coll = db.collection(msg.collection); - } - else { - node.error(RED._("mongodb.errors.nocollection"),msg); - return; - } + var connectToDB = function () { + MongoClient.connect( + node.mongoConfig.url, + function (err, db) { + if (err) { + node.status({ fill: 'red', shape: 'ring', text: RED._('mongodb.status.error') }) + if (noerror) { + node.error(err) } - delete msg._topic; - delete msg.collection; - if (node.operation === "store") { - if (node.payonly) { - if (typeof msg.payload !== "object") { - msg.payload = {"payload": msg.payload}; - } - if (msg.hasOwnProperty("_id") && !msg.payload.hasOwnProperty("_id")) { - msg.payload._id = msg._id; + noerror = false + node.tout = setTimeout(connectToDB, 10000) + } else { + node.status({ fill: 'green', shape: 'dot', text: RED._('mongodb.status.connected') }) + node.clientDb = db + noerror = true + var coll + if (node.collection) { + coll = db.collection(node.collection) + } + node.on('input', function (msg) { + if (!node.collection) { + if (msg.collection) { + coll = db.collection(msg.collection) + } else { + node.error(RED._('mongodb.errors.nocollection')) + return } - coll.save(msg.payload,function(err, item) { - if (err) { - node.error(err,msg); - } - }); + } else { + coll = db.collection(node.collection) } - else { - coll.save(msg,function(err, item) { - if (err) { - node.error(err,msg); - } - }); - } - } - else if (node.operation === "insert") { - if (node.payonly) { - if (typeof msg.payload !== "object") { - msg.payload = {"payload": msg.payload}; + 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 } - if (msg.hasOwnProperty("_id") && !msg.payload.hasOwnProperty("_id")) { - msg.payload._id = msg._id; + var skip = msg.skip + if (typeof skip === 'string' && !isNaN(skip)) { + skip = Number(skip) + } else if (typeof skip === 'undefined') { + skip = 0 } - coll.insert(msg.payload, function(err, item) { + + coll + .find(selector, 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,msg); + node.error(err) + } else { + msg.payload = count + node.send(msg) } - }); - } - else { - coll.insert(msg, function(err,item) { + }) + } else if (node.operation === 'aggregate') { + msg.payload = Array.isArray(msg.payload) ? msg.payload : [] + coll.aggregate(msg.payload, function (err, result) { if (err) { - node.error(err,msg); + node.error(err) + } else { + msg.payload = result + node.send(msg) } - }); - } - } - else if (node.operation === "update") { - if (typeof msg.payload !== "object") { - msg.payload = {"payload": msg.payload}; - } - var query = msg.query || {}; - var payload = msg.payload || {}; - var options = { - upsert: node.upsert, - multi: node.multi - }; - if (ObjectID.isValid(msg.query._id)) { - msg.query._id = new ObjectID(msg.query._id); - } - coll.update(query, payload, options, function(err, item) { - if (err) { - node.error(err,msg); - } - }); - } - else if (node.operation === "delete") { - coll.remove(msg.payload, function(err, items) { - if (err) { - node.error(err,msg); - } - }); - } - }); - } - }); - } - - if (node.mongoConfig) { connectToDB(); } - else { node.error(RED._("mongodb.errors.missingconfig")); } - - node.on("close", function() { - node.status({}); - if (node.tout) { clearTimeout(node.tout); } - if (node.clientDb) { node.clientDb.close(); } - }); - } - RED.nodes.registerType("mongodb out",MongoOutNode); - - - function MongoInNode(n) { - RED.nodes.createNode(this,n); - this.collection = n.collection; - this.mongodb = n.mongodb; - this.operation = n.operation || "find"; - this.mongoConfig = RED.nodes.getNode(this.mongodb); - this.status({fill:"grey",shape:"ring",text:RED._("mongodb.status.connecting")}); - var node = this; - var noerror = true; - - var connectToDB = function() { - MongoClient.connect(node.mongoConfig.url, function(err,db) { - 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.clientDb = 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; - } - - coll.find(selector,msg.projection).sort(msg.sort).limit(limit).skip(skip).toArray(function(err, items) { - if (err) { - node.error(err); + }) + } else if (node.operation === 'store') { + if (node.payonly) { + if (typeof msg.payload !== 'object') { + msg.payload = { payload: msg.payload } + } + if (msg.hasOwnProperty('_id') && !msg.payload.hasOwnProperty('_id')) { + msg.payload._id = msg._id + } + coll.save(msg.payload, function (err, item) { + if (err) { + node.error(err, msg) + } else { + msg.payload = item + node.send(msg) + } + }) } else { - msg.payload = items; - delete msg.projection; - delete msg.sort; - delete msg.limit; - delete msg.skip; - node.send(msg); + coll.save(msg, function (err, item) { + if (err) { + node.error(err, msg); + } + }); } - }); - } - else if (node.operation === "count") { - selector = ensureValidSelectorObject(msg.payload); - coll.count(selector, function(err, count) { - if (err) { - node.error(err); + } else if (node.operation === 'insert') { + if (node.payonly) { + if (typeof msg.payload !== 'object') { + msg.payload = { payload: msg.payload } + } + if (msg.hasOwnProperty('_id') && !msg.payload.hasOwnProperty('_id')) { + msg.payload._id = msg._id + } + coll.insert(msg.payload, function (err, item) { + if (err) { + node.error(err, msg) + } else { + msg.payload = item + node.send(msg) + } + }) } else { - msg.payload = count; - node.send(msg); + coll.insert(msg, function (err, item) { + if (err) { + node.error(err, msg); + } + }); } - }); - } - else if (node.operation === "aggregate") { - msg.payload = (Array.isArray(msg.payload)) ? msg.payload : []; - coll.aggregate(msg.payload, function(err, result) { - if (err) { - node.error(err); + } else if (node.operation === 'update') { + if (typeof msg.payload !== 'object') { + msg.payload = { payload: msg.payload } } - else { - msg.payload = result; - node.send(msg); + var query = msg.query || {} + var payload = msg.payload || {} + var options = { + upsert: node.upsert, + multi: node.multi } - }); - } - }); + if (ObjectID.isValid(msg.query._id)) { + msg.query._id = new ObjectID(msg.query._id) + } + coll.update(query, payload, options, function (err, item) { + if (err) { + node.error(err, msg) + } else { + msg.payload = item + node.send(msg) + } + }) + } else if (node.operation === 'delete') { + coll.remove(msg.payload, function (err, items) { + if (err) { + node.error(err, msg) + } else { + msg.payload = items + node.send(msg) + } + }) + } + }) + } } - }); + ) } - if (node.mongoConfig) { connectToDB(); } - else { node.error(RED._("mongodb.errors.missingconfig")); } + if (node.mongoConfig) { + connectToDB() + } else { + node.error(RED._('mongodb.errors.missingconfig')) + } - node.on("close", function() { - node.status({}); - if (node.tout) { clearTimeout(node.tout); } - if (node.clientDb) { node.clientDb.close(); } - }); + node.on('close', function () { + node.status({}) + if (node.tout) { + clearTimeout(node.tout) + } + if (node.clientDb) { + node.clientDb.close() + } + }) } - RED.nodes.registerType("mongodb in",MongoInNode); -} + RED.nodes.registerType('mongodb', MongoNode) +} \ No newline at end of file From 5a62f5b4d44dcd08c443741c897977dcf7536c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Michelet?= Date: Tue, 12 Feb 2019 16:29:58 +0100 Subject: [PATCH 2/5] Added missing operations to IN node --- storage/mongodb/66-mongodb.html | 131 ++++++--- storage/mongodb/66-mongodb.js | 482 +++++++++++++++++++------------- 2 files changed, 372 insertions(+), 241 deletions(-) diff --git a/storage/mongodb/66-mongodb.html b/storage/mongodb/66-mongodb.html index 57da9c6cc..3ddb44bf9 100644 --- a/storage/mongodb/66-mongodb.html +++ b/storage/mongodb/66-mongodb.html @@ -1,4 +1,4 @@ - - - + + + + + + + \ No newline at end of file + diff --git a/storage/mongodb/66-mongodb.js b/storage/mongodb/66-mongodb.js index 40108fcbb..433aa5091 100644 --- a/storage/mongodb/66-mongodb.js +++ b/storage/mongodb/66-mongodb.js @@ -7,7 +7,7 @@ module.exports = function(RED) { var MongoClient = mongo.MongoClient; function MongoNode(n) { - RED.nodes.createNode(this, n); + RED.nodes.createNode(this,n); this.hostname = n.hostname; this.port = n.port; this.db = n.db; @@ -46,10 +46,10 @@ module.exports = function(RED) { this.url = url; } - RED.nodes.registerType("mongodb", MongoNode, { + RED.nodes.registerType("mongodb",MongoNode,{ credentials: { - user: { type: "text" }, - password: { type: "password" } + user: {type:"text"}, + password: {type: "password"} } }); @@ -61,7 +61,7 @@ module.exports = function(RED) { } function MongoOutNode(n) { - RED.nodes.createNode(this, n); + RED.nodes.createNode(this,n); this.collection = n.collection; this.mongodb = n.mongodb; this.payonly = n.payonly || false; @@ -92,13 +92,13 @@ module.exports = function(RED) { if (node.collection) { coll = db.collection(node.collection); } - node.on("input", function (msg) { + node.on("input",function(msg) { if (!node.collection) { if (msg.collection) { coll = db.collection(msg.collection); } else { - node.error(RED._("mongodb.errors.nocollection"), msg); + node.error(RED._("mongodb.errors.nocollection"),msg); return; } } @@ -124,17 +124,17 @@ module.exports = function(RED) { if (node.mongoConfig) { connectToDB(); } else { node.error(RED._("mongodb.errors.missingconfig")); } - node.on("close", function () { + node.on("close", function() { node.status({}); if (node.tout) { clearTimeout(node.tout); } if (node.clientDb) { node.clientDb.close(); } }); } - RED.nodes.registerType("mongodb out", MongoOutNode); + RED.nodes.registerType("mongodb out",MongoOutNode); function MongoInNode(n) { - RED.nodes.createNode(this, n); + RED.nodes.createNode(this,n); this.collection = n.collection; this.mongodb = n.mongodb; this.payonly = n.payonly || false; @@ -142,7 +142,7 @@ module.exports = function(RED) { this.multi = n.multi || false; this.operation = n.operation || "find"; this.mongoConfig = RED.nodes.getNode(this.mongodb); - this.status({ fill: "grey", shape: "ring", text: RED._("mongodb.status.connecting") }); + this.status({fill:"grey",shape:"ring",text: RED._("mongodb.status.connecting")}); var node = this; var noerror = true; @@ -161,7 +161,7 @@ module.exports = function(RED) { var db = client.db(); noerror = true; var coll; - node.on("input", function (msg) { + node.on("input", function(msg) { if (!node.collection) { if (msg.collection) { coll = db.collection(msg.collection); @@ -194,7 +194,7 @@ module.exports = function(RED) { 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; @@ -207,7 +207,7 @@ module.exports = function(RED) { } else if (node.operation === "count") { selector = ensureValidSelectorObject(msg.payload); - coll.count(selector, function (err, count) { + coll.count(selector, function(err, count) { if (err) { node.error(err); } @@ -257,7 +257,7 @@ module.exports = function(RED) { if (node.mongoConfig) { connectToDB(); } else { node.error(RED._("mongodb.errors.missingconfig")); } - node.on("close", function () { + node.on("close", function() { node.status({}); if (node.tout) { clearTimeout(node.tout); } if (node.clientDb) { node.clientDb.close(); } From 81ff06cf88a3c7327ee1f2e43c7b83c1a0920609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Michelet?= Date: Sat, 2 Jan 2021 11:50:41 +0100 Subject: [PATCH 4/5] formatter issue --- storage/mongodb/66-mongodb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/mongodb/66-mongodb.js b/storage/mongodb/66-mongodb.js index 433aa5091..d753d3df7 100644 --- a/storage/mongodb/66-mongodb.js +++ b/storage/mongodb/66-mongodb.js @@ -76,7 +76,7 @@ module.exports = function(RED) { var connectToDB = function() { MongoClient.connect(node.mongoConfig.url, function(err, client) { if (err) { - node.status({ fill: "red", shape: "ring", text: RED._("mongodb.status.error") }); + node.status({fill:"red",shape:"ring",text:RED._("mongodb.status.error")}); if (noerror) { node.error(err); } noerror = false; node.tout = setTimeout(connectToDB, 10000); From d4af78f001adf97491e136c8a13613954e5ff416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Michelet?= Date: Sat, 2 Jan 2021 11:58:22 +0100 Subject: [PATCH 5/5] more formatting --- storage/mongodb/66-mongodb.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/mongodb/66-mongodb.js b/storage/mongodb/66-mongodb.js index d753d3df7..51867bd96 100644 --- a/storage/mongodb/66-mongodb.js +++ b/storage/mongodb/66-mongodb.js @@ -142,7 +142,7 @@ module.exports = function(RED) { this.multi = n.multi || false; this.operation = n.operation || "find"; this.mongoConfig = RED.nodes.getNode(this.mongodb); - this.status({fill:"grey",shape:"ring",text: RED._("mongodb.status.connecting")}); + this.status({fill:"grey",shape:"ring",text:RED._("mongodb.status.connecting")}); var node = this; var noerror = true; @@ -150,7 +150,7 @@ module.exports = function(RED) { 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") }); + node.status({fill:"red",shape:"ring",text:RED._("mongodb.status.error")}); if (noerror) { node.error(err); } noerror = false; node.tout = setTimeout(connectToDB, 10000);