Hmm, maybe it’s not as I understood. I’ve deleted the code that was doing this so will have to backtrack and see what happens. I’ll get back to you.
Until I do, I think one difference is that I was using the File returned by fetch() then insert /update to another entry, then delete the original entry. But the File has the version of the other entry.
EDIT: My editor had the deleted code in its undo cache You could run this again if you want to try it out (using SAFE Drive), by adding it back in place of copyFile()
in safentworkjs/src/nfs-files.js), but maybe it is just enough for it to confirm what I said immediately above. It just shows that I’m using a File obtained from fetch()
to call insert()
or update()
and subsequently use it again for delete()
that’s the point where the version is wrong.
async copyFile_TEST (sourcePath, destinationPath, copyMetadata) {
debug('%s.MODIFIED copyFile(\'%s\', \'%s\')', this.constructor.name, sourcePath, destinationPath, copyMetadata)
try {
let srcFileState = await this.getOrFetchFileState(sourcePath)
if (!srcFileState) throw new Error('copyFile error - source file not found:', sourcePath)
if (!copyMetadata) {
// TODO need to clear and reset metadata in srcFileState._fileFetched before
// Have asked for advice on how to do this: https://forum.safedev.org/t/implementing-nfs-api-rename/2109/5?u=happybeing
}
let destFileState = await this.getOrFetchFileState(destinationPath)
if (!destFileState) {
await this.nfs().insert(destinationPath, srcFileState._fileFetched)
} else {
await this.nfs().update(destinationPath, srcFileState._fileFetched, destFileState._fileFetched.version + 1)
}
await this.nfs().delete(sourcePath, srcFileState._fileFetched.version + 1)
} catch (e) {
debug(e)
throw e
}
}
If you look at the now working code in copyFile()
(this is now all pushed to master BTW), you can see I got it to work by calling _purgeFileState(srcFileState)
which ensures that when I try to delete (which is in moveFile()
) the File handle used by copyFile()
has been discarded from my cache and will be fetched anew.
async copyFile (sourcePath, destinationPath, copyMetadata) {
debug('%s.copyFile(\'%s\', \'%s\')', this.constructor.name, sourcePath, destinationPath, copyMetadata)
try {
let srcFileState = await this.getOrFetchFileState(sourcePath)
if (!srcFileState) throw new Error('copyFile error - source file not found:', sourcePath)
if (!copyMetadata) {
// TODO need to clear and reset metadata in srcFileState._fileFetched before
// Have asked for advice on how to do this: https://forum.safedev.org/t/implementing-nfs-api-rename/2109/5?u=happybeing
}
let perms // If auth needed, request default permissions
let destFileState = await this.getOrFetchFileState(destinationPath)
if (!destFileState) {
// Destination is a new file, so insert
await this._safeJs.nfsMutate(this.nfs(), perms, 'insert', destinationPath, srcFileState._fileFetched)
} else {
// Destination exists, so update
await this._safeJs.nfsMutate(this.nfs(), perms, 'update', destinationPath, srcFileState._fileFetched, destFileState.version() + 1)
await this._purgeFileState(destFileState) // New file so purge the cache
}
// After using the fetched file to update another entry, it takes on the version of the other, so needs refreshing
await this._purgeFileState(srcFileState)
} catch (e) {
debug(e)
throw e
}
}
It may be a bit confusing to follow the above fragments because in copyFile_TEST()
I’m calling the NFS API directly to help debugging, whereas in copyFile()
I’m calling those same functions, but via other APIs such as _safeJs.nfsMutate()
(which will do an auth request if needed).
Hope that helps!