2017-10-22 09:10:33 +08:00
"use strict" ;
2017-10-16 07:47:05 +08:00
const sql = require ( '../../services/sql' ) ;
2018-04-02 09:27:46 +08:00
const optionService = require ( '../../services/options' ) ;
const protectedSessionService = require ( '../../services/protected_session' ) ;
2018-04-17 08:40:18 +08:00
async function getNotes ( noteIds ) {
2018-05-31 08:28:10 +08:00
const notes = await sql . getManyRows ( `
2018-04-17 08:40:18 +08:00
SELECT noteId , title , isProtected , type , mime
2018-05-31 08:28:10 +08:00
FROM notes WHERE isDeleted = 0 AND noteId IN ( ? ? ? ) ` , noteIds);
2018-04-17 08:40:18 +08:00
2018-08-13 16:59:31 +08:00
const cssClassLabels = await sql . getManyRows ( `
SELECT noteId , value FROM attributes WHERE isDeleted = 0 AND type = 'label'
AND name = 'cssClass' AND noteId IN ( ? ? ? ) ` , noteIds);
for ( const label of cssClassLabels ) {
// FIXME: inefficient!
const note = notes . find ( note => note . noteId === label . noteId ) ;
if ( ! note ) {
continue ;
}
if ( note . cssClass ) {
note . cssClass += " " + label . value ;
}
else {
note . cssClass = label . value ;
}
}
2018-04-17 08:40:18 +08:00
protectedSessionService . decryptNotes ( notes ) ;
notes . forEach ( note => note . isProtected = ! ! note . isProtected ) ;
return notes ;
}
2018-04-17 11:13:33 +08:00
async function getRelations ( noteIds ) {
2018-05-31 08:28:10 +08:00
// we need to fetch both parentNoteId and noteId matches because we can have loaded child
// of which only some of the parents has been loaded.
2018-12-13 03:39:56 +08:00
// also now with note hoisting, it is possible to have the note displayed without its parent chain being loaded
2018-04-17 08:40:18 +08:00
2018-08-31 23:29:54 +08:00
const relations = await sql . getManyRows ( ` SELECT branchId, noteId AS 'childNoteId', parentNoteId, notePosition FROM branches WHERE isDeleted = 0
2018-05-31 08:28:10 +08:00
AND ( parentNoteId IN ( ? ? ? ) OR noteId IN ( ? ? ? ) ) ` , noteIds);
2018-08-31 23:29:54 +08:00
// although we're fetching relations for multiple notes, ordering will stay correct for single note as well - relations are being added into tree cache in the order they were returned
// cannot use ORDER BY because of usage of getManyRows which is not a single SQL query
relations . sort ( ( a , b ) => a . notePosition > b . notePosition ? 1 : - 1 ) ;
return relations ;
2018-04-17 08:40:18 +08:00
}
2017-10-15 11:31:44 +08:00
2018-04-01 23:05:09 +08:00
async function getTree ( ) {
2018-12-12 04:53:56 +08:00
const hoistedNoteId = await optionService . getOption ( 'hoistedNoteId' ) ;
2018-04-17 11:34:56 +08:00
// we fetch all branches of notes, even if that particular branch isn't visible
// this allows us to e.g. detect and properly display clones
2018-03-25 09:39:15 +08:00
const branches = await sql . getRows ( `
2018-04-17 04:26:47 +08:00
WITH RECURSIVE
tree ( branchId , noteId , isExpanded ) AS (
2018-12-12 04:53:56 +08:00
SELECT branchId , noteId , isExpanded FROM branches WHERE noteId = ?
2018-04-17 04:26:47 +08:00
UNION ALL
SELECT branches . branchId , branches . noteId , branches . isExpanded FROM branches
JOIN tree ON branches . parentNoteId = tree . noteId
WHERE tree . isExpanded = 1 AND branches . isDeleted = 0
)
2018-12-12 04:53:56 +08:00
SELECT branches . * FROM tree JOIN branches USING ( noteId ) WHERE branches . isDeleted = 0 ORDER BY branches . notePosition ` , [hoistedNoteId]);
2018-04-17 04:26:47 +08:00
2018-12-13 03:39:56 +08:00
// we also want root branch in there because all the paths start with root
branches . push ( await sql . getRow ( ` SELECT * FROM branches WHERE branchId = 'root' ` ) ) ;
2018-08-12 18:59:38 +08:00
const noteIds = Array . from ( new Set ( branches . map ( b => b . noteId ) ) ) ;
2018-03-25 08:41:27 +08:00
2018-04-17 08:40:18 +08:00
const notes = await getNotes ( noteIds ) ;
2018-03-25 08:41:27 +08:00
2018-04-17 11:13:33 +08:00
const relations = await getRelations ( noteIds ) ;
2018-04-17 04:26:47 +08:00
2018-04-17 08:40:18 +08:00
return {
2018-08-18 00:11:03 +08:00
startNotePath : ( await optionService . getOption ( 'startNotePath' ) ) || 'root' ,
2018-04-17 08:40:18 +08:00
branches ,
notes ,
2018-04-17 11:13:33 +08:00
relations
2018-04-17 08:40:18 +08:00
} ;
}
2018-04-17 04:26:47 +08:00
2018-04-17 08:40:18 +08:00
async function load ( req ) {
let noteIds = req . body . noteIds ;
const branchIds = req . body . branchIds ;
2018-04-17 04:26:47 +08:00
2018-04-17 08:40:18 +08:00
if ( branchIds && branchIds . length > 0 ) {
2018-05-31 11:18:56 +08:00
noteIds = ( await sql . getManyRows ( ` SELECT noteId FROM branches WHERE isDeleted = 0 AND branchId IN(???) ` , branchIds ) )
2018-05-31 08:28:10 +08:00
. map ( note => note . noteId ) ;
2018-04-17 04:26:47 +08:00
}
2018-02-14 11:30:33 +08:00
2018-05-31 08:28:10 +08:00
const branches = await sql . getManyRows ( ` SELECT * FROM branches WHERE isDeleted = 0 AND noteId IN (???) ` , noteIds ) ;
2018-04-17 08:40:18 +08:00
const notes = await getNotes ( noteIds ) ;
2018-04-17 11:13:33 +08:00
const relations = await getRelations ( noteIds ) ;
2018-04-17 08:40:18 +08:00
2018-03-31 00:57:22 +08:00
return {
2018-04-17 08:40:18 +08:00
branches ,
notes ,
2018-04-17 11:13:33 +08:00
relations
2018-03-31 00:57:22 +08:00
} ;
}
2017-10-15 11:31:44 +08:00
2018-03-31 00:57:22 +08:00
module . exports = {
2018-04-17 08:40:18 +08:00
getTree ,
load
2018-03-31 00:57:22 +08:00
} ;