MeshCentral now works with both MariaDB and MySQL.

Ylian Saint-Hilaire committed Feb 3, 2020 at 18:58 UTC 31e0f5c726210d55c15d44dc11e65b6a6b589a94
2 files changed +139 -139
db.js
+137 -139
@@ -68,8 +68,8 @@ module.exports.CreateDB = function (parent, func) {
68 // TODO: Remove all meshes that dont have any links
69
70 // Remove all events, power events and SMBIOS data from the main collection. They are all in seperate collections now.
71 - if (obj.databaseType == 4) {
72 - // MariaDB
71 + if ((obj.databaseType == 4) || (obj.databaseType == 5)) {
72 + // MariaDB or MySQL
73 obj.RemoveAllOfType('event', function () { });
74 obj.RemoveAllOfType('power', function () { });
75 obj.RemoveAllOfType('smbios', function () { });
@@ -89,9 +89,9 @@ module.exports.CreateDB = function (parent, func) {
89 obj.GetAllType('mesh', function (err, docs) {
90 var meshlist = [];
91 if ((err == null) && (docs.length > 0)) { for (var i in docs) { meshlist.push(docs[i]._id); } }
92 - if (obj.databaseType == 4) {
92 + if ((obj.databaseType == 4) || (obj.databaseType == 5)) {
93 // MariaDB
94 - mariaDbQuery('DELETE FROM MeshCentral.Main WHERE (extra LIKE ("mesh/%") AND (extra NOT IN ?)', [meshlist], func);
94 + sqlDbQuery('DELETE FROM MeshCentral.Main WHERE (extra LIKE ("mesh/%") AND (extra NOT IN ?)', [meshlist], func);
95 } else if (obj.databaseType == 3) {
96 // MongoDB
97 obj.file.deleteMany({ meshid: { $exists: true, $nin: meshlist } }, { multi: true });
@@ -323,50 +323,20 @@ module.exports.CreateDB = function (parent, func) {
323 obj.dbRecordsDecryptKey = parent.crypto.createHash('sha384').update(parent.args.dbrecordsdecryptkey).digest("raw").slice(0, 32);
324 }
325
326 -/*
327 -CREATE DATABASE xmeshcentral;
328 -CREATE TABLE xmeshcentral.main(id VARCHAR(256) NOT NULL, type CHAR(32), domain CHAR(64), extra CHAR(255), extraex CHAR(255), doc JSON, PRIMARY KEY(id), CHECK(json_valid(doc)));
329 -CREATE INDEX ndxtypedomainextra ON xmeshcentral.main(type, domain, extra);
330 -CREATE INDEX ndxextra ON xmeshcentral.main(extra);
331 -CREATE INDEX ndxextraex ON xmeshcentral.main(extraex);
332 -
333 -CREATE TABLE xmeshcentral.events(id INT NOT NULL AUTO_INCREMENT, time DATETIME, domain CHAR(64), action CHAR(255), nodeid CHAR(255), userid CHAR(255), doc JSON, PRIMARY KEY(id), CHECK(json_valid(doc)));
334 -CREATE INDEX ndxeventstime ON xmeshcentral.events(time);
335 -CREATE INDEX ndxeventsusername ON xmeshcentral.events(domain, userid, time);
336 -CREATE INDEX ndxeventsdomainnodeidtime ON xmeshcentral.events(domain, nodeid, time);
337 -
338 -CREATE TABLE xmeshcentral.eventids(fkid INT NOT NULL, target CHAR(255), CONSTRAINT fk_eventid FOREIGN KEY (fkid) REFERENCES events (id) ON DELETE CASCADE ON UPDATE RESTRICT);
339 -CREATE INDEX ndxeventids ON xmeshcentral.eventids(target);
340 -
341 -CREATE TABLE xmeshcentral.serverstats(time DATETIME, expire DATETIME, doc JSON, PRIMARY KEY(time), CHECK(json_valid(doc)));
342 -CREATE INDEX ndxserverstattime ON xmeshcentral.serverstats(time);
343 -CREATE INDEX ndxserverstatexpire ON xmeshcentral.serverstats(expire);
344 -CREATE TABLE xmeshcentral.power(id INT NOT NULL AUTO_INCREMENT, time DATETIME, nodeid CHAR(255), doc JSON, PRIMARY KEY(id), CHECK(json_valid(doc)));
345 -CREATE INDEX ndxpowernodeidtime ON xmeshcentral.power(nodeid, time);
346 -CREATE TABLE xmeshcentral.smbios(id CHAR(255), time DATETIME, expire DATETIME, doc JSON, PRIMARY KEY(id), CHECK(json_valid(doc)));
347 -CREATE INDEX ndxsmbiostime ON xmeshcentral.smbios(time);
348 -CREATE INDEX ndxsmbiosexpire ON xmeshcentral.smbios(expire);
349 -CREATE TABLE xmeshcentral.plugin(id INT NOT NULL AUTO_INCREMENT, doc JSON, PRIMARY KEY(id), CHECK(json_valid(doc)));
350 -
351 -INSERT INTO xmeshcentral.events VALUE (null, null, '', 'tstaction', 'nodeid', 'userid', '{ "a":1, "b":2 }');
352 -INSERT INTO xmeshcentral.eventids VALUE (LAST_INSERT_ID(), 'target1');
353 -INSERT INTO xmeshcentral.eventids VALUE (LAST_INSERT_ID(), 'target2');
354 -
355 -show tables;
356 -select * from events;
357 -select * from eventids;
358 -
359 -SELECT doc FROM xmeshcentral.events JOIN eventids ON id = fkid WHERE target IN ("target3") GROUP BY id;
360 -*/
361 -
362 - if (parent.args.mariadb) {
363 - // Use MariaDB
364 - obj.databaseType = 4;
365 - Datastore = require('mariadb').createPool(parent.args.mariadb);
366 - //mariaDbQuery('DROP DATABASE MeshCentral', null, function (err, docs) { console.log('DROP'); }); return;
367 - mariaDbQuery('USE meshcentral', null, function (err, docs) {
368 - if (err == null) { setupFunctions(func); } else
369 - mariaDbBatchExec([
326 + if (parent.args.mariadb || parent.args.mysql) {
327 + if (parent.args.mariadb) {
328 + // Use MariaDB
329 + obj.databaseType = 4;
330 + Datastore = require('mariadb').createPool(parent.args.mariadb);
331 + } else if (parent.args.mysql) {
332 + // Use MySQL
333 + Datastore = require('mysql').createConnection(parent.args.mysql);
334 + obj.databaseType = 5;
335 + }
336 + //sqlDbQuery('DROP DATABASE MeshCentral', null, function (err, docs) { console.log('DROP'); }); return;
337 + sqlDbQuery('USE meshcentral', null, function (err, docs) {
338 + if (err == null) { setupFunctions(func); } else {
339 + sqlDbBatchExec([
340 'CREATE DATABASE meshcentral',
341 // Main table
342 'CREATE TABLE meshcentral.main (id VARCHAR(256) NOT NULL, type CHAR(32), domain CHAR(64), extra CHAR(255), extraex CHAR(255), doc JSON, PRIMARY KEY(id), CHECK (json_valid(doc)))',
@@ -394,7 +364,8 @@ SELECT doc FROM xmeshcentral.events JOIN eventids ON id = fkid WHERE target IN (
364 'CREATE INDEX ndxsmbiosexpire ON meshcentral.smbios (expire)',
365 // Plugins table
366 'CREATE TABLE meshcentral.plugin (id INT NOT NULL AUTO_INCREMENT, doc JSON, PRIMARY KEY(id), CHECK (json_valid(doc)))'
397 - ], function (err) { if (err != null) { console.log(err); } setupFunctions(func); });
367 + ], function (err) { /*if (err != null) { console.log(err); }*/ setupFunctions(func); });
368 + }
369 });
370 } else if (parent.args.mongodb) {
371 // Use MongoDB
@@ -735,138 +706,165 @@ SELECT doc FROM xmeshcentral.events JOIN eventids ON id = fkid WHERE target IN (
706 }
707
708 // Query the database
738 - function mariaDbQuery(query, args, func) {
739 - Datastore.getConnection()
740 - .then(function (conn) {
741 - conn.query(query, args)
742 - .then(function (rows) {
743 - conn.release();
744 - const docs = [];
745 - for (var i in rows) { if (rows[i].doc) { docs.push(performTypedRecordDecrypt(JSON.parse(rows[i].doc))); } }
746 - if (func) try { func(null, docs); } catch (ex) { console.log(ex); }
747 - })
748 - .catch(function (err) { conn.release(); if (func) try { console.log(err); func(err); } catch (ex) { console.log(ex); } });
749 - }).catch(function (err) { if (func) { try { console.log(err); func(err); } catch (ex) { console.log(ex); } } });
709 + function sqlDbQuery(query, args, func) {
710 + if (obj.databaseType == 4) { // MariaDB
711 + Datastore.getConnection()
712 + .then(function (conn) {
713 + conn.query(query, args)
714 + .then(function (rows) {
715 + conn.release();
716 + const docs = [];
717 + for (var i in rows) { if (rows[i].doc) { docs.push(performTypedRecordDecrypt(JSON.parse(rows[i].doc))); } }
718 + if (func) try { func(null, docs); } catch (ex) { console.log(ex); }
719 + })
720 + .catch(function (err) { conn.release(); if (func) try { func(err); } catch (ex) { console.log(ex); } });
721 + }).catch(function (err) { if (func) { try { func(err); } catch (ex) { console.log(ex); } } });
722 + } else if (obj.databaseType == 5) { // MySQL
723 + Datastore.query(query, args, function (error, results, fields) {
724 + if (error != null) {
725 + if (func) try { func(error); } catch (ex) { console.log(ex); }
726 + } else {
727 + var docs = [];
728 + for (var i in results) { if (results[i].doc) { docs.push(JSON.parse(results[i].doc)); } }
729 + //console.log(docs);
730 + if (func) { try { func(null, docs); } catch (ex) { console.log(ex); } }
731 + }
732 + });
733 + }
734 }
735
736 // Exec on the database
753 - function mariaDbExec(query, args, func) {
754 - Datastore.getConnection()
755 - .then(function (conn) {
756 - conn.query(query, args)
757 - .then(function (rows) {
758 - conn.release();
759 - if (func) try { func(null, rows[0]); } catch (ex) { console.log(ex); }
760 - })
761 - .catch(function (err) { conn.release(); if (func) try { console.log(err); func(err); } catch (ex) { console.log(ex); } });
762 - }).catch(function (err) { if (func) { try { console.log(err); func(err); } catch (ex) { console.log(ex); } } });
737 + function sqlDbExec(query, args, func) {
738 + if (obj.databaseType == 4) { // MariaDB
739 + Datastore.getConnection()
740 + .then(function (conn) {
741 + conn.query(query, args)
742 + .then(function (rows) {
743 + conn.release();
744 + if (func) try { func(null, rows[0]); } catch (ex) { console.log(ex); }
745 + })
746 + .catch(function (err) { conn.release(); if (func) try { func(err); } catch (ex) { console.log(ex); } });
747 + }).catch(function (err) { if (func) { try { func(err); } catch (ex) { console.log(ex); } } });
748 + } else if (obj.databaseType == 5) { // MySQL
749 + Datastore.query(query, args, function (error, results, fields) {
750 + if (func) try { func(error, results[0]); } catch (ex) { console.log(ex); }
751 + });
752 + }
753 }
754
755 // Execute a batch of commands on the database
766 - function mariaDbBatchExec(queries, func) {
767 - Datastore.getConnection()
768 - .then(function (conn) {
769 - var Promises = [];
770 - for (var i in queries) { if (typeof queries[i] == 'string') { Promises.push(conn.query(queries[i])); } else { Promises.push(conn.query(queries[i][0], queries[i][1])); } }
771 - Promise.all(Promises)
772 - .then(function (rows) { conn.release(); if (func) { try { func(null); } catch (ex) { console.log(ex); } } })
773 - .catch(function (err) { conn.release(); if (func) { try { console.log(err); func(err); } catch (ex) { console.log(ex); } } });
774 - })
775 - .catch(function (err) { if (func) { try { console.log(err); func(err); } catch (ex) { console.log(ex); } } });
756 + function sqlDbBatchExec(queries, func) {
757 + if (obj.databaseType == 4) { // MariaDB
758 + Datastore.getConnection()
759 + .then(function (conn) {
760 + var Promises = [];
761 + for (var i in queries) { if (typeof queries[i] == 'string') { Promises.push(conn.query(queries[i])); } else { Promises.push(conn.query(queries[i][0], queries[i][1])); } }
762 + Promise.all(Promises)
763 + .then(function (rows) { conn.release(); if (func) { try { func(null); } catch (ex) { console.log(ex); } } })
764 + .catch(function (err) { conn.release(); if (func) { try { func(err); } catch (ex) { console.log(ex); } } });
765 + })
766 + .catch(function (err) { if (func) { try { func(err); } catch (ex) { console.log(ex); } } });
767 + } else if (obj.databaseType == 5) { // MySQL
768 + var Promises = [];
769 + for (var i in queries) { if (typeof queries[i] == 'string') { Promises.push(Datastore.query(queries[i])); } else { Promises.push(Datastore.query(queries[i][0], queries[i][1])); } }
770 + Promise.all(Promises)
771 + .then(function (error, results, fields) { if (func) { try { func(error, results); } catch (ex) { console.log(ex); } } })
772 + .catch(function (error, results, fields) { if (func) { try { func(error); } catch (ex) { console.log(ex); } } });
773 + }
774 }
775
776 function setupFunctions(func) {
779 - if (obj.databaseType == 4) {
780 - // Database actions on the main collection (MariaDB)
777 + if ((obj.databaseType == 4) || (obj.databaseType == 5)) {
778 + // Database actions on the main collection (MariaDB or MySQL)
779 obj.Set = function (value, func) {
780 var extra = null, extraex = null;
781 if (value.meshid) { extra = value.meshid; } else if (value.email) { extra = 'email/' + value.email; }
782 if ((value.type == 'node') && (value.intelamt != null) && (value.intelamt.uuid != null)) { extraex = 'uuid/' + value.intelamt.uuid; }
785 - mariaDbQuery('REPLACE INTO meshcentral.main VALUE (?, ?, ?, ?, ?, ?)', [value._id, (value.type ? value.type : null), ((value.domain != null) ? value.domain : null), extra, extraex, JSON.stringify(performTypedRecordEncrypt(value))], func);
783 + sqlDbQuery('REPLACE INTO meshcentral.main VALUE (?, ?, ?, ?, ?, ?)', [value._id, (value.type ? value.type : null), ((value.domain != null) ? value.domain : null), extra, extraex, JSON.stringify(performTypedRecordEncrypt(value))], func);
784 }
787 - obj.Get = function (_id, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], func); }
788 - obj.GetAll = function (func) { mariaDbQuery('SELECT domain, doc FROM meshcentral.main', null, func); }
789 - obj.GetHash = function (id, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [id], func); }
790 - obj.GetAllTypeNoTypeField = function (type, domain, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); };
791 - obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) { if (id && (id != '')) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE id = ? AND type = ? AND domain = ? AND extra IN ?', [id, type, domain, meshes], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); } else { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ? AND extra IN ?', [type, domain, meshes], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); } };
792 - obj.GetAllType = function (type, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE type = ?', [type], func); }
793 - obj.GetAllIdsOfType = function (ids, domain, type, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE id IN ? AND domain = ? AND type = ?', [ids, domain, type], func); }
794 - obj.GetUserWithEmail = function (domain, email, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], func); }
795 - obj.GetUserWithVerifiedEmail = function (domain, email, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], func); }
796 - obj.Remove = function (id, func) { mariaDbQuery('DELETE FROM meshcentral.main WHERE id = ?', [id], func); };
797 - obj.RemoveAll = function (func) { mariaDbQuery('DELETE FROM meshcentral.main', null, func); };
798 - obj.RemoveAllOfType = function (type, func) { mariaDbQuery('DELETE FROM meshcentral.main WHERE type = ?', [type], func); };
785 + obj.Get = function (_id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], func); }
786 + obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM meshcentral.main', null, func); }
787 + obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [id], func); }
788 + obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); };
789 + obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) { if (id && (id != '')) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?)', [id, type, domain, meshes], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); } else { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ? AND extra IN (?)', [type, domain, meshes], function (err, docs) { for (var i in docs) { delete docs[i].type } func(err, docs); }); } };
790 + obj.GetAllType = function (type, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ?', [type], func); }
791 + obj.GetAllIdsOfType = function (ids, domain, type, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id IN (?) AND domain = ? AND type = ?', [ids, domain, type], func); }
792 + obj.GetUserWithEmail = function (domain, email, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], func); }
793 + obj.GetUserWithVerifiedEmail = function (domain, email, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], func); }
794 + obj.Remove = function (id, func) { sqlDbQuery('DELETE FROM meshcentral.main WHERE id = ?', [id], func); };
795 + obj.RemoveAll = function (func) { sqlDbQuery('DELETE FROM meshcentral.main', null, func); };
796 + obj.RemoveAllOfType = function (type, func) { sqlDbQuery('DELETE FROM meshcentral.main WHERE type = ?', [type], func); };
797 obj.InsertMany = function (data, func) { var pendingOps = 0; for (var i in data) { pendingOps++; obj.Set(data[i], function () { if (--pendingOps == 0) { func(); } }); } };
800 - obj.RemoveMeshDocuments = function (id) { mariaDbQuery('DELETE FROM meshcentral.main WHERE extra = ?', [id], function () { mariaDbQuery('DELETE FROM meshcentral.main WHERE id = ?', ['nt' + id], func); } ); };
798 + obj.RemoveMeshDocuments = function (id) { sqlDbQuery('DELETE FROM meshcentral.main WHERE extra = ?', [id], function () { sqlDbQuery('DELETE FROM meshcentral.main WHERE id = ?', ['nt' + id], func); } ); };
799 obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); };
802 - obj.DeleteDomain = function (domain, func) { mariaDbQuery('DELETE FROM meshcentral.main WHERE domain = ?', [domain], func); };
800 + obj.DeleteDomain = function (domain, func) { sqlDbQuery('DELETE FROM meshcentral.main WHERE domain = ?', [domain], func); };
801 obj.SetUser = function (user) { if (user.subscriptions != null) { var u = Clone(user); if (u.subscriptions) { delete u.subscriptions; } obj.Set(u); } else { obj.Set(user); } };
802 obj.dispose = function () { for (var x in obj) { if (obj[x].close) { obj[x].close(); } delete obj[x]; } };
805 - obj.getLocalAmtNodes = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE (type = "node") AND (extraex IS NOT NULL)', null, function (err, docs) { var r = []; for (var i in docs) { if (docs[i].host != null) { r.push(docs[i]); } } func(err, r); }); };
806 - obj.getAmtUuidMeshNode = function (meshid, uuid, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE meshid = ? AND extraex = ?', [meshid, 'uuid/' + uuid], func); };
807 - obj.getAmtUuidNode = function (uuid, func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE type = "node" AND extraex = ?', ['uuid/' + uuid], func); };
808 - obj.isMaxType = function (max, type, domainid, func) { if (max == null) { func(false); } else { mariaDbExec('SELECT COUNT(id) FROM meshcentral.main WHERE domain = ? AND type = ?', [domainid, type], function (err, response) { func((response['COUNT(id)'] == null) || (response['COUNT(id)'] > max), response['COUNT(id)']) }); } }
803 + obj.getLocalAmtNodes = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE (type = "node") AND (extraex IS NOT NULL)', null, function (err, docs) { var r = []; for (var i in docs) { if (docs[i].host != null) { r.push(docs[i]); } } func(err, r); }); };
804 + obj.getAmtUuidMeshNode = function (meshid, uuid, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE meshid = ? AND extraex = ?', [meshid, 'uuid/' + uuid], func); };
805 + obj.getAmtUuidNode = function (uuid, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = "node" AND extraex = ?', ['uuid/' + uuid], func); };
806 + obj.isMaxType = function (max, type, domainid, func) { if (max == null) { func(false); } else { sqlDbExec('SELECT COUNT(id) FROM meshcentral.main WHERE domain = ? AND type = ?', [domainid, type], function (err, response) { func((response['COUNT(id)'] == null) || (response['COUNT(id)'] > max), response['COUNT(id)']) }); } }
807
808 // Database actions on the events collection
811 - obj.GetAllEvents = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.events', null, func); };
809 + obj.GetAllEvents = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.events', null, func); };
810 obj.StoreEvent = function (event) {
811 var batchQuery = [['INSERT INTO meshcentral.events VALUE (?, ?, ?, ?, ?, ?, ?)', [null, event.time, ((typeof event.domain == 'string') ? event.domain : null), event.action, event.nodeid ? event.nodeid : null, event.userid ? event.userid : null, JSON.stringify(event)]]];
812 for (var i in event.ids) { if (event.ids[i] != '*') { batchQuery.push(['INSERT INTO meshcentral.eventids VALUE (LAST_INSERT_ID(), ?)', [event.ids[i]]]); } }
815 - mariaDbBatchExec(batchQuery, function (err, docs) { });
813 + sqlDbBatchExec(batchQuery, function (err, docs) { });
814 };
815 obj.GetEvents = function (ids, domain, func) {
816 if (ids.indexOf('*') >= 0) {
819 - mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ?) ORDER BY time DESC', [domain], func);
817 + sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ?) ORDER BY time DESC', [domain], func);
818 } else {
821 - mariaDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, ids], func);
819 + sqlDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, ids], func);
820 }
821 };
822 obj.GetEventsWithLimit = function (ids, domain, limit, func) {
823 if (ids.indexOf('*') >= 0) {
826 - mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ?) ORDER BY time DESC LIMIT ?', [domain, limit], func);
824 + sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ?) ORDER BY time DESC LIMIT ?', [domain, limit], func);
825 } else {
828 - mariaDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, ids, limit], func);
826 + sqlDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, ids, limit], func);
827 }
828 };
829 obj.GetUserEvents = function (ids, domain, username, func) {
830 const userid = 'user/' + domain + '/' + username.toLowerCase();
831 if (ids.indexOf('*') >= 0) {
834 - mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ? AND userid = ?) ORDER BY time DESC', [domain, userid], func);
832 + sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ? AND userid = ?) ORDER BY time DESC', [domain, userid], func);
833 } else {
836 - mariaDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, userid, ids, limit], func);
834 + sqlDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, userid, ids, limit], func);
835 }
836 };
837 obj.GetUserEventsWithLimit = function (ids, domain, username, limit, func) {
838 const userid = 'user/' + domain + '/' + username.toLowerCase();
839 if (ids.indexOf('*') >= 0) {
842 - mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ? AND userid = ?) ORDER BY time DESC LIMIT ?', [domain, userid, limit], func);
840 + sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (domain = ? AND userid = ?) ORDER BY time DESC LIMIT ?', [domain, userid, limit], func);
841 } else {
844 - mariaDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, userid, ids, limit], func);
842 + sqlDbQuery('SELECT doc FROM meshcentral.events JOIN meshcentral.eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, userid, ids, limit], func);
843 }
844 };
847 - obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (nodeid = ?) AND (domain = ?) ORDER BY time DESC LIMIT ?', [nodeid, domain, limit], func); };
848 - obj.GetNodeEventsSelfWithLimit = function (nodeid, domain, userid, limit, func) { mariaDbQuery('SELECT doc FROM meshcentral.events WHERE (nodeid = ?) AND (domain = ?) AND ((userid = ?) OR (userid IS NULL)) ORDER BY time DESC LIMIT ?', [nodeid, domain, userid, limit], func); };
849 - obj.RemoveAllEvents = function (domain) { mariaDbQuery('DELETE FROM meshcentral.events', null, function (err, docs) { }); };
850 - obj.RemoveAllNodeEvents = function (domain, nodeid) { mariaDbQuery('DELETE FROM meshcentral.events WHERE domain = ? AND nodeid = ?', [domain, nodeid], function (err, docs) { }); };
851 - obj.RemoveAllUserEvents = function (domain, userid) { mariaDbQuery('DELETE FROM meshcentral.events WHERE domain = ? AND userid = ?', [domain, userid], function (err, docs) { }); };
852 - obj.GetFailedLoginCount = function (username, domainid, lastlogin, func) { mariaDbExec('SELECT COUNT(id) FROM meshcentral.events WHERE action = "authfail" AND domain = ? AND userid = ? AND time > ?', [domainid, 'user/' + domainid + '/' + username.toLowerCase(), lastlogin], function (err, response) { obj.stats.meshcentral = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } }); }
845 + obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (nodeid = ?) AND (domain = ?) ORDER BY time DESC LIMIT ?', [nodeid, domain, limit], func); };
846 + obj.GetNodeEventsSelfWithLimit = function (nodeid, domain, userid, limit, func) { sqlDbQuery('SELECT doc FROM meshcentral.events WHERE (nodeid = ?) AND (domain = ?) AND ((userid = ?) OR (userid IS NULL)) ORDER BY time DESC LIMIT ?', [nodeid, domain, userid, limit], func); };
847 + obj.RemoveAllEvents = function (domain) { sqlDbQuery('DELETE FROM meshcentral.events', null, function (err, docs) { }); };
848 + obj.RemoveAllNodeEvents = function (domain, nodeid) { sqlDbQuery('DELETE FROM meshcentral.events WHERE domain = ? AND nodeid = ?', [domain, nodeid], function (err, docs) { }); };
849 + obj.RemoveAllUserEvents = function (domain, userid) { sqlDbQuery('DELETE FROM meshcentral.events WHERE domain = ? AND userid = ?', [domain, userid], function (err, docs) { }); };
850 + obj.GetFailedLoginCount = function (username, domainid, lastlogin, func) { sqlDbExec('SELECT COUNT(id) FROM meshcentral.events WHERE action = "authfail" AND domain = ? AND userid = ? AND time > ?', [domainid, 'user/' + domainid + '/' + username.toLowerCase(), lastlogin], function (err, response) { func(err == null ? response['COUNT(id)'] : 0); }); }
851
852 // Database actions on the power collection
855 - obj.getAllPower = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.power', null, func); };
856 - obj.storePowerEvent = function (event, multiServer, func) { if (multiServer != null) { event.server = multiServer.serverid; } mariaDbQuery('INSERT INTO meshcentral.power VALUE (?, ?, ?, ?)', [null, event.time, event.nodeid ? event.nodeid : null, JSON.stringify(event)], func); };
857 - obj.getPowerTimeline = function (nodeid, func) { mariaDbQuery('SELECT doc FROM meshcentral.power WHERE ((nodeid = ?) OR (nodeid = "*")) ORDER BY time DESC', [nodeid], func); };
858 - obj.removeAllPowerEvents = function () { mariaDbQuery('DELETE FROM meshcentral.power', null, function (err, docs) { }); };
859 - obj.removeAllPowerEventsForNode = function (nodeid) { mariaDbQuery('DELETE FROM meshcentral.power WHERE nodeid = ?', [nodeid], function (err, docs) { }); };
853 + obj.getAllPower = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.power', null, func); };
854 + obj.storePowerEvent = function (event, multiServer, func) { if (multiServer != null) { event.server = multiServer.serverid; } sqlDbQuery('INSERT INTO meshcentral.power VALUE (?, ?, ?, ?)', [null, event.time, event.nodeid ? event.nodeid : null, JSON.stringify(event)], func); };
855 + obj.getPowerTimeline = function (nodeid, func) { sqlDbQuery('SELECT doc FROM meshcentral.power WHERE ((nodeid = ?) OR (nodeid = "*")) ORDER BY time DESC', [nodeid], func); };
856 + obj.removeAllPowerEvents = function () { sqlDbQuery('DELETE FROM meshcentral.power', null, function (err, docs) { }); };
857 + obj.removeAllPowerEventsForNode = function (nodeid) { sqlDbQuery('DELETE FROM meshcentral.power WHERE nodeid = ?', [nodeid], function (err, docs) { }); };
858
859 // Database actions on the SMBIOS collection
862 - obj.GetAllSMBIOS = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.smbios', null, func); };
863 - obj.SetSMBIOS = function (smbios, func) { var expire = new Date(smbios.time); expire.setMonth(expire.getMonth() + 6); mariaDbQuery('REPLACE INTO meshcentral.smbios VALUE (?, ?, ?, ?)', [smbios._id, smbios.time, expire, JSON.stringify(smbios)], func); };
864 - obj.RemoveSMBIOS = function (id) { mariaDbQuery('DELETE FROM meshcentral.smbios WHERE id = ?', [id], function (err, docs) { }); };
865 - obj.GetSMBIOS = function (id, func) { mariaDbQuery('SELECT doc FROM meshcentral.smbios WHERE id = ?', [id], func); };
860 + obj.GetAllSMBIOS = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.smbios', null, func); };
861 + obj.SetSMBIOS = function (smbios, func) { var expire = new Date(smbios.time); expire.setMonth(expire.getMonth() + 6); sqlDbQuery('REPLACE INTO meshcentral.smbios VALUE (?, ?, ?, ?)', [smbios._id, smbios.time, expire, JSON.stringify(smbios)], func); };
862 + obj.RemoveSMBIOS = function (id) { sqlDbQuery('DELETE FROM meshcentral.smbios WHERE id = ?', [id], function (err, docs) { }); };
863 + obj.GetSMBIOS = function (id, func) { sqlDbQuery('SELECT doc FROM meshcentral.smbios WHERE id = ?', [id], func); };
864
865 // Database actions on the Server Stats collection
868 - obj.SetServerStats = function (data, func) { mariaDbQuery('REPLACE INTO meshcentral.serverstats VALUE (?, ?, ?)', [data.time, data.expire, JSON.stringify(data)], func); };
869 - obj.GetServerStats = function (hours, func) { var t = new Date(); t.setTime(t.getTime() - (60 * 60 * 1000 * hours)); mariaDbQuery('SELECT doc FROM meshcentral.main WHERE time < ?', [t], func); }; // TODO: Expire old entries
866 + obj.SetServerStats = function (data, func) { sqlDbQuery('REPLACE INTO meshcentral.serverstats VALUE (?, ?, ?)', [data.time, data.expire, JSON.stringify(data)], func); };
867 + obj.GetServerStats = function (hours, func) { var t = new Date(); t.setTime(t.getTime() - (60 * 60 * 1000 * hours)); sqlDbQuery('SELECT doc FROM meshcentral.main WHERE time < ?', [t], func); }; // TODO: Expire old entries
868
869 // Read a configuration file from the database
870 obj.getConfigFile = function (path, func) { obj.Get('cfile/' + path, func); }
@@ -875,7 +873,7 @@ SELECT doc FROM xmeshcentral.events JOIN eventids ON id = fkid WHERE target IN (
873 obj.setConfigFile = function (path, data, func) { obj.Set({ _id: 'cfile/' + path, type: 'cfile', data: data.toString('base64') }, func); }
874
875 // List all configuration files
878 - obj.listConfigFiles = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.main WHERE type = "cfile" ORDER BY id', func); }
876 + obj.listConfigFiles = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = "cfile" ORDER BY id', func); }
877
878 // Get all configuration files
879 obj.getAllConfigFiles = function (password, func) {
@@ -894,20 +892,20 @@ SELECT doc FROM xmeshcentral.events JOIN eventids ON id = fkid WHERE target IN (
892 // Get database information (TODO: Complete this)
893 obj.getDbStats = function (func) {
894 obj.stats = { c: 4 };
897 - mariaDbExec('SELECT COUNT(id) FROM meshcentral.main', null, function (err, response) { obj.stats.meshcentral = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
898 - mariaDbExec('SELECT COUNT(time) FROM meshcentral.serverstats', null, function (err, response) { obj.stats.serverstats = response['COUNT(time)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
899 - mariaDbExec('SELECT COUNT(id) FROM meshcentral.power', null, function (err, response) { obj.stats.power = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
900 - mariaDbExec('SELECT COUNT(id) FROM meshcentral.smbios', null, function (err, response) { obj.stats.smbios = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
895 + sqlDbExec('SELECT COUNT(id) FROM meshcentral.main', null, function (err, response) { obj.stats.meshcentral = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
896 + sqlDbExec('SELECT COUNT(time) FROM meshcentral.serverstats', null, function (err, response) { obj.stats.serverstats = response['COUNT(time)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
897 + sqlDbExec('SELECT COUNT(id) FROM meshcentral.power', null, function (err, response) { obj.stats.power = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
898 + sqlDbExec('SELECT COUNT(id) FROM meshcentral.smbios', null, function (err, response) { obj.stats.smbios = response['COUNT(id)']; if (--obj.stats.c == 0) { delete obj.stats.c; func(obj.stats); } });
899 }
900
901 // Plugin operations
902 if (parent.config.settings.plugins != null) {
905 - obj.addPlugin = function (plugin, func) { mariaDbQuery('INSERT INTO meshcentral.plugin VALUE (?, ?)', [null, JSON.stringify(value)], func); }; // Add a plugin
906 - obj.getPlugins = function (func) { mariaDbQuery('SELECT doc FROM meshcentral.plugin', null, func); }; // Get all plugins
907 - obj.getPlugin = function (id, func) { mariaDbQuery('SELECT doc FROM meshcentral.plugin WHERE id = ?', [id], func); }; // Get plugin
908 - obj.deletePlugin = function (id, func) { mariaDbQuery('DELETE FROM meshcentral.plugin WHERE id = ?', [id], func); }; // Delete plugin
903 + obj.addPlugin = function (plugin, func) { sqlDbQuery('INSERT INTO meshcentral.plugin VALUE (?, ?)', [null, JSON.stringify(value)], func); }; // Add a plugin
904 + obj.getPlugins = function (func) { sqlDbQuery('SELECT doc FROM meshcentral.plugin', null, func); }; // Get all plugins
905 + obj.getPlugin = function (id, func) { sqlDbQuery('SELECT doc FROM meshcentral.plugin WHERE id = ?', [id], func); }; // Get plugin
906 + obj.deletePlugin = function (id, func) { sqlDbQuery('DELETE FROM meshcentral.plugin WHERE id = ?', [id], func); }; // Delete plugin
907 obj.setPluginStatus = function (id, status, func) { obj.getPlugin(id, function (err, docs) { if (docs.length == 1) { docs[0].status = status; obj.updatePlugin(id, docs[0], func); } }); };
910 - obj.updatePlugin = function (id, args, func) { delete args._id; mariaDbQuery('REPLACE INTO meshcentral.plugin VALUE (?, ?)', [id, JSON.stringify(args)], func); };
908 + obj.updatePlugin = function (id, args, func) { delete args._id; sqlDbQuery('REPLACE INTO meshcentral.plugin VALUE (?, ?)', [id, JSON.stringify(args)], func); };
909 }
910 } else if (obj.databaseType == 3) {
911 // Database actions on the main collection (MongoDB)
meshcentral.js
+2
@@ -816,6 +816,7 @@ function CreateMeshCentralServer(config, args) {
816 }
817
818 // Grad some of the values from the original config.json file if present.
819 + config2['mysql'] = config['mysql'];
820 config2['mariadb'] = config['mariadb'];
821 config2['mongodb'] = config['mongodb'];
822 config2['mongodbcol'] = config['mongodbcol'];
@@ -2323,6 +2324,7 @@ function mainStart() {
2324 if (ldap == true) { modules.push('ldapauth-fork'); }
2325 if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { addServerWarning("Let's Encrypt support requires Node v10.12 or higher.", !args.launch); } else { modules.push('greenlock'); } } // Add Greenlock Module
2326 if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules
2327 + if (config.settings.mysql != null) { modules.push('mysql'); } // Add MySQL, official driver.
2328 if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver.
2329 if (config.settings.mariadb != null) { modules.push('mariadb'); } // Add MariaDB, official driver.
2330 if (config.settings.vault != null) { modules.push('node-vault'); } // Add official HashiCorp's Vault module.