(oldPath: string, newPath: string, cb: BFSOneArgCallback)
| 749 | } |
| 750 | |
| 751 | public rename(oldPath: string, newPath: string, cb: BFSOneArgCallback): void { |
| 752 | const tx = this.store.beginTransaction('readwrite'); |
| 753 | const oldParent = path.dirname(oldPath), oldName = path.basename(oldPath); |
| 754 | const newParent = path.dirname(newPath), newName = path.basename(newPath); |
| 755 | const inodes: { [path: string]: Inode } = {}; |
| 756 | const lists: { |
| 757 | [path: string]: { [file: string]: string } |
| 758 | } = {}; |
| 759 | let errorOccurred: boolean = false; |
| 760 | |
| 761 | // Invariant: Can't move a folder inside itself. |
| 762 | // This funny little hack ensures that the check passes only if oldPath |
| 763 | // is a subpath of newParent. We append '/' to avoid matching folders that |
| 764 | // are a substring of the bottom-most folder in the path. |
| 765 | if ((newParent + '/').indexOf(oldPath + '/') === 0) { |
| 766 | return cb(new ApiError(ErrorCode.EBUSY, oldParent)); |
| 767 | } |
| 768 | |
| 769 | /** |
| 770 | * Responsible for Phase 2 of the rename operation: Modifying and |
| 771 | * committing the directory listings. Called once we have successfully |
| 772 | * retrieved both the old and new parent's inodes and listings. |
| 773 | */ |
| 774 | const theOleSwitcharoo = (): void => { |
| 775 | // Sanity check: Ensure both paths are present, and no error has occurred. |
| 776 | if (errorOccurred || !lists.hasOwnProperty(oldParent) || !lists.hasOwnProperty(newParent)) { |
| 777 | return; |
| 778 | } |
| 779 | const oldParentList = lists[oldParent], oldParentINode = inodes[oldParent], |
| 780 | newParentList = lists[newParent], newParentINode = inodes[newParent]; |
| 781 | |
| 782 | // Delete file from old parent. |
| 783 | if (!oldParentList[oldName]) { |
| 784 | cb(ApiError.ENOENT(oldPath)); |
| 785 | } else { |
| 786 | const fileId = oldParentList[oldName]; |
| 787 | delete oldParentList[oldName]; |
| 788 | |
| 789 | // Finishes off the renaming process by adding the file to the new |
| 790 | // parent. |
| 791 | const completeRename = () => { |
| 792 | newParentList[newName] = fileId; |
| 793 | // Commit old parent's list. |
| 794 | tx.put(oldParentINode.id, Buffer.from(JSON.stringify(oldParentList)), true, (e: ApiError) => { |
| 795 | if (noErrorTx(e, tx, cb)) { |
| 796 | if (oldParent === newParent) { |
| 797 | // DONE! |
| 798 | tx.commit(cb); |
| 799 | } else { |
| 800 | // Commit new parent's list. |
| 801 | tx.put(newParentINode.id, Buffer.from(JSON.stringify(newParentList)), true, (e: ApiError) => { |
| 802 | if (noErrorTx(e, tx, cb)) { |
| 803 | tx.commit(cb); |
| 804 | } |
| 805 | }); |
| 806 | } |
| 807 | } |
| 808 | }); |
nothing calls this directly
no test coverage detected