mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	erasing note revisions
This commit is contained in:
		| @@ -309,359 +309,365 @@ parentNoteId</ColNames> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="74" parent="11" name="isProtected"> | ||||
|     <column id="74" parent="11" name="isErased"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="75" parent="11" name="utcDateLastEdited"> | ||||
|     <column id="75" parent="11" name="isProtected"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="76" parent="11" name="utcDateCreated"> | ||||
|     <column id="76" parent="11" name="utcDateLastEdited"> | ||||
|       <Position>7</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="77" parent="11" name="utcDateModified"> | ||||
|     <column id="77" parent="11" name="utcDateCreated"> | ||||
|       <Position>8</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="78" parent="11" name="dateLastEdited"> | ||||
|     <column id="78" parent="11" name="utcDateModified"> | ||||
|       <Position>9</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="79" parent="11" name="dateCreated"> | ||||
|     <column id="79" parent="11" name="dateLastEdited"> | ||||
|       <Position>10</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="80" parent="11" name="type"> | ||||
|     <column id="80" parent="11" name="dateCreated"> | ||||
|       <Position>11</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>''</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="81" parent="11" name="mime"> | ||||
|     <column id="81" parent="11" name="type"> | ||||
|       <Position>12</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>''</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="82" parent="11" name="hash"> | ||||
|     <column id="82" parent="11" name="mime"> | ||||
|       <Position>13</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>''</DefaultExpression> | ||||
|     </column> | ||||
|     <index id="83" parent="11" name="sqlite_autoindex_note_revisions_1"> | ||||
|     <column id="83" parent="11" name="hash"> | ||||
|       <Position>14</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>''</DefaultExpression> | ||||
|     </column> | ||||
|     <index id="84" parent="11" name="sqlite_autoindex_note_revisions_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>noteRevisionId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <index id="84" parent="11" name="IDX_note_revisions_noteId"> | ||||
|     <index id="85" parent="11" name="IDX_note_revisions_noteId"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="85" parent="11" name="IDX_note_revisions_utcDateLastEdited"> | ||||
|     <index id="86" parent="11" name="IDX_note_revisions_utcDateLastEdited"> | ||||
|       <ColNames>utcDateLastEdited</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="86" parent="11" name="IDX_note_revisions_utcDateCreated"> | ||||
|     <index id="87" parent="11" name="IDX_note_revisions_utcDateCreated"> | ||||
|       <ColNames>utcDateCreated</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="87" parent="11" name="IDX_note_revisions_dateLastEdited"> | ||||
|     <index id="88" parent="11" name="IDX_note_revisions_dateLastEdited"> | ||||
|       <ColNames>dateLastEdited</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="88" parent="11" name="IDX_note_revisions_dateCreated"> | ||||
|     <index id="89" parent="11" name="IDX_note_revisions_dateCreated"> | ||||
|       <ColNames>dateCreated</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <key id="89" parent="11"> | ||||
|     <key id="90" parent="11"> | ||||
|       <ColNames>noteRevisionId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="90" parent="12" name="noteId"> | ||||
|     <column id="91" parent="12" name="noteId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="91" parent="12" name="title"> | ||||
|     <column id="92" parent="12" name="title"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>"note"</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="92" parent="12" name="contentLength"> | ||||
|     <column id="93" parent="12" name="contentLength"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="93" parent="12" name="isProtected"> | ||||
|     <column id="94" parent="12" name="isProtected"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="94" parent="12" name="type"> | ||||
|     <column id="95" parent="12" name="type"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>'text'</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="95" parent="12" name="mime"> | ||||
|     <column id="96" parent="12" name="mime"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>'text/html'</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="96" parent="12" name="hash"> | ||||
|     <column id="97" parent="12" name="hash"> | ||||
|       <Position>7</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>""</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="97" parent="12" name="isDeleted"> | ||||
|     <column id="98" parent="12" name="isDeleted"> | ||||
|       <Position>8</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="98" parent="12" name="isErased"> | ||||
|     <column id="99" parent="12" name="isErased"> | ||||
|       <Position>9</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="99" parent="12" name="dateCreated"> | ||||
|     <column id="100" parent="12" name="dateCreated"> | ||||
|       <Position>10</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="100" parent="12" name="dateModified"> | ||||
|     <column id="101" parent="12" name="dateModified"> | ||||
|       <Position>11</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="101" parent="12" name="utcDateCreated"> | ||||
|     <column id="102" parent="12" name="utcDateCreated"> | ||||
|       <Position>12</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="102" parent="12" name="utcDateModified"> | ||||
|     <column id="103" parent="12" name="utcDateModified"> | ||||
|       <Position>13</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <index id="103" parent="12" name="sqlite_autoindex_notes_1"> | ||||
|     <index id="104" parent="12" name="sqlite_autoindex_notes_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <index id="104" parent="12" name="IDX_notes_title"> | ||||
|     <index id="105" parent="12" name="IDX_notes_title"> | ||||
|       <ColNames>title</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="105" parent="12" name="IDX_notes_type"> | ||||
|     <index id="106" parent="12" name="IDX_notes_type"> | ||||
|       <ColNames>type</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="106" parent="12" name="IDX_notes_isDeleted"> | ||||
|     <index id="107" parent="12" name="IDX_notes_isDeleted"> | ||||
|       <ColNames>isDeleted</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="107" parent="12" name="IDX_notes_dateCreated"> | ||||
|     <index id="108" parent="12" name="IDX_notes_dateCreated"> | ||||
|       <ColNames>dateCreated</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="108" parent="12" name="IDX_notes_dateModified"> | ||||
|     <index id="109" parent="12" name="IDX_notes_dateModified"> | ||||
|       <ColNames>dateModified</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="109" parent="12" name="IDX_notes_utcDateCreated"> | ||||
|     <index id="110" parent="12" name="IDX_notes_utcDateCreated"> | ||||
|       <ColNames>utcDateCreated</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <index id="110" parent="12" name="IDX_notes_utcDateModified"> | ||||
|     <index id="111" parent="12" name="IDX_notes_utcDateModified"> | ||||
|       <ColNames>utcDateModified</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <key id="111" parent="12"> | ||||
|     <key id="112" parent="12"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_notes_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="112" parent="13" name="name"> | ||||
|     <column id="113" parent="13" name="name"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="113" parent="13" name="value"> | ||||
|     <column id="114" parent="13" name="value"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|     </column> | ||||
|     <column id="114" parent="13" name="isSynced"> | ||||
|     <column id="115" parent="13" name="isSynced"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>INTEGER|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>0</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="115" parent="13" name="hash"> | ||||
|     <column id="116" parent="13" name="hash"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>""</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="116" parent="13" name="utcDateCreated"> | ||||
|     <column id="117" parent="13" name="utcDateCreated"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="117" parent="13" name="utcDateModified"> | ||||
|     <column id="118" parent="13" name="utcDateModified"> | ||||
|       <Position>6</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <index id="118" parent="13" name="sqlite_autoindex_options_1"> | ||||
|     <index id="119" parent="13" name="sqlite_autoindex_options_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>name</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <key id="119" parent="13"> | ||||
|     <key id="120" parent="13"> | ||||
|       <ColNames>name</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="120" parent="14" name="noteId"> | ||||
|     <column id="121" parent="14" name="noteId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="121" parent="14" name="notePath"> | ||||
|     <column id="122" parent="14" name="notePath"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="122" parent="14" name="hash"> | ||||
|     <column id="123" parent="14" name="hash"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <DefaultExpression>""</DefaultExpression> | ||||
|     </column> | ||||
|     <column id="123" parent="14" name="utcDateCreated"> | ||||
|     <column id="124" parent="14" name="utcDateCreated"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="124" parent="14" name="isDeleted"> | ||||
|     <column id="125" parent="14" name="isDeleted"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>INT|0s</DataType> | ||||
|     </column> | ||||
|     <index id="125" parent="14" name="sqlite_autoindex_recent_notes_1"> | ||||
|     <index id="126" parent="14" name="sqlite_autoindex_recent_notes_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <key id="126" parent="14"> | ||||
|     <key id="127" parent="14"> | ||||
|       <ColNames>noteId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="127" parent="15" name="sourceId"> | ||||
|     <column id="128" parent="15" name="sourceId"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="128" parent="15" name="utcDateCreated"> | ||||
|     <column id="129" parent="15" name="utcDateCreated"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <index id="129" parent="15" name="sqlite_autoindex_source_ids_1"> | ||||
|     <index id="130" parent="15" name="sqlite_autoindex_source_ids_1"> | ||||
|       <NameSurrogate>1</NameSurrogate> | ||||
|       <ColNames>sourceId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <key id="130" parent="15"> | ||||
|     <key id="131" parent="15"> | ||||
|       <ColNames>sourceId</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|       <UnderlyingIndexName>sqlite_autoindex_source_ids_1</UnderlyingIndexName> | ||||
|     </key> | ||||
|     <column id="131" parent="16" name="type"> | ||||
|     <column id="132" parent="16" name="type"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>text|0s</DataType> | ||||
|     </column> | ||||
|     <column id="132" parent="16" name="name"> | ||||
|     <column id="133" parent="16" name="name"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>text|0s</DataType> | ||||
|     </column> | ||||
|     <column id="133" parent="16" name="tbl_name"> | ||||
|     <column id="134" parent="16" name="tbl_name"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>text|0s</DataType> | ||||
|     </column> | ||||
|     <column id="134" parent="16" name="rootpage"> | ||||
|     <column id="135" parent="16" name="rootpage"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>int|0s</DataType> | ||||
|     </column> | ||||
|     <column id="135" parent="16" name="sql"> | ||||
|     <column id="136" parent="16" name="sql"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>text|0s</DataType> | ||||
|     </column> | ||||
|     <column id="136" parent="17" name="name"> | ||||
|     <column id="137" parent="17" name="name"> | ||||
|       <Position>1</Position> | ||||
|     </column> | ||||
|     <column id="137" parent="17" name="seq"> | ||||
|     <column id="138" parent="17" name="seq"> | ||||
|       <Position>2</Position> | ||||
|     </column> | ||||
|     <column id="138" parent="18" name="id"> | ||||
|     <column id="139" parent="18" name="id"> | ||||
|       <Position>1</Position> | ||||
|       <DataType>INTEGER|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|       <SequenceIdentity>1</SequenceIdentity> | ||||
|     </column> | ||||
|     <column id="139" parent="18" name="entityName"> | ||||
|     <column id="140" parent="18" name="entityName"> | ||||
|       <Position>2</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="140" parent="18" name="entityId"> | ||||
|     <column id="141" parent="18" name="entityId"> | ||||
|       <Position>3</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="141" parent="18" name="sourceId"> | ||||
|     <column id="142" parent="18" name="sourceId"> | ||||
|       <Position>4</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <column id="142" parent="18" name="utcSyncDate"> | ||||
|     <column id="143" parent="18" name="utcSyncDate"> | ||||
|       <Position>5</Position> | ||||
|       <DataType>TEXT|0s</DataType> | ||||
|       <NotNull>1</NotNull> | ||||
|     </column> | ||||
|     <index id="143" parent="18" name="IDX_sync_entityName_entityId"> | ||||
|     <index id="144" parent="18" name="IDX_sync_entityName_entityId"> | ||||
|       <ColNames>entityName | ||||
| entityId</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|       <Unique>1</Unique> | ||||
|     </index> | ||||
|     <index id="144" parent="18" name="IDX_sync_utcSyncDate"> | ||||
|     <index id="145" parent="18" name="IDX_sync_utcSyncDate"> | ||||
|       <ColNames>utcSyncDate</ColNames> | ||||
|       <ColumnCollations></ColumnCollations> | ||||
|     </index> | ||||
|     <key id="145" parent="18"> | ||||
|     <key id="146" parent="18"> | ||||
|       <ColNames>id</ColNames> | ||||
|       <Primary>1</Primary> | ||||
|     </key> | ||||
|   | ||||
							
								
								
									
										26
									
								
								db/migrations/0153__add_isErased_to_note_revision.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								db/migrations/0153__add_isErased_to_note_revision.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| CREATE TABLE IF NOT EXISTS "note_revisions_mig" (`noteRevisionId`	TEXT NOT NULL PRIMARY KEY, | ||||
|                                                  `noteId`	TEXT NOT NULL, | ||||
|                                                  `title`	TEXT, | ||||
|                                                  `contentLength`	INT NOT NULL, | ||||
|                                                  `isErased`	INT NOT NULL DEFAULT 0, | ||||
|                                                  `isProtected`	INT NOT NULL DEFAULT 0, | ||||
|                                                  `utcDateLastEdited` TEXT NOT NULL, | ||||
|                                                  `utcDateCreated` TEXT NOT NULL, | ||||
|                                                  `utcDateModified` TEXT NOT NULL, | ||||
|                                                  `dateLastEdited` TEXT NOT NULL, | ||||
|                                                  `dateCreated` TEXT NOT NULL, | ||||
|                                                  type TEXT DEFAULT '' NOT NULL, | ||||
|                                                  mime TEXT DEFAULT '' NOT NULL, | ||||
|                                                  hash TEXT DEFAULT '' NOT NULL); | ||||
|  | ||||
| INSERT INTO note_revisions_mig (noteRevisionId, noteId, title, contentLength, isErased, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, type, mime, hash) | ||||
| SELECT noteRevisionId, noteId, title, contentLength, 0, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, type, mime, hash FROM note_revisions; | ||||
|  | ||||
| DROP TABLE note_revisions; | ||||
| ALTER TABLE note_revisions_mig RENAME TO note_revisions; | ||||
|  | ||||
| CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`); | ||||
| CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`); | ||||
| CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`); | ||||
| CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`); | ||||
| CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`); | ||||
| @@ -16,8 +16,9 @@ const syncTableService = require('../services/sync_table'); | ||||
|  * @property {string} type | ||||
|  * @property {string} mime | ||||
|  * @property {string} title | ||||
|  * @property {int} contentLength - length of content | ||||
|  * @property {string} isProtected | ||||
|  * @property {int} contentLength | ||||
|  * @property {boolean} isErased | ||||
|  * @property {boolean} isProtected | ||||
|  * @property {string} dateLastEdited | ||||
|  * @property {string} dateCreated | ||||
|  * @property {string} utcDateLastEdited | ||||
| @@ -29,7 +30,7 @@ const syncTableService = require('../services/sync_table'); | ||||
| class NoteRevision extends Entity { | ||||
|     static get entityName() { return "note_revisions"; } | ||||
|     static get primaryKeyName() { return "noteRevisionId"; } | ||||
|     static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "contentLength", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; } | ||||
|     static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "contentLength", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; } | ||||
|  | ||||
|     constructor(row) { | ||||
|         super(row); | ||||
| @@ -103,7 +104,7 @@ class NoteRevision extends Entity { | ||||
|     async setContent(content) { | ||||
|         // force updating note itself so that utcDateModified is represented correctly even for the content | ||||
|         this.forcedChange = true; | ||||
|         this.contentLength = content.length; | ||||
|         this.contentLength = content === null ? 0 : content.length; | ||||
|         await this.save(); | ||||
|  | ||||
|         this.content = content; | ||||
|   | ||||
| @@ -1,12 +1,14 @@ | ||||
| import noteDetailService from '../services/note_detail.js'; | ||||
| import utils from '../services/utils.js'; | ||||
| import server from '../services/server.js'; | ||||
| import toastService from "../services/toast.js"; | ||||
|  | ||||
| const $dialog = $("#note-revisions-dialog"); | ||||
| const $list = $("#note-revision-list"); | ||||
| const $content = $("#note-revision-content"); | ||||
| const $title = $("#note-revision-title"); | ||||
| const $titleButtons = $("#note-revision-title-buttons"); | ||||
| const $eraseAllRevisionsButton = $("#note-revisions-erase-all-revisions-button"); | ||||
|  | ||||
| let revisionItems = []; | ||||
| let note; | ||||
| @@ -22,6 +24,10 @@ export async function showNoteRevisionsDialog(noteId, noteRevisionId) { | ||||
|  | ||||
|     $dialog.modal(); | ||||
|  | ||||
|     await loadNoteRevisions(noteId, noteRevisionId); | ||||
| } | ||||
|  | ||||
| async function loadNoteRevisions(noteId, noteRevisionId) { | ||||
|     $list.empty(); | ||||
|     $content.empty(); | ||||
|  | ||||
| @@ -31,7 +37,7 @@ export async function showNoteRevisionsDialog(noteId, noteRevisionId) { | ||||
|     for (const item of revisionItems) { | ||||
|         $list.append($('<option>', { | ||||
|             value: item.noteRevisionId, | ||||
|             text: item.dateLastEdited | ||||
|             text: item.dateLastEdited.substr(0, 16) + (item.isErased ? ' (erased)' : '') | ||||
|         })); | ||||
|     } | ||||
|  | ||||
| @@ -41,8 +47,7 @@ export async function showNoteRevisionsDialog(noteId, noteRevisionId) { | ||||
|         } | ||||
|  | ||||
|         $list.val(noteRevisionId).trigger('change'); | ||||
|     } | ||||
|     else { | ||||
|     } else { | ||||
|         $title.text("No revisions for this note yet..."); | ||||
|     } | ||||
| } | ||||
| @@ -52,15 +57,42 @@ $list.on('change', async () => { | ||||
|  | ||||
|     const revisionItem = revisionItems.find(r => r.noteRevisionId === optVal); | ||||
|  | ||||
|     $titleButtons.empty(); | ||||
|     $content.empty(); | ||||
|  | ||||
|     if (revisionItem.isErased) { | ||||
|         $title.text('This revision has been erased'); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     $title.html(revisionItem.title); | ||||
|  | ||||
|     const $eraseRevisionButton = $('<button class="btn btn-sm" type="button">Erase this revision</button>'); | ||||
|  | ||||
|     $eraseRevisionButton.on('click', async () => { | ||||
|         const confirmDialog = await import('../dialogs/confirm.js'); | ||||
|         const text = 'Do you want to erase this revision? This action will erase revision title and content, but still preserve revision metadata.'; | ||||
|  | ||||
|         if (await confirmDialog.confirm(text)) { | ||||
|             await server.remove(`notes/${revisionItem.noteId}/revisions/${revisionItem.noteRevisionId}`); | ||||
|  | ||||
|             loadNoteRevisions(revisionItem.noteId); | ||||
|  | ||||
|             toastService.showMessage('Note revision has been erased.'); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     $titleButtons | ||||
|         .append($eraseRevisionButton) | ||||
|         .append('   '); | ||||
|  | ||||
|     const $downloadButton = $('<button class="btn btn-sm btn-primary" type="button">Download</button>'); | ||||
|  | ||||
|     $downloadButton.on('click', () => { | ||||
|         utils.download(utils.getHost() + `/api/notes/${revisionItem.noteId}/revisions/${revisionItem.noteRevisionId}/download`); | ||||
|     }); | ||||
|  | ||||
|     $titleButtons.html($downloadButton); | ||||
|     $titleButtons.append($downloadButton); | ||||
|  | ||||
|     const fullNoteRevision = await server.get(`notes/${revisionItem.noteId}/revisions/${revisionItem.noteRevisionId}`); | ||||
|  | ||||
| @@ -103,4 +135,17 @@ $list.on('change', async () => { | ||||
|     else { | ||||
|         $content.text("Preview isn't available for this note type."); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| $eraseAllRevisionsButton.on('click', async () => { | ||||
|     const confirmDialog = await import('../dialogs/confirm.js'); | ||||
|     const text = 'Do you want to erase all revision of this note? This action will erase revision title and content, but still preserve revision metadata.'; | ||||
|  | ||||
|     if (await confirmDialog.confirm(text)) { | ||||
|         await server.remove(`notes/${note.noteId}/revisions`); | ||||
|  | ||||
|         $dialog.modal('hide'); | ||||
|  | ||||
|         toastService.showMessage('Note revisions has been erased.'); | ||||
|     } | ||||
| }); | ||||
| @@ -7,13 +7,10 @@ const utils = require('../../services/utils'); | ||||
| const path = require('path'); | ||||
|  | ||||
| async function getNoteRevisions(req) { | ||||
|     const {noteId} = req.params; | ||||
|  | ||||
|     return await repository.getEntities(` | ||||
|         SELECT note_revisions.* | ||||
|         FROM note_revisions  | ||||
|         WHERE noteId = ?  | ||||
|         ORDER BY utcDateCreated DESC`, [noteId]); | ||||
|         SELECT * FROM note_revisions  | ||||
|         WHERE noteId = ? AND isErased = 0 | ||||
|         ORDER BY utcDateCreated DESC`, [req.params.noteId]); | ||||
| } | ||||
|  | ||||
| async function getNoteRevision(req) { | ||||
| @@ -86,6 +83,31 @@ async function downloadNoteRevision(req, res) { | ||||
|     res.send(await noteRevision.getContent()); | ||||
| } | ||||
|  | ||||
| async function eraseOneNoteRevision(noteRevision) { | ||||
|     noteRevision.isErased = true; | ||||
|     noteRevision.title = null; | ||||
|     await noteRevision.setContent(null); | ||||
|     await noteRevision.save(); | ||||
| } | ||||
|  | ||||
| async function eraseAllNoteRevisions(req) { | ||||
|     const noteRevisionsToErase = await repository.getEntities( | ||||
|         'SELECT * FROM note_revisions WHERE isErased = 0 AND noteId = ?', | ||||
|         [req.params.noteId]); | ||||
|  | ||||
|     for (const noteRevision of noteRevisionsToErase) { | ||||
|         await eraseOneNoteRevision(noteRevision); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function eraseNoteRevision(req) { | ||||
|     const noteRevision = await repository.getNoteRevision(req.params.noteRevisionId); | ||||
|  | ||||
|     if (noteRevision && !noteRevision.isErased) { | ||||
|         await eraseOneNoteRevision(noteRevision); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function getEditedNotesOnDate(req) { | ||||
|     const date = req.params.date; | ||||
|  | ||||
| @@ -110,5 +132,7 @@ module.exports = { | ||||
|     getNoteRevisions, | ||||
|     getNoteRevision, | ||||
|     downloadNoteRevision, | ||||
|     getEditedNotesOnDate | ||||
|     getEditedNotesOnDate, | ||||
|     eraseAllNoteRevisions, | ||||
|     eraseNoteRevision | ||||
| }; | ||||
| @@ -132,7 +132,9 @@ function register(app) { | ||||
|     apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectSubtree); | ||||
|     apiRoute(PUT, /\/api\/notes\/(.*)\/type\/(.*)\/mime\/(.*)/, notesApiRoute.setNoteTypeMime); | ||||
|     apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions); | ||||
|     apiRoute(DELETE, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.eraseAllNoteRevisions); | ||||
|     apiRoute(GET, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.getNoteRevision); | ||||
|     apiRoute(DELETE, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.eraseNoteRevision); | ||||
|     route(GET, '/api/notes/:noteId/revisions/:noteRevisionId/download', [auth.checkApiAuthOrElectron], noteRevisionsApiRoute.downloadNoteRevision); | ||||
|     apiRoute(POST, '/api/notes/relation-map', notesApiRoute.getRelationMap); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/change-title', notesApiRoute.changeTitle); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ const build = require('./build'); | ||||
| const packageJson = require('../../package'); | ||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||
|  | ||||
| const APP_DB_VERSION = 152; | ||||
| const APP_DB_VERSION = 153; | ||||
| const SYNC_VERSION = 11; | ||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||
|  | ||||
|   | ||||
| @@ -470,11 +470,20 @@ async function eraseDeletedNotes() { | ||||
|             utcDateModified = '${utcNowDateTime}'  | ||||
|         WHERE noteId IN (???)`, noteIdsToErase); | ||||
|  | ||||
|     // deleting first contents since the WHERE relies on isErased = 0 | ||||
|     await sql.executeMany(` | ||||
|         UPDATE note_revisions  | ||||
|         UPDATE note_revision_contents | ||||
|         SET content = NULL, | ||||
|             utcDateModified = '${utcNowDateTime}' | ||||
|         WHERE noteId IN (???)`, noteIdsToErase); | ||||
|         WHERE noteRevisionId IN  | ||||
|             (SELECT noteRevisionId FROM note_revisions WHERE isErased = 0 AND noteId IN ((???)))`, noteIdsToErase); | ||||
|  | ||||
|     await sql.executeMany(` | ||||
|         UPDATE note_revisions  | ||||
|         SET isErased = 1, | ||||
|             title = NULL, | ||||
|             utcDateModified = '${utcNowDateTime}' | ||||
|         WHERE isErased = 0 AND noteId IN (???)`, noteIdsToErase); | ||||
| } | ||||
|  | ||||
| async function duplicateNote(noteId, parentNoteId) { | ||||
|   | ||||
| @@ -18,6 +18,9 @@ async function updateEntity(sync, entity, sourceId) { | ||||
|     else if (entityName === 'note_revisions') { | ||||
|         await updateNoteRevision(entity, sourceId); | ||||
|     } | ||||
|     else if (entityName === 'note_revision_contents') { | ||||
|         await updateNoteRevisionContent(entity, sourceId); | ||||
|     } | ||||
|     else if (entityName === 'note_reordering') { | ||||
|         await updateNoteReordering(sync.entityId, entity, sourceId); | ||||
|     } | ||||
|   | ||||
| @@ -4,6 +4,11 @@ | ||||
|             <div class="modal-header"> | ||||
|                 <h5 class="modal-title mr-auto">Note revisions</h5> | ||||
|  | ||||
|                 <button class="btn btn-xs" | ||||
|                         id="note-revisions-erase-all-revisions-button" | ||||
|                         title="Erase all revisions of this note" | ||||
|                         style="padding: 0 10px 0 10px;" type="button">Erase all revisions</button> | ||||
|  | ||||
|                 <button class="help-button" type="button" data-help-page="Note-revisions" title="Help on Note revisions">?</button> | ||||
|  | ||||
|                 <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0 !important;"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user