diff --git a/docs/backend_api/ApiToken.html b/docs/backend_api/ApiToken.html index a0c9867ef..ad49fa01d 100644 --- a/docs/backend_api/ApiToken.html +++ b/docs/backend_api/ApiToken.html @@ -288,7 +288,7 @@
diff --git a/docs/backend_api/Attribute.html b/docs/backend_api/Attribute.html index 841556a23..e075fe18e 100644 --- a/docs/backend_api/Attribute.html +++ b/docs/backend_api/Attribute.html @@ -730,7 +730,7 @@
diff --git a/docs/backend_api/BackendScriptApi.html b/docs/backend_api/BackendScriptApi.html index fd7cc35f3..8bbf93376 100644 --- a/docs/backend_api/BackendScriptApi.html +++ b/docs/backend_api/BackendScriptApi.html @@ -3814,7 +3814,7 @@ transactional by default.
diff --git a/docs/backend_api/Branch.html b/docs/backend_api/Branch.html index 0fb9512b4..f7c46bc1f 100644 --- a/docs/backend_api/Branch.html +++ b/docs/backend_api/Branch.html @@ -511,7 +511,7 @@ Each note can have multiple (at least one) branches, meaning it can be placed in
diff --git a/docs/backend_api/Entity.html b/docs/backend_api/Entity.html index 5738a6d65..ad3cb3816 100644 --- a/docs/backend_api/Entity.html +++ b/docs/backend_api/Entity.html @@ -216,7 +216,7 @@
diff --git a/docs/backend_api/Link.html b/docs/backend_api/Link.html index 2247f9bfe..ba8ea1447 100644 --- a/docs/backend_api/Link.html +++ b/docs/backend_api/Link.html @@ -358,7 +358,7 @@ this is different concept than attribute/relation.
diff --git a/docs/backend_api/Note.html b/docs/backend_api/Note.html index 448585529..3d317b55d 100644 --- a/docs/backend_api/Note.html +++ b/docs/backend_api/Note.html @@ -446,7 +446,7 @@
- Finds notes with given attribute name and value. Only own attributes are considered, not inherited ones + Finds child notes with given attribute name and value. Only own attributes are considered, not inherited ones
@@ -1622,7 +1622,7 @@
Source:
@@ -1722,7 +1722,7 @@
Source:
@@ -1826,7 +1826,7 @@
Source:
@@ -2525,6 +2525,10 @@ +
+ Get list of links coming out of this note. +
+ @@ -2566,7 +2570,7 @@
Source:
@@ -2670,7 +2674,7 @@
Source:
@@ -2874,7 +2878,7 @@
Source:
@@ -3930,6 +3934,110 @@ + + + + + + + +
+ Get list of links targetting this note. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<Array.<Link>> + + +
+
+ + + + + + + + + + + + +

(async) getTargetRelations() → {Promise.<Array.<Attribute>>}

@@ -4258,7 +4366,7 @@
Source:
@@ -7189,7 +7297,7 @@ Cache is note instance scoped.
diff --git a/docs/backend_api/NoteRevision.html b/docs/backend_api/NoteRevision.html index 87fdf35ae..b3a85b60e 100644 --- a/docs/backend_api/NoteRevision.html +++ b/docs/backend_api/NoteRevision.html @@ -403,7 +403,7 @@
diff --git a/docs/backend_api/Option.html b/docs/backend_api/Option.html index 155eb46dc..5f576da93 100644 --- a/docs/backend_api/Option.html +++ b/docs/backend_api/Option.html @@ -311,7 +311,7 @@
diff --git a/docs/backend_api/RecentNote.html b/docs/backend_api/RecentNote.html index fa9e3e9d7..d6817f644 100644 --- a/docs/backend_api/RecentNote.html +++ b/docs/backend_api/RecentNote.html @@ -288,7 +288,7 @@
diff --git a/docs/backend_api/entities_api_token.js.html b/docs/backend_api/entities_api_token.js.html index a123fcacc..86960d717 100644 --- a/docs/backend_api/entities_api_token.js.html +++ b/docs/backend_api/entities_api_token.js.html @@ -75,7 +75,7 @@ module.exports = ApiToken;
diff --git a/docs/backend_api/entities_attribute.js.html b/docs/backend_api/entities_attribute.js.html index 10ed9ffbf..daac1dad6 100644 --- a/docs/backend_api/entities_attribute.js.html +++ b/docs/backend_api/entities_attribute.js.html @@ -151,7 +151,7 @@ module.exports = Attribute;
diff --git a/docs/backend_api/entities_branch.js.html b/docs/backend_api/entities_branch.js.html index da5323629..8cf66b4c0 100644 --- a/docs/backend_api/entities_branch.js.html +++ b/docs/backend_api/entities_branch.js.html @@ -105,7 +105,7 @@ module.exports = Branch;
diff --git a/docs/backend_api/entities_entity.js.html b/docs/backend_api/entities_entity.js.html index e02c82614..06edebc13 100644 --- a/docs/backend_api/entities_entity.js.html +++ b/docs/backend_api/entities_entity.js.html @@ -93,7 +93,7 @@ module.exports = Entity;
diff --git a/docs/backend_api/entities_link.js.html b/docs/backend_api/entities_link.js.html index 2912ef666..537f962bc 100644 --- a/docs/backend_api/entities_link.js.html +++ b/docs/backend_api/entities_link.js.html @@ -92,7 +92,7 @@ module.exports = Link;
diff --git a/docs/backend_api/entities_note.js.html b/docs/backend_api/entities_note.js.html index b2ff9f0de..1aa0d8f18 100644 --- a/docs/backend_api/entities_note.js.html +++ b/docs/backend_api/entities_note.js.html @@ -461,7 +461,7 @@ class Note extends Entity { } /** - * Finds notes with given attribute name and value. Only own attributes are considered, not inherited ones + * Finds child notes with given attribute name and value. Only own attributes are considered, not inherited ones * * @param {string} type - attribute type (label, relation, etc.) * @param {string} name - attribute name @@ -527,12 +527,23 @@ class Note extends Entity { } /** + * Get list of links coming out of this note. + * * @returns {Promise<Link[]>} */ async getLinks() { return await repository.getEntities("SELECT * FROM links WHERE noteId = ? AND isDeleted = 0", [this.noteId]); } + /** + * Get list of links targetting this note. + * + * @returns {Promise<Link[]>} + */ + async getTargetLinks() { + return await repository.getEntities("SELECT * FROM links WHERE targetNoteId = ? AND isDeleted = 0", [this.noteId]); + } + /** * Return all links from this note, including deleted ones. * @@ -640,7 +651,7 @@ module.exports = Note;
diff --git a/docs/backend_api/entities_note_revision.js.html b/docs/backend_api/entities_note_revision.js.html index 6b9c5de29..5a189c910 100644 --- a/docs/backend_api/entities_note_revision.js.html +++ b/docs/backend_api/entities_note_revision.js.html @@ -91,7 +91,7 @@ module.exports = NoteRevision;
diff --git a/docs/backend_api/entities_option.js.html b/docs/backend_api/entities_option.js.html index 06d3c5f02..f49b4fdec 100644 --- a/docs/backend_api/entities_option.js.html +++ b/docs/backend_api/entities_option.js.html @@ -78,7 +78,7 @@ module.exports = Option;
diff --git a/docs/backend_api/entities_recent_note.js.html b/docs/backend_api/entities_recent_note.js.html index 289d64f84..590e605f1 100644 --- a/docs/backend_api/entities_recent_note.js.html +++ b/docs/backend_api/entities_recent_note.js.html @@ -75,7 +75,7 @@ module.exports = RecentNote;
diff --git a/docs/backend_api/global.html b/docs/backend_api/global.html index 00a68a563..bc6e010d9 100644 --- a/docs/backend_api/global.html +++ b/docs/backend_api/global.html @@ -594,7 +594,7 @@
diff --git a/docs/backend_api/index.html b/docs/backend_api/index.html index 8197f413b..57a93ce40 100644 --- a/docs/backend_api/index.html +++ b/docs/backend_api/index.html @@ -56,7 +56,7 @@
diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html index c9ac8a9d3..c6668d50d 100644 --- a/docs/backend_api/services_backend_script_api.js.html +++ b/docs/backend_api/services_backend_script_api.js.html @@ -278,7 +278,7 @@ module.exports = BackendScriptApi;
diff --git a/docs/frontend_api/Branch.html b/docs/frontend_api/Branch.html index 8f2470bf9..ef8f37619 100644 --- a/docs/frontend_api/Branch.html +++ b/docs/frontend_api/Branch.html @@ -719,7 +719,7 @@
diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html index d198bb54d..406e40265 100644 --- a/docs/frontend_api/FrontendScriptApi.html +++ b/docs/frontend_api/FrontendScriptApi.html @@ -2846,7 +2846,7 @@ Internally this serializes the anonymous function into string and sends it to ba
diff --git a/docs/frontend_api/NoteFull.html b/docs/frontend_api/NoteFull.html index 7a49c7a15..e94c9b77e 100644 --- a/docs/frontend_api/NoteFull.html +++ b/docs/frontend_api/NoteFull.html @@ -279,7 +279,7 @@
diff --git a/docs/frontend_api/NoteShort.html b/docs/frontend_api/NoteShort.html index df0266233..f3df69275 100644 --- a/docs/frontend_api/NoteShort.html +++ b/docs/frontend_api/NoteShort.html @@ -1316,7 +1316,7 @@ Its notable omission is the note content.
diff --git a/docs/frontend_api/entities_branch.js.html b/docs/frontend_api/entities_branch.js.html index c9d5338a9..76f7c6cab 100644 --- a/docs/frontend_api/entities_branch.js.html +++ b/docs/frontend_api/entities_branch.js.html @@ -76,7 +76,7 @@ export default Branch;
diff --git a/docs/frontend_api/entities_note_full.js.html b/docs/frontend_api/entities_note_full.js.html index 93312d6c0..eaa172126 100644 --- a/docs/frontend_api/entities_note_full.js.html +++ b/docs/frontend_api/entities_note_full.js.html @@ -64,7 +64,7 @@ export default NoteFull;
diff --git a/docs/frontend_api/entities_note_short.js.html b/docs/frontend_api/entities_note_short.js.html index 9b56f110e..52416705e 100644 --- a/docs/frontend_api/entities_note_short.js.html +++ b/docs/frontend_api/entities_note_short.js.html @@ -128,7 +128,7 @@ export default NoteShort;
diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html index 901fbe515..5fb3fa812 100644 --- a/docs/frontend_api/global.html +++ b/docs/frontend_api/global.html @@ -339,7 +339,7 @@
diff --git a/docs/frontend_api/index.html b/docs/frontend_api/index.html index 9ba1bcdba..c576bce34 100644 --- a/docs/frontend_api/index.html +++ b/docs/frontend_api/index.html @@ -56,7 +56,7 @@
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html index 5c5517160..cd9c6f0fe 100644 --- a/docs/frontend_api/services_frontend_script_api.js.html +++ b/docs/frontend_api/services_frontend_script_api.js.html @@ -271,7 +271,7 @@ export default FrontendScriptApi;
diff --git a/src/entities/note.js b/src/entities/note.js index 4c9aaa6a5..d389ce93e 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -499,12 +499,23 @@ class Note extends Entity { } /** + * Get list of links coming out of this note. + * * @returns {Promise} */ async getLinks() { return await repository.getEntities("SELECT * FROM links WHERE noteId = ? AND isDeleted = 0", [this.noteId]); } + /** + * Get list of links targetting this note. + * + * @returns {Promise} + */ + async getTargetLinks() { + return await repository.getEntities("SELECT * FROM links WHERE targetNoteId = ? AND isDeleted = 0", [this.noteId]); + } + /** * Return all links from this note, including deleted ones. * diff --git a/src/services/app_info.js b/src/services/app_info.js index 76d2ab4a3..3b75b3d80 100644 --- a/src/services/app_info.js +++ b/src/services/app_info.js @@ -3,7 +3,7 @@ const build = require('./build'); const packageJson = require('../../package'); -const APP_DB_VERSION = 115; +const APP_DB_VERSION = 116; const SYNC_VERSION = 2; module.exports = { diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index 10ef57d99..a6045ef84 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -219,6 +219,65 @@ async function runAllChecks() { type == 'search'`, "Search note has children", errorList); + await fixEmptyRelationTargets(errorList); + + await runCheck(` + SELECT + attributeId + FROM + attributes + WHERE + type != 'label' + AND type != 'label-definition' + AND type != 'relation' + AND type != 'relation-definition'`, + "Attribute has invalid type", errorList); + + await runCheck(` + SELECT + attributeId + FROM + attributes + LEFT JOIN notes ON attributes.noteId = notes.noteId AND notes.isDeleted = 0 + WHERE + attributes.isDeleted = 0 + AND notes.noteId IS NULL`, + "Attribute reference to the owning note is broken", errorList); + + await runCheck(` + SELECT + attributeId + FROM + attributes + LEFT JOIN notes AS targetNote ON attributes.value = targetNote.noteId AND targetNote.isDeleted = 0 + WHERE + attributes.type = 'relation' + AND attributes.isDeleted = 0 + AND targetNote.noteId IS NULL`, + "Relation reference to the target note is broken", errorList); + + await runCheck(` + SELECT + linkId + FROM + links + WHERE + type != 'image' + AND type != 'hyper'`, + "Link type is invalid", errorList); + + await runCheck(` + SELECT + linkId + FROM + links + LEFT JOIN notes AS sourceNote ON sourceNote.noteId = links.noteId AND sourceNote.isDeleted = 0 + LEFT JOIN notes AS targetNote ON targetNote.noteId = links.noteId AND targetNote.isDeleted = 0 + WHERE + sourceNote.noteId IS NULL + OR targetNote.noteId IS NULL`, + "Link to source/target note link is broken", errorList); + await runSyncRowChecks("notes", "noteId", errorList); await runSyncRowChecks("note_revisions", "noteRevisionId", errorList); await runSyncRowChecks("branches", "branchId", errorList); @@ -233,8 +292,6 @@ async function runAllChecks() { await checkTreeCycles(errorList); } - await fixEmptyRelationTargets(errorList); - return errorList; } diff --git a/src/services/notes.js b/src/services/notes.js index 08eb35e1d..efbe27d6f 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -332,9 +332,19 @@ async function deleteNote(branch) { await attribute.save(); } - for (const attribute of await note.getTargetRelations()) { - attribute.isDeleted = true; - await attribute.save(); + for (const relation of await note.getTargetRelations()) { + relation.isDeleted = true; + await relation.save(); + } + + for (const link of await note.getLinks()) { + link.isDeleted = true; + await link.save(); + } + + for (const link of await note.getTargetLinks()) { + link.isDeleted = true; + await link.save(); } } }