change in naming of SQL methods

added assert methods to note tree
This commit is contained in:
azivner 2017-12-23 11:02:38 -05:00
parent c07c18f08a
commit bd2a5f6d82
27 changed files with 139 additions and 85 deletions

View File

@ -17,7 +17,7 @@ module.exports = async () => {
const password = await question("Enter password: "); const password = await question("Enter password: ");
const dataKey = await password_encryption.getDecryptedDataKey(password); const dataKey = await password_encryption.getDecryptedDataKey(password);
const protectedNotes = await sql.getResults("SELECT * FROM notes WHERE is_protected = 1"); const protectedNotes = await sql.getAll("SELECT * FROM notes WHERE is_protected = 1");
for (const note of protectedNotes) { for (const note of protectedNotes) {
const decryptedTitle = data_encryption.decrypt(dataKey, note.note_title); const decryptedTitle = data_encryption.decrypt(dataKey, note.note_title);
@ -30,7 +30,7 @@ module.exports = async () => {
await sql.execute("UPDATE notes SET note_title = ?, note_text = ? WHERE note_id = ?", [note.note_title, note.note_text, note.note_id]); await sql.execute("UPDATE notes SET note_title = ?, note_text = ? WHERE note_id = ?", [note.note_title, note.note_text, note.note_id]);
} }
const protectedNotesHistory = await sql.getResults("SELECT * FROM notes_history WHERE is_protected = 1"); const protectedNotesHistory = await sql.getAll("SELECT * FROM notes_history WHERE is_protected = 1");
for (const noteHistory of protectedNotesHistory) { for (const noteHistory of protectedNotesHistory) {
const decryptedTitle = data_encryption.decrypt(dataKey, noteHistory.note_title); const decryptedTitle = data_encryption.decrypt(dataKey, noteHistory.note_title);

View File

@ -15,6 +15,8 @@ const noteTree = (function() {
let noteIdToTitle = {}; let noteIdToTitle = {};
function getNoteTreeId(parentNoteId, childNoteId) { function getNoteTreeId(parentNoteId, childNoteId) {
assertArguments(parentNoteId, childNoteId);
const key = parentNoteId + "-" + childNoteId; const key = parentNoteId + "-" + childNoteId;
// this can return undefined and client code should deal with it somehow // this can return undefined and client code should deal with it somehow
@ -23,6 +25,8 @@ const noteTree = (function() {
} }
function getNoteTitle(noteId, parentNoteId = null) { function getNoteTitle(noteId, parentNoteId = null) {
assertArguments(noteId);
let title = noteIdToTitle[noteId]; let title = noteIdToTitle[noteId];
if (!title) { if (!title) {
@ -73,17 +77,23 @@ const noteTree = (function() {
} }
function getNodesByNoteTreeId(noteTreeId) { function getNodesByNoteTreeId(noteTreeId) {
assertArguments(noteTreeId);
const noteTree = notesTreeMap[noteTreeId]; const noteTree = notesTreeMap[noteTreeId];
return getNodesByNoteId(noteTree.note_id).filter(node => node.data.note_tree_id === noteTreeId); return getNodesByNoteId(noteTree.note_id).filter(node => node.data.note_tree_id === noteTreeId);
} }
function getNodesByNoteId(noteId) { function getNodesByNoteId(noteId) {
assertArguments(noteId);
const list = getTree().getNodesByRef(noteId); const list = getTree().getNodesByRef(noteId);
return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null
} }
function setPrefix(noteTreeId, prefix) { function setPrefix(noteTreeId, prefix) {
assertArguments(noteTreeId);
notesTreeMap[noteTreeId].prefix = prefix; notesTreeMap[noteTreeId].prefix = prefix;
getNodesByNoteTreeId(noteTreeId).map(node => { getNodesByNoteTreeId(noteTreeId).map(node => {
@ -94,6 +104,8 @@ const noteTree = (function() {
} }
function removeParentChildRelation(parentNoteId, childNoteId) { function removeParentChildRelation(parentNoteId, childNoteId) {
assertArguments(parentNoteId, childNoteId);
const key = parentNoteId + "-" + childNoteId; const key = parentNoteId + "-" + childNoteId;
delete parentChildToNoteTreeId[key]; delete parentChildToNoteTreeId[key];
@ -103,6 +115,8 @@ const noteTree = (function() {
} }
function setParentChildRelation(noteTreeId, parentNoteId, childNoteId) { function setParentChildRelation(noteTreeId, parentNoteId, childNoteId) {
assertArguments(noteTreeId, parentNoteId, childNoteId);
const key = parentNoteId + "-" + childNoteId; const key = parentNoteId + "-" + childNoteId;
parentChildToNoteTreeId[key] = noteTreeId; parentChildToNoteTreeId[key] = noteTreeId;
@ -121,6 +135,8 @@ const noteTree = (function() {
} }
function prepareNoteTree(notes) { function prepareNoteTree(notes) {
assertArguments(notes);
parentToChildren = {}; parentToChildren = {};
childToParents = {}; childToParents = {};
notesTreeMap = {}; notesTreeMap = {};
@ -139,6 +155,8 @@ const noteTree = (function() {
} }
function getExtraClasses(note) { function getExtraClasses(note) {
assertArguments(note);
let extraClasses = ''; let extraClasses = '';
if (note.is_protected) { if (note.is_protected) {
@ -157,6 +175,8 @@ const noteTree = (function() {
} }
function prepareNoteTreeInner(parentNoteId) { function prepareNoteTreeInner(parentNoteId) {
assertArguments(parentNoteId);
const childNoteIds = parentToChildren[parentNoteId]; const childNoteIds = parentToChildren[parentNoteId];
if (!childNoteIds) { if (!childNoteIds) {
messaging.logError("No children for " + parentNoteId + ". This shouldn't happen."); messaging.logError("No children for " + parentNoteId + ". This shouldn't happen.");
@ -199,6 +219,8 @@ const noteTree = (function() {
} }
async function activateNode(notePath) { async function activateNode(notePath) {
assertArguments(notePath);
const runPath = getRunPath(notePath); const runPath = getRunPath(notePath);
const noteId = treeUtils.getNoteIdFromNotePath(notePath); const noteId = treeUtils.getNoteIdFromNotePath(notePath);
@ -225,6 +247,8 @@ const noteTree = (function() {
* path change) or other corruption, in that case this will try to get some other valid path to the correct note. * path change) or other corruption, in that case this will try to get some other valid path to the correct note.
*/ */
function getRunPath(notePath) { function getRunPath(notePath) {
assertArguments(notePath);
const path = notePath.split("/").reverse(); const path = notePath.split("/").reverse();
path.push('root'); path.push('root');
@ -251,6 +275,8 @@ const noteTree = (function() {
console.log(now(), "Did not find parent " + parentNoteId + " for child " + childNoteId); console.log(now(), "Did not find parent " + parentNoteId + " for child " + childNoteId);
if (parents.length > 0) { if (parents.length > 0) {
console.log(now(), "Available parents:", parents);
const pathToRoot = getSomeNotePath(parents[0]).split("/").reverse(); const pathToRoot = getSomeNotePath(parents[0]).split("/").reverse();
for (const noteId of pathToRoot) { for (const noteId of pathToRoot) {
@ -279,6 +305,8 @@ const noteTree = (function() {
} }
function showParentList(noteId, node) { function showParentList(noteId, node) {
assertArguments(noteId, node);
const parents = childToParents[noteId]; const parents = childToParents[noteId];
if (!parents) { if (!parents) {
@ -313,6 +341,8 @@ const noteTree = (function() {
} }
function getNotePathTitle(notePath) { function getNotePathTitle(notePath) {
assertArguments(notePath);
const titlePath = []; const titlePath = [];
let parentNoteId = 'root'; let parentNoteId = 'root';
@ -327,6 +357,8 @@ const noteTree = (function() {
} }
function getSomeNotePath(noteId) { function getSomeNotePath(noteId) {
assertArguments(noteId);
const path = []; const path = [];
let cur = noteId; let cur = noteId;
@ -345,12 +377,16 @@ const noteTree = (function() {
} }
async function setExpandedToServer(noteTreeId, isExpanded) { async function setExpandedToServer(noteTreeId, isExpanded) {
assertArguments(noteTreeId);
const expandedNum = isExpanded ? 1 : 0; const expandedNum = isExpanded ? 1 : 0;
await server.put('notes/' + noteTreeId + '/expanded/' + expandedNum); await server.put('notes/' + noteTreeId + '/expanded/' + expandedNum);
} }
function setCurrentNotePathToHash(node) { function setCurrentNotePathToHash(node) {
assertArguments(node);
const currentNotePath = treeUtils.getNotePath(node); const currentNotePath = treeUtils.getNotePath(node);
const currentNoteTreeId = node.data.note_tree_id; const currentNoteTreeId = node.data.note_tree_id;
@ -360,6 +396,8 @@ const noteTree = (function() {
} }
function initFancyTree(noteTree) { function initFancyTree(noteTree) {
assertArguments(noteTree);
const keybindings = { const keybindings = {
"del": node => { "del": node => {
treeChanges.deleteNode(node); treeChanges.deleteNode(node);
@ -601,6 +639,8 @@ const noteTree = (function() {
} }
function setNoteTitle(noteId, title) { function setNoteTitle(noteId, title) {
assertArguments(noteId);
noteIdToTitle[noteId] = title; noteIdToTitle[noteId] = title;
getNodesByNoteId(noteId).map(clone => treeUtils.setNodeTitleWithPrefix(clone)); getNodesByNoteId(noteId).map(clone => treeUtils.setNodeTitleWithPrefix(clone));
@ -613,6 +653,8 @@ const noteTree = (function() {
} }
async function createNote(node, parentNoteId, target, isProtected) { async function createNote(node, parentNoteId, target, isProtected) {
assertArguments(node, parentNoteId, target);
// if isProtected isn't available (user didn't enter password yet), then note is created as unencrypted // if isProtected isn't available (user didn't enter password yet), then note is created as unencrypted
// but this is quite weird since user doesn't see WHERE the note is being created so it shouldn't occur often // but this is quite weird since user doesn't see WHERE the note is being created so it shouldn't occur often
if (!isProtected || !protected_session.isProtectedSessionAvailable()) { if (!isProtected || !protected_session.isProtectedSessionAvailable()) {

View File

@ -72,3 +72,15 @@ function now() {
function isElectron() { function isElectron() {
return window && window.process && window.process.type; return window && window.process && window.process.type;
} }
function assertArguments() {
for (const i in arguments) {
assert(arguments[i], `argument ${i} should not be falsy. Argument list: ${arguments}`);
}
}
function assert(expr, message) {
if (!expr) {
throwError(message);
}
}

View File

@ -9,7 +9,7 @@ const auth = require('../../services/auth');
router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, async (req, res, next) => { router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, async (req, res, next) => {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
const noteIdsToDelete = await sql.getFlattenedResults("SELECT note_id FROM notes WHERE is_deleted = 1"); const noteIdsToDelete = await sql.getFirstColumn("SELECT note_id FROM notes WHERE is_deleted = 1");
const noteIdsSql = noteIdsToDelete const noteIdsSql = noteIdsToDelete
.map(noteId => "'" + utils.sanitizeSql(noteId) + "'") .map(noteId => "'" + utils.sanitizeSql(noteId) + "'")
.join(', '); .join(', ');

View File

@ -8,13 +8,13 @@ const auth = require('../../services/auth');
router.get('', auth.checkApiAuth, async (req, res, next) => { router.get('', auth.checkApiAuth, async (req, res, next) => {
await deleteOld(); await deleteOld();
const result = await sql.getResults("SELECT * FROM event_log ORDER BY date_added DESC"); const result = await sql.getAll("SELECT * FROM event_log ORDER BY date_added DESC");
res.send(result); res.send(result);
}); });
async function deleteOld() { async function deleteOld() {
const cutoffId = await sql.getSingleValue("SELECT id FROM event_log ORDER BY id DESC LIMIT 1000, 1"); const cutoffId = await sql.getFirstValue("SELECT id FROM event_log ORDER BY id DESC LIMIT 1000, 1");
if (cutoffId) { if (cutoffId) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {

View File

@ -25,7 +25,7 @@ router.get('/:noteId/to/:directory', auth.checkApiAuth, async (req, res, next) =
fs.mkdirSync(completeExportDir); fs.mkdirSync(completeExportDir);
const noteTreeId = await sql.getSingleValue('SELECT note_tree_id FROM notes_tree WHERE note_id = ?', [noteId]); const noteTreeId = await sql.getFirstValue('SELECT note_tree_id FROM notes_tree WHERE note_id = ?', [noteId]);
await exportNote(noteTreeId, completeExportDir); await exportNote(noteTreeId, completeExportDir);
@ -33,14 +33,14 @@ router.get('/:noteId/to/:directory', auth.checkApiAuth, async (req, res, next) =
}); });
async function exportNote(noteTreeId, dir) { async function exportNote(noteTreeId, dir) {
const noteTree = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]); const noteTree = await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
const note = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteTree.note_id]); const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteTree.note_id]);
const pos = (noteTree.note_position + '').padStart(4, '0'); const pos = (noteTree.note_position + '').padStart(4, '0');
fs.writeFileSync(dir + '/' + pos + '-' + note.note_title + '.html', html.prettyPrint(note.note_text, {indent_size: 2})); fs.writeFileSync(dir + '/' + pos + '-' + note.note_title + '.html', html.prettyPrint(note.note_text, {indent_size: 2}));
const children = await sql.getResults("SELECT * FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [note.note_id]); const children = await sql.getAll("SELECT * FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [note.note_id]);
if (children.length > 0) { if (children.length > 0) {
const childrenDir = dir + '/' + pos + '-' + note.note_title; const childrenDir = dir + '/' + pos + '-' + note.note_title;

View File

@ -21,7 +21,7 @@ router.get('/:directory/to/:parentNoteId', auth.checkApiAuth, async (req, res, n
}); });
async function importNotes(dir, parentNoteId) { async function importNotes(dir, parentNoteId) {
const parent = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]); const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]);
if (!parent) { if (!parent) {
return; return;
@ -51,7 +51,7 @@ async function importNotes(dir, parentNoteId) {
noteTitle = match[2]; noteTitle = match[2];
} }
else { else {
let maxPos = await sql.getSingleValue("SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [parentNoteId]); let maxPos = await sql.getFirstValue("SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [parentNoteId]);
if (maxPos) { if (maxPos) {
notePos = maxPos + 1; notePos = maxPos + 1;
} }

View File

@ -10,7 +10,7 @@ const sync_table = require('../../services/sync_table');
router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
const history = await sql.getResults("SELECT * FROM notes_history WHERE note_id = ? order by date_modified_to desc", [noteId]); const history = await sql.getAll("SELECT * FROM notes_history WHERE note_id = ? order by date_modified_to desc", [noteId]);
const dataKey = protected_session.getDataKey(req); const dataKey = protected_session.getDataKey(req);

View File

@ -12,7 +12,7 @@ const data_encryption = require('../../services/data_encryption');
router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
const detail = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); const detail = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
if (!detail) { if (!detail) {
log.info("Note " + noteId + " has not been found."); log.info("Note " + noteId + " has not been found.");
@ -67,7 +67,7 @@ router.delete('/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
router.get('/', auth.checkApiAuth, async (req, res, next) => { router.get('/', auth.checkApiAuth, async (req, res, next) => {
const search = '%' + req.query.search + '%'; const search = '%' + req.query.search + '%';
const result = await sql.getResults("SELECT note_id FROM notes WHERE note_title liKE ? OR note_text LIKE ?", [search, search]); const result = await sql.getAll("SELECT note_id FROM notes WHERE note_title liKE ? OR note_text LIKE ?", [search, search]);
const noteIdList = []; const noteIdList = [];

View File

@ -12,7 +12,7 @@ router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, async (req,
const parentNoteId = req.params.parentNoteId; const parentNoteId = req.params.parentNoteId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const maxNotePos = await sql.getSingleValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]); const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
const now = utils.nowDate(); const now = utils.nowDate();
@ -32,7 +32,7 @@ router.put('/:noteTreeId/move-before/:beforeNoteTreeId', auth.checkApiAuth, asyn
const beforeNoteTreeId = req.params.beforeNoteTreeId; const beforeNoteTreeId = req.params.beforeNoteTreeId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const beforeNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [beforeNoteTreeId]); const beforeNote = await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [beforeNoteTreeId]);
if (beforeNote) { if (beforeNote) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
@ -63,7 +63,7 @@ router.put('/:noteTreeId/move-after/:afterNoteTreeId', auth.checkApiAuth, async
const afterNoteTreeId = req.params.afterNoteTreeId; const afterNoteTreeId = req.params.afterNoteTreeId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); const afterNote = await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]);
if (afterNote) { if (afterNote) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
@ -93,7 +93,7 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req
const prefix = req.body.prefix; const prefix = req.body.prefix;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND parent_note_id = ?', [childNoteId, parentNoteId]); const existing = await sql.getFirstValue('SELECT * FROM notes_tree WHERE note_id = ? AND parent_note_id = ?', [childNoteId, parentNoteId]);
if (existing && !existing.is_deleted) { if (existing && !existing.is_deleted) {
return res.send({ return res.send({
@ -109,7 +109,7 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, async (req
}); });
} }
const maxNotePos = await sql.getSingleValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]); const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
@ -141,7 +141,7 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, async (re
const afterNoteTreeId = req.params.afterNoteTreeId; const afterNoteTreeId = req.params.afterNoteTreeId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const afterNote = await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]); const afterNote = await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [afterNoteTreeId]);
if (!afterNote) { if (!afterNote) {
return res.status(500).send("After note " + afterNoteTreeId + " doesn't exist."); return res.status(500).send("After note " + afterNoteTreeId + " doesn't exist.");
@ -154,7 +154,7 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, async (re
}); });
} }
const existing = await sql.getSingleValue('SELECT * FROM notes_tree WHERE note_id = ? AND parent_note_id = ?', [noteId, afterNote.parent_note_id]); const existing = await sql.getFirstValue('SELECT * FROM notes_tree WHERE note_id = ? AND parent_note_id = ?', [noteId, afterNote.parent_note_id]);
if (existing && !existing.is_deleted) { if (existing && !existing.is_deleted) {
return res.send({ return res.send({
@ -200,7 +200,7 @@ async function checkCycle(parentNoteId, childNoteId) {
return false; return false;
} }
const parentNoteIds = await sql.getFlattenedResults("SELECT DISTINCT parent_note_id FROM notes_tree WHERE note_id = ?", [parentNoteId]); const parentNoteIds = await sql.getFirstColumn("SELECT DISTINCT parent_note_id FROM notes_tree WHERE note_id = ?", [parentNoteId]);
for (const pid of parentNoteIds) { for (const pid of parentNoteIds) {
if (!await checkCycle(pid, childNoteId)) { if (!await checkCycle(pid, childNoteId)) {

View File

@ -6,7 +6,7 @@ const sql = require('../../services/sql');
const auth = require('../../services/auth'); const auth = require('../../services/auth');
router.get('/', auth.checkApiAuth, async (req, res, next) => { router.get('/', auth.checkApiAuth, async (req, res, next) => {
const recentChanges = await sql.getResults( const recentChanges = await sql.getAll(
`SELECT `SELECT
notes.is_deleted AS current_is_deleted, notes.is_deleted AS current_is_deleted,
notes.note_title AS current_note_title, notes.note_title AS current_note_title,

View File

@ -34,7 +34,7 @@ router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) =
}); });
async function getRecentNotes() { async function getRecentNotes() {
return await sql.getResults(` return await sql.getAll(`
SELECT SELECT
recent_notes.* recent_notes.*
FROM FROM

View File

@ -11,7 +11,7 @@ router.post('/execute', auth.checkApiAuth, async (req, res, next) => {
try { try {
res.send({ res.send({
success: true, success: true,
rows: await sql.getResults(query) rows: await sql.getAll(query)
}); });
} }
catch (e) { catch (e) {

View File

@ -13,7 +13,7 @@ const content_hash = require('../../services/content_hash');
router.get('/check', auth.checkApiAuth, async (req, res, next) => { router.get('/check', auth.checkApiAuth, async (req, res, next) => {
res.send({ res.send({
'hashes': await content_hash.getHashes(), 'hashes': await content_hash.getHashes(),
'max_sync_id': await sql.getSingleValue('SELECT MAX(id) FROM sync') 'max_sync_id': await sql.getFirstValue('SELECT MAX(id) FROM sync')
}); });
}); });
@ -47,27 +47,27 @@ router.post('/force-full-sync', auth.checkApiAuth, async (req, res, next) => {
router.get('/changed', auth.checkApiAuth, async (req, res, next) => { router.get('/changed', auth.checkApiAuth, async (req, res, next) => {
const lastSyncId = parseInt(req.query.lastSyncId); const lastSyncId = parseInt(req.query.lastSyncId);
res.send(await sql.getResults("SELECT * FROM sync WHERE id > ?", [lastSyncId])); res.send(await sql.getAll("SELECT * FROM sync WHERE id > ?", [lastSyncId]));
}); });
router.get('/notes/:noteId', auth.checkApiAuth, async (req, res, next) => { router.get('/notes/:noteId', auth.checkApiAuth, async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
res.send({ res.send({
entity: await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]) entity: await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId])
}); });
}); });
router.get('/notes_tree/:noteTreeId', auth.checkApiAuth, async (req, res, next) => { router.get('/notes_tree/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const noteTreeId = req.params.noteTreeId;
res.send(await sql.getSingleResult("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId])); res.send(await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]));
}); });
router.get('/notes_history/:noteHistoryId', auth.checkApiAuth, async (req, res, next) => { router.get('/notes_history/:noteHistoryId', auth.checkApiAuth, async (req, res, next) => {
const noteHistoryId = req.params.noteHistoryId; const noteHistoryId = req.params.noteHistoryId;
res.send(await sql.getSingleResult("SELECT * FROM notes_history WHERE note_history_id = ?", [noteHistoryId])); res.send(await sql.getFirst("SELECT * FROM notes_history WHERE note_history_id = ?", [noteHistoryId]));
}); });
router.get('/options/:optName', auth.checkApiAuth, async (req, res, next) => { router.get('/options/:optName', auth.checkApiAuth, async (req, res, next) => {
@ -77,7 +77,7 @@ router.get('/options/:optName', auth.checkApiAuth, async (req, res, next) => {
res.send("This option can't be synced."); res.send("This option can't be synced.");
} }
else { else {
res.send(await sql.getSingleResult("SELECT * FROM options WHERE opt_name = ?", [optName])); res.send(await sql.getFirst("SELECT * FROM options WHERE opt_name = ?", [optName]));
} }
}); });
@ -93,7 +93,7 @@ router.get('/notes_reordering/:noteTreeParentId', auth.checkApiAuth, async (req,
router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, async (req, res, next) => { router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const noteTreeId = req.params.noteTreeId;
res.send(await sql.getSingleResult("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId])); res.send(await sql.getFirst("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId]));
}); });
router.put('/notes', auth.checkApiAuth, async (req, res, next) => { router.put('/notes', auth.checkApiAuth, async (req, res, next) => {

View File

@ -12,7 +12,7 @@ const notes = require('../../services/notes');
const sync_table = require('../../services/sync_table'); const sync_table = require('../../services/sync_table');
router.get('/', auth.checkApiAuth, async (req, res, next) => { router.get('/', auth.checkApiAuth, async (req, res, next) => {
const notes = await sql.getResults("SELECT " const notes = await sql.getAll("SELECT "
+ "notes_tree.*, " + "notes_tree.*, "
+ "notes.note_title, " + "notes.note_title, "
+ "notes.is_protected " + "notes.is_protected "

View File

@ -9,7 +9,7 @@ const sql = require('../services/sql');
router.get('', auth.checkAuth, async (req, res, next) => { router.get('', auth.checkAuth, async (req, res, next) => {
res.render('index', { res.render('index', {
sourceId: await source_id.generateSourceId(), sourceId: await source_id.generateSourceId(),
maxSyncIdAtLoad: await sql.getSingleValue("SELECT MAX(id) FROM sync") maxSyncIdAtLoad: await sql.getFirstValue("SELECT MAX(id) FROM sync")
}); });
}); });

View File

@ -5,7 +5,7 @@ const log = require('./log');
const messaging = require('./messaging'); const messaging = require('./messaging');
async function runCheck(query, errorText, errorList) { async function runCheck(query, errorText, errorList) {
const result = await sql.getFlattenedResults(query); const result = await sql.getFirstColumn(query);
if (result.length > 0) { if (result.length > 0) {
const err = errorText + ": " + result; const err = errorText + ": " + result;

View File

@ -16,7 +16,7 @@ async function getHashes() {
const optionsQuestionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(','); const optionsQuestionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(',');
return { return {
notes: getHash(await sql.getResults(`SELECT notes: getHash(await sql.getAll(`SELECT
note_id, note_id,
note_title, note_title,
note_text, note_text,
@ -26,7 +26,7 @@ async function getHashes() {
FROM notes FROM notes
ORDER BY note_id`)), ORDER BY note_id`)),
notes_tree: getHash(await sql.getResults(`SELECT notes_tree: getHash(await sql.getAll(`SELECT
note_tree_id, note_tree_id,
note_id, note_id,
parent_note_id, parent_note_id,
@ -37,7 +37,7 @@ async function getHashes() {
FROM notes_tree FROM notes_tree
ORDER BY note_tree_id`)), ORDER BY note_tree_id`)),
notes_history: getHash(await sql.getResults(`SELECT notes_history: getHash(await sql.getAll(`SELECT
note_history_id, note_history_id,
note_id, note_id,
note_title, note_title,
@ -47,7 +47,7 @@ async function getHashes() {
FROM notes_history FROM notes_history
ORDER BY note_history_id`)), ORDER BY note_history_id`)),
recent_notes: getHash(await sql.getResults(`SELECT recent_notes: getHash(await sql.getAll(`SELECT
note_tree_id, note_tree_id,
note_path, note_path,
date_accessed, date_accessed,
@ -55,7 +55,7 @@ async function getHashes() {
FROM recent_notes FROM recent_notes
ORDER BY note_path`)), ORDER BY note_path`)),
options: getHash(await sql.getResults(`SELECT options: getHash(await sql.getAll(`SELECT
opt_name, opt_name,
opt_value opt_value
FROM options FROM options

View File

@ -62,11 +62,11 @@ async function sendMessageToAllClients(message) {
} }
async function sendPing(client, lastSentSyncId) { async function sendPing(client, lastSentSyncId) {
const syncData = await sql.getResults("SELECT * FROM sync WHERE id > ?", [lastSentSyncId]); const syncData = await sql.getAll("SELECT * FROM sync WHERE id > ?", [lastSentSyncId]);
const lastSyncedPush = await options.getOption('last_synced_push'); const lastSyncedPush = await options.getOption('last_synced_push');
const changesToPushCount = await sql.getSingleValue("SELECT COUNT(*) FROM sync WHERE id > ?", [lastSyncedPush]); const changesToPushCount = await sql.getFirstValue("SELECT COUNT(*) FROM sync WHERE id > ?", [lastSyncedPush]);
await sendMessage(client, { await sendMessage(client, {
type: 'sync', type: 'sync',

View File

@ -13,12 +13,12 @@ async function createNewNote(parentNoteId, note, sourceId) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
if (note.target === 'into') { if (note.target === 'into') {
const maxNotePos = await sql.getSingleValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]); const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
} }
else if (note.target === 'after') { else if (note.target === 'after') {
const afterNote = await sql.getSingleResult('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]); const afterNote = await sql.getFirst('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]);
newNotePos = afterNote.note_position + 1; newNotePos = afterNote.note_position + 1;
@ -70,11 +70,11 @@ async function encryptNote(note, dataKey) {
} }
async function protectNoteRecursively(noteId, dataKey, protect, sourceId) { async function protectNoteRecursively(noteId, dataKey, protect, sourceId) {
const note = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
await protectNote(note, dataKey, protect, sourceId); await protectNote(note, dataKey, protect, sourceId);
const children = await sql.getFlattenedResults("SELECT note_id FROM notes_tree WHERE parent_note_id = ?", [noteId]); const children = await sql.getFirstColumn("SELECT note_id FROM notes_tree WHERE parent_note_id = ?", [noteId]);
for (const childNoteId of children) { for (const childNoteId of children) {
await protectNoteRecursively(childNoteId, dataKey, protect, sourceId); await protectNoteRecursively(childNoteId, dataKey, protect, sourceId);
@ -116,7 +116,7 @@ async function protectNote(note, dataKey, protect, sourceId) {
} }
async function protectNoteHistory(noteId, dataKey, protect, sourceId) { async function protectNoteHistory(noteId, dataKey, protect, sourceId) {
const historyToChange = await sql.getResults("SELECT * FROM notes_history WHERE note_id = ? AND is_protected != ?", [noteId, protect]); const historyToChange = await sql.getAll("SELECT * FROM notes_history WHERE note_id = ? AND is_protected != ?", [noteId, protect]);
for (const history of historyToChange) { for (const history of historyToChange) {
if (protect) { if (protect) {
@ -149,14 +149,14 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000)); const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000));
const existingNoteHistoryId = await sql.getSingleValue( const existingNoteHistoryId = await sql.getFirstValue(
"SELECT note_history_id FROM notes_history WHERE note_id = ? AND date_modified_to >= ?", [noteId, historyCutoff]); "SELECT note_history_id FROM notes_history WHERE note_id = ? AND date_modified_to >= ?", [noteId, historyCutoff]);
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
const msSinceDateCreated = now.getTime() - utils.parseDate(newNote.detail.date_created).getTime(); const msSinceDateCreated = now.getTime() - utils.parseDate(newNote.detail.date_created).getTime();
if (!existingNoteHistoryId && msSinceDateCreated >= historySnapshotTimeInterval * 1000) { if (!existingNoteHistoryId && msSinceDateCreated >= historySnapshotTimeInterval * 1000) {
const oldNote = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [noteId]); const oldNote = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
if (oldNote.is_protected) { if (oldNote.is_protected) {
decryptNote(oldNote, dataKey); decryptNote(oldNote, dataKey);
@ -197,15 +197,15 @@ async function deleteNote(noteTreeId, sourceId) {
await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]); await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addNoteTreeSync(noteTreeId, sourceId);
const noteId = await sql.getSingleValue("SELECT note_id FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]); const noteId = await sql.getFirstValue("SELECT note_id FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
const notDeletedNoteTreesCount = await sql.getSingleValue("SELECT COUNT(*) FROM notes_tree WHERE note_id = ? AND is_deleted = 0", [noteId]); const notDeletedNoteTreesCount = await sql.getFirstValue("SELECT COUNT(*) FROM notes_tree WHERE note_id = ? AND is_deleted = 0", [noteId]);
if (!notDeletedNoteTreesCount) { if (!notDeletedNoteTreesCount) {
await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]); await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]);
await sync_table.addNoteSync(noteId, sourceId); await sync_table.addNoteSync(noteId, sourceId);
const children = await sql.getResults("SELECT note_tree_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteId]); const children = await sql.getAll("SELECT note_tree_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteId]);
for (const child of children) { for (const child of children) {
await deleteNote(child.note_tree_id, sourceId); await deleteNote(child.note_tree_id, sourceId);

View File

@ -7,7 +7,7 @@ const SYNCED_OPTIONS = [ 'username', 'password_verification_hash', 'encrypted_da
'history_snapshot_time_interval' ]; 'history_snapshot_time_interval' ];
async function getOption(optName) { async function getOption(optName) {
const row = await sql.getSingleResultOrNull("SELECT opt_value FROM options WHERE opt_name = ?", [optName]); const row = await sql.getFirstOrNull("SELECT opt_value FROM options WHERE opt_name = ?", [optName]);
if (!row) { if (!row) {
throw new Error("Option " + optName + " doesn't exist"); throw new Error("Option " + optName + " doesn't exist");

View File

@ -20,7 +20,7 @@ async function generateSourceId() {
} }
async function refreshSourceIds() { async function refreshSourceIds() {
allSourceIds = await sql.getFlattenedResults("SELECT source_id FROM source_ids ORDER BY date_created DESC"); allSourceIds = await sql.getFirstColumn("SELECT source_id FROM source_ids ORDER BY date_created DESC");
} }
let allSourceIds = []; let allSourceIds = [];

View File

@ -24,7 +24,7 @@ const dbReady = new Promise((resolve, reject) => {
resolve(db); resolve(db);
}; };
const tableResults = await getResults("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'"); const tableResults = await getAll("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'");
if (tableResults.length !== 1) { if (tableResults.length !== 1) {
log.info("Connected to db, but schema doesn't exist. Initializing schema ..."); log.info("Connected to db, but schema doesn't exist. Initializing schema ...");
@ -62,7 +62,7 @@ const dbReady = new Promise((resolve, reject) => {
// the database // the database
} }
else { else {
const username = await getSingleValue("SELECT opt_value FROM options WHERE opt_name = 'username'"); const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
if (!username) { if (!username) {
log.info("Login/password not initialized. DB not ready."); log.info("Login/password not initialized. DB not ready.");
@ -120,18 +120,18 @@ async function rollback() {
return await wrap(async db => db.run("ROLLBACK")); return await wrap(async db => db.run("ROLLBACK"));
} }
async function getSingleResult(query, params = []) { async function getFirst(query, params = []) {
return await wrap(async db => db.get(query, ...params)); return await wrap(async db => db.get(query, ...params));
} }
async function getSingleResultOrNull(query, params = []) { async function getFirstOrNull(query, params = []) {
const all = await wrap(async db => db.all(query, ...params)); const all = await wrap(async db => db.all(query, ...params));
return all.length > 0 ? all[0] : null; return all.length > 0 ? all[0] : null;
} }
async function getSingleValue(query, params = []) { async function getFirstValue(query, params = []) {
const row = await getSingleResultOrNull(query, params); const row = await getFirstOrNull(query, params);
if (!row) { if (!row) {
return null; return null;
@ -140,13 +140,13 @@ async function getSingleValue(query, params = []) {
return row[Object.keys(row)[0]]; return row[Object.keys(row)[0]];
} }
async function getResults(query, params = []) { async function getAll(query, params = []) {
return await wrap(async db => db.all(query, ...params)); return await wrap(async db => db.all(query, ...params));
} }
async function getMap(query, params = []) { async function getMap(query, params = []) {
const map = {}; const map = {};
const results = await getResults(query, params); const results = await getAll(query, params);
for (const row of results) { for (const row of results) {
const keys = Object.keys(row); const keys = Object.keys(row);
@ -157,9 +157,9 @@ async function getMap(query, params = []) {
return map; return map;
} }
async function getFlattenedResults(query, params = []) { async function getFirstColumn(query, params = []) {
const list = []; const list = [];
const result = await getResults(query, params); const result = await getAll(query, params);
if (result.length === 0) { if (result.length === 0) {
return list; return list;
@ -237,7 +237,7 @@ async function doInTransaction(func) {
} }
async function isDbUpToDate() { async function isDbUpToDate() {
const dbVersion = parseInt(await getSingleValue("SELECT opt_value FROM options WHERE opt_name = 'db_version'")); const dbVersion = parseInt(await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'db_version'"));
const upToDate = dbVersion >= app_info.db_version; const upToDate = dbVersion >= app_info.db_version;
@ -252,12 +252,12 @@ module.exports = {
dbReady, dbReady,
insert, insert,
replace, replace,
getSingleValue, getFirstValue,
getSingleResult, getFirst,
getSingleResultOrNull, getFirstOrNull,
getResults, getAll,
getMap, getMap,
getFlattenedResults, getFirstColumn,
execute, execute,
executeScript, executeScript,
doInTransaction, doInTransaction,

View File

@ -176,7 +176,7 @@ async function pushSync(syncContext) {
let lastSyncedPush = await getLastSyncedPush(); let lastSyncedPush = await getLastSyncedPush();
while (true) { while (true) {
const sync = await sql.getSingleResultOrNull('SELECT * FROM sync WHERE id > ? LIMIT 1', [lastSyncedPush]); const sync = await sql.getFirstOrNull('SELECT * FROM sync WHERE id > ? LIMIT 1', [lastSyncedPush]);
if (sync === null) { if (sync === null) {
// nothing to sync // nothing to sync
@ -203,13 +203,13 @@ async function pushEntity(sync, syncContext) {
let entity; let entity;
if (sync.entity_name === 'notes') { if (sync.entity_name === 'notes') {
entity = await sql.getSingleResult('SELECT * FROM notes WHERE note_id = ?', [sync.entity_id]); entity = await sql.getFirst('SELECT * FROM notes WHERE note_id = ?', [sync.entity_id]);
} }
else if (sync.entity_name === 'notes_tree') { else if (sync.entity_name === 'notes_tree') {
entity = await sql.getSingleResult('SELECT * FROM notes_tree WHERE note_tree_id = ?', [sync.entity_id]); entity = await sql.getFirst('SELECT * FROM notes_tree WHERE note_tree_id = ?', [sync.entity_id]);
} }
else if (sync.entity_name === 'notes_history') { else if (sync.entity_name === 'notes_history') {
entity = await sql.getSingleResult('SELECT * FROM notes_history WHERE note_history_id = ?', [sync.entity_id]); entity = await sql.getFirst('SELECT * FROM notes_history WHERE note_history_id = ?', [sync.entity_id]);
} }
else if (sync.entity_name === 'notes_reordering') { else if (sync.entity_name === 'notes_reordering') {
entity = { entity = {
@ -218,10 +218,10 @@ async function pushEntity(sync, syncContext) {
}; };
} }
else if (sync.entity_name === 'options') { else if (sync.entity_name === 'options') {
entity = await sql.getSingleResult('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]); entity = await sql.getFirst('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]);
} }
else if (sync.entity_name === 'recent_notes') { else if (sync.entity_name === 'recent_notes') {
entity = await sql.getSingleResult('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]); entity = await sql.getFirst('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]);
} }
else { else {
throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`); throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
@ -252,7 +252,7 @@ async function checkContentHash(syncContext) {
} }
const lastSyncedPush = await getLastSyncedPush(); const lastSyncedPush = await getLastSyncedPush();
const notPushedSyncs = await sql.getSingleValue("SELECT COUNT(*) FROM sync WHERE id > ?", [lastSyncedPush]); const notPushedSyncs = await sql.getFirstValue("SELECT COUNT(*) FROM sync WHERE id > ?", [lastSyncedPush]);
if (notPushedSyncs > 0) { if (notPushedSyncs > 0) {
log.info("There's " + notPushedSyncs + " outstanding pushes, skipping content check."); log.info("There's " + notPushedSyncs + " outstanding pushes, skipping content check.");

View File

@ -54,10 +54,10 @@ async function cleanupSyncRowsForMissingEntities(entityName, entityKey) {
async function fillSyncRows(entityName, entityKey) { async function fillSyncRows(entityName, entityKey) {
await cleanupSyncRowsForMissingEntities(entityName, entityKey); await cleanupSyncRowsForMissingEntities(entityName, entityKey);
const entityIds = await sql.getFlattenedResults(`SELECT ${entityKey} FROM ${entityName}`); const entityIds = await sql.getFirstColumn(`SELECT ${entityKey} FROM ${entityName}`);
for (const entityId of entityIds) { for (const entityId of entityIds) {
const existingRows = await sql.getSingleValue("SELECT COUNT(id) FROM sync WHERE entity_name = ? AND entity_id = ?", [entityName, entityId]); const existingRows = await sql.getFirstValue("SELECT COUNT(id) FROM sync WHERE entity_name = ? AND entity_id = ?", [entityName, entityId]);
// we don't want to replace existing entities (which would effectively cause full resync) // we don't want to replace existing entities (which would effectively cause full resync)
if (existingRows === 0) { if (existingRows === 0) {

View File

@ -6,7 +6,7 @@ const notes = require('./notes');
const sync_table = require('./sync_table'); const sync_table = require('./sync_table');
async function updateNote(entity, sourceId) { async function updateNote(entity, sourceId) {
const origNote = await sql.getSingleResult("SELECT * FROM notes WHERE note_id = ?", [entity.note_id]); const origNote = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [entity.note_id]);
if (!origNote || origNote.date_modified <= entity.date_modified) { if (!origNote || origNote.date_modified <= entity.date_modified) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
@ -21,7 +21,7 @@ async function updateNote(entity, sourceId) {
} }
async function updateNoteTree(entity, sourceId) { async function updateNoteTree(entity, sourceId) {
const orig = await sql.getSingleResultOrNull("SELECT * FROM notes_tree WHERE note_tree_id = ?", [entity.note_tree_id]); const orig = await sql.getFirstOrNull("SELECT * FROM notes_tree WHERE note_tree_id = ?", [entity.note_tree_id]);
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
if (orig === null || orig.date_modified < entity.date_modified) { if (orig === null || orig.date_modified < entity.date_modified) {
@ -37,7 +37,7 @@ async function updateNoteTree(entity, sourceId) {
} }
async function updateNoteHistory(entity, sourceId) { async function updateNoteHistory(entity, sourceId) {
const orig = await sql.getSingleResultOrNull("SELECT * FROM notes_history WHERE note_history_id = ?", [entity.note_history_id]); const orig = await sql.getFirstOrNull("SELECT * FROM notes_history WHERE note_history_id = ?", [entity.note_history_id]);
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
if (orig === null || orig.date_modified_to < entity.date_modified_to) { if (orig === null || orig.date_modified_to < entity.date_modified_to) {
@ -65,7 +65,7 @@ async function updateOptions(entity, sourceId) {
return; return;
} }
const orig = await sql.getSingleResultOrNull("SELECT * FROM options WHERE opt_name = ?", [entity.opt_name]); const orig = await sql.getFirstOrNull("SELECT * FROM options WHERE opt_name = ?", [entity.opt_name]);
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
if (orig === null || orig.date_modified < entity.date_modified) { if (orig === null || orig.date_modified < entity.date_modified) {
@ -79,7 +79,7 @@ async function updateOptions(entity, sourceId) {
} }
async function updateRecentNotes(entity, sourceId) { async function updateRecentNotes(entity, sourceId) {
const orig = await sql.getSingleResultOrNull("SELECT * FROM recent_notes WHERE note_tree_id = ?", [entity.note_tree_id]); const orig = await sql.getFirstOrNull("SELECT * FROM recent_notes WHERE note_tree_id = ?", [entity.note_tree_id]);
if (orig === null || orig.date_accessed < entity.date_accessed) { if (orig === null || orig.date_accessed < entity.date_accessed) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {

View File

@ -249,7 +249,7 @@
<h4>Cleanup</h4> <h4>Cleanup</h4>
<button id="cleanup-soft-deleted-items-button" class="btn btn-danger btn-sm">Permanently cleanup soft-deleted items</button> <button id="cleanup-soft-deleted-items-button" class="btn btn-danger btn-sm">Permanently cleanup soft-deleted items</button> (should be executed in all synced instances)
<br/> <br/>
<br/> <br/>