mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	added flag for the erased notes
This commit is contained in:
		
							
								
								
									
										31
									
								
								db/migrations/0151__add_isCleaned_to_note.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								db/migrations/0151__add_isCleaned_to_note.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| CREATE TABLE IF NOT EXISTS "notes_mig" ( | ||||
|                                        `noteId`	TEXT NOT NULL, | ||||
|                                        `title`	TEXT NOT NULL DEFAULT "note", | ||||
|                                        `isProtected`	INT NOT NULL DEFAULT 0, | ||||
|                                        `type` TEXT NOT NULL DEFAULT 'text', | ||||
|                                        `mime` TEXT NOT NULL DEFAULT 'text/html', | ||||
|                                        `hash` TEXT DEFAULT "" NOT NULL, | ||||
|                                        `isDeleted`	INT NOT NULL DEFAULT 0, | ||||
|                                        `isErased`	INT NOT NULL DEFAULT 0, | ||||
|                                        `dateCreated`	TEXT NOT NULL, | ||||
|                                        `dateModified`	TEXT NOT NULL, | ||||
|                                        `utcDateCreated`	TEXT NOT NULL, | ||||
|                                        `utcDateModified`	TEXT NOT NULL, | ||||
|                                        PRIMARY KEY(`noteId`)); | ||||
|  | ||||
| INSERT INTO notes_mig (noteId, title, isProtected, type, mime, hash, isDeleted, isErased, dateCreated, dateModified, utcDateCreated, utcDateModified) | ||||
| SELECT noteId, title, isProtected, type, mime, hash, isDeleted, 0, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes; | ||||
|  | ||||
| DROP TABLE notes; | ||||
| ALTER TABLE notes_mig RENAME TO notes; | ||||
|  | ||||
| UPDATE notes SET isErased = 1 WHERE isDeleted = 1 | ||||
| AND (SELECT CASE content WHEN NULL THEN 1 ELSE 0 END FROM note_contents WHERE note_contents.noteId = notes.noteId); | ||||
|  | ||||
| CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`); | ||||
| CREATE INDEX `IDX_notes_title` ON `notes` (`title`); | ||||
| CREATE INDEX `IDX_notes_type` ON `notes` (`type`); | ||||
| CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`); | ||||
| CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`); | ||||
| CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`); | ||||
| CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`); | ||||
| @@ -38,20 +38,6 @@ CREATE TABLE IF NOT EXISTS "attributes" | ||||
|   isDeleted    INT  not null, | ||||
|   hash         TEXT default "" not null, | ||||
|   isInheritable int DEFAULT 0 NULL); | ||||
| CREATE TABLE IF NOT EXISTS "notes" ( | ||||
|                                      `noteId`	TEXT NOT NULL, | ||||
|                                      `title`	TEXT NOT NULL DEFAULT "note", | ||||
|                                      `isProtected`	INT NOT NULL DEFAULT 0, | ||||
|                                      `type` TEXT NOT NULL DEFAULT 'text', | ||||
|                                      `mime` TEXT NOT NULL DEFAULT 'text/html', | ||||
|                                      `hash` TEXT DEFAULT "" NOT NULL, | ||||
|                                      `isDeleted`	INT NOT NULL DEFAULT 0, | ||||
|                                      `dateCreated`	TEXT NOT NULL, | ||||
|                                      `dateModified`	TEXT NOT NULL, | ||||
|                                      `utcDateCreated`	TEXT NOT NULL, | ||||
|                                      `utcDateModified`	TEXT NOT NULL, | ||||
|                                      PRIMARY KEY(`noteId`) | ||||
| ); | ||||
| CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` ( | ||||
|                                                               `entityName`, | ||||
|                                                               `entityId` | ||||
| @@ -119,3 +105,24 @@ CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCr | ||||
| 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`); | ||||
| CREATE TABLE IF NOT EXISTS "notes" ( | ||||
|                                        `noteId`	TEXT NOT NULL, | ||||
|                                        `title`	TEXT NOT NULL DEFAULT "note", | ||||
|                                        `isProtected`	INT NOT NULL DEFAULT 0, | ||||
|                                        `type` TEXT NOT NULL DEFAULT 'text', | ||||
|                                        `mime` TEXT NOT NULL DEFAULT 'text/html', | ||||
|                                        `hash` TEXT DEFAULT "" NOT NULL, | ||||
|                                        `isDeleted`	INT NOT NULL DEFAULT 0, | ||||
|                                        `isErased`	INT NOT NULL DEFAULT 0, | ||||
|                                        `dateCreated`	TEXT NOT NULL, | ||||
|                                        `dateModified`	TEXT NOT NULL, | ||||
|                                        `utcDateCreated`	TEXT NOT NULL, | ||||
|                                        `utcDateModified`	TEXT NOT NULL, | ||||
|                                        PRIMARY KEY(`noteId`)); | ||||
| CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`); | ||||
| CREATE INDEX `IDX_notes_title` ON `notes` (`title`); | ||||
| CREATE INDEX `IDX_notes_type` ON `notes` (`type`); | ||||
| CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`); | ||||
| CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`); | ||||
| CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`); | ||||
| CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`); | ||||
|   | ||||
							
								
								
									
										8
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "trilium", | ||||
|   "version": "0.36.1-beta", | ||||
|   "version": "0.36.2", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
| @@ -5219,9 +5219,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "file-type": { | ||||
|       "version": "12.3.1", | ||||
|       "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.3.1.tgz", | ||||
|       "integrity": "sha512-FXxY5h6vSYMjrRal4YqbtfuoKD/oE0AMjJ7E5Hm+BdaQECcFVD03B41RAWYJ7wyuLr/wRnCtFo7y37l+nh+TAA==" | ||||
|       "version": "12.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.0.tgz", | ||||
|       "integrity": "sha512-WTvyKq8yjtNmUtVAD8LGcTkvtCdJglM6ks2HTqEClm6+65XTqM6MoZYA1Vtra50DLRWLiM38fEs1y56f5VhnUA==" | ||||
|     }, | ||||
|     "filename-regex": { | ||||
|       "version": "2.0.1", | ||||
|   | ||||
| @@ -37,7 +37,7 @@ | ||||
|     "electron-window-state": "5.0.3", | ||||
|     "express": "4.17.1", | ||||
|     "express-session": "1.17.0", | ||||
|     "file-type": "12.3.1", | ||||
|     "file-type": "12.4.0", | ||||
|     "fs-extra": "8.1.0", | ||||
|     "helmet": "3.21.2", | ||||
|     "html": "1.0.0", | ||||
|   | ||||
| @@ -23,6 +23,7 @@ const RELATION_DEFINITION = 'relation-definition'; | ||||
|  * @property {string} title - note title | ||||
|  * @property {boolean} isProtected - true if note is protected | ||||
|  * @property {boolean} isDeleted - true if note is deleted | ||||
|  * @property {boolean} isErased - true if note's content is erased after it has been deleted | ||||
|  * @property {string} dateCreated - local date time (with offset) | ||||
|  * @property {string} dateModified - local date time (with offset) | ||||
|  * @property {string} utcDateCreated | ||||
|   | ||||
| @@ -4,7 +4,7 @@ const build = require('./build'); | ||||
| const packageJson = require('../../package'); | ||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||
|  | ||||
| const APP_DB_VERSION = 150; | ||||
| const APP_DB_VERSION = 151; | ||||
| const SYNC_VERSION = 11; | ||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||
|  | ||||
|   | ||||
| @@ -228,6 +228,23 @@ async function findLogicIssues() { | ||||
|             AND content IS NULL`, | ||||
|         ({noteId}) => `Note ${noteId} content is null even though it is not deleted`); | ||||
|  | ||||
|     await findIssues(` | ||||
|           SELECT noteId | ||||
|           FROM notes | ||||
|           JOIN note_contents USING(noteId) | ||||
|           WHERE | ||||
|             isErased = 1 | ||||
|             AND content IS NOT NULL`, | ||||
|         ({noteId}) => `Note ${noteId} content is not null even though the note is erased`); | ||||
|  | ||||
|     await findIssues(` | ||||
|         SELECT noteId | ||||
|         FROM notes | ||||
|         WHERE | ||||
|             isErased = 1 | ||||
|             AND isDeleted = 0`, | ||||
|         ({noteId}) => `Note ${noteId} is not deleted even though it is erased`); | ||||
|  | ||||
|     await findIssues(` | ||||
|           SELECT parentNoteId | ||||
|           FROM  | ||||
|   | ||||
| @@ -457,15 +457,35 @@ async function scanForLinks(noteId) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function cleanupDeletedNotes() { | ||||
| async function eraseDeletedNotes() { | ||||
|     const cutoffDate = new Date(Date.now() - 48 * 3600 * 1000); | ||||
|  | ||||
|     const noteIdsToErase = await sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1 AND isErased = 0 AND notes.utcDateModified <= ?", [dateUtils.utcDateStr(cutoffDate)]); | ||||
|  | ||||
|     const utcNowDateTime = dateUtils.utcNowDateTime(); | ||||
|     const localNowDateTime = dateUtils.localNowDateTime(); | ||||
|  | ||||
|     // it's better to not use repository for this because it will complain about saving protected notes | ||||
|     // out of protected session | ||||
|  | ||||
|     await sql.execute("UPDATE note_contents SET content = NULL WHERE content IS NOT NULL AND noteId IN (SELECT noteId FROM notes WHERE isDeleted = 1 AND notes.utcDateModified <= ?)", [dateUtils.utcDateStr(cutoffDate)]); | ||||
|     await sql.executeMany(` | ||||
|         UPDATE notes  | ||||
|         SET isErased = 1,  | ||||
|             utcDateModified = '${utcNowDateTime}', | ||||
|             dateModified = '${localNowDateTime}' | ||||
|         WHERE noteId IN (???)`, noteIdsToErase); | ||||
|  | ||||
|     await sql.execute("UPDATE note_revisions SET content = NULL WHERE note_revisions.content IS NOT NULL AND noteId IN (SELECT noteId FROM notes WHERE isDeleted = 1 AND notes.utcDateModified <= ?)", [dateUtils.utcDateStr(cutoffDate)]); | ||||
|     await sql.executeMany(` | ||||
|         UPDATE note_contents  | ||||
|         SET content = NULL, | ||||
|             utcDateModified = '${utcNowDateTime}'  | ||||
|         WHERE noteId IN (???)`, noteIdsToErase); | ||||
|  | ||||
|     await sql.executeMany(` | ||||
|         UPDATE note_revisions  | ||||
|         SET content = NULL, | ||||
|             utcDateModified = '${utcNowDateTime}' | ||||
|         WHERE noteId IN (???)`, noteIdsToErase); | ||||
| } | ||||
|  | ||||
| async function duplicateNote(noteId, parentNoteId) { | ||||
| @@ -508,9 +528,9 @@ async function duplicateNote(noteId, parentNoteId) { | ||||
|  | ||||
| sqlInit.dbReady.then(() => { | ||||
|     // first cleanup kickoff 5 minutes after startup | ||||
|     setTimeout(cls.wrap(cleanupDeletedNotes), 5 * 60 * 1000); | ||||
|     setTimeout(cls.wrap(eraseDeletedNotes), 5 * 60 * 1000); | ||||
|  | ||||
|     setInterval(cls.wrap(cleanupDeletedNotes), 4 * 3600 * 1000); | ||||
|     setInterval(cls.wrap(eraseDeletedNotes), 4 * 3600 * 1000); | ||||
| }); | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
| @@ -152,6 +152,11 @@ async function execute(query, params = []) { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| async function executeMany(query, params) { | ||||
|     // essentially just alias | ||||
|     await getManyRows(query, params); | ||||
| } | ||||
|  | ||||
| async function executeScript(query) { | ||||
|     return await wrap(async db => db.exec(query)); | ||||
| } | ||||
| @@ -235,6 +240,7 @@ module.exports = { | ||||
|     getMap, | ||||
|     getColumn, | ||||
|     execute, | ||||
|     executeMany, | ||||
|     executeScript, | ||||
|     transactional, | ||||
|     upsert | ||||
|   | ||||
		Reference in New Issue
	
	Block a user