| 1271 | } |
| 1272 | |
| 1273 | fn del_view(&mut self, view: &ViewState) -> PristineResult<()> { |
| 1274 | // Guard: Shared views cannot be deleted (they own global GRAPH edges). |
| 1275 | if view.kind.is_shared() { |
| 1276 | return Err(PristineError::CannotDeleteSharedView { |
| 1277 | name: view.name.clone(), |
| 1278 | }); |
| 1279 | } |
| 1280 | |
| 1281 | // Guard: Check for child views that reference this view as parent. |
| 1282 | // Deleting a parent would leave children with a dangling parent pointer. |
| 1283 | let children = ViewTxnT::get_children_views(self, view.id)?; |
| 1284 | if !children.is_empty() { |
| 1285 | let child_names: Vec<String> = children.iter().map(|c| c.name.clone()).collect(); |
| 1286 | return Err(PristineError::ViewHasChildren { |
| 1287 | name: view.name.clone(), |
| 1288 | children: child_names, |
| 1289 | }); |
| 1290 | } |
| 1291 | |
| 1292 | // Remove from VIEWS table |
| 1293 | { |
| 1294 | let mut table = self.txn.open_table(VIEWS)?; |
| 1295 | table.remove(view.name.as_str())?; |
| 1296 | } |
| 1297 | |
| 1298 | // Remove all change log entries for this view |
| 1299 | { |
| 1300 | let mut table = self.txn.open_table(VIEW_CHANGES)?; |
| 1301 | for seq in 0..view.change_count { |
| 1302 | let key = encode_view_seq(view.id, seq); |
| 1303 | table.remove(&key)?; |
| 1304 | } |
| 1305 | } |
| 1306 | |
| 1307 | // Remove all reverse change log entries |
| 1308 | { |
| 1309 | let mut rev_table = self.txn.open_table(REV_VIEW_CHANGES)?; |
| 1310 | let table = self.txn.open_table(VIEW_CHANGES)?; |
| 1311 | for seq in 0..view.change_count { |
| 1312 | let key = encode_view_seq(view.id, seq); |
| 1313 | if let Some(change_id) = table.get(&key)? { |
| 1314 | let rev_key = encode_view_seq(view.id, change_id.value()); |
| 1315 | rev_table.remove(&rev_key)?; |
| 1316 | } |
| 1317 | } |
| 1318 | } |
| 1319 | |
| 1320 | // Remove all state/sequence mappings from STATES table |
| 1321 | { |
| 1322 | let mut table = self.txn.open_table(STATES)?; |
| 1323 | let merkle_table = self.txn.open_table(MERKLE_CHAIN)?; |
| 1324 | for seq in 0..view.change_count { |
| 1325 | let key = encode_view_seq(view.id, seq); |
| 1326 | if let Some(merkle_bytes) = merkle_table.get(&key)? { |
| 1327 | let merkle = merkle_bytes.value(); |
| 1328 | let state_key = encode_view_merkle(view.id, merkle); |
| 1329 | table.remove(&state_key)?; |
| 1330 | } |