mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +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