-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathnode_helper.js
More file actions
96 lines (78 loc) · 3.25 KB
/
node_helper.js
File metadata and controls
96 lines (78 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* global module, require */
/* MagicMirror²
* Node Helper: MMM-MysqlQuery
* MIT Licensed.
*/
var NodeHelper = require("node_helper");
var mysql = require("mysql");
module.exports = NodeHelper.create({
debuglog: function(msg) {
//console.log("[DEBUG][MMM-MysqlQuery] " + msg);
},
socketNotificationReceived: function(notification, payload) {
var helper = this;
if (notification === "MYSQLQUERY") {
this.debuglog("Received " + JSON.stringify(payload, null, 2));
var con = mysql.createConnection(payload.connection);
con.connect(function(err) {
if (err) {
con.destroy();
throw err;
}
con.query(payload.query, function(err, result) {
helper.debuglog("Received from MySQL: " + JSON.stringify(result, null, 2));
if (err) {
con.destroy();
throw err;
}
var arrayForBrowser = helper.flattenResultSets(result);
helper.sendSocketNotification("MYSQLQUERY_RESULT", {
identifier: payload.identifier,
rows: arrayForBrowser
});
helper.debuglog("Sending result: " + JSON.stringify(arrayForBrowser, null, 2));
});
});
/*
* Annoying part of Socket.io used by MM core logic: it doesn't support promise chaining, so you
* can't put a promise on the completion of sendSocketNofication() above. You can't just call
* con.destroy() here, or the connection to the database will be closed *before* the data has been
* consumed and sent to the browser! So, we have a total HACK here: wait a few seconds for the
* data to presumably be sent, then close the connection. YES, this is a race condition. LOSE.
*/
setTimeout(
function(con) {
helper.debuglog("Destroying unneeded SQL connection");
con.destroy();
},
10000,
con
);
}
},
/*
* Special case: if we received more than one result back, combine them
* together and emit as a single result set. If there is a Summary returned
* at the end, strip it off (usually from a CALL invocation instead of a
* SELECT invocation).
*
* CALL emits an object that looks like this at the end of the results:
* { "fieldCount": 0, "affectedRows": 0, "insertId": 0, "serverStatus": 34, "warningCount": 1, "message": "",
* "protocol41": true, "changedRows": 0 }
*/
flattenResultSets: function(results) {
ret = []
for(var thing of results)
if (Array.isArray(thing))
ret = ret.concat(thing);
else if (! this.isSummaryObject(thing))
ret.push(thing);
return ret;
},
isSummaryObject: function(thing) {
return "fieldCount" in thing &&
"affectedRows" in thing &&
"insertId" in thing &&
"serverStatus" in thing; // close enough :-)
}
});