@@ -12,33 +12,42 @@ Therefore, we need migrations to convert the old schema to the new one.
12
12
- Update the Tree key used in [crate::db::trees]
13
13
*/
14
14
15
- use crate :: { errors:: AtomicResult , Db } ;
15
+ use crate :: { errors:: AtomicResult , resources:: PropVals , Db } ;
16
+
17
+ const RESOURCE_TREE_V0 : & str = "resources" ;
18
+ const RESOURCE_TREE_V1 : & str = "resources_v1" ;
19
+ const RESOURCE_TREE_V2 : & str = "resources_v2" ;
20
+ pub const RESOURCE_TREE_CURRENT : & str = RESOURCE_TREE_V2 ;
21
+
22
+ const REFERENCE_INDEX_V0 : & str = "reference_index" ;
23
+ const REFERENCE_INDEX_V1 : & str = "reference_index_v1" ;
24
+ pub const REFERENCE_INDEX_CURRENT : & str = REFERENCE_INDEX_V1 ;
16
25
17
26
/// Checks the current version(s) of the internal Store, and performs migrations if needed.
18
27
pub fn migrate_maybe ( store : & Db ) -> AtomicResult < ( ) > {
19
28
for tree in store. db . tree_names ( ) {
20
29
match String :: from_utf8_lossy ( & tree) . as_ref ( ) {
21
30
// Add migrations for outdated Trees to this list
22
- "resources" => v0_to_v1 ( store) ?,
23
- "reference_index" => ref_v0_to_v1 ( store) ?,
31
+ RESOURCE_TREE_V0 => res_v0_to_v1 ( store) ?,
32
+ RESOURCE_TREE_V1 => res_v1_to_v2 ( store) ?,
33
+ REFERENCE_INDEX_V0 => ref_v0_to_v1 ( store) ?,
24
34
_other => { }
25
35
}
26
36
}
27
37
Ok ( ( ) )
28
38
}
29
39
30
40
/// Change the subjects from `bincode` to `.as_bytes()`
31
- fn v0_to_v1 ( store : & Db ) -> AtomicResult < ( ) > {
41
+ fn res_v0_to_v1 ( store : & Db ) -> AtomicResult < ( ) > {
32
42
tracing:: warn!( "Migrating resources schema from v0 to v1..." ) ;
33
- let new = store. db . open_tree ( "resources_v1" ) ?;
34
- let old_key = "resources" ;
43
+ let new = store. db . open_tree ( RESOURCE_TREE_V1 ) ?;
44
+ let old_key = RESOURCE_TREE_V0 ;
35
45
let old = store. db . open_tree ( old_key) ?;
36
46
let mut count = 0 ;
37
47
38
48
for item in old. into_iter ( ) {
39
49
let ( subject, resource_bin) = item. expect ( "Unable to convert into iterable" ) ;
40
- let subject: String =
41
- bincode:: deserialize ( & subject) . expect ( "Unable to deserialize subject" ) ;
50
+ let subject: String = String :: from_utf8_lossy ( & subject) . to_string ( ) ;
42
51
new. insert ( subject. as_bytes ( ) , resource_bin) ?;
43
52
count += 1 ;
44
53
}
@@ -73,6 +82,72 @@ fn v0_to_v1(store: &Db) -> AtomicResult<()> {
73
82
Ok ( ( ) )
74
83
}
75
84
85
+ /// add a trailing slash to all "home" subjects
86
+ fn res_v1_to_v2 ( store : & Db ) -> AtomicResult < ( ) > {
87
+ tracing:: warn!( "Migrating resources schema from v1 to v2..." ) ;
88
+ let new = store. db . open_tree ( RESOURCE_TREE_V2 ) ?;
89
+ let old_key = RESOURCE_TREE_V1 ;
90
+ let old = store. db . open_tree ( old_key) ?;
91
+ let mut count = 0 ;
92
+
93
+ fn migrate_subject ( subject : & str ) -> String {
94
+ let url = url:: Url :: parse ( subject) . expect ( "Unable to parse subject URL" ) ;
95
+ if subject != url. to_string ( ) {
96
+ println ! ( "Migrating: {} -> {}" , subject, url. to_string( ) )
97
+ } ;
98
+ url. to_string ( )
99
+ }
100
+
101
+ for item in old. into_iter ( ) {
102
+ let ( subject, resource_bin) = item. expect ( "Unable to convert into iterable" ) ;
103
+ let subject: String = String :: from_utf8_lossy ( & subject) . to_string ( ) ;
104
+
105
+ let mut propvals: PropVals = bincode:: deserialize ( & resource_bin) ?;
106
+
107
+ for ( _prop, val) in propvals. iter_mut ( ) {
108
+ match val {
109
+ crate :: Value :: AtomicUrl ( a) => {
110
+ * a = migrate_subject ( a) ;
111
+ }
112
+ crate :: Value :: ResourceArray ( arr) => {
113
+ for url in arr. iter_mut ( ) {
114
+ match url {
115
+ crate :: values:: SubResource :: Subject ( s) => {
116
+ * s = migrate_subject ( s) ;
117
+ }
118
+ // This skips nested resources
119
+ _other => { }
120
+ }
121
+ }
122
+ }
123
+ // This skips nested resources
124
+ _other => { }
125
+ } ;
126
+ }
127
+ new. insert ( migrate_subject ( & subject) , bincode:: serialize ( & propvals) ?) ?;
128
+ count += 1 ;
129
+ }
130
+
131
+ assert_eq ! (
132
+ new. len( ) ,
133
+ store. resources. len( ) ,
134
+ "Not all resources were migrated."
135
+ ) ;
136
+
137
+ assert ! (
138
+ store. db. drop_tree( old_key) ?,
139
+ "Old resources tree not properly removed."
140
+ ) ;
141
+
142
+ tracing:: warn!( "Rebuilding indexes due to migrating to new version..." ) ;
143
+ store. db . drop_tree ( old_key) ?;
144
+ store. build_index ( true ) ?;
145
+ tracing:: warn!( "Rebuilding index finished!" ) ;
146
+
147
+ tracing:: warn!( "Finished migration of {} resources" , count) ;
148
+ Ok ( ( ) )
149
+ }
150
+
76
151
/// Add `prop_val_sub` index
77
152
fn ref_v0_to_v1 ( store : & Db ) -> AtomicResult < ( ) > {
78
153
tracing:: warn!( "Rebuilding indexes due to migrating to new version..." ) ;
0 commit comments