mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
fix(sql): prepared statements leak raw state (fixes #1705)
This commit is contained in:
parent
bbc8536068
commit
2b4d9f8536
@ -112,12 +112,21 @@ function upsert<T extends {}>(tableName: string, primaryKey: string, rec: T) {
|
|||||||
execute(query, rec);
|
execute(query, rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stmt(sql: string) {
|
/**
|
||||||
if (!(sql in statementCache)) {
|
* For the given SQL query, returns a prepared statement. For the same query (string comparison), the same statement is returned.
|
||||||
statementCache[sql] = dbConnection.prepare(sql);
|
*
|
||||||
|
* @param sql the SQL query for which to return a prepared statement.
|
||||||
|
* @param isRaw indicates whether `.raw()` is going to be called on the prepared statement in order to return the raw rows (e.g. via {@link getRawRows()}). The reason is that the raw state is preserved in the saved statement and would break non-raw calls for the same query.
|
||||||
|
* @returns the corresponding {@link Statement}.
|
||||||
|
*/
|
||||||
|
function stmt(sql: string, isRaw?: boolean) {
|
||||||
|
const key = (isRaw ? "raw/" + sql : sql);
|
||||||
|
|
||||||
|
if (!(key in statementCache)) {
|
||||||
|
statementCache[key] = dbConnection.prepare(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return statementCache[sql];
|
return statementCache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRow<T>(query: string, params: Params = []): T {
|
function getRow<T>(query: string, params: Params = []): T {
|
||||||
@ -172,7 +181,7 @@ function getRows<T>(query: string, params: Params = []): T[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] {
|
function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] {
|
||||||
return (wrap(query, (s) => s.raw().all(params)) as T[]) || [];
|
return (wrap(query, (s) => s.raw().all(params), true) as T[]) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function iterateRows<T>(query: string, params: Params = []): IterableIterator<T> {
|
function iterateRows<T>(query: string, params: Params = []): IterableIterator<T> {
|
||||||
@ -234,7 +243,10 @@ function executeScript(query: string): DatabaseType {
|
|||||||
return dbConnection.exec(query);
|
return dbConnection.exec(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrap(query: string, func: (statement: Statement) => unknown): unknown {
|
/**
|
||||||
|
* @param isRaw indicates whether `.raw()` is going to be called on the prepared statement in order to return the raw rows (e.g. via {@link getRawRows()}). The reason is that the raw state is preserved in the saved statement and would break non-raw calls for the same query.
|
||||||
|
*/
|
||||||
|
function wrap(query: string, func: (statement: Statement) => unknown, isRaw?: boolean): unknown {
|
||||||
const startTimestamp = Date.now();
|
const startTimestamp = Date.now();
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
@ -243,7 +255,7 @@ function wrap(query: string, func: (statement: Statement) => unknown): unknown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = func(stmt(query));
|
result = func(stmt(query, isRaw));
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.message.includes("The database connection is not open")) {
|
if (e.message.includes("The database connection is not open")) {
|
||||||
// this often happens on killing the app which puts these alerts in front of user
|
// this often happens on killing the app which puts these alerts in front of user
|
||||||
|
Loading…
x
Reference in New Issue
Block a user