mirror of
https://github.com/louislam/uptime-kuma.git
synced 2026-01-31 11:03:11 +08:00
fix: remove duplicate and keep old behavior
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user