1
0
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:
feiniks
2024-09-13 14:58:45 +08:00
committed by GitHub
parent b2bde11d89
commit c80bf17efb
15 changed files with 755 additions and 24 deletions

View File

@@ -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;
}