|
|
|
|
@@ -1,9 +1,9 @@
|
|
|
|
|
require('dotenv').config();
|
|
|
|
|
const mysql = require('mysql');
|
|
|
|
|
const utils = require('./utils');
|
|
|
|
|
const { nodeObject } = require("./recordHelper");
|
|
|
|
|
const { nodeObject, clientObject, connectionObject } = require("./recordHelper");
|
|
|
|
|
const { DebugBuilder } = require("../utilities/debugBuilder");
|
|
|
|
|
const { BufferToJson } = require("../utilities/utils");
|
|
|
|
|
const { BufferToJson, getClientObjectByClientID } = require("../utilities/utils");
|
|
|
|
|
|
|
|
|
|
const log = new DebugBuilder("server", "mysSQLHandler");
|
|
|
|
|
|
|
|
|
|
@@ -15,6 +15,7 @@ const connection = mysql.createPool({
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const nodesTable = `${process.env.NODE_DB_NAME}.nodes`;
|
|
|
|
|
const nodeConnectionsTable = `${process.env.NODE_DB_NAME}.node_connections`;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return a node object from a single SQL row
|
|
|
|
|
@@ -31,7 +32,8 @@ function returnNodeObjectFromRow(row) {
|
|
|
|
|
_location: row.location,
|
|
|
|
|
_nearbySystems: BufferToJson(row.nearbySystems),
|
|
|
|
|
_online: (row.online === 1) ? true : false,
|
|
|
|
|
_connected: (row.connected === 1) ? true : false
|
|
|
|
|
_connected: (row.connected === 1) ? true : false,
|
|
|
|
|
_connection: (row.connection) ? row.connection : null,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -53,6 +55,21 @@ function returnNodeObjectFromRows(rows) {
|
|
|
|
|
return rows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a connection object from an SQL row
|
|
|
|
|
*
|
|
|
|
|
* @param {*} row The SQL row to convert to a connection object
|
|
|
|
|
* @returns {connectionObject}
|
|
|
|
|
*/
|
|
|
|
|
async function returnConnectionObjectFromRow(row) {
|
|
|
|
|
log.DEBUG("Connection row: ", row);
|
|
|
|
|
return new connectionObject({
|
|
|
|
|
_connection_id: row.connection_id,
|
|
|
|
|
_node: await getNodeInfoFromId(row.id),
|
|
|
|
|
_client_object: await getClientObjectByClientID(row.discord_client_id)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Get all nodes the server knows about regardless of status
|
|
|
|
|
* @param {*} callback Callback function
|
|
|
|
|
*/
|
|
|
|
|
@@ -71,8 +88,7 @@ exports.getAllNodes = (callback) => {
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
exports.getAllNodesSync = async () => {
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodesTable}`
|
|
|
|
|
var returnObjects = [];
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodesTable}`
|
|
|
|
|
const rows = await runSQL(sqlQuery);
|
|
|
|
|
|
|
|
|
|
console.log("Rows: ", rows);
|
|
|
|
|
@@ -94,20 +110,26 @@ exports.getOnlineNodes = (callback) => {
|
|
|
|
|
* @param nodeId The ID of the node
|
|
|
|
|
* @param callback Callback function
|
|
|
|
|
*/
|
|
|
|
|
exports.getNodeInfoFromId = (nodeId, callback) => {
|
|
|
|
|
async function getNodeInfoFromId(nodeId, callback = undefined) {
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodesTable} WHERE id = ${nodeId}`
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
// Call back the first (and theoretically only) row
|
|
|
|
|
// Specify 0 so downstream functions don't have to worry about it
|
|
|
|
|
return callback(returnNodeObjectFromRow(rows[0]));
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Call back the first (and theoretically only) row
|
|
|
|
|
// Specify 0 so downstream functions don't have to worry about it
|
|
|
|
|
return (callback) ? callback(returnNodeObjectFromRow(sqlResponse[0])) : returnNodeObjectFromRow(sqlResponse[0]);
|
|
|
|
|
}
|
|
|
|
|
exports.getNodeInfoFromId = getNodeInfoFromId
|
|
|
|
|
|
|
|
|
|
/** Add a new node to the DB
|
|
|
|
|
* @param nodeObject Node information object
|
|
|
|
|
* @param callback Callback function
|
|
|
|
|
*/
|
|
|
|
|
exports.addNewNode = (nodeObject, callback) => {
|
|
|
|
|
exports.addNewNode = async (nodeObject, callback) => {
|
|
|
|
|
if (!nodeObject.name) throw new Error("No name provided");
|
|
|
|
|
const name = nodeObject.name,
|
|
|
|
|
ip = nodeObject.ip,
|
|
|
|
|
@@ -118,16 +140,22 @@ exports.addNewNode = (nodeObject, callback) => {
|
|
|
|
|
connected = 0;
|
|
|
|
|
const sqlQuery = `INSERT INTO ${nodesTable} (name, ip, port, location, nearbySystems, online, connected) VALUES ('${name}', '${ip}', ${port}, '${location}', '${nearbySystems}', ${online}, ${connected})`;
|
|
|
|
|
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
return callback(returnNodeObjectFromRows(rows));
|
|
|
|
|
})
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Call back the first (and theoretically only) row
|
|
|
|
|
// Specify 0 so downstream functions don't have to worry about it
|
|
|
|
|
return (callback) ? callback(returnNodeObjectFromRow(sqlResponse)) : returnNodeObjectFromRow(sqlResponse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Update the known info on a node
|
|
|
|
|
* @param nodeObject Node information object
|
|
|
|
|
* @param callback Callback function
|
|
|
|
|
*/
|
|
|
|
|
exports.updateNodeInfo = (nodeObject, callback = undefined) => {
|
|
|
|
|
exports.updateNodeInfo = async (nodeObject, callback = undefined) => {
|
|
|
|
|
if(!nodeObject.id) throw new Error("Attempted to updated node without providing ID", nodeObject);
|
|
|
|
|
const name = nodeObject.name,
|
|
|
|
|
ip = nodeObject.ip,
|
|
|
|
|
@@ -175,21 +203,167 @@ exports.updateNodeInfo = (nodeObject, callback = undefined) => {
|
|
|
|
|
|
|
|
|
|
sqlQuery = `${sqlQuery} WHERE id = ${nodeObject.id};`
|
|
|
|
|
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
if (rows.affectedRows === 1) return (callback) ? callback(true) : true;
|
|
|
|
|
else return (callback) ? callback(returnNodeObjectFromRows(rows)) : returnNodeObjectFromRows(rows);
|
|
|
|
|
})
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (sqlResponse.affectedRows === 1) return (callback) ? callback(true) : true;
|
|
|
|
|
else return (callback) ? callback(returnNodeObjectFromRows(sqlResponse)) : returnNodeObjectFromRows(sqlResponse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a new connection to the DB when a bot has been connected to the server
|
|
|
|
|
*
|
|
|
|
|
* @param {*} nodeObject The node object that is being used for this connection
|
|
|
|
|
* @param {*} clientId The client ID Object being used for this connection
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to be called with the results, will return otherwise
|
|
|
|
|
*/
|
|
|
|
|
exports.addNodeConnection = (nodeObject, clientObject, callback = undefined) => {
|
|
|
|
|
if (!nodeObject.id || !clientObject.clientId) throw new Error("Tried to add a connection without a client and/or node ID");
|
|
|
|
|
const sqlQuery = `INSERT INTO ${nodeConnectionsTable} (id, discord_client_id) VALUES (${nodeObject.id}, '${clientObject.clientId}')`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) throw new Error("No result from added connection");
|
|
|
|
|
return (callback) ? callback(true) : true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check what node is connected with a given client ID object
|
|
|
|
|
*
|
|
|
|
|
* @param {*} clientId The client ID object used to search for a connected node
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to be called with the results, return will be used otherwise
|
|
|
|
|
*/
|
|
|
|
|
exports.checkNodeConnectionByClientId = async (clientId, callback = undefined) => {
|
|
|
|
|
if (!clientId.clientId) throw new Error("Tried to check a connection without a client ID");
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodeConnectionsTable} WHERE discord_client_id = '${clientId.clientId}'`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
log.VERBOSE("SQL Response from checking connection: ", sqlResponse);
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) return (callback) ? callback(undefined) : undefined;
|
|
|
|
|
const newNodeObject = await getNodeInfoFromId(sqlResponse[0].id);
|
|
|
|
|
log.DEBUG("Node Object from SQL Response: ", newNodeObject);
|
|
|
|
|
return (callback) ? callback(newNodeObject) : newNodeObject;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a connection by node ID
|
|
|
|
|
*
|
|
|
|
|
* @param {*} nodeId The ID to search for a connection with
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to be called with the results, return will be used otherwise
|
|
|
|
|
* @returns {connectionObject}
|
|
|
|
|
*/
|
|
|
|
|
exports.getConnectionByNodeId = async (nodeId, callback = undefined) => {
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodeConnectionsTable} WHERE id = '${nodeId}'`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
log.VERBOSE("SQL Response from checking connection: ", sqlResponse);
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) return (callback) ? callback(undefined) : undefined;
|
|
|
|
|
const newConnectionObject = await returnConnectionObjectFromRow(sqlResponse)
|
|
|
|
|
log.DEBUG("Connection Object from SQL Response: ", newConnectionObject);
|
|
|
|
|
return (callback) ? callback(newConnectionObject) : newConnectionObject;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a node connection by the node
|
|
|
|
|
*
|
|
|
|
|
* @param {*} nodeId The node ID of the node to remove connections of
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to callback with the results, return will be used otherwise
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
exports.removeNodeConnectionByNodeId = async (nodeId, callback = undefined) => {
|
|
|
|
|
const sqlQuery = `DELETE FROM ${nodeConnectionsTable} WHERE id = '${nodeId}'`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
log.VERBOSE("SQL Response from removing connection: ", sqlResponse);
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) return (callback) ? callback(undefined) : undefined;
|
|
|
|
|
return (callback) ? callback(sqlResponse) : sqlResponse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets all connected nodes
|
|
|
|
|
*
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to callback with the results, return will be used otherwise
|
|
|
|
|
* @returns {nodeObject}
|
|
|
|
|
*/
|
|
|
|
|
exports.getConnectedNodes = async (callback = undefined) => {
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodeConnectionsTable}`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
log.VERBOSE("SQL Response from checking connection: ", sqlResponse);
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) return (callback) ? callback(undefined) : undefined;
|
|
|
|
|
var nodeObjects = []
|
|
|
|
|
for (const row of sqlResponse) {
|
|
|
|
|
const newNodeObject = await getNodeInfoFromId(row.id);
|
|
|
|
|
log.DEBUG("Node Object from SQL Response: ", newNodeObject);
|
|
|
|
|
nodeObjects.push(newNodeObject);
|
|
|
|
|
}
|
|
|
|
|
return (callback) ? callback(nodeObjects) : nodeObjects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns all connections
|
|
|
|
|
*
|
|
|
|
|
* @param {*} callback [OPTIONAL] The callback function to callback with the results, return will be used otherwise
|
|
|
|
|
* @returns {connectionObject}
|
|
|
|
|
*/
|
|
|
|
|
exports.getAllConnections = async (callback = undefined) => {
|
|
|
|
|
const sqlQuery = `SELECT * FROM ${nodeConnectionsTable}`;
|
|
|
|
|
|
|
|
|
|
const sqlResponse = await new Promise((recordResolve, recordReject) => {
|
|
|
|
|
runSQL(sqlQuery, (rows) => {
|
|
|
|
|
recordResolve(rows);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
log.VERBOSE("SQL Response from checking connection: ", sqlResponse);
|
|
|
|
|
|
|
|
|
|
if (!sqlResponse) return (callback) ? callback(undefined) : undefined;
|
|
|
|
|
var connectionObjects = []
|
|
|
|
|
for (const row of sqlResponse) {
|
|
|
|
|
connectionObjects.push(await returnConnectionObjectFromRow(row));
|
|
|
|
|
}
|
|
|
|
|
return (callback) ? callback(connectionObjects) : connectionObjects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function to run and handle SQL errors
|
|
|
|
|
function runSQL(sqlQuery, callback, error = (err) => {
|
|
|
|
|
function runSQL(sqlQuery, callback = undefined, error = (err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
throw err;
|
|
|
|
|
}) {
|
|
|
|
|
return connection.query(sqlQuery, (err, rows) => {
|
|
|
|
|
connection.query(sqlQuery, (err, rows) => {
|
|
|
|
|
if (err) return error(err);
|
|
|
|
|
//console.log('The rows are:', rows);
|
|
|
|
|
return callback(rows);
|
|
|
|
|
//console.log('The rows are:', rows);
|
|
|
|
|
return (callback) ? callback(rows) : rows
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|