neo_devpack_solidity/runtime/storage/storage_impl/manager/
crud.rs1use super::*;
2
3impl StorageManager {
4 pub fn get(&mut self, account: &str, key: &[u8]) -> Result<Option<Vec<u8>>, RuntimeError> {
6 self.read_count += 1;
7
8 let account_storage = self.storage.get(account);
9
10 if let Some(storage) = account_storage {
11 if let Some(change) = storage.pending_changes.get(key) {
13 match change.change_type {
14 StorageChangeType::Delete => return Ok(None),
15 _ => {
16 if let Some(ref new_value) = change.new_value {
17 return Ok(Some(new_value.clone()));
18 }
19 }
20 }
21 }
22
23 if let Some(value) = storage.storage.get(key) {
25 return Ok(Some(value.clone()));
26 }
27 }
28
29 Ok(None)
30 }
31
32 pub fn set(&mut self, account: &str, key: &[u8], value: &[u8]) -> Result<(), RuntimeError> {
34 self.write_count += 1;
35
36 let old_value = self.get(account, key)?;
37
38 let change_type = match &old_value {
40 None => StorageChangeType::Create,
41 Some(old) if old == value => StorageChangeType::NoChange,
42 Some(_) if value.is_empty() => StorageChangeType::Delete,
43 Some(_) => StorageChangeType::Update,
44 };
45
46 let gas_cost = self.calculate_storage_gas_cost(&change_type, value.len());
47
48 let account_storage =
50 self.storage
51 .entry(account.to_string())
52 .or_insert_with(|| AccountStorage {
53 account: account.to_string(),
54 storage: BTreeMap::new(),
55 pending_changes: HashMap::new(),
56 });
57
58 let change = StorageChange {
60 key: key.to_vec(),
61 old_value,
62 new_value: if value.is_empty() {
63 None
64 } else {
65 Some(value.to_vec())
66 },
67 change_type,
68 gas_cost,
69 };
70
71 account_storage.pending_changes.insert(key.to_vec(), change);
72
73 Ok(())
74 }
75
76 pub fn delete(&mut self, account: &str, key: &[u8]) -> Result<(), RuntimeError> {
78 self.set(account, key, &[])
79 }
80
81 pub fn exists(&mut self, account: &str, key: &[u8]) -> Result<bool, RuntimeError> {
83 Ok(self.get(account, key)?.is_some())
84 }
85}