Chore: Migrate SQL queries in preparation for web support (#10670)

pull/10671/head
Henry Heino 2024-07-01 10:56:40 -07:00 committed by GitHub
parent 337d50437b
commit d89be23069
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 33 additions and 33 deletions

View File

@ -346,7 +346,7 @@ class BaseModel {
if (!options.fields) options.fields = '*';
let sql = `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``;
sql += ` WHERE id IN ("${ids.join('","')}")`;
sql += ` WHERE id IN ('${ids.join('\',\'')}')`;
const q = this.applySqlOptions(options, sql);
return this.modelSelectAll(q.sql);
}
@ -745,7 +745,7 @@ class BaseModel {
options = this.modOptions(options);
const idFieldName = options.idFieldName ? options.idFieldName : 'id';
const sql = `DELETE FROM ${this.tableName()} WHERE ${idFieldName} IN ("${ids.join('","')}")`;
const sql = `DELETE FROM ${this.tableName()} WHERE ${idFieldName} IN ('${ids.join('\',\'')}')`;
await this.db().exec(sql);
}

View File

@ -312,7 +312,7 @@ export default class JoplinDatabase extends Database {
throw new Error(`\`notes_fts\` (${countFieldsNotesFts} fields) must have the same number of fields as \`items_fts\` (${countFieldsItemsFts} fields) for the search engine BM25 algorithm to work`);
}
const tableRows = await this.selectAll('SELECT name FROM sqlite_master WHERE type="table"');
const tableRows = await this.selectAll('SELECT name FROM sqlite_master WHERE type=\'table\'');
for (let i = 0; i < tableRows.length; i++) {
const tableName = tableRows[i].name;
@ -416,7 +416,7 @@ export default class JoplinDatabase extends Database {
if (targetVersion === 4) {
queries.push('INSERT INTO settings (`key`, `value`) VALUES (\'sync.3.context\', (SELECT `value` FROM settings WHERE `key` = \'sync.context\'))');
queries.push('DELETE FROM settings WHERE `key` = "sync.context"');
queries.push('DELETE FROM settings WHERE `key` = \'sync.context\'');
}
if (targetVersion === 5) {

View File

@ -247,7 +247,7 @@ export default class BaseItem extends BaseModel {
let output: any[] = [];
for (let i = 0; i < classes.length; i++) {
const ItemClass = this.getClass(classes[i]);
const sql = `SELECT * FROM ${ItemClass.tableName()} WHERE id IN ("${ids.join('","')}")`;
const sql = `SELECT * FROM ${ItemClass.tableName()} WHERE id IN ('${ids.join('\',\'')}')`;
const models = await ItemClass.modelSelectAll(sql);
output = output.concat(models);
}
@ -261,7 +261,7 @@ export default class BaseItem extends BaseModel {
const fields = options && options.fields ? options.fields : [];
const ItemClass = this.getClassByItemType(itemType);
const fieldsSql = fields.length ? this.db().escapeFields(fields) : '*';
const sql = `SELECT ${fieldsSql} FROM ${ItemClass.tableName()} WHERE id IN ("${ids.join('","')}")`;
const sql = `SELECT ${fieldsSql} FROM ${ItemClass.tableName()} WHERE id IN ('${ids.join('\',\'')}')`;
return ItemClass.modelSelectAll(sql);
}
@ -300,7 +300,7 @@ export default class BaseItem extends BaseModel {
// since no other client have (or should have) them.
let conflictNoteIds: string[] = [];
if (this.modelType() === BaseModel.TYPE_NOTE) {
const conflictNotes = await this.db().selectAll(`SELECT id FROM notes WHERE id IN ("${ids.join('","')}") AND is_conflict = 1`);
const conflictNotes = await this.db().selectAll(`SELECT id FROM notes WHERE id IN ('${ids.join('\',\'')}') AND is_conflict = 1`);
conflictNoteIds = conflictNotes.map((n: NoteEntity) => {
return n.id;
});
@ -654,7 +654,7 @@ export default class BaseItem extends BaseModel {
whereSql = [`(encryption_applied = 1 OR (${blobDownloadedButEncryptedSql})`];
}
if (exclusions.length) whereSql.push(`id NOT IN ("${exclusions.join('","')}")`);
if (exclusions.length) whereSql.push(`id NOT IN ('${exclusions.join('\',\'')}')`);
const sql = sprintf(
`
@ -936,7 +936,7 @@ export default class BaseItem extends BaseModel {
});
if (!ids.length) continue;
await this.db().exec(`UPDATE sync_items SET force_sync = 1 WHERE item_id IN ("${ids.join('","')}")`);
await this.db().exec(`UPDATE sync_items SET force_sync = 1 WHERE item_id IN ('${ids.join('\',\'')}')`);
}
}

View File

@ -247,7 +247,7 @@ export default class Folder extends BaseItem {
// The remaining folders, that don't contain any notes are sorted by their own user_updated_time
public static async orderByLastModified(folders: FolderEntity[], dir = 'DESC') {
dir = dir.toUpperCase();
const sql = 'select parent_id, max(user_updated_time) content_updated_time from notes where parent_id != "" group by parent_id';
const sql = 'select parent_id, max(user_updated_time) content_updated_time from notes where parent_id != \'\' group by parent_id';
const rows = await this.db().selectAll(sql);
const folderIdToTime: Record<string, number> = {};
@ -388,7 +388,7 @@ export default class Folder extends BaseItem {
}
public static async rootSharedFolders(): Promise<FolderEntity[]> {
return this.db().selectAll('SELECT id, share_id FROM folders WHERE parent_id = "" AND share_id != ""');
return this.db().selectAll('SELECT id, share_id FROM folders WHERE parent_id = \'\' AND share_id != \'\'');
}
public static async rootShareFoldersByKeyId(keyId: string): Promise<FolderEntity[]> {
@ -431,9 +431,9 @@ export default class Folder extends BaseItem {
// if they've been moved out of a shared folder.
// await this.unshareItems(ModelType.Folder, sharedFolderIds);
const sql = ['SELECT id, parent_id FROM folders WHERE share_id != ""'];
const sql = ['SELECT id, parent_id FROM folders WHERE share_id != \'\''];
if (sharedFolderIds.length) {
sql.push(` AND id NOT IN ("${sharedFolderIds.join('","')}")`);
sql.push(` AND id NOT IN ('${sharedFolderIds.join('\',\'')}')`);
}
const foldersToUnshare: FolderEntity[] = await this.db().selectAll(sql.join(' '));
@ -650,7 +650,7 @@ export default class Folder extends BaseItem {
const query = activeShareIds.length ? `
SELECT ${this.db().escapeFields(fields)} FROM ${tableName}
WHERE share_id != "" AND share_id NOT IN ("${activeShareIds.join('","')}")
WHERE share_id != '' AND share_id NOT IN ('${activeShareIds.join('\',\'')}')
` : `
SELECT ${this.db().escapeFields(fields)} FROM ${tableName}
WHERE share_id != ''

View File

@ -896,7 +896,7 @@ export default class Note extends BaseItem {
const sql = `
UPDATE notes
SET ${updateSql.join(', ')}
WHERE id IN ("${processIds.join('","')}")
WHERE id IN ('${processIds.join('\',\'')}')
`;
await this.db().exec({ sql, params });

View File

@ -91,7 +91,7 @@ export default class NoteResource extends BaseModel {
FROM note_resources
LEFT JOIN notes
ON notes.id = note_resources.note_id
WHERE resource_id IN ("${resourceIds.join('", "')}") AND is_associated = 1
WHERE resource_id IN ('${resourceIds.join('\', \'')}') AND is_associated = 1
`);
const output: Record<string, NoteEntity[]> = {};

View File

@ -12,7 +12,7 @@ export default class NoteTag extends BaseItem {
public static async byNoteIds(noteIds: string[]) {
if (!noteIds.length) return [];
return this.modelSelectAll(`SELECT * FROM note_tags WHERE note_id IN ("${noteIds.join('","')}")`);
return this.modelSelectAll(`SELECT * FROM note_tags WHERE note_id IN ('${noteIds.join('\',\'')}')`);
}
public static async tagIdsByNoteId(noteId: string) {

View File

@ -76,7 +76,7 @@ export default class Resource extends BaseItem {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public static fetchStatuses(resourceIds: string[]): Promise<any[]> {
if (!resourceIds.length) return Promise.resolve([]);
return this.db().selectAll(`SELECT resource_id, fetch_status FROM resource_local_states WHERE resource_id IN ("${resourceIds.join('","')}")`);
return this.db().selectAll(`SELECT resource_id, fetch_status FROM resource_local_states WHERE resource_id IN ('${resourceIds.join('\',\'')}')`);
}
public static sharedResourceIds(): Promise<string[]> {
@ -107,7 +107,7 @@ export default class Resource extends BaseItem {
}
public static async resetFetchErrorStatus(resourceId: string) {
await this.db().exec('UPDATE resource_local_states SET fetch_status = ?, fetch_error = "" WHERE resource_id = ?', [Resource.FETCH_STATUS_IDLE, resourceId]);
await this.db().exec('UPDATE resource_local_states SET fetch_status = ?, fetch_error = \'\' WHERE resource_id = ?', [Resource.FETCH_STATUS_IDLE, resourceId]);
await this.resetOcrStatus(resourceId);
}
@ -368,7 +368,7 @@ export default class Resource extends BaseItem {
public static async downloadedButEncryptedBlobCount(excludedIds: string[] = null) {
let excludedSql = '';
if (excludedIds && excludedIds.length) {
excludedSql = `AND resource_id NOT IN ("${excludedIds.join('","')}")`;
excludedSql = `AND resource_id NOT IN ('${excludedIds.join('\',\'')}')`;
}
const r = await this.db().selectOne(`
@ -520,7 +520,7 @@ export default class Resource extends BaseItem {
WHERE
ocr_status = ? AND
encryption_applied = 0 AND
mime IN ("${supportedMimeTypes.join('","')}")
mime IN ('${supportedMimeTypes.join('\',\'')}')
`,
params: [
ResourceOcrStatus.Todo,
@ -536,7 +536,7 @@ export default class Resource extends BaseItem {
public static async needOcr(supportedMimeTypes: string[], skippedResourceIds: string[], limit: number, options: LoadOptions): Promise<ResourceEntity[]> {
const query = this.baseNeedOcrQuery(this.selectFields(options), supportedMimeTypes);
const skippedResourcesSql = skippedResourceIds.length ? `AND resources.id NOT IN ("${skippedResourceIds.join('","')}")` : '';
const skippedResourcesSql = skippedResourceIds.length ? `AND resources.id NOT IN ('${skippedResourceIds.join('\',\'')}')` : '';
return await this.db().selectAll(`
${query.sql}
@ -576,7 +576,7 @@ export default class Resource extends BaseItem {
public static async resourceOcrTextsByIds(ids: string[]): Promise<ResourceEntity[]> {
if (!ids.length) return [];
ids = unique(ids);
return this.modelSelectAll(`SELECT id, ocr_text FROM resources WHERE id IN ("${ids.join('","')}")`);
return this.modelSelectAll(`SELECT id, ocr_text FROM resources WHERE id IN ('${ids.join('\',\'')}')`);
}
public static async allForNormalization(updatedTime: number, id: string, limit = 100, options: LoadOptions = null) {
@ -595,7 +595,7 @@ export default class Resource extends BaseItem {
sql: `
SELECT ${this.selectFields(options)} FROM resources
WHERE ${whereSql}
AND ocr_text != ""
AND ocr_text != ''
AND ocr_status = ?
ORDER BY updated_time ASC, id ASC
LIMIT ?

View File

@ -214,7 +214,7 @@ export default class Revision extends BaseItem {
public static async itemsWithRevisions(itemType: ModelType, itemIds: string[]) {
if (!itemIds.length) return [];
const rows = await this.db().selectAll(`SELECT distinct item_id FROM revisions WHERE item_type = ? AND item_id IN ("${itemIds.join('","')}")`, [itemType]);
const rows = await this.db().selectAll(`SELECT distinct item_id FROM revisions WHERE item_type = ? AND item_id IN ('${itemIds.join('\',\'')}')`, [itemType]);
return rows.map((r: RevisionEntity) => r.item_id);
}

View File

@ -39,7 +39,7 @@ export default class Tag extends BaseItem {
return Note.previews(
null,
{ ...options, conditions: [`id IN ("${noteIds.join('","')}")`] },
{ ...options, conditions: [`id IN ('${noteIds.join('\',\'')}')`] },
);
}
@ -153,7 +153,7 @@ export default class Tag extends BaseItem {
const tagIds = await NoteTag.tagIdsByNoteId(noteId);
if (!tagIds.length) return [];
return this.modelSelectAll(`SELECT ${options.fields ? this.db().escapeFields(options.fields) : '*'} FROM tags WHERE id IN ("${tagIds.join('","')}")`);
return this.modelSelectAll(`SELECT ${options.fields ? this.db().escapeFields(options.fields) : '*'} FROM tags WHERE id IN ('${tagIds.join('\',\'')}')`);
}
public static async commonTagsByNoteIds(noteIds: string[]) {
@ -168,7 +168,7 @@ export default class Tag extends BaseItem {
break;
}
}
return this.modelSelectAll(`SELECT * FROM tags WHERE id IN ("${commonTagIds.join('","')}")`);
return this.modelSelectAll(`SELECT * FROM tags WHERE id IN ('${commonTagIds.join('\',\'')}')`);
}
public static async loadByTitle(title: string): Promise<TagEntity> {

View File

@ -54,7 +54,7 @@ export default class ResourceService extends BaseService {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const noteIds = changes.map((a: any) => a.item_id);
const notes = await Note.modelSelectAll(`SELECT id, title, body, encryption_applied FROM notes WHERE id IN ("${noteIds.join('","')}")`);
const notes = await Note.modelSelectAll(`SELECT id, title, body, encryption_applied FROM notes WHERE id IN ('${noteIds.join('\',\'')}')`);
const noteById = (noteId: string) => {
for (let i = 0; i < notes.length; i++) {

View File

@ -138,7 +138,7 @@ export default class RevisionService extends BaseService {
if (!changes.length) break;
const noteIds = changes.map((a) => a.item_id);
const notes = await Note.modelSelectAll(`SELECT * FROM notes WHERE is_conflict = 0 AND encryption_applied = 0 AND id IN ("${noteIds.join('","')}")`);
const notes = await Note.modelSelectAll(`SELECT * FROM notes WHERE is_conflict = 0 AND encryption_applied = 0 AND id IN ('${noteIds.join('\',\'')}')`);
for (let i = 0; i < changes.length; i++) {
const change = changes[i];

View File

@ -136,7 +136,7 @@ export default class SearchEngine {
const notes = await Note.modelSelectAll(`
SELECT ${SearchEngine.relevantFields}
FROM notes
WHERE id IN ("${currentIds.join('","')}") AND is_conflict = 0 AND encryption_applied = 0 AND deleted_time = 0`);
WHERE id IN ('${currentIds.join('\',\'')}') AND is_conflict = 0 AND encryption_applied = 0 AND deleted_time = 0`);
const queries = [];
for (let i = 0; i < notes.length; i++) {
@ -219,7 +219,7 @@ export default class SearchEngine {
const noteIds = changes.map(a => a.item_id);
const notes = await Note.modelSelectAll(`
SELECT ${SearchEngine.relevantFields}
FROM notes WHERE id IN ("${noteIds.join('","')}") AND is_conflict = 0 AND encryption_applied = 0 AND deleted_time = 0`,
FROM notes WHERE id IN ('${noteIds.join('\',\'')}') AND is_conflict = 0 AND encryption_applied = 0 AND deleted_time = 0`,
);
for (let i = 0; i < changes.length; i++) {

View File

@ -58,7 +58,7 @@ export default class SearchEngineUtils {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const previewOptions: any = { order: [],
fields: fields,
conditions: [`id IN ("${noteIds.join('","')}")`], ...options };
conditions: [`id IN ('${noteIds.join('\',\'')}')`], ...options };
const notes = await Note.previews(null, previewOptions);