trilium/src/routes/api/link_map.js

61 lines
1.5 KiB
JavaScript
Raw Normal View History

2019-06-04 04:55:59 +08:00
"use strict";
const sql = require('../../services/sql');
async function getLinks(noteIds, linkTypes) {
return (await sql.getManyRows(`
2019-06-04 04:55:59 +08:00
SELECT noteId, targetNoteId, type
FROM links
WHERE (noteId IN (???) OR targetNoteId IN (???))
AND isDeleted = 0
UNION
SELECT noteId, value, 'relation'
FROM attributes
WHERE (noteId IN (???) OR value IN (???))
AND type = 'relation'
AND isDeleted = 0
`, Array.from(noteIds))).filter(l => linkTypes.includes(l.type));
2019-06-04 04:55:59 +08:00
}
async function getLinkMap(req) {
const {noteId} = req.params;
2019-07-25 04:52:51 +08:00
const {linkTypes, maxNotes, maxDepth} = req.body;
2019-06-04 04:55:59 +08:00
let noteIds = new Set([noteId]);
let links = [];
2019-07-25 04:52:51 +08:00
let depth = 0;
2019-06-04 04:55:59 +08:00
while (true) {
2019-07-25 04:52:51 +08:00
links = await getLinks(noteIds, linkTypes);
if (depth === maxDepth) {
break;
}
const newNoteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId)));
2019-06-04 04:55:59 +08:00
2019-06-05 04:57:10 +08:00
if (newNoteIds.size === noteIds.size) {
2019-06-04 04:55:59 +08:00
// no new note discovered, no need to search any further
break;
}
if (newNoteIds.size > maxNotes) {
2019-06-04 04:55:59 +08:00
// to many notes to display
break;
}
noteIds = newNoteIds;
2019-07-25 04:52:51 +08:00
depth++;
2019-06-04 04:55:59 +08:00
}
// keep only links coming from and targetting some note in the noteIds set
links = links.filter(l => noteIds.has(l.noteId) && noteIds.has(l.targetNoteId));
return links;
}
module.exports = {
getLinkMap
};