Skip to content

Commit

Permalink
Support older sqlite versions.
Browse files Browse the repository at this point in the history
The `FALSE` constant was introduced in sqlite version 3.23.0,
but Android does not support this version of sqlite until API
level 30; we support back to Android API 27 so we have to use
`0` as the constant for `FALSE` instead.
  • Loading branch information
nuttycom committed Aug 30, 2024
1 parent 59582a7 commit c91b34e
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
5 changes: 5 additions & 0 deletions zcash_client_sqlite/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this library adheres to Rust's notion of

## [Unreleased]

### Changed
- The `v_tx_outputs` view was modified slightly to support older versions of
`sqlite`.


## [0.11.1] - 2024-08-21

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_sqlite/src/wallet/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ SELECT transactions.txid AS txid,
NULL AS to_account_id,
sent_notes.to_address AS to_address,
sent_notes.value AS value,
FALSE AS is_change,
0 AS is_change,
sent_notes.memo AS memo
FROM sent_notes
JOIN transactions
Expand Down
4 changes: 4 additions & 0 deletions zcash_client_sqlite/src/wallet/init/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod sapling_memo_consistency;
mod sent_notes_to_internal;
mod shardtree_support;
mod spend_key_available;
mod support_legacy_sqlite;
mod tx_retrieval_queue;
mod ufvk_support;
mod utxos_table;
Expand Down Expand Up @@ -74,6 +75,8 @@ pub(super) fn all_migrations<P: consensus::Parameters + 'static>(
// \ \ ephemeral_addresses / /
// \ \ | / /
// ------------------------------ tx_retrieval_queue ----------------------------
// |
// support_legacy_sqlite
vec![
Box::new(initial_setup::Migration {}),
Box::new(utxos_table::Migration {}),
Expand Down Expand Up @@ -131,6 +134,7 @@ pub(super) fn all_migrations<P: consensus::Parameters + 'static>(
Box::new(tx_retrieval_queue::Migration {
params: params.clone(),
}),
Box::new(support_legacy_sqlite::Migration),
]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! A migration that removes the use of `FALSE` in sqlite view definitions.
//! This is necessary to support older
use std::collections::HashSet;

use rusqlite;
use schemer;
use schemer_rusqlite::RusqliteMigration;
use uuid::Uuid;

use crate::wallet::init::{migrations::tx_retrieval_queue, WalletMigrationError};

pub(super) const MIGRATION_ID: Uuid = Uuid::from_u128(0xc9ed1fb5_b2c3_467f_89dc_2591dcca5562);

const DEPENDENCIES: &[Uuid] = &[tx_retrieval_queue::MIGRATION_ID];

pub(super) struct Migration;

impl schemer::Migration for Migration {
fn id(&self) -> Uuid {
MIGRATION_ID
}

fn dependencies(&self) -> HashSet<Uuid> {
DEPENDENCIES.iter().copied().collect()
}

fn description(&self) -> &'static str {
"Removes the FALSE keyword from the v_tx_outputs view definition"
}
}

impl RusqliteMigration for Migration {
type Error = WalletMigrationError;

fn up(&self, transaction: &rusqlite::Transaction) -> Result<(), WalletMigrationError> {
transaction.execute_batch(
r#"
DROP VIEW v_tx_outputs;
CREATE VIEW v_tx_outputs AS
-- select all outputs received by the wallet
SELECT transactions.txid AS txid,
ro.pool AS output_pool,
ro.output_index AS output_index,
sent_notes.from_account_id AS from_account_id,
ro.account_id AS to_account_id,
NULL AS to_address,
ro.value AS value,
ro.is_change AS is_change,
ro.memo AS memo
FROM v_received_outputs ro
JOIN transactions
ON transactions.id_tx = ro.transaction_id
-- join to the sent_notes table to obtain `from_account_id`
LEFT JOIN sent_notes ON sent_notes.id = ro.sent_note_id
UNION
-- select all outputs sent from the wallet to external recipients
SELECT transactions.txid AS txid,
sent_notes.output_pool AS output_pool,
sent_notes.output_index AS output_index,
sent_notes.from_account_id AS from_account_id,
NULL AS to_account_id,
sent_notes.to_address AS to_address,
sent_notes.value AS value,
0 AS is_change,
sent_notes.memo AS memo
FROM sent_notes
JOIN transactions
ON transactions.id_tx = sent_notes.tx
LEFT JOIN v_received_outputs ro ON ro.sent_note_id = sent_notes.id
-- exclude any sent notes for which a row exists in the v_received_outputs view
WHERE ro.account_id IS NULL
"#,
)?;

Ok(())
}

fn down(&self, _: &rusqlite::Transaction) -> Result<(), WalletMigrationError> {
Err(WalletMigrationError::CannotRevert(MIGRATION_ID))
}
}

#[cfg(test)]
mod tests {
use crate::wallet::init::migrations::tests::test_migrate;

#[test]
fn migrate() {
test_migrate(&[super::MIGRATION_ID]);
}
}

0 comments on commit c91b34e

Please sign in to comment.