mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-09-16 23:29:25 +00:00
Add batch del files RPC (#694)
* Add batch del files RPC * Add pack multi-level files * Go add pack multi-level files * Use change set to batch del files * Improve args --------- Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
128
server/repo-op.c
128
server/repo-op.c
@@ -21,6 +21,7 @@
|
||||
#include "seafile-crypt.h"
|
||||
#include "diff-simple.h"
|
||||
#include "merge-new.h"
|
||||
#include "change-set.h"
|
||||
|
||||
#include "seaf-db.h"
|
||||
|
||||
@@ -1844,6 +1845,131 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
do_batch_del_files (ChangeSet *changeset,
|
||||
const char *file_list,
|
||||
int *mode, int *deleted_num, char **desc_file)
|
||||
{
|
||||
GList *filepaths = NULL, *ptr;
|
||||
char *name;
|
||||
|
||||
filepaths = json_to_file_list (file_list);
|
||||
|
||||
for (ptr = filepaths; ptr; ptr = ptr->next) {
|
||||
name = ptr->data;
|
||||
if (!name || g_strcmp0 (name, "") == 0) {
|
||||
continue;
|
||||
}
|
||||
char *canon_path = get_canonical_path (name);
|
||||
char *base_name= g_path_get_basename (canon_path);
|
||||
char *del_path = canon_path;
|
||||
if (canon_path[0] == '/') {
|
||||
del_path = canon_path + 1;
|
||||
}
|
||||
|
||||
remove_from_changeset (changeset, del_path, FALSE, NULL, mode);
|
||||
|
||||
(*deleted_num)++;
|
||||
if (desc_file && *desc_file == NULL)
|
||||
*desc_file = g_strdup (base_name);
|
||||
|
||||
g_free (canon_path);
|
||||
g_free (base_name);
|
||||
}
|
||||
|
||||
string_list_free (filepaths);
|
||||
}
|
||||
|
||||
int
|
||||
seaf_repo_manager_batch_del_files (SeafRepoManager *mgr,
|
||||
const char *repo_id,
|
||||
const char *file_list,
|
||||
const char *user,
|
||||
GError **error)
|
||||
{
|
||||
SeafRepo *repo = NULL;
|
||||
SeafCommit *head_commit = NULL;
|
||||
SeafDir *dir = NULL;
|
||||
char buf[SEAF_PATH_MAX];
|
||||
char *root_id = NULL;
|
||||
char *desc_file = NULL;
|
||||
ChangeSet *changeset = NULL;
|
||||
int mode = 0;
|
||||
int ret = 0;
|
||||
int deleted_num = 0;
|
||||
|
||||
GET_REPO_OR_FAIL(repo, repo_id);
|
||||
GET_COMMIT_OR_FAIL(head_commit, repo->id, repo->version, repo->head->commit_id);
|
||||
|
||||
dir = seaf_fs_manager_get_seafdir_sorted (seaf->fs_mgr,
|
||||
repo->store_id, repo->version,
|
||||
head_commit->root_id);
|
||||
if (!dir) {
|
||||
seaf_warning ("root dir doesn't exist in repo %s.\n",
|
||||
repo->store_id);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
changeset = changeset_new (repo_id, dir);
|
||||
if (!changeset) {
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL,
|
||||
"Failed to batch del files");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do_batch_del_files (changeset, file_list, &mode, &deleted_num, &desc_file);
|
||||
|
||||
if (deleted_num == 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
root_id = commit_tree_from_changeset (changeset);
|
||||
if (!root_id) {
|
||||
seaf_warning ("Failed to commit changeset for repo %s.\n", repo_id);
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL,
|
||||
"Failed to batch del files");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Commit. */
|
||||
if (deleted_num > 1) {
|
||||
snprintf(buf, SEAF_PATH_MAX, "Deleted \"%s\" and %d more files",
|
||||
desc_file, deleted_num - 1);
|
||||
} else if (S_ISDIR(mode)) {
|
||||
snprintf(buf, SEAF_PATH_MAX, "Removed directory \"%s\"", desc_file);
|
||||
} else {
|
||||
snprintf(buf, SEAF_PATH_MAX, "Deleted \"%s\"", desc_file);
|
||||
}
|
||||
|
||||
if (gen_new_commit (repo_id, head_commit, root_id,
|
||||
user, buf, NULL, TRUE, error) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
seaf_repo_manager_merge_virtual_repo (mgr, repo_id, NULL);
|
||||
|
||||
out:
|
||||
changeset_free (changeset);
|
||||
if (repo)
|
||||
seaf_repo_unref (repo);
|
||||
if (head_commit)
|
||||
seaf_commit_unref(head_commit);
|
||||
if (dir)
|
||||
seaf_dir_free (dir);
|
||||
g_free (root_id);
|
||||
g_free (desc_file);
|
||||
|
||||
if (ret == 0) {
|
||||
update_repo_size (repo_id);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SeafDirent *
|
||||
get_dirent_by_path (SeafRepo *repo,
|
||||
const char *root_id,
|
||||
@@ -6635,6 +6761,7 @@ seaf_repo_manager_get_deleted_entries (SeafRepoManager *mgr,
|
||||
g_hash_table_destroy (entries);
|
||||
seaf_repo_unref (repo);
|
||||
g_free (data.path);
|
||||
g_free (next_scan_stat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -6656,6 +6783,7 @@ seaf_repo_manager_get_deleted_entries (SeafRepoManager *mgr,
|
||||
|
||||
seaf_repo_unref (repo);
|
||||
g_free (data.path);
|
||||
g_free (next_scan_stat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user