@@ -7,7 +7,6 @@ use rusqlite::{named_params, Connection};
7
7
use serde:: { Deserialize , Serialize } ;
8
8
use std:: collections:: { BTreeMap , BTreeSet } ;
9
9
use std:: marker:: PhantomData ;
10
- use std:: path:: Path ;
11
10
use std:: str:: FromStr ;
12
11
use std:: sync:: { Arc , Mutex } ;
13
12
@@ -19,9 +18,7 @@ use bdk_chain::{
19
18
20
19
/// Persists [`ChangeSet`] data in to a relational schema based SQLite database file.
21
20
///
22
- /// The changesets loaded or stored represent changes to keychain and blockchain data. If the
23
- /// keychain (K) is a simple enum without variant fields you must enable the
24
- /// [serde internal tag](https://serde.rs/enum-representations.html#internally-tagged) feature.
21
+ /// The changesets loaded or stored represent changes to keychain and blockchain data.
25
22
#[ derive( Debug ) ]
26
23
pub struct Store < K , A > {
27
24
// A rusqlite connection to the SQLite database. Uses a Mutex for thread safety.
35
32
K : Ord + for < ' de > Deserialize < ' de > + Serialize + Send ,
36
33
A : Anchor + for < ' de > Deserialize < ' de > + Serialize + Send ,
37
34
{
38
- /// Creates a new store from a [`Path`].
39
- ///
40
- /// The file must be able to be opened with read and write permissions.
41
- pub fn new < P : AsRef < Path > > ( path : P ) -> Result < Self , rusqlite:: Error > {
42
- let mut conn = Connection :: open ( path) ?;
35
+ /// Creates a new store from a [`Connection`].
36
+ pub fn new ( mut conn : Connection ) -> Result < Self , rusqlite:: Error > {
43
37
Self :: migrate ( & mut conn) ?;
44
-
45
- Ok ( Self {
46
- conn : Mutex :: new ( conn) ,
47
- keychain_marker : Default :: default ( ) ,
48
- anchor_marker : Default :: default ( ) ,
49
- } )
50
- }
51
-
52
- /// Creates a new in-memory, not persisted database store.
53
- ///
54
- /// This is primarily used for testing.
55
- pub fn new_memory ( ) -> Result < Self , rusqlite:: Error > {
56
- let mut conn = Connection :: open_in_memory ( ) ?;
57
- Self :: migrate ( & mut conn) ?;
58
-
59
38
Ok ( Self {
60
39
conn : Mutex :: new ( conn) ,
61
40
keychain_marker : Default :: default ( ) ,
@@ -261,13 +240,13 @@ where
261
240
db_transaction : & rusqlite:: Transaction ,
262
241
) -> Result < BTreeMap < K , Descriptor < DescriptorPublicKey > > , Error > {
263
242
let mut select_keychains_added_stmt = db_transaction
264
- . prepare_cached ( "SELECT json_extract (keychain, '$' ), descriptor FROM keychain" )
243
+ . prepare_cached ( "SELECT json (keychain), descriptor FROM keychain" )
265
244
. expect ( "select keychains statement" ) ;
266
245
267
246
let keychains = select_keychains_added_stmt
268
247
. query_map ( [ ] , |row| {
269
248
let keychain = row. get_unwrap :: < usize , String > ( 0 ) ;
270
- let keychain: K = serde_json:: from_str ( keychain. as_str ( ) ) . expect ( "keychain" ) ;
249
+ let keychain = serde_json:: from_str :: < K > ( keychain. as_str ( ) ) . expect ( "keychain" ) ;
271
250
let descriptor = row. get_unwrap :: < usize , String > ( 1 ) ;
272
251
let descriptor = Descriptor :: from_str ( descriptor. as_str ( ) ) . expect ( "descriptor" ) ;
273
252
Ok ( ( keychain, descriptor) )
@@ -487,7 +466,7 @@ where
487
466
) -> Result < BTreeSet < ( A , Txid ) > , Error > {
488
467
// serde_json::from_str
489
468
let mut select_anchor_stmt = db_transaction
490
- . prepare_cached ( "SELECT block_hash, json_extract (anchor, '$' ), txid FROM anchor_tx" )
469
+ . prepare_cached ( "SELECT block_hash, json (anchor), txid FROM anchor_tx" )
491
470
. expect ( "select anchor statement" ) ;
492
471
let anchors = select_anchor_stmt
493
472
. query_map ( [ ] , |row| {
@@ -626,19 +605,18 @@ mod test {
626
605
}
627
606
628
607
#[ test]
629
- fn insert_and_load_aggregate_changesets_with_confirmation_time_height_anchor ( ) {
608
+ fn insert_and_load_aggregate_changesets_with_confirmation_time_height_anchor (
609
+ ) -> anyhow:: Result < ( ) > {
630
610
let ( test_changesets, agg_test_changesets) =
631
611
create_test_changesets ( & |height, time, hash| ConfirmationTimeHeightAnchor {
632
612
confirmation_height : height,
633
613
confirmation_time : time,
634
614
anchor_block : ( height, hash) . into ( ) ,
635
615
} ) ;
636
616
637
- let mut store = Store :: < Keychain , ConfirmationTimeHeightAnchor > :: new_memory ( )
617
+ let conn = Connection :: open_in_memory ( ) . expect ( "in memory connection" ) ;
618
+ let mut store = Store :: < Keychain , ConfirmationTimeHeightAnchor > :: new ( conn)
638
619
. expect ( "create new memory db store" ) ;
639
- // let mut store =
640
- // Store::<Keychain, ConfirmationTimeHeightAnchor>::new(Path::new("test_agg.sqlite"))
641
- // .expect("create new file db store");
642
620
643
621
test_changesets. iter ( ) . for_each ( |changeset| {
644
622
store. write_changes ( changeset) . expect ( "write changeset" ) ;
@@ -647,21 +625,21 @@ mod test {
647
625
let agg_changeset = store. load_from_persistence ( ) . expect ( "aggregated changeset" ) ;
648
626
649
627
assert_eq ! ( agg_changeset, Some ( agg_test_changesets) ) ;
628
+ Ok ( ( ) )
650
629
}
651
630
652
631
#[ test]
653
- fn insert_and_load_aggregate_changesets_with_confirmation_height_anchor ( ) {
632
+ fn insert_and_load_aggregate_changesets_with_confirmation_height_anchor ( ) -> anyhow:: Result < ( ) >
633
+ {
654
634
let ( test_changesets, agg_test_changesets) =
655
635
create_test_changesets ( & |height, _time, hash| ConfirmationHeightAnchor {
656
636
confirmation_height : height,
657
637
anchor_block : ( height, hash) . into ( ) ,
658
638
} ) ;
659
639
660
- let mut store = Store :: < Keychain , ConfirmationHeightAnchor > :: new_memory ( )
640
+ let conn = Connection :: open_in_memory ( ) . expect ( "in memory connection" ) ;
641
+ let mut store = Store :: < Keychain , ConfirmationHeightAnchor > :: new ( conn)
661
642
. expect ( "create new memory db store" ) ;
662
- // let mut store =
663
- // Store::<Keychain, ConfirmationHeightAnchor>::new(Path::new("test_agg.sqlite"))
664
- // .expect("create new file db store");
665
643
666
644
test_changesets. iter ( ) . for_each ( |changeset| {
667
645
store. write_changes ( changeset) . expect ( "write changeset" ) ;
@@ -670,17 +648,16 @@ mod test {
670
648
let agg_changeset = store. load_from_persistence ( ) . expect ( "aggregated changeset" ) ;
671
649
672
650
assert_eq ! ( agg_changeset, Some ( agg_test_changesets) ) ;
651
+ Ok ( ( ) )
673
652
}
674
653
675
654
#[ test]
676
- fn insert_and_load_aggregate_changesets_with_blockid_anchor ( ) {
655
+ fn insert_and_load_aggregate_changesets_with_blockid_anchor ( ) -> anyhow :: Result < ( ) > {
677
656
let ( test_changesets, agg_test_changesets) =
678
657
create_test_changesets ( & |height, _time, hash| BlockId { height, hash } ) ;
679
658
680
- let mut store =
681
- Store :: < Keychain , BlockId > :: new_memory ( ) . expect ( "create new memory db store" ) ;
682
- // let mut store = Store::<Keychain, BlockId>::new(Path::new("test_agg.sqlite"))
683
- // .expect("create new file db store");
659
+ let conn = Connection :: open_in_memory ( ) . expect ( "in memory connection" ) ;
660
+ let mut store = Store :: < Keychain , BlockId > :: new ( conn) . expect ( "create new memory db store" ) ;
684
661
685
662
test_changesets. iter ( ) . for_each ( |changeset| {
686
663
store. write_changes ( changeset) . expect ( "write changeset" ) ;
@@ -689,6 +666,7 @@ mod test {
689
666
let agg_changeset = store. load_from_persistence ( ) . expect ( "aggregated changeset" ) ;
690
667
691
668
assert_eq ! ( agg_changeset, Some ( agg_test_changesets) ) ;
669
+ Ok ( ( ) )
692
670
}
693
671
694
672
fn create_test_changesets < A : Anchor + Copy > (
0 commit comments