use rusqlite::{OptionalExtension, params};
use super::Storage;
use super::decode::decode_json_row;
use crate::bridge_protocol::PendingServerRequestRecord;
impl Storage {
pub fn put_pending_request(&self, request: &PendingServerRequestRecord) -> anyhow::Result<()> {
let conn = self.connect()?;
conn.execute(
"INSERT INTO pending_server_requests (
request_id, runtime_id, request_type, thread_id, turn_id, item_id, title,
reason, command, cwd, grant_root, tool_name, arguments, questions,
proposed_execpolicy_amendment, network_approval_context, schema,
available_decisions, raw_payload, created_at_ms, raw_json
)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21)
ON CONFLICT(request_id) DO UPDATE SET
runtime_id = excluded.runtime_id,
request_type = excluded.request_type,
thread_id = excluded.thread_id,
turn_id = excluded.turn_id,
item_id = excluded.item_id,
title = excluded.title,
reason = excluded.reason,
command = excluded.command,
cwd = excluded.cwd,
grant_root = excluded.grant_root,
tool_name = excluded.tool_name,
arguments = excluded.arguments,
questions = excluded.questions,
proposed_execpolicy_amendment = excluded.proposed_execpolicy_amendment,
network_approval_context = excluded.network_approval_context,
schema = excluded.schema,
available_decisions = excluded.available_decisions,
raw_payload = excluded.raw_payload,
created_at_ms = excluded.created_at_ms,
raw_json = excluded.raw_json",
params![
request.request_id,
request.runtime_id,
request.request_type,
request.thread_id,
request.turn_id,
request.item_id,
request.title,
request.reason,
request.command,
request.cwd,
request.grant_root,
request.tool_name,
request.arguments.as_ref().map(serde_json::to_string).transpose()?,
serde_json::to_string(&request.questions)?,
request
.proposed_execpolicy_amendment
.as_ref()
.map(serde_json::to_string)
.transpose()?,
request
.network_approval_context
.as_ref()
.map(serde_json::to_string)
.transpose()?,
request.schema.as_ref().map(serde_json::to_string).transpose()?,
serde_json::to_string(&request.available_decisions)?,
serde_json::to_string(&request.raw_payload)?,
request.created_at_ms,
serde_json::to_string(request)?
],
)?;
Ok(())
}
pub fn get_pending_request(
&self,
request_id: &str,
) -> anyhow::Result<Option<PendingServerRequestRecord>> {
let conn = self.connect()?;
let record = conn
.query_row(
"SELECT raw_json FROM pending_server_requests WHERE request_id = ?1",
params![request_id],
|row| {
let raw: String = row.get(0)?;
decode_json_row(raw)
},
)
.optional()?;
Ok(record)
}
pub fn list_pending_requests(&self) -> anyhow::Result<Vec<PendingServerRequestRecord>> {
let conn = self.connect()?;
let mut stmt = conn.prepare(
"SELECT raw_json
FROM pending_server_requests
ORDER BY created_at_ms ASC",
)?;
let rows = stmt.query_map([], |row| {
let raw: String = row.get(0)?;
decode_json_row(raw)
})?;
Ok(rows.collect::<rusqlite::Result<Vec<_>>>()?)
}
pub fn remove_pending_request(&self, request_id: &str) -> anyhow::Result<()> {
let conn = self.connect()?;
conn.execute(
"DELETE FROM pending_server_requests WHERE request_id = ?1",
params![request_id],
)?;
Ok(())
}
pub fn clear_pending_requests(&self) -> anyhow::Result<()> {
let conn = self.connect()?;
conn.execute("DELETE FROM pending_server_requests", [])?;
Ok(())
}
}