Files
cursor-byok/server/src/store/storage.rs
T

112 lines
3.6 KiB
Rust

//! Row accounting and cleanup for disposable observability data.
use serde::{Deserialize, Serialize};
use crate::Result;
use super::Store;
#[derive(Clone, Copy, Debug, Default, Serialize)]
pub struct StatisticsStorage {
pub call_count: i64,
pub trace_count: i64,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum StatisticsStorageScope {
#[default]
Details,
All,
}
impl Store {
pub async fn statistics_storage(&self) -> Result<StatisticsStorage> {
let (call_count, trace_count) = sqlx::query_as::<_, (i64, i64)>(
"SELECT (SELECT COUNT(*) FROM llm_calls), (SELECT COUNT(*) FROM cursor_run_traces)",
)
.fetch_one(&self.pool)
.await?;
Ok(StatisticsStorage {
call_count,
trace_count,
})
}
pub async fn clear_statistics_storage(&self) -> Result<StatisticsStorage> {
let _write = self.writes.lock().await;
let mut transaction = self.pool.begin().await?;
Self::clear_detail_storage_tx(&mut transaction).await?;
transaction.commit().await?;
self.statistics_storage().await
}
pub async fn clear_all_statistics_storage(&self) -> Result<StatisticsStorage> {
let _write = self.writes.lock().await;
let mut transaction = self.pool.begin().await?;
Self::clear_trace_artifacts_tx(&mut transaction).await?;
sqlx::query("DELETE FROM llm_calls")
.execute(&mut *transaction)
.await?;
sqlx::query("DELETE FROM cursor_run_traces")
.execute(&mut *transaction)
.await?;
transaction.commit().await?;
self.statistics_storage().await
}
async fn clear_detail_storage_tx(
transaction: &mut sqlx::Transaction<'_, sqlx::Sqlite>,
) -> Result<()> {
sqlx::query("DELETE FROM llm_call_requests")
.execute(&mut **transaction)
.await?;
sqlx::query("DELETE FROM llm_call_response_chunks")
.execute(&mut **transaction)
.await?;
Self::clear_trace_artifacts_tx(transaction).await
}
async fn clear_trace_artifacts_tx(
transaction: &mut sqlx::Transaction<'_, sqlx::Sqlite>,
) -> Result<()> {
sqlx::query(
"CREATE TEMP TABLE IF NOT EXISTS clear_statistics_blob_ids(
blob_id BLOB PRIMARY KEY
)",
)
.execute(&mut **transaction)
.await?;
sqlx::query("DELETE FROM clear_statistics_blob_ids")
.execute(&mut **transaction)
.await?;
sqlx::query(
"INSERT OR IGNORE INTO clear_statistics_blob_ids(blob_id)
SELECT blob_id FROM cursor_run_trace_artifacts",
)
.execute(&mut **transaction)
.await?;
sqlx::query("DELETE FROM cursor_run_trace_artifacts")
.execute(&mut **transaction)
.await?;
sqlx::query(
"DELETE FROM blobs
WHERE blob_id IN (SELECT blob_id FROM clear_statistics_blob_ids)
AND NOT EXISTS (
SELECT 1 FROM cursor_run_trace_artifacts a WHERE a.blob_id = blobs.blob_id
)
AND NOT EXISTS (
SELECT 1 FROM blob_edges e
WHERE e.parent_blob_id = blobs.blob_id OR e.child_blob_id = blobs.blob_id
)",
)
.execute(&mut **transaction)
.await?;
sqlx::query("DROP TABLE clear_statistics_blob_ids")
.execute(&mut **transaction)
.await?;
Ok(())
}
}