2019-06-04 04:55:59 +08:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const sql = require('../../services/sql');
|
|
|
|
|
2019-06-10 20:33:59 +08:00
|
|
|
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
|
2019-06-10 20:33:59 +08:00
|
|
|
`, 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-06-10 20:33:59 +08:00
|
|
|
const {linkTypes, maxNotes} = req.body;
|
2019-06-04 04:55:59 +08:00
|
|
|
|
|
|
|
let noteIds = new Set([noteId]);
|
|
|
|
let links = [];
|
|
|
|
|
|
|
|
while (true) {
|
2019-06-10 20:33:59 +08:00
|
|
|
const newLinks = await getLinks(noteIds, linkTypes);
|
2019-06-04 04:55:59 +08:00
|
|
|
const newNoteIds = new Set(newLinks.map(l => l.noteId).concat(newLinks.map(l => l.targetNoteId)));
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-06-10 20:33:59 +08:00
|
|
|
if (newNoteIds.size > maxNotes) {
|
2019-06-04 04:55:59 +08:00
|
|
|
// to many notes to display
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
noteIds = newNoteIds;
|
|
|
|
links = newLinks;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
};
|