You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-26 22:41:17 +02:00
handle deleted sync items
This commit is contained in:
@@ -37,6 +37,10 @@ class BaseModel {
|
||||
return false;
|
||||
}
|
||||
|
||||
static trackDeleted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static byId(items, id) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].id == id) return items[i];
|
||||
@@ -239,6 +243,10 @@ class BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
static deletedItems() {
|
||||
return this.db().selectAll('SELECT * FROM deleted_items');
|
||||
}
|
||||
|
||||
static delete(id, options = null) {
|
||||
options = this.modOptions(options);
|
||||
|
||||
@@ -248,6 +256,10 @@ class BaseModel {
|
||||
}
|
||||
|
||||
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]).then(() => {
|
||||
if (this.trackDeleted()) {
|
||||
return this.db().exec('INSERT INTO deleted_items (item_type, item_id, deleted_time) VALUES (?, ?, ?)', [this.itemType(), id, time.unixMs()]);
|
||||
}
|
||||
|
||||
// if (options.trackChanges && this.trackChanges()) {
|
||||
// const { Change } = require('src/models/change.js');
|
||||
|
||||
|
||||
@@ -36,6 +36,13 @@ CREATE TABLE notes (
|
||||
\`order\` INT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE deleted_items (
|
||||
id TEXT PRIMARY KEY,
|
||||
item_type INT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
deleted_time INT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE tags (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT,
|
||||
|
||||
@@ -25,6 +25,10 @@ class Folder extends BaseItem {
|
||||
static trackChanges() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static trackDeleted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static newFolder() {
|
||||
return {
|
||||
@@ -33,8 +37,18 @@ class Folder extends BaseItem {
|
||||
}
|
||||
}
|
||||
|
||||
static noteIds(id) {
|
||||
return this.db().selectAll('SELECT id FROM notes WHERE parent_id = ?', [id]).then((rows) => {
|
||||
static syncedNoteIds() {
|
||||
return this.db().selectAll('SELECT id FROM notes WHERE sync_time > 0').then((rows) => {
|
||||
let output = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
output.push(rows[i].id);
|
||||
}
|
||||
return output;
|
||||
});
|
||||
}
|
||||
|
||||
static noteIds(parentId) {
|
||||
return this.db().selectAll('SELECT id FROM notes WHERE parent_id = ?', [parentId]).then((rows) => {
|
||||
let output = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
@@ -46,6 +60,8 @@ class Folder extends BaseItem {
|
||||
|
||||
static delete(folderId, options = null) {
|
||||
return this.load(folderId).then((folder) => {
|
||||
if (!folder) throw new Error('Trying to delete non-existing folder: ' + folderId);
|
||||
|
||||
if (!!folder.is_default) {
|
||||
throw new Error(_('Cannot delete the default list'));
|
||||
}
|
||||
@@ -72,7 +88,6 @@ class Folder extends BaseItem {
|
||||
|
||||
static loadNoteByField(folderId, field, value) {
|
||||
return this.modelSelectAll('SELECT * FROM notes WHERE `parent_id` = ? AND `' + field + '` = ?', [folderId, value]);
|
||||
//return this.db().selectOne('SELECT * FROM notes WHERE `parent_id` = ? AND `' + field + '` = ?', [folderId, value]);
|
||||
}
|
||||
|
||||
static async all(includeNotes = false) {
|
||||
|
||||
@@ -24,6 +24,10 @@ class Note extends BaseItem {
|
||||
return true;
|
||||
}
|
||||
|
||||
static trackDeleted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static new(parentId = '') {
|
||||
let output = super.new();
|
||||
output.parent_id = parentId;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
// A service that handle notes and folders in a uniform way
|
||||
|
||||
|
||||
// TODO: remote this service
|
||||
// - Move setting of geo-location to GUI side (only for note explicitely created on client
|
||||
// - Don't do diffing - make caller explicitely set model properties that need to be saved
|
||||
|
||||
import { BaseService } from 'src/base-service.js';
|
||||
import { BaseModel } from 'src/base-model.js';
|
||||
import { BaseItem } from 'src/models/base-item.js';
|
||||
|
||||
@@ -48,7 +48,13 @@ class Synchronizer {
|
||||
let updateSyncTimeOnly = true;
|
||||
|
||||
if (!remote) {
|
||||
action = 'createRemote';
|
||||
if (!local.sync_time) {
|
||||
action = 'createRemote';
|
||||
} else {
|
||||
// Note or folder was modified after having been deleted remotely
|
||||
action = local.type_ == BaseModel.MODEL_TYPE_NOTE ? 'noteConflict' : 'folderConflict';
|
||||
// TODO: handle conflict
|
||||
}
|
||||
} else {
|
||||
if (remote.updated_time > local.sync_time) {
|
||||
// Since, in this loop, we are only dealing with notes that require sync, if the
|
||||
@@ -107,10 +113,12 @@ class Synchronizer {
|
||||
// At this point all the local items that have changed have been pushed to remote
|
||||
// or handled as conflicts, so no conflict is possible after this.
|
||||
|
||||
let remoteIds = [];
|
||||
let remotes = await this.api().list();
|
||||
for (let i = 0; i < remotes.length; i++) {
|
||||
let remote = remotes[i];
|
||||
let path = remote.path;
|
||||
remoteIds.push(BaseItem.pathToId(path));
|
||||
if (donePaths.indexOf(path) > 0) continue;
|
||||
|
||||
let action = null;
|
||||
@@ -143,6 +151,18 @@ class Synchronizer {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Search, among the local IDs, those that don't exist remotely, which
|
||||
// means the item has been deleted.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// let noteIds = Folder.syncedNoteIds();
|
||||
// for (let i = 0; i < noteIds.length; i++) {
|
||||
// if (remoteIds.indexOf(noteIds[i]) < 0) {
|
||||
// console.info('Sync action (3): Delete ' + noteIds[i]);
|
||||
// await Note.delete(noteIds[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user