Merge pull request #1269 from realm/ap/delete_realm_api
Add Realm.deleteFile API [#363]
This commit is contained in:
commit
4d4606c905
|
@ -5,6 +5,7 @@ X.Y.Z Release notes
|
|||
|
||||
### Enhancements
|
||||
* Improve performance of the RPC worker for chrome debugging.
|
||||
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
||||
|
||||
### Bug fixes
|
||||
* None
|
||||
|
@ -35,6 +36,7 @@ X.Y.Z Release notes
|
|||
### Bug fixes
|
||||
* None
|
||||
|
||||
|
||||
1.10.3 Release notes (2017-8-16)
|
||||
=============================================================
|
||||
### Breaking changes
|
||||
|
|
|
@ -237,6 +237,13 @@ class Realm {
|
|||
*/
|
||||
Realm.schemaVersion = function(path, encryptionKey) {};
|
||||
|
||||
/**
|
||||
* Delete the Realm file for the given configuration.
|
||||
* @param {Realm~Configuration} config
|
||||
* @throws {Error} If anything in the provided `config` is invalid.
|
||||
*/
|
||||
Realm.deleteFile = function(config) {};
|
||||
|
||||
/**
|
||||
* The default path where to create and access the Realm file.
|
||||
* @type {string}
|
||||
|
|
|
@ -169,6 +169,11 @@ Object.defineProperties(Realm, {
|
|||
return rpc.callMethod(undefined, Realm[keys.id], 'schemaVersion', Array.from(arguments));
|
||||
}
|
||||
},
|
||||
deleteFile: {
|
||||
value: function(config) {
|
||||
return rpc.callMethod(undefined, Realm[keys.id], 'deleteFile', Array.from(arguments));
|
||||
}
|
||||
},
|
||||
copyBundledRealmFiles: {
|
||||
value: function() {
|
||||
return rpc.callMethod(undefined, Realm[keys.id], 'copyBundledRealmFiles', []);
|
||||
|
|
|
@ -423,6 +423,12 @@ declare class Realm {
|
|||
*/
|
||||
static openAsync(config: Realm.Configuration, callback: (error: any, realm: Realm) => void): void
|
||||
|
||||
/**
|
||||
* Delete the Realm file for the given configuration.
|
||||
* @param {Configuration} config
|
||||
*/
|
||||
static deleteFile(config: Realm.Configuration): void
|
||||
|
||||
/**
|
||||
* @param {Realm.Configuration} config?
|
||||
*/
|
||||
|
|
|
@ -93,4 +93,19 @@ namespace realm {
|
|||
s_default_realm_directory + "/*.realm.lock";
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void remove_directory(const std::string &path)
|
||||
{
|
||||
std::string cmd_clear_dir = "rm " + path + "/*";
|
||||
system(cmd_clear_dir.c_str());
|
||||
|
||||
std::string cmd_rmdir = "rmdir " + path;
|
||||
system(cmd_rmdir.c_str());
|
||||
}
|
||||
|
||||
void remove_file(const std::string &path)
|
||||
{
|
||||
std::string cmd = "rm " + path;
|
||||
system(cmd.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,5 +101,20 @@ void remove_realm_files_from_directory(const std::string &directory)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_file(const std::string &path)
|
||||
{
|
||||
NSFileManager *manager = [NSFileManager defaultManager];
|
||||
NSString *filePath = @(path.c_str());
|
||||
|
||||
if (![manager removeItemAtPath:filePath error:nil]) {
|
||||
throw std::runtime_error((std::string)"Failed to delete file at path " + filePath.UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_directory(const std::string &path)
|
||||
{
|
||||
remove_file(path); // works for directories too
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
static void schema_version(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void clear_test_state(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void copy_bundled_realm_files(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void delete_file(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
|
||||
// static properties
|
||||
static void get_default_path(ContextType, ObjectType, ReturnValue &);
|
||||
|
@ -211,6 +212,7 @@ public:
|
|||
{"schemaVersion", wrap<schema_version>},
|
||||
{"clearTestState", wrap<clear_test_state>},
|
||||
{"copyBundledRealmFiles", wrap<copy_bundled_realm_files>},
|
||||
{"deleteFile", wrap<delete_file>},
|
||||
{"_waitForDownload", wrap<wait_for_download_completion>},
|
||||
};
|
||||
|
||||
|
@ -526,6 +528,37 @@ void RealmClass<T>::copy_bundled_realm_files(ContextType ctx, FunctionType, Obje
|
|||
realm::copy_bundled_realm_files();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::delete_file(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
|
||||
ValueType value = arguments[0];
|
||||
if (!Value::is_object(ctx, value)) {
|
||||
throw std::runtime_error("Invalid argument, expected a Realm configuration object");
|
||||
}
|
||||
|
||||
ObjectType object = Value::validated_to_object(ctx, value);
|
||||
realm::Realm::Config config;
|
||||
|
||||
static const String path_string = "path";
|
||||
ValueType path_value = Object::get_property(ctx, object, path_string);
|
||||
if (!Value::is_undefined(ctx, path_value)) {
|
||||
config.path = Value::validated_to_string(ctx, path_value, "path");
|
||||
}
|
||||
else if (config.path.empty()) {
|
||||
config.path = js::default_path();
|
||||
}
|
||||
|
||||
config.path = normalize_realm_path(config.path);
|
||||
|
||||
std::string realm_file_path = config.path;
|
||||
realm::remove_file(realm_file_path);
|
||||
realm::remove_file(realm_file_path + ".lock");
|
||||
realm::remove_file(realm_file_path + ".note");
|
||||
realm::remove_directory(realm_file_path + ".management");
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::get_default_path(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
||||
return_value.set(realm::js::default_path());
|
||||
|
|
|
@ -134,4 +134,55 @@ void remove_realm_files_from_directory(const std::string &dir_path)
|
|||
}
|
||||
}
|
||||
|
||||
void remove_directory(const std::string &path)
|
||||
{
|
||||
FileSystemRequest exists_req;
|
||||
if (uv_fs_stat(uv_default_loop(), &exists_req, path.c_str(), nullptr) != 0) {
|
||||
if (exists_req.result == UV_ENOENT) {
|
||||
// path doesn't exist, ignore
|
||||
return;
|
||||
} else {
|
||||
throw UVException(static_cast<uv_errno_t>(exists_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
uv_dirent_t dir_entry;
|
||||
FileSystemRequest dir_scan_req;
|
||||
if (uv_fs_scandir(uv_default_loop(), &dir_scan_req, path.c_str(), 0, nullptr) < 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(dir_scan_req.result));
|
||||
}
|
||||
|
||||
while (uv_fs_scandir_next(&dir_scan_req, &dir_entry) != UV_EOF) {
|
||||
std::string dir_entry_path = path + '/' + dir_entry.name;
|
||||
FileSystemRequest delete_req;
|
||||
if (uv_fs_unlink(uv_default_loop(), &delete_req, dir_entry_path.c_str(), nullptr) != 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(delete_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemRequest rmdir_req;
|
||||
if (uv_fs_rmdir(uv_default_loop(), &rmdir_req, path.c_str(), nullptr)) {
|
||||
throw UVException(static_cast<uv_errno_t>(rmdir_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_file(const std::string &path)
|
||||
{
|
||||
FileSystemRequest exists_req;
|
||||
if (uv_fs_stat(uv_default_loop(), &exists_req, path.c_str(), nullptr) != 0) {
|
||||
if (exists_req.result == UV_ENOENT) {
|
||||
// path doesn't exist, ignore
|
||||
return;
|
||||
} else {
|
||||
throw UVException(static_cast<uv_errno_t>(exists_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemRequest delete_req;
|
||||
if (uv_fs_unlink(uv_default_loop(), &delete_req, path.c_str(), nullptr) != 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(delete_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
} // realm
|
||||
|
|
|
@ -41,4 +41,10 @@ void copy_bundled_realm_files();
|
|||
// remove all realm files in the given directory
|
||||
void remove_realm_files_from_directory(const std::string &directory);
|
||||
|
||||
// remove file at the given path
|
||||
void remove_file(const std::string &path);
|
||||
|
||||
// remove directory at the given path
|
||||
void remove_directory(const std::string &path);
|
||||
|
||||
}
|
||||
|
|
|
@ -1030,5 +1030,41 @@ module.exports = {
|
|||
const realm1 = new Realm({schema: [schemas.StringOnly]});
|
||||
const realm2 = new Realm({schema: [schemas.StringOnly]});
|
||||
TestCase.assertThrows(realm1.compact());
|
||||
},
|
||||
|
||||
testRealmDeleteFileDefaultConfigPath: function() {
|
||||
const config = {schema: [schemas.TestObject]};
|
||||
const realm = new Realm(config);
|
||||
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', {doubleCol: 1});
|
||||
});
|
||||
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||
realm.close();
|
||||
|
||||
Realm.deleteFile(config);
|
||||
|
||||
const realm2 = new Realm(config);
|
||||
TestCase.assertEqual(realm2.objects('TestObject').length, 0);
|
||||
realm.close();
|
||||
},
|
||||
|
||||
testRealmDeleteFileCustomConfigPath: function() {
|
||||
const config = {schema: [schemas.TestObject], path: 'test-realm-delete-file.realm'};
|
||||
const realm = new Realm(config);
|
||||
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', {doubleCol: 1});
|
||||
});
|
||||
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||
realm.close();
|
||||
|
||||
Realm.deleteFile(config);
|
||||
|
||||
const realm2 = new Realm(config);
|
||||
TestCase.assertEqual(realm2.objects('TestObject').length, 0);
|
||||
realm.close();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue