diff --git a/README.md b/README.md index 4a430c1..fcbdeea 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,19 @@ msg.topic = 'SELECT * FROM `users` WHERE `name` = :name AND `age` > :age;'; msg.payload = { name: 'Adrien', age: 30 }; return msg; ``` +If you have multiple arguments, put them in an array of objects in the `payload` variable. +You will get the result in the `payload` output variable. + +Example: +```javascript +msg.topic = 'INSERT INTO `users` (`name`, `age`) VALUES( :name, :age) ;'; +msg.payload = [ + { name: 'Adrien', age: 30 }, + { name: 'Maria', age: 62 } +] +return msg; +``` > Avoid SQL injections!! > > Do not NEVER EVER put variables content in `topic` directly! @@ -54,4 +66,4 @@ You have to connect using TLS encryption. Simply check the box in this node conf You are probably using another node than `node-red-contrib-stackhero-mysql` and tryin to connect to a MySQL >= 8 server using "Caching SHA2 password" authentication method. -To resolve that issue, simply use this node `node-red-contrib-stackhero-mysql`. \ No newline at end of file +To resolve that issue, simply use this node `node-red-contrib-stackhero-mysql`. diff --git a/src/main.js b/src/main.js index bfb72f7..a33a505 100644 --- a/src/main.js +++ b/src/main.js @@ -91,7 +91,7 @@ module.exports = (RED) => { } ); - + function MysqlDBNodeIn(config) { RED.nodes.createNode(this, config); @@ -115,7 +115,9 @@ module.exports = (RED) => { else if (code === 'queryDone') { this.status({ fill: 'blue', shape: 'dot', text: 'query done' }); } - else { + else if (code === 'singleQueryDone') { + this.status({ fill: 'blue', shape: 'dot', text: 'single query done' }); + }{ this.status({}); } }; @@ -128,34 +130,102 @@ module.exports = (RED) => { return; } - const isAnObject = value => value === Object(value) && !Array.isArray(value); + const isAnObject = (value) => value === Object(value); if (msg.payload !== undefined && !isAnObject(msg.payload)) { - this.error('msg.payload should be an object containing the query arguments.'); + this.error( + "msg.payload should be an object or an array containing the query arguments." + ); return; } - - try { - const [ result ] = await this.serverConfig - .query( - msg.topic, - msg.payload - ); - this.setState('queryDone'); - msg.payload = result; - this.send(msg); - } - catch (error) { - this.error(error, msg); - this.setState('error', error.toString()); + if ((msg.payload != undefined )) + if( !Array.isArray(msg.payload)){ + try { + const [ result ] = await this.serverConfig + .query( + msg.topic, + msg.payload + ); + this.setState('singleQueryDone'); + msg.payload = result; + this.send(msg); + } + catch (error) { + this.error(error, msg); + this.setState('error', error.toString()); + } } + else + processArray(msg, this); + else{ + //this.error(error, "No payload passed"); + this.setState('error', "Error no payload"); + } }); - this.on('close', async () => { + this.on('close', async () => { this.serverConfig.removeAllListeners(); this.setState(); }); this.serverConfig.connect(); } + function processArray( msg,thisNode){ + let values = []; + values =msg.payload; + thisNode.serverConfig.pool.getConnection(function (err, connection) { + if (err) { + if(connection) + connection.rollback(function () { + connection.release(); + }); + return + } + connection.beginTransaction(function (err) { + let promisses = []; + msg.payload = values.forEach((value) => { + promisses.push( + new Promise(function (resolve, reject) { + connection.query( + msg.topic, + value, + + function (error, results, _fields) { + if (error) + reject( error) + else resolve(results); + } + ); + }) + ); + }); + Promise.all(promisses).then((results) => { + connection + .commit(function (error) { + if (error) { + connection.rollback(function () { + connection.release(); + //Failure + thisNode.error(error); + thisNode.setState("error", error.toString()); + }); + } else { + connection.commit(); + connection.release(); + msg.payload = results; + thisNode.setState("queryDone"); + thisNode.send(msg); + } + }) + + }).catch((error) => { + connection.rollback(function () { + connection.release(); + }); + thisNode.error(error); + thisNode.setState("error", error.toString()); + });; + }); + }); + } RED.nodes.registerType('Stackhero-MySQL', MysqlDBNodeIn); };