Add: support delete tag and its references
This commit is contained in:
@@ -99,6 +99,7 @@ func NewAPI(config Config) (*API, error) {
|
||||
apiMux.HandleFunc("/put_tag_on_file", api.HandlePutTagOnFile)
|
||||
apiMux.HandleFunc("/get_tags_on_file", api.HandleGetTagsOnFile)
|
||||
apiMux.HandleFunc("/delete_tag_on_file", api.HandleDeleteTagOnFile)
|
||||
apiMux.HandleFunc("/delete_tag", api.HandleDeleteTag)
|
||||
// folder
|
||||
apiMux.HandleFunc("/update_foldername", api.HandleUpdateFoldername)
|
||||
// review
|
||||
|
||||
@@ -125,3 +125,34 @@ func (api *API) HandleUpdateTag(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type DeleteTagRequest struct {
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
func (api *API) HandleDeleteTag(w http.ResponseWriter, r *http.Request) {
|
||||
// check if user is admin
|
||||
err := api.CheckAdmin(w, r)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
req := &DeleteTagRequest{}
|
||||
err = json.NewDecoder(r.Body).Decode(req)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = api.Db.DeleteTag(req.ID)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("Successfully deleted tag and its references", req.ID)
|
||||
|
||||
api.HandleOK(w, r)
|
||||
}
|
||||
|
||||
|
||||
@@ -60,3 +60,33 @@ func (database *Database) UpdateTag(tag *Tag) (*Tag, error) {
|
||||
}
|
||||
return database.GetTag(tag.ID)
|
||||
}
|
||||
|
||||
// delete tag and all its references in file_has_tag
|
||||
func (database *Database) DeleteTag(id int64) error {
|
||||
// begin transaction
|
||||
tx, err := database.sqlConn.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete tag
|
||||
_, err = tx.Stmt(database.stmt.deleteTag).Exec(id)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// delete file_has_tag
|
||||
_, err = tx.Stmt(database.stmt.deleteTagReferenceInFileHasTag).Exec(id)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// commit transaction
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -205,6 +205,8 @@ var getAnonymousUserQuery = `SELECT id, username, role, avatar_id FROM users WHE
|
||||
|
||||
var insertTagQuery = `INSERT INTO tags (name, description, created_by_user_id) VALUES (?, ?, ?);`
|
||||
|
||||
var deleteTagQuery = `DELETE FROM tags WHERE id = ?;`
|
||||
|
||||
var getTagQuery = `SELECT
|
||||
tags.id, tags.name, tags.description,
|
||||
users.id, users.username, users.role, users.avatar_id
|
||||
@@ -231,6 +233,8 @@ WHERE file_has_tag.file_id = ?;`
|
||||
|
||||
var deleteTagOnFileQuery = `DELETE FROM file_has_tag WHERE tag_id = ? AND file_id = ?;`
|
||||
|
||||
var deleteTagReferenceInFileHasTagQuery = `DELETE FROM file_has_tag WHERE tag_id = ?;`
|
||||
|
||||
var updateFoldernameQuery = `UPDATE folders SET foldername = ? WHERE id = ?;`
|
||||
|
||||
var insertReviewQuery = `INSERT INTO reviews (user_id, file_id, created_at, content)
|
||||
@@ -265,58 +269,60 @@ ORDER BY reviews.created_at
|
||||
;`
|
||||
|
||||
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
|
||||
getTag *sql.Stmt
|
||||
getTags *sql.Stmt
|
||||
updateTag *sql.Stmt
|
||||
putTagOnFile *sql.Stmt
|
||||
getTagsOnFile *sql.Stmt
|
||||
deleteTagOnFile *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
|
||||
}
|
||||
|
||||
func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
@@ -621,6 +627,12 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init deleteTag
|
||||
stmt.deleteTag, err = sqlConn.Prepare(deleteTagQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init getTag
|
||||
stmt.getTag, err = sqlConn.Prepare(getTagQuery)
|
||||
if err != nil {
|
||||
@@ -657,6 +669,13 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init deleteTagReferenceInFileHasTag
|
||||
stmt.deleteTagReferenceInFileHasTag, err = sqlConn.Prepare(
|
||||
deleteTagReferenceInFileHasTagQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init updateFoldername
|
||||
stmt.updateFoldername, err = sqlConn.Prepare(updateFoldernameQuery)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useParams } from "react-router";
|
||||
import { useParams, useNavigate } from "react-router";
|
||||
|
||||
function EditTag() {
|
||||
let params = useParams();
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [tag, setTag] = useState({
|
||||
id: "",
|
||||
name: "",
|
||||
@@ -62,6 +64,27 @@ function EditTag() {
|
||||
refreshTagInfo();
|
||||
}, []);
|
||||
|
||||
function deleteTag() {
|
||||
fetch("/api/v1/delete_tag", {
|
||||
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 {
|
||||
alert("Tag deleted successfully");
|
||||
navigate(-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="page">
|
||||
<h3>Edit Tag</h3>
|
||||
@@ -107,6 +130,7 @@ function EditTag() {
|
||||
value={tag.description}
|
||||
onChange={(e) => setTag({ ...tag, description: e.target.value })}
|
||||
/>
|
||||
<button onClick={deleteTag}>Delete</button>
|
||||
<button onClick={() => updateTagInfo()}>Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user