mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	renaming note_tree to branch
This commit is contained in:
		| @@ -11,11 +11,11 @@ | ||||
|     <collation id="5" parent="1" name="RTRIM"/> | ||||
|     <table id="6" parent="2" name="api_tokens"/> | ||||
|     <table id="7" parent="2" name="attributes"/> | ||||
|     <table id="8" parent="2" name="event_log"/> | ||||
|     <table id="9" parent="2" name="images"/> | ||||
|     <table id="10" parent="2" name="note_images"/> | ||||
|     <table id="11" parent="2" name="note_revisions"/> | ||||
|     <table id="12" parent="2" name="note_tree"/> | ||||
|     <table id="8" parent="2" name="branches"/> | ||||
|     <table id="9" parent="2" name="event_log"/> | ||||
|     <table id="10" parent="2" name="images"/> | ||||
|     <table id="11" parent="2" name="note_images"/> | ||||
|     <table id="12" parent="2" name="note_revisions"/> | ||||
|     <table id="13" parent="2" name="notes"/> | ||||
|     <table id="14" parent="2" name="options"/> | ||||
|     <table id="15" parent="2" name="recent_notes"/> | ||||
| @@ -122,199 +122,202 @@ value</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_attributes_1</UnderlyingIndexName> | ||||
|     </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> | ||||
|       <DataType>INTEGER|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <SequenceIdentity>1</SequenceIdentity> | ||||
|     </column> | ||||
|     <column id="39" parent="8" name="noteId"> | ||||
|     <column id="51" parent="9" name="noteId"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|     </column> | ||||
|     <column id="40" parent="8" name="comment"> | ||||
|     <column id="52" parent="9" name="comment"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|     </column> | ||||
|     <column id="41" parent="8" name="dateAdded"> | ||||
|     <column id="53" parent="9" name="dateAdded"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <key id="42" parent="8"> | ||||
|     <key id="54" parent="9"> | ||||
|       <ColNames>id</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|     </key> | ||||
|     <foreign-key id="43" parent="8"> | ||||
|     <foreign-key id="55" parent="9"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <RefTableName>notes</RefTableName> | ||||
|       <RefColNames>noteId</RefColNames> | ||||
|     </foreign-key> | ||||
|     <column id="44" parent="9" name="imageId"> | ||||
|     <column id="56" parent="10" name="imageId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="45" parent="9" name="format"> | ||||
|     <column id="57" parent="10" name="format"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="46" parent="9" name="checksum"> | ||||
|     <column id="58" parent="10" name="checksum"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="47" parent="9" name="name"> | ||||
|     <column id="59" parent="10" name="name"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="48" parent="9" name="data"> | ||||
|     <column id="60" parent="10" name="data"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>BLOB|0s</DataType> | ||||
|     </column> | ||||
|     <column id="49" parent="9" name="isDeleted"> | ||||
|     <column id="61" parent="10" name="isDeleted"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="50" parent="9" name="dateModified"> | ||||
|     <column id="62" parent="10" name="dateModified"> | ||||
|       <Position>7</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="51" parent="9" name="dateCreated"> | ||||
|     <column id="63" parent="10" name="dateCreated"> | ||||
|       <Position>8</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <index id="52" parent="9" name="sqlite_autoindex_images_1"> | ||||
|     <index id="64" parent="10" name="sqlite_autoindex_images_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>imageId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <key id="53" parent="9"> | ||||
|     <key id="65" parent="10"> | ||||
|       <ColNames>imageId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_images_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="54" parent="10" name="noteImageId"> | ||||
|     <column id="66" parent="11" name="noteImageId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="55" parent="10" name="noteId"> | ||||
|     <column id="67" parent="11" name="noteId"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="56" parent="10" name="imageId"> | ||||
|     <column id="68" parent="11" name="imageId"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="57" parent="10" name="isDeleted"> | ||||
|     <column id="69" parent="11" name="isDeleted"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="58" parent="10" name="dateModified"> | ||||
|     <column id="70" parent="11" name="dateModified"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="59" parent="10" name="dateCreated"> | ||||
|     <column id="71" parent="11" name="dateCreated"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </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> | ||||
|       <ColNames>noteImageId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </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 | ||||
| imageId</ColNames> | ||||
|       <ColumnCollations> | ||||
| </ColumnCollations> | ||||
|     </index> | ||||
|     <index id="62" parent="10" name="IDX_note_images_noteId"> | ||||
|     <index id="74" parent="11" name="IDX_note_images_noteId"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="63" parent="10" name="IDX_note_images_imageId"> | ||||
|     <index id="75" parent="11" name="IDX_note_images_imageId"> | ||||
|       <ColNames>imageId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <key id="64" parent="10"> | ||||
|     <key id="76" parent="11"> | ||||
|       <ColNames>noteImageId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_note_images_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="65" parent="11" 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"> | ||||
|     <column id="77" parent="12" name="noteRevisionId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
| @@ -324,55 +327,52 @@ imageId</ColNames> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="79" parent="12" name="parentNoteId"> | ||||
|     <column id="79" parent="12" name="title"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="80" parent="12" name="notePosition"> | ||||
|     <column id="80" parent="12" name="content"> | ||||
|       <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> | ||||
|     </column> | ||||
|     <column id="82" parent="12" name="isExpanded"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>BOOLEAN|0s</DataType> | ||||
|     </column> | ||||
|     <column id="83" parent="12" name="isDeleted"> | ||||
|       <Position>7</Position> | ||||
|       <DataType>INTEGER|0s</DataType> | ||||
|     <column id="81" parent="12" name="isProtected"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="84" parent="12" name="dateModified"> | ||||
|       <Position>8</Position> | ||||
|     <column id="82" parent="12" name="dateModifiedFrom"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </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> | ||||
|       <ColNames>noteTreeId</ColNames> | ||||
|       <ColNames>noteRevisionId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <index id="86" parent="12" name="IDX_note_tree_noteId_parentNoteId"> | ||||
|       <ColNames>noteId | ||||
| parentNoteId</ColNames> | ||||
|       <ColumnCollations> | ||||
| </ColumnCollations> | ||||
|     </index> | ||||
|     <index id="87" parent="12" name="IDX_note_tree_noteId"> | ||||
|     <index id="85" parent="12" name="IDX_note_revisions_noteId"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </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"> | ||||
|       <ColNames>noteTreeId</ColNames> | ||||
|       <ColNames>noteRevisionId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_note_tree_1</UnderlyingIndexName> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="89" parent="13" name="noteId"> | ||||
|       <Position>1</Position> | ||||
| @@ -466,7 +466,7 @@ parentNoteId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="107" parent="15" name="noteTreeId"> | ||||
|     <column id="107" parent="15" name="branchId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
| @@ -487,12 +487,12 @@ parentNoteId</ColNames> | ||||
|     </column> | ||||
|     <index id="111" parent="15" name="sqlite_autoindex_recent_notes_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>noteTreeId</ColNames> | ||||
|       <ColNames>branchId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <key id="112" parent="15"> | ||||
|       <ColNames>noteTreeId</ColNames> | ||||
|       <ColNames>branchId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|   | ||||
							
								
								
									
										38
									
								
								db/migrations/0079__rename_note_tree.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								db/migrations/0079__rename_note_tree.sql
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										18
									
								
								src/entities/branch.js
									
									
									
									
									
										Normal 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; | ||||
| @@ -79,50 +79,50 @@ class Note extends Entity { | ||||
|     } | ||||
|  | ||||
|     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) { | ||||
|         return this.repository.getEntity(` | ||||
|           SELECT notes.*  | ||||
|           FROM note_tree  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
|           WHERE notes.isDeleted = 0 | ||||
|                 AND note_tree.isDeleted = 0 | ||||
|                 AND note_tree.parentNoteId = ? | ||||
|                 AND branches.isDeleted = 0 | ||||
|                 AND branches.parentNoteId = ? | ||||
|                 AND notes.title = ?`, [this.noteId, name]); | ||||
|     } | ||||
|  | ||||
|     async getChildren() { | ||||
|         return this.repository.getEntities(` | ||||
|           SELECT notes.*  | ||||
|           FROM note_tree  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
|           WHERE notes.isDeleted = 0 | ||||
|                 AND note_tree.isDeleted = 0 | ||||
|                 AND note_tree.parentNoteId = ? | ||||
|           ORDER BY note_tree.notePosition`, [this.noteId]); | ||||
|                 AND branches.isDeleted = 0 | ||||
|                 AND branches.parentNoteId = ? | ||||
|           ORDER BY branches.notePosition`, [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     async getParents() { | ||||
|         return this.repository.getEntities(` | ||||
|           SELECT parent_notes.*  | ||||
|           FROM  | ||||
|             note_tree AS child_tree  | ||||
|             branches AS child_tree  | ||||
|             JOIN notes AS parent_notes ON parent_notes.noteId = child_tree.parentNoteId  | ||||
|           WHERE child_tree.noteId = ? | ||||
|                 AND child_tree.isDeleted = 0 | ||||
|                 AND parent_notes.isDeleted = 0`, [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     async getNoteTree() { | ||||
|     async getBranch() { | ||||
|         return this.repository.getEntities(` | ||||
|           SELECT note_tree.*  | ||||
|           FROM note_tree  | ||||
|           SELECT branches.*  | ||||
|           FROM branches  | ||||
|             JOIN notes USING(noteId)  | ||||
|           WHERE notes.isDeleted = 0 | ||||
|                 AND note_tree.isDeleted = 0 | ||||
|                 AND note_tree.noteId = ?`, [this.noteId]); | ||||
|                 AND branches.isDeleted = 0 | ||||
|                 AND branches.noteId = ?`, [this.noteId]); | ||||
|     } | ||||
|  | ||||
|     beforeSaving() { | ||||
|   | ||||
| @@ -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; | ||||
| @@ -24,7 +24,7 @@ function ScriptApi(startNote, currentNote) { | ||||
|     const $pluginButtons = $("#plugin-buttons"); | ||||
|  | ||||
|     async function activateNote(notePath) { | ||||
|         await noteTree.activateNode(notePath); | ||||
|         await treeService.activateNode(notePath); | ||||
|     } | ||||
|  | ||||
|     function addButtonToToolbar(buttonId, button) { | ||||
| @@ -70,7 +70,7 @@ function ScriptApi(startNote, currentNote) { | ||||
|         currentNote: currentNote, | ||||
|         addButtonToToolbar, | ||||
|         activateNote, | ||||
|         getInstanceName: noteTree.getInstanceName, | ||||
|         getInstanceName: treeService.getInstanceName, | ||||
|         runOnServer | ||||
|     } | ||||
| } | ||||
| @@ -11,19 +11,19 @@ const cloning = (function() { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         await noteTree.reload(); | ||||
|         await treeService.reload(); | ||||
|     } | ||||
|  | ||||
|     // beware that first arg is noteId and second is noteTreeId! | ||||
|     async function cloneNoteAfter(noteId, afterNoteTreeId) { | ||||
|         const resp = await server.put('notes/' + noteId + '/clone-after/' + afterNoteTreeId); | ||||
|     // beware that first arg is noteId and second is branchId! | ||||
|     async function cloneNoteAfter(noteId, afterBranchId) { | ||||
|         const resp = await server.put('notes/' + noteId + '/clone-after/' + afterBranchId); | ||||
|  | ||||
|         if (!resp.success) { | ||||
|             alert(resp.message); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         await noteTree.reload(); | ||||
|         await treeService.reload(); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|   | ||||
| @@ -17,7 +17,7 @@ const contextMenu = (function() { | ||||
|         } | ||||
|         else if (clipboardMode === 'copy') { | ||||
|             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 | ||||
| @@ -95,9 +95,9 @@ const contextMenu = (function() { | ||||
|         ], | ||||
|         beforeOpen: (event, ui) => { | ||||
|             const node = $.ui.fancytree.getNode(ui.target); | ||||
|             const nt = noteTree.getNoteTree(node.data.noteTreeId); | ||||
|             const note = noteTree.getNote(node.data.noteId); | ||||
|             const parentNote = noteTree.getNote(nt.parentNoteId); | ||||
|             const branch = treeService.getBranch(node.data.branchId); | ||||
|             const note = treeService.getNote(node.data.noteId); | ||||
|             const parentNote = treeService.getNote(branch.parentNoteId); | ||||
|  | ||||
|             // Modify menu entries depending on node status | ||||
|             $tree.contextmenu("enableEntry", "pasteAfter", clipboardIds.length > 0 && (!parentNote || parentNote.type !== 'search')); | ||||
| @@ -121,10 +121,10 @@ const contextMenu = (function() { | ||||
|                 const parentNoteId = node.data.parentNoteId; | ||||
|                 const isProtected = treeUtils.getParentProtectedStatus(node); | ||||
|  | ||||
|                 noteTree.createNote(node, parentNoteId, 'after', isProtected); | ||||
|                 treeService.createNote(node, parentNoteId, 'after', isProtected); | ||||
|             } | ||||
|             else if (ui.cmd === "insertChildNote") { | ||||
|                 noteTree.createNote(node, node.data.noteId, 'into'); | ||||
|                 treeService.createNote(node, node.data.noteId, 'into'); | ||||
|             } | ||||
|             else if (ui.cmd === "editTreePrefix") { | ||||
|                 editTreePrefix.showDialog(node); | ||||
| @@ -136,10 +136,10 @@ const contextMenu = (function() { | ||||
|                 protected_session.protectSubTree(node.data.noteId, false); | ||||
|             } | ||||
|             else if (ui.cmd === "copy") { | ||||
|                 copy(noteTree.getSelectedNodes()); | ||||
|                 copy(treeService.getSelectedNodes()); | ||||
|             } | ||||
|             else if (ui.cmd === "cut") { | ||||
|                 cut(noteTree.getSelectedNodes()); | ||||
|                 cut(treeService.getSelectedNodes()); | ||||
|             } | ||||
|             else if (ui.cmd === "pasteAfter") { | ||||
|                 pasteAfter(node); | ||||
| @@ -148,7 +148,7 @@ const contextMenu = (function() { | ||||
|                 pasteInto(node); | ||||
|             } | ||||
|             else if (ui.cmd === "delete") { | ||||
|                 treeChanges.deleteNodes(noteTree.getSelectedNodes(true)); | ||||
|                 treeChanges.deleteNodes(treeService.getSelectedNodes(true)); | ||||
|             } | ||||
|             else if (ui.cmd === "exportSubTree") { | ||||
|                 exportSubTree(node.data.noteId); | ||||
| @@ -157,13 +157,13 @@ const contextMenu = (function() { | ||||
|                 importSubTree(node.data.noteId); | ||||
|             } | ||||
|             else if (ui.cmd === "collapseSubTree") { | ||||
|                 noteTree.collapseTree(node); | ||||
|                 treeService.collapseTree(node); | ||||
|             } | ||||
|             else if (ui.cmd === "forceNoteSync") { | ||||
|                 forceNoteSync(node.data.noteId); | ||||
|             } | ||||
|             else if (ui.cmd === "sortAlphabetically") { | ||||
|                 noteTree.sortAlphabetically(node.data.noteId); | ||||
|                 treeService.sortAlphabetically(node.data.noteId); | ||||
|             } | ||||
|             else { | ||||
|                 messaging.logError("Unknown command: " + ui.cmd); | ||||
|   | ||||
| @@ -43,13 +43,13 @@ const addLink = (function() { | ||||
|         $linkTitle.val(''); | ||||
|  | ||||
|         function setDefaultLinkTitle(noteId) { | ||||
|             const noteTitle = noteTree.getNoteTitle(noteId); | ||||
|             const noteTitle = treeService.getNoteTitle(noteId); | ||||
|  | ||||
|             $linkTitle.val(noteTitle); | ||||
|         } | ||||
|  | ||||
|         $autoComplete.autocomplete({ | ||||
|             source: noteTree.getAutocompleteItems(), | ||||
|             source: treeService.getAutocompleteItems(), | ||||
|             minLength: 0, | ||||
|             change: () => { | ||||
|                 const val = $autoComplete.val(); | ||||
|   | ||||
| @@ -6,7 +6,7 @@ const editTreePrefix = (function() { | ||||
|     const $treePrefixInput = $("#tree-prefix-input"); | ||||
|     const $noteTitle = $('#tree-prefix-note-title'); | ||||
|  | ||||
|     let noteTreeId; | ||||
|     let branchId; | ||||
|  | ||||
|     async function showDialog() { | ||||
|         glob.activeDialog = $dialog; | ||||
| @@ -16,14 +16,14 @@ const editTreePrefix = (function() { | ||||
|             width: 500 | ||||
|         }); | ||||
|  | ||||
|         const currentNode = noteTree.getCurrentNode(); | ||||
|         const currentNode = treeService.getCurrentNode(); | ||||
|  | ||||
|         noteTreeId = currentNode.data.noteTreeId; | ||||
|         const nt = noteTree.getNoteTree(noteTreeId); | ||||
|         branchId = currentNode.data.branchId; | ||||
|         const nt = treeService.getBranch(branchId); | ||||
|  | ||||
|         $treePrefixInput.val(nt.prefix).focus(); | ||||
|  | ||||
|         const noteTitle = noteTree.getNoteTitle(currentNode.data.noteId); | ||||
|         const noteTitle = treeService.getNoteTitle(currentNode.data.noteId); | ||||
|  | ||||
|         $noteTitle.html(noteTitle); | ||||
|     } | ||||
| @@ -31,9 +31,9 @@ const editTreePrefix = (function() { | ||||
|     $form.submit(() => { | ||||
|         const prefix = $treePrefixInput.val(); | ||||
|  | ||||
|         server.put('tree/' + noteTreeId + '/set-prefix', { | ||||
|         server.put('tree/' + branchId + '/set-prefix', { | ||||
|             prefix: prefix | ||||
|         }).then(() => noteTree.setPrefix(noteTreeId, prefix)); | ||||
|         }).then(() => treeService.setPrefix(branchId, prefix)); | ||||
|  | ||||
|         $dialog.dialog("close"); | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ const jumpToNote = (function() { | ||||
|         }); | ||||
|  | ||||
|         await $autoComplete.autocomplete({ | ||||
|             source: await stopWatch("building autocomplete", noteTree.getAutocompleteItems), | ||||
|             source: await stopWatch("building autocomplete", treeService.getAutocompleteItems), | ||||
|             minLength: 0 | ||||
|         }); | ||||
|     } | ||||
| @@ -31,7 +31,7 @@ const jumpToNote = (function() { | ||||
|         const notePath = getSelectedNotePath(); | ||||
|  | ||||
|         if (notePath) { | ||||
|             noteTree.activateNode(notePath); | ||||
|             treeService.activateNode(notePath); | ||||
|  | ||||
|             $dialog.dialog('close'); | ||||
|         } | ||||
|   | ||||
| @@ -14,11 +14,11 @@ const recentNotes = (function() { | ||||
|         list = result.map(r => r.notePath); | ||||
|     } | ||||
|  | ||||
|     function addRecentNote(noteTreeId, notePath) { | ||||
|     function addRecentNote(branchId, notePath) { | ||||
|         setTimeout(async () => { | ||||
|             // we include the note into recent list only if the user stayed on the note at least 5 seconds | ||||
|             if (notePath && notePath === noteTree.getCurrentNotePath()) { | ||||
|                 const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath)); | ||||
|             if (notePath && notePath === treeService.getCurrentNotePath()) { | ||||
|                 const result = await server.put('recent-notes/' + branchId + '/' + encodeURIComponent(notePath)); | ||||
|  | ||||
|                 list = result.map(r => r.notePath); | ||||
|             } | ||||
| @@ -38,14 +38,14 @@ const recentNotes = (function() { | ||||
|         $searchInput.val(''); | ||||
|  | ||||
|         // remove the current note | ||||
|         const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath()); | ||||
|         const recNotes = list.filter(note => note !== treeService.getCurrentNotePath()); | ||||
|  | ||||
|         $searchInput.autocomplete({ | ||||
|             source: recNotes.map(notePath => { | ||||
|                 let noteTitle; | ||||
|  | ||||
|                 try { | ||||
|                     noteTitle = noteTree.getNotePathTitle(notePath); | ||||
|                     noteTitle = treeService.getNotePathTitle(notePath); | ||||
|                 } | ||||
|                 catch (e) { | ||||
|                     noteTitle = "[error - can't find note title]"; | ||||
| @@ -61,7 +61,7 @@ const recentNotes = (function() { | ||||
|             minLength: 0, | ||||
|             autoFocus: true, | ||||
|             select: function (event, ui) { | ||||
|                 noteTree.activateNode(ui.item.value); | ||||
|                 treeService.activateNode(ui.item.value); | ||||
|  | ||||
|                 $searchInput.autocomplete('destroy'); | ||||
|                 $dialog.dialog('close'); | ||||
|   | ||||
| @@ -49,7 +49,7 @@ const dragAndDropSetup = { | ||||
|         const nodeToMove = data.otherNode; | ||||
|         nodeToMove.setSelected(true); | ||||
|  | ||||
|         const selectedNodes = noteTree.getSelectedNodes(); | ||||
|         const selectedNodes = treeService.getSelectedNodes(); | ||||
|  | ||||
|         if (data.hitMode === "before") { | ||||
|             treeChanges.moveBeforeNode(selectedNodes, node); | ||||
|   | ||||
| @@ -28,5 +28,5 @@ $("#import-upload").change(async function() { | ||||
|         processData: false, // NEEDED, DON'T OMIT THIS | ||||
|     }); | ||||
|  | ||||
|     await noteTree.reload(); | ||||
|     await treeService.reload(); | ||||
| }); | ||||
| @@ -55,7 +55,7 @@ $(document).bind('keydown', 'ctrl+f', () => { | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+up", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     const node = treeService.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.UP, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
| @@ -64,7 +64,7 @@ $(document).bind('keydown', "ctrl+shift+up", () => { | ||||
| }); | ||||
|  | ||||
| $(document).bind('keydown', "ctrl+shift+down", () => { | ||||
|     const node = noteTree.getCurrentNode(); | ||||
|     const node = treeService.getCurrentNode(); | ||||
|     node.navigate($.ui.keyCode.DOWN, true); | ||||
|  | ||||
|     $("#note-detail").focus(); | ||||
| @@ -211,16 +211,16 @@ $(document).ready(() => { | ||||
| if (isElectron()) { | ||||
|     require('electron').ipcRenderer.on('create-day-sub-note', async function(event, parentNoteId) { | ||||
|         // this might occur when day note had to be created | ||||
|         if (!noteTree.noteExists(parentNoteId)) { | ||||
|             await noteTree.reload(); | ||||
|         if (!treeService.noteExists(parentNoteId)) { | ||||
|             await treeService.reload(); | ||||
|         } | ||||
|  | ||||
|         await noteTree.activateNode(parentNoteId); | ||||
|         await treeService.activateNode(parentNoteId); | ||||
|  | ||||
|         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); | ||||
|     }); | ||||
| } | ||||
| @@ -244,7 +244,7 @@ $("#attachment-upload").change(async function() { | ||||
|         processData: false, // NEEDED, DON'T OMIT THIS | ||||
|     }); | ||||
|  | ||||
|     await noteTree.reload(); | ||||
|     await treeService.reload(); | ||||
|  | ||||
|     await noteTree.activateNode(resp.noteId); | ||||
|     await treeService.activateNode(resp.noteId); | ||||
| }); | ||||
| @@ -26,7 +26,7 @@ const link = (function() { | ||||
|         if (!noteTitle) { | ||||
|             const noteId = treeUtils.getNoteIdFromNotePath(notePath); | ||||
|  | ||||
|             noteTitle = noteTree.getNoteTitle(noteId); | ||||
|             noteTitle = treeService.getNoteTitle(noteId); | ||||
|         } | ||||
|  | ||||
|         const noteLink = $("<a>", { | ||||
| @@ -60,7 +60,7 @@ const link = (function() { | ||||
|             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 | ||||
|         $("[role='tooltip']").remove(); | ||||
|   | ||||
| @@ -29,12 +29,12 @@ const messaging = (function() { | ||||
|  | ||||
|             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')) { | ||||
|  | ||||
|                 console.log(now(), "Reloading tree because of background changes"); | ||||
|  | ||||
|                 noteTree.reload(); | ||||
|                 treeService.reload(); | ||||
|             } | ||||
|  | ||||
|             if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === noteEditor.getCurrentNoteId())) { | ||||
|   | ||||
| @@ -110,7 +110,7 @@ const noteEditor = (function() { | ||||
|  | ||||
|         note.detail.title = title; | ||||
|  | ||||
|         noteTree.setNoteTitle(note.detail.noteId, title); | ||||
|         treeService.setNoteTitle(note.detail.noteId, title); | ||||
|     } | ||||
|  | ||||
|     async function saveNoteToServer(note) { | ||||
| @@ -264,7 +264,7 @@ const noteEditor = (function() { | ||||
|         noteChangeDisabled = false; | ||||
|  | ||||
|         setNoteBackgroundIfProtected(currentNote); | ||||
|         noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId); | ||||
|         treeService.setBranchBackgroundBasedOnProtectedStatus(noteId); | ||||
|  | ||||
|         // after loading new note make sure editor is scrolled to the top | ||||
|         $noteDetailWrapper.scrollTop(0); | ||||
| @@ -366,7 +366,7 @@ const noteEditor = (function() { | ||||
|  | ||||
|             const title = $noteTitle.val(); | ||||
|  | ||||
|             noteTree.setNoteTitle(getCurrentNoteId(), title); | ||||
|             treeService.setNoteTitle(getCurrentNoteId(), title); | ||||
|         }); | ||||
|  | ||||
|         // so that tab jumps from note title (which has tabindex 1) | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| "use strict"; | ||||
|  | ||||
| class TreeCache { | ||||
|     constructor(noteRows, noteTreeRows) { | ||||
|     constructor(noteRows, branchRows) { | ||||
|         this.parents = []; | ||||
|         this.children = []; | ||||
|         this.childParentToNoteTree = {}; | ||||
|         this.childParentToBranch = {}; | ||||
|  | ||||
|         this.notes = {}; | ||||
|         for (const noteRow of noteRows) { | ||||
| @@ -13,12 +13,12 @@ class TreeCache { | ||||
|             this.notes[note.noteId] = note; | ||||
|         } | ||||
|  | ||||
|         this.noteTree = {}; | ||||
|         for (const noteTreeRow of noteTreeRows) { | ||||
|             const nt = new NoteTree(this, noteTreeRow); | ||||
|         this.branches = {}; | ||||
|         for (const branchRow of branchRows) { | ||||
|             const branch = new Branch(this, branchRow); | ||||
|  | ||||
|             this.noteTree[nt.noteTreeId] = nt; | ||||
|             this.addNoteTree(nt); | ||||
|             this.branches[branch.branchId] = branch; | ||||
|             this.addBranch(branch); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -26,22 +26,24 @@ class TreeCache { | ||||
|         return this.notes[noteId]; | ||||
|     } | ||||
|  | ||||
|     addNoteTree(nt) { | ||||
|         this.parents[nt.noteId] = this.parents[nt.noteId] || []; | ||||
|         this.parents[nt.noteId].push(this.notes[nt.parentNoteId]); | ||||
|     addBranch(branch) { | ||||
|         this.parents[branch.noteId] = this.parents[branch.noteId] || []; | ||||
|         this.parents[branch.noteId].push(this.notes[branch.parentNoteId]); | ||||
|  | ||||
|         this.children[nt.parentNoteId] = this.children[nt.parentNoteId] || []; | ||||
|         this.children[nt.parentNoteId].push(this.notes[nt.noteId]); | ||||
|         this.children[branch.parentNoteId] = this.children[branch.parentNoteId] || []; | ||||
|         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.addBranch(branch); | ||||
|     } | ||||
|  | ||||
|     async getNoteTree(childNoteId, parentNoteId) { | ||||
|         return this.childParentToNoteTree[childNoteId + '-' + parentNoteId]; | ||||
|     async getBranch(childNoteId, parentNoteId) { | ||||
|         return this.childParentToBranch[childNoteId + '-' + parentNoteId]; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -56,24 +58,24 @@ class NoteShort { | ||||
|         this.hideInAutocomplete = row.hideInAutocomplete; | ||||
|     } | ||||
|  | ||||
|     async getNoteTrees() { | ||||
|         const noteTrees = []; | ||||
|     async getBranches() { | ||||
|         const branches = []; | ||||
|  | ||||
|         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() { | ||||
|         const noteTrees = []; | ||||
|     async getChildBranches() { | ||||
|         const branches = []; | ||||
|  | ||||
|         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() { | ||||
| @@ -89,10 +91,10 @@ class NoteShort { | ||||
|     } | ||||
| } | ||||
|  | ||||
| class NoteTree { | ||||
| class Branch { | ||||
|     constructor(treeCache, row) { | ||||
|         this.treeCache = treeCache; | ||||
|         this.noteTreeId = row.noteTreeId; | ||||
|         this.branchId = row.branchId; | ||||
|         this.noteId = row.noteId; | ||||
|         this.note = null; | ||||
|         this.parentNoteId = row.parentNoteId; | ||||
| @@ -106,11 +108,11 @@ class NoteTree { | ||||
|     } | ||||
|  | ||||
|     get toString() { | ||||
|         return `NoteTree(noteTreeId=${this.noteTreeId})`; | ||||
|         return `Branch(branchId=${this.branchId})`; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const noteTree = (function() { | ||||
| const treeService = (function() { | ||||
|     let treeCache; | ||||
|  | ||||
|     const $tree = $("#tree"); | ||||
| @@ -126,8 +128,8 @@ const noteTree = (function() { | ||||
|  | ||||
|     /** @type {Object.<string, NoteShort>} */ | ||||
|     let noteMap = {}; | ||||
|     /** @type {Object.<string, NoteTree>} */ | ||||
|     let noteTreeMap = {}; | ||||
|     /** @type {Object.<string, Branch>} */ | ||||
|     let branchMap = {}; | ||||
|  | ||||
|     function getNote(noteId) { | ||||
|         const note = noteMap[noteId]; | ||||
| @@ -139,7 +141,7 @@ const noteTree = (function() { | ||||
|         return note; | ||||
|     } | ||||
|  | ||||
|     function getNoteTreeId(parentNoteId, childNoteId) { | ||||
|     function getBranchId(parentNoteId, childNoteId) { | ||||
|         assertArguments(parentNoteId, childNoteId); | ||||
|  | ||||
|  | ||||
| @@ -148,7 +150,7 @@ const noteTree = (function() { | ||||
|  | ||||
|         // this can return undefined and client code should deal with it somehow | ||||
|  | ||||
|         return parentChildToNoteTreeId[key]; | ||||
|         return parentChildToBranchId[key]; | ||||
|     } | ||||
|  | ||||
|     function getNoteTitle(noteId, parentNoteId = null) { | ||||
| @@ -157,13 +159,13 @@ const noteTree = (function() { | ||||
|         let title = treeCache.getNote(noteId).title; | ||||
|  | ||||
|         if (parentNoteId !== null) { | ||||
|             const noteTreeId = getNoteTreeId(parentNoteId, noteId); | ||||
|             const branchId = getBranchId(parentNoteId, noteId); | ||||
|  | ||||
|             if (noteTreeId) { | ||||
|                 const noteTree = noteTreeMap[noteTreeId]; | ||||
|             if (branchId) { | ||||
|                 const branch = branchMap[branchId]; | ||||
|  | ||||
|                 if (noteTree.prefix) { | ||||
|                     title = noteTree.prefix + ' - ' + title; | ||||
|                 if (branch.prefix) { | ||||
|                     title = branch.prefix + ' - ' + title; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -182,12 +184,12 @@ const noteTree = (function() { | ||||
|         return treeUtils.getNotePath(node); | ||||
|     } | ||||
|  | ||||
|     function getNodesByNoteTreeId(noteTreeId) { | ||||
|         assertArguments(noteTreeId); | ||||
|     function getNodesByBranchId(branchId) { | ||||
|         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) { | ||||
| @@ -197,19 +199,19 @@ const noteTree = (function() { | ||||
|         return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null | ||||
|     } | ||||
|  | ||||
|     function setPrefix(noteTreeId, prefix) { | ||||
|         assertArguments(noteTreeId); | ||||
|     function setPrefix(branchId, prefix) { | ||||
|         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) { | ||||
|         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; | ||||
|  | ||||
| @@ -222,32 +224,24 @@ const noteTree = (function() { | ||||
|         const parentNote = noteMap[parentNoteId]; | ||||
|         const childNote = noteMap[childNoteId]; | ||||
|  | ||||
|         parentNote.children = parentNote.children.filter(note => note.noteId !== childNoteId); | ||||
|         childNote.parents = childNote.parents.filter(note => note.noteId !== parentNoteId); | ||||
|         childNote.noteTree = childNote.noteTree.filter(nt => nt.parentNoteId !== parentNoteId); | ||||
|         // FIXME | ||||
|     } | ||||
|  | ||||
|     function setParentChildRelation(noteTreeId, parentNoteId, childNoteId) { | ||||
|         assertArguments(noteTreeId, parentNoteId, childNoteId); | ||||
|     function setParentChildRelation(branchId, parentNoteId, childNoteId) { | ||||
|         assertArguments(branchId, parentNoteId, childNoteId); | ||||
|  | ||||
|         const parentNote = noteMap[parentNoteId]; | ||||
|         const childNote = noteMap[childNoteId]; | ||||
|  | ||||
|         // 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); | ||||
|  | ||||
|         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) { | ||||
| @@ -268,31 +262,31 @@ const noteTree = (function() { | ||||
|         return extraClasses.join(" "); | ||||
|     } | ||||
|  | ||||
|     async function prepareNoteTreeInner(parentNote) { | ||||
|     async function prepareBranchInner(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.`); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const noteList = []; | ||||
|  | ||||
|         for (const noteTree of childrenNoteTrees) { | ||||
|             const note = await noteTree.getNote(); | ||||
|             const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + note.title; | ||||
|         for (const branch of childBranches) { | ||||
|             const note = await branch.getNote(); | ||||
|             const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title; | ||||
|  | ||||
|             const node = { | ||||
|                 noteId: note.noteId, | ||||
|                 parentNoteId: noteTree.parentNoteId, | ||||
|                 noteTreeId: noteTree.noteTreeId, | ||||
|                 parentNoteId: branch.parentNoteId, | ||||
|                 branchId: branch.branchId, | ||||
|                 isProtected: note.isProtected, | ||||
|                 title: escapeHtml(title), | ||||
|                 extraClasses: getExtraClasses(note), | ||||
|                 refKey: note.noteId, | ||||
|                 expanded: note.type !== 'search' && noteTree.isExpanded | ||||
|                 expanded: note.type !== 'search' && branch.isExpanded | ||||
|             }; | ||||
|  | ||||
|             const hasChildren = (await note.getChildNotes()).length > 0; | ||||
| @@ -301,7 +295,7 @@ const noteTree = (function() { | ||||
|                 node.folder = true; | ||||
|  | ||||
|                 if (node.expanded && note.type !== 'search') { | ||||
|                     node.children = await prepareNoteTreeInner(note); | ||||
|                     node.children = await prepareBranchInner(note); | ||||
|                 } | ||||
|                 else { | ||||
|                     node.lazy = true; | ||||
| @@ -485,23 +479,23 @@ const noteTree = (function() { | ||||
|         return path.reverse().join('/'); | ||||
|     } | ||||
|  | ||||
|     async function setExpandedToServer(noteTreeId, isExpanded) { | ||||
|         assertArguments(noteTreeId); | ||||
|     async function setExpandedToServer(branchId, isExpanded) { | ||||
|         assertArguments(branchId); | ||||
|  | ||||
|         const expandedNum = isExpanded ? 1 : 0; | ||||
|  | ||||
|         await server.put('tree/' + noteTreeId + '/expanded/' + expandedNum); | ||||
|         await server.put('tree/' + branchId + '/expanded/' + expandedNum); | ||||
|     } | ||||
|  | ||||
|     function setCurrentNotePathToHash(node) { | ||||
|         assertArguments(node); | ||||
|  | ||||
|         const currentNotePath = treeUtils.getNotePath(node); | ||||
|         const currentNoteTreeId = node.data.noteTreeId; | ||||
|         const currentBranchId = node.data.branchId; | ||||
|  | ||||
|         document.location.hash = currentNotePath; | ||||
|  | ||||
|         recentNotes.addRecentNote(currentNoteTreeId, currentNotePath); | ||||
|         recentNotes.addRecentNote(currentBranchId, currentNotePath); | ||||
|     } | ||||
|  | ||||
|     function getSelectedNodes(stopOnParents = false) { | ||||
| @@ -520,8 +514,8 @@ const noteTree = (function() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function initFancyTree(noteTree) { | ||||
|         assertArguments(noteTree); | ||||
|     function initFancyTree(branch) { | ||||
|         assertArguments(branch); | ||||
|  | ||||
|         const keybindings = { | ||||
|             "del": node => { | ||||
| @@ -656,7 +650,7 @@ const noteTree = (function() { | ||||
|             autoScroll: true, | ||||
|             keyboard: false, // we takover keyboard handling in the hotkeys plugin | ||||
|             extensions: ["hotkeys", "filter", "dnd", "clones"], | ||||
|             source: noteTree, | ||||
|             source: branch, | ||||
|             scrollParent: $("#tree"), | ||||
|             click: (event, data) => { | ||||
|                 const targetType = data.targetType; | ||||
| @@ -686,10 +680,10 @@ const noteTree = (function() { | ||||
|                 showParentList(node.noteId, data.node); | ||||
|             }, | ||||
|             expand: (event, data) => { | ||||
|                 setExpandedToServer(data.node.data.noteTreeId, true); | ||||
|                 setExpandedToServer(data.node.data.branchId, true); | ||||
|             }, | ||||
|             collapse: (event, data) => { | ||||
|                 setExpandedToServer(data.node.data.noteTreeId, false); | ||||
|                 setExpandedToServer(data.node.data.branchId, false); | ||||
|             }, | ||||
|             init: (event, data) => { | ||||
|                 const noteId = treeUtils.getNoteIdFromNotePath(startNotePath); | ||||
| @@ -731,7 +725,7 @@ const noteTree = (function() { | ||||
|                     data.result = loadSearchNote(noteId); | ||||
|                 } | ||||
|                 else { | ||||
|                     data.result = await prepareNoteTreeInner(note); | ||||
|                     data.result = await prepareBranchInner(note); | ||||
|                 } | ||||
|             }, | ||||
|             clones: { | ||||
| @@ -750,20 +744,20 @@ const noteTree = (function() { | ||||
|         const noteIds = await server.get('search/' + encodeURIComponent(json.searchString)); | ||||
|  | ||||
|         for (const noteId of noteIds) { | ||||
|             const noteTreeId = "virt" + randomString(10); | ||||
|             const branchId = "virt" + randomString(10); | ||||
|  | ||||
|             noteTreeMap[noteTreeId] = { | ||||
|                 noteTreeId: noteTreeId, | ||||
|             branchMap[branchId] = { | ||||
|                 branchId: branchId, | ||||
|                 noteId: noteId, | ||||
|                 parentNoteId: searchNoteId, | ||||
|                 prefix: '', | ||||
|                 virtual: true | ||||
|             }; | ||||
|  | ||||
|             setParentChildRelation(noteTreeId, searchNoteId, noteId); | ||||
|             setParentChildRelation(branchId, searchNoteId, noteId); | ||||
|         } | ||||
|  | ||||
|         return await prepareNoteTreeInner(searchNoteId); | ||||
|         return await prepareBranchInner(searchNoteId); | ||||
|     } | ||||
|  | ||||
|     function getTree() { | ||||
| @@ -790,10 +784,10 @@ const noteTree = (function() { | ||||
|             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) { | ||||
|         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)); | ||||
|     } | ||||
|  | ||||
|     function setProtected(noteId, isProtected) { | ||||
|         getNodesByNoteId(noteId).map(node => node.data.isProtected = isProtected); | ||||
|  | ||||
|         setNoteTreeBackgroundBasedOnProtectedStatus(noteId); | ||||
|         setBranchBackgroundBasedOnProtectedStatus(noteId); | ||||
|     } | ||||
|  | ||||
|     function getAutocompleteItems(parentNoteId, notePath, titlePath) { | ||||
| @@ -900,13 +894,13 @@ const noteTree = (function() { | ||||
|         const result = await server.post('notes/' + parentNoteId + '/children', { | ||||
|             title: newNoteName, | ||||
|             target: target, | ||||
|             target_noteTreeId: node.data.noteTreeId, | ||||
|             target_branchId: node.data.branchId, | ||||
|             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] = { | ||||
|             noteId: result.noteId, | ||||
| @@ -923,7 +917,7 @@ const noteTree = (function() { | ||||
|             noteId: result.noteId, | ||||
|             parentNoteId: parentNoteId, | ||||
|             refKey: result.noteId, | ||||
|             noteTreeId: result.noteTreeId, | ||||
|             branchId: result.branchId, | ||||
|             isProtected: isProtected, | ||||
|             extraClasses: getExtraClasses(result.note) | ||||
|         }; | ||||
| @@ -967,8 +961,8 @@ const noteTree = (function() { | ||||
|         return instanceName; | ||||
|     } | ||||
|  | ||||
|     function getNoteTree(noteTreeId) { | ||||
|         return noteTreeMap[noteTreeId]; | ||||
|     function getBranch(branchId) { | ||||
|         return branchMap[branchId]; | ||||
|     } | ||||
|  | ||||
|     $(document).bind('keydown', 'ctrl+o', e => { | ||||
| @@ -1031,7 +1025,7 @@ const noteTree = (function() { | ||||
|         reload, | ||||
|         collapseTree, | ||||
|         scrollToCurrentNote, | ||||
|         setNoteTreeBackgroundBasedOnProtectedStatus, | ||||
|         setBranchBackgroundBasedOnProtectedStatus, | ||||
|         setProtected, | ||||
|         getCurrentNode, | ||||
|         expandToNote, | ||||
| @@ -1051,7 +1045,7 @@ const noteTree = (function() { | ||||
|         sortAlphabetically, | ||||
|         noteExists, | ||||
|         getInstanceName, | ||||
|         getNoteTree, | ||||
|         getBranch, | ||||
|         getNote | ||||
|     }; | ||||
| })(); | ||||
| @@ -91,7 +91,7 @@ const noteType = (function() { | ||||
|             await noteEditor.reload(); | ||||
|  | ||||
|             // for the note icon to be updated in the tree | ||||
|             await noteTree.reload(); | ||||
|             await treeService.reload(); | ||||
|  | ||||
|             self.updateExecuteScriptButtonVisibility(); | ||||
|         } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ const protected_session = (function() { | ||||
|         if (requireProtectedSession && !isProtectedSessionAvailable()) { | ||||
|             protectedSessionDeferred = dfd; | ||||
|  | ||||
|             if (noteTree.getCurrentNode().data.isProtected) { | ||||
|             if (treeService.getCurrentNode().data.isProtected) { | ||||
|                 $noteDetailWrapper.hide(); | ||||
|             } | ||||
|  | ||||
| @@ -37,7 +37,7 @@ const protected_session = (function() { | ||||
|                 open: () => { | ||||
|                     if (!modal) { | ||||
|                         // 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"); | ||||
|  | ||||
|         noteEditor.reload(); | ||||
|         noteTree.reload(); | ||||
|         treeService.reload(); | ||||
|  | ||||
|         if (protectedSessionDeferred !== null) { | ||||
|             ensureDialogIsClosed($dialog, $password); | ||||
| @@ -121,7 +121,7 @@ const protected_session = (function() { | ||||
|  | ||||
|         await noteEditor.saveNoteToServer(note); | ||||
|  | ||||
|         noteTree.setProtected(note.detail.noteId, note.detail.isProtected); | ||||
|         treeService.setProtected(note.detail.noteId, note.detail.isProtected); | ||||
|  | ||||
|         noteEditor.setNoteBackgroundIfProtected(note); | ||||
|     } | ||||
| @@ -137,7 +137,7 @@ const protected_session = (function() { | ||||
|  | ||||
|         await noteEditor.saveNoteToServer(note); | ||||
|  | ||||
|         noteTree.setProtected(note.detail.noteId, note.detail.isProtected); | ||||
|         treeService.setProtected(note.detail.noteId, note.detail.isProtected); | ||||
|  | ||||
|         noteEditor.setNoteBackgroundIfProtected(note); | ||||
|     } | ||||
| @@ -155,7 +155,7 @@ const protected_session = (function() { | ||||
|  | ||||
|         showMessage("Request to un/protect sub tree has finished successfully"); | ||||
|  | ||||
|         noteTree.reload(); | ||||
|         treeService.reload(); | ||||
|         noteEditor.reload(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -35,7 +35,7 @@ async function doSearch() { | ||||
|     const noteIds = await server.get('search/' + encodeURIComponent(searchText)); | ||||
|  | ||||
|     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 | ||||
| @@ -45,9 +45,9 @@ async function doSearch() { | ||||
| async function saveSearch() { | ||||
|     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 => { | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| const treeChanges = (function() { | ||||
|     async function moveBeforeNode(nodesToMove, beforeNode) { | ||||
|         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) { | ||||
|                 alert(resp.message); | ||||
| @@ -18,7 +18,7 @@ const treeChanges = (function() { | ||||
|         nodesToMove.reverse(); // need to reverse to keep the note order | ||||
|  | ||||
|         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) { | ||||
|                 alert(resp.message); | ||||
| @@ -31,7 +31,7 @@ const treeChanges = (function() { | ||||
|  | ||||
|     async function moveToNode(nodesToMove, toNode) { | ||||
|         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) { | ||||
|                 alert(resp.message); | ||||
| @@ -61,7 +61,7 @@ const treeChanges = (function() { | ||||
|         } | ||||
|  | ||||
|         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 | ||||
| @@ -80,10 +80,10 @@ const treeChanges = (function() { | ||||
|             // activate next element after this one is deleted so we don't lose focus | ||||
|             next.setActive(); | ||||
|  | ||||
|             noteTree.setCurrentNotePathToHash(next); | ||||
|             treeService.setCurrentNotePathToHash(next); | ||||
|         } | ||||
|  | ||||
|         noteTree.reload(); | ||||
|         treeService.reload(); | ||||
|  | ||||
|         showMessage("Note(s) has been deleted."); | ||||
|     } | ||||
| @@ -93,7 +93,7 @@ const treeChanges = (function() { | ||||
|             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) { | ||||
|             alert(resp.message); | ||||
| @@ -111,15 +111,15 @@ const treeChanges = (function() { | ||||
|     function changeNode(node, func) { | ||||
|         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); | ||||
|  | ||||
|         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 { | ||||
|   | ||||
							
								
								
									
										2
									
								
								src/public/libraries/ckeditor/ckeditor.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/public/libraries/ckeditor/ckeditor.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -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 note_tree WHERE isDeleted = 1"); | ||||
|         await sql.execute("DELETE FROM branches 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 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("recent_notes", "noteTreeId"); | ||||
|         await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "branchId"); | ||||
|  | ||||
|         log.info("Following notes has been completely cleaned from database: " + noteIdsSql); | ||||
|     }); | ||||
|   | ||||
| @@ -19,12 +19,12 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async | ||||
|         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; | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         const noteTree = { | ||||
|             noteTreeId: utils.newNoteTreeId(), | ||||
|         const branch = { | ||||
|             branchId: utils.newBranchId(), | ||||
|             noteId: childNoteId, | ||||
|             parentNoteId: parentNoteId, | ||||
|             prefix: prefix, | ||||
| @@ -34,22 +34,22 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async | ||||
|             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 }); | ||||
| })); | ||||
|  | ||||
| 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 afterNoteTreeId = req.params.afterNoteTreeId; | ||||
|     const afterBranchId = req.params.afterBranchId; | ||||
|     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)) { | ||||
|         return; | ||||
| @@ -58,13 +58,13 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(asyn | ||||
|     await sql.doInTransaction(async () => { | ||||
|         // 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 | ||||
|         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]); | ||||
|  | ||||
|         await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId); | ||||
|  | ||||
|         const noteTree = { | ||||
|             noteTreeId: utils.newNoteTreeId(), | ||||
|         const branch = { | ||||
|             branchId: utils.newBranchId(), | ||||
|             noteId: noteId, | ||||
|             parentNoteId: afterNote.parentNoteId, | ||||
|             notePosition: afterNote.notePosition + 1, | ||||
| @@ -73,9 +73,9 @@ router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(asyn | ||||
|             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 }); | ||||
|   | ||||
| @@ -14,11 +14,11 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next) | ||||
|     const noteId = req.params.noteId; | ||||
|     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 name = await exportNote(noteTreeId, '', pack, repo); | ||||
|     const name = await exportNote(branchId, '', pack, repo); | ||||
|  | ||||
|     pack.finalize(); | ||||
|  | ||||
| @@ -28,9 +28,9 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next) | ||||
|     pack.pipe(res); | ||||
| })); | ||||
|  | ||||
| async function exportNote(noteTreeId, directory, pack, repo) { | ||||
|     const noteTree = await sql.getRow("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); | ||||
|     const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [noteTree.noteId]); | ||||
| async function exportNote(branchId, directory, pack, repo) { | ||||
|     const branch = await sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]); | ||||
|     const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [branch.noteId]); | ||||
|  | ||||
|     if (note.isProtected) { | ||||
|         return; | ||||
| @@ -51,11 +51,11 @@ async function exportNote(noteTreeId, directory, pack, repo) { | ||||
|  | ||||
|     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) { | ||||
|         for (const child of children) { | ||||
|             await exportNote(child.noteTreeId, childFileName + "/", pack, repo); | ||||
|             await exportNote(child.branchId, childFileName + "/", pack, repo); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -48,11 +48,11 @@ router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res, | ||||
|     const newNote = req.body; | ||||
|  | ||||
|     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({ | ||||
|             'noteId': noteId, | ||||
|             'noteTreeId': noteTreeId, | ||||
|             'branchId': branchId, | ||||
|             'note': note | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -13,20 +13,20 @@ router.get('', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     res.send(await getRecentNotes()); | ||||
| })); | ||||
|  | ||||
| router.put('/:noteTreeId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.put('/:branchId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const notePath = req.params.notePath; | ||||
|     const sourceId = req.headers.source_id; | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sql.replace('recent_notes', { | ||||
|             noteTreeId: noteTreeId, | ||||
|             branchId: branchId, | ||||
|             notePath: notePath, | ||||
|             dateAccessed: utils.nowDate(), | ||||
|             isDeleted: 0 | ||||
|         }); | ||||
|  | ||||
|         await sync_table.addRecentNoteSync(noteTreeId, sourceId); | ||||
|         await sync_table.addRecentNoteSync(branchId, sourceId); | ||||
|  | ||||
|         await options.setOption('start_note_path', notePath, sourceId); | ||||
|     }); | ||||
| @@ -40,10 +40,10 @@ async function getRecentNotes() { | ||||
|         recent_notes.*  | ||||
|       FROM  | ||||
|         recent_notes | ||||
|         JOIN note_tree USING(noteTreeId) | ||||
|         JOIN branches USING(branchId) | ||||
|       WHERE | ||||
|         recent_notes.isDeleted = 0 | ||||
|         AND note_tree.isDeleted = 0 | ||||
|         AND branches.isDeleted = 0 | ||||
|       ORDER BY  | ||||
|         dateAccessed DESC | ||||
|       LIMIT 200`); | ||||
|   | ||||
| @@ -53,9 +53,9 @@ router.post('/force-note-sync/:noteId', auth.checkApiAuth, wrap(async (req, res, | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sync_table.addNoteSync(noteId); | ||||
|  | ||||
|         for (const noteTreeId of await sql.getColumn("SELECT noteTreeId FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [noteId])) { | ||||
|             await sync_table.addNoteTreeSync(noteTreeId); | ||||
|             await sync_table.addRecentNoteSync(noteTreeId); | ||||
|         for (const branchId of await sql.getColumn("SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ?", [noteId])) { | ||||
|             await sync_table.addBranchSync(branchId); | ||||
|             await sync_table.addRecentNoteSync(branchId); | ||||
|         } | ||||
|  | ||||
|         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) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.get('/branches/:branchId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     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) => { | ||||
| @@ -117,14 +117,14 @@ router.get('/note_reordering/:parentNoteId', auth.checkApiAuth, wrap(async (req, | ||||
|  | ||||
|     res.send({ | ||||
|         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) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.get('/recent_notes/:branchId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     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) => { | ||||
| @@ -162,8 +162,8 @@ router.put('/notes', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     res.send({}); | ||||
| })); | ||||
|  | ||||
| router.put('/note_tree', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     await syncUpdate.updateNoteTree(req.body.entity, req.body.sourceId); | ||||
| router.put('/branches', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     await syncUpdate.updateBranch(req.body.entity, req.body.sourceId); | ||||
|  | ||||
|     res.send({}); | ||||
| })); | ||||
|   | ||||
| @@ -12,16 +12,16 @@ const sync_table = require('../../services/sync_table'); | ||||
| const wrap = require('express-promise-wrap').wrap; | ||||
|  | ||||
| router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTree = await sql.getRows(` | ||||
|     const branches = await sql.getRows(` | ||||
|       SELECT  | ||||
|         noteTreeId, | ||||
|         branchId, | ||||
|         noteId, | ||||
|         parentNoteId, | ||||
|         notePosition, | ||||
|         prefix, | ||||
|         isExpanded | ||||
|       FROM | ||||
|         note_tree  | ||||
|         branches  | ||||
|       WHERE  | ||||
|         isDeleted = 0 | ||||
|       ORDER BY  | ||||
| @@ -60,21 +60,21 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|  | ||||
|     res.send({ | ||||
|         instanceName: config.General ? config.General.instanceName : null, | ||||
|         noteTree: noteTree, | ||||
|         branches: branches, | ||||
|         notes: notes, | ||||
|         start_note_path: await options.getOption('start_note_path') | ||||
|     }); | ||||
| })); | ||||
|  | ||||
| router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.put('/:branchId/set-prefix', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const sourceId = req.headers.source_id; | ||||
|     const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix; | ||||
|  | ||||
|     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({}); | ||||
|   | ||||
| @@ -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. | ||||
|  */ | ||||
|  | ||||
| router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.put('/:branchId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const parentNoteId = req.params.parentNoteId; | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     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 now = utils.nowDate(); | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", | ||||
|             [parentNoteId, newNotePos, now, noteTreeId]); | ||||
|         await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?", | ||||
|             [parentNoteId, newNotePos, now, branchId]); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||
|         await sync_table.addBranchSync(branchId, sourceId); | ||||
|     }); | ||||
|  | ||||
|     res.send({ success: true }); | ||||
| })); | ||||
|  | ||||
| router.put('/:noteTreeId/move-before/:beforeNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
|     const beforeNoteTreeId = req.params.beforeNoteTreeId; | ||||
| router.put('/:branchId/move-before/:beforeBranchId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const beforeBranchId = req.params.beforeBranchId; | ||||
|     const sourceId = req.headers.source_id; | ||||
|  | ||||
|     const noteToMove = await tree.getNoteTree(noteTreeId); | ||||
|     const beforeNote = await tree.getNoteTree(beforeNoteTreeId); | ||||
|     const noteToMove = await tree.getBranch(branchId); | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         // 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 | ||||
|         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]); | ||||
|  | ||||
|         await sync_table.addNoteReorderingSync(beforeNote.parentNoteId, sourceId); | ||||
|  | ||||
|         await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", | ||||
|             [beforeNote.parentNoteId, beforeNote.notePosition, utils.nowDate(), noteTreeId]); | ||||
|         await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?", | ||||
|             [beforeNote.parentNoteId, beforeNote.notePosition, utils.nowDate(), branchId]); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||
|         await sync_table.addBranchSync(branchId, sourceId); | ||||
|     }); | ||||
|  | ||||
|     res.send({ success: true }); | ||||
| })); | ||||
|  | ||||
| router.put('/:noteTreeId/move-after/:afterNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
|     const afterNoteTreeId = req.params.afterNoteTreeId; | ||||
| router.put('/:branchId/move-after/:afterBranchId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const afterBranchId = req.params.afterBranchId; | ||||
|     const sourceId = req.headers.source_id; | ||||
|  | ||||
|     const noteToMove = await tree.getNoteTree(noteTreeId); | ||||
|     const afterNote = await tree.getNoteTree(afterNoteTreeId); | ||||
|     const noteToMove = await tree.getBranch(branchId); | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         // 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 | ||||
|         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]); | ||||
|  | ||||
|         await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId); | ||||
|  | ||||
|         await sql.execute("UPDATE note_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?", | ||||
|             [afterNote.parentNoteId, afterNote.notePosition + 1, utils.nowDate(), noteTreeId]); | ||||
|         await sql.execute("UPDATE branches SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE branchId = ?", | ||||
|             [afterNote.parentNoteId, afterNote.notePosition + 1, utils.nowDate(), branchId]); | ||||
|  | ||||
|         await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||
|         await sync_table.addBranchSync(branchId, sourceId); | ||||
|     }); | ||||
|  | ||||
|     res.send({ success: true }); | ||||
| })); | ||||
|  | ||||
| router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const noteTreeId = req.params.noteTreeId; | ||||
| router.put('/:branchId/expanded/:expanded', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||
|     const branchId = req.params.branchId; | ||||
|     const expanded = req.params.expanded; | ||||
|  | ||||
|     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 | ||||
|     }); | ||||
| @@ -112,9 +112,9 @@ router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req | ||||
|     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 notes.deleteNote(req.params.noteTreeId, req.headers.source_id); | ||||
|         await notes.deleteNote(req.params.branchId, req.headers.source_id); | ||||
|     }); | ||||
|  | ||||
|     res.send({}); | ||||
|   | ||||
| @@ -18,7 +18,7 @@ async function anonymize() { | ||||
|  | ||||
|     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_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  | ||||
|                     ('document_secret', 'encrypted_data_key', 'password_verification_hash',  | ||||
|                      'password_verification_salt', 'password_derived_key_salt')`); | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| const build = require('./build'); | ||||
| const packageJson = require('../../package'); | ||||
|  | ||||
| const APP_DB_VERSION = 78; | ||||
| const APP_DB_VERSION = 79; | ||||
|  | ||||
| module.exports = { | ||||
|     app_version: packageJson.version, | ||||
|   | ||||
| @@ -23,7 +23,7 @@ async function runCheck(query, errorText, errorList) { | ||||
|  | ||||
| async function checkTreeCycles(errorList) { | ||||
|     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) { | ||||
|         const childNoteId = row.noteId; | ||||
| @@ -92,17 +92,17 @@ async function runAllChecks() { | ||||
|             noteId  | ||||
|           FROM  | ||||
|             notes  | ||||
|             LEFT JOIN note_tree USING(noteId)  | ||||
|             LEFT JOIN branches USING(noteId)  | ||||
|           WHERE  | ||||
|             noteId != 'root'  | ||||
|             AND note_tree.noteTreeId IS NULL`, | ||||
|         "Missing note_tree records for following note IDs", errorList); | ||||
|             AND branches.branchId IS NULL`, | ||||
|         "Missing branches records for following note IDs", errorList); | ||||
|  | ||||
|     await runCheck(` | ||||
|           SELECT  | ||||
|             noteTreeId || ' > ' || note_tree.noteId  | ||||
|             branchId || ' > ' || branches.noteId  | ||||
|           FROM  | ||||
|             note_tree  | ||||
|             branches  | ||||
|             LEFT JOIN notes USING(noteId)  | ||||
|           WHERE  | ||||
|             notes.noteId IS NULL`, | ||||
| @@ -110,24 +110,24 @@ async function runAllChecks() { | ||||
|  | ||||
|     await runCheck(` | ||||
|           SELECT  | ||||
|             noteTreeId  | ||||
|             branchId  | ||||
|           FROM  | ||||
|             note_tree  | ||||
|             branches  | ||||
|             JOIN notes USING(noteId)  | ||||
|           WHERE  | ||||
|             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); | ||||
|  | ||||
|     await runCheck(` | ||||
|           SELECT  | ||||
|             child.noteTreeId | ||||
|             child.branchId | ||||
|           FROM  | ||||
|             note_tree AS child | ||||
|             branches AS child | ||||
|           WHERE  | ||||
|             child.isDeleted = 0 | ||||
|             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`, | ||||
|         "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 | ||||
|           FROM | ||||
|             notes | ||||
|             JOIN note_tree USING(noteId) | ||||
|             JOIN branches USING(noteId) | ||||
|           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 | ||||
|     `, 'No undeleted note trees for note IDs', errorList); | ||||
|  | ||||
|     await runCheck(` | ||||
|           SELECT  | ||||
|             child.parentNoteId || ' > ' || child.noteId  | ||||
|           FROM note_tree  | ||||
|           FROM branches  | ||||
|             AS child  | ||||
|             LEFT JOIN note_tree AS parent ON parent.noteId = child.parentNoteId  | ||||
|             LEFT JOIN branches AS parent ON parent.noteId = child.parentNoteId  | ||||
|           WHERE  | ||||
|             parent.noteId IS NULL  | ||||
|             AND child.parentNoteId != 'root'`, | ||||
| @@ -165,14 +165,14 @@ async function runAllChecks() { | ||||
|  | ||||
|     await runCheck(` | ||||
|           SELECT  | ||||
|             note_tree.parentNoteId || ' > ' || note_tree.noteId  | ||||
|             branches.parentNoteId || ' > ' || branches.noteId  | ||||
|           FROM  | ||||
|             note_tree  | ||||
|             branches  | ||||
|           WHERE  | ||||
|             note_tree.isDeleted = 0 | ||||
|             branches.isDeleted = 0 | ||||
|           GROUP BY  | ||||
|             note_tree.parentNoteId, | ||||
|             note_tree.noteId | ||||
|             branches.parentNoteId, | ||||
|             branches.noteId | ||||
|           HAVING  | ||||
|             COUNT(*) > 1`, | ||||
|         "Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList); | ||||
| @@ -221,16 +221,16 @@ async function runAllChecks() { | ||||
|           SELECT  | ||||
|             parentNoteId | ||||
|           FROM  | ||||
|             note_tree | ||||
|             JOIN notes ON notes.noteId = note_tree.parentNoteId | ||||
|             branches | ||||
|             JOIN notes ON notes.noteId = branches.parentNoteId | ||||
|           WHERE  | ||||
|             type == 'search'`, | ||||
|         "Search note has children", errorList); | ||||
|  | ||||
|     await runSyncRowChecks("notes", "noteId", errorList); | ||||
|     await runSyncRowChecks("note_revisions", "noteRevisionId", errorList); | ||||
|     await runSyncRowChecks("note_tree", "noteTreeId", errorList); | ||||
|     await runSyncRowChecks("recent_notes", "noteTreeId", errorList); | ||||
|     await runSyncRowChecks("branches", "branchId", errorList); | ||||
|     await runSyncRowChecks("recent_notes", "branchId", errorList); | ||||
|     await runSyncRowChecks("images", "imageId", errorList); | ||||
|     await runSyncRowChecks("note_images", "noteImageId", errorList); | ||||
|     await runSyncRowChecks("attributes", "attributeId", errorList); | ||||
|   | ||||
| @@ -29,17 +29,17 @@ async function getHashes() { | ||||
|             FROM notes | ||||
|             ORDER BY noteId`)), | ||||
|  | ||||
|         note_tree: getHash(await sql.getRows(` | ||||
|         branches: getHash(await sql.getRows(` | ||||
|             SELECT | ||||
|                noteTreeId, | ||||
|                branchId, | ||||
|                noteId, | ||||
|                parentNoteId, | ||||
|                notePosition, | ||||
|                dateModified, | ||||
|                isDeleted, | ||||
|                prefix | ||||
|              FROM note_tree | ||||
|              ORDER BY noteTreeId`)), | ||||
|              FROM branches | ||||
|              ORDER BY branchId`)), | ||||
|  | ||||
|         note_revisions: getHash(await sql.getRows(` | ||||
|             SELECT | ||||
| @@ -54,7 +54,7 @@ async function getHashes() { | ||||
|  | ||||
|         recent_notes: getHash(await sql.getRows(` | ||||
|            SELECT | ||||
|              noteTreeId, | ||||
|              branchId, | ||||
|              notePath, | ||||
|              dateAccessed, | ||||
|              isDeleted | ||||
|   | ||||
| @@ -23,10 +23,10 @@ async function createNote(parentNoteId, noteTitle, noteText) { | ||||
| } | ||||
|  | ||||
| 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}%' | ||||
|                                     AND notes.isDeleted = 0 AND isProtected = 0  | ||||
|                                     AND note_tree.isDeleted = 0`, [parentNoteId]); | ||||
|                                     AND branches.isDeleted = 0`, [parentNoteId]); | ||||
| } | ||||
|  | ||||
| async function getRootCalendarNoteId() { | ||||
|   | ||||
| @@ -7,22 +7,22 @@ const protected_session = require('./protected_session'); | ||||
|  | ||||
| async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) { | ||||
|     const noteId = utils.newNoteId(); | ||||
|     const noteTreeId = utils.newNoteTreeId(); | ||||
|     const branchId = utils.newBranchId(); | ||||
|  | ||||
|     let newNotePos = 0; | ||||
|  | ||||
|     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; | ||||
|     } | ||||
|     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; | ||||
|  | ||||
|         // 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]); | ||||
|  | ||||
|         await sync_table.addNoteReorderingSync(parentNoteId, sourceId); | ||||
| @@ -64,8 +64,8 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) { | ||||
|  | ||||
|     await sync_table.addNoteSync(noteId, sourceId); | ||||
|  | ||||
|     await sql.insert("note_tree", { | ||||
|         noteTreeId: noteTreeId, | ||||
|     await sql.insert("branches", { | ||||
|         branchId: branchId, | ||||
|         noteId: noteId, | ||||
|         parentNoteId: parentNoteId, | ||||
|         notePosition: newNotePos, | ||||
| @@ -74,11 +74,11 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) { | ||||
|         isDeleted: 0 | ||||
|     }); | ||||
|  | ||||
|     await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||
|     await sync_table.addBranchSync(branchId, sourceId); | ||||
|  | ||||
|     return { | ||||
|         noteId, | ||||
|         noteTreeId, | ||||
|         branchId, | ||||
|         note | ||||
|     }; | ||||
| } | ||||
| @@ -122,7 +122,7 @@ async function protectNoteRecursively(noteId, 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) { | ||||
|         await protectNoteRecursively(childNoteId, dataKey, protect, sourceId); | ||||
| @@ -311,30 +311,30 @@ async function updateNote(noteId, newNote, dataKey, sourceId) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function deleteNote(noteTreeId, sourceId) { | ||||
|     const noteTree = await sql.getRowOrNull("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); | ||||
| async function deleteNote(branchId, sourceId) { | ||||
|     const branch = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [branchId]); | ||||
|  | ||||
|     if (!noteTree || noteTree.isDeleted === 1) { | ||||
|     if (!branch || branch.isDeleted === 1) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const now = utils.nowDate(); | ||||
|  | ||||
|     await sql.execute("UPDATE note_tree SET isDeleted = 1, dateModified = ? WHERE noteTreeId = ?", [now, noteTreeId]); | ||||
|     await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||
|     await sql.execute("UPDATE branches SET isDeleted = 1, dateModified = ? WHERE branchId = ?", [now, branchId]); | ||||
|     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 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) { | ||||
|             await deleteNote(child.noteTreeId, sourceId); | ||||
|             await deleteNote(child.branchId, sourceId); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ const sql = require('./sql'); | ||||
| const protected_session = require('./protected_session'); | ||||
| const Note = require('../entities/note'); | ||||
| const NoteRevision = require('../entities/note_revision'); | ||||
| const NoteTree = require('../entities/note_tree'); | ||||
| const Branch = require('../entities/branch'); | ||||
| const Attribute = require('../entities/attribute'); | ||||
| const sync_table = require('../services/sync_table'); | ||||
|  | ||||
| @@ -46,8 +46,8 @@ class Repository { | ||||
|         else if (row.noteRevisionId) { | ||||
|             entity = new NoteRevision(this, row); | ||||
|         } | ||||
|         else if (row.noteTreeId) { | ||||
|             entity = new NoteTree(this, row); | ||||
|         else if (row.branchId) { | ||||
|             entity = new Branch(this, row); | ||||
|         } | ||||
|         else if (row.noteId) { | ||||
|             entity = new Note(this, row); | ||||
|   | ||||
| @@ -30,7 +30,7 @@ const dbReady = new Promise((resolve, reject) => { | ||||
|  | ||||
|             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 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 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(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('./sync_table').fillAllSyncRows(); | ||||
|   | ||||
| @@ -125,8 +125,8 @@ async function pullSync(syncContext) { | ||||
|         else if (sync.entityName === 'notes') { | ||||
|             await syncUpdate.updateNote(resp.entity, syncContext.sourceId); | ||||
|         } | ||||
|         else if (sync.entityName === 'note_tree') { | ||||
|             await syncUpdate.updateNoteTree(resp, syncContext.sourceId); | ||||
|         else if (sync.entityName === 'branches') { | ||||
|             await syncUpdate.updateBranch(resp, syncContext.sourceId); | ||||
|         } | ||||
|         else if (sync.entityName === 'note_revisions') { | ||||
|             await syncUpdate.updateNoteHistory(resp, syncContext.sourceId); | ||||
| @@ -207,8 +207,8 @@ async function pushEntity(sync, syncContext) { | ||||
|  | ||||
|         serializeNoteContentBuffer(entity); | ||||
|     } | ||||
|     else if (sync.entityName === 'note_tree') { | ||||
|         entity = await sql.getRow('SELECT * FROM note_tree WHERE noteTreeId = ?', [sync.entityId]); | ||||
|     else if (sync.entityName === 'branches') { | ||||
|         entity = await sql.getRow('SELECT * FROM branches WHERE branchId = ?', [sync.entityId]); | ||||
|     } | ||||
|     else if (sync.entityName === 'note_revisions') { | ||||
|         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') { | ||||
|         entity = { | ||||
|             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') { | ||||
|         entity = await sql.getRow('SELECT * FROM options WHERE name = ?', [sync.entityId]); | ||||
|     } | ||||
|     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') { | ||||
|         entity = await sql.getRow('SELECT * FROM images WHERE imageId = ?', [sync.entityId]); | ||||
|   | ||||
| @@ -8,8 +8,8 @@ async function addNoteSync(noteId, sourceId) { | ||||
|     await addEntitySync("notes", noteId, sourceId) | ||||
| } | ||||
|  | ||||
| async function addNoteTreeSync(noteTreeId, sourceId) { | ||||
|     await addEntitySync("note_tree", noteTreeId, sourceId) | ||||
| async function addBranchSync(branchId, sourceId) { | ||||
|     await addEntitySync("branches", branchId, sourceId) | ||||
| } | ||||
|  | ||||
| async function addNoteReorderingSync(parentNoteId, sourceId) { | ||||
| @@ -24,8 +24,8 @@ async function addOptionsSync(name, sourceId) { | ||||
|     await addEntitySync("options", name, sourceId); | ||||
| } | ||||
|  | ||||
| async function addRecentNoteSync(noteTreeId, sourceId) { | ||||
|     await addEntitySync("recent_notes", noteTreeId, sourceId); | ||||
| async function addRecentNoteSync(branchId, sourceId) { | ||||
|     await addEntitySync("recent_notes", branchId, sourceId); | ||||
| } | ||||
|  | ||||
| async function addImageSync(imageId, sourceId) { | ||||
| @@ -91,9 +91,9 @@ async function fillSyncRows(entityName, entityKey) { | ||||
|  | ||||
| async function fillAllSyncRows() { | ||||
|     await fillSyncRows("notes", "noteId"); | ||||
|     await fillSyncRows("note_tree", "noteTreeId"); | ||||
|     await fillSyncRows("branches", "branchId"); | ||||
|     await fillSyncRows("note_revisions", "noteRevisionId"); | ||||
|     await fillSyncRows("recent_notes", "noteTreeId"); | ||||
|     await fillSyncRows("recent_notes", "branchId"); | ||||
|     await fillSyncRows("images", "imageId"); | ||||
|     await fillSyncRows("note_images", "noteImageId"); | ||||
|     await fillSyncRows("attributes", "attributeId"); | ||||
| @@ -102,7 +102,7 @@ async function fillAllSyncRows() { | ||||
|  | ||||
| module.exports = { | ||||
|     addNoteSync, | ||||
|     addNoteTreeSync, | ||||
|     addBranchSync, | ||||
|     addNoteReorderingSync, | ||||
|     addNoteHistorySync, | ||||
|     addOptionsSync, | ||||
|   | ||||
| @@ -26,18 +26,18 @@ async function updateNote(entity, sourceId) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function updateNoteTree(entity, sourceId) { | ||||
|     const orig = await sql.getRowOrNull("SELECT * FROM note_tree WHERE noteTreeId = ?", [entity.noteTreeId]); | ||||
| async function updateBranch(entity, sourceId) { | ||||
|     const orig = await sql.getRowOrNull("SELECT * FROM branches WHERE branchId = ?", [entity.branchId]); | ||||
|  | ||||
|     await sql.doInTransaction(async () => { | ||||
|         if (orig === null || orig.dateModified < entity.dateModified) { | ||||
|             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) { | ||||
|     await sql.doInTransaction(async () => { | ||||
|         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); | ||||
| @@ -87,13 +87,13 @@ async function updateOptions(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) { | ||||
|         await sql.doInTransaction(async () => { | ||||
|             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 = { | ||||
|     updateNote, | ||||
|     updateNoteTree, | ||||
|     updateBranch, | ||||
|     updateNoteHistory, | ||||
|     updateNoteReordering, | ||||
|     updateOptions, | ||||
|   | ||||
| @@ -4,10 +4,10 @@ const sql = require('./sql'); | ||||
| const sync_table = require('./sync_table'); | ||||
| const protected_session = require('./protected_session'); | ||||
|  | ||||
| async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId = null) { | ||||
|     const existing = await getExistingNoteTree(parentNoteId, childNoteId); | ||||
| async function validateParentChild(res, parentNoteId, childNoteId, branchId = null) { | ||||
|     const existing = await getExistingBranch(parentNoteId, childNoteId); | ||||
|  | ||||
|     if (existing && (noteTreeId === null || existing.noteTreeId !== noteTreeId)) { | ||||
|     if (existing && (branchId === null || existing.branchId !== branchId)) { | ||||
|         res.send({ | ||||
|             success: false, | ||||
|             message: 'This note already exists in the target.' | ||||
| @@ -28,8 +28,8 @@ async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId = | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| async function getExistingNoteTree(parentNoteId, childNoteId) { | ||||
|     return await sql.getRow('SELECT * FROM note_tree WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0', [childNoteId, parentNoteId]); | ||||
| async function getExistingBranch(parentNoteId, childNoteId) { | ||||
|     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; | ||||
|         } | ||||
|  | ||||
|         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) { | ||||
|             if (!await checkTreeCycleInner(pid)) { | ||||
| @@ -66,14 +66,14 @@ async function checkTreeCycle(parentNoteId, childNoteId) { | ||||
|     return await checkTreeCycleInner(parentNoteId); | ||||
| } | ||||
|  | ||||
| async function getNoteTree(noteTreeId) { | ||||
|     return sql.getRow("SELECT * FROM note_tree WHERE noteTreeId = ?", [noteTreeId]); | ||||
| async function getBranch(branchId) { | ||||
|     return sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]); | ||||
| } | ||||
|  | ||||
| async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) { | ||||
|     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) { | ||||
|         await loadSubTreeNoteIds(childNoteId, subTreeNoteIds); | ||||
| @@ -82,9 +82,9 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) { | ||||
|  | ||||
| async function sortNotesAlphabetically(parentNoteId, req, sourceId) { | ||||
|     await sql.doInTransaction(async () => { | ||||
|         const notes = await sql.getRows(`SELECT noteTreeId, noteId, title, isProtected  | ||||
|                                        FROM notes JOIN note_tree USING(noteId)  | ||||
|                                        WHERE note_tree.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]); | ||||
|         const notes = await sql.getRows(`SELECT branchId, noteId, title, isProtected  | ||||
|                                        FROM notes JOIN branches USING(noteId)  | ||||
|                                        WHERE branches.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]); | ||||
|  | ||||
|         protected_session.decryptNotes(req, notes); | ||||
|  | ||||
| @@ -93,8 +93,8 @@ async function sortNotesAlphabetically(parentNoteId, req, sourceId) { | ||||
|         let position = 1; | ||||
|  | ||||
|         for (const note of notes) { | ||||
|             await sql.execute("UPDATE note_tree SET notePosition = ? WHERE noteTreeId = ?", | ||||
|                 [position, note.noteTreeId]); | ||||
|             await sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", | ||||
|                 [position, note.branchId]); | ||||
|  | ||||
|             position++; | ||||
|         } | ||||
| @@ -105,6 +105,6 @@ async function sortNotesAlphabetically(parentNoteId, req, sourceId) { | ||||
|  | ||||
| module.exports = { | ||||
|     validateParentChild, | ||||
|     getNoteTree, | ||||
|     getBranch, | ||||
|     sortNotesAlphabetically | ||||
| }; | ||||
| @@ -8,7 +8,7 @@ function newNoteId() { | ||||
|     return randomString(12); | ||||
| } | ||||
|  | ||||
| function newNoteTreeId() { | ||||
| function newBranchId() { | ||||
|     return randomString(12); | ||||
| } | ||||
|  | ||||
| @@ -155,7 +155,7 @@ module.exports = { | ||||
|     parseDate, | ||||
|     parseDateTime, | ||||
|     newNoteId, | ||||
|     newNoteTreeId, | ||||
|     newBranchId, | ||||
|     newNoteRevisionId, | ||||
|     newImageId, | ||||
|     newNoteImageId, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user