const path = require('path');
module.exports = function(r) {

    async function moveDir(directoryId, toDirectoryId) {
        let dirs = await r.table('datadirs').getAll(directoryId, toDirectoryId);
        let origDir = dirs.filter(d => d.id === directoryId)[0];
        let toDir = dirs.filter(d => d.id === toDirectoryId)[0];
        let origDirName = path.basename(origDir.name);
        let newPathName = path.join(toDir.name, origDirName);
        await moveDirAndDescendents(directoryId, origDir.name, newPathName);
        await r.table('datadirs').get(directoryId).update({parent: toDir.id});
    }

    // renameChildDirs renames all the children of directoryId by replacing
    // the old name with the new name. The reason this is done is because
    // directory names contain the full path.
    //
    // Example:
    //    Given project/dir1/dir2/dir3
    //    There are 4 directories named:
    //       project
    //       project/dir1
    //       project/dir1/dir2
    //       project/dir1/dir2/dir3
    //    If dir1 renamed to newdir1, then the names for the directories
    //    would need to be:
    //       project
    //       project/newdir1
    //       project/newdir1/dir2
    //       project/newdir1/dir2/dir3
    //
    // This method will find all the descendents or dir1 and update their
    // names to reflect the new structure above.
    async function moveDirAndDescendents(directoryId, oldPath, newPath) {
        let dir = await r.table('datadirs').get(directoryId);

        // For this part we want to do the updates as efficiently as
        // possible by doing them in one go, rather than making multiple
        // calls to the database. To do this we are going to gather all
        // the entries into a set, changes their names then do a single
        // write back to the database.
        // Since we need to get all descendents we have to continue to
        // run queries as we go through all the dirs.
        let directoryIdSet = new Set([directoryId]); // initialize with first dir
        let size = directoryIdSet.size;
        let oldSize = 0;
        // Loop until our queries don't change the set.
        while (size !== oldSize) {
            oldSize = size;
            // Take all the ids from the directoryIdSet and find the directories that have them
            // as a parent. We are redundantly querying from the set which means we are querying on
            // dirs we queried before plus new ones. This is inefficient but in practice hasn't affected
            // the application.
            let directoryList = await r.table('datadirs').getAll(r.args([...directoryIdSet]), {index: 'parent'});
            // Add directories from query into set
            for (let i = 0; i < directoryList.length; i++) {
                directoryIdSet.add(directoryList[i].id);
            }

            // Set size to new size. Thus if the nothing new was added, then the loop
            // will exit because size === oldSize.
            size = directoryIdSet.size;
        }

        // This point we have all the directory ids in directoryIdSet that we want to change,
        // so make a query to get them all and then rename their paths.
        let directoryList = await r.table('datadirs').getAll(r.args([...directoryIdSet]));

        // Rename the directories to the new path
        for (let i = 0; i < directoryList.length; i++) {
            let directory = directoryList[i];
            directory.name = directory.name.replace(oldPath, newPath);
        }

        // Update database in a single call
        await r.table('datadirs').insert(directoryList, {conflict: 'update'});

        // last step is to set the original directories new parent if newDir is set
        let parentPath = path.basename(newPath);
    }

    async function renameDir(directoryId, newDirectoryName) {
        let dir = await r.table('datadirs').get(directoryId);
        let oldName = dir.name;

        // replace the last entry in the name with newDirectoryName
        // ie, given name a/b/c then c is what we are renaming.
        // So, if we split on '/', then the last entry will b 'c',
        // and we can replace c with the new name.
        // Example:
        //    (assume newName = 'd')
        //    let parts = "a/b/c".split('/') // => ['a', 'b', 'c']
        //    So to replace 'c' with new name
        //    parts[parts.length-1] = newName;
        //    so parts is now => ['a', 'b', 'd']
        //
        let dirParts = oldName.split('/');
        dirParts[dirParts.length - 1] = newDirectoryName;

        // Following our example above, we join on parts to
        // get the new path, ie
        // parts.join('/') => 'a/b/d', which is the new name for
        // the directory.
        let fixedNamePath = dirParts.join('/');
        await moveDirAndDescendents(directoryId, oldName, fixedNamePath);
    }

    return {
        moveDir,
        renameDir,
    };
};
@@ -1448,71 +1448,8 @@
 ) %7B%0A
-        let dir = await r.table('datadirs').get(directoryId);%0A%0A
     
@@ -3598,142 +3598,8 @@
 '%7D);
-%0A%0A        // last step is to set the original directories new parent if newDir is set%0A        let parentPath = path.basename(newPath);
 %0A   

Remove unused code and comment that implies something is going to happen but there is nothing to do