Fixed circular reference issues
This commit is contained in:
parent
d4624eba9d
commit
3fc974c14c
@ -133,11 +133,15 @@ const localDbSvc = {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Create the DB transaction
|
||||
this.connection.createTx((tx) => {
|
||||
const { lastTx } = this;
|
||||
|
||||
// Look for DB changes and apply them to the store
|
||||
this.readAll(tx, (storeItemMap) => {
|
||||
// Sanitize the workspace
|
||||
workspaceSvc.ensureUniquePaths();
|
||||
workspaceSvc.ensureUniqueLocations();
|
||||
// Sanitize the workspace if changes have been applied
|
||||
if (lastTx !== this.lastTx) {
|
||||
workspaceSvc.sanitizeWorkspace();
|
||||
}
|
||||
|
||||
// Persist all the store changes into the DB
|
||||
this.writeAll(storeItemMap, tx);
|
||||
// Sync the localStorage
|
||||
@ -156,7 +160,7 @@ const localDbSvc = {
|
||||
let { lastTx } = this;
|
||||
const dbStore = tx.objectStore(dbStoreName);
|
||||
const index = dbStore.index('tx');
|
||||
const range = window.IDBKeyRange.lowerBound(this.lastTx, true);
|
||||
const range = IDBKeyRange.lowerBound(this.lastTx, true);
|
||||
const changes = [];
|
||||
index.openCursor(range).onsuccess = (event) => {
|
||||
const cursor = event.target.result;
|
||||
@ -225,7 +229,7 @@ const localDbSvc = {
|
||||
tx: incrementedTx,
|
||||
});
|
||||
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);
|
||||
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);
|
||||
|
||||
// Sanitize the workspace
|
||||
workspaceSvc.ensureUniquePaths(idsToKeep);
|
||||
workspaceSvc.ensureUniqueLocations(idsToKeep);
|
||||
workspaceSvc.sanitizeWorkspace(idsToKeep);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -134,6 +134,9 @@ export default {
|
||||
// Save item in the store
|
||||
store.commit(`${item.type}/setItem`, item);
|
||||
|
||||
// Remove circular reference
|
||||
this.removeCircularReference(item);
|
||||
|
||||
// Ensure path uniqueness
|
||||
if (store.getters['workspace/currentWorkspaceHasUniquePaths']) {
|
||||
this.makePathUnique(item.id);
|
||||
@ -162,6 +165,37 @@ export default {
|
||||
.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.
|
||||
*/
|
||||
|
@ -122,7 +122,6 @@ export default {
|
||||
});
|
||||
|
||||
// Build the tree
|
||||
const parentsMap = {};
|
||||
Object.entries(nodeMap).forEach(([, node]) => {
|
||||
let parentNode = nodeMap[node.item.parentId];
|
||||
if (!parentNode || !parentNode.isFolder) {
|
||||
@ -130,18 +129,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
parentNode.folders.push(node);
|
||||
|
Loading…
Reference in New Issue
Block a user