11//! Objects related to [`SqliteStore`] live here.
2+ use crate :: utils:: check_namespace_key_validity;
3+
24use lightning:: util:: persist:: KVStore ;
35use lightning:: util:: string:: PrintableString ;
46
@@ -15,7 +17,7 @@ pub const DEFAULT_SQLITE_DB_FILE_NAME: &str = "ldk_data.sqlite";
1517pub const DEFAULT_KV_TABLE_NAME : & str = "ldk_data" ;
1618
1719// The current SQLite `user_version`, which we can use if we'd ever need to do a schema migration.
18- const SCHEMA_USER_VERSION : u16 = 1 ;
20+ const SCHEMA_USER_VERSION : u16 = 2 ;
1921
2022/// A [`KVStore`] implementation that writes to and reads from an [SQLite] database.
2123///
@@ -56,8 +58,9 @@ impl SqliteStore {
5658 let sql = format ! (
5759 "CREATE TABLE IF NOT EXISTS {} (
5860 namespace TEXT NOT NULL,
61+ sub_namespace TEXT DEFAULT \" \" NOT NULL,
5962 key TEXT NOT NULL CHECK (key <> ''),
60- value BLOB, PRIMARY KEY ( namespace, key )
63+ value BLOB, PRIMARY KEY ( namespace, sub_namespace, key )
6164 );" ,
6265 kv_table_name
6366 ) ;
@@ -76,27 +79,13 @@ impl SqliteStore {
7679}
7780
7881impl KVStore for SqliteStore {
79- fn read ( & self , namespace : & str , key : & str ) -> std:: io:: Result < Vec < u8 > > {
80- if key. is_empty ( ) {
81- debug_assert ! ( false , "Failed to read {}/{}: key may not be empty." ,
82- PrintableString ( namespace) , PrintableString ( key) ) ;
83- let msg = format ! ( "Failed to read {}/{}: key may not be empty." ,
84- PrintableString ( namespace) , PrintableString ( key) ) ;
85- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
86- }
87-
88- if namespace. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) ||
89- key. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) {
90- debug_assert ! ( false , "Failed to read {}/{}: namespace and key must be valid ASCII
91- strings." , PrintableString ( namespace) , PrintableString ( key) ) ;
92- let msg = format ! ( "Failed to read {}/{}: namespace and key must be valid ASCII strings." ,
93- PrintableString ( namespace) , PrintableString ( key) ) ;
94- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
95- }
82+ fn read ( & self , namespace : & str , sub_namespace : & str , key : & str ) -> std:: io:: Result < Vec < u8 > > {
83+ check_namespace_key_validity ( namespace, sub_namespace, Some ( key) , "read" ) ?;
9684
9785 let locked_conn = self . connection . lock ( ) . unwrap ( ) ;
9886 let sql =
99- format ! ( "SELECT value FROM {} WHERE namespace=:namespace AND key=:key;" , self . kv_table_name) ;
87+ format ! ( "SELECT value FROM {} WHERE namespace=:namespace AND sub_namespace=:sub_namespace AND key=:key;" ,
88+ self . kv_table_name) ;
10089
10190 let mut stmt = locked_conn. prepare_cached ( & sql) . map_err ( |e| {
10291 let msg = format ! ( "Failed to prepare statement: {}" , e) ;
@@ -107,46 +96,35 @@ impl KVStore for SqliteStore {
10796 . query_row (
10897 named_params ! {
10998 ":namespace" : namespace,
99+ ":sub_namespace" : sub_namespace,
110100 ":key" : key,
111101 } ,
112102 |row| row. get ( 0 ) ,
113103 )
114104 . map_err ( |e| match e {
115105 rusqlite:: Error :: QueryReturnedNoRows => {
116106 let msg =
117- format ! ( "Failed to read as key could not be found: {}/{}" , namespace, key) ;
107+ format ! ( "Failed to read as key could not be found: {}/{}/{}" ,
108+ PrintableString ( namespace) , PrintableString ( sub_namespace) , PrintableString ( key) ) ;
118109 std:: io:: Error :: new ( std:: io:: ErrorKind :: NotFound , msg)
119110 }
120111 e => {
121- let msg = format ! ( "Failed to read from key {}/{}: {}" , namespace, key, e) ;
112+ let msg = format ! ( "Failed to read from key {}/{}/{}: {}" ,
113+ PrintableString ( namespace) , PrintableString ( sub_namespace) ,
114+ PrintableString ( key) , e) ;
122115 std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg)
123116 }
124117 } ) ?;
125118 Ok ( res)
126119 }
127120
128- fn write ( & self , namespace : & str , key : & str , buf : & [ u8 ] ) -> std:: io:: Result < ( ) > {
129- if key. is_empty ( ) {
130- debug_assert ! ( false , "Failed to write {}/{}: key may not be empty." ,
131- PrintableString ( namespace) , PrintableString ( key) ) ;
132- let msg = format ! ( "Failed to write {}/{}: key may not be empty." ,
133- PrintableString ( namespace) , PrintableString ( key) ) ;
134- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
135- }
136-
137- if namespace. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) ||
138- key. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) {
139- debug_assert ! ( false , "Failed to write {}/{}: namespace and key must be valid ASCII
140- strings." , PrintableString ( namespace) , PrintableString ( key) ) ;
141- let msg = format ! ( "Failed to write {}/{}: namespace and key must be valid ASCII strings." ,
142- PrintableString ( namespace) , PrintableString ( key) ) ;
143- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
144- }
121+ fn write ( & self , namespace : & str , sub_namespace : & str , key : & str , buf : & [ u8 ] ) -> std:: io:: Result < ( ) > {
122+ check_namespace_key_validity ( namespace, sub_namespace, Some ( key) , "write" ) ?;
145123
146124 let locked_conn = self . connection . lock ( ) . unwrap ( ) ;
147125
148126 let sql = format ! (
149- "INSERT OR REPLACE INTO {} (namespace, key, value) VALUES (:namespace, :key, :value);" ,
127+ "INSERT OR REPLACE INTO {} (namespace, sub_namespace, key, value) VALUES (:namespace, :sub_namespace , :key, :value);" ,
150128 self . kv_table_name
151129 ) ;
152130
@@ -158,38 +136,26 @@ impl KVStore for SqliteStore {
158136 stmt. execute (
159137 named_params ! {
160138 ":namespace" : namespace,
139+ ":sub_namespace" : sub_namespace,
161140 ":key" : key,
162141 ":value" : buf,
163142 } ,
164143 )
165144 . map ( |_| ( ) )
166145 . map_err ( |e| {
167- let msg = format ! ( "Failed to write to key {}/{}: {}" , namespace, key, e) ;
146+ let msg = format ! ( "Failed to write to key {}/{}/{}: {}" ,
147+ PrintableString ( namespace) , PrintableString ( sub_namespace) ,
148+ PrintableString ( key) , e) ;
168149 std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg)
169150 } )
170151 }
171152
172- fn remove ( & self , namespace : & str , key : & str ) -> lightning:: io:: Result < ( ) > {
173- if key. is_empty ( ) {
174- debug_assert ! ( false , "Failed to remove {}/{}: key may not be empty." ,
175- PrintableString ( namespace) , PrintableString ( key) ) ;
176- let msg = format ! ( "Failed to remove {}/{}: key may not be empty." ,
177- PrintableString ( namespace) , PrintableString ( key) ) ;
178- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
179- }
180-
181- if namespace. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) ||
182- key. chars ( ) . any ( |c| !c. is_ascii ( ) || c. is_control ( ) ) {
183- debug_assert ! ( false , "Failed to remove {}/{}: namespace and key must be valid ASCII
184- strings." , PrintableString ( namespace) , PrintableString ( key) ) ;
185- let msg = format ! ( "Failed to remove {}/{}: namespace and key must be valid ASCII strings." ,
186- PrintableString ( namespace) , PrintableString ( key) ) ;
187- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg) ) ;
188- }
153+ fn remove ( & self , namespace : & str , sub_namespace : & str , key : & str , lazy : bool ) -> std:: io:: Result < ( ) > {
154+ check_namespace_key_validity ( namespace, sub_namespace, Some ( key) , "remove" ) ?;
189155
190156 let locked_conn = self . connection . lock ( ) . unwrap ( ) ;
191157
192- let sql = format ! ( "DELETE FROM {} WHERE namespace=:namespace AND key=:key;" , self . kv_table_name) ;
158+ let sql = format ! ( "DELETE FROM {} WHERE namespace=:namespace AND sub_namespace=:sub_namespace AND key=:key;" , self . kv_table_name) ;
193159
194160 let mut stmt = locked_conn. prepare_cached ( & sql) . map_err ( |e| {
195161 let msg = format ! ( "Failed to prepare statement: {}" , e) ;
@@ -199,20 +165,25 @@ impl KVStore for SqliteStore {
199165 stmt. execute (
200166 named_params ! {
201167 ":namespace" : namespace,
168+ ":sub_namespace" : sub_namespace,
202169 ":key" : key,
203170 } ,
204171 )
205172 . map_err ( |e| {
206- let msg = format ! ( "Failed to delete key {}/{}: {}" , namespace, key, e) ;
173+ let msg = format ! ( "Failed to delete key {}/{}/{}: {}" ,
174+ PrintableString ( namespace) , PrintableString ( sub_namespace) ,
175+ PrintableString ( key) , e) ;
207176 std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg)
208177 } ) ?;
209178 Ok ( ( ) )
210179 }
211180
212- fn list ( & self , namespace : & str ) -> std:: io:: Result < Vec < String > > {
181+ fn list ( & self , namespace : & str , sub_namespace : & str ) -> std:: io:: Result < Vec < String > > {
182+ check_namespace_key_validity ( namespace, sub_namespace, None , "list" ) ?;
183+
213184 let locked_conn = self . connection . lock ( ) . unwrap ( ) ;
214185
215- let sql = format ! ( "SELECT key FROM {} WHERE namespace=:namespace" , self . kv_table_name) ;
186+ let sql = format ! ( "SELECT key FROM {} WHERE namespace=:namespace AND sub_namespace=:sub_namespace " , self . kv_table_name) ;
216187 let mut stmt = locked_conn. prepare_cached ( & sql) . map_err ( |e| {
217188 let msg = format ! ( "Failed to prepare statement: {}" , e) ;
218189 std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg)
@@ -221,7 +192,11 @@ impl KVStore for SqliteStore {
221192 let mut keys = Vec :: new ( ) ;
222193
223194 let rows_iter = stmt
224- . query_map ( named_params ! { ":namespace" : namespace, } , |row| row. get ( 0 ) )
195+ . query_map (
196+ named_params ! {
197+ ":namespace" : namespace,
198+ ":sub_namespace" : sub_namespace,
199+ } , |row| row. get ( 0 ) )
225200 . map_err ( |e| {
226201 let msg = format ! ( "Failed to retrieve queried rows: {}" , e) ;
227202 std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , msg)
0 commit comments