mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-10-06 13:44:21 +08:00
112 lines
3.6 KiB
Rust
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(())
|
|
}
|
|
}
|