Fixed circular reference issues
This commit is contained in:
parent
d4624eba9d
commit
3fc974c14c
@ -133,11 +133,15 @@ const localDbSvc = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// Create the DB transaction
|
// Create the DB transaction
|
||||||
this.connection.createTx((tx) => {
|
this.connection.createTx((tx) => {
|
||||||
|
const { lastTx } = this;
|
||||||
|
|
||||||
// Look for DB changes and apply them to the store
|
// Look for DB changes and apply them to the store
|
||||||
this.readAll(tx, (storeItemMap) => {
|
this.readAll(tx, (storeItemMap) => {
|
||||||
// Sanitize the workspace
|
// Sanitize the workspace if changes have been applied
|
||||||
workspaceSvc.ensureUniquePaths();
|
if (lastTx !== this.lastTx) {
|
||||||
workspaceSvc.ensureUniqueLocations();
|
workspaceSvc.sanitizeWorkspace();
|
||||||
|
}
|
||||||
|
|
||||||
// Persist all the store changes into the DB
|
// Persist all the store changes into the DB
|
||||||
this.writeAll(storeItemMap, tx);
|
this.writeAll(storeItemMap, tx);
|
||||||
// Sync the localStorage
|
// Sync the localStorage
|
||||||
@ -156,7 +160,7 @@ const localDbSvc = {
|
|||||||
let { lastTx } = this;
|
let { lastTx } = this;
|
||||||
const dbStore = tx.objectStore(dbStoreName);
|
const dbStore = tx.objectStore(dbStoreName);
|
||||||
const index = dbStore.index('tx');
|
const index = dbStore.index('tx');
|
||||||
const range = window.IDBKeyRange.lowerBound(this.lastTx, true);
|
const range = IDBKeyRange.lowerBound(this.lastTx, true);
|
||||||
const changes = [];
|
const changes = [];
|
||||||
index.openCursor(range).onsuccess = (event) => {
|
index.openCursor(range).onsuccess = (event) => {
|
||||||
const cursor = event.target.result;
|
const cursor = event.target.result;
|
||||||
@ -225,7 +229,7 @@ const localDbSvc = {
|
|||||||
tx: incrementedTx,
|
tx: incrementedTx,
|
||||||
});
|
});
|
||||||
delete this.hashMap[type][id];
|
delete this.hashMap[type][id];
|
||||||
this.lastTx = incrementedTx; // No need to read what we just wrote
|
this.lastTx = incrementedTx;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -239,7 +243,7 @@ const localDbSvc = {
|
|||||||
};
|
};
|
||||||
dbStore.put(item);
|
dbStore.put(item);
|
||||||
this.hashMap[item.type][item.id] = item.hash;
|
this.hashMap[item.type][item.id] = item.hash;
|
||||||
this.lastTx = incrementedTx; // No need to read what we just wrote
|
this.lastTx = incrementedTx;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -185,8 +185,7 @@ const applyChanges = (changes) => {
|
|||||||
store.dispatch('data/setSyncDataById', syncDataById);
|
store.dispatch('data/setSyncDataById', syncDataById);
|
||||||
|
|
||||||
// Sanitize the workspace
|
// Sanitize the workspace
|
||||||
workspaceSvc.ensureUniquePaths(idsToKeep);
|
workspaceSvc.sanitizeWorkspace(idsToKeep);
|
||||||
workspaceSvc.ensureUniqueLocations(idsToKeep);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,6 +134,9 @@ export default {
|
|||||||
// Save item in the store
|
// Save item in the store
|
||||||
store.commit(`${item.type}/setItem`, item);
|
store.commit(`${item.type}/setItem`, item);
|
||||||
|
|
||||||
|
// Remove circular reference
|
||||||
|
this.removeCircularReference(item);
|
||||||
|
|
||||||
// Ensure path uniqueness
|
// Ensure path uniqueness
|
||||||
if (store.getters['workspace/currentWorkspaceHasUniquePaths']) {
|
if (store.getters['workspace/currentWorkspaceHasUniquePaths']) {
|
||||||
this.makePathUnique(item.id);
|
this.makePathUnique(item.id);
|
||||||
@ -162,6 +165,37 @@ export default {
|
|||||||
.forEach(item => store.commit('publishLocation/deleteItem', item.id));
|
.forEach(item => store.commit('publishLocation/deleteItem', item.id));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitize the whole workspace.
|
||||||
|
*/
|
||||||
|
sanitizeWorkspace(idsToKeep) {
|
||||||
|
// Detect and remove circular references for all folders.
|
||||||
|
store.getters['folder/items'].forEach(folder => this.removeCircularReference(folder));
|
||||||
|
|
||||||
|
this.ensureUniquePaths(idsToKeep);
|
||||||
|
this.ensureUniqueLocations(idsToKeep);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect and remove circular reference for an item.
|
||||||
|
*/
|
||||||
|
removeCircularReference(item) {
|
||||||
|
const foldersById = store.state.folder.itemsById;
|
||||||
|
for (
|
||||||
|
let parentFolder = foldersById[item.parentId];
|
||||||
|
parentFolder;
|
||||||
|
parentFolder = foldersById[parentFolder.parentId]
|
||||||
|
) {
|
||||||
|
if (parentFolder.id === item.id) {
|
||||||
|
store.commit('folder/patchItem', {
|
||||||
|
id: item.id,
|
||||||
|
parentId: null,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure two files/folders don't have the same path if the workspace doesn't allow it.
|
* Ensure two files/folders don't have the same path if the workspace doesn't allow it.
|
||||||
*/
|
*/
|
||||||
|
@ -122,7 +122,6 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Build the tree
|
// Build the tree
|
||||||
const parentsMap = {};
|
|
||||||
Object.entries(nodeMap).forEach(([, node]) => {
|
Object.entries(nodeMap).forEach(([, node]) => {
|
||||||
let parentNode = nodeMap[node.item.parentId];
|
let parentNode = nodeMap[node.item.parentId];
|
||||||
if (!parentNode || !parentNode.isFolder) {
|
if (!parentNode || !parentNode.isFolder) {
|
||||||
@ -130,18 +129,6 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parentNode = rootNode;
|
parentNode = rootNode;
|
||||||
} else if (node.isFolder) {
|
|
||||||
// Detect circular reference
|
|
||||||
const parentParents = parentsMap[node.item.parentId] || {};
|
|
||||||
if (parentParents[node.item.id]) {
|
|
||||||
// Node is already a parent of its supposed parent
|
|
||||||
parentNode = rootNode;
|
|
||||||
} else {
|
|
||||||
parentsMap[node.item.id] = {
|
|
||||||
...parentParents,
|
|
||||||
[node.item.parentId]: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (node.isFolder) {
|
if (node.isFolder) {
|
||||||
parentNode.folders.push(node);
|
parentNode.folders.push(node);
|
||||||
|
Loading…
Reference in New Issue
Block a user