Fixes
This commit is contained in:
parent
71abb1ed7d
commit
689b85e6f2
3 changed files with 53 additions and 6 deletions
45
src/db.rs
45
src/db.rs
|
|
@ -76,13 +76,45 @@ impl Db {
|
|||
|
||||
pub async fn list_keys(&self, prefix: &str) -> Result<Vec<String>, AppError> {
|
||||
let conn = self.conn.clone();
|
||||
let pattern = format!("{prefix}%");
|
||||
let prefix = prefix.to_string();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = conn.lock().unwrap();
|
||||
let mut stmt = conn.prepare_cached("SELECT key FROM kv WHERE key LIKE ?1 ORDER BY key")?;
|
||||
let keys = stmt
|
||||
.query_map(params![pattern], |row| row.get(0))?
|
||||
.collect::<Result<Vec<String>, _>>()?;
|
||||
if prefix.is_empty() {
|
||||
let mut stmt = conn.prepare_cached("SELECT key FROM kv ORDER BY key")?;
|
||||
let keys = stmt
|
||||
.query_map([], |row| row.get(0))?
|
||||
.collect::<Result<Vec<String>, _>>()?;
|
||||
return Ok(keys);
|
||||
}
|
||||
// Compute exclusive upper bound: increment last non-0xFF byte
|
||||
let upper = {
|
||||
let mut bytes = prefix.as_bytes().to_vec();
|
||||
let mut result = None;
|
||||
while let Some(last) = bytes.pop() {
|
||||
if last < 0xFF {
|
||||
bytes.push(last + 1);
|
||||
result = Some(String::from_utf8_lossy(&bytes).into_owned());
|
||||
break;
|
||||
}
|
||||
}
|
||||
result
|
||||
};
|
||||
let keys = match &upper {
|
||||
Some(end) => {
|
||||
let mut stmt = conn.prepare_cached(
|
||||
"SELECT key FROM kv WHERE key >= ?1 AND key < ?2 ORDER BY key",
|
||||
)?;
|
||||
stmt.query_map(params![prefix, end], |row| row.get(0))?
|
||||
.collect::<Result<Vec<String>, _>>()?
|
||||
}
|
||||
None => {
|
||||
let mut stmt = conn.prepare_cached(
|
||||
"SELECT key FROM kv WHERE key >= ?1 ORDER BY key",
|
||||
)?;
|
||||
stmt.query_map(params![prefix], |row| row.get(0))?
|
||||
.collect::<Result<Vec<String>, _>>()?
|
||||
}
|
||||
};
|
||||
Ok(keys)
|
||||
})
|
||||
.await
|
||||
|
|
@ -120,6 +152,7 @@ impl Db {
|
|||
let conn = self.conn.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = conn.lock().unwrap();
|
||||
conn.execute_batch("BEGIN")?;
|
||||
let mut stmt = conn.prepare_cached(
|
||||
"INSERT INTO kv (key, volumes, size) VALUES (?1, ?2, ?3)
|
||||
ON CONFLICT(key) DO UPDATE SET volumes = ?2, size = ?3",
|
||||
|
|
@ -127,6 +160,8 @@ impl Db {
|
|||
for (key, volumes, size) in &records {
|
||||
stmt.execute(params![key, encode_volumes(volumes), size])?;
|
||||
}
|
||||
drop(stmt);
|
||||
conn.execute_batch("COMMIT")?;
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue