codex_mobile_bridge/storage/
pending_requests.rs1use rusqlite::{OptionalExtension, params};
2
3use super::Storage;
4use super::decode::decode_json_row;
5use crate::bridge_protocol::PendingServerRequestRecord;
6
7impl Storage {
8 pub fn put_pending_request(&self, request: &PendingServerRequestRecord) -> anyhow::Result<()> {
9 let conn = self.connect()?;
10 conn.execute(
11 "INSERT INTO pending_server_requests (
12 request_id, runtime_id, request_type, thread_id, turn_id, item_id, title,
13 reason, command, cwd, grant_root, tool_name, arguments, questions,
14 proposed_execpolicy_amendment, network_approval_context, schema,
15 available_decisions, raw_payload, created_at_ms, raw_json
16 )
17 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21)
18 ON CONFLICT(request_id) DO UPDATE SET
19 runtime_id = excluded.runtime_id,
20 request_type = excluded.request_type,
21 thread_id = excluded.thread_id,
22 turn_id = excluded.turn_id,
23 item_id = excluded.item_id,
24 title = excluded.title,
25 reason = excluded.reason,
26 command = excluded.command,
27 cwd = excluded.cwd,
28 grant_root = excluded.grant_root,
29 tool_name = excluded.tool_name,
30 arguments = excluded.arguments,
31 questions = excluded.questions,
32 proposed_execpolicy_amendment = excluded.proposed_execpolicy_amendment,
33 network_approval_context = excluded.network_approval_context,
34 schema = excluded.schema,
35 available_decisions = excluded.available_decisions,
36 raw_payload = excluded.raw_payload,
37 created_at_ms = excluded.created_at_ms,
38 raw_json = excluded.raw_json",
39 params![
40 request.request_id,
41 request.runtime_id,
42 request.request_type,
43 request.thread_id,
44 request.turn_id,
45 request.item_id,
46 request.title,
47 request.reason,
48 request.command,
49 request.cwd,
50 request.grant_root,
51 request.tool_name,
52 request.arguments.as_ref().map(serde_json::to_string).transpose()?,
53 serde_json::to_string(&request.questions)?,
54 request
55 .proposed_execpolicy_amendment
56 .as_ref()
57 .map(serde_json::to_string)
58 .transpose()?,
59 request
60 .network_approval_context
61 .as_ref()
62 .map(serde_json::to_string)
63 .transpose()?,
64 request.schema.as_ref().map(serde_json::to_string).transpose()?,
65 serde_json::to_string(&request.available_decisions)?,
66 serde_json::to_string(&request.raw_payload)?,
67 request.created_at_ms,
68 serde_json::to_string(request)?
69 ],
70 )?;
71 Ok(())
72 }
73
74 pub fn get_pending_request(
75 &self,
76 request_id: &str,
77 ) -> anyhow::Result<Option<PendingServerRequestRecord>> {
78 let conn = self.connect()?;
79 let record = conn
80 .query_row(
81 "SELECT raw_json FROM pending_server_requests WHERE request_id = ?1",
82 params![request_id],
83 |row| {
84 let raw: String = row.get(0)?;
85 decode_json_row(raw)
86 },
87 )
88 .optional()?;
89 Ok(record)
90 }
91
92 pub fn list_pending_requests(&self) -> anyhow::Result<Vec<PendingServerRequestRecord>> {
93 let conn = self.connect()?;
94 let mut stmt = conn.prepare(
95 "SELECT raw_json
96 FROM pending_server_requests
97 ORDER BY created_at_ms ASC",
98 )?;
99
100 let rows = stmt.query_map([], |row| {
101 let raw: String = row.get(0)?;
102 decode_json_row(raw)
103 })?;
104
105 Ok(rows.collect::<rusqlite::Result<Vec<_>>>()?)
106 }
107
108 pub fn remove_pending_request(&self, request_id: &str) -> anyhow::Result<()> {
109 let conn = self.connect()?;
110 conn.execute(
111 "DELETE FROM pending_server_requests WHERE request_id = ?1",
112 params![request_id],
113 )?;
114 Ok(())
115 }
116
117 pub fn clear_pending_requests(&self) -> anyhow::Result<()> {
118 let conn = self.connect()?;
119 conn.execute("DELETE FROM pending_server_requests", [])?;
120 Ok(())
121 }
122}