-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Desktop,Mobile,Cli: Fixes #11630: Adjust how items are queried by ID #11657
Changes from all commits
e969d7e
f245085
b17fc09
b888206
3933180
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,12 @@ export interface DeleteOptions { | |
toTrashParentId?: string; | ||
} | ||
|
||
interface IdsWhereClauseOptions { | ||
ids: string[]; | ||
field?: string; | ||
negate?: boolean; | ||
} | ||
|
||
class BaseModel { | ||
|
||
// TODO: This ancient part of Joplin about model types is a bit of a | ||
|
@@ -345,15 +351,24 @@ class BaseModel { | |
return this.modelSelectAll(q.sql, q.params); | ||
} | ||
|
||
public static whereIdsInSql({ ids, field = 'id', negate = false }: IdsWhereClauseOptions) { | ||
const idsPlaceholders = ids.map(() => '?').join(','); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In response to closing this PR due to the bind parameter limitation - why not just strip single quotes from each id instead of replacing with a bind param here, and return the sql only in this method? Any existing usages where this method was introduced would already be broken if the value contained 1 or more single quotes in it, so stripping quotes here couldn't make anything worse, and would fix the issue at hand There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the feedback! I'm linking to a commit that does something similar to this suggestion(personalizedrefrigerator@8983a12) — it escapes single quotes while building the SQL queries. Before re-opening the pull request, I plan to do more manual testing, explore another possible solution, and/or refactor how |
||
return { | ||
sql: `${this.db().escapeField(field)} ${negate ? 'NOT' : ''} IN (${idsPlaceholders})`, | ||
params: ids, | ||
}; | ||
} | ||
|
||
public static async byIds(ids: string[], options: LoadOptions = null) { | ||
if (!ids.length) return []; | ||
if (!options) options = {}; | ||
if (!options.fields) options.fields = '*'; | ||
|
||
let sql = `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``; | ||
sql += ` WHERE id IN ('${ids.join('\',\'')}')`; | ||
const q = this.applySqlOptions(options, sql); | ||
return this.modelSelectAll(q.sql); | ||
const idsSql = this.whereIdsInSql({ ids }); | ||
sql += ` WHERE ${idsSql.sql}`; | ||
const q = this.applySqlOptions(options, sql, idsSql.params); | ||
return this.modelSelectAll(q); | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied | ||
|
@@ -750,8 +765,9 @@ class BaseModel { | |
|
||
options = this.modOptions(options); | ||
const idFieldName = options.idFieldName ? options.idFieldName : 'id'; | ||
const sql = `DELETE FROM ${this.tableName()} WHERE ${idFieldName} IN ('${ids.join('\',\'')}')`; | ||
await this.db().exec(sql); | ||
const idsCondition = this.whereIdsInSql({ ids, field: idFieldName }); | ||
const sql = `DELETE FROM ${this.tableName()} WHERE ${idsCondition.sql}`; | ||
await this.db().exec(sql, idsCondition.params); | ||
} | ||
|
||
public static db() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whereIdsInSql
is responsible for generating theids IN (...)
clause used elsewhere.