mirror of https://github.com/laurent22/joplin.git
Chore: Migrate SQL queries in preparation for web support (#10670)
parent
337d50437b
commit
d89be23069
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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('\',\'')}')`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 != ''
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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[]> = {};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 ?
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue