diff --git a/src/db/fileinfostore/file_info_store.go b/src/db/fileinfostore/file_info_store.go index 1d046ef..7935e5a 100644 --- a/src/db/fileinfostore/file_info_store.go +++ b/src/db/fileinfostore/file_info_store.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/ihexxa/quickshare/src/db" "github.com/ihexxa/quickshare/src/kvstore" ) @@ -39,6 +40,7 @@ type FileInfo struct { Shared bool `json:"shared"` ShareID string `json:"shareID"` // for short url Sha1 string `json:"sha1"` + Size int64 `json:"size"` } type IFileInfoStore interface { @@ -117,7 +119,44 @@ func migrate(fi *FileInfoStore) error { return err } case "v1": - // no op + // add size to file info + infoStrs, err := fi.store.ListStringsIn(InfoNs) + if err != nil { + return err + } + + type FileInfoV1 struct { + IsDir bool `json:"isDir"` + Shared bool `json:"shared"` + Sha1 string `json:"sha1"` + ShareID string `json:"shareID"` // for short url + } + + infoV1 := &FileInfoV1{} + for itemPath, infoStr := range infoStrs { + err = json.Unmarshal([]byte(infoStr), infoV1) + if err != nil { + return fmt.Errorf("list sharing error: %w", err) + } + + newInfo := &FileInfo{ + IsDir: infoV1.IsDir, + Shared: infoV1.Shared, + ShareID: infoV1.ShareID, + Sha1: infoV1.Sha1, + Size: 0, // need to run an async task to refresh this + } + if err = fi.SetInfo(itemPath, newInfo); err != nil { + return err + } + } + + err = fi.store.SetStringIn(InitNs, SchemaVerKey, db.SchemaV2) + if err != nil { + return err + } + case db.SchemaV2: + // no need to migrate default: return fmt.Errorf("file info: unknown schema version (%s)", ver) } diff --git a/src/handlers/fileshdr/handlers.go b/src/handlers/fileshdr/handlers.go index 75eaf07..7296b29 100644 --- a/src/handlers/fileshdr/handlers.go +++ b/src/handlers/fileshdr/handlers.go @@ -18,6 +18,7 @@ import ( "github.com/ihexxa/gocfg" "github.com/ihexxa/multipart" + "github.com/ihexxa/quickshare/src/db/fileinfostore" "github.com/ihexxa/quickshare/src/db/userstore" "github.com/ihexxa/quickshare/src/depidx" q "github.com/ihexxa/quickshare/src/handlers" @@ -195,6 +196,7 @@ func (h *FileHandlers) Create(c *gin.Context) { tmpFilePath := q.UploadPath(userName, req.Path) locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker.Exec(func() { + // TODO: ok, err := h.deps.Users().CanIncrUsed(userIDInt, req.FileSize) if err != nil { c.JSON(q.ErrResp(c, 500, err)) @@ -257,7 +259,7 @@ func (h *FileHandlers) Delete(c *gin.Context) { locker := h.NewAutoLocker(c, lockName(filePath)) locker.Exec(func() { - info, err := h.deps.FS().Stat(filePath) + info, err := h.deps.FileInfos().GetInfo(filePath) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return @@ -269,11 +271,18 @@ func (h *FileHandlers) Delete(c *gin.Context) { return } - err = h.deps.Users().SetUsed(userIDInt, false, info.Size()) + err = h.deps.Users().SetUsed(userIDInt, false, info.Size) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return } + + err = h.deps.FileInfos().DelInfo(filePath) + if err != nil { + c.JSON(q.ErrResp(c, 500, err)) + return + } + c.JSON(q.Resp(200)) }) } @@ -471,6 +480,35 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { return } + fsInfo, err := h.deps.FS().Stat(fsFilePath) + if err != nil { + c.JSON(q.ErrResp(c, 500, err)) + return + } + + err = h.deps.FileInfos().SetInfo(fsFilePath, &fileinfostore.FileInfo{ + IsDir: false, + Shared: false, + Size: fsInfo.Size(), + }) + if err != nil { + c.JSON(q.ErrResp(c, 500, err)) + return + } + + // TODO: check space quota? + if fsInfo.Size()-fileSize != 0 { + sizeDiff := fsInfo.Size() - fileSize + if sizeDiff < 0 { + sizeDiff = -sizeDiff + } + err = h.deps.Users().SetUsed(userIDInt, fsInfo.Size()-fileSize > 0, sizeDiff) + if err != nil { + c.JSON(q.ErrResp(c, 500, err)) + return + } + } + msg, err := json.Marshal(Sha1Params{ FilePath: fsFilePath, }) diff --git a/src/kvstore/boltdbpvd/provider.go b/src/kvstore/boltdbpvd/provider.go index 5b120da..f274aa4 100644 --- a/src/kvstore/boltdbpvd/provider.go +++ b/src/kvstore/boltdbpvd/provider.go @@ -432,3 +432,7 @@ func (bp *BoltPvd) ListStringsByPrefixIn(prefix, ns string) (map[string]string, return results, err } + +func (bp *BoltPvd) StartUpdateTxBolt(op func(*bolt.Tx) error) error { + return bp.db.Update(op) +}