SQLite fixes and addition to config.json schema.

Ylian Saint-Hilaire committed Aug 15, 2022 at 16:28 UTC 8c9067ed4a9b786882a3247221de4bbb20847693
4 files changed +37 -23
db.js
+29 -15
@@ -1190,12 +1190,20 @@ module.exports.CreateDB = function (parent, func) {
1190 }
1191
1192 // Query the database
1193 - function sqlDbQuery(query, args, func) {
1193 + function sqlDbQuery(query, args, func, debug) {
1194 if (obj.databaseType == 8) { // SQLite
1195 if (args == null) { args = []; }
1196 obj.file.all(query, args, function (err, docs) {
1197 if (err != null) { console.log(query, args, err, docs); }
1198 - if (docs != null) { for (var i in docs) { if (typeof docs[i].doc == 'string') { docs[i] = JSON.parse(docs[i].doc); } } }
1198 + if (docs != null) {
1199 + for (var i in docs) {
1200 + if (typeof docs[i].doc == 'string') {
1201 + try { docs[i] = JSON.parse(docs[i].doc); } catch (ex) {
1202 + console.log(query, args, docs[i]);
1203 + }
1204 + }
1205 + }
1206 + }
1207 if (func) { func(err, docs); }
1208 });
1209 } else if (obj.databaseType == 4) { // MariaDB
@@ -1323,18 +1331,18 @@ module.exports.CreateDB = function (parent, func) {
1331 };
1332 obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
1333 if (id && (id != '')) {
1326 - sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN ($4))', [id, type, domain, meshes], function (err, docs) {
1334 + sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN (' + dbMergeSqlArray(meshes) + '))', [id, type, domain], function (err, docs) {
1335 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1336 func(err, performTypedRecordDecrypt(docs));
1337 });
1338 } else {
1339 if (extrasids == null) {
1332 - sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN ($3))', [type, domain, meshes], function (err, docs) {
1340 + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN (' + dbMergeSqlArray(meshes) + '))', [type, domain], function (err, docs) {
1341 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1342 func(err, performTypedRecordDecrypt(docs));
1335 - }, true);
1343 + });
1344 } else {
1337 - sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra IN ($3)) OR (id IN ($4)))', [type, domain, meshes, extrasids], function (err, docs) {
1345 + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra IN (' + dbMergeSqlArray(meshes) + ')) OR (id IN (' + dbMergeSqlArray(extrasids) + ')))', [type, domain], function (err, docs) {
1346 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1347 func(err, performTypedRecordDecrypt(docs));
1348 });
@@ -1343,12 +1351,12 @@ module.exports.CreateDB = function (parent, func) {
1351 };
1352 obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
1353 if (id && (id != '')) {
1346 - sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN ($4))', [id, type, domain, nodes], function (err, docs) {
1354 + sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN (' + dbMergeSqlArray(nodes) + '))', [id, type, domain], function (err, docs) {
1355 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1356 func(err, performTypedRecordDecrypt(docs));
1357 });
1358 } else {
1351 - sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN ($3))', [type, domain, nodes], function (err, docs) {
1359 + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN (' + dbMergeSqlArray(nodes) + '))', [type, domain], function (err, docs) {
1360 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1361 func(err, performTypedRecordDecrypt(docs));
1362 });
@@ -1361,7 +1369,7 @@ module.exports.CreateDB = function (parent, func) {
1369 });
1370 }
1371 obj.GetAllIdsOfType = function (ids, domain, type, func) {
1364 - sqlDbQuery('SELECT doc FROM main WHERE (id IN ($1)) AND domain = $2 AND type = $3', [ids, domain, type], function (err, docs) {
1372 + sqlDbQuery('SELECT doc FROM main WHERE (id IN (' + dbMergeSqlArray(ids) + ')) AND domain = $1 AND type = $2', [domain, type], function (err, docs) {
1373 if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
1374 func(err, performTypedRecordDecrypt(docs));
1375 });
@@ -1415,35 +1423,35 @@ module.exports.CreateDB = function (parent, func) {
1423 if (ids.indexOf('*') >= 0) {
1424 sqlDbQuery('SELECT doc FROM events WHERE (domain = $1) ORDER BY time DESC', [domain], func);
1425 } else {
1418 - sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND (target IN ($2))) GROUP BY id ORDER BY time DESC', [domain, ids], func);
1426 + sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND (target IN (' + dbMergeSqlArray(ids) + '))) GROUP BY id ORDER BY time DESC', [domain], func);
1427 }
1428 };
1429 obj.GetEventsWithLimit = function (ids, domain, limit, func) {
1430 if (ids.indexOf('*') >= 0) {
1431 sqlDbQuery('SELECT doc FROM events WHERE (domain = $1) ORDER BY time DESC LIMIT $2', [domain, limit], func);
1432 } else {
1425 - sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND (target IN ($2))) GROUP BY id ORDER BY time DESC LIMIT $3', [domain, ids, limit], func);
1433 + sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND (target IN (' + dbMergeSqlArray(ids) + '))) GROUP BY id ORDER BY time DESC LIMIT $2', [domain, limit], func);
1434 }
1435 };
1436 obj.GetUserEvents = function (ids, domain, userid, func) {
1437 if (ids.indexOf('*') >= 0) {
1438 sqlDbQuery('SELECT doc FROM events WHERE (domain = $1 AND userid = $2) ORDER BY time DESC', [domain, userid], func);
1439 } else {
1432 - sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND userid = $2 AND (target IN ($3))) GROUP BY id ORDER BY time DESC', [domain, userid, ids], func);
1440 + sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND userid = $2 AND (target IN (' + dbMergeSqlArray(ids) + '))) GROUP BY id ORDER BY time DESC', [domain, userid], func);
1441 }
1442 };
1443 obj.GetUserEventsWithLimit = function (ids, domain, userid, limit, func) {
1444 if (ids.indexOf('*') >= 0) {
1445 sqlDbQuery('SELECT doc FROM events WHERE (domain = $1 AND userid = $2) ORDER BY time DESC LIMIT $3', [domain, userid, limit], func);
1446 } else {
1439 - sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND userid = $2 AND (target IN ($3))) GROUP BY id ORDER BY time DESC LIMIT $4', [domain, userid, ids, limit], func);
1447 + sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = $1 AND userid = $2 AND (target IN (' + dbMergeSqlArray(ids) + '))) GROUP BY id ORDER BY time DESC LIMIT $3', [domain, userid, limit], func);
1448 }
1449 };
1450 obj.GetEventsTimeRange = function (ids, domain, msgids, start, end, func) {
1451 if (ids.indexOf('*') >= 0) {
1452 sqlDbQuery('SELECT doc FROM events WHERE ((domain = $1) AND (time BETWEEN $2 AND $3)) ORDER BY time', [domain, start, end], func);
1453 } else {
1446 - sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE ((domain = $1) AND (target IN ($2)) AND (time BETWEEN $3 AND $4)) GROUP BY id ORDER BY time', [domain, ids, start, end], func);
1454 + sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE ((domain = $1) AND (target IN (' + dbMergeSqlArray(ids) + ')) AND (time BETWEEN $2 AND $3)) GROUP BY id ORDER BY time', [domain, start, end], func);
1455 }
1456 };
1457 //obj.GetUserLoginEvents = function (domain, userid, func) { } // TODO
@@ -1456,7 +1464,7 @@ module.exports.CreateDB = function (parent, func) {
1464
1465 // Database actions on the power collection
1466 obj.getAllPower = function (func) { sqlDbQuery('SELECT doc FROM power', null, func); };
1459 - obj.storePowerEvent = function (event, multiServer, func) { obj.dbCounters.powerSet++; if (multiServer != null) { event.server = multiServer.serverid; } sqlDbQuery('INSERT INTO power VALUES (NULL, $1, $2, $3)', [event.time, event.nodeid ? event.nodeid : null, event], func); };
1467 + obj.storePowerEvent = function (event, multiServer, func) { obj.dbCounters.powerSet++; if (multiServer != null) { event.server = multiServer.serverid; } sqlDbQuery('INSERT INTO power VALUES (NULL, $1, $2, $3)', [event.time, event.nodeid ? event.nodeid : null, JSON.stringify(event)], func); };
1468 obj.getPowerTimeline = function (nodeid, func) { sqlDbQuery('SELECT doc FROM power WHERE ((nodeid = $1) OR (nodeid = \'*\')) ORDER BY time ASC', [nodeid], func); };
1469 obj.removeAllPowerEvents = function () { sqlDbQuery('DELETE FROM power', null, function (err, docs) { }); };
1470 obj.removeAllPowerEventsForNode = function (nodeid) { if (nodeid == null) return; sqlDbQuery('DELETE FROM power WHERE nodeid = $1', [nodeid], function (err, docs) { }); };
@@ -3280,5 +3288,11 @@ module.exports.CreateDB = function (parent, func) {
3288 parent.DispatchEvent(['*', usergroup.ugrpid], obj, usergroup);
3289 }
3290
3291 + function dbMergeSqlArray(arr) {
3292 + var x = '';
3293 + for (var i in arr) { if (x != '') { x += ','; } x += '"' + arr[i] + '"'; }
3294 + return x;
3295 + }
3296 +
3297 return obj;
3298 };
meshcentral-config-schema.json
+6 -7
@@ -35,13 +35,7 @@
35 }
36 }
37 },
38 - "acebase": {
39 - "type": "object",
40 - "description": "Add this section to enable AceBase database support, this is a local database system much like NeDB.",
41 - "properties": {
42 - "sponsor": { "type": "boolean", "default": false, "description": "Set true to remove the AceBase banner on startup." },
43 - }
44 - },
38 + "sqlite3": { "type": "boolean", "default": false, "description": "Set true to use SQLite3 as a local MeshCentral database." },
39 "mySQL": {
40 "type": "object",
41 "description": "Add this section to connect MeshCentral to a MySQL database instance.",
@@ -75,6 +69,11 @@
69 "database": { "type": "string", "default": "meshcentral", "description": "Name of PostgreSQL database used" }
70 }
71 },
72 + "acebase": {
73 + "type": "object",
74 + "description": "Add this section to enable AceBase database support, this is a local database system much like NeDB.",
75 + "properties": { "sponsor": { "type": "boolean", "default": false, "description": "Set true to remove the AceBase banner on startup." } }
76 + },
77 "WANonly": { "type": "boolean", "default": false, "description": "When enabled, only MeshCentral WAN features are enabled and agents will connect to the server using a well known DNS name." },
78 "LANonly": { "type": "boolean", "default": false, "description": "When enabled, only MeshCentral LAN features are enabled and agents will find the server using multicast LAN packets." },
79 "maintenanceMode": { "type": "boolean", "default": false, "description": "When enabled the server is in maintenance mode, only administrators can login. Use the maintenance command in server console to change." },
meshuser.js
+1 -1
@@ -696,7 +696,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
696 // Request a list of all nodes
697 db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, function (err, docs) {
698
699 - //console.log(err, docs);
699 + //console.log(err, docs, links, extraids, domain.id, 'node', command.id);
700
701 if (docs == null) { docs = []; }
702 parent.common.unEscapeAllLinksFieldName(docs);
sample-config-advanced.json
+1
@@ -3,6 +3,7 @@
3 "__comment__": "This is a sample configuration file, all values and sections that start with underscore (_) are ignored. Edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
4 "settings": {
5 "_cert": "myserver.mydomain.com",
6 + "_SQLite3": true,
7 "_acebase": { "_sponsor": true },
8 "_mongoDb": "mongodb://127.0.0.1:27017",
9 "_mongoDbName": "meshcentral",