use anyhow::Result;
use rusqlite::Connection;
use crate::state::session::SessionActivityState;
pub(crate) fn read(conn: &Connection) -> Result<Option<SessionActivityState>> {
let mut stmt = conn.prepare(
"SELECT session_id, actor_id, current_activity, updated_at_epoch_s, session_revision
FROM session_activity WHERE id = 1",
)?;
let result = stmt.query_row([], |row| {
Ok(SessionActivityState {
session_id: row.get(0)?,
actor_id: row.get(1)?,
current_activity: row.get(2)?,
updated_at_epoch_s: row.get(3)?,
session_revision: row.get(4)?,
})
});
match result {
Ok(state) => Ok(Some(state)),
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
Err(error) => Err(error.into()),
}
}
pub(crate) fn write(conn: &Connection, state: &SessionActivityState) -> Result<()> {
conn.execute(
"INSERT OR REPLACE INTO session_activity
(id, session_id, actor_id, current_activity, updated_at_epoch_s, session_revision)
VALUES (1, ?1, ?2, ?3, ?4, ?5)",
rusqlite::params![
&state.session_id,
&state.actor_id,
&state.current_activity,
state.updated_at_epoch_s,
state.session_revision,
],
)?;
Ok(())
}
pub(crate) fn delete(conn: &Connection) -> Result<()> {
conn.execute("DELETE FROM session_activity WHERE id = 1", [])?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::db::schema;
fn test_conn() -> Connection {
let conn = Connection::open_in_memory().unwrap();
schema::initialize(&conn, None).unwrap();
conn
}
#[test]
fn read_returns_none_when_empty() {
let conn = test_conn();
assert!(read(&conn).unwrap().is_none());
}
#[test]
fn write_and_read_roundtrip() {
let conn = test_conn();
let state = SessionActivityState {
session_id: "ses_01ABC".to_owned(),
actor_id: "runtime/worker-1".to_owned(),
current_activity: "running tests".to_owned(),
updated_at_epoch_s: 1_000_000,
session_revision: 2,
};
write(&conn, &state).unwrap();
let loaded = read(&conn).unwrap().expect("should exist");
assert_eq!(loaded, state);
}
#[test]
fn delete_removes_activity() {
let conn = test_conn();
write(
&conn,
&SessionActivityState {
session_id: "ses_01ABC".to_owned(),
actor_id: "runtime/worker-1".to_owned(),
current_activity: "running tests".to_owned(),
updated_at_epoch_s: 1_000_000,
session_revision: 2,
},
)
.unwrap();
delete(&conn).unwrap();
assert!(read(&conn).unwrap().is_none());
}
}