label service refactoring + rename of doInTransaction to transactional

This commit is contained in:
azivner 2018-04-07 13:03:16 -04:00
parent 39dc0f71b4
commit e378d9f645
15 changed files with 70 additions and 89 deletions

View File

@ -76,7 +76,7 @@ app.on('ready', () => {
const dateNoteService = require('./src/services/date_notes'); const dateNoteService = require('./src/services/date_notes');
const dateUtils = require('./src/services/date_utils'); 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 // window may be hidden / not in focus
mainWindow.focus(); mainWindow.focus();

View File

@ -36,9 +36,9 @@ async function uploadImage(req) {
return [400, "Unknown image type: " + file.mimetype]; 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", title: "Sender image",
content: "", content: "",
target: 'into', target: 'into',
@ -57,9 +57,9 @@ async function uploadImage(req) {
} }
async function saveNote(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, title: req.body.title,
content: req.body.content, content: req.body.content,
target: 'into', target: 'into',

View File

@ -70,7 +70,7 @@ function route(method, path, middleware, routeHandler, resultHandler) {
cls.namespace.set('sourceId', req.headers.source_id); cls.namespace.set('sourceId', req.headers.source_id);
protectedSessionService.setProtectedSessionId(req); protectedSessionService.setProtectedSessionId(req);
return await sql.doInTransaction(async () => { return await sql.transactional(async () => {
return await routeHandler(req, res, next); return await routeHandler(req, res, next);
}); });
}); });

View File

@ -17,7 +17,7 @@ async function changePassword(currentPassword, newPassword) {
const newPasswordVerificationKey = utils.toBase64(await myScryptService.getVerificationHash(newPassword)); const newPasswordVerificationKey = utils.toBase64(await myScryptService.getVerificationHash(newPassword));
const decryptedDataKey = await passwordEncryptionService.getDataKey(currentPassword); const decryptedDataKey = await passwordEncryptionService.getDataKey(currentPassword);
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await passwordEncryptionService.setDataKey(newPassword, decryptedDataKey); await passwordEncryptionService.setDataKey(newPassword, decryptedDataKey);
await optionService.setOption('passwordVerificationHash', newPasswordVerificationKey); await optionService.setOption('passwordVerificationHash', newPasswordVerificationKey);

View File

@ -4,6 +4,7 @@ const sql = require('./sql');
const noteService = require('./notes'); const noteService = require('./notes');
const labelService = require('./labels'); const labelService = require('./labels');
const dateUtils = require('./date_utils'); const dateUtils = require('./date_utils');
const repository = require('./repository');
const CALENDAR_ROOT_LABEL = 'calendarRoot'; const CALENDAR_ROOT_LABEL = 'calendarRoot';
const YEAR_LABEL = 'yearNote'; 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']; const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
async function createNote(parentNoteId, noteTitle, noteText) { async function createNote(parentNoteId, noteTitle, noteText) {
const {note} = await noteService.createNewNote(parentNoteId, { return await noteService.createNewNote(parentNoteId, {
title: noteTitle, title: noteTitle,
content: noteText, content: noteText,
target: 'into', target: 'into',
isProtected: false isProtected: false
}); });
return note.noteId;
} }
async function getNoteStartingWith(parentNoteId, startsWith) { 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}%' WHERE parentNoteId = ? AND title LIKE '${startsWith}%'
AND notes.isDeleted = 0 AND isProtected = 0 AND notes.isDeleted = 0 AND isProtected = 0
AND branches.isDeleted = 0`, [parentNoteId]); AND branches.isDeleted = 0`, [parentNoteId]);
} }
async function getRootCalendarNoteId() { async function getRootCalendarNote() {
let rootNoteId = await sql.getValue(`SELECT notes.noteId FROM notes JOIN labels USING(noteId) let rootNote = await labelService.getNoteWithLabel(CALENDAR_ROOT_LABEL);
WHERE labels.name = '${CALENDAR_ROOT_LABEL}' AND notes.isDeleted = 0`);
if (!rootNoteId) { if (!rootNote) {
const {rootNote} = await noteService.createNewNote('root', { rootNote = (await noteService.createNewNote('root', {
title: 'Calendar', title: 'Calendar',
target: 'into', target: 'into',
isProtected: false isProtected: false
}); })).note;
const rootNoteId = rootNote.noteId; await labelService.createLabel(rootNote.noteId, CALENDAR_ROOT_LABEL);
await labelService.createLabel(rootNoteId, CALENDAR_ROOT_LABEL);
} }
return rootNoteId; return rootNote;
} }
async function getYearNoteId(dateTimeStr, rootNoteId) { async function getYearNote(dateTimeStr, rootNote) {
const yearStr = dateTimeStr.substr(0, 4); const yearStr = dateTimeStr.substr(0, 4);
let yearNoteId = await labelService.getNoteIdWithLabel(YEAR_LABEL, yearStr); let yearNote = await labelService.getNoteWithLabel(YEAR_LABEL, yearStr);
if (!yearNoteId) { if (!yearNote) {
yearNoteId = await getNoteStartingWith(rootNoteId, yearStr); yearNote = await getNoteStartingWith(rootNote.noteId, yearStr);
if (!yearNoteId) { if (!yearNote) {
yearNoteId = await createNote(rootNoteId, yearStr); 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 monthStr = dateTimeStr.substr(0, 7);
const monthNumber = dateTimeStr.substr(5, 2); const monthNumber = dateTimeStr.substr(5, 2);
let monthNoteId = await labelService.getNoteIdWithLabel(MONTH_LABEL, monthStr); let monthNote = await labelService.getNoteWithLabel(MONTH_LABEL, monthStr);
if (!monthNoteId) { if (!monthNote) {
const yearNoteId = await getYearNoteId(dateTimeStr, rootNoteId); 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 dateObj = dateUtils.parseDate(dateTimeStr);
const noteTitle = monthNumber + " - " + MONTHS[dateObj.getMonth()]; 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) { async function getDateNote(dateTimeStr, rootNote = null) {
if (!rootNoteId) { if (!rootNote) {
rootNoteId = await getRootCalendarNoteId(); rootNote = await getRootCalendarNote();
} }
const dateStr = dateTimeStr.substr(0, 10); const dateStr = dateTimeStr.substr(0, 10);
const dayNumber = dateTimeStr.substr(8, 2); const dayNumber = dateTimeStr.substr(8, 2);
let dateNoteId = await labelService.getNoteIdWithLabel(DATE_LABEL, dateStr); let dateNote = await labelService.getNoteWithLabel(DATE_LABEL, dateStr);
if (!dateNoteId) { if (!dateNote) {
const monthNoteId = await getMonthNoteId(dateTimeStr, rootNoteId); 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 dateObj = dateUtils.parseDate(dateTimeStr);
const noteTitle = dayNumber + " - " + DAYS[dateObj.getDay()]; 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 = { module.exports = {
getRootCalendarNoteId, getRootCalendarNote,
getYearNoteId, getYearNote,
getMonthNoteId, getMonthNote,
getDateNoteId getDateNote
}; };

View File

@ -1,6 +1,5 @@
"use strict"; "use strict";
const sql = require('./sql');
const repository = require('./repository'); const repository = require('./repository');
const Label = require('../entities/label'); const Label = require('../entities/label');
@ -15,14 +14,6 @@ const BUILTIN_LABELS = [
'appCss' '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) { async function getNotesWithLabel(name, value) {
let notes; let notes;
@ -44,11 +35,6 @@ async function getNoteWithLabel(name, value) {
return notes.length > 0 ? notes[0] : null; 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 = "") { async function createLabel(noteId, name, value = "") {
return await new Label({ return await new Label({
noteId: noteId, noteId: noteId,
@ -58,10 +44,8 @@ async function createLabel(noteId, name, value = "") {
} }
module.exports = { module.exports = {
getNoteIdWithLabel,
getNotesWithLabel, getNotesWithLabel,
getNoteWithLabel, getNoteWithLabel,
getNoteIdsWithLabel,
createLabel, createLabel,
BUILTIN_LABELS BUILTIN_LABELS
}; };

View File

@ -45,7 +45,7 @@ async function migrate() {
// needs to happen outside of the transaction (otherwise it's a NO-OP) // needs to happen outside of the transaction (otherwise it's a NO-OP)
await sql.execute("PRAGMA foreign_keys = OFF"); await sql.execute("PRAGMA foreign_keys = OFF");
await sql.doInTransaction(async () => { await sql.transactional(async () => {
if (mig.type === 'sql') { if (mig.type === 'sql') {
const migrationSql = fs.readFileSync(resourceDir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8'); const migrationSql = fs.readFileSync(resourceDir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8');

View File

@ -50,7 +50,7 @@ async function updateEntity(entity) {
delete clone.jsonContent; delete clone.jsonContent;
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace(entity.constructor.tableName, clone); await sql.replace(entity.constructor.tableName, clone);
const primaryKey = entity[entity.constructor.primaryKeyName]; const primaryKey = entity[entity.constructor.primaryKeyName];

View File

@ -27,7 +27,7 @@ async function executeBundle(bundle, startNote) {
return await execute(ctx, script, ''); return await execute(ctx, script, '');
} }
else { else {
return await sql.doInTransaction(async () => execute(ctx, script, '')); return await sql.transactional(async () => execute(ctx, script, ''));
} }
} }

View File

@ -56,10 +56,10 @@ function ScriptApi(startNote, currentNote) {
this.log = message => log.info(`Script ${currentNote.noteId}: ${message}`); this.log = message => log.info(`Script ${currentNote.noteId}: ${message}`);
this.getRootCalendarNoteId = dateNoteService.getRootCalendarNoteId; this.getRootCalendarNote = dateNoteService.getRootCalendarNote;
this.getDateNoteId = dateNoteService.getDateNoteId; this.getDateNote = dateNoteService.getDateNote;
this.transactional = sql.doInTransaction; this.transactional = sql.transactional;
} }
module.exports = ScriptContext; module.exports = ScriptContext;

View File

@ -122,7 +122,7 @@ async function wrap(func) {
let transactionActive = false; let transactionActive = false;
let transactionPromise = null; let transactionPromise = null;
async function doInTransaction(func) { async function transactional(func) {
if (cls.namespace.get('isInTransaction')) { if (cls.namespace.get('isInTransaction')) {
return await func(); return await func();
} }
@ -181,5 +181,5 @@ module.exports = {
getColumn, getColumn,
execute, execute,
executeScript, executeScript,
doInTransaction transactional
}; };

View File

@ -58,7 +58,7 @@ async function createInitialDatabase() {
const imagesSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_images.sql', 'UTF-8'); 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'); 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(schema);
await sql.executeScript(notesSql); await sql.executeScript(notesSql);
await sql.executeScript(notesTreeSql); await sql.executeScript(notesTreeSql);

View File

@ -15,7 +15,7 @@ async function updateNote(entity, sourceId) {
const origNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [entity.noteId]); const origNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [entity.noteId]);
if (!origNote || origNote.dateModified <= entity.dateModified) { if (!origNote || origNote.dateModified <= entity.dateModified) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace("notes", entity); await sql.replace("notes", entity);
await syncTableService.addNoteSync(entity.noteId, sourceId); await syncTableService.addNoteSync(entity.noteId, sourceId);
@ -29,7 +29,7 @@ async function updateNote(entity, sourceId) {
async function updateBranch(entity, sourceId) { async function updateBranch(entity, sourceId) {
const orig = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [entity.branchId]); 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) { if (orig === null || orig.dateModified < entity.dateModified) {
delete entity.isExpanded; delete entity.isExpanded;
@ -45,7 +45,7 @@ async function updateBranch(entity, sourceId) {
async function updateNoteRevision(entity, sourceId) { async function updateNoteRevision(entity, sourceId) {
const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]); 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 // 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 // is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) { if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
@ -59,7 +59,7 @@ async function updateNoteRevision(entity, sourceId) {
} }
async function updateNoteReordering(entity, sourceId) { async function updateNoteReordering(entity, sourceId) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
Object.keys(entity.ordering).forEach(async key => { Object.keys(entity.ordering).forEach(async key => {
await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [entity.ordering[key], key]); await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [entity.ordering[key], key]);
}); });
@ -75,7 +75,7 @@ async function updateOptions(entity, sourceId) {
return; return;
} }
await sql.doInTransaction(async () => { await sql.transactional(async () => {
if (orig === null || orig.dateModified < entity.dateModified) { if (orig === null || orig.dateModified < entity.dateModified) {
await sql.replace('options', entity); 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]); const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE branchId = ?", [entity.branchId]);
if (orig === null || orig.dateAccessed < entity.dateAccessed) { if (orig === null || orig.dateAccessed < entity.dateAccessed) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace('recent_notes', entity); await sql.replace('recent_notes', entity);
await syncTableService.addRecentNoteSync(entity.branchId, sourceId); 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]); const origImage = await sql.getRow("SELECT * FROM images WHERE imageId = ?", [entity.imageId]);
if (!origImage || origImage.dateModified <= entity.dateModified) { if (!origImage || origImage.dateModified <= entity.dateModified) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace("images", entity); await sql.replace("images", entity);
await syncTableService.addImageSync(entity.imageId, sourceId); 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]); const origNoteImage = await sql.getRow("SELECT * FROM note_images WHERE noteImageId = ?", [entity.noteImageId]);
if (!origNoteImage || origNoteImage.dateModified <= entity.dateModified) { if (!origNoteImage || origNoteImage.dateModified <= entity.dateModified) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace("note_images", entity); await sql.replace("note_images", entity);
await syncTableService.addNoteImageSync(entity.noteImageId, sourceId); 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]); const origLabel = await sql.getRow("SELECT * FROM labels WHERE labelId = ?", [entity.labelId]);
if (!origLabel || origLabel.dateModified <= entity.dateModified) { if (!origLabel || origLabel.dateModified <= entity.dateModified) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace("labels", entity); await sql.replace("labels", entity);
await syncTableService.addLabelSync(entity.labelId, sourceId); 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]); const apiTokenId = await sql.getRow("SELECT * FROM api_tokens WHERE apiTokenId = ?", [entity.apiTokenId]);
if (!apiTokenId) { if (!apiTokenId) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
await sql.replace("api_tokens", entity); await sql.replace("api_tokens", entity);
await syncTableService.addApiTokenSync(entity.apiTokenId, sourceId); await syncTableService.addApiTokenSync(entity.apiTokenId, sourceId);

View File

@ -77,7 +77,7 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
} }
async function sortNotesAlphabetically(parentNoteId) { async function sortNotesAlphabetically(parentNoteId) {
await sql.doInTransaction(async () => { await sql.transactional(async () => {
const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected
FROM notes JOIN branches USING(noteId) FROM notes JOIN branches USING(noteId)
WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]); WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]);

View File

@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/public" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/public" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/dist" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />