Open dwhipps opened 7 years ago
It looks like IDBFS does not offer a direct API to do that. Currently it looks like the mount point name is taken as the database name: https://github.com/kripken/emscripten/blob/master/src/library_idbfs.js#L112. Perhaps that will be static enough to do a deletion?
Here is the code I use in one project for IndexedDB (though that one is not IDBFS based):
function deleteIndexedDBCache(dbName, onsuccess, onerror, onblocked) {
var idb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if (exinstingDBConnectionInstance) exinstingDBConnectionInstance.close(); // Otherwise .onblocked() event will occur
var req = indexedDB.deleteDatabase(dbName);
req.onsuccess = function() { console.log('Deleted IndexedDB cache ' + dbName + '!'); if (onsuccess) onsuccess(); }
req.onerror = function() { console.error('Failed to delete IndexedDB cache ' + dbName + '!'); if (onerror) onerror(); }
req.onblocked = function() { console.error('Failed to delete IndexedDB cache ' + dbName + ', DB was blocked!'); if (onblocked) onblocked(); }
}
@juj Thanks for this. I decided to go another route... I recursive-delete all files in the local (in memory) FileSystem, then immediately sync that back to the IDBFs. It seemed cleaner and doesn't rely on any undocumented behaviour.
@dwhipps Can you provide an example how you did that?
I mean, I'm trying to do this exact same task and for some reason I could not get it right PS: I'm quite new on JS stuff so I really don't know if I'm missing some obvious thing!
Here's my "example" code:
function DeleteSfuff_Example() {
debugger;
var l = FS.readdir("/Contents/Resources"); // My initial path
for(var i in l) {
var item = l[i]
var fullpath = "/Contents/Resources/" + item;
if(item == "." || item == "..") {
console.log("Ignoring -- " + fullpath);
continue;
}
var is_directory = true;
try {
console.log("REading dir: " + fullpath);
FS.readdir(fullpath); // FS.isDir(fullpath) always return false IDK why...
} catch(e) {
is_directory = false;
console.log(fullpath + " is not directory");
}
if(is_directory) {
continue;
}
try {
// Actually this isn't quite working...
IDBStore.deleteFile("/Contents/Resources", fullpath, function(){});
} catch(e) {
console.log("Failed to delete: " + fullpath);
}
}
}
Just write a function that deletes all files in a tree using a c-function (there are lots of examples of this out there), then call that function from JavaScript. Make sure you export the function and call it with ccall().
Here's one example. Use at your own risk!
// Deletes an entire folder tree of its files, but leaves directories
void deleteAllFilesInPath(const char* pathToRM) {
DIR *d;
struct dirent *dir;
d = opendir(pathToRM);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
std::string fullpath(pathToRM);
fullpath += '/' + std::string(dir->d_name);
if ((dir->d_type == DT_DIR) && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0) {
deleteAllFilesInPath(fullpath.c_str());
} else if (dir->d_type != DT_DIR) {
if (remove(fullpath.c_str()) != 0)
printf("FAILED to delete file: %s\n", dir->d_name);
}
}
closedir(d);
}
}
Also stumbled on this. Since IDBFS is often used for cache, a purge operation would be very useful @kripken
I agree it would be nice to add a helper function for this on IDBFS, reopening.
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.
stale bump
hey, it would be nice to have this in JS land!
From what I can tell it's something like this maybe?
function force_rmdir(path) {
FS.readdir(path).forEach(function(f) {
if (f === '.' || f === '..') return;
fpath = path + '/' + f;
if (FS.analyzePath(fpath).object.isFolder) {
force_rmdir(fpath);
FS.rmdir(fpath);
} else {
FS.unlink(fpath);
}
});
}
And then later:
force_rmdir(my_path);
Module['FS_syncfs'](false, function(err){});
Actually despite that working, I think it's best to first move to a "trash" location, where the user could run the software and verify that the files removed did the intended result and then later actually remove from storage by deleting in the trash location. Essentially the recycle bin functionality.
I can't however figure out how to do a mv operation using FS library.
What is the preferred way to delete / empty / clear a filesystem persisted using IDBFS?
I've found the deleteDatabase() and clear() functions that operate on an IDBFactory and IDBObectStore respectively, but there doesn't seem to be any way to get my IDBFS database name.