From 435e3605f7f1766faf2bd4b6b09b809e45ca50d8 Mon Sep 17 00:00:00 2001 From: heimoshuiyu Date: Thu, 16 Dec 2021 11:41:07 +0800 Subject: [PATCH] Add: support delete file --- pkg/api/api.go | 1 + pkg/api/handle_manage_file.go | 34 +++++++++ pkg/database/method.go | 40 ++++++++++ pkg/database/sql_stmt.go | 137 ++++++++++++++++++++-------------- web/src/component/FileInfo.js | 30 ++++++++ 5 files changed, 188 insertions(+), 54 deletions(-) create mode 100644 pkg/api/handle_manage_file.go diff --git a/pkg/api/api.go b/pkg/api/api.go index 7e1f97c..a4baab8 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -79,6 +79,7 @@ func NewAPI(config Config) (*API, error) { apiMux.HandleFunc("/get_file_info", api.HandleGetFileInfo) apiMux.HandleFunc("/get_file_stream_direct", api.HandleGetFileStreamDirect) apiMux.HandleFunc("/prepare_file_stream_direct", api.HandlePrepareFileStreamDirect) + apiMux.HandleFunc("/delete_file", api.HandleDeleteFile) // feedback apiMux.HandleFunc("/feedback", api.HandleFeedback) apiMux.HandleFunc("/get_feedbacks", api.HandleGetFeedbacks) diff --git a/pkg/api/handle_manage_file.go b/pkg/api/handle_manage_file.go new file mode 100644 index 0000000..5c71665 --- /dev/null +++ b/pkg/api/handle_manage_file.go @@ -0,0 +1,34 @@ +package api + +import ( + "encoding/json" + "net/http" +) + +type DeleteFileRequest struct { + ID int64 `json:"id"` +} + +func (api *API) HandleDeleteFile(w http.ResponseWriter, r *http.Request) { + // check admin + err := api.CheckAdmin(w, r) + if err != nil { + api.HandleError(w, r, err) + return + } + + req := &DeleteFileRequest{} + err = json.NewDecoder(r.Body).Decode(req) + if err != nil { + api.HandleError(w, r, err) + return + } + + err = api.Db.DeleteFile(req.ID) + if err != nil { + api.HandleError(w, r, err) + return + } + + api.HandleOK(w, r) +} diff --git a/pkg/database/method.go b/pkg/database/method.go index 819c8b4..25b3587 100644 --- a/pkg/database/method.go +++ b/pkg/database/method.go @@ -321,3 +321,43 @@ func (database *Database) UpdateFoldername(folderId int64, foldername string) er } return nil } + +func (database *Database) DeleteFile(fileId int64) error { + database.singleThreadLock.Lock() + defer database.singleThreadLock.Unlock() + + // begin transaction + tx, err := database.sqlConn.Begin() + if err != nil { + return err + } + + // delete file + _, err = tx.Stmt(database.stmt.deleteFile).Exec(fileId) + if err != nil { + tx.Rollback() + return err + } + + // delete tag on file + _, err = tx.Stmt(database.stmt.deleteFileReferenceInFileHasTag).Exec(fileId) + if err != nil { + tx.Rollback() + return err + } + + // delete reviews on file + _, err = tx.Stmt(database.stmt.deleteFileReferenceInReviews).Exec(fileId) + if err != nil { + tx.Rollback() + return err + } + + // commit transaction + err = tx.Commit() + if err != nil { + return err + } + + return nil +} diff --git a/pkg/database/sql_stmt.go b/pkg/database/sql_stmt.go index 6c0522d..45dace2 100644 --- a/pkg/database/sql_stmt.go +++ b/pkg/database/sql_stmt.go @@ -268,61 +268,70 @@ WHERE reviews.user_id = ? ORDER BY reviews.created_at ;` +var deleteFileQuery = `DELETE FROM files WHERE id = ?;` + +var deleteFileReferenceInFileHasTagQuery = `DELETE FROM file_has_tag WHERE file_id = ?;` + +var deleteFileReferenceInReviewsQuery = `DELETE FROM reviews WHERE file_id = ?;` + type Stmt struct { - initFilesTable *sql.Stmt - initFoldersTable *sql.Stmt - initFeedbacksTable *sql.Stmt - initUsersTable *sql.Stmt - initAvatarsTable *sql.Stmt - initTagsTable *sql.Stmt - initFileHasTag *sql.Stmt - initLikesTable *sql.Stmt - initReviewsTable *sql.Stmt - initPlaybacksTable *sql.Stmt - initLogsTable *sql.Stmt - initTmpfsTable *sql.Stmt - insertFolder *sql.Stmt - insertFile *sql.Stmt - findFolder *sql.Stmt - findFile *sql.Stmt - searchFiles *sql.Stmt - getFolder *sql.Stmt - dropFiles *sql.Stmt - dropFolder *sql.Stmt - getFile *sql.Stmt - searchFolders *sql.Stmt - getFilesInFolder *sql.Stmt - getRandomFiles *sql.Stmt - getRandomFilesWithTag *sql.Stmt - insertFeedback *sql.Stmt - getFeedbacks *sql.Stmt - deleteFeedback *sql.Stmt - insertUser *sql.Stmt - countUser *sql.Stmt - countAdmin *sql.Stmt - getUser *sql.Stmt - getUsers *sql.Stmt - getUserById *sql.Stmt - updateUserActive *sql.Stmt - updateUsername *sql.Stmt - updateUserPassword *sql.Stmt - getAnonymousUser *sql.Stmt - insertTag *sql.Stmt - deleteTag *sql.Stmt - getTag *sql.Stmt - getTags *sql.Stmt - updateTag *sql.Stmt - putTagOnFile *sql.Stmt - getTagsOnFile *sql.Stmt - deleteTagOnFile *sql.Stmt - deleteTagReferenceInFileHasTag *sql.Stmt - updateFoldername *sql.Stmt - insertReview *sql.Stmt - getReviewsOnFile *sql.Stmt - getReview *sql.Stmt - updateReview *sql.Stmt - deleteReview *sql.Stmt - getReviewsByUser *sql.Stmt + initFilesTable *sql.Stmt + initFoldersTable *sql.Stmt + initFeedbacksTable *sql.Stmt + initUsersTable *sql.Stmt + initAvatarsTable *sql.Stmt + initTagsTable *sql.Stmt + initFileHasTag *sql.Stmt + initLikesTable *sql.Stmt + initReviewsTable *sql.Stmt + initPlaybacksTable *sql.Stmt + initLogsTable *sql.Stmt + initTmpfsTable *sql.Stmt + insertFolder *sql.Stmt + insertFile *sql.Stmt + findFolder *sql.Stmt + findFile *sql.Stmt + searchFiles *sql.Stmt + getFolder *sql.Stmt + dropFiles *sql.Stmt + dropFolder *sql.Stmt + getFile *sql.Stmt + searchFolders *sql.Stmt + getFilesInFolder *sql.Stmt + getRandomFiles *sql.Stmt + getRandomFilesWithTag *sql.Stmt + insertFeedback *sql.Stmt + getFeedbacks *sql.Stmt + deleteFeedback *sql.Stmt + insertUser *sql.Stmt + countUser *sql.Stmt + countAdmin *sql.Stmt + getUser *sql.Stmt + getUsers *sql.Stmt + getUserById *sql.Stmt + updateUserActive *sql.Stmt + updateUsername *sql.Stmt + updateUserPassword *sql.Stmt + getAnonymousUser *sql.Stmt + insertTag *sql.Stmt + deleteTag *sql.Stmt + getTag *sql.Stmt + getTags *sql.Stmt + updateTag *sql.Stmt + putTagOnFile *sql.Stmt + getTagsOnFile *sql.Stmt + deleteTagOnFile *sql.Stmt + deleteTagReferenceInFileHasTag *sql.Stmt + updateFoldername *sql.Stmt + insertReview *sql.Stmt + getReviewsOnFile *sql.Stmt + getReview *sql.Stmt + updateReview *sql.Stmt + deleteReview *sql.Stmt + getReviewsByUser *sql.Stmt + deleteFile *sql.Stmt + deleteFileReferenceInFileHasTag *sql.Stmt + deleteFileReferenceInReviews *sql.Stmt } func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) { @@ -718,5 +727,25 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) { return nil, err } + // init deleteFile + stmt.deleteFile, err = sqlConn.Prepare(deleteFileQuery) + if err != nil { + return nil, err + } + + // init deleteFileReferenceInFileHasTag + stmt.deleteFileReferenceInFileHasTag, err = sqlConn.Prepare( + deleteFileReferenceInFileHasTagQuery) + if err != nil { + return nil, err + } + + // init deleteFileReferenceInReviews + stmt.deleteFileReferenceInReviews, err = sqlConn.Prepare( + deleteFileReferenceInReviewsQuery) + if err != nil { + return nil, err + } + return stmt, err } diff --git a/web/src/component/FileInfo.js b/web/src/component/FileInfo.js index 82fbaec..3b6ef63 100644 --- a/web/src/component/FileInfo.js +++ b/web/src/component/FileInfo.js @@ -88,6 +88,29 @@ function FileInfo(props) { }); } + function deleteFile() { + // show Warning + if (window.confirm("Are you sure you want to delete this file?")) { + fetch(`/api/v1/delete_file`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: parseInt(params.id), + }), + }) + .then((res) => res.json()) + .then((data) => { + if (data.error) { + alert(data.error); + } else { + navigate(-1); + } + }); + } + } + useEffect(() => { refresh(); getTags(); @@ -120,6 +143,13 @@ function FileInfo(props) { > Share +