sqlx prepare, bunch of nits

This commit is contained in:
durch
2025-05-15 13:28:30 +02:00
parent 770078a9ed
commit 3be9e06bef
5 changed files with 108 additions and 114 deletions
@@ -1,26 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n d.node_id as \"node_id: NodeId\",\n CASE WHEN count(*) > 3 THEN AVG(reliability) ELSE 100 END as \"value: f32\"\n FROM\n gateway_details d\n JOIN\n gateway_status s on d.id = s.gateway_details_id\n WHERE\n timestamp >= ? AND\n timestamp <= ?\n GROUP BY 1\n ",
"describe": {
"columns": [
{
"name": "node_id: NodeId",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "value: f32",
"ordinal": 1,
"type_info": "Int"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
true
]
},
"hash": "676299beb2004ab89f7b38cf21ffb84ab5e7d7435297573523e2532560c2e302"
}
@@ -0,0 +1,44 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n layer1 as \"layer1\",\n layer2 as \"layer2\",\n layer3 as \"layer3\",\n gw as \"gw\",\n success\n FROM routes\n WHERE timestamp >= ? AND timestamp <= ?\n ORDER BY timestamp ASC\n ",
"describe": {
"columns": [
{
"name": "layer1",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "layer2",
"ordinal": 1,
"type_info": "Int64"
},
{
"name": "layer3",
"ordinal": 2,
"type_info": "Int64"
},
{
"name": "gw",
"ordinal": 3,
"type_info": "Int64"
},
{
"name": "success",
"ordinal": 4,
"type_info": "Bool"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
false,
false
]
},
"hash": "6b2479c02cf1ef5ae674ce0ab4d027595b91739f3579e1f289b0c722ea91bbcc"
}
@@ -1,26 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n d.mix_id as \"mix_id: NodeId\",\n AVG(s.reliability) as \"value: f32\"\n FROM\n mixnode_details d\n JOIN\n mixnode_status s on d.id = s.mixnode_details_id\n WHERE\n timestamp >= ? AND\n timestamp <= ?\n GROUP BY 1\n ",
"describe": {
"columns": [
{
"name": "mix_id: NodeId",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "value: f32",
"ordinal": 1,
"type_info": "Int64"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
true
]
},
"hash": "c19e1b3768bf2929407599e6e8783ead09f4d7319b7997fa2a9bb628f9404166"
}
@@ -1,16 +1,17 @@
-- Drop the table if it exists
DROP TABLE IF EXISTS routes;
-- Create the routes table
CREATE TABLE routes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
layer1 INTEGER,
layer2 INTEGER,
layer3 INTEGER,
gw INTEGER,
success BOOLEAN
-- Add routes table for storing route metrics data
CREATE TABLE IF NOT EXISTS routes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
layer1 INTEGER NOT NULL, -- NodeId of layer 1 mixnode
layer2 INTEGER NOT NULL, -- NodeId of layer 2 mixnode
layer3 INTEGER NOT NULL, -- NodeId of layer 3 mixnode
gw INTEGER NOT NULL, -- NodeId of gateway
success BOOLEAN NOT NULL, -- Whether the packet was delivered successfully
timestamp INTEGER NOT NULL DEFAULT (unixepoch()) -- When the measurement was taken
);
-- Create an index on created_at
CREATE INDEX routes_created_at ON routes(created_at);
-- Add indexes for efficient querying
CREATE INDEX IF NOT EXISTS idx_routes_timestamp ON routes(timestamp);
CREATE INDEX IF NOT EXISTS idx_routes_layer1 ON routes(layer1);
CREATE INDEX IF NOT EXISTS idx_routes_layer2 ON routes(layer2);
CREATE INDEX IF NOT EXISTS idx_routes_layer3 ON routes(layer3);
CREATE INDEX IF NOT EXISTS idx_routes_gw ON routes(gw);
+49 -48
View File
@@ -96,27 +96,25 @@ impl StorageManager {
start_ts_secs: i64,
end_ts_secs: i64,
) -> Result<Vec<AvgMixnodeReliability>, sqlx::Error> {
let result = sqlx::query_as!(
AvgMixnodeReliability,
r#"
SELECT
d.mix_id as "mix_id: NodeId",
AVG(s.reliability) as "value: f32"
FROM
mixnode_details d
JOIN
mixnode_status s on d.id = s.mixnode_details_id
WHERE
timestamp >= ? AND
timestamp <= ?
GROUP BY 1
"#,
start_ts_secs,
end_ts_secs
)
.fetch_all(&self.connection_pool)
.await?;
Ok(result)
let corrected_reliabilities = self
.calculate_corrected_node_reliabilities_for_interval(start_ts_secs, end_ts_secs)
.await
.map_err(|_e| sqlx::Error::PoolClosed)?; // Example: map anyhow::Error to sqlx::Error; adjust as needed
let mut avg_mix_reliabilities = Vec::new();
for corrected_node_info in corrected_reliabilities {
// Check if this node_id is a mixnode by attempting to fetch its identity key as a mixnode.
// This relies on get_mixnode_identity_key returning Some for mixnodes and None (or error) for non-mixnodes.
if self.get_mixnode_identity_key(corrected_node_info.node_id).await?.is_some() {
avg_mix_reliabilities.push(AvgMixnodeReliability {
mix_id: corrected_node_info.node_id,
value: Some(corrected_node_info.reliability as f32),
});
}
}
Ok(avg_mix_reliabilities)
}
pub(super) async fn get_all_avg_gateway_reliability_in_interval(
@@ -124,27 +122,30 @@ impl StorageManager {
start_ts_secs: i64,
end_ts_secs: i64,
) -> Result<Vec<AvgGatewayReliability>, sqlx::Error> {
let result = sqlx::query_as!(
AvgGatewayReliability,
r#"
SELECT
d.node_id as "node_id: NodeId",
CASE WHEN count(*) > 3 THEN AVG(reliability) ELSE 100 END as "value: f32"
FROM
gateway_details d
JOIN
gateway_status s on d.id = s.gateway_details_id
WHERE
timestamp >= ? AND
timestamp <= ?
GROUP BY 1
"#,
start_ts_secs,
end_ts_secs
)
.fetch_all(&self.connection_pool)
.await?;
Ok(result)
let corrected_reliabilities = self
.calculate_corrected_node_reliabilities_for_interval(start_ts_secs, end_ts_secs)
.await
.map_err(|_e| sqlx::Error::PoolClosed)?; // Example: map anyhow::Error to sqlx::Error; adjust as needed
let mut avg_gateway_reliabilities = Vec::new();
for corrected_node_info in corrected_reliabilities {
// Check if this node_id is a gateway.
if self.get_gateway_identity_key(corrected_node_info.node_id).await?.is_some() {
let total_samples = corrected_node_info.pos_samples_in_interval + corrected_node_info.neg_samples_in_interval;
let reliability_value = if total_samples <= 3 {
100.0 // Default to 100% if 3 or fewer samples
} else {
corrected_node_info.reliability as f32
};
avg_gateway_reliabilities.push(AvgGatewayReliability {
node_id: corrected_node_info.node_id, // AvgGatewayReliability uses node_id
value: Some(reliability_value),
});
}
}
Ok(avg_gateway_reliabilities)
}
/// Tries to obtain row id of given mixnode given its identity.
@@ -1387,11 +1388,11 @@ impl StorageManager {
// Temporary struct to match the expected columns from the 'routes' table
// NodeId here is assumed to be compatible with how layer1, etc. are stored (e.g. u32/i32/i64)
struct RawRouteData {
layer1: NodeId,
layer2: NodeId,
layer3: NodeId,
gw: NodeId,
success: bool,
layer1: i64,
layer2: i64,
layer3: i64,
gw: i64,
success: Option<bool>,
// timestamp: i64, // Not explicitly selected into struct, but used in WHERE and ORDER BY
}
@@ -1420,7 +1421,7 @@ impl StorageManager {
Ok(db_routes
.into_iter()
.map(|r| (r.layer1, r.layer2, r.layer3, r.gw, r.success))
.map(|r| (r.layer1 as NodeId, r.layer2 as NodeId, r.layer3 as NodeId, r.gw as NodeId, r.success.unwrap_or_default()))
.collect())
}