1use crate::DbHash;
22use codec::{Decode, Encode};
23use sp_blockchain;
24use sp_database::{Database, Transaction};
25use std::hash::Hash;
26
27pub fn read_children<
29 K: Eq + Hash + Clone + Encode + Decode,
30 V: Eq + Hash + Clone + Encode + Decode,
31>(
32 db: &dyn Database<DbHash>,
33 column: u32,
34 prefix: &[u8],
35 parent_hash: K,
36) -> sp_blockchain::Result<Vec<V>> {
37 let mut buf = prefix.to_vec();
38 parent_hash.using_encoded(|s| buf.extend(s));
39
40 let raw_val_opt = db.get(column, &buf[..]);
41
42 let raw_val = match raw_val_opt {
43 Some(val) => val,
44 None => return Ok(Vec::new()),
45 };
46
47 let children: Vec<V> = match Decode::decode(&mut &raw_val[..]) {
48 Ok(children) => children,
49 Err(_) => return Err(sp_blockchain::Error::Backend("Error decoding children".into())),
50 };
51
52 Ok(children)
53}
54
55pub fn write_children<
58 K: Eq + Hash + Clone + Encode + Decode,
59 V: Eq + Hash + Clone + Encode + Decode,
60>(
61 tx: &mut Transaction<DbHash>,
62 column: u32,
63 prefix: &[u8],
64 parent_hash: K,
65 children_hashes: V,
66) {
67 let mut key = prefix.to_vec();
68 parent_hash.using_encoded(|s| key.extend(s));
69 tx.set_from_vec(column, &key[..], children_hashes.encode());
70}
71
72pub fn remove_children<K: Eq + Hash + Clone + Encode + Decode>(
74 tx: &mut Transaction<DbHash>,
75 column: u32,
76 prefix: &[u8],
77 parent_hash: K,
78) {
79 let mut key = prefix.to_vec();
80 parent_hash.using_encoded(|s| key.extend(s));
81 tx.remove(column, &key);
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use std::sync::Arc;
88
89 #[test]
90 fn children_write_read_remove() {
91 const PREFIX: &[u8] = b"children";
92 let db = Arc::new(sp_database::MemDb::default());
93
94 let mut tx = Transaction::new();
95
96 let mut children1 = Vec::new();
97 children1.push(1_3);
98 children1.push(1_5);
99 write_children(&mut tx, 0, PREFIX, 1_1, children1);
100
101 let mut children2 = Vec::new();
102 children2.push(1_4);
103 children2.push(1_6);
104 write_children(&mut tx, 0, PREFIX, 1_2, children2);
105
106 db.commit(tx.clone()).unwrap();
107
108 let r1: Vec<u32> = read_children(&*db, 0, PREFIX, 1_1).expect("(1) Getting r1 failed");
109 let r2: Vec<u32> = read_children(&*db, 0, PREFIX, 1_2).expect("(1) Getting r2 failed");
110
111 assert_eq!(r1, vec![1_3, 1_5]);
112 assert_eq!(r2, vec![1_4, 1_6]);
113
114 remove_children(&mut tx, 0, PREFIX, 1_2);
115 db.commit(tx).unwrap();
116
117 let r1: Vec<u32> = read_children(&*db, 0, PREFIX, 1_1).expect("(2) Getting r1 failed");
118 let r2: Vec<u32> = read_children(&*db, 0, PREFIX, 1_2).expect("(2) Getting r2 failed");
119
120 assert_eq!(r1, vec![1_3, 1_5]);
121 assert_eq!(r2.len(), 0);
122 }
123}