Skip to main content

kaizen/extensions/
diffs.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3use crate::store::Store;
4use anyhow::Result;
5use rusqlite::params;
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
9pub struct StepDiff {
10    pub session_id: String,
11    pub span_id: String,
12    pub files: Vec<String>,
13    pub added_lines: u64,
14    pub removed_lines: u64,
15    pub raw_patch_stored: bool,
16}
17
18pub fn refresh_session(
19    store: &Store,
20    session_id: &str,
21    capture_raw_patch: bool,
22) -> Result<Vec<StepDiff>> {
23    let rows: Vec<StepDiff> = store
24        .tool_spans_for_session(session_id)?
25        .into_iter()
26        .filter(|span| !span.paths.is_empty())
27        .map(|span| StepDiff {
28            session_id: session_id.to_string(),
29            span_id: span.span_id,
30            files: span.paths,
31            added_lines: 0,
32            removed_lines: 0,
33            raw_patch_stored: capture_raw_patch,
34        })
35        .collect();
36    store
37        .conn()
38        .execute("DELETE FROM step_diffs WHERE session_id = ?1", [session_id])?;
39    rows.iter().try_for_each(|row| insert(store, row))?;
40    Ok(rows)
41}
42
43fn insert(store: &Store, row: &StepDiff) -> Result<()> {
44    let files_json = serde_json::to_string(&row.files)?;
45    store.conn().execute(
46        "INSERT OR REPLACE INTO step_diffs(
47            session_id, span_id, files_json, added_lines, removed_lines, raw_patch
48         ) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
49        params![
50            row.session_id,
51            row.span_id,
52            files_json,
53            row.added_lines as i64,
54            row.removed_lines as i64,
55            Option::<String>::None,
56        ],
57    )?;
58    Ok(())
59}