You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Fixing sync
This commit is contained in:
		| @@ -23,6 +23,14 @@ let fileDriver = new FileApiDriverLocal(); | ||||
| let fileApi = new FileApi('/home/laurent/Temp/TestImport', fileDriver); | ||||
| let synchronizer = new Synchronizer(db, fileApi); | ||||
|  | ||||
| function sleep(n) { | ||||
| 	return new Promise((resolve, reject) => { | ||||
| 		setTimeout(() => { | ||||
| 			resolve(); | ||||
| 		}, n * 1000); | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| function clearDatabase() { | ||||
| 	let queries = [ | ||||
| 		'DELETE FROM changes', | ||||
| @@ -34,6 +42,35 @@ function clearDatabase() { | ||||
| 	return db.transactionExecBatch(queries); | ||||
| } | ||||
|  | ||||
| async function runTest() { | ||||
| 	db.setDebugEnabled(!true); | ||||
| 	await db.open({ name: '/home/laurent/Temp/test-sync.sqlite3' }); | ||||
|  | ||||
| 	BaseModel.db_ = db; | ||||
| 	 	 | ||||
| 	await clearDatabase(); | ||||
|  | ||||
| 	let folder = await Folder.save({ title: "folder1" }); | ||||
| 	let note1 = await Note.save({ title: "un", parent_id: folder.id }); | ||||
| 	await Note.save({ title: "deux", parent_id: folder.id }); | ||||
| 	folder = await Folder.save({ title: "folder2" }); | ||||
| 	await Note.save({ title: "trois", parent_id: folder.id }); | ||||
|  | ||||
| 	await synchronizer.start(); | ||||
|  | ||||
| 	note1 = await Note.load(note1.id); | ||||
| 	note1.title = 'un update'; | ||||
| 	await Note.save(note1); | ||||
|  | ||||
| 	await synchronizer.start(); | ||||
| } | ||||
|  | ||||
| runTest(); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| function createRemoteItems() { | ||||
| 	let a = fileApi; | ||||
| 	return Promise.all([a.mkdir('test1'), a.mkdir('test2'), a.mkdir('test3')]).then(() => { | ||||
| @@ -56,6 +93,7 @@ async function createLocalItems() { | ||||
| 	folder = await Folder.save({ title: "folder2" }); | ||||
| 	await Note.save({ title: "trois", parent_id: folder.id }); | ||||
|  | ||||
|  | ||||
| 	// let folder = await Folder.save({ title: "folder1" }); | ||||
| 	// await Note.save({ title: "un", parent_id: folder.id }); | ||||
| 	// await Note.save({ title: "deux", parent_id: folder.id }); | ||||
| @@ -73,16 +111,19 @@ async function createLocalItems() { | ||||
| 	// await Note.save({ title: "huit", parent_id: folder.id }); | ||||
| } | ||||
|  | ||||
| db.setDebugEnabled(!true); | ||||
| db.open({ name: '/home/laurent/Temp/test-sync.sqlite3' }).then(() => { | ||||
|  	BaseModel.db_ = db; | ||||
|  	//return clearDatabase(); | ||||
|  	return clearDatabase().then(createLocalItems); | ||||
| }).then(() => { | ||||
| 	return synchronizer.start(); | ||||
| }).catch((error) => { | ||||
| 	console.error(error); | ||||
| }); | ||||
|  | ||||
|  | ||||
|  | ||||
| // db.setDebugEnabled(!true); | ||||
| // db.open({ name: '/home/laurent/Temp/test-sync.sqlite3' }).then(() => { | ||||
| //  	BaseModel.db_ = db; | ||||
| //  	//return clearDatabase(); | ||||
| //  	return clearDatabase().then(createLocalItems); | ||||
| // }).then(() => { | ||||
| // 	return synchronizer.start(); | ||||
| // }).catch((error) => { | ||||
| // 	console.error(error); | ||||
| // }); | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import { BaseModel } from 'src/base-model.js'; | ||||
| import { promiseChain } from 'src/promise-utils.js'; | ||||
| import { NoteFolderService } from 'src/services/note-folder-service.js'; | ||||
| import { time } from 'src/time-utils.js'; | ||||
| import { sprintf } from 'sprintf-js'; | ||||
| //import { promiseWhile } from 'src/promise-utils.js'; | ||||
| import moment from 'moment'; | ||||
|  | ||||
| @@ -83,10 +84,6 @@ class Synchronizer { | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	// isNewerThan(date1, date2) { | ||||
| 	// 	return date1 > date2; | ||||
| 	// } | ||||
|  | ||||
| 	itemByPath(items, path) { | ||||
| 		for (let i = 0; i < items.length; i++) { | ||||
| 			if (items[i].path == path) return items[i]; | ||||
| @@ -95,16 +92,14 @@ class Synchronizer { | ||||
| 	} | ||||
|  | ||||
| 	itemIsSameDate(item, date) { | ||||
| 		return Math.abs(item.updatedTime - date) <= 1; | ||||
| 		return item.updatedTime === date; | ||||
| 	} | ||||
|  | ||||
| 	itemIsNewerThan(item, date) { | ||||
| 		if (this.itemIsSameDate(item, date)) return false; | ||||
| 	itemIsStrictlyNewerThan(item, date) { | ||||
| 		return item.updatedTime > date; | ||||
| 	} | ||||
|  | ||||
| 	itemIsOlderThan(item, date) { | ||||
| 		if (this.itemIsSameDate(item, date)) return false; | ||||
| 	itemIsStrictlyOlderThan(item, date) { | ||||
| 		return item.updatedTime < date; | ||||
| 	} | ||||
|  | ||||
| @@ -177,13 +172,19 @@ class Synchronizer { | ||||
| 					action.dest = 'remote'; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (this.itemIsOlderThan(local, local.syncTime)) continue; | ||||
| 				if (this.itemIsStrictlyOlderThan(local, local.syncTime)) continue; | ||||
|  | ||||
| 				if (this.itemIsOlderThan(remote, local.syncTime)) { | ||||
| 				if (this.itemIsStrictlyOlderThan(remote, local.syncTime)) { | ||||
| 					action.type = 'update'; | ||||
| 					action.dest = 'remote'; | ||||
| 				} else { | ||||
| 				} else if (this.itemIsStrictlyNewerThan(remote, local.syncTime)) { | ||||
| 					action.type = 'conflict'; | ||||
| 					action.reason = sprintf('Both remote (%s) and local items (%s) were modified after the last sync (%s).', | ||||
| 						moment.unix(remote.updatedTime).toISOString(), | ||||
| 						moment.unix(local.updatedTime).toISOString(), | ||||
| 						moment.unix(local.syncTime).toISOString() | ||||
| 					); | ||||
|  | ||||
| 					if (local.type == 'folder') { | ||||
| 						// For folders, currently we don't completely handle conflicts, we just | ||||
| 						// we just update the local dir (.folder metadata file) with the remote | ||||
| @@ -199,6 +200,8 @@ class Synchronizer { | ||||
| 							{ type: 'update', dest: 'local' }, | ||||
| 						]; | ||||
| 					} | ||||
| 				} else { | ||||
| 					continue; // Neither local nor remote item have been changed recently | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -226,7 +229,7 @@ class Synchronizer { | ||||
| 					action.dest = 'local'; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (this.itemIsOlderThan(remote, local.syncTime)) continue; // Already have this version | ||||
| 				if (this.itemIsStrictlyOlderThan(remote, local.syncTime)) continue; // Already have this version | ||||
| 				// Note: no conflict is possible here since if the local item has been | ||||
| 				// modified since the last sync, it's been processed in the previous loop. | ||||
| 				action.type = 'update'; | ||||
| @@ -265,7 +268,10 @@ class Synchronizer { | ||||
|  | ||||
| 		if (!action) return Promise.resolve(); | ||||
|  | ||||
| 		console.info('Sync action: ' + action.type + ' ' + action.dest); | ||||
|  | ||||
| 		if (action.type == 'conflict') { | ||||
| 			console.info(action); | ||||
|  | ||||
| 		} else { | ||||
| 			let syncItem = action[action.dest == 'local' ? 'remote' : 'local']; | ||||
| @@ -372,6 +378,8 @@ class Synchronizer { | ||||
| 		for (let i = 0; i < items.length; i++) { | ||||
| 			await this.processRemoteItem(items[i]); | ||||
| 		} | ||||
|  | ||||
| 		return this.processState('idle'); | ||||
| 	} | ||||
|  | ||||
| 	start() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user