1
+ use std:: collections:: HashMap ;
2
+ use std:: path:: Path ;
3
+ use grovedb:: { Element , Error , GroveDb } ;
4
+ use minicbor:: decode:: { Token , Tokenizer } ;
5
+
6
+ pub struct Drive {
7
+ grove : GroveDb ,
8
+ }
9
+
10
+ // split_contract_indices will take an array of indices and construct an array of group indices
11
+ // grouped indices will group on identical first indices then on identical second indices
12
+ // if the first index is common and so forth
13
+ pub fn split_contract_indices ( contract_indices : Vec < Vec < Vec < u8 > > > ) -> HashMap < & [ u8 ] , V > {
14
+
15
+ }
16
+
17
+ impl Drive {
18
+ pub fn open < P : AsRef < Path > > ( path : P ) -> Result < Self , Error > {
19
+ match GroveDb :: open ( path) {
20
+ Ok ( grove) => Ok ( Drive {
21
+ grove,
22
+ } ) ,
23
+ Err ( e) => Err ( e) ,
24
+ }
25
+ }
26
+
27
+ fn store ( & mut self , document_cbor : & [ u8 ] , contract_indices_cbor : & [ u8 ] ) -> Result < ( ) , Error > {
28
+ // first we need to deserialize the document and contract indices
29
+ let document : HashMap < str , V > = minicbor:: decode ( document_cbor. as_ref ( ) ) ?;
30
+ let mut contract_id: & [ u8 ] = & [ ] ;
31
+ let mut document_id: & [ u8 ] = & [ ] ;
32
+ match document. get ( "contractID" ) {
33
+ Some ( recovered_contract_id) => {
34
+ contract_id = recovered_contract_id;
35
+ } ,
36
+ None ( ) => Err ( ( ) )
37
+ }
38
+ match document. get ( "documentID" ) {
39
+ Some ( recovered_document_id) => {
40
+ document_id = recovered_document_id;
41
+ } ,
42
+ None ( ) => Err ( ( ) )
43
+ }
44
+
45
+ let contract_indices : Vec < Vec < Vec < u8 > > > = minicbor:: decode ( contract_indices_cbor. as_ref ( ) ) ?;
46
+
47
+ // second we need to construct the path for documents on the contract
48
+ // the path is
49
+ // * Document and Contract root tree
50
+ // * Contract ID recovered from document
51
+ // * 0 to signify Documents and not Contract
52
+ let mut contract_path = & [ b"5" , contract_id, b"0" ] ;
53
+
54
+ // third we need to store the document for it's primary key
55
+ let primary_key_path = contract_path. clone ( ) . append ( document_id) ;
56
+ let document_element = Element :: Item ( Vec :: from ( document_cbor) ) ;
57
+ self . grove . insert ( primary_key_path, Vec :: from ( document_id) , document_element) ?;
58
+
59
+ // fourth we need to store a reference to the document for each index
60
+ for ( grouped_contract_index_key, grouped) in split_contract_indices ( contract_indices) {
61
+
62
+ // if there is a grouping on the contract index then we need to insert a tree
63
+ let index_path = contract_path. clone ( ) . append ( grouped_contract_index_key) ;
64
+ let document_index = Element :: Tree ( ) ;
65
+ self . grove . insert ( index_path, Vec :: from ( document_id) , document_index) ?;
66
+
67
+ let index_path = contract_path. clone ( ) . append ( contract_index) ;
68
+ let document_index = Element :: Reference ( primary_key_path) ;
69
+ self . grove . insert ( index_path, Vec :: from ( document_id) , document_index) ?;
70
+ } ;
71
+ }
72
+ }
0 commit comments