coven_database/
store_reclaim_records.rs1use super::*;
2
3pub fn store_reclaim_journal_error(error: StoreReclaimJournalError) -> DbError {
4 DbError::from(error)
5}
6
7pub fn parse_store_reclaim_operation(
8 operation_id: ObjectHash,
9 raw: &str,
10) -> Result<DurableStoreReclaimOperation, DbError> {
11 let operation: DurableStoreReclaimOperation = serde_json::from_str(raw).map_err(|error| {
12 DbError::context(
13 format!("Store reclaim operation {operation_id} has invalid durable state"),
14 error,
15 )
16 })?;
17 operation.validate().map_err(store_reclaim_journal_error)?;
18 if operation.operation_id() != operation_id {
19 return Err(DbError::Message(format!(
20 "Store reclaim operation key {operation_id} differs from its authorization {}",
21 operation.operation_id()
22 )));
23 }
24 Ok(operation)
25}
26
27pub(crate) fn load_store_reclaim_operation_on(
28 conn: &Connection,
29 operation_id: ObjectHash,
30) -> Result<Option<DurableStoreReclaimOperation>, DbError> {
31 conn.query_row(
32 "SELECT state FROM store_reclaim_operations WHERE authorization_hash = ?1",
33 [operation_id.to_string()],
34 |row| row.get::<_, String>(0),
35 )
36 .optional()
37 .map_err(DbError::from)?
38 .map(|raw| parse_store_reclaim_operation(operation_id, &raw))
39 .transpose()
40}
41
42pub(crate) fn insert_store_reclaim_operation_on(
43 conn: &Connection,
44 operation: &DurableStoreReclaimOperation,
45) -> Result<(), DbError> {
46 operation.validate().map_err(store_reclaim_journal_error)?;
47 let state = serde_json::to_string(operation)
48 .map_err(|error| DbError::context("serialize Store reclaim operation", error))?;
49 conn.execute(
50 "INSERT INTO store_reclaim_operations (authorization_hash, state) VALUES (?1, ?2)",
51 (operation.operation_id().to_string(), state),
52 )
53 .map(|_| ())
54 .map_err(DbError::from)
55}
56
57pub(crate) fn mark_store_reclaim_operation_stuck_on(
59 conn: &Connection,
60 operation_id: ObjectHash,
61 error: &str,
62) -> Result<(), DbError> {
63 let error = if error.trim().is_empty() {
66 format!("Store reclaim operation {operation_id} failed without a message")
67 } else {
68 error.to_string()
69 };
70 let updated = conn
71 .execute(
72 "UPDATE store_reclaim_operations SET stuck_error = ?2 WHERE authorization_hash = ?1",
73 (operation_id.to_string(), error),
74 )
75 .map_err(DbError::from)?;
76 if updated != 1 {
77 return Err(DbError::Message(format!(
78 "Store reclaim operation {operation_id} is absent and cannot be marked stuck"
79 )));
80 }
81 Ok(())
82}
83
84pub(crate) fn clear_store_reclaim_operation_stuck_on(
88 conn: &Connection,
89 operation_id: ObjectHash,
90) -> Result<(), DbError> {
91 let updated = conn
92 .execute(
93 "UPDATE store_reclaim_operations SET stuck_error = NULL
94 WHERE authorization_hash = ?1 AND stuck_error IS NOT NULL",
95 [operation_id.to_string()],
96 )
97 .map_err(DbError::from)?;
98 if updated != 1 {
99 return Err(DbError::Message(format!(
100 "Store reclaim operation {operation_id} is not stuck"
101 )));
102 }
103 Ok(())
104}
105
106pub(crate) fn update_store_reclaim_operation_on(
107 conn: &Connection,
108 expected: &DurableStoreReclaimOperation,
109 next: &DurableStoreReclaimOperation,
110) -> Result<(), DbError> {
111 expected.validate().map_err(store_reclaim_journal_error)?;
112 next.validate().map_err(store_reclaim_journal_error)?;
113 if expected.operation_id() != next.operation_id() {
114 return Err(DbError::Message(
115 "Store reclaim transition changes its authorization identity".to_string(),
116 ));
117 }
118 let expected_state = serde_json::to_string(expected)
119 .map_err(|error| DbError::context("serialize expected Store reclaim state", error))?;
120 let next_state = serde_json::to_string(next)
121 .map_err(|error| DbError::context("serialize next Store reclaim state", error))?;
122 let updated = conn
123 .execute(
124 "UPDATE store_reclaim_operations SET state = ?3
125 WHERE authorization_hash = ?1 AND state = ?2",
126 (
127 expected.operation_id().to_string(),
128 expected_state,
129 next_state,
130 ),
131 )
132 .map_err(DbError::from)?;
133 if updated != 1 {
134 return Err(DbError::Message(
135 "Store reclaim operation changed during transition".to_string(),
136 ));
137 }
138 Ok(())
139}