fix(duckdb): explicitly close connections to release file locks on Windows

DuckDB opens database files with exclusive locks on Windows. Previously
connections were only released via Drop, which may not release the file
handle synchronously, causing "file already in use" errors when
reconnecting or testing connections in quick succession.
This commit is contained in:
t8y2 committed 2026-05-27 13:53:14 +08:00
1 parent bcfad319a6
commit a296bd6c3c
3 files changed
+33 -4

No files matched your search

+3 -1
View File
@@ -529,7 +529,9 @@ impl AppState {
.cloned()
.collect();
for key in keys_to_remove {
conns.remove(&key);
if let Some(PoolKind::DuckDb(con)) = conns.remove(&key) {
crate::db::duckdb_driver::close_connection(con);
}
}
}
+24
View File
@@ -54,6 +54,30 @@ pub fn is_memory_database_path(path: &str) -> bool {
path.trim().eq_ignore_ascii_case(":memory:")
}
/// Closes a DuckDB connection, releasing the file lock.
///
/// Unlike relying on Drop, this calls `duckdb_disconnect` synchronously
/// so the file handle is released before this function returns.
/// On Windows this prevents "file already in use" errors when reconnecting.
pub fn close_connection(con: Arc<Mutex<duckdb::Connection>>) {
match Arc::try_unwrap(con) {
Ok(mutex) => {
match mutex.into_inner() {
Ok(conn) => {
let _ = conn.close();
}
Err(poisoned) => {
let _ = poisoned.into_inner().close();
}
}
}
Err(_) => {
// Arc still referenced elsewhere (e.g. running queries);
// the last holder will drop and close the connection.
}
}
}
#[cfg(test)]
mod tests {
use super::*;