mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
fix(ext/node): SQLite reset guards to prevent database locks (#28298)
Fixes https://github.com/denoland/deno/issues/28295
This commit is contained in:
parent
b9cffda7c9
commit
e66ef32a8f
2 changed files with 29 additions and 4 deletions
|
@ -391,6 +391,14 @@ impl StatementSync {
|
|||
}
|
||||
}
|
||||
|
||||
struct ResetGuard<'a>(&'a StatementSync);
|
||||
|
||||
impl<'a> Drop for ResetGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.0.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Represents a single prepared statement. Cannot be initialized directly via constructor.
|
||||
// Instances are created using `DatabaseSync#prepare`.
|
||||
//
|
||||
|
@ -416,6 +424,8 @@ impl StatementSync {
|
|||
|
||||
self.bind_params(scope, params)?;
|
||||
|
||||
let _reset = ResetGuard(self);
|
||||
|
||||
let entry = self.read_row(scope)?;
|
||||
let result = entry
|
||||
.map(|r| r.into())
|
||||
|
@ -438,9 +448,10 @@ impl StatementSync {
|
|||
let db = db.as_ref().ok_or(SqliteError::InUse)?;
|
||||
|
||||
self.bind_params(scope, params)?;
|
||||
self.step()?;
|
||||
|
||||
self.reset()?;
|
||||
let _reset = ResetGuard(self);
|
||||
|
||||
self.step()?;
|
||||
|
||||
Ok(RunStatementResult {
|
||||
last_insert_rowid: db.last_insert_rowid(),
|
||||
|
@ -460,12 +471,12 @@ impl StatementSync {
|
|||
let mut arr = vec![];
|
||||
|
||||
self.bind_params(scope, params)?;
|
||||
|
||||
let _reset = ResetGuard(self);
|
||||
while let Some(result) = self.read_row(scope)? {
|
||||
arr.push(result.into());
|
||||
}
|
||||
|
||||
self.reset()?;
|
||||
|
||||
let arr = v8::Array::new_with_elements(scope, &arr);
|
||||
Ok(arr)
|
||||
}
|
||||
|
|
|
@ -272,3 +272,17 @@ Deno.test("[node/sqlite] error message", () => {
|
|||
"NOT NULL constraint failed: foo.b",
|
||||
);
|
||||
});
|
||||
|
||||
// https://github.com/denoland/deno/issues/28295
|
||||
Deno.test("[node/sqlite] StatementSync reset guards don't lock db", () => {
|
||||
const db = new DatabaseSync(":memory:");
|
||||
|
||||
db.exec("CREATE TABLE foo(a integer, b text)");
|
||||
db.exec("CREATE TABLE bar(a integer, b text)");
|
||||
|
||||
const stmt = db.prepare("SELECT name FROM sqlite_master WHERE type='table' ");
|
||||
|
||||
assertEquals(stmt.get(), { name: "foo", __proto__: null });
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS foo");
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue