mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
converted most dynamic SQL queries into prepared statement to avoid excessive statement caching
This commit is contained in:
parent
969f31dde2
commit
5f699cc28c
@ -33,10 +33,12 @@ function getAutocomplete(req) {
|
|||||||
|
|
||||||
function getRecentNotes(activeNoteId) {
|
function getRecentNotes(activeNoteId) {
|
||||||
let extraCondition = '';
|
let extraCondition = '';
|
||||||
|
const params = [activeNoteId];
|
||||||
|
|
||||||
const hoistedNoteId = optionService.getOption('hoistedNoteId');
|
const hoistedNoteId = optionService.getOption('hoistedNoteId');
|
||||||
if (hoistedNoteId !== 'root') {
|
if (hoistedNoteId !== 'root') {
|
||||||
extraCondition = `AND recent_notes.notePath LIKE '%${utils.sanitizeSql(hoistedNoteId)}%'`;
|
extraCondition = `AND recent_notes.notePath LIKE ?`;
|
||||||
|
params.push(hoistedNoteId + '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
const recentNotes = repository.getEntities(`
|
const recentNotes = repository.getEntities(`
|
||||||
@ -52,7 +54,7 @@ function getRecentNotes(activeNoteId) {
|
|||||||
${extraCondition}
|
${extraCondition}
|
||||||
ORDER BY
|
ORDER BY
|
||||||
utcDateCreated DESC
|
utcDateCreated DESC
|
||||||
LIMIT 200`, [activeNoteId]);
|
LIMIT 200`, params);
|
||||||
|
|
||||||
return recentNotes.map(rn => {
|
return recentNotes.map(rn => {
|
||||||
const title = noteCacheService.getNoteTitleForPath(rn.notePath.split('/'));
|
const title = noteCacheService.getNoteTitleForPath(rn.notePath.split('/'));
|
||||||
|
@ -119,21 +119,19 @@ function restoreNoteRevision(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEditedNotesOnDate(req) {
|
function getEditedNotesOnDate(req) {
|
||||||
const date = utils.sanitizeSql(req.params.date);
|
|
||||||
|
|
||||||
const notes = repository.getEntities(`
|
const notes = repository.getEntities(`
|
||||||
SELECT notes.*
|
SELECT notes.*
|
||||||
FROM notes
|
FROM notes
|
||||||
WHERE noteId IN (
|
WHERE noteId IN (
|
||||||
SELECT noteId FROM notes
|
SELECT noteId FROM notes
|
||||||
WHERE notes.dateCreated LIKE '${date}%'
|
WHERE notes.dateCreated LIKE :date
|
||||||
OR notes.dateModified LIKE '${date}%'
|
OR notes.dateModified LIKE :date
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT noteId FROM note_revisions
|
SELECT noteId FROM note_revisions
|
||||||
WHERE note_revisions.dateLastEdited LIKE '${date}%'
|
WHERE note_revisions.dateLastEdited LIKE :date
|
||||||
)
|
)
|
||||||
ORDER BY isDeleted
|
ORDER BY isDeleted
|
||||||
LIMIT 50`);
|
LIMIT 50`, {date: req.params.date + '%'});
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
const notePath = noteCacheService.getNotePath(note.noteId);
|
const notePath = noteCacheService.getNotePath(note.noteId);
|
||||||
|
@ -97,7 +97,7 @@ function getAttributeNames(type, nameLike) {
|
|||||||
FROM attributes
|
FROM attributes
|
||||||
WHERE isDeleted = 0
|
WHERE isDeleted = 0
|
||||||
AND type = ?
|
AND type = ?
|
||||||
AND name LIKE '%${utils.sanitizeSql(nameLike)}%'`, [type]);
|
AND name LIKE ?`, [type, '%' + nameLike + '%']);
|
||||||
|
|
||||||
for (const attr of BUILTIN_ATTRIBUTES) {
|
for (const attr of BUILTIN_ATTRIBUTES) {
|
||||||
if (attr.type === type && attr.name.toLowerCase().includes(nameLike) && !names.includes(attr.name)) {
|
if (attr.type === type && attr.name.toLowerCase().includes(nameLike) && !names.includes(attr.name)) {
|
||||||
|
@ -31,8 +31,6 @@ function periodBackup(optionName, fileName, periodInSeconds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const COPY_ATTEMPT_COUNT = 50;
|
|
||||||
|
|
||||||
async function copyFile(backupFile) {
|
async function copyFile(backupFile) {
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
|
|
||||||
@ -78,7 +76,7 @@ async function anonymize() {
|
|||||||
// on the other hand builtin/system attrs should not contain any sensitive info
|
// on the other hand builtin/system attrs should not contain any sensitive info
|
||||||
const builtinAttrs = attributeService
|
const builtinAttrs = attributeService
|
||||||
.getBuiltinAttributeNames()
|
.getBuiltinAttributeNames()
|
||||||
.map(name => "'" + utils.sanitizeSql(name) + "'").join(', ');
|
.map(name => "'" + name + "'").join(', ');
|
||||||
|
|
||||||
db.prepare(`UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN(${builtinAttrs})`).run();
|
db.prepare(`UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN(${builtinAttrs})`).run();
|
||||||
db.prepare(`UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN (${builtinAttrs})`).run();
|
db.prepare(`UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN (${builtinAttrs})`).run();
|
||||||
|
@ -127,7 +127,8 @@ function getManyRows(query, params) {
|
|||||||
const questionMarks = curParams.map(() => ":param" + i++).join(",");
|
const questionMarks = curParams.map(() => ":param" + i++).join(",");
|
||||||
const curQuery = query.replace(/\?\?\?/g, questionMarks);
|
const curQuery = query.replace(/\?\?\?/g, questionMarks);
|
||||||
|
|
||||||
results = results.concat(getRows(curQuery, curParamsObj));
|
const subResults = dbConnection.prepare(curQuery).all(curParamsObj);
|
||||||
|
results = results.concat(subResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
@ -200,7 +201,7 @@ function wrap(query, func) {
|
|||||||
|
|
||||||
const milliseconds = Date.now() - startTimestamp;
|
const milliseconds = Date.now() - startTimestamp;
|
||||||
|
|
||||||
if (milliseconds >= 100) {
|
if (milliseconds >= 20) {
|
||||||
if (query.includes("WITH RECURSIVE")) {
|
if (query.includes("WITH RECURSIVE")) {
|
||||||
log.info(`Slow recursive query took ${milliseconds}ms.`);
|
log.info(`Slow recursive query took ${milliseconds}ms.`);
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,6 @@ function isEmptyOrWhitespace(str) {
|
|||||||
return str === null || str.match(/^ *$/) !== null;
|
return str === null || str.match(/^ *$/) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitizeSql(str) {
|
|
||||||
// should be improved or usage eliminated
|
|
||||||
return str.replace(/'/g, "''");
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizeSqlIdentifier(str) {
|
function sanitizeSqlIdentifier(str) {
|
||||||
return str.replace(/[^A-Za-z0-9_]/g, "");
|
return str.replace(/[^A-Za-z0-9_]/g, "");
|
||||||
}
|
}
|
||||||
@ -286,7 +281,6 @@ module.exports = {
|
|||||||
isElectron,
|
isElectron,
|
||||||
hash,
|
hash,
|
||||||
isEmptyOrWhitespace,
|
isEmptyOrWhitespace,
|
||||||
sanitizeSql,
|
|
||||||
sanitizeSqlIdentifier,
|
sanitizeSqlIdentifier,
|
||||||
prepareSqlForLike,
|
prepareSqlForLike,
|
||||||
stopWatch,
|
stopWatch,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user