mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-29 02:28:57 +01:00 
			
		
		
		
	added hash columns for faster sync check calculation
This commit is contained in:
		
							parent
							
								
									9fa6c0918c
								
							
						
					
					
						commit
						49a53f7a45
					
				
							
								
								
									
										9
									
								
								db/migrations/0093__add_hash_field.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								db/migrations/0093__add_hash_field.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| ALTER TABLE notes ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE branches ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE note_revisions ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE recent_notes ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE options ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE note_images ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE images ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE labels ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| ALTER TABLE api_tokens ADD hash TEXT DEFAULT "" NOT NULL; | ||||
| @ -6,6 +6,7 @@ const dateUtils = require('../services/date_utils'); | ||||
| class ApiToken extends Entity { | ||||
|     static get tableName() { return "api_tokens"; } | ||||
|     static get primaryKeyName() { return "apiTokenId"; } | ||||
|     static get syncedProperties() { return ["apiTokenId", "token", "dateCreated", "isDeleted"]; } | ||||
| 
 | ||||
|     beforeSaving() { | ||||
|         super.beforeSaving(); | ||||
|  | ||||
| @ -8,6 +8,7 @@ const sql = require('../services/sql'); | ||||
| class Branch extends Entity { | ||||
|     static get tableName() { return "branches"; } | ||||
|     static get primaryKeyName() { return "branchId"; } | ||||
|     static get syncedProperties() { return ["branchId", "noteId", "parentNoteId", "notePosition", "dateModified", "isDeleted", "prefix"]; } | ||||
| 
 | ||||
|     async getNote() { | ||||
|         return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|  | ||||
| @ -14,6 +14,14 @@ class Entity { | ||||
|         if (!this[this.constructor.primaryKeyName]) { | ||||
|             this[this.constructor.primaryKeyName] = utils.newEntityId(); | ||||
|         } | ||||
| 
 | ||||
|         let contentToHash = ""; | ||||
| 
 | ||||
|         for (const propertyName of this.constructor.syncedProperties) { | ||||
|             contentToHash += "|" + this[propertyName]; | ||||
|         } | ||||
| 
 | ||||
|         this["hash"] = utils.hash(contentToHash).substr(0, 10); | ||||
|     } | ||||
| 
 | ||||
|     async save() { | ||||
|  | ||||
| @ -6,6 +6,7 @@ const dateUtils = require('../services/date_utils'); | ||||
| class Image extends Entity { | ||||
|     static get tableName() { return "images"; } | ||||
|     static get primaryKeyName() { return "imageId"; } | ||||
|     static get syncedProperties() { return ["imageId", "format", "checksum", "name", "isDeleted", "dateModified", "dateCreated"]; } | ||||
| 
 | ||||
|     beforeSaving() { | ||||
|         super.beforeSaving(); | ||||
|  | ||||
| @ -8,6 +8,7 @@ const sql = require('../services/sql'); | ||||
| class Label extends Entity { | ||||
|     static get tableName() { return "labels"; } | ||||
|     static get primaryKeyName() { return "labelId"; } | ||||
|     static get syncedProperties() { return ["labelId", "noteId", "name", "value", "dateModified", "dateCreated"]; } | ||||
| 
 | ||||
|     async getNote() { | ||||
|         return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|  | ||||
| @ -8,6 +8,7 @@ const dateUtils = require('../services/date_utils'); | ||||
| class Note extends Entity { | ||||
|     static get tableName() { return "notes"; } | ||||
|     static get primaryKeyName() { return "noteId"; } | ||||
|     static get syncedProperties() { return ["noteId", "title", "content", "type", "dateModified", "isProtected", "isDeleted"]; } | ||||
| 
 | ||||
|     constructor(row) { | ||||
|         super(row); | ||||
|  | ||||
| @ -7,6 +7,7 @@ const dateUtils = require('../services/date_utils'); | ||||
| class NoteImage extends Entity { | ||||
|     static get tableName() { return "note_images"; } | ||||
|     static get primaryKeyName() { return "noteImageId"; } | ||||
|     static get syncedProperties() { return ["noteImageId", "noteId", "imageId", "isDeleted", "dateModified", "dateCreated"]; } | ||||
| 
 | ||||
|     async getNote() { | ||||
|         return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); | ||||
|  | ||||
| @ -7,6 +7,7 @@ const repository = require('../services/repository'); | ||||
| class NoteRevision extends Entity { | ||||
|     static get tableName() { return "note_revisions"; } | ||||
|     static get primaryKeyName() { return "noteRevisionId"; } | ||||
|     static get syncedProperties() { return ["noteRevisionId", "noteId", "title", "content", "dateModifiedFrom", "dateModifiedTo"]; } | ||||
| 
 | ||||
|     constructor(row) { | ||||
|         super(row); | ||||
|  | ||||
							
								
								
									
										11
									
								
								src/entities/option.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/entities/option.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const Entity = require('./entity'); | ||||
| 
 | ||||
| class Option extends Entity { | ||||
|     static get tableName() { return "options"; } | ||||
|     static get primaryKeyName() { return "name"; } | ||||
|     static get syncedProperties() { return ["name", "value"]; } | ||||
| } | ||||
| 
 | ||||
| module.exports = Option; | ||||
| @ -5,6 +5,7 @@ const Entity = require('./entity'); | ||||
| class RecentNote extends Entity { | ||||
|     static get tableName() { return "recent_notes"; } | ||||
|     static get primaryKeyName() { return "branchId"; } | ||||
|     static get syncedProperties() { return ["branchId", "notePath", "dateAccessed", "isDeleted"]; } | ||||
| } | ||||
| 
 | ||||
| module.exports = RecentNote; | ||||
| @ -3,7 +3,7 @@ | ||||
| const build = require('./build'); | ||||
| const packageJson = require('../../package'); | ||||
| 
 | ||||
| const APP_DB_VERSION = 92; | ||||
| const APP_DB_VERSION = 93; | ||||
| 
 | ||||
| module.exports = { | ||||
|     appVersion: packageJson.version, | ||||
|  | ||||
| @ -5,117 +5,40 @@ const utils = require('./utils'); | ||||
| const log = require('./log'); | ||||
| const eventLogService = require('./event_log'); | ||||
| const messagingService = require('./messaging'); | ||||
| const ApiToken = require('../entities/api_token'); | ||||
| const Branch = require('../entities/branch'); | ||||
| const Image = require('../entities/image'); | ||||
| const Note = require('../entities/note'); | ||||
| const NoteImage = require('../entities/note_image'); | ||||
| const Label = require('../entities/label'); | ||||
| const NoteRevision = require('../entities/note_revision'); | ||||
| const RecentNote = require('../entities/recent_note'); | ||||
| const Option = require('../entities/option'); | ||||
| 
 | ||||
| function getHash(rows) { | ||||
|     let hash = ''; | ||||
| async function getHash(entityConstructor, whereBranch) { | ||||
|     let contentToHash = await sql.getValue(`SELECT GROUP_CONCAT(hash) FROM ${entityConstructor.tableName} ` | ||||
|                 + (whereBranch ? `WHERE ${whereBranch} ` : '') + `ORDER BY ${entityConstructor.primaryKeyName}`); | ||||
| 
 | ||||
|     for (const row of rows) { | ||||
|         hash = utils.hash(hash + JSON.stringify(row)); | ||||
|     if (!contentToHash) { // might be null in case of no rows
 | ||||
|         contentToHash = ""; | ||||
|     } | ||||
| 
 | ||||
|     return hash; | ||||
|     return utils.hash(contentToHash); | ||||
| } | ||||
| 
 | ||||
| async function getHashes() { | ||||
|     const startTime = new Date(); | ||||
| 
 | ||||
|     const hashes = { | ||||
|         notes: getHash(await sql.getRows(` | ||||
|             SELECT | ||||
|               noteId, | ||||
|               title, | ||||
|               content, | ||||
|               type, | ||||
|               dateModified, | ||||
|               isProtected, | ||||
|               isDeleted | ||||
|             FROM notes | ||||
|             ORDER BY noteId`)),
 | ||||
| 
 | ||||
|         branches: getHash(await sql.getRows(` | ||||
|             SELECT | ||||
|                branchId, | ||||
|                noteId, | ||||
|                parentNoteId, | ||||
|                notePosition, | ||||
|                dateModified, | ||||
|                isDeleted, | ||||
|                prefix | ||||
|              FROM branches | ||||
|              ORDER BY branchId`)),
 | ||||
| 
 | ||||
|         note_revisions: getHash(await sql.getRows(` | ||||
|             SELECT | ||||
|               noteRevisionId, | ||||
|               noteId, | ||||
|               title, | ||||
|               content, | ||||
|               dateModifiedFrom, | ||||
|               dateModifiedTo | ||||
|             FROM note_revisions | ||||
|             ORDER BY noteRevisionId`)),
 | ||||
| 
 | ||||
|         recent_notes: getHash(await sql.getRows(` | ||||
|            SELECT | ||||
|              branchId, | ||||
|              notePath, | ||||
|              dateAccessed, | ||||
|              isDeleted | ||||
|            FROM recent_notes | ||||
|            ORDER BY notePath`)),
 | ||||
| 
 | ||||
|         options: getHash(await sql.getRows(` | ||||
|            SELECT  | ||||
|              name, | ||||
|              value  | ||||
|            FROM options  | ||||
|            WHERE isSynced = 1 | ||||
|            ORDER BY name`)),
 | ||||
| 
 | ||||
|         // we don't include image data on purpose because they are quite large, checksum is good enough
 | ||||
|         // to represent the data anyway
 | ||||
|         images: getHash(await sql.getRows(` | ||||
|           SELECT  | ||||
|             imageId, | ||||
|             format, | ||||
|             checksum, | ||||
|             name, | ||||
|             isDeleted, | ||||
|             dateModified, | ||||
|             dateCreated | ||||
|           FROM images   | ||||
|           ORDER BY imageId`)),
 | ||||
| 
 | ||||
|         note_images: getHash(await sql.getRows(` | ||||
|           SELECT | ||||
|             noteImageId, | ||||
|             noteId, | ||||
|             imageId, | ||||
|             isDeleted, | ||||
|             dateModified, | ||||
|             dateCreated | ||||
|           FROM note_images | ||||
|           ORDER BY noteImageId`)),
 | ||||
| 
 | ||||
|         labels: getHash(await sql.getRows(` | ||||
|           SELECT  | ||||
|             labelId, | ||||
|             noteId, | ||||
|             name, | ||||
|             value, | ||||
|             dateModified, | ||||
|             dateCreated | ||||
|           FROM labels   | ||||
|           ORDER BY labelId`)),
 | ||||
| 
 | ||||
|         api_tokens: getHash(await sql.getRows(` | ||||
|           SELECT  | ||||
|             apiTokenId, | ||||
|             token, | ||||
|             dateCreated, | ||||
|             isDeleted | ||||
|           FROM api_tokens   | ||||
|           ORDER BY apiTokenId`))
 | ||||
|         notes: await getHash(Note), | ||||
|         branches: await getHash(Branch), | ||||
|         note_revisions: await getHash(NoteRevision), | ||||
|         recent_notes: await getHash(RecentNote), | ||||
|         options: await getHash(Option, "isSynced = 1"), | ||||
|         images: await getHash(Image), | ||||
|         note_images: await getHash(NoteImage), | ||||
|         labels: await getHash(Label), | ||||
|         api_tokens: await getHash(ApiToken) | ||||
|     }; | ||||
| 
 | ||||
|     const elapseTimeMs = new Date().getTime() - startTime.getTime(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 azivner
						azivner