From d317aba2d086f2916029cd487e221d44742e6e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Mon, 10 Apr 2023 23:17:20 +0800 Subject: [PATCH] fix: FileDB -> f --- backend/global/file.go | 90 +++++++++++++++++++++++++++++--------- backend/global/list.go | 30 ++++++------- backend/global/question.go | 25 +++++++++++ 3 files changed, 110 insertions(+), 35 deletions(-) diff --git a/backend/global/file.go b/backend/global/file.go index 38d975c..4970de9 100644 --- a/backend/global/file.go +++ b/backend/global/file.go @@ -117,7 +117,9 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func return nil, ErrInvalidRole } progress(1) - lst, err := sql.Find[List](&FileDB.db, FileTableList, "WHERE ID="+strconv.Itoa(lstid)) + f.mu.RLock() + lst, err := sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(lstid)) + f.mu.RUnlock() if err != nil { return nil, err } @@ -380,8 +382,8 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func } var q Question dupmap := make(map[string]float64, 64) - FileDB.mu.RLock() - err = FileDB.db.FindFor(FileTableQuestion, &q, "", func() error { + f.mu.RLock() + err = f.db.FindFor(FileTableQuestion, &q, "", func() error { r, err := q.GetDuplicateRate(que) if err != nil { logrus.Warnln("[global.AddFile] GetDuplicateRate err:", err) @@ -395,7 +397,7 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func dupmap[hex.EncodeToString(buf[:])] = r return nil }) - FileDB.mu.RUnlock() + f.mu.RUnlock() if err == nil && len(dupmap) > 0 { que.Dup, _ = json.Marshal(dupmap) } @@ -407,20 +409,20 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func if err == nil { m5 := md5.Sum(w.Bytes()) quepath := questionpath + hex.EncodeToString(m5[:]) + ".docx" - f, err := os.Create(quepath) + qf, err := os.Create(quepath) if err == nil { - _, _ = io.Copy(f, w) - _ = f.Close() + _, _ = io.Copy(qf, w) + _ = qf.Close() } que.Path = quepath if istemp { - FileDB.mu.Lock() - _ = FileDB.db.Insert(FileTableTempQuestion, que) - FileDB.mu.Unlock() + f.mu.Lock() + _ = f.db.Insert(FileTableTempQuestion, que) + f.mu.Unlock() } else { - FileDB.mu.Lock() + f.mu.Lock() for k, v := range dupmap { - err = FileDB.db.Find(FileTableQuestion, &q, "WHERE ID=0x"+k) + err = f.db.Find(FileTableQuestion, &q, "WHERE ID=0x"+k) if err == nil { thismap := make(map[string]float64, 64) err := json.Unmarshal(q.Dup, &thismap) @@ -428,13 +430,13 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func thismap[queidstr] = v q.Dup, err = json.Marshal(thismap) if err == nil { - _ = FileDB.db.Insert(FileTableQuestion, &q) + _ = f.db.Insert(FileTableQuestion, &q) } } } } - _ = FileDB.db.Insert(FileTableQuestion, que) - FileDB.mu.Unlock() + _ = f.db.Insert(FileTableQuestion, que) + f.mu.Unlock() } } r := 0.0 @@ -473,16 +475,64 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func return nil, err } progress(95) - FileDB.mu.Lock() + f.mu.Lock() if istemp { - err = FileDB.db.Insert(FileTableTempFile, file) + err = f.db.Insert(FileTableTempFile, file) lst.IsTemp = true } else { - err = FileDB.db.Insert(FileTableFile, file) + err = f.db.Insert(FileTableFile, file) lst.IsTemp = false } - _ = FileDB.db.Insert(FileTableList, &lst) - FileDB.mu.Unlock() + _ = f.db.Insert(FileTableList, &lst) + f.mu.Unlock() progress(100) return file, err } + +// DelFile by listid +func (f *FileDatabase) DelFile(fileid, uid int, istemp bool) error { + user, err := UserDB.GetUserByID(uid) + if err != nil { + return err + } + if !user.IsSuper() { + return ErrInvalidRole + } + var file File + f.mu.RLock() + if istemp { + file, err = sql.Find[File](&f.db, FileTableTempFile, "WHERE ID="+strconv.Itoa(fileid)) + } else { + file, err = sql.Find[File](&f.db, FileTableFile, "WHERE ID="+strconv.Itoa(fileid)) + } + f.mu.RUnlock() + if err != nil { + return err + } + f.mu.RLock() + lst, err := sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(file.ListID)) + f.mu.RUnlock() + if err != nil { + return err + } + if lst.Path == "" || strings.Contains(lst.Path, "..") { + return os.ErrNotExist + } + ques := make([]QuestionJSON, 0, 64) + err = json.Unmarshal(file.Questions, &ques) + if err != nil { + return err + } + for _, q := range ques { + q.Delete(f, istemp) + } + if istemp { + err = f.db.Del(FileTableTempFile, "WHERE ID="+strconv.Itoa(fileid)) + } else { + err = f.db.Del(FileTableFile, "WHERE ID="+strconv.Itoa(fileid)) + } + if err != nil { + logrus.Warnln("[global.DelFile] err:", err) + } + +} diff --git a/backend/global/list.go b/backend/global/list.go index 30b488f..3977488 100644 --- a/backend/global/list.go +++ b/backend/global/list.go @@ -45,9 +45,9 @@ func (f *FileDatabase) SaveFileToTemp(uploader int, file io.Reader, name string) return } fpath := tmpdir + "/" + name - FileDB.mu.RLock() - lst, _ := sql.Find[List](&FileDB.db, FileTableList, "WHERE Path='"+fpath+"'") - FileDB.mu.RUnlock() + f.mu.RLock() + lst, _ := sql.Find[List](&f.db, FileTableList, "WHERE Path='"+fpath+"'") + f.mu.RUnlock() lst.Uploader = uploader lst.UpName = user.Name lst.UpTime = time.Now().Unix() @@ -65,9 +65,9 @@ func (f *FileDatabase) SaveFileToTemp(uploader int, file io.Reader, name string) return } lst.Size = sz - FileDB.mu.Lock() - err = FileDB.db.Insert(FileTableList, &lst) - FileDB.mu.Unlock() + f.mu.Lock() + err = f.db.Insert(FileTableList, &lst) + f.mu.Unlock() if err != nil { return } @@ -75,24 +75,24 @@ func (f *FileDatabase) SaveFileToTemp(uploader int, file io.Reader, name string) id = *lst.ID return } - FileDB.mu.RLock() - err = FileDB.db.Find(FileTableList, &lst, "WHERE Path='"+fpath+"'") - FileDB.mu.RUnlock() + f.mu.RLock() + err = f.db.Find(FileTableList, &lst, "WHERE Path='"+fpath+"'") + f.mu.RUnlock() id = *lst.ID return } // ListUploadedFile will select all file that HasntAnalyzed && IsTemp or !HasntAnalyzed && !IsTemp func (f *FileDatabase) ListUploadedFile() (lst []*List, err error) { - FileDB.mu.RLock() - lst, err = sql.FindAll[List](&FileDB.db, FileTableList, "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC") - FileDB.mu.RUnlock() + f.mu.RLock() + lst, err = sql.FindAll[List](&f.db, FileTableList, "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC") + f.mu.RUnlock() return } func (f *FileDatabase) GetFileInfo(id int) (lst List, err error) { - FileDB.mu.RLock() - lst, err = sql.Find[List](&FileDB.db, FileTableList, "WHERE ID="+strconv.Itoa(id)) - FileDB.mu.RUnlock() + f.mu.RLock() + lst, err = sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(id)) + f.mu.RUnlock() return } diff --git a/backend/global/question.go b/backend/global/question.go index 80b0c1e..5453640 100644 --- a/backend/global/question.go +++ b/backend/global/question.go @@ -4,9 +4,11 @@ import ( "encoding/binary" "encoding/hex" "encoding/json" + "strconv" "github.com/corona10/goimagehash" "github.com/fumiama/paper-manager/backend/utils" + "github.com/sirupsen/logrus" ) // QuestionJSON is the struct representation of File.Questions @@ -17,6 +19,29 @@ type QuestionJSON struct { Sub []QuestionJSON `json:"sub,omitempty"` } +// Delete me and all subs +func (q *QuestionJSON) Delete(f *FileDatabase, istemp bool) { + if b, err := hex.DecodeString(q.Name); err == nil { + err = f.DelQuestion(int64(binary.LittleEndian.Uint64(b)), istemp) + if err != nil { + logrus.Warnln("[global.QuestionJSON] Delete", q.Name, "err:", err) + } + } + for _, sq := range q.Sub { + sq.Delete(f, istemp) + } +} + +// DelQuestion 删除问题, 其它问题的 dup 可能会残留有 id, 使用时需要排除 +func (f *FileDatabase) DelQuestion(id int64, istemp bool) error { + f.mu.Lock() + defer f.mu.Unlock() + if istemp { + return f.db.Del(FileTableTempQuestion, "WHERE ID="+strconv.FormatInt(id, 10)) + } + return f.db.Del(FileTableQuestion, "WHERE ID="+strconv.FormatInt(id, 10)) +} + type Question struct { ID int64 // ID is the first 8 bytes of the Plain's md5 Path string // Path is the question's docx position