renaming note_tree to branch

This commit is contained in:
azivner 2018-03-24 21:39:15 -04:00
parent 511fb89af0
commit 4c472ce78b
45 changed files with 540 additions and 508 deletions

View File

@ -11,11 +11,11 @@
<collation id="5" parent="1" name="RTRIM"/> <collation id="5" parent="1" name="RTRIM"/>
<table id="6" parent="2" name="api_tokens"/> <table id="6" parent="2" name="api_tokens"/>
<table id="7" parent="2" name="attributes"/> <table id="7" parent="2" name="attributes"/>
<table id="8" parent="2" name="event_log"/> <table id="8" parent="2" name="branches"/>
<table id="9" parent="2" name="images"/> <table id="9" parent="2" name="event_log"/>
<table id="10" parent="2" name="note_images"/> <table id="10" parent="2" name="images"/>
<table id="11" parent="2" name="note_revisions"/> <table id="11" parent="2" name="note_images"/>
<table id="12" parent="2" name="note_tree"/> <table id="12" parent="2" name="note_revisions"/>
<table id="13" parent="2" name="notes"/> <table id="13" parent="2" name="notes"/>
<table id="14" parent="2" name="options"/> <table id="14" parent="2" name="options"/>
<table id="15" parent="2" name="recent_notes"/> <table id="15" parent="2" name="recent_notes"/>
@ -122,199 +122,202 @@ value</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_attributes_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_attributes_1</UnderlyingIndexName>
</key> </key>
<column id="38" parent="8" name="id"> <column id="38" parent="8" name="branchId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="39" parent="8" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="40" parent="8" name="parentNoteId">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="41" parent="8" name="notePosition">
<Position>4</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="42" parent="8" name="prefix">
<Position>5</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="43" parent="8" name="isExpanded">
<Position>6</Position>
<DataType>BOOLEAN|0s</DataType>
</column>
<column id="44" parent="8" name="isDeleted">
<Position>7</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="45" parent="8" name="dateModified">
<Position>8</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="46" parent="8" name="sqlite_autoindex_branches_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>branchId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<index id="47" parent="8" name="IDX_branches_noteId_parentNoteId">
<ColNames>noteId
parentNoteId</ColNames>
<ColumnCollations>
</ColumnCollations>
</index>
<index id="48" parent="8" name="IDX_branches_noteId">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="49" parent="8">
<ColNames>branchId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_branches_1</UnderlyingIndexName>
</key>
<column id="50" parent="9" name="id">
<Position>1</Position> <Position>1</Position>
<DataType>INTEGER|0s</DataType> <DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
<SequenceIdentity>1</SequenceIdentity> <SequenceIdentity>1</SequenceIdentity>
</column> </column>
<column id="39" parent="8" name="noteId"> <column id="51" parent="9" name="noteId">
<Position>2</Position> <Position>2</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
</column> </column>
<column id="40" parent="8" name="comment"> <column id="52" parent="9" name="comment">
<Position>3</Position> <Position>3</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
</column> </column>
<column id="41" parent="8" name="dateAdded"> <column id="53" parent="9" name="dateAdded">
<Position>4</Position> <Position>4</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<key id="42" parent="8"> <key id="54" parent="9">
<ColNames>id</ColNames> <ColNames>id</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
</key> </key>
<foreign-key id="43" parent="8"> <foreign-key id="55" parent="9">
<ColNames>noteId</ColNames> <ColNames>noteId</ColNames>
<RefTableName>notes</RefTableName> <RefTableName>notes</RefTableName>
<RefColNames>noteId</RefColNames> <RefColNames>noteId</RefColNames>
</foreign-key> </foreign-key>
<column id="44" parent="9" name="imageId"> <column id="56" parent="10" name="imageId">
<Position>1</Position> <Position>1</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="45" parent="9" name="format"> <column id="57" parent="10" name="format">
<Position>2</Position> <Position>2</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="46" parent="9" name="checksum"> <column id="58" parent="10" name="checksum">
<Position>3</Position> <Position>3</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="47" parent="9" name="name"> <column id="59" parent="10" name="name">
<Position>4</Position> <Position>4</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="48" parent="9" name="data"> <column id="60" parent="10" name="data">
<Position>5</Position> <Position>5</Position>
<DataType>BLOB|0s</DataType> <DataType>BLOB|0s</DataType>
</column> </column>
<column id="49" parent="9" name="isDeleted"> <column id="61" parent="10" name="isDeleted">
<Position>6</Position> <Position>6</Position>
<DataType>INT|0s</DataType> <DataType>INT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression> <DefaultExpression>0</DefaultExpression>
</column> </column>
<column id="50" parent="9" name="dateModified"> <column id="62" parent="10" name="dateModified">
<Position>7</Position> <Position>7</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="51" parent="9" name="dateCreated"> <column id="63" parent="10" name="dateCreated">
<Position>8</Position> <Position>8</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<index id="52" parent="9" name="sqlite_autoindex_images_1"> <index id="64" parent="10" name="sqlite_autoindex_images_1">
<NameSurrogate>1</NameSurrogate> <NameSurrogate>1</NameSurrogate>
<ColNames>imageId</ColNames> <ColNames>imageId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
<Unique>1</Unique> <Unique>1</Unique>
</index> </index>
<key id="53" parent="9"> <key id="65" parent="10">
<ColNames>imageId</ColNames> <ColNames>imageId</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_images_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_images_1</UnderlyingIndexName>
</key> </key>
<column id="54" parent="10" name="noteImageId"> <column id="66" parent="11" name="noteImageId">
<Position>1</Position> <Position>1</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="55" parent="10" name="noteId"> <column id="67" parent="11" name="noteId">
<Position>2</Position> <Position>2</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="56" parent="10" name="imageId"> <column id="68" parent="11" name="imageId">
<Position>3</Position> <Position>3</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="57" parent="10" name="isDeleted"> <column id="69" parent="11" name="isDeleted">
<Position>4</Position> <Position>4</Position>
<DataType>INT|0s</DataType> <DataType>INT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression> <DefaultExpression>0</DefaultExpression>
</column> </column>
<column id="58" parent="10" name="dateModified"> <column id="70" parent="11" name="dateModified">
<Position>5</Position> <Position>5</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="59" parent="10" name="dateCreated"> <column id="71" parent="11" name="dateCreated">
<Position>6</Position> <Position>6</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<index id="60" parent="10" name="sqlite_autoindex_note_images_1"> <index id="72" parent="11" name="sqlite_autoindex_note_images_1">
<NameSurrogate>1</NameSurrogate> <NameSurrogate>1</NameSurrogate>
<ColNames>noteImageId</ColNames> <ColNames>noteImageId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
<Unique>1</Unique> <Unique>1</Unique>
</index> </index>
<index id="61" parent="10" name="IDX_note_images_noteId_imageId"> <index id="73" parent="11" name="IDX_note_images_noteId_imageId">
<ColNames>noteId <ColNames>noteId
imageId</ColNames> imageId</ColNames>
<ColumnCollations> <ColumnCollations>
</ColumnCollations> </ColumnCollations>
</index> </index>
<index id="62" parent="10" name="IDX_note_images_noteId"> <index id="74" parent="11" name="IDX_note_images_noteId">
<ColNames>noteId</ColNames> <ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
</index> </index>
<index id="63" parent="10" name="IDX_note_images_imageId"> <index id="75" parent="11" name="IDX_note_images_imageId">
<ColNames>imageId</ColNames> <ColNames>imageId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
</index> </index>
<key id="64" parent="10"> <key id="76" parent="11">
<ColNames>noteImageId</ColNames> <ColNames>noteImageId</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_images_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_note_images_1</UnderlyingIndexName>
</key> </key>
<column id="65" parent="11" name="noteRevisionId"> <column id="77" parent="12" name="noteRevisionId">
<Position>1</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="66" parent="11" name="noteId">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="67" parent="11" name="title">
<Position>3</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="68" parent="11" name="content">
<Position>4</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="69" parent="11" name="isProtected">
<Position>5</Position>
<DataType>INT|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="70" parent="11" name="dateModifiedFrom">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="71" parent="11" name="dateModifiedTo">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="72" parent="11" name="sqlite_autoindex_note_revisions_1">
<NameSurrogate>1</NameSurrogate>
<ColNames>noteRevisionId</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<index id="73" parent="11" name="IDX_note_revisions_noteId">
<ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="74" parent="11" name="IDX_note_revisions_dateModifiedFrom">
<ColNames>dateModifiedFrom</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="75" parent="11" name="IDX_note_revisions_dateModifiedTo">
<ColNames>dateModifiedTo</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="76" parent="11">
<ColNames>noteRevisionId</ColNames>
<Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName>
</key>
<column id="77" parent="12" name="noteTreeId">
<Position>1</Position> <Position>1</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
@ -324,55 +327,52 @@ imageId</ColNames>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<column id="79" parent="12" name="parentNoteId"> <column id="79" parent="12" name="title">
<Position>3</Position> <Position>3</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column> </column>
<column id="80" parent="12" name="notePosition"> <column id="80" parent="12" name="content">
<Position>4</Position> <Position>4</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="81" parent="12" name="prefix">
<Position>5</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
</column> </column>
<column id="82" parent="12" name="isExpanded"> <column id="81" parent="12" name="isProtected">
<Position>6</Position> <Position>5</Position>
<DataType>BOOLEAN|0s</DataType> <DataType>INT|0s</DataType>
</column>
<column id="83" parent="12" name="isDeleted">
<Position>7</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression> <DefaultExpression>0</DefaultExpression>
</column> </column>
<column id="84" parent="12" name="dateModified"> <column id="82" parent="12" name="dateModifiedFrom">
<Position>8</Position> <Position>6</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
</column> </column>
<index id="85" parent="12" name="sqlite_autoindex_note_tree_1"> <column id="83" parent="12" name="dateModifiedTo">
<Position>7</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="84" parent="12" name="sqlite_autoindex_note_revisions_1">
<NameSurrogate>1</NameSurrogate> <NameSurrogate>1</NameSurrogate>
<ColNames>noteTreeId</ColNames> <ColNames>noteRevisionId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
<Unique>1</Unique> <Unique>1</Unique>
</index> </index>
<index id="86" parent="12" name="IDX_note_tree_noteId_parentNoteId"> <index id="85" parent="12" name="IDX_note_revisions_noteId">
<ColNames>noteId
parentNoteId</ColNames>
<ColumnCollations>
</ColumnCollations>
</index>
<index id="87" parent="12" name="IDX_note_tree_noteId">
<ColNames>noteId</ColNames> <ColNames>noteId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
</index> </index>
<index id="86" parent="12" name="IDX_note_revisions_dateModifiedFrom">
<ColNames>dateModifiedFrom</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<index id="87" parent="12" name="IDX_note_revisions_dateModifiedTo">
<ColNames>dateModifiedTo</ColNames>
<ColumnCollations></ColumnCollations>
</index>
<key id="88" parent="12"> <key id="88" parent="12">
<ColNames>noteTreeId</ColNames> <ColNames>noteRevisionId</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_note_tree_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName>
</key> </key>
<column id="89" parent="13" name="noteId"> <column id="89" parent="13" name="noteId">
<Position>1</Position> <Position>1</Position>
@ -466,7 +466,7 @@ parentNoteId</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName>
</key> </key>
<column id="107" parent="15" name="noteTreeId"> <column id="107" parent="15" name="branchId">
<Position>1</Position> <Position>1</Position>
<DataType>TEXT|0s</DataType> <DataType>TEXT|0s</DataType>
<NotNull>1</NotNull> <NotNull>1</NotNull>
@ -487,12 +487,12 @@ parentNoteId</ColNames>
</column> </column>
<index id="111" parent="15" name="sqlite_autoindex_recent_notes_1"> <index id="111" parent="15" name="sqlite_autoindex_recent_notes_1">
<NameSurrogate>1</NameSurrogate> <NameSurrogate>1</NameSurrogate>
<ColNames>noteTreeId</ColNames> <ColNames>branchId</ColNames>
<ColumnCollations></ColumnCollations> <ColumnCollations></ColumnCollations>
<Unique>1</Unique> <Unique>1</Unique>
</index> </index>
<key id="112" parent="15"> <key id="112" parent="15">
<ColNames>noteTreeId</ColNames> <ColNames>branchId</ColNames>
<Primary>1</Primary> <Primary>1</Primary>
<UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName> <UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName>
</key> </key>

View File

@ -0,0 +1,38 @@
CREATE TABLE "branches" (
`branchId` TEXT NOT NULL,
`noteId` TEXT NOT NULL,
`parentNoteId` TEXT NOT NULL,
`notePosition` INTEGER NOT NULL,
`prefix` TEXT,
`isExpanded` BOOLEAN,
`isDeleted` INTEGER NOT NULL DEFAULT 0,
`dateModified` TEXT NOT NULL,
PRIMARY KEY(`branchId`)
);
INSERT INTO branches (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified)
SELECT noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified FROM note_tree;
DROP TABLE note_tree;
CREATE INDEX `IDX_branches_noteId` ON `branches` (
`noteId`
);
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (
`noteId`,
`parentNoteId`
);
CREATE TABLE `recent_notes_mig` (
`branchId` TEXT NOT NULL PRIMARY KEY,
`notePath` TEXT NOT NULL,
`dateAccessed` TEXT NOT NULL,
isDeleted INT
);
INSERT INTO recent_notes_mig (branchId, notePath, dateAccessed, isDeleted)
SELECT noteTreeId, notePath, dateAccessed, isDeleted FROM recent_notes;
DROP TABLE recent_notes;
ALTER TABLE recent_notes_mig RENAME TO recent_notes;

18
src/entities/branch.js Normal file
View File

@ -0,0 +1,18 @@
"use strict";
const Entity = require('./entity');
class Branch extends Entity {
static get tableName() { return "branches"; }
static get primaryKeyName() { return "branchId"; }
async getNote() {
return this.repository.getEntity("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
}
async getParentNote() {
return this.repository.getEntity("SELECT * FROM branches WHERE isDeleted = 0 AND parentNoteId = ?", [this.parentNoteId]);
}
}
module.exports = Branch;

View File

@ -79,50 +79,50 @@ class Note extends Entity {
} }
async getTrees() { async getTrees() {
return this.repository.getEntities("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); return this.repository.getEntities("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
} }
async getChild(name) { async getChild(name) {
return this.repository.getEntity(` return this.repository.getEntity(`
SELECT notes.* SELECT notes.*
FROM note_tree FROM branches
JOIN notes USING(noteId) JOIN notes USING(noteId)
WHERE notes.isDeleted = 0 WHERE notes.isDeleted = 0
AND note_tree.isDeleted = 0 AND branches.isDeleted = 0
AND note_tree.parentNoteId = ? AND branches.parentNoteId = ?
AND notes.title = ?`, [this.noteId, name]); AND notes.title = ?`, [this.noteId, name]);
} }
async getChildren() { async getChildren() {
return this.repository.getEntities(` return this.repository.getEntities(`
SELECT notes.* SELECT notes.*
FROM note_tree FROM branches
JOIN notes USING(noteId) JOIN notes USING(noteId)
WHERE notes.isDeleted = 0 WHERE notes.isDeleted = 0
AND note_tree.isDeleted = 0 AND branches.isDeleted = 0
AND note_tree.parentNoteId = ? AND branches.parentNoteId = ?
ORDER BY note_tree.notePosition`, [this.noteId]); ORDER BY branches.notePosition`, [this.noteId]);
} }
async getParents() { async getParents() {
return this.repository.getEntities(` return this.repository.getEntities(`
SELECT parent_notes.* SELECT parent_notes.*
FROM FROM
note_tree AS child_tree branches AS child_tree
JOIN notes AS parent_notes ON parent_notes.noteId = child_tree.parentNoteId JOIN notes AS parent_notes ON parent_notes.noteId = child_tree.parentNoteId
WHERE child_tree.noteId = ? WHERE child_tree.noteId = ?
AND child_tree.isDeleted = 0 AND child_tree.isDeleted = 0
AND parent_notes.isDeleted = 0`, [this.noteId]); AND parent_notes.isDeleted = 0`, [this.noteId]);
} }
async getNoteTree() { async getBranch() {
return this.repository.getEntities(` return this.repository.getEntities(`
SELECT note_tree.* SELECT branches.*
FROM note_tree FROM branches
JOIN notes USING(noteId) JOIN notes USING(noteId)
WHERE notes.isDeleted = 0 WHERE notes.isDeleted = 0
AND note_tree.isDeleted = 0 AND branches.isDeleted = 0
AND note_tree.noteId = ?`, [this.noteId]); AND branches.noteId = ?`, [this.noteId]);
} }
beforeSaving() { beforeSaving() {

View File

@ -1,18 +0,0 @@
"use strict";
const Entity = require('./entity');
class NoteTree extends Entity {
static get tableName() { return "note_tree"; }
static get primaryKeyName() { return "noteTreeId"; }
async getNote() {
return this.repository.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
}
async getParentNote() {
return this.repository.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND parentNoteId = ?", [this.parentNoteId]);
}
}
module.exports = NoteTree;

View File

@ -24,7 +24,7 @@ function ScriptApi(startNote, currentNote) {
const $pluginButtons = $("#plugin-buttons"); const $pluginButtons = $("#plugin-buttons");
async function activateNote(notePath) { async function activateNote(notePath) {
await noteTree.activateNode(notePath); await treeService.activateNode(notePath);
} }
function addButtonToToolbar(buttonId, button) { function addButtonToToolbar(buttonId, button) {
@ -70,7 +70,7 @@ function ScriptApi(startNote, currentNote) {
currentNote: currentNote, currentNote: currentNote,
addButtonToToolbar, addButtonToToolbar,
activateNote, activateNote,
getInstanceName: noteTree.getInstanceName, getInstanceName: treeService.getInstanceName,
runOnServer runOnServer
} }
} }

View File

@ -11,19 +11,19 @@ const cloning = (function() {
return; return;
} }
await noteTree.reload(); await treeService.reload();
} }
// beware that first arg is noteId and second is noteTreeId! // beware that first arg is noteId and second is branchId!
async function cloneNoteAfter(noteId, afterNoteTreeId) { async function cloneNoteAfter(noteId, afterBranchId) {
const resp = await server.put('notes/' + noteId + '/clone-after/' + afterNoteTreeId); const resp = await server.put('notes/' + noteId + '/clone-after/' + afterBranchId);
if (!resp.success) { if (!resp.success) {
alert(resp.message); alert(resp.message);
return; return;
} }
await noteTree.reload(); await treeService.reload();
} }
return { return {

View File

@ -17,7 +17,7 @@ const contextMenu = (function() {
} }
else if (clipboardMode === 'copy') { else if (clipboardMode === 'copy') {
for (const noteId of clipboardIds) { for (const noteId of clipboardIds) {
await cloning.cloneNoteAfter(noteId, node.data.noteTreeId); await cloning.cloneNoteAfter(noteId, node.data.branchId);
} }
// copy will keep clipboardIds and clipboardMode so it's possible to paste into multiple places // copy will keep clipboardIds and clipboardMode so it's possible to paste into multiple places
@ -95,9 +95,9 @@ const contextMenu = (function() {
], ],
beforeOpen: (event, ui) => { beforeOpen: (event, ui) => {
const node = $.ui.fancytree.getNode(ui.target); const node = $.ui.fancytree.getNode(ui.target);
const nt = noteTree.getNoteTree(node.data.noteTreeId); const branch = treeService.getBranch(node.data.branchId);
const note = noteTree.getNote(node.data.noteId); const note = treeService.getNote(node.data.noteId);
const parentNote = noteTree.getNote(nt.parentNoteId); const parentNote = treeService.getNote(branch.parentNoteId);
// Modify menu entries depending on node status // Modify menu entries depending on node status
$tree.contextmenu("enableEntry", "pasteAfter", clipboardIds.length > 0 && (!parentNote || parentNote.type !== 'search')); $tree.contextmenu("enableEntry", "pasteAfter", clipboardIds.length > 0 && (!parentNote || parentNote.type !== 'search'));
@ -121,10 +121,10 @@ const contextMenu = (function() {
const parentNoteId = node.data.parentNoteId; const parentNoteId = node.data.parentNoteId;
const isProtected = treeUtils.getParentProtectedStatus(node); const isProtected = treeUtils.getParentProtectedStatus(node);
noteTree.createNote(node, parentNoteId, 'after', isProtected); treeService.createNote(node, parentNoteId, 'after', isProtected);
} }
else if (ui.cmd === "insertChildNote") { else if (ui.cmd === "insertChildNote") {
noteTree.createNote(node, node.data.noteId, 'into'); treeService.createNote(node, node.data.noteId, 'into');
} }
else if (ui.cmd === "editTreePrefix") { else if (ui.cmd === "editTreePrefix") {
editTreePrefix.showDialog(node); editTreePrefix.showDialog(node);
@ -136,10 +136,10 @@ const contextMenu = (function() {
protected_session.protectSubTree(node.data.noteId, false); protected_session.protectSubTree(node.data.noteId, false);
} }
else if (ui.cmd === "copy") { else if (ui.cmd === "copy") {
copy(noteTree.getSelectedNodes()); copy(treeService.getSelectedNodes());
} }
else if (ui.cmd === "cut") { else if (ui.cmd === "cut") {
cut(noteTree.getSelectedNodes()); cut(treeService.getSelectedNodes());
} }
else if (ui.cmd === "pasteAfter") { else if (ui.cmd === "pasteAfter") {
pasteAfter(node); pasteAfter(node);
@ -148,7 +148,7 @@ const contextMenu = (function() {
pasteInto(node); pasteInto(node);
} }
else if (ui.cmd === "delete") { else if (ui.cmd === "delete") {
treeChanges.deleteNodes(noteTree.getSelectedNodes(true)); treeChanges.deleteNodes(treeService.getSelectedNodes(true));
} }
else if (ui.cmd === "exportSubTree") { else if (ui.cmd === "exportSubTree") {
exportSubTree(node.data.noteId); exportSubTree(node.data.noteId);
@ -157,13 +157,13 @@ const contextMenu = (function() {
importSubTree(node.data.noteId); importSubTree(node.data.noteId);
} }
else if (ui.cmd === "collapseSubTree") { else if (ui.cmd === "collapseSubTree") {
noteTree.collapseTree(node); treeService.collapseTree(node);
} }
else if (ui.cmd === "forceNoteSync") { else if (ui.cmd === "forceNoteSync") {
forceNoteSync(node.data.noteId); forceNoteSync(node.data.noteId);
} }
else if (ui.cmd === "sortAlphabetically") { else if (ui.cmd === "sortAlphabetically") {
noteTree.sortAlphabetically(node.data.noteId); treeService.sortAlphabetically(node.data.noteId);
} }
else { else {
messaging.logError("Unknown command: " + ui.cmd); messaging.logError("Unknown command: " + ui.cmd);

View File

@ -43,13 +43,13 @@ const addLink = (function() {
$linkTitle.val(''); $linkTitle.val('');
function setDefaultLinkTitle(noteId) { function setDefaultLinkTitle(noteId) {
const noteTitle = noteTree.getNoteTitle(noteId); const noteTitle = treeService.getNoteTitle(noteId);
$linkTitle.val(noteTitle); $linkTitle.val(noteTitle);
} }
$autoComplete.autocomplete({ $autoComplete.autocomplete({
source: noteTree.getAutocompleteItems(), source: treeService.getAutocompleteItems(),
minLength: 0, minLength: 0,
change: () => { change: () => {
const val = $autoComplete.val(); const val = $autoComplete.val();

View File

@ -6,7 +6,7 @@ const editTreePrefix = (function() {
const $treePrefixInput = $("#tree-prefix-input"); const $treePrefixInput = $("#tree-prefix-input");
const $noteTitle = $('#tree-prefix-note-title'); const $noteTitle = $('#tree-prefix-note-title');
let noteTreeId; let branchId;
async function showDialog() { async function showDialog() {
glob.activeDialog = $dialog; glob.activeDialog = $dialog;
@ -16,14 +16,14 @@ const editTreePrefix = (function() {
width: 500 width: 500
}); });
const currentNode = noteTree.getCurrentNode(); const currentNode = treeService.getCurrentNode();
noteTreeId = currentNode.data.noteTreeId; branchId = currentNode.data.branchId;
const nt = noteTree.getNoteTree(noteTreeId); const nt = treeService.getBranch(branchId);
$treePrefixInput.val(nt.prefix).focus(); $treePrefixInput.val(nt.prefix).focus();
const noteTitle = noteTree.getNoteTitle(currentNode.data.noteId); const noteTitle = treeService.getNoteTitle(currentNode.data.noteId);
$noteTitle.html(noteTitle); $noteTitle.html(noteTitle);
} }
@ -31,9 +31,9 @@ const editTreePrefix = (function() {
$form.submit(() => { $form.submit(() => {
const prefix = $treePrefixInput.val(); const prefix = $treePrefixInput.val();
server.put('tree/' + noteTreeId + '/set-prefix', { server.put('tree/' + branchId + '/set-prefix', {
prefix: prefix prefix: prefix
}).then(() => noteTree.setPrefix(noteTreeId, prefix)); }).then(() => treeService.setPrefix(branchId, prefix));
$dialog.dialog("close"); $dialog.dialog("close");

View File

@ -17,7 +17,7 @@ const jumpToNote = (function() {
}); });
await $autoComplete.autocomplete({ await $autoComplete.autocomplete({
source: await stopWatch("building autocomplete", noteTree.getAutocompleteItems), source: await stopWatch("building autocomplete", treeService.getAutocompleteItems),
minLength: 0 minLength: 0
}); });
} }
@ -31,7 +31,7 @@ const jumpToNote = (function() {
const notePath = getSelectedNotePath(); const notePath = getSelectedNotePath();
if (notePath) { if (notePath) {
noteTree.activateNode(notePath); treeService.activateNode(notePath);
$dialog.dialog('close'); $dialog.dialog('close');
} }

View File

@ -14,11 +14,11 @@ const recentNotes = (function() {
list = result.map(r => r.notePath); list = result.map(r => r.notePath);
} }
function addRecentNote(noteTreeId, notePath) { function addRecentNote(branchId, notePath) {
setTimeout(async () => { setTimeout(async () => {
// we include the note into recent list only if the user stayed on the note at least 5 seconds // we include the note into recent list only if the user stayed on the note at least 5 seconds
if (notePath && notePath === noteTree.getCurrentNotePath()) { if (notePath && notePath === treeService.getCurrentNotePath()) {
const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath)); const result = await server.put('recent-notes/' + branchId + '/' + encodeURIComponent(notePath));
list = result.map(r => r.notePath); list = result.map(r => r.notePath);
} }
@ -38,14 +38,14 @@ const recentNotes = (function() {
$searchInput.val(''); $searchInput.val('');
// remove the current note // remove the current note
const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath()); const recNotes = list.filter(note => note !== treeService.getCurrentNotePath());
$searchInput.autocomplete({ $searchInput.autocomplete({
source: recNotes.map(notePath => { source: recNotes.map(notePath => {
let noteTitle; let noteTitle;
try { try {
noteTitle = noteTree.getNotePathTitle(notePath); noteTitle = treeService.getNotePathTitle(notePath);
} }
catch (e) { catch (e) {
noteTitle = "[error - can't find note title]"; noteTitle = "[error - can't find note title]";
@ -61,7 +61,7 @@ const recentNotes = (function() {
minLength: 0, minLength: 0,
autoFocus: true, autoFocus: true,
select: function (event, ui) { select: function (event, ui) {
noteTree.activateNode(ui.item.value); treeService.activateNode(ui.item.value);
$searchInput.autocomplete('destroy'); $searchInput.autocomplete('destroy');
$dialog.dialog('close'); $dialog.dialog('close');

View File

@ -49,7 +49,7 @@ const dragAndDropSetup = {
const nodeToMove = data.otherNode; const nodeToMove = data.otherNode;
nodeToMove.setSelected(true); nodeToMove.setSelected(true);
const selectedNodes = noteTree.getSelectedNodes(); const selectedNodes = treeService.getSelectedNodes();
if (data.hitMode === "before") { if (data.hitMode === "before") {
treeChanges.moveBeforeNode(selectedNodes, node); treeChanges.moveBeforeNode(selectedNodes, node);

View File

@ -28,5 +28,5 @@ $("#import-upload").change(async function() {
processData: false, // NEEDED, DON'T OMIT THIS processData: false, // NEEDED, DON'T OMIT THIS
}); });
await noteTree.reload(); await treeService.reload();
}); });

View File

@ -55,7 +55,7 @@ $(document).bind('keydown', 'ctrl+f', () => {
}); });
$(document).bind('keydown', "ctrl+shift+up", () => { $(document).bind('keydown', "ctrl+shift+up", () => {
const node = noteTree.getCurrentNode(); const node = treeService.getCurrentNode();
node.navigate($.ui.keyCode.UP, true); node.navigate($.ui.keyCode.UP, true);
$("#note-detail").focus(); $("#note-detail").focus();
@ -64,7 +64,7 @@ $(document).bind('keydown', "ctrl+shift+up", () => {
}); });
$(document).bind('keydown', "ctrl+shift+down", () => { $(document).bind('keydown', "ctrl+shift+down", () => {
const node = noteTree.getCurrentNode(); const node = treeService.getCurrentNode();
node.navigate($.ui.keyCode.DOWN, true); node.navigate($.ui.keyCode.DOWN, true);
$("#note-detail").focus(); $("#note-detail").focus();
@ -211,16 +211,16 @@ $(document).ready(() => {
if (isElectron()) { if (isElectron()) {
require('electron').ipcRenderer.on('create-day-sub-note', async function(event, parentNoteId) { require('electron').ipcRenderer.on('create-day-sub-note', async function(event, parentNoteId) {
// this might occur when day note had to be created // this might occur when day note had to be created
if (!noteTree.noteExists(parentNoteId)) { if (!treeService.noteExists(parentNoteId)) {
await noteTree.reload(); await treeService.reload();
} }
await noteTree.activateNode(parentNoteId); await treeService.activateNode(parentNoteId);
setTimeout(() => { setTimeout(() => {
const node = noteTree.getCurrentNode(); const node = treeService.getCurrentNode();
noteTree.createNote(node, node.data.noteId, 'into', node.data.isProtected); treeService.createNote(node, node.data.noteId, 'into', node.data.isProtected);
}, 500); }, 500);
}); });
} }
@ -244,7 +244,7 @@ $("#attachment-upload").change(async function() {
processData: false, // NEEDED, DON'T OMIT THIS processData: false, // NEEDED, DON'T OMIT THIS
}); });
await noteTree.reload(); await treeService.reload();
await noteTree.activateNode(resp.noteId); await treeService.activateNode(resp.noteId);
}); });

View File

@ -26,7 +26,7 @@ const link = (function() {
if (!noteTitle) { if (!noteTitle) {
const noteId = treeUtils.getNoteIdFromNotePath(notePath); const noteId = treeUtils.getNoteIdFromNotePath(notePath);
noteTitle = noteTree.getNoteTitle(noteId); noteTitle = treeService.getNoteTitle(noteId);
} }
const noteLink = $("<a>", { const noteLink = $("<a>", {
@ -60,7 +60,7 @@ const link = (function() {
notePath = getNotePathFromLink(address); notePath = getNotePathFromLink(address);
} }
noteTree.activateNode(notePath); treeService.activateNode(notePath);
// this is quite ugly hack, but it seems like we can't close the tooltip otherwise // this is quite ugly hack, but it seems like we can't close the tooltip otherwise
$("[role='tooltip']").remove(); $("[role='tooltip']").remove();

View File

@ -29,12 +29,12 @@ const messaging = (function() {
const syncData = message.data.filter(sync => sync.sourceId !== glob.sourceId); const syncData = message.data.filter(sync => sync.sourceId !== glob.sourceId);
if (syncData.some(sync => sync.entityName === 'note_tree') if (syncData.some(sync => sync.entityName === 'branches')
|| syncData.some(sync => sync.entityName === 'notes')) { || syncData.some(sync => sync.entityName === 'notes')) {
console.log(now(), "Reloading tree because of background changes"); console.log(now(), "Reloading tree because of background changes");
noteTree.reload(); treeService.reload();
} }
if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === noteEditor.getCurrentNoteId())) { if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === noteEditor.getCurrentNoteId())) {

View File

@ -110,7 +110,7 @@ const noteEditor = (function() {
note.detail.title = title; note.detail.title = title;
noteTree.setNoteTitle(note.detail.noteId, title); treeService.setNoteTitle(note.detail.noteId, title);
} }
async function saveNoteToServer(note) { async function saveNoteToServer(note) {
@ -264,7 +264,7 @@ const noteEditor = (function() {
noteChangeDisabled = false; noteChangeDisabled = false;
setNoteBackgroundIfProtected(currentNote); setNoteBackgroundIfProtected(currentNote);
noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId); treeService.setBranchBackgroundBasedOnProtectedStatus(noteId);
// after loading new note make sure editor is scrolled to the top // after loading new note make sure editor is scrolled to the top
$noteDetailWrapper.scrollTop(0); $noteDetailWrapper.scrollTop(0);
@ -366,7 +366,7 @@ const noteEditor = (function() {
const title = $noteTitle.val(); const title = $noteTitle.val();
noteTree.setNoteTitle(getCurrentNoteId(), title); treeService.setNoteTitle(getCurrentNoteId(), title);
}); });
// so that tab jumps from note title (which has tabindex 1) // so that tab jumps from note title (which has tabindex 1)

View File

@ -1,10 +1,10 @@
"use strict"; "use strict";
class TreeCache { class TreeCache {
constructor(noteRows, noteTreeRows) { constructor(noteRows, branchRows) {
this.parents = []; this.parents = [];
this.children = []; this.children = [];
this.childParentToNoteTree = {}; this.childParentToBranch = {};
this.notes = {}; this.notes = {};
for (const noteRow of noteRows) { for (const noteRow of noteRows) {
@ -13,12 +13,12 @@ class TreeCache {
this.notes[note.noteId] = note; this.notes[note.noteId] = note;
} }
this.noteTree = {}; this.branches = {};
for (const noteTreeRow of noteTreeRows) { for (const branchRow of branchRows) {
const nt = new NoteTree(this, noteTreeRow); const branch = new Branch(this, branchRow);
this.noteTree[nt.noteTreeId] = nt; this.branches[branch.branchId] = branch;
this.addNoteTree(nt); this.addBranch(branch);
} }
} }
@ -26,22 +26,24 @@ class TreeCache {
return this.notes[noteId]; return this.notes[noteId];
} }
addNoteTree(nt) { addBranch(branch) {
this.parents[nt.noteId] = this.parents[nt.noteId] || []; this.parents[branch.noteId] = this.parents[branch.noteId] || [];
this.parents[nt.noteId].push(this.notes[nt.parentNoteId]); this.parents[branch.noteId].push(this.notes[branch.parentNoteId]);
this.children[nt.parentNoteId] = this.children[nt.parentNoteId] || []; this.children[branch.parentNoteId] = this.children[branch.parentNoteId] || [];
this.children[nt.parentNoteId].push(this.notes[nt.noteId]); this.children[branch.parentNoteId].push(this.notes[branch.noteId]);
this.childParentToNoteTree[nt.noteId + '-' + nt.parentNoteId] = nt; this.childParentToBranch[branch.noteId + '-' + branch.parentNoteId] = branch;
} }
add(note, nt) { add(note, branch) {
this.notes[note.noteId] = note; this.notes[note.noteId] = note;
this.addBranch(branch);
} }
async getNoteTree(childNoteId, parentNoteId) { async getBranch(childNoteId, parentNoteId) {
return this.childParentToNoteTree[childNoteId + '-' + parentNoteId]; return this.childParentToBranch[childNoteId + '-' + parentNoteId];
} }
} }
@ -56,24 +58,24 @@ class NoteShort {
this.hideInAutocomplete = row.hideInAutocomplete; this.hideInAutocomplete = row.hideInAutocomplete;
} }
async getNoteTrees() { async getBranches() {
const noteTrees = []; const branches = [];
for (const parent of this.treeCache.parents[this.noteId]) { for (const parent of this.treeCache.parents[this.noteId]) {
noteTrees.push(await this.treeCache.getNoteTree(this.noteId, p.noteId)); branches.push(await this.treeCache.getBranch(this.noteId, p.noteId));
} }
return noteTrees; return branches;
} }
async getChildNoteTrees() { async getChildBranches() {
const noteTrees = []; const branches = [];
for (const child of this.treeCache.children[this.noteId]) { for (const child of this.treeCache.children[this.noteId]) {
noteTrees.push(await this.treeCache.getNoteTree(child.noteId, this.noteId)); branches.push(await this.treeCache.getBranch(child.noteId, this.noteId));
} }
return noteTrees; return branches;
} }
async getParentNotes() { async getParentNotes() {
@ -89,10 +91,10 @@ class NoteShort {
} }
} }
class NoteTree { class Branch {
constructor(treeCache, row) { constructor(treeCache, row) {
this.treeCache = treeCache; this.treeCache = treeCache;
this.noteTreeId = row.noteTreeId; this.branchId = row.branchId;
this.noteId = row.noteId; this.noteId = row.noteId;
this.note = null; this.note = null;
this.parentNoteId = row.parentNoteId; this.parentNoteId = row.parentNoteId;
@ -106,11 +108,11 @@ class NoteTree {
} }
get toString() { get toString() {
return `NoteTree(noteTreeId=${this.noteTreeId})`; return `Branch(branchId=${this.branchId})`;
} }
} }
const noteTree = (function() { const treeService = (function() {
let treeCache; let treeCache;
const $tree = $("#tree"); const $tree = $("#tree");
@ -126,8 +128,8 @@ const noteTree = (function() {
/** @type {Object.<string, NoteShort>} */ /** @type {Object.<string, NoteShort>} */
let noteMap = {}; let noteMap = {};
/** @type {Object.<string, NoteTree>} */ /** @type {Object.<string, Branch>} */
let noteTreeMap = {}; let branchMap = {};
function getNote(noteId) { function getNote(noteId) {
const note = noteMap[noteId]; const note = noteMap[noteId];
@ -139,7 +141,7 @@ const noteTree = (function() {
return note; return note;
} }
function getNoteTreeId(parentNoteId, childNoteId) { function getBranchId(parentNoteId, childNoteId) {
assertArguments(parentNoteId, childNoteId); assertArguments(parentNoteId, childNoteId);
@ -148,7 +150,7 @@ const noteTree = (function() {
// this can return undefined and client code should deal with it somehow // this can return undefined and client code should deal with it somehow
return parentChildToNoteTreeId[key]; return parentChildToBranchId[key];
} }
function getNoteTitle(noteId, parentNoteId = null) { function getNoteTitle(noteId, parentNoteId = null) {
@ -157,13 +159,13 @@ const noteTree = (function() {
let title = treeCache.getNote(noteId).title; let title = treeCache.getNote(noteId).title;
if (parentNoteId !== null) { if (parentNoteId !== null) {
const noteTreeId = getNoteTreeId(parentNoteId, noteId); const branchId = getBranchId(parentNoteId, noteId);
if (noteTreeId) { if (branchId) {
const noteTree = noteTreeMap[noteTreeId]; const branch = branchMap[branchId];
if (noteTree.prefix) { if (branch.prefix) {
title = noteTree.prefix + ' - ' + title; title = branch.prefix + ' - ' + title;
} }
} }
} }
@ -182,12 +184,12 @@ const noteTree = (function() {
return treeUtils.getNotePath(node); return treeUtils.getNotePath(node);
} }
function getNodesByNoteTreeId(noteTreeId) { function getNodesByBranchId(branchId) {
assertArguments(noteTreeId); assertArguments(branchId);
const noteTree = noteTreeMap[noteTreeId]; const branch = branchMap[branchId];
return getNodesByNoteId(noteTree.noteId).filter(node => node.data.noteTreeId === noteTreeId); return getNodesByNoteId(branch.noteId).filter(node => node.data.branchId === branchId);
} }
function getNodesByNoteId(noteId) { function getNodesByNoteId(noteId) {
@ -197,19 +199,19 @@ const noteTree = (function() {
return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null
} }
function setPrefix(noteTreeId, prefix) { function setPrefix(branchId, prefix) {
assertArguments(noteTreeId); assertArguments(branchId);
noteTreeMap[noteTreeId].prefix = prefix; branchMap[branchId].prefix = prefix;
getNodesByNoteTreeId(noteTreeId).map(node => setNodeTitleWithPrefix(node)); getNodesByBranchId(branchId).map(node => setNodeTitleWithPrefix(node));
} }
function setNodeTitleWithPrefix(node) { function setNodeTitleWithPrefix(node) {
const noteTitle = getNoteTitle(node.data.noteId); const noteTitle = getNoteTitle(node.data.noteId);
const noteTree = noteTreeMap[node.data.noteTreeId]; const branch = branchMap[node.data.branchId];
const prefix = noteTree.prefix; const prefix = branch.prefix;
const title = (prefix ? (prefix + " - ") : "") + noteTitle; const title = (prefix ? (prefix + " - ") : "") + noteTitle;
@ -222,32 +224,24 @@ const noteTree = (function() {
const parentNote = noteMap[parentNoteId]; const parentNote = noteMap[parentNoteId];
const childNote = noteMap[childNoteId]; const childNote = noteMap[childNoteId];
parentNote.children = parentNote.children.filter(note => note.noteId !== childNoteId); // FIXME
childNote.parents = childNote.parents.filter(note => note.noteId !== parentNoteId);
childNote.noteTree = childNote.noteTree.filter(nt => nt.parentNoteId !== parentNoteId);
} }
function setParentChildRelation(noteTreeId, parentNoteId, childNoteId) { function setParentChildRelation(branchId, parentNoteId, childNoteId) {
assertArguments(noteTreeId, parentNoteId, childNoteId); assertArguments(branchId, parentNoteId, childNoteId);
const parentNote = noteMap[parentNoteId]; const parentNote = noteMap[parentNoteId];
const childNote = noteMap[childNoteId]; const childNote = noteMap[childNoteId];
// FIXME: assert // FIXME: assert
childNote.parents.push(parentNote);
parentNote.children.push(childNote);
const noteTree = noteTreeMap[noteTreeId];
childNote.noteTree.push(noteTree);
} }
async function prepareNoteTree(noteRows, noteTreeRows) { async function prepareBranch(noteRows, branchRows) {
assertArguments(noteRows); assertArguments(noteRows);
treeCache = new TreeCache(noteRows, noteTreeRows); treeCache = new TreeCache(noteRows, branchRows);
return await prepareNoteTreeInner(treeCache.getNote('root')); return await prepareBranchInner(treeCache.getNote('root'));
} }
async function getExtraClasses(note) { async function getExtraClasses(note) {
@ -268,31 +262,31 @@ const noteTree = (function() {
return extraClasses.join(" "); return extraClasses.join(" ");
} }
async function prepareNoteTreeInner(parentNote) { async function prepareBranchInner(parentNote) {
assertArguments(parentNote); assertArguments(parentNote);
const childrenNoteTrees = await parentNote.getChildNoteTrees(); const childBranches = await parentNote.getChildBranches();
if (!childrenNoteTrees) { if (!childBranches) {
messaging.logError(`No children for ${parentNote}. This shouldn't happen.`); messaging.logError(`No children for ${parentNote}. This shouldn't happen.`);
return; return;
} }
const noteList = []; const noteList = [];
for (const noteTree of childrenNoteTrees) { for (const branch of childBranches) {
const note = await noteTree.getNote(); const note = await branch.getNote();
const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + note.title; const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title;
const node = { const node = {
noteId: note.noteId, noteId: note.noteId,
parentNoteId: noteTree.parentNoteId, parentNoteId: branch.parentNoteId,
noteTreeId: noteTree.noteTreeId, branchId: branch.branchId,
isProtected: note.isProtected, isProtected: note.isProtected,
title: escapeHtml(title), title: escapeHtml(title),
extraClasses: getExtraClasses(note), extraClasses: getExtraClasses(note),
refKey: note.noteId, refKey: note.noteId,
expanded: note.type !== 'search' && noteTree.isExpanded expanded: note.type !== 'search' && branch.isExpanded
}; };
const hasChildren = (await note.getChildNotes()).length > 0; const hasChildren = (await note.getChildNotes()).length > 0;
@ -301,7 +295,7 @@ const noteTree = (function() {
node.folder = true; node.folder = true;
if (node.expanded && note.type !== 'search') { if (node.expanded && note.type !== 'search') {
node.children = await prepareNoteTreeInner(note); node.children = await prepareBranchInner(note);
} }
else { else {
node.lazy = true; node.lazy = true;
@ -485,23 +479,23 @@ const noteTree = (function() {
return path.reverse().join('/'); return path.reverse().join('/');
} }
async function setExpandedToServer(noteTreeId, isExpanded) { async function setExpandedToServer(branchId, isExpanded) {
assertArguments(noteTreeId); assertArguments(branchId);
const expandedNum = isExpanded ? 1 : 0; const expandedNum = isExpanded ? 1 : 0;
await server.put('tree/' + noteTreeId + '/expanded/' + expandedNum); await server.put('tree/' + branchId + '/expanded/' + expandedNum);
} }
function setCurrentNotePathToHash(node) { function setCurrentNotePathToHash(node) {
assertArguments(node); assertArguments(node);
const currentNotePath = treeUtils.getNotePath(node); const currentNotePath = treeUtils.getNotePath(node);
const currentNoteTreeId = node.data.noteTreeId; const currentBranchId = node.data.branchId;
document.location.hash = currentNotePath; document.location.hash = currentNotePath;
recentNotes.addRecentNote(currentNoteTreeId, currentNotePath); recentNotes.addRecentNote(currentBranchId, currentNotePath);
} }
function getSelectedNodes(stopOnParents = false) { function getSelectedNodes(stopOnParents = false) {
@ -520,8 +514,8 @@ const noteTree = (function() {
} }
} }
function initFancyTree(noteTree) { function initFancyTree(branch) {
assertArguments(noteTree); assertArguments(branch);
const keybindings = { const keybindings = {
"del": node => { "del": node => {
@ -656,7 +650,7 @@ const noteTree = (function() {
autoScroll: true, autoScroll: true,
keyboard: false, // we takover keyboard handling in the hotkeys plugin keyboard: false, // we takover keyboard handling in the hotkeys plugin
extensions: ["hotkeys", "filter", "dnd", "clones"], extensions: ["hotkeys", "filter", "dnd", "clones"],
source: noteTree, source: branch,
scrollParent: $("#tree"), scrollParent: $("#tree"),
click: (event, data) => { click: (event, data) => {
const targetType = data.targetType; const targetType = data.targetType;
@ -686,10 +680,10 @@ const noteTree = (function() {
showParentList(node.noteId, data.node); showParentList(node.noteId, data.node);
}, },
expand: (event, data) => { expand: (event, data) => {
setExpandedToServer(data.node.data.noteTreeId, true); setExpandedToServer(data.node.data.branchId, true);
}, },
collapse: (event, data) => { collapse: (event, data) => {
setExpandedToServer(data.node.data.noteTreeId, false); setExpandedToServer(data.node.data.branchId, false);
}, },
init: (event, data) => { init: (event, data) => {
const noteId = treeUtils.getNoteIdFromNotePath(startNotePath); const noteId = treeUtils.getNoteIdFromNotePath(startNotePath);
@ -731,7 +725,7 @@ const noteTree = (function() {
data.result = loadSearchNote(noteId); data.result = loadSearchNote(noteId);
} }
else { else {
data.result = await prepareNoteTreeInner(note); data.result = await prepareBranchInner(note);
} }
}, },
clones: { clones: {
@ -750,20 +744,20 @@ const noteTree = (function() {
const noteIds = await server.get('search/' + encodeURIComponent(json.searchString)); const noteIds = await server.get('search/' + encodeURIComponent(json.searchString));
for (const noteId of noteIds) { for (const noteId of noteIds) {
const noteTreeId = "virt" + randomString(10); const branchId = "virt" + randomString(10);
noteTreeMap[noteTreeId] = { branchMap[branchId] = {
noteTreeId: noteTreeId, branchId: branchId,
noteId: noteId, noteId: noteId,
parentNoteId: searchNoteId, parentNoteId: searchNoteId,
prefix: '', prefix: '',
virtual: true virtual: true
}; };
setParentChildRelation(noteTreeId, searchNoteId, noteId); setParentChildRelation(branchId, searchNoteId, noteId);
} }
return await prepareNoteTreeInner(searchNoteId); return await prepareBranchInner(searchNoteId);
} }
function getTree() { function getTree() {
@ -790,10 +784,10 @@ const noteTree = (function() {
startNotePath = getNotePathFromAddress(); startNotePath = getNotePathFromAddress();
} }
return await prepareNoteTree(resp.notes, resp.noteTree); return await prepareBranch(resp.notes, resp.branches);
} }
$(() => loadTree().then(noteTree => initFancyTree(noteTree))); $(() => loadTree().then(branch => initFancyTree(branch)));
function collapseTree(node = null) { function collapseTree(node = null) {
if (!node) { if (!node) {
@ -817,14 +811,14 @@ const noteTree = (function() {
} }
} }
function setNoteTreeBackgroundBasedOnProtectedStatus(noteId) { function setBranchBackgroundBasedOnProtectedStatus(noteId) {
getNodesByNoteId(noteId).map(node => node.toggleClass("protected", !!node.data.isProtected)); getNodesByNoteId(noteId).map(node => node.toggleClass("protected", !!node.data.isProtected));
} }
function setProtected(noteId, isProtected) { function setProtected(noteId, isProtected) {
getNodesByNoteId(noteId).map(node => node.data.isProtected = isProtected); getNodesByNoteId(noteId).map(node => node.data.isProtected = isProtected);
setNoteTreeBackgroundBasedOnProtectedStatus(noteId); setBranchBackgroundBasedOnProtectedStatus(noteId);
} }
function getAutocompleteItems(parentNoteId, notePath, titlePath) { function getAutocompleteItems(parentNoteId, notePath, titlePath) {
@ -900,13 +894,13 @@ const noteTree = (function() {
const result = await server.post('notes/' + parentNoteId + '/children', { const result = await server.post('notes/' + parentNoteId + '/children', {
title: newNoteName, title: newNoteName,
target: target, target: target,
target_noteTreeId: node.data.noteTreeId, target_branchId: node.data.branchId,
isProtected: isProtected isProtected: isProtected
}); });
setParentChildRelation(result.noteTreeId, parentNoteId, result.noteId); setParentChildRelation(result.branchId, parentNoteId, result.noteId);
noteTreeMap[result.noteTreeId] = result; branchMap[result.branchId] = result;
noteMap[result.noteId] = { noteMap[result.noteId] = {
noteId: result.noteId, noteId: result.noteId,
@ -923,7 +917,7 @@ const noteTree = (function() {
noteId: result.noteId, noteId: result.noteId,
parentNoteId: parentNoteId, parentNoteId: parentNoteId,
refKey: result.noteId, refKey: result.noteId,
noteTreeId: result.noteTreeId, branchId: result.branchId,
isProtected: isProtected, isProtected: isProtected,
extraClasses: getExtraClasses(result.note) extraClasses: getExtraClasses(result.note)
}; };
@ -967,8 +961,8 @@ const noteTree = (function() {
return instanceName; return instanceName;
} }
function getNoteTree(noteTreeId) { function getBranch(branchId) {
return noteTreeMap[noteTreeId]; return branchMap[branchId];
} }
$(document).bind('keydown', 'ctrl+o', e => { $(document).bind('keydown', 'ctrl+o', e => {
@ -1031,7 +1025,7 @@ const noteTree = (function() {
reload, reload,
collapseTree, collapseTree,
scrollToCurrentNote, scrollToCurrentNote,
setNoteTreeBackgroundBasedOnProtectedStatus, setBranchBackgroundBasedOnProtectedStatus,
setProtected, setProtected,
getCurrentNode, getCurrentNode,
expandToNote, expandToNote,
@ -1051,7 +1045,7 @@ const noteTree = (function() {
sortAlphabetically, sortAlphabetically,
noteExists, noteExists,
getInstanceName, getInstanceName,
getNoteTree, getBranch,
getNote getNote
}; };
})(); })();

View File

@ -91,7 +91,7 @@ const noteType = (function() {
await noteEditor.reload(); await noteEditor.reload();
// for the note icon to be updated in the tree // for the note icon to be updated in the tree
await noteTree.reload(); await treeService.reload();
self.updateExecuteScriptButtonVisibility(); self.updateExecuteScriptButtonVisibility();
} }

View File

@ -27,7 +27,7 @@ const protected_session = (function() {
if (requireProtectedSession && !isProtectedSessionAvailable()) { if (requireProtectedSession && !isProtectedSessionAvailable()) {
protectedSessionDeferred = dfd; protectedSessionDeferred = dfd;
if (noteTree.getCurrentNode().data.isProtected) { if (treeService.getCurrentNode().data.isProtected) {
$noteDetailWrapper.hide(); $noteDetailWrapper.hide();
} }
@ -37,7 +37,7 @@ const protected_session = (function() {
open: () => { open: () => {
if (!modal) { if (!modal) {
// dialog steals focus for itself, which is not what we want for non-modal (viewing) // dialog steals focus for itself, which is not what we want for non-modal (viewing)
noteTree.getCurrentNode().setFocus(); treeService.getCurrentNode().setFocus();
} }
} }
}); });
@ -65,7 +65,7 @@ const protected_session = (function() {
$dialog.dialog("close"); $dialog.dialog("close");
noteEditor.reload(); noteEditor.reload();
noteTree.reload(); treeService.reload();
if (protectedSessionDeferred !== null) { if (protectedSessionDeferred !== null) {
ensureDialogIsClosed($dialog, $password); ensureDialogIsClosed($dialog, $password);
@ -121,7 +121,7 @@ const protected_session = (function() {
await noteEditor.saveNoteToServer(note); await noteEditor.saveNoteToServer(note);
noteTree.setProtected(note.detail.noteId, note.detail.isProtected); treeService.setProtected(note.detail.noteId, note.detail.isProtected);
noteEditor.setNoteBackgroundIfProtected(note); noteEditor.setNoteBackgroundIfProtected(note);
} }
@ -137,7 +137,7 @@ const protected_session = (function() {
await noteEditor.saveNoteToServer(note); await noteEditor.saveNoteToServer(note);
noteTree.setProtected(note.detail.noteId, note.detail.isProtected); treeService.setProtected(note.detail.noteId, note.detail.isProtected);
noteEditor.setNoteBackgroundIfProtected(note); noteEditor.setNoteBackgroundIfProtected(note);
} }
@ -155,7 +155,7 @@ const protected_session = (function() {
showMessage("Request to un/protect sub tree has finished successfully"); showMessage("Request to un/protect sub tree has finished successfully");
noteTree.reload(); treeService.reload();
noteEditor.reload(); noteEditor.reload();
} }

View File

@ -35,7 +35,7 @@ async function doSearch() {
const noteIds = await server.get('search/' + encodeURIComponent(searchText)); const noteIds = await server.get('search/' + encodeURIComponent(searchText));
for (const noteId of noteIds) { for (const noteId of noteIds) {
await noteTree.expandToNote(noteId, {noAnimation: true, noEvents: true}); await treeService.expandToNote(noteId, {noAnimation: true, noEvents: true});
} }
// Pass a string to perform case insensitive matching // Pass a string to perform case insensitive matching
@ -45,9 +45,9 @@ async function doSearch() {
async function saveSearch() { async function saveSearch() {
const {noteId} = await server.post('search/' + encodeURIComponent($searchInput.val())); const {noteId} = await server.post('search/' + encodeURIComponent($searchInput.val()));
await noteTree.reload(); await treeService.reload();
await noteTree.activateNode(noteId); await treeService.activateNode(noteId);
} }
$searchInput.keyup(e => { $searchInput.keyup(e => {

View File

@ -3,7 +3,7 @@
const treeChanges = (function() { const treeChanges = (function() {
async function moveBeforeNode(nodesToMove, beforeNode) { async function moveBeforeNode(nodesToMove, beforeNode) {
for (const nodeToMove of nodesToMove) { for (const nodeToMove of nodesToMove) {
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-before/' + beforeNode.data.noteTreeId); const resp = await server.put('tree/' + nodeToMove.data.branchId + '/move-before/' + beforeNode.data.branchId);
if (!resp.success) { if (!resp.success) {
alert(resp.message); alert(resp.message);
@ -18,7 +18,7 @@ const treeChanges = (function() {
nodesToMove.reverse(); // need to reverse to keep the note order nodesToMove.reverse(); // need to reverse to keep the note order
for (const nodeToMove of nodesToMove) { for (const nodeToMove of nodesToMove) {
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-after/' + afterNode.data.noteTreeId); const resp = await server.put('tree/' + nodeToMove.data.branchId + '/move-after/' + afterNode.data.branchId);
if (!resp.success) { if (!resp.success) {
alert(resp.message); alert(resp.message);
@ -31,7 +31,7 @@ const treeChanges = (function() {
async function moveToNode(nodesToMove, toNode) { async function moveToNode(nodesToMove, toNode) {
for (const nodeToMove of nodesToMove) { for (const nodeToMove of nodesToMove) {
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-to/' + toNode.data.noteId); const resp = await server.put('tree/' + nodeToMove.data.branchId + '/move-to/' + toNode.data.noteId);
if (!resp.success) { if (!resp.success) {
alert(resp.message); alert(resp.message);
@ -61,7 +61,7 @@ const treeChanges = (function() {
} }
for (const node of nodes) { for (const node of nodes) {
await server.remove('tree/' + node.data.noteTreeId); await server.remove('tree/' + node.data.branchId);
} }
// following code assumes that nodes contain only top-most selected nodes - getSelectedNodes has been // following code assumes that nodes contain only top-most selected nodes - getSelectedNodes has been
@ -80,10 +80,10 @@ const treeChanges = (function() {
// activate next element after this one is deleted so we don't lose focus // activate next element after this one is deleted so we don't lose focus
next.setActive(); next.setActive();
noteTree.setCurrentNotePathToHash(next); treeService.setCurrentNotePathToHash(next);
} }
noteTree.reload(); treeService.reload();
showMessage("Note(s) has been deleted."); showMessage("Note(s) has been deleted.");
} }
@ -93,7 +93,7 @@ const treeChanges = (function() {
return; return;
} }
const resp = await server.put('tree/' + node.data.noteTreeId + '/move-after/' + node.getParent().data.noteTreeId); const resp = await server.put('tree/' + node.data.branchId + '/move-after/' + node.getParent().data.branchId);
if (!resp.success) { if (!resp.success) {
alert(resp.message); alert(resp.message);
@ -111,15 +111,15 @@ const treeChanges = (function() {
function changeNode(node, func) { function changeNode(node, func) {
assertArguments(node.data.parentNoteId, node.data.noteId); assertArguments(node.data.parentNoteId, node.data.noteId);
noteTree.removeParentChildRelation(node.data.parentNoteId, node.data.noteId); treeService.removeParentChildRelation(node.data.parentNoteId, node.data.noteId);
func(node); func(node);
node.data.parentNoteId = isTopLevelNode(node) ? 'root' : node.getParent().data.noteId; node.data.parentNoteId = isTopLevelNode(node) ? 'root' : node.getParent().data.noteId;
noteTree.setParentChildRelation(node.data.noteTreeId, node.data.parentNoteId, node.data.noteId); treeService.setParentChildRelation(node.data.branchId, node.data.parentNoteId, node.data.noteId);
noteTree.setCurrentNotePathToHash(node); treeService.setCurrentNotePathToHash(node);
} }
return { return {

File diff suppressed because one or more lines are too long

View File

@ -24,7 +24,7 @@ router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, wrap(async (req, r
await sql.execute(`DELETE FROM attributes WHERE noteId IN (${noteIdsSql})`); await sql.execute(`DELETE FROM attributes WHERE noteId IN (${noteIdsSql})`);
await sql.execute("DELETE FROM note_tree WHERE isDeleted = 1"); await sql.execute("DELETE FROM branches WHERE isDeleted = 1");
await sql.execute("DELETE FROM note_images WHERE isDeleted = 1"); await sql.execute("DELETE FROM note_images WHERE isDeleted = 1");
@ -35,9 +35,9 @@ router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, wrap(async (req, r
await sql.execute("DELETE FROM recent_notes"); await sql.execute("DELETE FROM recent_notes");
await sync_table.cleanupSyncRowsForMissingEntities("notes", "noteId"); await sync_table.cleanupSyncRowsForMissingEntities("notes", "noteId");
await sync_table.cleanupSyncRowsForMissingEntities("note_tree", "noteTreeId"); await sync_table.cleanupSyncRowsForMissingEntities("branches", "branchId");
await sync_table.cleanupSyncRowsForMissingEntities("note_revisions", "noteRevisionId"); await sync_table.cleanupSyncRowsForMissingEntities("note_revisions", "noteRevisionId");
await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "noteTreeId"); await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "branchId");
log.info("Following notes has been completely cleaned from database: " + noteIdsSql); log.info("Following notes has been completely cleaned from database: " + noteIdsSql);
}); });

View File

@ -19,12 +19,12 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async
return; return;
} }
const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]); const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
const noteTree = { const branch = {
noteTreeId: utils.newNoteTreeId(), branchId: utils.newBranchId(),
noteId: childNoteId, noteId: childNoteId,
parentNoteId: parentNoteId, parentNoteId: parentNoteId,
prefix: prefix, prefix: prefix,
@ -34,22 +34,22 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async
isDeleted: 0 isDeleted: 0
}; };
await sql.replace("note_tree", noteTree); await sql.replace("branches", branch);
await sync_table.addNoteTreeSync(noteTree.noteTreeId, sourceId); await sync_table.addBranchSync(branch.branchId, sourceId);
await sql.execute("UPDATE note_tree SET isExpanded = 1 WHERE noteId = ?", [parentNoteId]); await sql.execute("UPDATE branches SET isExpanded = 1 WHERE noteId = ?", [parentNoteId]);
}); });
res.send({ success: true }); res.send({ success: true });
})); }));
router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:noteId/clone-after/:afterBranchId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
const afterNoteTreeId = req.params.afterNoteTreeId; const afterBranchId = req.params.afterBranchId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const afterNote = await tree.getNoteTree(afterNoteTreeId); const afterNote = await tree.getBranch(afterBranchId);
if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteId)) { if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteId)) {
return; return;
@ -58,13 +58,13 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(asyn
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
// we don't change dateModified so other changes are prioritized in case of conflict // we don't change dateModified so other changes are prioritized in case of conflict
// also we would have to sync all those modified note trees otherwise hash checks would fail // also we would have to sync all those modified note trees otherwise hash checks would fail
await sql.execute("UPDATE note_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0", await sql.execute("UPDATE branches SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0",
[afterNote.parentNoteId, afterNote.notePosition]); [afterNote.parentNoteId, afterNote.notePosition]);
await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId); await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId);
const noteTree = { const branch = {
noteTreeId: utils.newNoteTreeId(), branchId: utils.newBranchId(),
noteId: noteId, noteId: noteId,
parentNoteId: afterNote.parentNoteId, parentNoteId: afterNote.parentNoteId,
notePosition: afterNote.notePosition + 1, notePosition: afterNote.notePosition + 1,
@ -73,9 +73,9 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(asyn
isDeleted: 0 isDeleted: 0
}; };
await sql.replace("note_tree", noteTree); await sql.replace("branches", branch);
await sync_table.addNoteTreeSync(noteTree.noteTreeId, sourceId); await sync_table.addBranchSync(branch.branchId, sourceId);
}); });
res.send({ success: true }); res.send({ success: true });

View File

@ -14,11 +14,11 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next)
const noteId = req.params.noteId; const noteId = req.params.noteId;
const repo = new Repository(req); const repo = new Repository(req);
const noteTreeId = await sql.getValue('SELECT noteTreeId FROM note_tree WHERE noteId = ?', [noteId]); const branchId = await sql.getValue('SELECT branchId FROM branches WHERE noteId = ?', [noteId]);
const pack = tar.pack(); const pack = tar.pack();
const name = await exportNote(noteTreeId, '', pack, repo); const name = await exportNote(branchId, '', pack, repo);
pack.finalize(); pack.finalize();
@ -28,9 +28,9 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next)
pack.pipe(res); pack.pipe(res);
})); }));
async function exportNote(noteTreeId, directory, pack, repo) { async function exportNote(branchId, directory, pack, repo) {
const noteTree = await sql.getRow("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); const branch = await sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]);
const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [noteTree.noteId]); const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [branch.noteId]);
if (note.isProtected) { if (note.isProtected) {
return; return;
@ -51,11 +51,11 @@ async function exportNote(noteTreeId, directory, pack, repo) {
pack.entry({ name: childFileName + ".dat", size: content.length }, content); pack.entry({ name: childFileName + ".dat", size: content.length }, content);
const children = await sql.getRows("SELECT * FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0", [note.noteId]); const children = await sql.getRows("SELECT * FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [note.noteId]);
if (children.length > 0) { if (children.length > 0) {
for (const child of children) { for (const child of children) {
await exportNote(child.noteTreeId, childFileName + "/", pack, repo); await exportNote(child.branchId, childFileName + "/", pack, repo);
} }
} }

View File

@ -48,11 +48,11 @@ router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res,
const newNote = req.body; const newNote = req.body;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
const { noteId, noteTreeId, note } = await notes.createNewNote(parentNoteId, newNote, req, sourceId); const { noteId, branchId, note } = await notes.createNewNote(parentNoteId, newNote, req, sourceId);
res.send({ res.send({
'noteId': noteId, 'noteId': noteId,
'noteTreeId': noteTreeId, 'branchId': branchId,
'note': note 'note': note
}); });
}); });

View File

@ -13,20 +13,20 @@ router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
res.send(await getRecentNotes()); res.send(await getRecentNotes());
})); }));
router.put('/:noteTreeId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const notePath = req.params.notePath; const notePath = req.params.notePath;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.replace('recent_notes', { await sql.replace('recent_notes', {
noteTreeId: noteTreeId, branchId: branchId,
notePath: notePath, notePath: notePath,
dateAccessed: utils.nowDate(), dateAccessed: utils.nowDate(),
isDeleted: 0 isDeleted: 0
}); });
await sync_table.addRecentNoteSync(noteTreeId, sourceId); await sync_table.addRecentNoteSync(branchId, sourceId);
await options.setOption('start_note_path', notePath, sourceId); await options.setOption('start_note_path', notePath, sourceId);
}); });
@ -40,10 +40,10 @@ async function getRecentNotes() {
recent_notes.* recent_notes.*
FROM FROM
recent_notes recent_notes
JOIN note_tree USING(noteTreeId) JOIN branches USING(branchId)
WHERE WHERE
recent_notes.isDeleted = 0 recent_notes.isDeleted = 0
AND note_tree.isDeleted = 0 AND branches.isDeleted = 0
ORDER BY ORDER BY
dateAccessed DESC dateAccessed DESC
LIMIT 200`); LIMIT 200`);

View File

@ -53,9 +53,9 @@ router.post('/force-note-sync/:noteId', auth.checkApiAuth, wrap(async (req, res,
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sync_table.addNoteSync(noteId); await sync_table.addNoteSync(noteId);
for (const noteTreeId of await sql.getColumn("SELECT noteTreeId FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [noteId])) { for (const branchId of await sql.getColumn("SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ?", [noteId])) {
await sync_table.addNoteTreeSync(noteTreeId); await sync_table.addBranchSync(branchId);
await sync_table.addRecentNoteSync(noteTreeId); await sync_table.addRecentNoteSync(branchId);
} }
for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) { for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
@ -88,10 +88,10 @@ router.get('/notes/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
}); });
})); }));
router.get('/note_tree/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/branches/:branchId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
res.send(await sql.getRow("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId])); res.send(await sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]));
})); }));
router.get('/note_revisions/:noteRevisionId', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/note_revisions/:noteRevisionId', auth.checkApiAuth, wrap(async (req, res, next) => {
@ -117,14 +117,14 @@ router.get('/note_reordering/:parentNoteId', auth.checkApiAuth, wrap(async (req,
res.send({ res.send({
parentNoteId: parentNoteId, parentNoteId: parentNoteId,
ordering: await sql.getMap("SELECT noteTreeId, notePosition FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId]) ordering: await sql.getMap("SELECT branchId, notePosition FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId])
}); });
})); }));
router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/recent_notes/:branchId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
res.send(await sql.getRow("SELECT * FROM recent_notes WHERE noteTreeId = ?", [noteTreeId])); res.send(await sql.getRow("SELECT * FROM recent_notes WHERE branchId = ?", [branchId]));
})); }));
router.get('/images/:imageId', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/images/:imageId', auth.checkApiAuth, wrap(async (req, res, next) => {
@ -162,8 +162,8 @@ router.put('/notes', auth.checkApiAuth, wrap(async (req, res, next) => {
res.send({}); res.send({});
})); }));
router.put('/note_tree', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/branches', auth.checkApiAuth, wrap(async (req, res, next) => {
await syncUpdate.updateNoteTree(req.body.entity, req.body.sourceId); await syncUpdate.updateBranch(req.body.entity, req.body.sourceId);
res.send({}); res.send({});
})); }));

View File

@ -12,16 +12,16 @@ const sync_table = require('../../services/sync_table');
const wrap = require('express-promise-wrap').wrap; const wrap = require('express-promise-wrap').wrap;
router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTree = await sql.getRows(` const branches = await sql.getRows(`
SELECT SELECT
noteTreeId, branchId,
noteId, noteId,
parentNoteId, parentNoteId,
notePosition, notePosition,
prefix, prefix,
isExpanded isExpanded
FROM FROM
note_tree branches
WHERE WHERE
isDeleted = 0 isDeleted = 0
ORDER BY ORDER BY
@ -60,21 +60,21 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
res.send({ res.send({
instanceName: config.General ? config.General.instanceName : null, instanceName: config.General ? config.General.instanceName : null,
noteTree: noteTree, branches: branches,
notes: notes, notes: notes,
start_note_path: await options.getOption('start_note_path') start_note_path: await options.getOption('start_note_path')
}); });
})); }));
router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/set-prefix', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.execute("UPDATE note_tree SET prefix = ?, dateModified = ? WHERE noteTreeId = ?", [prefix, utils.nowDate(), noteTreeId]); await sql.execute("UPDATE branches SET prefix = ?, dateModified = ? WHERE branchId = ?", [prefix, utils.nowDate(), branchId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
}); });
res.send({}); res.send({});

View File

@ -15,96 +15,96 @@ const wrap = require('express-promise-wrap').wrap;
* for not deleted note trees. There may be multiple deleted note-parent note relationships. * for not deleted note trees. There may be multiple deleted note-parent note relationships.
*/ */
router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const parentNoteId = req.params.parentNoteId; const parentNoteId = req.params.parentNoteId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const noteToMove = await tree.getNoteTree(noteTreeId); const noteToMove = await tree.getBranch(branchId);
if (!await tree.validateParentChild(res, parentNoteId, noteToMove.noteId, noteTreeId)) { if (!await tree.validateParentChild(res, parentNoteId, noteToMove.noteId, branchId)) {
return; return;
} }
const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]); const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
const now = utils.nowDate(); const now = utils.nowDate();
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?",
[parentNoteId, newNotePos, now, noteTreeId]); [parentNoteId, newNotePos, now, branchId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
}); });
res.send({ success: true }); res.send({ success: true });
})); }));
router.put('/:noteTreeId/move-before/:beforeNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/move-before/:beforeBranchId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const beforeNoteTreeId = req.params.beforeNoteTreeId; const beforeBranchId = req.params.beforeBranchId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const noteToMove = await tree.getNoteTree(noteTreeId); const noteToMove = await tree.getBranch(branchId);
const beforeNote = await tree.getNoteTree(beforeNoteTreeId); const beforeNote = await tree.getBranch(beforeBranchId);
if (!await tree.validateParentChild(res, beforeNote.parentNoteId, noteToMove.noteId, noteTreeId)) { if (!await tree.validateParentChild(res, beforeNote.parentNoteId, noteToMove.noteId, branchId)) {
return; return;
} }
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
// we don't change dateModified so other changes are prioritized in case of conflict // we don't change dateModified so other changes are prioritized in case of conflict
// also we would have to sync all those modified note trees otherwise hash checks would fail // also we would have to sync all those modified note trees otherwise hash checks would fail
await sql.execute("UPDATE note_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0", await sql.execute("UPDATE branches SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0",
[beforeNote.parentNoteId, beforeNote.notePosition]); [beforeNote.parentNoteId, beforeNote.notePosition]);
await sync_table.addNoteReorderingSync(beforeNote.parentNoteId, sourceId); await sync_table.addNoteReorderingSync(beforeNote.parentNoteId, sourceId);
await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?",
[beforeNote.parentNoteId, beforeNote.notePosition, utils.nowDate(), noteTreeId]); [beforeNote.parentNoteId, beforeNote.notePosition, utils.nowDate(), branchId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
}); });
res.send({ success: true }); res.send({ success: true });
})); }));
router.put('/:noteTreeId/move-after/:afterNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/move-after/:afterBranchId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const afterNoteTreeId = req.params.afterNoteTreeId; const afterBranchId = req.params.afterBranchId;
const sourceId = req.headers.source_id; const sourceId = req.headers.source_id;
const noteToMove = await tree.getNoteTree(noteTreeId); const noteToMove = await tree.getBranch(branchId);
const afterNote = await tree.getNoteTree(afterNoteTreeId); const afterNote = await tree.getBranch(afterBranchId);
if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteToMove.noteId, noteTreeId)) { if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteToMove.noteId, branchId)) {
return; return;
} }
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
// we don't change dateModified so other changes are prioritized in case of conflict // we don't change dateModified so other changes are prioritized in case of conflict
// also we would have to sync all those modified note trees otherwise hash checks would fail // also we would have to sync all those modified note trees otherwise hash checks would fail
await sql.execute("UPDATE note_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0", await sql.execute("UPDATE branches SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0",
[afterNote.parentNoteId, afterNote.notePosition]); [afterNote.parentNoteId, afterNote.notePosition]);
await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId); await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId);
await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?",
[afterNote.parentNoteId, afterNote.notePosition + 1, utils.nowDate(), noteTreeId]); [afterNote.parentNoteId, afterNote.notePosition + 1, utils.nowDate(), branchId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
}); });
res.send({ success: true }); res.send({ success: true });
})); }));
router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req, res, next) => { router.put('/:branchId/expanded/:expanded', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteTreeId = req.params.noteTreeId; const branchId = req.params.branchId;
const expanded = req.params.expanded; const expanded = req.params.expanded;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.execute("UPDATE note_tree SET isExpanded = ? WHERE noteTreeId = ?", [expanded, noteTreeId]); await sql.execute("UPDATE branches SET isExpanded = ? WHERE branchId = ?", [expanded, branchId]);
// we don't sync expanded attribute // we don't sync expanded attribute
}); });
@ -112,9 +112,9 @@ router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req
res.send({}); res.send({});
})); }));
router.delete('/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { router.delete('/:branchId', auth.checkApiAuth, wrap(async (req, res, next) => {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await notes.deleteNote(req.params.noteTreeId, req.headers.source_id); await notes.deleteNote(req.params.branchId, req.headers.source_id);
}); });
res.send({}); res.send({});

View File

@ -18,7 +18,7 @@ async function anonymize() {
await db.run("UPDATE notes SET title = 'title', content = 'text'"); await db.run("UPDATE notes SET title = 'title', content = 'text'");
await db.run("UPDATE note_revisions SET title = 'title', content = 'text'"); await db.run("UPDATE note_revisions SET title = 'title', content = 'text'");
await db.run("UPDATE note_tree SET prefix = 'prefix' WHERE prefix IS NOT NULL"); await db.run("UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL");
await db.run(`UPDATE options SET value = 'anonymized' WHERE name IN await db.run(`UPDATE options SET value = 'anonymized' WHERE name IN
('document_secret', 'encrypted_data_key', 'password_verification_hash', ('document_secret', 'encrypted_data_key', 'password_verification_hash',
'password_verification_salt', 'password_derived_key_salt')`); 'password_verification_salt', 'password_derived_key_salt')`);

View File

@ -3,7 +3,7 @@
const build = require('./build'); const build = require('./build');
const packageJson = require('../../package'); const packageJson = require('../../package');
const APP_DB_VERSION = 78; const APP_DB_VERSION = 79;
module.exports = { module.exports = {
app_version: packageJson.version, app_version: packageJson.version,

View File

@ -23,7 +23,7 @@ async function runCheck(query, errorText, errorList) {
async function checkTreeCycles(errorList) { async function checkTreeCycles(errorList) {
const childToParents = {}; const childToParents = {};
const rows = await sql.getRows("SELECT noteId, parentNoteId FROM note_tree WHERE isDeleted = 0"); const rows = await sql.getRows("SELECT noteId, parentNoteId FROM branches WHERE isDeleted = 0");
for (const row of rows) { for (const row of rows) {
const childNoteId = row.noteId; const childNoteId = row.noteId;
@ -92,17 +92,17 @@ async function runAllChecks() {
noteId noteId
FROM FROM
notes notes
LEFT JOIN note_tree USING(noteId) LEFT JOIN branches USING(noteId)
WHERE WHERE
noteId != 'root' noteId != 'root'
AND note_tree.noteTreeId IS NULL`, AND branches.branchId IS NULL`,
"Missing note_tree records for following note IDs", errorList); "Missing branches records for following note IDs", errorList);
await runCheck(` await runCheck(`
SELECT SELECT
noteTreeId || ' > ' || note_tree.noteId branchId || ' > ' || branches.noteId
FROM FROM
note_tree branches
LEFT JOIN notes USING(noteId) LEFT JOIN notes USING(noteId)
WHERE WHERE
notes.noteId IS NULL`, notes.noteId IS NULL`,
@ -110,24 +110,24 @@ async function runAllChecks() {
await runCheck(` await runCheck(`
SELECT SELECT
noteTreeId branchId
FROM FROM
note_tree branches
JOIN notes USING(noteId) JOIN notes USING(noteId)
WHERE WHERE
notes.isDeleted = 1 notes.isDeleted = 1
AND note_tree.isDeleted = 0`, AND branches.isDeleted = 0`,
"Note tree is not deleted even though main note is deleted for following note tree IDs", errorList); "Note tree is not deleted even though main note is deleted for following note tree IDs", errorList);
await runCheck(` await runCheck(`
SELECT SELECT
child.noteTreeId child.branchId
FROM FROM
note_tree AS child branches AS child
WHERE WHERE
child.isDeleted = 0 child.isDeleted = 0
AND child.parentNoteId != 'root' AND child.parentNoteId != 'root'
AND (SELECT COUNT(*) FROM note_tree AS parent WHERE parent.noteId = child.parentNoteId AND (SELECT COUNT(*) FROM branches AS parent WHERE parent.noteId = child.parentNoteId
AND parent.isDeleted = 0) = 0`, AND parent.isDeleted = 0) = 0`,
"All parent note trees are deleted but child note tree is not for these child note tree IDs", errorList); "All parent note trees are deleted but child note tree is not for these child note tree IDs", errorList);
@ -137,18 +137,18 @@ async function runAllChecks() {
DISTINCT noteId DISTINCT noteId
FROM FROM
notes notes
JOIN note_tree USING(noteId) JOIN branches USING(noteId)
WHERE WHERE
(SELECT COUNT(*) FROM note_tree WHERE notes.noteId = note_tree.noteId AND note_tree.isDeleted = 0) = 0 (SELECT COUNT(*) FROM branches WHERE notes.noteId = branches.noteId AND branches.isDeleted = 0) = 0
AND notes.isDeleted = 0 AND notes.isDeleted = 0
`, 'No undeleted note trees for note IDs', errorList); `, 'No undeleted note trees for note IDs', errorList);
await runCheck(` await runCheck(`
SELECT SELECT
child.parentNoteId || ' > ' || child.noteId child.parentNoteId || ' > ' || child.noteId
FROM note_tree FROM branches
AS child AS child
LEFT JOIN note_tree AS parent ON parent.noteId = child.parentNoteId LEFT JOIN branches AS parent ON parent.noteId = child.parentNoteId
WHERE WHERE
parent.noteId IS NULL parent.noteId IS NULL
AND child.parentNoteId != 'root'`, AND child.parentNoteId != 'root'`,
@ -165,14 +165,14 @@ async function runAllChecks() {
await runCheck(` await runCheck(`
SELECT SELECT
note_tree.parentNoteId || ' > ' || note_tree.noteId branches.parentNoteId || ' > ' || branches.noteId
FROM FROM
note_tree branches
WHERE WHERE
note_tree.isDeleted = 0 branches.isDeleted = 0
GROUP BY GROUP BY
note_tree.parentNoteId, branches.parentNoteId,
note_tree.noteId branches.noteId
HAVING HAVING
COUNT(*) > 1`, COUNT(*) > 1`,
"Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList); "Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList);
@ -221,16 +221,16 @@ async function runAllChecks() {
SELECT SELECT
parentNoteId parentNoteId
FROM FROM
note_tree branches
JOIN notes ON notes.noteId = note_tree.parentNoteId JOIN notes ON notes.noteId = branches.parentNoteId
WHERE WHERE
type == 'search'`, type == 'search'`,
"Search note has children", errorList); "Search note has children", errorList);
await runSyncRowChecks("notes", "noteId", errorList); await runSyncRowChecks("notes", "noteId", errorList);
await runSyncRowChecks("note_revisions", "noteRevisionId", errorList); await runSyncRowChecks("note_revisions", "noteRevisionId", errorList);
await runSyncRowChecks("note_tree", "noteTreeId", errorList); await runSyncRowChecks("branches", "branchId", errorList);
await runSyncRowChecks("recent_notes", "noteTreeId", errorList); await runSyncRowChecks("recent_notes", "branchId", errorList);
await runSyncRowChecks("images", "imageId", errorList); await runSyncRowChecks("images", "imageId", errorList);
await runSyncRowChecks("note_images", "noteImageId", errorList); await runSyncRowChecks("note_images", "noteImageId", errorList);
await runSyncRowChecks("attributes", "attributeId", errorList); await runSyncRowChecks("attributes", "attributeId", errorList);

View File

@ -29,17 +29,17 @@ async function getHashes() {
FROM notes FROM notes
ORDER BY noteId`)), ORDER BY noteId`)),
note_tree: getHash(await sql.getRows(` branches: getHash(await sql.getRows(`
SELECT SELECT
noteTreeId, branchId,
noteId, noteId,
parentNoteId, parentNoteId,
notePosition, notePosition,
dateModified, dateModified,
isDeleted, isDeleted,
prefix prefix
FROM note_tree FROM branches
ORDER BY noteTreeId`)), ORDER BY branchId`)),
note_revisions: getHash(await sql.getRows(` note_revisions: getHash(await sql.getRows(`
SELECT SELECT
@ -54,7 +54,7 @@ async function getHashes() {
recent_notes: getHash(await sql.getRows(` recent_notes: getHash(await sql.getRows(`
SELECT SELECT
noteTreeId, branchId,
notePath, notePath,
dateAccessed, dateAccessed,
isDeleted isDeleted

View File

@ -23,10 +23,10 @@ async function createNote(parentNoteId, noteTitle, noteText) {
} }
async function getNoteStartingWith(parentNoteId, startsWith) { async function getNoteStartingWith(parentNoteId, startsWith) {
return await sql.getValue(`SELECT noteId FROM notes JOIN note_tree USING(noteId) return await sql.getValue(`SELECT noteId FROM notes JOIN branches USING(noteId)
WHERE parentNoteId = ? AND title LIKE '${startsWith}%' WHERE parentNoteId = ? AND title LIKE '${startsWith}%'
AND notes.isDeleted = 0 AND isProtected = 0 AND notes.isDeleted = 0 AND isProtected = 0
AND note_tree.isDeleted = 0`, [parentNoteId]); AND branches.isDeleted = 0`, [parentNoteId]);
} }
async function getRootCalendarNoteId() { async function getRootCalendarNoteId() {

View File

@ -7,22 +7,22 @@ const protected_session = require('./protected_session');
async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) { async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
const noteId = utils.newNoteId(); const noteId = utils.newNoteId();
const noteTreeId = utils.newNoteTreeId(); const branchId = utils.newBranchId();
let newNotePos = 0; let newNotePos = 0;
if (noteOpts.target === 'into') { if (noteOpts.target === 'into') {
const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]); const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
} }
else if (noteOpts.target === 'after') { else if (noteOpts.target === 'after') {
const afterNote = await sql.getRow('SELECT notePosition FROM note_tree WHERE noteTreeId = ?', [noteOpts.target_noteTreeId]); const afterNote = await sql.getRow('SELECT notePosition FROM branches WHERE branchId = ?', [noteOpts.target_branchId]);
newNotePos = afterNote.notePosition + 1; newNotePos = afterNote.notePosition + 1;
// not updating dateModified to avoig having to sync whole rows // not updating dateModified to avoig having to sync whole rows
await sql.execute('UPDATE note_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0', await sql.execute('UPDATE branches SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0',
[parentNoteId, afterNote.notePosition]); [parentNoteId, afterNote.notePosition]);
await sync_table.addNoteReorderingSync(parentNoteId, sourceId); await sync_table.addNoteReorderingSync(parentNoteId, sourceId);
@ -64,8 +64,8 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
await sync_table.addNoteSync(noteId, sourceId); await sync_table.addNoteSync(noteId, sourceId);
await sql.insert("note_tree", { await sql.insert("branches", {
noteTreeId: noteTreeId, branchId: branchId,
noteId: noteId, noteId: noteId,
parentNoteId: parentNoteId, parentNoteId: parentNoteId,
notePosition: newNotePos, notePosition: newNotePos,
@ -74,11 +74,11 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
isDeleted: 0 isDeleted: 0
}); });
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
return { return {
noteId, noteId,
noteTreeId, branchId,
note note
}; };
} }
@ -122,7 +122,7 @@ async function protectNoteRecursively(noteId, dataKey, protect, sourceId) {
await protectNote(note, dataKey, protect, sourceId); await protectNote(note, dataKey, protect, sourceId);
const children = await sql.getColumn("SELECT noteId FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0", [noteId]); const children = await sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
for (const childNoteId of children) { for (const childNoteId of children) {
await protectNoteRecursively(childNoteId, dataKey, protect, sourceId); await protectNoteRecursively(childNoteId, dataKey, protect, sourceId);
@ -311,30 +311,30 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
}); });
} }
async function deleteNote(noteTreeId, sourceId) { async function deleteNote(branchId, sourceId) {
const noteTree = await sql.getRowOrNull("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); const branch = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [branchId]);
if (!noteTree || noteTree.isDeleted === 1) { if (!branch || branch.isDeleted === 1) {
return; return;
} }
const now = utils.nowDate(); const now = utils.nowDate();
await sql.execute("UPDATE note_tree SET isDeleted = 1, dateModified = ? WHERE noteTreeId = ?", [now, noteTreeId]); await sql.execute("UPDATE branches SET isDeleted = 1, dateModified = ? WHERE branchId = ?", [now, branchId]);
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addBranchSync(branchId, sourceId);
const noteId = await sql.getValue("SELECT noteId FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); const noteId = await sql.getValue("SELECT noteId FROM branches WHERE branchId = ?", [branchId]);
const notDeletedNoteTreesCount = await sql.getValue("SELECT COUNT(*) FROM note_tree WHERE noteId = ? AND isDeleted = 0", [noteId]); const notDeletedBranchsCount = await sql.getValue("SELECT COUNT(*) FROM branches WHERE noteId = ? AND isDeleted = 0", [noteId]);
if (!notDeletedNoteTreesCount) { if (!notDeletedBranchsCount) {
await sql.execute("UPDATE notes SET isDeleted = 1, dateModified = ? WHERE noteId = ?", [now, noteId]); await sql.execute("UPDATE notes SET isDeleted = 1, dateModified = ? WHERE noteId = ?", [now, noteId]);
await sync_table.addNoteSync(noteId, sourceId); await sync_table.addNoteSync(noteId, sourceId);
const children = await sql.getRows("SELECT noteTreeId FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0", [noteId]); const children = await sql.getRows("SELECT branchId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
for (const child of children) { for (const child of children) {
await deleteNote(child.noteTreeId, sourceId); await deleteNote(child.branchId, sourceId);
} }
} }
} }

View File

@ -2,7 +2,7 @@ const sql = require('./sql');
const protected_session = require('./protected_session'); const protected_session = require('./protected_session');
const Note = require('../entities/note'); const Note = require('../entities/note');
const NoteRevision = require('../entities/note_revision'); const NoteRevision = require('../entities/note_revision');
const NoteTree = require('../entities/note_tree'); const Branch = require('../entities/branch');
const Attribute = require('../entities/attribute'); const Attribute = require('../entities/attribute');
const sync_table = require('../services/sync_table'); const sync_table = require('../services/sync_table');
@ -46,8 +46,8 @@ class Repository {
else if (row.noteRevisionId) { else if (row.noteRevisionId) {
entity = new NoteRevision(this, row); entity = new NoteRevision(this, row);
} }
else if (row.noteTreeId) { else if (row.branchId) {
entity = new NoteTree(this, row); entity = new Branch(this, row);
} }
else if (row.noteId) { else if (row.noteId) {
entity = new Note(this, row); entity = new Note(this, row);

View File

@ -30,7 +30,7 @@ const dbReady = new Promise((resolve, reject) => {
const schema = fs.readFileSync(resource_dir.DB_INIT_DIR + '/schema.sql', 'UTF-8'); const schema = fs.readFileSync(resource_dir.DB_INIT_DIR + '/schema.sql', 'UTF-8');
const notesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes.sql', 'UTF-8'); const notesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes.sql', 'UTF-8');
const notesTreeSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_note_tree.sql', 'UTF-8'); const notesTreeSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_branches.sql', 'UTF-8');
const imagesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_images.sql', 'UTF-8'); const imagesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_images.sql', 'UTF-8');
const notesImageSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_note_images.sql', 'UTF-8'); const notesImageSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_note_images.sql', 'UTF-8');
@ -41,7 +41,7 @@ const dbReady = new Promise((resolve, reject) => {
await executeScript(imagesSql); await executeScript(imagesSql);
await executeScript(notesImageSql); await executeScript(notesImageSql);
const startNoteId = await getValue("SELECT noteId FROM note_tree WHERE parentNoteId = 'root' AND isDeleted = 0 ORDER BY notePosition"); const startNoteId = await getValue("SELECT noteId FROM branches WHERE parentNoteId = 'root' AND isDeleted = 0 ORDER BY notePosition");
await require('./options').initOptions(startNoteId); await require('./options').initOptions(startNoteId);
await require('./sync_table').fillAllSyncRows(); await require('./sync_table').fillAllSyncRows();

View File

@ -125,8 +125,8 @@ async function pullSync(syncContext) {
else if (sync.entityName === 'notes') { else if (sync.entityName === 'notes') {
await syncUpdate.updateNote(resp.entity, syncContext.sourceId); await syncUpdate.updateNote(resp.entity, syncContext.sourceId);
} }
else if (sync.entityName === 'note_tree') { else if (sync.entityName === 'branches') {
await syncUpdate.updateNoteTree(resp, syncContext.sourceId); await syncUpdate.updateBranch(resp, syncContext.sourceId);
} }
else if (sync.entityName === 'note_revisions') { else if (sync.entityName === 'note_revisions') {
await syncUpdate.updateNoteHistory(resp, syncContext.sourceId); await syncUpdate.updateNoteHistory(resp, syncContext.sourceId);
@ -207,8 +207,8 @@ async function pushEntity(sync, syncContext) {
serializeNoteContentBuffer(entity); serializeNoteContentBuffer(entity);
} }
else if (sync.entityName === 'note_tree') { else if (sync.entityName === 'branches') {
entity = await sql.getRow('SELECT * FROM note_tree WHERE noteTreeId = ?', [sync.entityId]); entity = await sql.getRow('SELECT * FROM branches WHERE branchId = ?', [sync.entityId]);
} }
else if (sync.entityName === 'note_revisions') { else if (sync.entityName === 'note_revisions') {
entity = await sql.getRow('SELECT * FROM note_revisions WHERE noteRevisionId = ?', [sync.entityId]); entity = await sql.getRow('SELECT * FROM note_revisions WHERE noteRevisionId = ?', [sync.entityId]);
@ -216,14 +216,14 @@ async function pushEntity(sync, syncContext) {
else if (sync.entityName === 'note_reordering') { else if (sync.entityName === 'note_reordering') {
entity = { entity = {
parentNoteId: sync.entityId, parentNoteId: sync.entityId,
ordering: await sql.getMap('SELECT noteTreeId, notePosition FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0', [sync.entityId]) ordering: await sql.getMap('SELECT branchId, notePosition FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [sync.entityId])
}; };
} }
else if (sync.entityName === 'options') { else if (sync.entityName === 'options') {
entity = await sql.getRow('SELECT * FROM options WHERE name = ?', [sync.entityId]); entity = await sql.getRow('SELECT * FROM options WHERE name = ?', [sync.entityId]);
} }
else if (sync.entityName === 'recent_notes') { else if (sync.entityName === 'recent_notes') {
entity = await sql.getRow('SELECT * FROM recent_notes WHERE noteTreeId = ?', [sync.entityId]); entity = await sql.getRow('SELECT * FROM recent_notes WHERE branchId = ?', [sync.entityId]);
} }
else if (sync.entityName === 'images') { else if (sync.entityName === 'images') {
entity = await sql.getRow('SELECT * FROM images WHERE imageId = ?', [sync.entityId]); entity = await sql.getRow('SELECT * FROM images WHERE imageId = ?', [sync.entityId]);

View File

@ -8,8 +8,8 @@ async function addNoteSync(noteId, sourceId) {
await addEntitySync("notes", noteId, sourceId) await addEntitySync("notes", noteId, sourceId)
} }
async function addNoteTreeSync(noteTreeId, sourceId) { async function addBranchSync(branchId, sourceId) {
await addEntitySync("note_tree", noteTreeId, sourceId) await addEntitySync("branches", branchId, sourceId)
} }
async function addNoteReorderingSync(parentNoteId, sourceId) { async function addNoteReorderingSync(parentNoteId, sourceId) {
@ -24,8 +24,8 @@ async function addOptionsSync(name, sourceId) {
await addEntitySync("options", name, sourceId); await addEntitySync("options", name, sourceId);
} }
async function addRecentNoteSync(noteTreeId, sourceId) { async function addRecentNoteSync(branchId, sourceId) {
await addEntitySync("recent_notes", noteTreeId, sourceId); await addEntitySync("recent_notes", branchId, sourceId);
} }
async function addImageSync(imageId, sourceId) { async function addImageSync(imageId, sourceId) {
@ -91,9 +91,9 @@ async function fillSyncRows(entityName, entityKey) {
async function fillAllSyncRows() { async function fillAllSyncRows() {
await fillSyncRows("notes", "noteId"); await fillSyncRows("notes", "noteId");
await fillSyncRows("note_tree", "noteTreeId"); await fillSyncRows("branches", "branchId");
await fillSyncRows("note_revisions", "noteRevisionId"); await fillSyncRows("note_revisions", "noteRevisionId");
await fillSyncRows("recent_notes", "noteTreeId"); await fillSyncRows("recent_notes", "branchId");
await fillSyncRows("images", "imageId"); await fillSyncRows("images", "imageId");
await fillSyncRows("note_images", "noteImageId"); await fillSyncRows("note_images", "noteImageId");
await fillSyncRows("attributes", "attributeId"); await fillSyncRows("attributes", "attributeId");
@ -102,7 +102,7 @@ async function fillAllSyncRows() {
module.exports = { module.exports = {
addNoteSync, addNoteSync,
addNoteTreeSync, addBranchSync,
addNoteReorderingSync, addNoteReorderingSync,
addNoteHistorySync, addNoteHistorySync,
addOptionsSync, addOptionsSync,

View File

@ -26,18 +26,18 @@ async function updateNote(entity, sourceId) {
} }
} }
async function updateNoteTree(entity, sourceId) { async function updateBranch(entity, sourceId) {
const orig = await sql.getRowOrNull("SELECT * FROM note_tree WHERE noteTreeId = ?", [entity.noteTreeId]); const orig = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [entity.branchId]);
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
if (orig === null || orig.dateModified < entity.dateModified) { if (orig === null || orig.dateModified < entity.dateModified) {
delete entity.isExpanded; delete entity.isExpanded;
await sql.replace('note_tree', entity); await sql.replace('branches', entity);
await sync_table.addNoteTreeSync(entity.noteTreeId, sourceId); await sync_table.addBranchSync(entity.branchId, sourceId);
log.info("Update/sync note tree " + entity.noteTreeId); log.info("Update/sync note tree " + entity.branchId);
} }
}); });
} }
@ -61,7 +61,7 @@ async function updateNoteHistory(entity, sourceId) {
async function updateNoteReordering(entity, sourceId) { async function updateNoteReordering(entity, sourceId) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
Object.keys(entity.ordering).forEach(async key => { Object.keys(entity.ordering).forEach(async key => {
await sql.execute("UPDATE note_tree SET notePosition = ? WHERE noteTreeId = ?", [entity.ordering[key], key]); await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [entity.ordering[key], key]);
}); });
await sync_table.addNoteReorderingSync(entity.parentNoteId, sourceId); await sync_table.addNoteReorderingSync(entity.parentNoteId, sourceId);
@ -87,13 +87,13 @@ async function updateOptions(entity, sourceId) {
} }
async function updateRecentNotes(entity, sourceId) { async function updateRecentNotes(entity, sourceId) {
const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE noteTreeId = ?", [entity.noteTreeId]); const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE branchId = ?", [entity.branchId]);
if (orig === null || orig.dateAccessed < entity.dateAccessed) { if (orig === null || orig.dateAccessed < entity.dateAccessed) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
await sql.replace('recent_notes', entity); await sql.replace('recent_notes', entity);
await sync_table.addRecentNoteSync(entity.noteTreeId, sourceId); await sync_table.addRecentNoteSync(entity.branchId, sourceId);
}); });
} }
} }
@ -160,7 +160,7 @@ async function updateApiToken(entity, sourceId) {
module.exports = { module.exports = {
updateNote, updateNote,
updateNoteTree, updateBranch,
updateNoteHistory, updateNoteHistory,
updateNoteReordering, updateNoteReordering,
updateOptions, updateOptions,

View File

@ -4,10 +4,10 @@ const sql = require('./sql');
const sync_table = require('./sync_table'); const sync_table = require('./sync_table');
const protected_session = require('./protected_session'); const protected_session = require('./protected_session');
async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId = null) { async function validateParentChild(res, parentNoteId, childNoteId, branchId = null) {
const existing = await getExistingNoteTree(parentNoteId, childNoteId); const existing = await getExistingBranch(parentNoteId, childNoteId);
if (existing && (noteTreeId === null || existing.noteTreeId !== noteTreeId)) { if (existing && (branchId === null || existing.branchId !== branchId)) {
res.send({ res.send({
success: false, success: false,
message: 'This note already exists in the target.' message: 'This note already exists in the target.'
@ -28,8 +28,8 @@ async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId =
return true; return true;
} }
async function getExistingNoteTree(parentNoteId, childNoteId) { async function getExistingBranch(parentNoteId, childNoteId) {
return await sql.getRow('SELECT * FROM note_tree WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0', [childNoteId, parentNoteId]); return await sql.getRow('SELECT * FROM branches WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0', [childNoteId, parentNoteId]);
} }
/** /**
@ -52,7 +52,7 @@ async function checkTreeCycle(parentNoteId, childNoteId) {
return false; return false;
} }
const parentNoteIds = await sql.getColumn("SELECT DISTINCT parentNoteId FROM note_tree WHERE noteId = ? AND isDeleted = 0", [parentNoteId]); const parentNoteIds = await sql.getColumn("SELECT DISTINCT parentNoteId FROM branches WHERE noteId = ? AND isDeleted = 0", [parentNoteId]);
for (const pid of parentNoteIds) { for (const pid of parentNoteIds) {
if (!await checkTreeCycleInner(pid)) { if (!await checkTreeCycleInner(pid)) {
@ -66,14 +66,14 @@ async function checkTreeCycle(parentNoteId, childNoteId) {
return await checkTreeCycleInner(parentNoteId); return await checkTreeCycleInner(parentNoteId);
} }
async function getNoteTree(noteTreeId) { async function getBranch(branchId) {
return sql.getRow("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); return sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]);
} }
async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) { async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
subTreeNoteIds.push(parentNoteId); subTreeNoteIds.push(parentNoteId);
const children = await sql.getColumn("SELECT noteId FROM note_tree WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId]); const children = await sql.getColumn("SELECT noteId FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId]);
for (const childNoteId of children) { for (const childNoteId of children) {
await loadSubTreeNoteIds(childNoteId, subTreeNoteIds); await loadSubTreeNoteIds(childNoteId, subTreeNoteIds);
@ -82,9 +82,9 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
async function sortNotesAlphabetically(parentNoteId, req, sourceId) { async function sortNotesAlphabetically(parentNoteId, req, sourceId) {
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
const notes = await sql.getRows(`SELECT noteTreeId, noteId, title, isProtected const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected
FROM notes JOIN note_tree USING(noteId) FROM notes JOIN branches USING(noteId)
WHERE note_tree.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]); WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]);
protected_session.decryptNotes(req, notes); protected_session.decryptNotes(req, notes);
@ -93,8 +93,8 @@ async function sortNotesAlphabetically(parentNoteId, req, sourceId) {
let position = 1; let position = 1;
for (const note of notes) { for (const note of notes) {
await sql.execute("UPDATE note_tree SET notePosition = ? WHERE noteTreeId = ?", await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?",
[position, note.noteTreeId]); [position, note.branchId]);
position++; position++;
} }
@ -105,6 +105,6 @@ async function sortNotesAlphabetically(parentNoteId, req, sourceId) {
module.exports = { module.exports = {
validateParentChild, validateParentChild,
getNoteTree, getBranch,
sortNotesAlphabetically sortNotesAlphabetically
}; };

View File

@ -8,7 +8,7 @@ function newNoteId() {
return randomString(12); return randomString(12);
} }
function newNoteTreeId() { function newBranchId() {
return randomString(12); return randomString(12);
} }
@ -155,7 +155,7 @@ module.exports = {
parseDate, parseDate,
parseDateTime, parseDateTime,
newNoteId, newNoteId,
newNoteTreeId, newBranchId,
newNoteRevisionId, newNoteRevisionId,
newImageId, newImageId,
newNoteImageId, newNoteImageId,