Skip to content

Commit 4ad9117

Browse files
committed
refactor: use transactions for any query
1 parent ddfb91c commit 4ad9117

File tree

5 files changed

+72
-103
lines changed

5 files changed

+72
-103
lines changed

crates/store/src/db/connection.rs

-22
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,3 @@ impl Connection {
4040
self.inner.transaction().map(Transaction::new)
4141
}
4242
}
43-
44-
#[cfg(not(feature = "explain-query-plans"))]
45-
impl Connection {
46-
#[inline]
47-
pub fn prepare_cached(&self, sql: &str) -> rusqlite::Result<rusqlite::CachedStatement<'_>> {
48-
self.inner.prepare_cached(sql)
49-
}
50-
51-
#[inline]
52-
pub fn execute<P: rusqlite::Params>(&self, sql: &str, params: P) -> rusqlite::Result<usize> {
53-
self.inner.execute(sql, params)
54-
}
55-
56-
#[inline]
57-
pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> rusqlite::Result<T>
58-
where
59-
P: rusqlite::Params,
60-
F: FnOnce(&rusqlite::Row<'_>) -> rusqlite::Result<T>,
61-
{
62-
self.inner.query_row(sql, params, f)
63-
}
64-
}

crates/store/src/db/settings.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,23 @@ use crate::db::{connection::Connection, sql::utils::table_exists};
55
pub struct Settings;
66

77
impl Settings {
8-
pub fn exists(conn: &Connection) -> Result<bool> {
9-
table_exists(conn, "settings")
8+
pub fn exists(conn: &mut Connection) -> Result<bool> {
9+
table_exists(&conn.transaction()?, "settings")
1010
}
1111

12-
pub fn get_value<T: FromSql>(conn: &Connection, name: &str) -> Result<Option<T>> {
13-
conn.query_row("SELECT value FROM settings WHERE name = $1", params![name], |row| {
14-
row.get(0)
15-
})
16-
.optional()
12+
pub fn get_value<T: FromSql>(conn: &mut Connection, name: &str) -> Result<Option<T>> {
13+
conn.transaction()?
14+
.inner()
15+
.query_row("SELECT value FROM settings WHERE name = $1", params![name], |row| {
16+
row.get(0)
17+
})
18+
.optional()
1719
}
1820

19-
pub fn set_value<T: ToSql>(conn: &Connection, name: &str, value: &T) -> Result<()> {
21+
pub fn set_value<T: ToSql>(conn: &mut Connection, name: &str, value: &T) -> Result<()> {
2022
let count = conn
23+
.transaction()?
24+
.inner()
2125
.execute("INSERT OR REPLACE INTO settings (name, value) VALUES (?, ?)", params![
2226
name, value
2327
])?;

crates/store/src/db/sql/mod.rs

+44-28
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ use crate::{
5656
/// A vector with accounts, or an error.
5757
#[cfg(test)]
5858
pub fn select_all_accounts(conn: &mut Connection) -> Result<Vec<AccountInfo>> {
59-
let mut stmt = conn.prepare_cached(
59+
let transaction = conn.transaction()?;
60+
let mut stmt = transaction.prepare_cached(
6061
"
6162
SELECT
6263
account_id,
@@ -84,7 +85,8 @@ pub fn select_all_accounts(conn: &mut Connection) -> Result<Vec<AccountInfo>> {
8485
///
8586
/// The vector with the account id and corresponding hash, or an error.
8687
pub fn select_all_account_hashes(conn: &mut Connection) -> Result<Vec<(AccountId, RpoDigest)>> {
87-
let mut stmt = conn
88+
let transaction = conn.transaction()?;
89+
let mut stmt = transaction
8890
.prepare_cached("SELECT account_id, account_hash FROM accounts ORDER BY block_num ASC;")?;
8991
let mut rows = stmt.query([])?;
9092

@@ -112,7 +114,8 @@ pub fn select_accounts_by_block_range(
112114
block_end: BlockNumber,
113115
account_ids: &[AccountId],
114116
) -> Result<Vec<AccountSummary>> {
115-
let mut stmt = conn.prepare_cached(
117+
let transaction = conn.transaction()?;
118+
let mut stmt = transaction.prepare_cached(
116119
"
117120
SELECT
118121
account_id,
@@ -151,7 +154,8 @@ pub fn select_accounts_by_block_range(
151154
///
152155
/// The latest account details, or an error.
153156
pub fn select_account(conn: &mut Connection, account_id: AccountId) -> Result<AccountInfo> {
154-
let mut stmt = conn.prepare_cached(
157+
let transaction = conn.transaction()?;
158+
let mut stmt = transaction.prepare_cached(
155159
"
156160
SELECT
157161
account_id,
@@ -181,7 +185,8 @@ pub fn select_accounts_by_ids(
181185
conn: &mut Connection,
182186
account_ids: &[AccountId],
183187
) -> Result<Vec<AccountInfo>> {
184-
let mut stmt = conn.prepare_cached(
188+
let transaction = conn.transaction()?;
189+
let mut stmt = transaction.prepare_cached(
185190
"
186191
SELECT
187192
account_id,
@@ -227,7 +232,8 @@ pub fn select_account_delta(
227232
block_start: BlockNumber,
228233
block_end: BlockNumber,
229234
) -> Result<Option<AccountDelta>> {
230-
let mut select_nonce_stmt = conn.prepare_cached(
235+
let transaction = conn.transaction()?;
236+
let mut select_nonce_stmt = transaction.prepare_cached(
231237
"
232238
SELECT
233239
nonce
@@ -241,7 +247,7 @@ pub fn select_account_delta(
241247
",
242248
)?;
243249

244-
let mut select_slot_updates_stmt = conn.prepare_cached(
250+
let mut select_slot_updates_stmt = transaction.prepare_cached(
245251
"
246252
SELECT
247253
slot, value
@@ -263,7 +269,7 @@ pub fn select_account_delta(
263269
",
264270
)?;
265271

266-
let mut select_storage_map_updates_stmt = conn.prepare_cached(
272+
let mut select_storage_map_updates_stmt = transaction.prepare_cached(
267273
"
268274
SELECT
269275
slot, key, value
@@ -286,7 +292,7 @@ pub fn select_account_delta(
286292
",
287293
)?;
288294

289-
let mut select_fungible_asset_deltas_stmt = conn.prepare_cached(
295+
let mut select_fungible_asset_deltas_stmt = transaction.prepare_cached(
290296
"
291297
SELECT
292298
faucet_id, SUM(delta)
@@ -301,7 +307,7 @@ pub fn select_account_delta(
301307
",
302308
)?;
303309

304-
let mut select_non_fungible_asset_updates_stmt = conn.prepare_cached(
310+
let mut select_non_fungible_asset_updates_stmt = transaction.prepare_cached(
305311
"
306312
SELECT
307313
block_num, vault_key, is_remove
@@ -418,10 +424,10 @@ pub fn upsert_accounts(
418424
block_num: BlockNumber,
419425
) -> Result<usize> {
420426
let mut upsert_stmt = transaction.prepare_cached(
421-
"INSERT OR REPLACE INTO accounts (account_id, account_hash, block_num, details) VALUES (?1, ?2, ?3, ?4);",
427+
"INSERT OR REPLACE INTO accounts (account_id, account_hash, block_num, details) VALUES (?1, ?2, ?3, ?4)",
422428
)?;
423429
let mut select_details_stmt =
424-
transaction.prepare_cached("SELECT details FROM accounts WHERE account_id = ?1;")?;
430+
transaction.prepare_cached("SELECT details FROM accounts WHERE account_id = ?1")?;
425431

426432
let mut count = 0;
427433
for update in accounts {
@@ -601,7 +607,7 @@ pub fn insert_nullifiers_for_block(
601607
let mut count = stmt.execute(params![serialized_nullifiers])?;
602608

603609
let mut stmt = transaction.prepare_cached(
604-
"INSERT INTO nullifiers (nullifier, nullifier_prefix, block_num) VALUES (?1, ?2, ?3);",
610+
"INSERT INTO nullifiers (nullifier, nullifier_prefix, block_num) VALUES (?1, ?2, ?3)",
605611
)?;
606612

607613
for (nullifier, bytes) in nullifiers.iter().zip(serialized_nullifiers.iter()) {
@@ -617,8 +623,9 @@ pub fn insert_nullifiers_for_block(
617623
///
618624
/// A vector with nullifiers and the block height at which they were created, or an error.
619625
pub fn select_all_nullifiers(conn: &mut Connection) -> Result<Vec<(Nullifier, BlockNumber)>> {
620-
let mut stmt =
621-
conn.prepare_cached("SELECT nullifier, block_num FROM nullifiers ORDER BY block_num ASC;")?;
626+
let transaction = conn.transaction()?;
627+
let mut stmt = transaction
628+
.prepare_cached("SELECT nullifier, block_num FROM nullifiers ORDER BY block_num ASC")?;
622629
let mut rows = stmt.query([])?;
623630

624631
let mut result = vec![];
@@ -652,7 +659,8 @@ pub fn select_nullifiers_by_prefix(
652659
let nullifier_prefixes: Vec<Value> =
653660
nullifier_prefixes.iter().copied().map(Into::into).collect();
654661

655-
let mut stmt = conn.prepare_cached(
662+
let transaction = conn.transaction()?;
663+
let mut stmt = transaction.prepare_cached(
656664
"
657665
SELECT
658666
nullifier,
@@ -689,7 +697,8 @@ pub fn select_nullifiers_by_prefix(
689697
/// A vector with notes, or an error.
690698
#[cfg(test)]
691699
pub fn select_all_notes(conn: &mut Connection) -> Result<Vec<NoteRecord>> {
692-
let mut stmt = conn.prepare_cached(&format!(
700+
let transaction = conn.transaction()?;
701+
let mut stmt = transaction.prepare_cached(&format!(
693702
"SELECT {} FROM notes ORDER BY block_num ASC",
694703
NoteRecord::SELECT_COLUMNS,
695704
))?;
@@ -735,7 +744,7 @@ pub fn insert_notes(
735744

736745
let mut count = 0;
737746
for (note, nullifier) in notes {
738-
let details = note.details.as_ref().map(miden_objects::utils::Serializable::to_bytes);
747+
let details = note.details.as_ref().map(Serializable::to_bytes);
739748
count += stmt.execute(params![
740749
note.block_num.as_u32(),
741750
note.note_index.batch_idx(),
@@ -777,7 +786,8 @@ pub fn select_notes_since_block_by_tag_and_sender(
777786
account_ids: &[AccountId],
778787
block_num: BlockNumber,
779788
) -> Result<Vec<NoteSyncRecord>> {
780-
let mut stmt = conn
789+
let transaction = conn.transaction()?;
790+
let mut stmt = transaction
781791
.prepare_cached(include_str!("queries/select_notes_since_block_by_tag_and_sender.sql"))?;
782792

783793
let tags: Vec<Value> = tags.iter().copied().map(Into::into).collect();
@@ -835,7 +845,8 @@ pub fn select_notes_since_block_by_tag_and_sender(
835845
pub fn select_notes_by_id(conn: &mut Connection, note_ids: &[NoteId]) -> Result<Vec<NoteRecord>> {
836846
let note_ids: Vec<Value> = note_ids.iter().map(|id| id.to_bytes().into()).collect();
837847

838-
let mut stmt = conn.prepare_cached(&format!(
848+
let transaction = conn.transaction()?;
849+
let mut stmt = transaction.prepare_cached(&format!(
839850
"SELECT {} FROM notes WHERE note_id IN rarray(?1)",
840851
NoteRecord::SELECT_COLUMNS
841852
))?;
@@ -861,7 +872,8 @@ pub fn select_note_inclusion_proofs(
861872
) -> Result<BTreeMap<NoteId, NoteInclusionProof>> {
862873
let note_ids: Vec<Value> = note_ids.into_iter().map(|id| id.to_bytes().into()).collect();
863874

864-
let mut select_notes_stmt = conn.prepare_cached(
875+
let transaction = conn.transaction()?;
876+
let mut select_notes_stmt = transaction.prepare_cached(
865877
"
866878
SELECT
867879
block_num,
@@ -983,13 +995,14 @@ pub fn select_block_header_by_block_num(
983995
conn: &mut Connection,
984996
block_number: Option<BlockNumber>,
985997
) -> Result<Option<BlockHeader>> {
998+
let transaction = conn.transaction()?;
986999
let mut stmt;
9871000
let mut rows = if let Some(block_number) = block_number {
988-
stmt =
989-
conn.prepare_cached("SELECT block_header FROM block_headers WHERE block_num = ?1")?;
1001+
stmt = transaction
1002+
.prepare_cached("SELECT block_header FROM block_headers WHERE block_num = ?1")?;
9901003
stmt.query([block_number.as_u32()])?
9911004
} else {
992-
stmt = conn.prepare_cached(
1005+
stmt = transaction.prepare_cached(
9931006
"SELECT block_header FROM block_headers ORDER BY block_num DESC LIMIT 1",
9941007
)?;
9951008
stmt.query([])?
@@ -1020,7 +1033,8 @@ pub fn select_block_headers(
10201033
let blocks: Vec<Value> = blocks.map(|b| b.as_u32().into()).collect();
10211034

10221035
let mut headers = Vec::with_capacity(blocks.len());
1023-
let mut stmt = conn
1036+
let transaction = conn.transaction()?;
1037+
let mut stmt = transaction
10241038
.prepare_cached("SELECT block_header FROM block_headers WHERE block_num IN rarray(?1);")?;
10251039
let mut rows = stmt.query(params![Rc::new(blocks)])?;
10261040

@@ -1039,8 +1053,9 @@ pub fn select_block_headers(
10391053
///
10401054
/// A vector of [`BlockHeader`] or an error.
10411055
pub fn select_all_block_headers(conn: &mut Connection) -> Result<Vec<BlockHeader>> {
1042-
let mut stmt =
1043-
conn.prepare_cached("SELECT block_header FROM block_headers ORDER BY block_num ASC;")?;
1056+
let transaction = conn.transaction()?;
1057+
let mut stmt = transaction
1058+
.prepare_cached("SELECT block_header FROM block_headers ORDER BY block_num ASC;")?;
10441059
let mut rows = stmt.query([])?;
10451060
let mut result = vec![];
10461061
while let Some(row) = rows.next()? {
@@ -1105,7 +1120,8 @@ pub fn select_transactions_by_accounts_and_block_range(
11051120
.map(|account_id| account_id.to_bytes().into())
11061121
.collect();
11071122

1108-
let mut stmt = conn.prepare_cached(
1123+
let transaction = conn.transaction()?;
1124+
let mut stmt = transaction.prepare_cached(
11091125
"
11101126
SELECT
11111127
account_id,

crates/store/src/db/sql/plan_explainer.rs

+4-40
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,22 @@ use rusqlite::{CachedStatement, Params, Row, Rows, Statement};
22
use termtree::Tree;
33
use tracing::info;
44

5-
use crate::db::{connection::Connection, transaction::Transaction};
6-
7-
impl Connection {
8-
#[inline]
9-
pub fn prepare_cached(&self, sql: &str) -> rusqlite::Result<CachedStatementWithQueryPlan<'_>> {
10-
let statement = self.inner().prepare_cached(sql)?;
11-
12-
Ok(CachedStatementWithQueryPlan {
13-
executor: Executor::Connection(self.inner()),
14-
sql: sql.into(),
15-
statement,
16-
})
17-
}
18-
19-
#[inline]
20-
pub fn execute<P: Params + Clone>(&self, sql: &str, params: P) -> rusqlite::Result<usize> {
21-
self.prepare_cached(sql)?.execute(params)
22-
}
23-
24-
#[inline]
25-
pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> rusqlite::Result<T>
26-
where
27-
P: Params + Clone,
28-
F: FnOnce(&Row<'_>) -> rusqlite::Result<T>,
29-
{
30-
self.prepare_cached(sql)?.query_row(params, f)
31-
}
32-
}
5+
use crate::db::transaction::Transaction;
336

347
impl Transaction<'_> {
358
pub fn prepare_cached(&self, sql: &str) -> rusqlite::Result<CachedStatementWithQueryPlan> {
369
let statement = self.inner().prepare_cached(sql)?;
3710

3811
Ok(CachedStatementWithQueryPlan {
39-
executor: Executor::Transaction(self.inner()),
12+
transaction: self.inner(),
4013
sql: sql.into(),
4114
statement,
4215
})
4316
}
4417
}
4518

46-
enum Executor<'conn> {
47-
Connection(&'conn rusqlite::Connection),
48-
Transaction(&'conn rusqlite::Transaction<'conn>),
49-
}
50-
5119
pub struct CachedStatementWithQueryPlan<'conn> {
52-
executor: Executor<'conn>,
20+
transaction: &'conn rusqlite::Transaction<'conn>,
5321
sql: Box<str>,
5422
statement: CachedStatement<'conn>,
5523
}
@@ -101,11 +69,7 @@ impl CachedStatementWithQueryPlan<'_> {
10169
}
10270

10371
let explain_sql = format!("EXPLAIN QUERY PLAN {}", self.sql);
104-
let mut explain_stmt = match self.executor {
105-
Executor::Connection(conn) => conn.prepare(&explain_sql)?,
106-
Executor::Transaction(transaction) => transaction.prepare(&explain_sql)?,
107-
};
108-
72+
let mut explain_stmt = self.transaction.prepare(&explain_sql)?;
10973
let mut rows = explain_stmt.query(params)?;
11074
let expanded_sql = rows.as_ref().and_then(Statement::expanded_sql).unwrap_or_default();
11175

0 commit comments

Comments
 (0)