Skip to content

Commit 259057c

Browse files
committed
f Update SQLite Store
1 parent 1684503 commit 259057c

File tree

1 file changed

+38
-63
lines changed
  • lightning-persister/src/sqlite_store

1 file changed

+38
-63
lines changed

lightning-persister/src/sqlite_store/mod.rs

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//! Objects related to [`SqliteStore`] live here.
2+
use crate::utils::check_namespace_key_validity;
3+
24
use lightning::util::persist::KVStore;
35
use lightning::util::string::PrintableString;
46

@@ -15,7 +17,7 @@ pub const DEFAULT_SQLITE_DB_FILE_NAME: &str = "ldk_data.sqlite";
1517
pub 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

7881
impl 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

Comments
 (0)