Compare commits

..

11 Commits

16 changed files with 75 additions and 44 deletions

View File

@@ -635,20 +635,26 @@ parentNoteId</ColNames>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<column id="145" parent="18" name="utcSyncDate">
<column id="145" parent="18" name="isSynced">
<Position>5</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<DefaultExpression>0</DefaultExpression>
</column>
<column id="146" parent="18" name="utcSyncDate">
<Position>6</Position>
<DataType>TEXT|0s</DataType>
<NotNull>1</NotNull>
</column>
<index id="146" parent="18" name="IDX_sync_entityName_entityId">
<index id="147" parent="18" name="IDX_sync_entityName_entityId">
<ColNames>entityName
entityId</ColNames>
<Unique>1</Unique>
</index>
<index id="147" parent="18" name="IDX_sync_utcSyncDate">
<index id="148" parent="18" name="IDX_sync_utcSyncDate">
<ColNames>utcSyncDate</ColNames>
</index>
<key id="148" parent="18">
<key id="149" parent="18">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>

View File

@@ -0,0 +1,22 @@
CREATE TABLE IF NOT EXISTS "sync_mig" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`isSynced` INTEGER default 0 not null,
`utcSyncDate` TEXT NOT NULL);
INSERT INTO sync_mig (id, entityName, entityId, sourceId, isSynced, utcSyncDate)
SELECT id, entityName, entityId, sourceId, 1, utcSyncDate FROM sync;
DROP TABLE sync;
ALTER TABLE sync_mig RENAME TO sync;
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
`utcSyncDate`
);

View File

@@ -1,16 +1,8 @@
CREATE TABLE IF NOT EXISTS "sync" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`utcSyncDate` TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS "source_ids" (
`sourceId` TEXT NOT NULL,
`utcDateCreated` TEXT NOT NULL,
PRIMARY KEY(`sourceId`)
);
CREATE INDEX IDX_source_ids_utcDateCreated
on source_ids (utcDateCreated);
CREATE TABLE IF NOT EXISTS "api_tokens"
(
apiTokenId TEXT PRIMARY KEY NOT NULL,
@@ -27,13 +19,6 @@ CREATE TABLE IF NOT EXISTS "options"
utcDateCreated TEXT not null,
utcDateModified TEXT NOT NULL
);
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
`utcSyncDate`
);
CREATE TABLE IF NOT EXISTS "note_contents" (
`noteId` TEXT NOT NULL,
`content` TEXT NULL DEFAULT NULL,
@@ -72,6 +57,8 @@ 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 INDEX IDX_source_ids_utcDateCreated
on source_ids (utcDateCreated);
CREATE TABLE IF NOT EXISTS "notes" (
`noteId` TEXT NOT NULL,
`title` TEXT NOT NULL DEFAULT "note",
@@ -130,3 +117,17 @@ CREATE INDEX IDX_attributes_noteId_index
on attributes (noteId);
CREATE INDEX IDX_attributes_value_index
on attributes (value);
CREATE TABLE IF NOT EXISTS "sync" (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`entityName` TEXT NOT NULL,
`entityId` TEXT NOT NULL,
`sourceId` TEXT NOT NULL,
`isSynced` INTEGER default 0 not null,
`utcSyncDate` TEXT NOT NULL);
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
`entityName`,
`entityId`
);
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
`utcSyncDate`
);

View File

@@ -2,7 +2,7 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.40.5",
"version": "0.40.6",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {

View File

@@ -11,7 +11,9 @@ const ENTITY_NAME_TO_ENTITY = {
"attributes": Attribute,
"branches": Branch,
"notes": Note,
"note_contents": Note,
"note_revisions": NoteRevision,
"note_revision_contents": NoteRevision,
"recent_notes": RecentNote,
"options": Option,
"api_tokens": ApiToken,

View File

@@ -60,6 +60,7 @@ class NoteDetailCode {
// CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check)
// we provide fallback
this.codeEditor.setValue(this.ctx.note.content || "");
this.codeEditor.clearHistory();
const info = CodeMirror.findModeByMIME(this.ctx.note.mime);

View File

@@ -1,9 +1,9 @@
"use strict";
const app_info = require('../../services/app_info');
const appInfo = require('../../services/app_info');
async function getAppInfo() {
return app_info;
return appInfo;
}
module.exports = {

View File

@@ -49,7 +49,7 @@ async function loginSync(req) {
return {
sourceId: sourceIdService.getCurrentSourceId(),
maxSyncId: await sql.getValue("SELECT MAX(id) FROM sync")
maxSyncId: await sql.getValue("SELECT MAX(id) FROM sync WHERE isSynced = 1")
};
}

View File

@@ -50,7 +50,7 @@ async function getStats() {
async function checkSync() {
return {
entityHashes: await contentHashService.getEntityHashes(),
maxSyncId: await sql.getValue('SELECT MAX(id) FROM sync')
maxSyncId: await sql.getValue('SELECT MAX(id) FROM sync WHERE isSynced = 1')
};
}
@@ -116,11 +116,11 @@ async function forceNoteSync(req) {
async function getChanged(req) {
const lastSyncId = parseInt(req.query.lastSyncId);
const syncs = await sql.getRows("SELECT * FROM sync WHERE id > ? LIMIT 1000", [lastSyncId]);
const syncs = await sql.getRows("SELECT * FROM sync WHERE isSynced = 1 AND id > ? LIMIT 1000", [lastSyncId]);
return {
syncs: await syncService.getSyncRecords(syncs),
maxSyncId: await sql.getValue('SELECT MAX(id) FROM sync')
maxSyncId: await sql.getValue('SELECT MAX(id) FROM sync WHERE isSynced = 1')
};
}

View File

@@ -4,7 +4,7 @@ const build = require('./build');
const packageJson = require('../../package');
const {TRILIUM_DATA_DIR} = require('./data_dir');
const APP_DB_VERSION = 157;
const APP_DB_VERSION = 158;
const SYNC_VERSION = 14;
const CLIPPER_PROTOCOL_VERSION = "1.0";

View File

@@ -1 +1 @@
module.exports = { buildDate:"2020-03-08T21:05:52+01:00", buildRevision: "e4039ea5e1c6ac87e0947bc77b6bdcbb29a23092" };
module.exports = { buildDate:"2020-03-15T11:21:43+01:00", buildRevision: "f5e27278ab2a38484019ee2510781099b60ec2b6" };

View File

@@ -51,7 +51,7 @@ class ConsistencyChecks {
childToParents[childNoteId].push(parentNoteId);
}
function checkTreeCycle(noteId, path) {
const checkTreeCycle = (noteId, path) => {
if (noteId === 'root') {
return;
}
@@ -75,7 +75,7 @@ class ConsistencyChecks {
checkTreeCycle(parentNoteId, newPath);
}
}
}
};
const noteIds = Object.keys(childToParents);
@@ -546,7 +546,7 @@ class ConsistencyChecks {
${entityName}
LEFT JOIN sync ON sync.entityName = '${entityName}' AND entityId = ${key}
WHERE
sync.id IS NULL AND ` + (entityName === 'options' ? 'isSynced = 1' : '1'),
sync.id IS NULL AND ` + (entityName === 'options' ? 'options.isSynced = 1' : '1'),
async ({entityId}) => {
if (this.autoFix) {
await syncTableService.addEntitySync(entityName, entityId);

View File

@@ -235,8 +235,6 @@ async function importEnex(taskContext, file, parentNote) {
taskContext.increaseProgressCount();
let noteContent = await noteEntity.getContent();
for (const resource of resources) {
const hash = utils.md5(resource.content);
@@ -268,7 +266,7 @@ async function importEnex(taskContext, file, parentNote) {
const resourceLink = `<a href="#root/${resourceNote.noteId}">${utils.escapeHtml(resource.title)}</a>`;
noteContent = noteContent.replace(mediaRegex, resourceLink);
content = content.replace(mediaRegex, resourceLink);
};
if (["image/jpeg", "image/png", "image/gif", "image/webp"].includes(resource.mime)) {
@@ -281,12 +279,12 @@ async function importEnex(taskContext, file, parentNote) {
const imageLink = `<img src="${url}">`;
noteContent = noteContent.replace(mediaRegex, imageLink);
content = content.replace(mediaRegex, imageLink);
if (!noteContent.includes(imageLink)) {
if (!content.includes(imageLink)) {
// if there wasn't any match for the reference, we'll add the image anyway
// otherwise image would be removed since no note would include it
noteContent += imageLink;
content += imageLink;
}
} catch (e) {
log.error("error when saving image from ENEX file: " + e);
@@ -298,7 +296,7 @@ async function importEnex(taskContext, file, parentNote) {
}
// save updated content with links to files/images
await noteEntity.setContent(noteContent);
await noteEntity.setContent(content);
await noteService.scanForLinks(noteEntity.noteId);

View File

@@ -209,6 +209,8 @@ async function transactional(func) {
transactionActive = false;
resolve();
setTimeout(() => require('./ws').sendPingToAllClients(), 50);
}
catch (e) {
if (transactionActive) {

View File

@@ -176,7 +176,7 @@ async function pushSync(syncContext) {
let lastSyncedPush = await getLastSyncedPush();
while (true) {
const syncs = await sql.getRows('SELECT * FROM sync WHERE id > ? LIMIT 1000', [lastSyncedPush]);
const syncs = await sql.getRows('SELECT * FROM sync WHERE isSynced = 1 AND id > ? LIMIT 1000', [lastSyncedPush]);
if (syncs.length === 0) {
log.info("Nothing to push");
@@ -236,7 +236,7 @@ async function checkContentHash(syncContext) {
return true;
}
const notPushedSyncs = await sql.getValue("SELECT EXISTS(SELECT 1 FROM sync WHERE id > ?)", [await getLastSyncedPush()]);
const notPushedSyncs = await sql.getValue("SELECT EXISTS(SELECT 1 FROM sync WHERE isSynced = 1 AND id > ?)", [await getLastSyncedPush()]);
if (notPushedSyncs) {
log.info(`There's ${notPushedSyncs} outstanding pushes, skipping content check.`);
@@ -353,7 +353,7 @@ async function updatePushStats() {
if (await syncOptions.isSyncSetup()) {
const lastSyncedPush = await optionService.getOption('lastSyncedPush');
stats.outstandingPushes = await sql.getValue("SELECT COUNT(1) FROM sync WHERE id > ?", [lastSyncedPush]);
stats.outstandingPushes = await sql.getValue("SELECT COUNT(1) FROM sync WHERE isSynced = 1 AND id > ?", [lastSyncedPush]);
}
}

View File

@@ -11,7 +11,8 @@ async function insertEntitySync(entityName, entityId, sourceId) {
entityName: entityName,
entityId: entityId,
utcSyncDate: dateUtils.utcNowDateTime(),
sourceId: sourceId || cls.getSourceId() || sourceIdService.getCurrentSourceId()
sourceId: sourceId || cls.getSourceId() || sourceIdService.getCurrentSourceId(),
isSynced: 1
};
sync.id = await sql.replace("sync", sync);
@@ -23,8 +24,6 @@ async function addEntitySync(entityName, entityId, sourceId) {
const sync = await insertEntitySync(entityName, entityId, sourceId);
syncs.push(sync);
setTimeout(() => require('./ws').sendPingToAllClients(), 50);
}
async function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) {