diff --git a/electron.js b/electron.js index 64a13493f..796e635d4 100644 --- a/electron.js +++ b/electron.js @@ -76,7 +76,7 @@ app.on('ready', () => { const dateNoteService = require('./src/services/date_notes'); const dateUtils = require('./src/services/date_utils'); - const parentNoteId = await dateNoteService.getDateNoteId(dateUtils.nowDate()); + const parentNoteId = await dateNoteService.getDateNote(dateUtils.nowDate()); // window may be hidden / not in focus mainWindow.focus(); diff --git a/src/routes/api/sender.js b/src/routes/api/sender.js index 06ab61cb9..aa0d7b081 100644 --- a/src/routes/api/sender.js +++ b/src/routes/api/sender.js @@ -36,9 +36,9 @@ async function uploadImage(req) { return [400, "Unknown image type: " + file.mimetype]; } - const parentNoteId = await dateNoteService.getDateNoteId(req.headers['x-local-date']); + const parentNote = await dateNoteService.getDateNote(req.headers['x-local-date']); - const {note} = await noteService.createNewNote(parentNoteId, { + const {note} = await noteService.createNewNote(parentNote.noteId, { title: "Sender image", content: "", target: 'into', @@ -57,9 +57,9 @@ async function uploadImage(req) { } async function saveNote(req) { - const parentNoteId = await dateNoteService.getDateNoteId(req.headers['x-local-date']); + const parentNote = await dateNoteService.getDateNote(req.headers['x-local-date']); - await noteService.createNewNote(parentNoteId, { + await noteService.createNewNote(parentNote.noteId, { title: req.body.title, content: req.body.content, target: 'into', diff --git a/src/routes/routes.js b/src/routes/routes.js index 27d6e9a18..156d190a7 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -70,7 +70,7 @@ function route(method, path, middleware, routeHandler, resultHandler) { cls.namespace.set('sourceId', req.headers.source_id); protectedSessionService.setProtectedSessionId(req); - return await sql.doInTransaction(async () => { + return await sql.transactional(async () => { return await routeHandler(req, res, next); }); }); diff --git a/src/services/change_password.js b/src/services/change_password.js index d50b86176..9ac63b429 100644 --- a/src/services/change_password.js +++ b/src/services/change_password.js @@ -17,7 +17,7 @@ async function changePassword(currentPassword, newPassword) { const newPasswordVerificationKey = utils.toBase64(await myScryptService.getVerificationHash(newPassword)); const decryptedDataKey = await passwordEncryptionService.getDataKey(currentPassword); - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await passwordEncryptionService.setDataKey(newPassword, decryptedDataKey); await optionService.setOption('passwordVerificationHash', newPasswordVerificationKey); diff --git a/src/services/date_notes.js b/src/services/date_notes.js index 10356f485..072c06b4a 100644 --- a/src/services/date_notes.js +++ b/src/services/date_notes.js @@ -4,6 +4,7 @@ const sql = require('./sql'); const noteService = require('./notes'); const labelService = require('./labels'); const dateUtils = require('./date_utils'); +const repository = require('./repository'); const CALENDAR_ROOT_LABEL = 'calendarRoot'; const YEAR_LABEL = 'yearNote'; @@ -14,117 +15,112 @@ const DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Satur const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December']; async function createNote(parentNoteId, noteTitle, noteText) { - const {note} = await noteService.createNewNote(parentNoteId, { + return await noteService.createNewNote(parentNoteId, { title: noteTitle, content: noteText, target: 'into', isProtected: false }); - - return note.noteId; } async function getNoteStartingWith(parentNoteId, startsWith) { - return await sql.getValue(`SELECT noteId FROM notes JOIN branches USING(noteId) + return await repository.getEntity(`SELECT notes.* FROM notes JOIN branches USING(noteId) WHERE parentNoteId = ? AND title LIKE '${startsWith}%' AND notes.isDeleted = 0 AND isProtected = 0 AND branches.isDeleted = 0`, [parentNoteId]); } -async function getRootCalendarNoteId() { - let rootNoteId = await sql.getValue(`SELECT notes.noteId FROM notes JOIN labels USING(noteId) - WHERE labels.name = '${CALENDAR_ROOT_LABEL}' AND notes.isDeleted = 0`); +async function getRootCalendarNote() { + let rootNote = await labelService.getNoteWithLabel(CALENDAR_ROOT_LABEL); - if (!rootNoteId) { - const {rootNote} = await noteService.createNewNote('root', { + if (!rootNote) { + rootNote = (await noteService.createNewNote('root', { title: 'Calendar', target: 'into', isProtected: false - }); + })).note; - const rootNoteId = rootNote.noteId; - - await labelService.createLabel(rootNoteId, CALENDAR_ROOT_LABEL); + await labelService.createLabel(rootNote.noteId, CALENDAR_ROOT_LABEL); } - return rootNoteId; + return rootNote; } -async function getYearNoteId(dateTimeStr, rootNoteId) { +async function getYearNote(dateTimeStr, rootNote) { const yearStr = dateTimeStr.substr(0, 4); - let yearNoteId = await labelService.getNoteIdWithLabel(YEAR_LABEL, yearStr); + let yearNote = await labelService.getNoteWithLabel(YEAR_LABEL, yearStr); - if (!yearNoteId) { - yearNoteId = await getNoteStartingWith(rootNoteId, yearStr); + if (!yearNote) { + yearNote = await getNoteStartingWith(rootNote.noteId, yearStr); - if (!yearNoteId) { - yearNoteId = await createNote(rootNoteId, yearStr); + if (!yearNote) { + yearNote = await createNote(rootNote.noteId, yearStr); } - await labelService.createLabel(yearNoteId, YEAR_LABEL, yearStr); + await labelService.createLabel(yearNote.noteId, YEAR_LABEL, yearStr); } - return yearNoteId; + return yearNote; } -async function getMonthNoteId(dateTimeStr, rootNoteId) { +async function getMonthNote(dateTimeStr, rootNote) { const monthStr = dateTimeStr.substr(0, 7); const monthNumber = dateTimeStr.substr(5, 2); - let monthNoteId = await labelService.getNoteIdWithLabel(MONTH_LABEL, monthStr); + let monthNote = await labelService.getNoteWithLabel(MONTH_LABEL, monthStr); - if (!monthNoteId) { - const yearNoteId = await getYearNoteId(dateTimeStr, rootNoteId); + if (!monthNote) { + const yearNote = await getYearNote(dateTimeStr, rootNote); - monthNoteId = await getNoteStartingWith(yearNoteId, monthNumber); + monthNote = await getNoteStartingWith(yearNote.noteId, monthNumber); - if (!monthNoteId) { + if (!monthNote) { const dateObj = dateUtils.parseDate(dateTimeStr); const noteTitle = monthNumber + " - " + MONTHS[dateObj.getMonth()]; - monthNoteId = await createNote(yearNoteId, noteTitle); + monthNote = await createNote(yearNote.noteId, noteTitle); } - await labelService.createLabel(monthNoteId, MONTH_LABEL, monthStr); + await labelService.createLabel(monthNote.noteId, MONTH_LABEL, monthStr); } - return monthNoteId; + return monthNote; } -async function getDateNoteId(dateTimeStr, rootNoteId = null) { - if (!rootNoteId) { - rootNoteId = await getRootCalendarNoteId(); +async function getDateNote(dateTimeStr, rootNote = null) { + if (!rootNote) { + rootNote = await getRootCalendarNote(); } const dateStr = dateTimeStr.substr(0, 10); const dayNumber = dateTimeStr.substr(8, 2); - let dateNoteId = await labelService.getNoteIdWithLabel(DATE_LABEL, dateStr); + let dateNote = await labelService.getNoteWithLabel(DATE_LABEL, dateStr); - if (!dateNoteId) { - const monthNoteId = await getMonthNoteId(dateTimeStr, rootNoteId); + if (!dateNote) { + const monthNote = await getMonthNote(dateTimeStr, rootNote); - dateNoteId = await getNoteStartingWith(monthNoteId, dayNumber); + dateNote = await getNoteStartingWith(monthNote.noteId, dayNumber); - if (!dateNoteId) { + if (!dateNote) { const dateObj = dateUtils.parseDate(dateTimeStr); const noteTitle = dayNumber + " - " + DAYS[dateObj.getDay()]; - dateNoteId = await createNote(monthNoteId, noteTitle); + dateNote = await createNote(monthNote.noteId, noteTitle); } - await labelService.createLabel(dateNoteId, DATE_LABEL, dateStr); + await labelService.createLabel(dateNote.noteId, DATE_LABEL, dateStr); } - return dateNoteId; + return dateNote; } module.exports = { - getRootCalendarNoteId, - getYearNoteId, - getMonthNoteId, - getDateNoteId + getRootCalendarNote, + getYearNote, + getMonthNote, + getDateNote }; \ No newline at end of file diff --git a/src/services/labels.js b/src/services/labels.js index cc8f74a50..203844fbd 100644 --- a/src/services/labels.js +++ b/src/services/labels.js @@ -1,6 +1,5 @@ "use strict"; -const sql = require('./sql'); const repository = require('./repository'); const Label = require('../entities/label'); @@ -15,14 +14,6 @@ const BUILTIN_LABELS = [ 'appCss' ]; -async function getNoteIdWithLabel(name, value) { - return await sql.getValue(`SELECT notes.noteId FROM notes JOIN labels USING(noteId) - WHERE notes.isDeleted = 0 - AND labels.isDeleted = 0 - AND labels.name = ? - AND labels.value = ?`, [name, value]); -} - async function getNotesWithLabel(name, value) { let notes; @@ -44,11 +35,6 @@ async function getNoteWithLabel(name, value) { return notes.length > 0 ? notes[0] : null; } -async function getNoteIdsWithLabel(name) { - return await sql.getColumn(`SELECT DISTINCT notes.noteId FROM notes JOIN labels USING(noteId) - WHERE notes.isDeleted = 0 AND labels.isDeleted = 0 AND labels.name = ? AND labels.isDeleted = 0`, [name]); -} - async function createLabel(noteId, name, value = "") { return await new Label({ noteId: noteId, @@ -58,10 +44,8 @@ async function createLabel(noteId, name, value = "") { } module.exports = { - getNoteIdWithLabel, getNotesWithLabel, getNoteWithLabel, - getNoteIdsWithLabel, createLabel, BUILTIN_LABELS }; \ No newline at end of file diff --git a/src/services/migration.js b/src/services/migration.js index 7419bde80..943885c50 100644 --- a/src/services/migration.js +++ b/src/services/migration.js @@ -45,7 +45,7 @@ async function migrate() { // needs to happen outside of the transaction (otherwise it's a NO-OP) await sql.execute("PRAGMA foreign_keys = OFF"); - await sql.doInTransaction(async () => { + await sql.transactional(async () => { if (mig.type === 'sql') { const migrationSql = fs.readFileSync(resourceDir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); diff --git a/src/services/repository.js b/src/services/repository.js index dea33e70e..705715327 100644 --- a/src/services/repository.js +++ b/src/services/repository.js @@ -50,7 +50,7 @@ async function updateEntity(entity) { delete clone.jsonContent; - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace(entity.constructor.tableName, clone); const primaryKey = entity[entity.constructor.primaryKeyName]; diff --git a/src/services/script.js b/src/services/script.js index dadb0b17f..e9b18ad07 100644 --- a/src/services/script.js +++ b/src/services/script.js @@ -27,7 +27,7 @@ async function executeBundle(bundle, startNote) { return await execute(ctx, script, ''); } else { - return await sql.doInTransaction(async () => execute(ctx, script, '')); + return await sql.transactional(async () => execute(ctx, script, '')); } } diff --git a/src/services/script_context.js b/src/services/script_context.js index 9e31dd811..be8aa954b 100644 --- a/src/services/script_context.js +++ b/src/services/script_context.js @@ -56,10 +56,10 @@ function ScriptApi(startNote, currentNote) { this.log = message => log.info(`Script ${currentNote.noteId}: ${message}`); - this.getRootCalendarNoteId = dateNoteService.getRootCalendarNoteId; - this.getDateNoteId = dateNoteService.getDateNoteId; + this.getRootCalendarNote = dateNoteService.getRootCalendarNote; + this.getDateNote = dateNoteService.getDateNote; - this.transactional = sql.doInTransaction; + this.transactional = sql.transactional; } module.exports = ScriptContext; \ No newline at end of file diff --git a/src/services/sql.js b/src/services/sql.js index 1e0c18370..68ece67ea 100644 --- a/src/services/sql.js +++ b/src/services/sql.js @@ -122,7 +122,7 @@ async function wrap(func) { let transactionActive = false; let transactionPromise = null; -async function doInTransaction(func) { +async function transactional(func) { if (cls.namespace.get('isInTransaction')) { return await func(); } @@ -181,5 +181,5 @@ module.exports = { getColumn, execute, executeScript, - doInTransaction + transactional }; \ No newline at end of file diff --git a/src/services/sql_init.js b/src/services/sql_init.js index 9fb5a94a3..0d52ce540 100644 --- a/src/services/sql_init.js +++ b/src/services/sql_init.js @@ -58,7 +58,7 @@ async function createInitialDatabase() { const imagesSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_images.sql', 'UTF-8'); const notesImageSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_note_images.sql', 'UTF-8'); - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.executeScript(schema); await sql.executeScript(notesSql); await sql.executeScript(notesTreeSql); diff --git a/src/services/sync_update.js b/src/services/sync_update.js index deab3c43e..d33c9009e 100644 --- a/src/services/sync_update.js +++ b/src/services/sync_update.js @@ -15,7 +15,7 @@ async function updateNote(entity, sourceId) { const origNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [entity.noteId]); if (!origNote || origNote.dateModified <= entity.dateModified) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace("notes", entity); await syncTableService.addNoteSync(entity.noteId, sourceId); @@ -29,7 +29,7 @@ async function updateNote(entity, sourceId) { async function updateBranch(entity, sourceId) { const orig = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [entity.branchId]); - await sql.doInTransaction(async () => { + await sql.transactional(async () => { if (orig === null || orig.dateModified < entity.dateModified) { delete entity.isExpanded; @@ -45,7 +45,7 @@ async function updateBranch(entity, sourceId) { async function updateNoteRevision(entity, sourceId) { const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]); - await sql.doInTransaction(async () => { + await sql.transactional(async () => { // we update note revision even if date modified to is the same because the only thing which might have changed // is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) { @@ -59,7 +59,7 @@ async function updateNoteRevision(entity, sourceId) { } async function updateNoteReordering(entity, sourceId) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { Object.keys(entity.ordering).forEach(async key => { await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [entity.ordering[key], key]); }); @@ -75,7 +75,7 @@ async function updateOptions(entity, sourceId) { return; } - await sql.doInTransaction(async () => { + await sql.transactional(async () => { if (orig === null || orig.dateModified < entity.dateModified) { await sql.replace('options', entity); @@ -90,7 +90,7 @@ async function updateRecentNotes(entity, sourceId) { const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE branchId = ?", [entity.branchId]); if (orig === null || orig.dateAccessed < entity.dateAccessed) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace('recent_notes', entity); await syncTableService.addRecentNoteSync(entity.branchId, sourceId); @@ -106,7 +106,7 @@ async function updateImage(entity, sourceId) { const origImage = await sql.getRow("SELECT * FROM images WHERE imageId = ?", [entity.imageId]); if (!origImage || origImage.dateModified <= entity.dateModified) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace("images", entity); await syncTableService.addImageSync(entity.imageId, sourceId); @@ -120,7 +120,7 @@ async function updateNoteImage(entity, sourceId) { const origNoteImage = await sql.getRow("SELECT * FROM note_images WHERE noteImageId = ?", [entity.noteImageId]); if (!origNoteImage || origNoteImage.dateModified <= entity.dateModified) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace("note_images", entity); await syncTableService.addNoteImageSync(entity.noteImageId, sourceId); @@ -134,7 +134,7 @@ async function updateLabel(entity, sourceId) { const origLabel = await sql.getRow("SELECT * FROM labels WHERE labelId = ?", [entity.labelId]); if (!origLabel || origLabel.dateModified <= entity.dateModified) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace("labels", entity); await syncTableService.addLabelSync(entity.labelId, sourceId); @@ -148,7 +148,7 @@ async function updateApiToken(entity, sourceId) { const apiTokenId = await sql.getRow("SELECT * FROM api_tokens WHERE apiTokenId = ?", [entity.apiTokenId]); if (!apiTokenId) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { await sql.replace("api_tokens", entity); await syncTableService.addApiTokenSync(entity.apiTokenId, sourceId); diff --git a/src/services/tree.js b/src/services/tree.js index fecc7a5b9..d0ca2370b 100644 --- a/src/services/tree.js +++ b/src/services/tree.js @@ -77,7 +77,7 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) { } async function sortNotesAlphabetically(parentNoteId) { - await sql.doInTransaction(async () => { + await sql.transactional(async () => { const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected FROM notes JOIN branches USING(noteId) WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]); diff --git a/trilium.iml b/trilium.iml index 2d6087754..eb60d2818 100644 --- a/trilium.iml +++ b/trilium.iml @@ -5,6 +5,7 @@ +