mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-02 12:47:41 +02:00
Merge branch 'dev' of github.com:laurent22/joplin into dev
This commit is contained in:
commit
3b6a66a016
@ -343,7 +343,7 @@ export default class JoplinDatabase extends Database {
|
||||
// must be set in the synchronizer too.
|
||||
|
||||
// Note: v16 and v17 don't do anything. They were used to debug an issue.
|
||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38];
|
||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39];
|
||||
|
||||
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
||||
|
||||
@ -888,6 +888,10 @@ export default class JoplinDatabase extends Database {
|
||||
GROUP BY tags.id`);
|
||||
}
|
||||
|
||||
if (targetVersion == 39) {
|
||||
queries.push('ALTER TABLE `notes` ADD COLUMN conflict_original_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
|
||||
|
||||
queries.push(updateVersionQuery);
|
||||
|
@ -610,10 +610,7 @@ export default class Synchronizer {
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
if (mustHandleConflict) {
|
||||
const conflictedNote = Object.assign({}, local);
|
||||
delete conflictedNote.id;
|
||||
conflictedNote.is_conflict = 1;
|
||||
await Note.save(conflictedNote, { autoTimestamp: false, changeSource: ItemChange.SOURCE_SYNC });
|
||||
await Note.createConflictNote(local, ItemChange.SOURCE_SYNC);
|
||||
}
|
||||
} else if (action == 'resourceConflict') {
|
||||
// ------------------------------------------------------------------------------
|
||||
|
@ -6,6 +6,7 @@ import { sortedIds, createNTestNotes, setupDatabaseAndSynchronizer, switchClient
|
||||
import Folder from './Folder';
|
||||
import Note from './Note';
|
||||
import Tag from './Tag';
|
||||
import ItemChange from './ItemChange';
|
||||
const ArrayUtils = require('../ArrayUtils.js');
|
||||
|
||||
async function allItems() {
|
||||
@ -344,4 +345,44 @@ describe('models_Note', function() {
|
||||
expect(sortedNotes3[4].id).toBe(note2.id);
|
||||
}));
|
||||
|
||||
it('should create a conflict note', async () => {
|
||||
const folder = await Folder.save({ title: 'Source Folder' });
|
||||
const origNote = await Note.save({ title: 'note', parent_id: folder.id });
|
||||
const conflictedNote = await Note.createConflictNote(origNote, ItemChange.SOURCE_SYNC);
|
||||
|
||||
expect(conflictedNote.is_conflict).toBe(1);
|
||||
expect(conflictedNote.conflict_original_id).toBe(origNote.id);
|
||||
expect(conflictedNote.parent_id).toBe(folder.id);
|
||||
});
|
||||
|
||||
it('should copy conflicted note to target folder and cancel conflict', (async () => {
|
||||
const srcfolder = await Folder.save({ title: 'Source Folder' });
|
||||
const targetfolder = await Folder.save({ title: 'Target Folder' });
|
||||
|
||||
const note1 = await Note.save({ title: 'note', parent_id: srcfolder.id });
|
||||
const conflictedNote = await Note.createConflictNote(note1, ItemChange.SOURCE_SYNC);
|
||||
|
||||
const note2 = await Note.copyToFolder(conflictedNote.id, targetfolder.id);
|
||||
|
||||
expect(note2.id === conflictedNote.id).toBe(false);
|
||||
expect(note2.title).toBe(conflictedNote.title);
|
||||
expect(note2.is_conflict).toBe(0);
|
||||
expect(note2.conflict_original_id).toBe('');
|
||||
expect(note2.parent_id).toBe(targetfolder.id);
|
||||
}));
|
||||
|
||||
it('should move conflicted note to target folder and cancel conflict', (async () => {
|
||||
const srcFolder = await Folder.save({ title: 'Source Folder' });
|
||||
const targetFolder = await Folder.save({ title: 'Target Folder' });
|
||||
const note1 = await Note.save({ title: 'note', parent_id: srcFolder.id });
|
||||
|
||||
const conflictedNote = await Note.createConflictNote(note1, ItemChange.SOURCE_SYNC);
|
||||
|
||||
const movedNote = await Note.moveToFolder(conflictedNote.id, targetFolder.id);
|
||||
|
||||
expect(movedNote.parent_id).toBe(targetFolder.id);
|
||||
expect(movedNote.is_conflict).toBe(0);
|
||||
expect(movedNote.conflict_original_id).toBe('');
|
||||
}));
|
||||
|
||||
});
|
||||
|
@ -523,6 +523,7 @@ export default class Note extends BaseItem {
|
||||
changes: {
|
||||
parent_id: folderId,
|
||||
is_conflict: 0, // Also reset the conflict flag in case we're moving the note out of the conflict folder
|
||||
conflict_original_id: '', // Reset parent id as well.
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -537,6 +538,7 @@ export default class Note extends BaseItem {
|
||||
id: noteId,
|
||||
parent_id: folderId,
|
||||
is_conflict: 0,
|
||||
conflict_original_id: '',
|
||||
updated_time: time.unixMs(),
|
||||
};
|
||||
|
||||
@ -911,4 +913,12 @@ export default class Note extends BaseItem {
|
||||
return new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
|
||||
}
|
||||
|
||||
|
||||
static async createConflictNote(sourceNote: NoteEntity, changeSource: number): Promise<NoteEntity> {
|
||||
const conflictNote = Object.assign({}, sourceNote);
|
||||
delete conflictNote.id;
|
||||
conflictNote.is_conflict = 1;
|
||||
conflictNote.conflict_original_id = sourceNote.id;
|
||||
return await Note.save(conflictNote, { autoTimestamp: false, changeSource: changeSource });
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ export interface NoteEntity {
|
||||
"created_time"?: number
|
||||
"updated_time"?: number
|
||||
"is_conflict"?: number
|
||||
"conflict_original_id"?: string
|
||||
"latitude"?: number
|
||||
"longitude"?: number
|
||||
"altitude"?: number
|
||||
|
@ -44,9 +44,10 @@ describe('Synchronizer.conflicts', function() {
|
||||
// the conflicted and original note must be the same in every way, to make sure no data has been lost.
|
||||
const conflictedNote = conflictedNotes[0];
|
||||
expect(conflictedNote.id == note2conf.id).toBe(false);
|
||||
expect(conflictedNote.conflict_original_id).toBe(note2conf.id);
|
||||
for (const n in conflictedNote) {
|
||||
if (!conflictedNote.hasOwnProperty(n)) continue;
|
||||
if (n == 'id' || n == 'is_conflict') continue;
|
||||
if (n == 'id' || n == 'is_conflict' || n == 'conflict_original_id') continue;
|
||||
expect(conflictedNote[n]).toBe(note2conf[n]);
|
||||
}
|
||||
|
||||
|
@ -477,6 +477,7 @@ encryption_applied: 0
|
||||
markup_language: 1
|
||||
is_shared: 1
|
||||
share_id: ${note.share_id || ''}
|
||||
conflict_original_id:
|
||||
type_: 1`;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user