Apply rustfmt (toolchain 1.96.0) to satisfy the CI Format check. Co-Authored-By: Claude Opus 4.8 <[email protected]>
74 lines
2.2 KiB
Rust
74 lines
2.2 KiB
Rust
//! Per-node installed dev-tool versions (probed by the daemon) and the latest
|
|
//! upstream version per tool (filled by a nightly checker). Drives the fleet
|
|
//! UI's "update available" badges.
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use cm_domain::NodeId;
|
|
use sqlx::{PgPool, Row};
|
|
|
|
use crate::DbError;
|
|
|
|
/// Replace a node's reported tool versions with `tools` (tool, version).
|
|
pub async fn upsert(
|
|
pool: &PgPool,
|
|
node_id: NodeId,
|
|
tools: &[(String, String)],
|
|
) -> Result<(), DbError> {
|
|
for (tool, version) in tools {
|
|
sqlx::query(
|
|
"INSERT INTO node_tools (node_id, tool, version, updated_at)
|
|
VALUES ($1, $2, $3, now())
|
|
ON CONFLICT (node_id, tool) DO UPDATE SET version = excluded.version, updated_at = now()",
|
|
)
|
|
.bind(node_id.as_uuid())
|
|
.bind(tool)
|
|
.bind(version)
|
|
.execute(pool)
|
|
.await?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// A node's installed tool versions as `(tool, version)`.
|
|
pub async fn list(pool: &PgPool, node_id: NodeId) -> Result<Vec<(String, String)>, DbError> {
|
|
let rows = sqlx::query("SELECT tool, version FROM node_tools WHERE node_id = $1")
|
|
.bind(node_id.as_uuid())
|
|
.fetch_all(pool)
|
|
.await?;
|
|
Ok(rows
|
|
.into_iter()
|
|
.map(|r| (r.get::<String, _>("tool"), r.get::<String, _>("version")))
|
|
.collect())
|
|
}
|
|
|
|
/// Record the latest upstream version for a tool.
|
|
pub async fn set_latest(pool: &PgPool, tool: &str, latest: &str) -> Result<(), DbError> {
|
|
sqlx::query(
|
|
"INSERT INTO tool_latest (tool, latest_version, checked_at)
|
|
VALUES ($1, $2, now())
|
|
ON CONFLICT (tool) DO UPDATE SET latest_version = excluded.latest_version, checked_at = now()",
|
|
)
|
|
.bind(tool)
|
|
.bind(latest)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// All known latest versions, keyed by tool.
|
|
pub async fn all_latest(pool: &PgPool) -> Result<HashMap<String, String>, DbError> {
|
|
let rows = sqlx::query("SELECT tool, latest_version FROM tool_latest")
|
|
.fetch_all(pool)
|
|
.await?;
|
|
Ok(rows
|
|
.into_iter()
|
|
.map(|r| {
|
|
(
|
|
r.get::<String, _>("tool"),
|
|
r.get::<String, _>("latest_version"),
|
|
)
|
|
})
|
|
.collect())
|
|
}
|