fix(fileinfo_store): refactor file info store
This commit is contained in:
parent
d65f1c4356
commit
41827f20c0
7 changed files with 194 additions and 175 deletions
|
@ -116,7 +116,7 @@ func (bs *BoltStore) setUploadInfo(tx *bolt.Tx, userID uint64, uploadPath string
|
||||||
func (bs *BoltStore) getFileInfo(tx *bolt.Tx, userID uint64, itemPath string) (*db.FileInfo, error) {
|
func (bs *BoltStore) getFileInfo(tx *bolt.Tx, userID uint64, itemPath string) (*db.FileInfo, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
fileInfoBucket := tx.Bucket([]byte(db.FileInfoNs))
|
||||||
if fileInfoBucket == nil {
|
if fileInfoBucket == nil {
|
||||||
return nil, db.ErrBucketNotFound
|
return nil, db.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ func (bs *BoltStore) getFileInfo(tx *bolt.Tx, userID uint64, itemPath string) (*
|
||||||
func (bs *BoltStore) setFileInfo(tx *bolt.Tx, userID uint64, itemPath string, fileInfo *db.FileInfo) error {
|
func (bs *BoltStore) setFileInfo(tx *bolt.Tx, userID uint64, itemPath string, fileInfo *db.FileInfo) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
fileInfoBucket := tx.Bucket([]byte(db.FileInfoNs))
|
||||||
if fileInfoBucket == nil {
|
if fileInfoBucket == nil {
|
||||||
return db.ErrBucketNotFound
|
return db.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ func (bs *BoltStore) DelInfos(userID uint64, itemPath string, isDir bool) error
|
||||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
fileInfoBucket := tx.Bucket([]byte(db.FileInfoNs))
|
||||||
if fileInfoBucket == nil {
|
if fileInfoBucket == nil {
|
||||||
return db.ErrBucketNotFound
|
return db.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ func (bs *BoltStore) MoveInfos(userID uint64, oldPath, newPath string, isDir boo
|
||||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
fileInfoBucket := tx.Bucket([]byte(db.FileInfoNs))
|
||||||
if fileInfoBucket == nil {
|
if fileInfoBucket == nil {
|
||||||
return db.ErrBucketNotFound
|
return db.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,11 @@ const (
|
||||||
SchemaV2 = "v2" // add size to file info
|
SchemaV2 = "v2" // add size to file info
|
||||||
|
|
||||||
UserSchemaNs = "UserSchemaNs"
|
UserSchemaNs = "UserSchemaNs"
|
||||||
|
FileSchemaNs = "FileSchemaNs"
|
||||||
UserIDsNs = "UserIDsNs"
|
UserIDsNs = "UserIDsNs"
|
||||||
UsersNs = "UsersNs"
|
UsersNs = "UsersNs"
|
||||||
RolesNs = "RolesNs"
|
RolesNs = "RolesNs"
|
||||||
InfoNs = "InfoNs"
|
FileInfoNs = "FileInfoNs"
|
||||||
ShareIDNs = "ShareIDNs"
|
ShareIDNs = "ShareIDNs"
|
||||||
|
|
||||||
uploadsPrefix = "uploads"
|
uploadsPrefix = "uploads"
|
||||||
|
@ -290,17 +291,17 @@ func CheckBgConfig(cfg *BgConfig, fillDefault bool) error {
|
||||||
|
|
||||||
func CheckUser(user *User, fillDefault bool) error {
|
func CheckUser(user *User, fillDefault bool) error {
|
||||||
if user.ID == 0 && user.Role != AdminRole {
|
if user.ID == 0 && user.Role != AdminRole {
|
||||||
return ErrInvalidUser
|
return fmt.Errorf("invalid ID: (%w)", ErrInvalidUser)
|
||||||
}
|
}
|
||||||
// TODO: add length check
|
// TODO: add length check
|
||||||
if user.Name == "" || user.Pwd == "" || user.Role == "" {
|
if user.Name == "" || user.Role == "" {
|
||||||
return ErrInvalidUser
|
return fmt.Errorf("invalid Name/pwd/role: (%w)", ErrInvalidUser)
|
||||||
}
|
}
|
||||||
if user.UsedSpace < 0 {
|
if user.UsedSpace < 0 {
|
||||||
return ErrInvalidUser
|
return fmt.Errorf("invalid UsedSpace: (%w)", ErrInvalidUser)
|
||||||
}
|
}
|
||||||
if user.Quota == nil || user.Preferences == nil {
|
if user.Quota == nil || user.Preferences == nil {
|
||||||
return ErrInvalidUser
|
return fmt.Errorf("invalid Quota: (%w)", ErrInvalidUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
|
|
||||||
"github.com/ihexxa/quickshare/src/db"
|
"github.com/ihexxa/quickshare/src/db"
|
||||||
"github.com/ihexxa/quickshare/src/kvstore"
|
"github.com/ihexxa/quickshare/src/kvstore"
|
||||||
"github.com/ihexxa/quickshare/src/kvstore/boltdbpvd"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -52,14 +51,13 @@ type IFileInfoStore interface {
|
||||||
type FileInfoStore struct {
|
type FileInfoStore struct {
|
||||||
mtx *sync.RWMutex
|
mtx *sync.RWMutex
|
||||||
store kvstore.IKVStore
|
store kvstore.IKVStore
|
||||||
boltdb boltdbpvd.BoltProvider
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
|
func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
|
||||||
var err error
|
var err error
|
||||||
for _, nsName := range []string{
|
for _, nsName := range []string{
|
||||||
InitNs,
|
db.FileSchemaNs,
|
||||||
db.InfoNs,
|
db.FileInfoNs,
|
||||||
db.ShareIDNs,
|
db.ShareIDNs,
|
||||||
} {
|
} {
|
||||||
if !store.HasNamespace(nsName) {
|
if !store.HasNamespace(nsName) {
|
||||||
|
@ -69,115 +67,15 @@ func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boltdb := store.(boltdbpvd.BoltProvider)
|
|
||||||
|
|
||||||
fi := &FileInfoStore{
|
fi := &FileInfoStore{
|
||||||
store: store,
|
store: store,
|
||||||
boltdb: boltdb,
|
|
||||||
mtx: &sync.RWMutex{},
|
mtx: &sync.RWMutex{},
|
||||||
}
|
}
|
||||||
return fi, nil
|
return fi, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) AddSharing(dirPath string) error {
|
func (fi *FileInfoStore) getInfo(itemPath string) (*db.FileInfo, error) {
|
||||||
fi.mtx.Lock()
|
infoStr, ok := fi.store.GetStringIn(db.FileInfoNs, itemPath)
|
||||||
defer fi.mtx.Unlock()
|
|
||||||
|
|
||||||
info, err := fi.GetInfo(dirPath)
|
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, ErrNotFound) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
info = &db.FileInfo{
|
|
||||||
IsDir: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: ensure Atomicity
|
|
||||||
shareID, err := fi.getShareID(dirPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fi.store.SetStringIn(db.ShareIDNs, shareID, dirPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
info.Shared = true
|
|
||||||
info.ShareID = shareID
|
|
||||||
return fi.SetInfo(dirPath, info)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) DelSharing(dirPath string) error {
|
|
||||||
fi.mtx.Lock()
|
|
||||||
defer fi.mtx.Unlock()
|
|
||||||
|
|
||||||
info, err := fi.GetInfo(dirPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: ensure Atomicity
|
|
||||||
// In the bolt, if the key does not exist
|
|
||||||
// then nothing is done and a nil error is returned
|
|
||||||
|
|
||||||
// because before this version, shareIDs are not removed correctly
|
|
||||||
// so it iterates all shareIDs and cleans remaining entries
|
|
||||||
shareIDtoDir, err := fi.store.ListStringsIn(db.ShareIDNs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for shareID, shareDir := range shareIDtoDir {
|
|
||||||
if shareDir == dirPath {
|
|
||||||
err = fi.store.DelStringIn(db.ShareIDNs, shareID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.ShareID = ""
|
|
||||||
info.Shared = false
|
|
||||||
return fi.SetInfo(dirPath, info)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) GetSharing(dirPath string) (bool, bool) {
|
|
||||||
fi.mtx.Lock()
|
|
||||||
defer fi.mtx.Unlock()
|
|
||||||
|
|
||||||
// TODO: differentiate error and not exist
|
|
||||||
info, err := fi.GetInfo(dirPath)
|
|
||||||
if err != nil {
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
return info.IsDir && info.Shared, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) ListSharings(prefix string) (map[string]string, error) {
|
|
||||||
infoStrs, err := fi.store.ListStringsByPrefixIn(prefix, db.InfoNs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
info := &db.FileInfo{}
|
|
||||||
sharings := map[string]string{}
|
|
||||||
for itemPath, infoStr := range infoStrs {
|
|
||||||
err = json.Unmarshal([]byte(infoStr), info)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("list sharing error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.IsDir && info.Shared {
|
|
||||||
sharings[itemPath] = info.ShareID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharings, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) GetInfo(itemPath string) (*db.FileInfo, error) {
|
|
||||||
infoStr, ok := fi.store.GetStringIn(db.InfoNs, itemPath)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
|
@ -190,10 +88,14 @@ func (fi *FileInfoStore) GetInfo(itemPath string) (*db.FileInfo, error) {
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) GetInfo(itemPath string) (*db.FileInfo, error) {
|
||||||
|
return fi.getInfo(itemPath)
|
||||||
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*db.FileInfo, error) {
|
func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*db.FileInfo, error) {
|
||||||
infos := map[string]*db.FileInfo{}
|
infos := map[string]*db.FileInfo{}
|
||||||
for _, itemPath := range itemPaths {
|
for _, itemPath := range itemPaths {
|
||||||
info, err := fi.GetInfo(itemPath)
|
info, err := fi.getInfo(itemPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, ErrNotFound) {
|
if !errors.Is(err, ErrNotFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -206,28 +108,34 @@ func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*db.FileInfo,
|
||||||
return infos, nil
|
return infos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) SetInfo(itemPath string, info *db.FileInfo) error {
|
func (fi *FileInfoStore) setInfo(itemPath string, info *db.FileInfo) error {
|
||||||
infoStr, err := json.Marshal(info)
|
infoStr, err := json.Marshal(info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("set file info: %w", err)
|
return fmt.Errorf("set file info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fi.store.SetStringIn(db.InfoNs, itemPath, string(infoStr))
|
err = fi.store.SetStringIn(db.FileInfoNs, itemPath, string(infoStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("set file info: %w", err)
|
return fmt.Errorf("set file info: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) DelInfo(itemPath string) error {
|
func (fi *FileInfoStore) SetInfo(itemPath string, info *db.FileInfo) error {
|
||||||
return fi.store.DelStringIn(db.InfoNs, itemPath)
|
return fi.setInfo(itemPath, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) DelInfo(itemPath string) error {
|
||||||
|
return fi.store.DelStringIn(db.FileInfoNs, itemPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sharings
|
||||||
|
|
||||||
func (fi *FileInfoStore) SetSha1(itemPath, sign string) error {
|
func (fi *FileInfoStore) SetSha1(itemPath, sign string) error {
|
||||||
fi.mtx.Lock()
|
fi.mtx.Lock()
|
||||||
defer fi.mtx.Unlock()
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
info, err := fi.GetInfo(itemPath)
|
info, err := fi.getInfo(itemPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, ErrNotFound) {
|
if !errors.Is(err, ErrNotFound) {
|
||||||
return err
|
return err
|
||||||
|
@ -238,7 +146,7 @@ func (fi *FileInfoStore) SetSha1(itemPath, sign string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info.Sha1 = sign
|
info.Sha1 = sign
|
||||||
return fi.SetInfo(itemPath, info)
|
return fi.setInfo(itemPath, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) getShareID(payload string) (string, error) {
|
func (fi *FileInfoStore) getShareID(payload string) (string, error) {
|
||||||
|
@ -273,3 +181,100 @@ func (fi *FileInfoStore) GetSharingDir(hashID string) (string, error) {
|
||||||
}
|
}
|
||||||
return dirPath, nil
|
return dirPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) AddSharing(dirPath string) error {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
info, err := fi.getInfo(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, ErrNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info = &db.FileInfo{
|
||||||
|
IsDir: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ensure Atomicity
|
||||||
|
shareID, err := fi.getShareID(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = fi.store.SetStringIn(db.ShareIDNs, shareID, dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info.Shared = true
|
||||||
|
info.ShareID = shareID
|
||||||
|
return fi.setInfo(dirPath, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) DelSharing(dirPath string) error {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
info, err := fi.getInfo(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ensure Atomicity
|
||||||
|
// In the bolt, if the key does not exist
|
||||||
|
// then nothing is done and a nil error is returned
|
||||||
|
|
||||||
|
// because before this version, shareIDs are not removed correctly
|
||||||
|
// so it iterates all shareIDs and cleans remaining entries
|
||||||
|
shareIDtoDir, err := fi.store.ListStringsIn(db.ShareIDNs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for shareID, shareDir := range shareIDtoDir {
|
||||||
|
if shareDir == dirPath {
|
||||||
|
err = fi.store.DelStringIn(db.ShareIDNs, shareID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info.ShareID = ""
|
||||||
|
info.Shared = false
|
||||||
|
return fi.setInfo(dirPath, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) GetSharing(dirPath string) (bool, bool) {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
// TODO: differentiate error and not exist
|
||||||
|
info, err := fi.getInfo(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
return info.IsDir && info.Shared, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) ListSharings(prefix string) (map[string]string, error) {
|
||||||
|
infoStrs, err := fi.store.ListStringsByPrefixIn(prefix, db.FileInfoNs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := &db.FileInfo{}
|
||||||
|
sharings := map[string]string{}
|
||||||
|
for itemPath, infoStr := range infoStrs {
|
||||||
|
err = json.Unmarshal([]byte(infoStr), info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("list sharing error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.IsDir && info.Shared {
|
||||||
|
sharings[itemPath] = info.ShareID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sharings, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package fileinfostore
|
package fileinfostore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -140,7 +141,7 @@ func TestUserStores(t *testing.T) {
|
||||||
// get infos
|
// get infos
|
||||||
for itemPath := range pathInfos {
|
for itemPath := range pathInfos {
|
||||||
_, err := store.GetInfo(itemPath)
|
_, err := store.GetInfo(itemPath)
|
||||||
if !IsNotFound(err) {
|
if !errors.Is(err, ErrNotFound) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,52 +12,7 @@ var (
|
||||||
ErrUploadNotFound = errors.New("upload info not found")
|
ErrUploadNotFound = errors.New("upload info not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (fi *FileInfoStore) AddUploadInfo(user, filePath, tmpPath string, fileSize int64) error {
|
func (fi *FileInfoStore) getUploadInfo(user, filePath string) (string, int64, int64, error) {
|
||||||
ns := db.UploadNS(user)
|
|
||||||
err := fi.store.AddNamespace(ns)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, ok := fi.store.GetStringIn(ns, tmpPath)
|
|
||||||
if ok {
|
|
||||||
return db.ErrCreateExisting
|
|
||||||
}
|
|
||||||
|
|
||||||
info := &db.UploadInfo{
|
|
||||||
RealFilePath: filePath,
|
|
||||||
Size: fileSize,
|
|
||||||
Uploaded: 0,
|
|
||||||
}
|
|
||||||
infoBytes, err := json.Marshal(info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fi.store.SetStringIn(ns, tmpPath, string(infoBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) SetUploadInfo(user, filePath string, newUploaded int64) error {
|
|
||||||
realFilePath, fileSize, _, err := fi.GetUploadInfo(user, filePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if newUploaded > fileSize {
|
|
||||||
return ErrGreaterThanSize
|
|
||||||
}
|
|
||||||
|
|
||||||
newInfo := &db.UploadInfo{
|
|
||||||
RealFilePath: realFilePath,
|
|
||||||
Size: fileSize,
|
|
||||||
Uploaded: newUploaded,
|
|
||||||
}
|
|
||||||
newInfoBytes, err := json.Marshal(newInfo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return fi.store.SetStringIn(db.UploadNS(user), filePath, string(newInfoBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi *FileInfoStore) GetUploadInfo(user, filePath string) (string, int64, int64, error) {
|
|
||||||
ns := db.UploadNS(user)
|
ns := db.UploadNS(user)
|
||||||
infoBytes, ok := fi.store.GetStringIn(ns, filePath)
|
infoBytes, ok := fi.store.GetStringIn(ns, filePath)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -73,6 +28,61 @@ func (fi *FileInfoStore) GetUploadInfo(user, filePath string) (string, int64, in
|
||||||
return info.RealFilePath, info.Size, info.Uploaded, nil
|
return info.RealFilePath, info.Size, info.Uploaded, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) setUploadInfo(user, filePath string, info *db.UploadInfo) error {
|
||||||
|
newInfoBytes, err := json.Marshal(info)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fi.store.SetStringIn(db.UploadNS(user), filePath, string(newInfoBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) AddUploadInfo(user, filePath, tmpPath string, fileSize int64) error {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
ns := db.UploadNS(user)
|
||||||
|
err := fi.store.AddNamespace(ns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, _, err = fi.getUploadInfo(user, tmpPath)
|
||||||
|
if err == nil {
|
||||||
|
return db.ErrCreateExisting
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.setUploadInfo(user, filePath, &db.UploadInfo{
|
||||||
|
RealFilePath: filePath,
|
||||||
|
Size: fileSize,
|
||||||
|
Uploaded: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) SetUploadInfo(user, filePath string, newUploaded int64) error {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
realFilePath, fileSize, _, err := fi.getUploadInfo(user, filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if newUploaded > fileSize {
|
||||||
|
return ErrGreaterThanSize
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.setUploadInfo(user, filePath, &db.UploadInfo{
|
||||||
|
RealFilePath: realFilePath,
|
||||||
|
Size: fileSize,
|
||||||
|
Uploaded: newUploaded,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi *FileInfoStore) GetUploadInfo(user, filePath string) (string, int64, int64, error) {
|
||||||
|
fi.mtx.Lock()
|
||||||
|
defer fi.mtx.Unlock()
|
||||||
|
|
||||||
|
return fi.getUploadInfo(user, filePath)
|
||||||
|
}
|
||||||
|
|
||||||
func (fi *FileInfoStore) DelUploadInfo(user, filePath string) error {
|
func (fi *FileInfoStore) DelUploadInfo(user, filePath string) error {
|
||||||
return fi.store.DelInt64In(db.UploadNS(user), filePath)
|
return fi.store.DelInt64In(db.UploadNS(user), filePath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ type IUserStore interface {
|
||||||
GetUser(id uint64) (*db.User, error)
|
GetUser(id uint64) (*db.User, error)
|
||||||
GetUserByName(name string) (*db.User, error)
|
GetUserByName(name string) (*db.User, error)
|
||||||
SetInfo(id uint64, user *db.User) error
|
SetInfo(id uint64, user *db.User) error
|
||||||
// CanIncrUsed(id uint64, capacity int64) (bool, error)
|
|
||||||
SetUsed(id uint64, incr bool, capacity int64) error
|
SetUsed(id uint64, incr bool, capacity int64) error
|
||||||
ResetUsed(id uint64, used int64) error
|
ResetUsed(id uint64, used int64) error
|
||||||
SetPwd(id uint64, pwd string) error
|
SetPwd(id uint64, pwd string) error
|
||||||
|
@ -322,6 +321,9 @@ func (us *KVUserStore) ListUsers() ([]*db.User, error) {
|
||||||
}
|
}
|
||||||
user.Pwd = ""
|
user.Pwd = ""
|
||||||
|
|
||||||
|
if err = db.CheckUser(user, true); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
users = append(users, user)
|
users = append(users, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
src/server/testdata/test_quickshare.db
vendored
BIN
src/server/testdata/test_quickshare.db
vendored
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue