essential_node_db/query_range/
address.rs1use essential_node_db_sql as sql;
6use essential_types::{ContentAddress, Key, Value, Word};
7use rusqlite::{named_params, Connection, OptionalExtension, Transaction};
8
9use crate::{blob_from_words, words_from_blob, QueryError};
10
11pub fn query_state_inclusive_block(
16 conn: &Connection,
17 contract_ca: &ContentAddress,
18 key: &Key,
19 block_address: &ContentAddress,
20) -> Result<Option<Value>, QueryError> {
21 let mut stmt = conn.prepare(sql::query::QUERY_STATE_BLOCK_ADDRESS)?;
22 let value_blob: Option<(Option<Vec<u8>>, Word)> = stmt
23 .query_row(
24 named_params! {
25 ":contract_ca": contract_ca.0,
26 ":key": blob_from_words(key),
27 ":block_address": block_address.0,
28 ":solution_set_index": None::<u64>,
29 },
30 |row| {
31 let value = row.get("found_value")?;
32 let number = row.get("number")?;
33 Ok((value, number))
34 },
35 )
36 .optional()?;
37 match value_blob {
38 None => Ok(None),
39 Some((Some(value_blob), _)) => Ok(Some(words_from_blob(&value_blob))),
40 Some((None, block_number)) => {
41 super::finalized::query_state_inclusive_block(conn, contract_ca, key, block_number)
42 }
43 }
44}
45
46pub fn query_state_exclusive_block(
51 tx: &Transaction,
52 contract_ca: &ContentAddress,
53 key: &Key,
54 block_address: &ContentAddress,
55) -> Result<Option<Value>, QueryError> {
56 let Some(parent_addr) = crate::get_parent_block_address(tx, block_address)? else {
57 return Ok(None);
58 };
59 query_state_inclusive_block(tx, contract_ca, key, &parent_addr)
60}
61
62pub fn query_state_inclusive_solution_set(
69 conn: &Connection,
70 contract_ca: &ContentAddress,
71 key: &Key,
72 block_address: &ContentAddress,
73 solution_set_index: u64,
74) -> Result<Option<Value>, QueryError> {
75 let mut stmt = conn.prepare(sql::query::QUERY_STATE_BLOCK_ADDRESS)?;
76 let value_blob: Option<(Option<Vec<u8>>, Word)> = stmt
77 .query_row(
78 named_params! {
79 ":contract_ca": contract_ca.0,
80 ":key": blob_from_words(key),
81 ":block_address": block_address.0,
82 ":solution_set_index": Some(solution_set_index),
83 },
84 |row| {
85 let value = row.get("found_value")?;
86 let number = row.get("number")?;
87 Ok((value, number))
88 },
89 )
90 .optional()?;
91 match value_blob {
92 None => Ok(None),
93 Some((Some(value_blob), _)) => Ok(Some(words_from_blob(&value_blob))),
94 Some((None, block_number)) => {
95 super::finalized::query_state_inclusive_block(conn, contract_ca, key, block_number)
96 }
97 }
98}
99
100pub fn query_state_exclusive_solution_set(
106 tx: &Transaction,
107 contract_ca: &ContentAddress,
108 key: &Key,
109 block_address: &ContentAddress,
110 solution_set_index: u64,
111) -> Result<Option<Value>, QueryError> {
112 match solution_set_index.checked_sub(1) {
113 Some(solution_set_index) => query_state_inclusive_solution_set(
114 tx,
115 contract_ca,
116 key,
117 block_address,
118 solution_set_index,
119 ),
120 None => query_state_exclusive_block(tx, contract_ca, key, block_address),
121 }
122}