fix: remove duplicate and keep old behavior

This commit is contained in:
leonace924
2026-01-06 01:13:42 -05:00
parent af0866ec7d
commit e6481fa8aa
2 changed files with 81 additions and 29 deletions

View File

@@ -30,39 +30,84 @@ class MysqlMonitorType extends MonitorType {
// TODO: rename `radius_password` to `password` later for general use
const password = monitor.radiusPassword;
let result;
const conditions = ConditionExpressionGroup.fromMonitor(monitor);
const hasConditions = conditions && conditions.length > 0;
try {
result = await this.mysqlQuery(monitor.databaseConnectionString, query, password);
if (hasConditions) {
// When conditions are enabled, expect a single value result
const result = await this.mysqlQuerySingleValue(monitor.databaseConnectionString, query, password);
heartbeat.ping = dayjs().valueOf() - startTime;
const conditionsResult = evaluateExpressionGroup(conditions, { result: String(result) });
if (!conditionsResult) {
throw new Error(`Query result did not meet the specified conditions (${result})`);
}
heartbeat.msg = "";
} else {
// Backwards compatible: just check connection and return row count
const result = await this.mysqlQuery(monitor.databaseConnectionString, query, password);
heartbeat.ping = dayjs().valueOf() - startTime;
heartbeat.msg = result;
}
} catch (error) {
heartbeat.ping = dayjs().valueOf() - startTime;
log.error("mysql", "Database query failed:", error.message);
throw new Error(`Database connection/query failed: ${error.message}`);
} finally {
heartbeat.ping = dayjs().valueOf() - startTime;
}
const conditions = ConditionExpressionGroup.fromMonitor(monitor);
const handleConditions = (data) =>
conditions ? evaluateExpressionGroup(conditions, data) : true;
// Since result is now a single value, pass it directly to conditions
const conditionsResult = handleConditions({ result: String(result) });
if (!conditionsResult) {
throw new Error(`Query result did not meet the specified conditions (${result})`);
}
heartbeat.msg = "";
heartbeat.status = UP;
}
/**
* Run a query on MySQL/MariaDB
* Run a query on MySQL/MariaDB (backwards compatible - returns row count)
* @param {string} connectionString The database connection string
* @param {string} query The query to execute
* @param {string} password Optional password override
* @returns {Promise<string>} Row count message
*/
mysqlQuery(connectionString, query, password = undefined) {
return new Promise((resolve, reject) => {
const connection = mysql.createConnection({
uri: connectionString,
password
});
connection.on("error", (err) => {
reject(err);
});
connection.query(query, (err, res) => {
try {
connection.end();
} catch (_) {
connection.destroy();
}
if (err) {
reject(err);
return;
}
if (Array.isArray(res)) {
resolve("Rows: " + res.length);
} else {
resolve("No Error, but the result is not an array. Type: " + typeof res);
}
});
});
}
/**
* Run a query on MySQL/MariaDB expecting a single value result
* @param {string} connectionString The database connection string
* @param {string} query The query to execute
* @param {string} password Optional password override
* @returns {Promise<any>} Single value from the first column of the first row
*/
mysqlQuery(connectionString, query, password = undefined) {
mysqlQuerySingleValue(connectionString, query, password = undefined) {
return new Promise((resolve, reject) => {
const connection = mysql.createConnection({
uri: connectionString,

View File

@@ -6,12 +6,19 @@ const { UP, PENDING } = require("../../../src/util");
/**
* Helper function to create and start a MariaDB container
* @returns {Promise<MariaDbContainer>} The started MariaDB container
* @returns {Promise<{container: MariaDbContainer, connectionString: string}>} The started container and connection string
*/
async function createAndStartMariaDBContainer() {
return await new MariaDbContainer("mariadb:10.11")
const container = await new MariaDbContainer("mariadb:10.11")
.withStartupTimeout(90000)
.start();
const connectionString = `mysql://${container.getUsername()}:${container.getUserPassword()}@${container.getHost()}:${container.getPort()}/${container.getDatabase()}`;
return {
container,
connectionString
};
}
describe(
@@ -23,11 +30,11 @@ describe(
},
() => {
test("check() sets status to UP when MariaDB server is reachable", async () => {
const mariadbContainer = await createAndStartMariaDBContainer();
const { container, connectionString } = await createAndStartMariaDBContainer();
const mysqlMonitor = new MysqlMonitorType();
const monitor = {
databaseConnectionString: `mysql://${mariadbContainer.getUsername()}:${mariadbContainer.getUserPassword()}@${mariadbContainer.getHost()}:${mariadbContainer.getPort()}/${mariadbContainer.getDatabase()}`,
databaseConnectionString: connectionString,
conditions: "[]",
};
@@ -44,7 +51,7 @@ describe(
`Expected status ${UP} but got ${heartbeat.status}`
);
} finally {
await mariadbContainer.stop();
await container.stop();
}
});
@@ -79,11 +86,11 @@ describe(
});
test("check() sets status to UP when custom query result meets condition", async () => {
const mariadbContainer = await createAndStartMariaDBContainer();
const { container, connectionString } = await createAndStartMariaDBContainer();
const mysqlMonitor = new MysqlMonitorType();
const monitor = {
databaseConnectionString: `mysql://${mariadbContainer.getUsername()}:${mariadbContainer.getUserPassword()}@${mariadbContainer.getHost()}:${mariadbContainer.getPort()}/${mariadbContainer.getDatabase()}`,
databaseConnectionString: connectionString,
databaseQuery: "SELECT 42 AS value",
conditions: JSON.stringify([
{
@@ -109,16 +116,16 @@ describe(
`Expected status ${UP} but got ${heartbeat.status}`
);
} finally {
await mariadbContainer.stop();
await container.stop();
}
});
test("check() rejects when custom query result does not meet condition", async () => {
const mariadbContainer = await createAndStartMariaDBContainer();
const { container, connectionString } = await createAndStartMariaDBContainer();
const mysqlMonitor = new MysqlMonitorType();
const monitor = {
databaseConnectionString: `mysql://${mariadbContainer.getUsername()}:${mariadbContainer.getUserPassword()}@${mariadbContainer.getHost()}:${mariadbContainer.getPort()}/${mariadbContainer.getDatabase()}`,
databaseConnectionString: connectionString,
databaseQuery: "SELECT 99 AS value",
conditions: JSON.stringify([
{
@@ -149,7 +156,7 @@ describe(
`Expected status should not be ${heartbeat.status}`
);
} finally {
await mariadbContainer.stop();
await container.stop();
}
});
}