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.
|
// Represents a single prepared statement. Cannot be initialized directly via constructor.
|
||||||
// Instances are created using `DatabaseSync#prepare`.
|
// Instances are created using `DatabaseSync#prepare`.
|
||||||
//
|
//
|
||||||
|
@ -416,6 +424,8 @@ impl StatementSync {
|
||||||
|
|
||||||
self.bind_params(scope, params)?;
|
self.bind_params(scope, params)?;
|
||||||
|
|
||||||
|
let _reset = ResetGuard(self);
|
||||||
|
|
||||||
let entry = self.read_row(scope)?;
|
let entry = self.read_row(scope)?;
|
||||||
let result = entry
|
let result = entry
|
||||||
.map(|r| r.into())
|
.map(|r| r.into())
|
||||||
|
@ -438,9 +448,10 @@ impl StatementSync {
|
||||||
let db = db.as_ref().ok_or(SqliteError::InUse)?;
|
let db = db.as_ref().ok_or(SqliteError::InUse)?;
|
||||||
|
|
||||||
self.bind_params(scope, params)?;
|
self.bind_params(scope, params)?;
|
||||||
self.step()?;
|
|
||||||
|
|
||||||
self.reset()?;
|
let _reset = ResetGuard(self);
|
||||||
|
|
||||||
|
self.step()?;
|
||||||
|
|
||||||
Ok(RunStatementResult {
|
Ok(RunStatementResult {
|
||||||
last_insert_rowid: db.last_insert_rowid(),
|
last_insert_rowid: db.last_insert_rowid(),
|
||||||
|
@ -460,12 +471,12 @@ impl StatementSync {
|
||||||
let mut arr = vec![];
|
let mut arr = vec![];
|
||||||
|
|
||||||
self.bind_params(scope, params)?;
|
self.bind_params(scope, params)?;
|
||||||
|
|
||||||
|
let _reset = ResetGuard(self);
|
||||||
while let Some(result) = self.read_row(scope)? {
|
while let Some(result) = self.read_row(scope)? {
|
||||||
arr.push(result.into());
|
arr.push(result.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reset()?;
|
|
||||||
|
|
||||||
let arr = v8::Array::new_with_elements(scope, &arr);
|
let arr = v8::Array::new_with_elements(scope, &arr);
|
||||||
Ok(arr)
|
Ok(arr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,3 +272,17 @@ Deno.test("[node/sqlite] error message", () => {
|
||||||
"NOT NULL constraint failed: foo.b",
|
"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