• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bitcoindevkit / bdk / 9142429407

18 May 2024 08:23PM UTC coverage: 83.234% (+0.8%) from 82.434%
9142429407

Pull #1128

github

web-flow
Merge 73fe06efd into 2f059a158
Pull Request #1128: feat: add bdk_sqlite_store crate implementing PersistBackend

803 of 831 new or added lines in 5 files covered. (96.63%)

8 existing lines in 5 files now uncovered.

11448 of 13754 relevant lines covered (83.23%)

17192.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.45
/crates/sqlite_store/src/schema.rs
1
use rusqlite::{named_params, Connection, Error};
2

3
const SCHEMA_0: &str = include_str!("../schema/schema_0.sql");
4
const MIGRATIONS: &[&str] = &[SCHEMA_0];
5

6
pub(crate) trait Schema {
7
    /// Migrate sqlite db schema to latest version.
8
    fn migrate(conn: &mut Connection) -> Result<(), Error> {
12✔
9
        let stmts = &MIGRATIONS
12✔
10
            .iter()
12✔
11
            .flat_map(|stmt| {
12✔
12
                // remove comment lines
12✔
13
                let s = stmt
12✔
14
                    .split('\n')
12✔
15
                    .filter(|l| !l.starts_with("--") && !l.is_empty())
852✔
16
                    .collect::<Vec<_>>()
12✔
17
                    .join(" ");
12✔
18
                // split into statements
12✔
19
                s.split(';')
12✔
20
                    // remove extra spaces
12✔
21
                    .map(|s| {
108✔
22
                        s.trim()
108✔
23
                            .split(' ')
108✔
24
                            .filter(|s| !s.is_empty())
3,648✔
25
                            .collect::<Vec<_>>()
108✔
26
                            .join(" ")
108✔
27
                    })
108✔
28
                    .collect::<Vec<_>>()
12✔
29
            })
12✔
30
            // remove empty statements
12✔
31
            .filter(|s| !s.is_empty())
108✔
32
            .collect::<Vec<String>>();
12✔
33

34
        let version = Self::get_schema_version(conn)?;
12✔
35
        let stmts = &stmts[(version as usize)..];
12✔
36

37
        // begin transaction, all migration statements and new schema version commit or rollback
38
        let tx = conn.transaction()?;
12✔
39

40
        // execute every statement and return `Some` new schema version
41
        // if execution fails, return `Error::Rusqlite`
42
        // if no statements executed returns `None`
43
        let new_version = stmts
12✔
44
            .iter()
12✔
45
            .enumerate()
12✔
46
            .map(|version_stmt| {
40✔
47
                tx.execute(version_stmt.1.as_str(), [])
40✔
48
                    // map result value to next migration version
40✔
49
                    .map(|_| version_stmt.0 as i32 + version + 1)
40✔
50
            })
40✔
51
            .last()
12✔
52
            .transpose()?;
12✔
53

54
        // if `Some` new statement version, set new schema version
55
        if let Some(version) = new_version {
12✔
56
            Self::set_schema_version(&tx, version)?;
5✔
57
        }
7✔
58

59
        // commit transaction
60
        tx.commit()?;
12✔
61
        Ok(())
12✔
62
    }
12✔
63

64
    fn get_schema_version(conn: &Connection) -> rusqlite::Result<i32> {
12✔
65
        let statement = conn.prepare_cached("SELECT version FROM version");
12✔
66
        match statement {
5✔
67
            Err(Error::SqliteFailure(e, Some(msg))) => {
5✔
68
                if msg == "no such table: version" {
5✔
69
                    Ok(0)
5✔
70
                } else {
NEW
71
                    Err(Error::SqliteFailure(e, Some(msg)))
×
72
                }
73
            }
74
            Ok(mut stmt) => {
7✔
75
                let mut rows = stmt.query([])?;
7✔
76
                match rows.next()? {
7✔
77
                    Some(row) => {
7✔
78
                        let version: i32 = row.get(0)?;
7✔
79
                        Ok(version)
7✔
80
                    }
NEW
81
                    None => Ok(0),
×
82
                }
83
            }
NEW
84
            _ => Ok(0),
×
85
        }
86
    }
12✔
87

88
    fn set_schema_version(conn: &Connection, version: i32) -> rusqlite::Result<usize> {
5✔
89
        conn.execute(
5✔
90
            "UPDATE version SET version=:version",
5✔
91
            named_params! {":version": version},
5✔
92
        )
5✔
93
    }
5✔
94
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc