mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	added flag for the erased notes
This commit is contained in:
		
							parent
							
								
									2e58e32112
								
							
						
					
					
						commit
						2af86927b0
					
				
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user