mirror of
https://github.com/TriliumNext/Notes.git
synced 2026-01-05 20:39:49 -06:00
added foreign keys to relations to guarantee data consistency
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
const build = require('./build');
|
||||
const packageJson = require('../package');
|
||||
|
||||
const APP_DB_VERSION = 56;
|
||||
const APP_DB_VERSION = 57;
|
||||
|
||||
module.exports = {
|
||||
app_version: packageJson.version,
|
||||
|
||||
@@ -16,7 +16,7 @@ async function runCheck(query, errorText, errorList) {
|
||||
}
|
||||
|
||||
async function runSyncRowChecks(table, key, errorList) {
|
||||
await runCheck(`SELECT ${key} FROM ${table} LEFT JOIN sync ON sync.entity_name = '${table}' AND entity_id = ${key} WHERE sync.id IS NULL`,
|
||||
await runCheck(`SELECT ${key} FROM ${table} LEFT JOIN sync ON sync.entity_name = '${table}' AND entity_id = ${key} WHERE entity_id != 'root' AND sync.id IS NULL`,
|
||||
`Missing sync records for ${key} in table ${table}`, errorList);
|
||||
|
||||
await runCheck(`SELECT entity_id FROM sync LEFT JOIN ${table} ON entity_id = ${key} WHERE sync.entity_name = '${table}' AND ${key} IS NULL`,
|
||||
@@ -26,7 +26,7 @@ async function runSyncRowChecks(table, key, errorList) {
|
||||
async function runChecks() {
|
||||
const errorList = [];
|
||||
|
||||
await runCheck("SELECT note_id FROM notes LEFT JOIN notes_tree USING(note_id) WHERE notes_tree.note_tree_id IS NULL",
|
||||
await runCheck("SELECT note_id FROM notes LEFT JOIN notes_tree USING(note_id) WHERE note_id != 'root' AND notes_tree.note_tree_id IS NULL",
|
||||
"Missing notes_tree records for following note IDs", errorList);
|
||||
|
||||
await runCheck("SELECT note_tree_id || ' > ' || notes_tree.note_id FROM notes_tree LEFT JOIN notes USING(note_id) WHERE notes.note_id IS NULL",
|
||||
@@ -35,7 +35,7 @@ async function runChecks() {
|
||||
await runCheck("SELECT note_tree_id FROM notes_tree JOIN notes USING(note_id) WHERE notes.is_deleted = 1 AND notes_tree.is_deleted = 0",
|
||||
"Note tree is not deleted even though main note is deleted for following note tree IDs", errorList);
|
||||
|
||||
await runCheck("SELECT child.note_pid || ' > ' || child.note_id FROM notes_tree AS child LEFT JOIN notes_tree AS parent ON parent.note_id = child.note_pid WHERE parent.note_id IS NULL AND child.note_pid != 'root'",
|
||||
await runCheck("SELECT child.parent_note_id || ' > ' || child.note_id FROM notes_tree AS child LEFT JOIN notes_tree AS parent ON parent.note_id = child.parent_note_id WHERE parent.note_id IS NULL AND child.parent_note_id != 'root'",
|
||||
"Not existing parent in the following parent > child relations", errorList);
|
||||
|
||||
await runCheck("SELECT note_history_id || ' > ' || notes_history.note_id FROM notes_history LEFT JOIN notes USING(note_id) WHERE notes.note_id IS NULL",
|
||||
|
||||
@@ -29,8 +29,8 @@ async function getHashes() {
|
||||
notes_tree: getHash(await sql.getResults(`SELECT
|
||||
note_tree_id,
|
||||
note_id,
|
||||
note_pid,
|
||||
note_pos,
|
||||
parent_note_id,
|
||||
note_position,
|
||||
date_modified,
|
||||
is_deleted,
|
||||
prefix
|
||||
|
||||
@@ -13,18 +13,18 @@ async function createNewNote(parentNoteId, note, sourceId) {
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
if (note.target === 'into') {
|
||||
const maxNotePos = await sql.getSingleValue('SELECT MAX(note_pos) FROM notes_tree WHERE note_pid = ? AND is_deleted = 0', [parentNoteId]);
|
||||
const maxNotePos = await sql.getSingleValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
|
||||
|
||||
newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
|
||||
}
|
||||
else if (note.target === 'after') {
|
||||
const afterNote = await sql.getSingleResult('SELECT note_pos FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]);
|
||||
const afterNote = await sql.getSingleResult('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]);
|
||||
|
||||
newNotePos = afterNote.note_pos + 1;
|
||||
newNotePos = afterNote.note_position + 1;
|
||||
|
||||
// not updating date_modified to avoig having to sync whole rows
|
||||
await sql.execute('UPDATE notes_tree SET note_pos = note_pos + 1 WHERE note_pid = ? AND note_pos > ? AND is_deleted = 0',
|
||||
[parentNoteId, afterNote.note_pos]);
|
||||
await sql.execute('UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0',
|
||||
[parentNoteId, afterNote.note_position]);
|
||||
|
||||
await sync_table.addNoteReorderingSync(parentNoteId, sourceId);
|
||||
}
|
||||
@@ -48,8 +48,8 @@ async function createNewNote(parentNoteId, note, sourceId) {
|
||||
await sql.insert("notes_tree", {
|
||||
note_tree_id: noteTreeId,
|
||||
note_id: noteId,
|
||||
note_pid: parentNoteId,
|
||||
note_pos: newNotePos,
|
||||
parent_note_id: parentNoteId,
|
||||
note_position: newNotePos,
|
||||
is_expanded: 0,
|
||||
date_modified: now,
|
||||
is_deleted: 0
|
||||
@@ -74,7 +74,7 @@ async function protectNoteRecursively(noteId, dataKey, protect, sourceId) {
|
||||
|
||||
await protectNote(note, dataKey, protect, sourceId);
|
||||
|
||||
const children = await sql.getFlattenedResults("SELECT note_id FROM notes_tree WHERE note_pid = ?", [noteId]);
|
||||
const children = await sql.getFlattenedResults("SELECT note_id FROM notes_tree WHERE parent_note_id = ?", [noteId]);
|
||||
|
||||
for (const childNoteId of children) {
|
||||
await protectNoteRecursively(childNoteId, dataKey, protect, sourceId);
|
||||
@@ -205,7 +205,7 @@ async function deleteNote(noteTreeId, sourceId) {
|
||||
await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]);
|
||||
await sync_table.addNoteSync(noteId, sourceId);
|
||||
|
||||
const children = await sql.getResults("SELECT note_tree_id FROM notes_tree WHERE note_pid = ? AND is_deleted = 0", [noteId]);
|
||||
const children = await sql.getResults("SELECT note_tree_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteId]);
|
||||
|
||||
for (const child of children) {
|
||||
await deleteNote(child.note_tree_id, sourceId);
|
||||
|
||||
@@ -37,8 +37,8 @@ const dbReady = new Promise((resolve, reject) => {
|
||||
await insert('notes_tree', {
|
||||
note_tree_id: utils.newNoteTreeId(),
|
||||
note_id: noteId,
|
||||
note_pid: 'root',
|
||||
note_pos: 1,
|
||||
parent_note_id: 'root',
|
||||
note_position: 1,
|
||||
is_deleted: 0,
|
||||
date_modified: now
|
||||
});
|
||||
|
||||
@@ -209,8 +209,8 @@ async function pushEntity(sync, syncContext) {
|
||||
}
|
||||
else if (sync.entity_name === 'notes_reordering') {
|
||||
entity = {
|
||||
note_pid: sync.entity_id,
|
||||
ordering: await sql.getMap('SELECT note_tree_id, note_pos FROM notes_tree WHERE note_pid = ?', [sync.entity_id])
|
||||
parent_note_id: sync.entity_id,
|
||||
ordering: await sql.getMap('SELECT note_tree_id, note_position FROM notes_tree WHERE parent_note_id = ?', [sync.entity_id])
|
||||
};
|
||||
}
|
||||
else if (sync.entity_name === 'options') {
|
||||
|
||||
@@ -53,10 +53,10 @@ async function updateNoteHistory(entity, sourceId) {
|
||||
async function updateNoteReordering(entity, sourceId) {
|
||||
await sql.doInTransaction(async () => {
|
||||
Object.keys(entity.ordering).forEach(async key => {
|
||||
await sql.execute("UPDATE notes_tree SET note_pos = ? WHERE note_tree_id = ?", [entity.ordering[key], key]);
|
||||
await sql.execute("UPDATE notes_tree SET note_position = ? WHERE note_tree_id = ?", [entity.ordering[key], key]);
|
||||
});
|
||||
|
||||
await sync_table.addNoteReorderingSync(entity.note_pid, sourceId);
|
||||
await sync_table.addNoteReorderingSync(entity.parent_note_id, sourceId);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user