Skip to main content

dejavu/store/
models.rs

1//! Row structs for `runs` and `sessions`.
2
3use rusqlite::Row;
4
5/// One captured command run. Mirrors the `runs` table (spec §15.1) plus
6/// `overhead_ms`. `classification`/`comparison_result` are stored as strings.
7#[derive(Debug, Clone)]
8pub struct RunRecord {
9    pub id: String,
10    pub session_id: String,
11    pub created_at: String,
12    pub repo_root: String,
13    pub cwd: String,
14    pub shim_name: String,
15    pub argv_json: String,
16    pub command_original: String,
17    pub command_family: String,
18    pub command_key: String,
19    pub classification: String,
20    pub exit_code: i64,
21    pub duration_ms: i64,
22    pub overhead_ms: i64,
23    pub stdout_path: Option<String>,
24    pub stderr_path: Option<String>,
25    pub normalized_path: Option<String>,
26    pub raw_stdout_bytes: i64,
27    pub raw_stderr_bytes: i64,
28    pub raw_total_bytes: i64,
29    pub emitted_bytes: i64,
30    pub estimated_raw_tokens: i64,
31    pub estimated_emitted_tokens: i64,
32    pub estimated_saved_tokens: i64,
33    pub normalized_hash: Option<String>,
34    pub stdout_hash: Option<String>,
35    pub stderr_hash: Option<String>,
36    pub git_head: Option<String>,
37    pub git_worktree_hash: Option<String>,
38    pub comparison_base_run_id: Option<String>,
39    pub comparison_result: String,
40    pub summary: Option<String>,
41    pub full_output_requested: i64,
42    pub internal_error: Option<String>,
43}
44
45impl RunRecord {
46    pub fn from_row(row: &Row<'_>) -> rusqlite::Result<RunRecord> {
47        Ok(RunRecord {
48            id: row.get("id")?,
49            session_id: row.get("session_id")?,
50            created_at: row.get("created_at")?,
51            repo_root: row.get("repo_root")?,
52            cwd: row.get("cwd")?,
53            shim_name: row.get("shim_name")?,
54            argv_json: row.get("argv_json")?,
55            command_original: row.get("command_original")?,
56            command_family: row.get("command_family")?,
57            command_key: row.get("command_key")?,
58            classification: row.get("classification")?,
59            exit_code: row.get("exit_code")?,
60            duration_ms: row.get("duration_ms")?,
61            overhead_ms: row.get("overhead_ms")?,
62            stdout_path: row.get("stdout_path")?,
63            stderr_path: row.get("stderr_path")?,
64            normalized_path: row.get("normalized_path")?,
65            raw_stdout_bytes: row.get("raw_stdout_bytes")?,
66            raw_stderr_bytes: row.get("raw_stderr_bytes")?,
67            raw_total_bytes: row.get("raw_total_bytes")?,
68            emitted_bytes: row.get("emitted_bytes")?,
69            estimated_raw_tokens: row.get("estimated_raw_tokens")?,
70            estimated_emitted_tokens: row.get("estimated_emitted_tokens")?,
71            estimated_saved_tokens: row.get("estimated_saved_tokens")?,
72            normalized_hash: row.get("normalized_hash")?,
73            stdout_hash: row.get("stdout_hash")?,
74            stderr_hash: row.get("stderr_hash")?,
75            git_head: row.get("git_head")?,
76            git_worktree_hash: row.get("git_worktree_hash")?,
77            comparison_base_run_id: row.get("comparison_base_run_id")?,
78            comparison_result: row.get("comparison_result")?,
79            summary: row.get("summary")?,
80            full_output_requested: row.get("full_output_requested")?,
81            internal_error: row.get("internal_error")?,
82        })
83    }
84}
85
86/// One agent session. Mirrors the `sessions` table (spec §15.2).
87#[derive(Debug, Clone)]
88pub struct SessionRecord {
89    pub id: String,
90    pub created_at: String,
91    pub ended_at: Option<String>,
92    pub repo_root: String,
93    pub agent_command: String,
94    pub raw_tokens_total: i64,
95    pub emitted_tokens_total: i64,
96    pub saved_tokens_total: i64,
97}