fix(files): add boltdb store and refactor files handlers
This commit is contained in:
parent
044cdea1d4
commit
17b4544487
19 changed files with 751 additions and 402 deletions
377
src/db/boltstore/bolt_store.go
Normal file
377
src/db/boltstore/bolt_store.go
Normal file
|
@ -0,0 +1,377 @@
|
|||
package boltstore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/ihexxa/quickshare/src/db"
|
||||
)
|
||||
|
||||
type BoltStore struct {
|
||||
boltdb *bolt.DB
|
||||
}
|
||||
|
||||
func NewBoltStore(boltdb *bolt.DB) (*BoltStore, error) {
|
||||
bs := &BoltStore{
|
||||
boltdb: boltdb,
|
||||
}
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
func (bs *BoltStore) getUserInfo(tx *bolt.Tx, userID uint64) (*db.User, error) {
|
||||
var err error
|
||||
|
||||
usersBucket := tx.Bucket([]byte(db.UsersNs))
|
||||
if usersBucket == nil {
|
||||
return nil, db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
uidStr := fmt.Sprint(userID)
|
||||
infoBytes := usersBucket.Get([]byte(uidStr))
|
||||
if infoBytes == nil {
|
||||
return nil, db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
userInfo := &db.User{}
|
||||
err = json.Unmarshal(infoBytes, userInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if userInfo.ID != userID {
|
||||
return nil, fmt.Errorf("user id key(%d) info(%d) does match", userID, userInfo.ID)
|
||||
}
|
||||
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
func (bs *BoltStore) setUserInfo(tx *bolt.Tx, userID uint64, userInfo *db.User) error {
|
||||
var err error
|
||||
|
||||
usersBucket := tx.Bucket([]byte(db.UsersNs))
|
||||
if usersBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
userInfoBytes, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uidStr := fmt.Sprint(userID)
|
||||
return usersBucket.Put([]byte(uidStr), userInfoBytes)
|
||||
}
|
||||
|
||||
func (bs *BoltStore) getUploadInfo(tx *bolt.Tx, userID uint64, itemPath string) (*db.UploadInfo, error) {
|
||||
var err error
|
||||
|
||||
uidStr := fmt.Sprint(userID)
|
||||
userUploadNS := db.UploadNS(uidStr)
|
||||
|
||||
uploadInfoBucket := tx.Bucket([]byte(userUploadNS))
|
||||
if uploadInfoBucket == nil {
|
||||
return nil, bolt.ErrBucketNotFound
|
||||
|
||||
}
|
||||
|
||||
uploadInfoBytes := uploadInfoBucket.Get([]byte(itemPath))
|
||||
if uploadInfoBytes == nil {
|
||||
return nil, db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
uploadInfo := &db.UploadInfo{}
|
||||
err = json.Unmarshal(uploadInfoBytes, uploadInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uploadInfo, nil
|
||||
}
|
||||
|
||||
func (bs *BoltStore) setUploadInfo(tx *bolt.Tx, userID uint64, uploadPath string, uploadInfo *db.UploadInfo, overWrite bool) error {
|
||||
var err error
|
||||
|
||||
uidStr := fmt.Sprint(userID)
|
||||
userUploadNS := db.UploadNS(uidStr)
|
||||
uploadInfoBucket := tx.Bucket([]byte(userUploadNS))
|
||||
if uploadInfoBucket == nil {
|
||||
uploadInfoBucket, err = tx.CreateBucket([]byte(userUploadNS))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
existingInfo := uploadInfoBucket.Get([]byte(uploadPath))
|
||||
if existingInfo != nil && !overWrite {
|
||||
return db.ErrCreateExisting
|
||||
}
|
||||
|
||||
uploadInfoBytes, err := json.Marshal(uploadInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return uploadInfoBucket.Put([]byte(uploadPath), uploadInfoBytes)
|
||||
}
|
||||
|
||||
func (bs *BoltStore) getFileInfo(tx *bolt.Tx, userID uint64, itemPath string) (*db.FileInfo, error) {
|
||||
var err error
|
||||
|
||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
||||
if fileInfoBucket == nil {
|
||||
return nil, db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
fileInfoBytes := fileInfoBucket.Get([]byte(itemPath))
|
||||
if fileInfoBytes == nil {
|
||||
return nil, db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
fileInfo := &db.FileInfo{}
|
||||
err = json.Unmarshal(fileInfoBytes, fileInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fileInfo, nil
|
||||
}
|
||||
|
||||
func (bs *BoltStore) setFileInfo(tx *bolt.Tx, userID uint64, itemPath string, fileInfo *db.FileInfo) error {
|
||||
var err error
|
||||
|
||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
||||
if fileInfoBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
fileInfoBytes, err := json.Marshal(fileInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fileInfoBucket.Put([]byte(itemPath), fileInfoBytes)
|
||||
}
|
||||
|
||||
func (bs *BoltStore) AddUploadInfos(userID uint64, tmpPath, filePath string, info *db.FileInfo) error {
|
||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||
var err error
|
||||
// check space quota
|
||||
userInfo, err := bs.getUserInfo(tx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if userInfo.UsedSpace+info.Size > int64(userInfo.Quota.SpaceLimit) {
|
||||
return errors.New("space limit is reached")
|
||||
}
|
||||
|
||||
// update used space
|
||||
userInfo.UsedSpace += info.Size
|
||||
err = bs.setUserInfo(tx, userID, userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add upload info
|
||||
uploadInfo := &db.UploadInfo{
|
||||
RealFilePath: filePath,
|
||||
Size: info.Size,
|
||||
Uploaded: 0,
|
||||
}
|
||||
return bs.setUploadInfo(tx, userID, tmpPath, uploadInfo, false)
|
||||
})
|
||||
}
|
||||
|
||||
func (bs *BoltStore) DelUploadingInfos(userID uint64, uploadPath string) error {
|
||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||
var err error
|
||||
|
||||
// delete upload info
|
||||
uidStr := fmt.Sprint(userID)
|
||||
userUploadNS := db.UploadNS(uidStr)
|
||||
|
||||
uploadInfoBucket := tx.Bucket([]byte(userUploadNS))
|
||||
if uploadInfoBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
uploadInfoBytes := uploadInfoBucket.Get([]byte(uploadPath))
|
||||
if uploadInfoBytes == nil {
|
||||
return db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
uploadInfo := &db.UploadInfo{}
|
||||
err = json.Unmarshal(uploadInfoBytes, uploadInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = uploadInfoBucket.Delete([]byte(uploadPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// decr used space
|
||||
userInfo, err := bs.getUserInfo(tx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userInfo.UsedSpace -= uploadInfo.Size
|
||||
return bs.setUserInfo(tx, userID, userInfo)
|
||||
})
|
||||
}
|
||||
|
||||
func (bs *BoltStore) MoveUploadingInfos(userID uint64, uploadPath, itemPath string) error {
|
||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||
var err error
|
||||
|
||||
// delete upload info
|
||||
uidStr := fmt.Sprint(userID)
|
||||
userUploadNS := db.UploadNS(uidStr)
|
||||
|
||||
uploadInfoBucket := tx.Bucket([]byte(userUploadNS))
|
||||
if uploadInfoBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
uploadInfoBytes := uploadInfoBucket.Get([]byte(uploadPath))
|
||||
if uploadInfoBytes == nil {
|
||||
return db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
uploadInfo := &db.UploadInfo{}
|
||||
err = json.Unmarshal(uploadInfoBytes, uploadInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = uploadInfoBucket.Delete([]byte(uploadPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create file info
|
||||
fileInfo := &db.FileInfo{
|
||||
IsDir: false,
|
||||
Size: uploadInfo.Size,
|
||||
}
|
||||
return bs.setFileInfo(tx, userID, itemPath, fileInfo)
|
||||
})
|
||||
}
|
||||
|
||||
func (bs *BoltStore) delShareID(tx *bolt.Tx, itemPath string) error {
|
||||
var err error
|
||||
|
||||
shareIDBucket := tx.Bucket([]byte(db.ShareIDNs))
|
||||
if shareIDBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
shareIDtoDir := map[string]string{}
|
||||
shareIDBucket.ForEach(func(k, v []byte) error {
|
||||
shareIDtoDir[string(k)] = string(v)
|
||||
return nil
|
||||
})
|
||||
|
||||
// because before this version, shareIDs are not removed correctly
|
||||
// so it iterates all shareIDs and cleans remaining entries
|
||||
for shareID, shareDir := range shareIDtoDir {
|
||||
if shareDir == itemPath {
|
||||
err = shareIDBucket.Delete([]byte(shareID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *BoltStore) DelInfos(userID uint64, itemPath string) error {
|
||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||
var err error
|
||||
|
||||
// delete file info
|
||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
||||
if fileInfoBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
fileInfoBytes := fileInfoBucket.Get([]byte(itemPath))
|
||||
if fileInfoBucket == nil {
|
||||
return db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
fileInfo := &db.FileInfo{}
|
||||
err = json.Unmarshal(fileInfoBytes, fileInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = fileInfoBucket.Delete([]byte(itemPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// decr used space
|
||||
userInfo, err := bs.getUserInfo(tx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userInfo.UsedSpace -= fileInfo.Size
|
||||
err = bs.setUserInfo(tx, userID, userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete share id
|
||||
if fileInfo.IsDir {
|
||||
err = bs.delShareID(tx, itemPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (bs *BoltStore) MoveInfos(userID uint64, oldPath, newPath string, isDir bool) error {
|
||||
return bs.boltdb.Update(func(tx *bolt.Tx) error {
|
||||
var err error
|
||||
|
||||
fileInfoBucket := tx.Bucket([]byte(db.InfoNs))
|
||||
if fileInfoBucket == nil {
|
||||
return db.ErrBucketNotFound
|
||||
}
|
||||
|
||||
fileInfo, err := bs.getFileInfo(tx, userID, oldPath)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrKeyNotFound) && isDir {
|
||||
// the file info for the dir does not exist
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// delete old shareID
|
||||
if isDir {
|
||||
fileInfo.Shared = false
|
||||
fileInfo.ShareID = ""
|
||||
err = bs.delShareID(tx, oldPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// delete old info
|
||||
err = fileInfoBucket.Delete([]byte(oldPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("\n\n\n4", err)
|
||||
// add new info
|
||||
return bs.setFileInfo(tx, userID, newPath, fileInfo)
|
||||
})
|
||||
}
|
|
@ -1,3 +1,65 @@
|
|||
package db
|
||||
|
||||
const SchemaV2 = "v2" // add size to file info
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db/sitestore"
|
||||
)
|
||||
|
||||
const (
|
||||
SchemaV2 = "v2" // add size to file info
|
||||
|
||||
UsersNs = "users"
|
||||
InfoNs = "sharing"
|
||||
ShareIDNs = "sharingKey"
|
||||
|
||||
uploadsPrefix = "uploads"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrBucketNotFound = errors.New("bucket not found")
|
||||
ErrKeyNotFound = errors.New("key not found")
|
||||
ErrCreateExisting = errors.New("create upload info which already exists")
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
IsDir bool `json:"isDir"`
|
||||
Shared bool `json:"shared"`
|
||||
ShareID string `json:"shareID"` // for short url
|
||||
Sha1 string `json:"sha1"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type Quota struct {
|
||||
SpaceLimit int64 `json:"spaceLimit,string"`
|
||||
UploadSpeedLimit int `json:"uploadSpeedLimit"`
|
||||
DownloadSpeedLimit int `json:"downloadSpeedLimit"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Bg *sitestore.BgConfig `json:"bg"`
|
||||
CSSURL string `json:"cssURL"`
|
||||
LanPackURL string `json:"lanPackURL"`
|
||||
Lan string `json:"lan"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uint64 `json:"id,string"`
|
||||
Name string `json:"name"`
|
||||
Pwd string `json:"pwd"`
|
||||
Role string `json:"role"`
|
||||
UsedSpace int64 `json:"usedSpace,string"`
|
||||
Quota *Quota `json:"quota"`
|
||||
Preferences *Preferences `json:"preferences"`
|
||||
}
|
||||
|
||||
type UploadInfo struct {
|
||||
RealFilePath string `json:"realFilePath"`
|
||||
Size int64 `json:"size"`
|
||||
Uploaded int64 `json:"uploaded"`
|
||||
}
|
||||
|
||||
func UploadNS(user string) string {
|
||||
return fmt.Sprintf("%s/%s", uploadsPrefix, user)
|
||||
}
|
||||
|
|
|
@ -11,12 +11,11 @@ import (
|
|||
|
||||
"github.com/ihexxa/quickshare/src/db"
|
||||
"github.com/ihexxa/quickshare/src/kvstore"
|
||||
"github.com/ihexxa/quickshare/src/kvstore/boltdbpvd"
|
||||
)
|
||||
|
||||
const (
|
||||
InitNs = "Init"
|
||||
InfoNs = "sharing"
|
||||
ShareIDNs = "sharingKey"
|
||||
InitTimeKey = "initTime"
|
||||
SchemaVerKey = "SchemaVersion"
|
||||
SchemaV1 = "v1"
|
||||
|
@ -35,36 +34,29 @@ func IsNotFound(err error) bool {
|
|||
return err == ErrNotFound
|
||||
}
|
||||
|
||||
type FileInfo struct {
|
||||
IsDir bool `json:"isDir"`
|
||||
Shared bool `json:"shared"`
|
||||
ShareID string `json:"shareID"` // for short url
|
||||
Sha1 string `json:"sha1"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type IFileInfoStore interface {
|
||||
AddSharing(dirPath string) error
|
||||
DelSharing(dirPath string) error
|
||||
GetSharing(dirPath string) (bool, bool)
|
||||
ListSharings(prefix string) (map[string]string, error)
|
||||
GetInfo(itemPath string) (*FileInfo, error)
|
||||
SetInfo(itemPath string, info *FileInfo) error
|
||||
GetInfo(itemPath string) (*db.FileInfo, error)
|
||||
SetInfo(itemPath string, info *db.FileInfo) error
|
||||
DelInfo(itemPath string) error
|
||||
SetSha1(itemPath, sign string) error
|
||||
GetInfos(itemPaths []string) (map[string]*FileInfo, error)
|
||||
GetInfos(itemPaths []string) (map[string]*db.FileInfo, error)
|
||||
GetSharingDir(hashID string) (string, error)
|
||||
// upload info
|
||||
AddUploadInfo(user, filePath, tmpPath string, fileSize int64) error
|
||||
SetUploadInfo(user, filePath string, newUploaded int64) error
|
||||
GetUploadInfo(user, filePath string) (string, int64, int64, error)
|
||||
DelUploadInfo(user, filePath string) error
|
||||
ListUploadInfo(user string) ([]*UploadInfo, error)
|
||||
ListUploadInfo(user string) ([]*db.UploadInfo, error)
|
||||
}
|
||||
|
||||
type FileInfoStore struct {
|
||||
mtx *sync.RWMutex
|
||||
store kvstore.IKVStore
|
||||
mtx *sync.RWMutex
|
||||
store kvstore.IKVStore
|
||||
boltdb boltdbpvd.BoltProvider
|
||||
}
|
||||
|
||||
func migrate(fi *FileInfoStore) error {
|
||||
|
@ -77,7 +69,7 @@ func migrate(fi *FileInfoStore) error {
|
|||
switch ver {
|
||||
case "v0":
|
||||
// add ShareID to FileInfos
|
||||
infoStrs, err := fi.store.ListStringsIn(InfoNs)
|
||||
infoStrs, err := fi.store.ListStringsIn(db.InfoNs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -103,13 +95,13 @@ func migrate(fi *FileInfoStore) error {
|
|||
}
|
||||
shareID = dirShareID
|
||||
|
||||
err = fi.store.SetStringIn(ShareIDNs, shareID, itemPath)
|
||||
err = fi.store.SetStringIn(db.ShareIDNs, shareID, itemPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newInfo := &FileInfo{
|
||||
newInfo := &db.FileInfo{
|
||||
IsDir: infoV0.IsDir,
|
||||
Shared: infoV0.Shared,
|
||||
ShareID: shareID,
|
||||
|
@ -126,7 +118,7 @@ func migrate(fi *FileInfoStore) error {
|
|||
}
|
||||
case "v1":
|
||||
// add size to file info
|
||||
infoStrs, err := fi.store.ListStringsIn(InfoNs)
|
||||
infoStrs, err := fi.store.ListStringsIn(db.InfoNs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -145,7 +137,7 @@ func migrate(fi *FileInfoStore) error {
|
|||
return fmt.Errorf("list sharing error: %w", err)
|
||||
}
|
||||
|
||||
newInfo := &FileInfo{
|
||||
newInfo := &db.FileInfo{
|
||||
IsDir: infoV1.IsDir,
|
||||
Shared: infoV1.Shared,
|
||||
ShareID: infoV1.ShareID,
|
||||
|
@ -174,8 +166,8 @@ func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
|
|||
var err error
|
||||
for _, nsName := range []string{
|
||||
InitNs,
|
||||
InfoNs,
|
||||
ShareIDNs,
|
||||
db.InfoNs,
|
||||
db.ShareIDNs,
|
||||
} {
|
||||
if !store.HasNamespace(nsName) {
|
||||
if err = store.AddNamespace(nsName); err != nil {
|
||||
|
@ -184,9 +176,12 @@ func NewFileInfoStore(store kvstore.IKVStore) (*FileInfoStore, error) {
|
|||
}
|
||||
}
|
||||
|
||||
boltdb := store.(boltdbpvd.BoltProvider)
|
||||
|
||||
fi := &FileInfoStore{
|
||||
store: store,
|
||||
mtx: &sync.RWMutex{},
|
||||
store: store,
|
||||
boltdb: boltdb,
|
||||
mtx: &sync.RWMutex{},
|
||||
}
|
||||
if err = migrate(fi); err != nil {
|
||||
return nil, err
|
||||
|
@ -203,7 +198,7 @@ func (fi *FileInfoStore) AddSharing(dirPath string) error {
|
|||
if !IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
info = &FileInfo{
|
||||
info = &db.FileInfo{
|
||||
IsDir: true,
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +208,7 @@ func (fi *FileInfoStore) AddSharing(dirPath string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = fi.store.SetStringIn(ShareIDNs, shareID, dirPath)
|
||||
err = fi.store.SetStringIn(db.ShareIDNs, shareID, dirPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -238,14 +233,14 @@ func (fi *FileInfoStore) DelSharing(dirPath string) error {
|
|||
|
||||
// because before this version, shareIDs are not removed correctly
|
||||
// so it iterates all shareIDs and cleans remaining entries
|
||||
shareIDtoDir, err := fi.store.ListStringsIn(ShareIDNs)
|
||||
shareIDtoDir, err := fi.store.ListStringsIn(db.ShareIDNs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for shareID, shareDir := range shareIDtoDir {
|
||||
if shareDir == dirPath {
|
||||
err = fi.store.DelStringIn(ShareIDNs, shareID)
|
||||
err = fi.store.DelStringIn(db.ShareIDNs, shareID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -270,12 +265,12 @@ func (fi *FileInfoStore) GetSharing(dirPath string) (bool, bool) {
|
|||
}
|
||||
|
||||
func (fi *FileInfoStore) ListSharings(prefix string) (map[string]string, error) {
|
||||
infoStrs, err := fi.store.ListStringsByPrefixIn(prefix, InfoNs)
|
||||
infoStrs, err := fi.store.ListStringsByPrefixIn(prefix, db.InfoNs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := &FileInfo{}
|
||||
info := &db.FileInfo{}
|
||||
sharings := map[string]string{}
|
||||
for itemPath, infoStr := range infoStrs {
|
||||
err = json.Unmarshal([]byte(infoStr), info)
|
||||
|
@ -291,13 +286,13 @@ func (fi *FileInfoStore) ListSharings(prefix string) (map[string]string, error)
|
|||
return sharings, nil
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) GetInfo(itemPath string) (*FileInfo, error) {
|
||||
infoStr, ok := fi.store.GetStringIn(InfoNs, itemPath)
|
||||
func (fi *FileInfoStore) GetInfo(itemPath string) (*db.FileInfo, error) {
|
||||
infoStr, ok := fi.store.GetStringIn(db.InfoNs, itemPath)
|
||||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
info := &FileInfo{}
|
||||
info := &db.FileInfo{}
|
||||
err := json.Unmarshal([]byte(infoStr), info)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get file info: %w", err)
|
||||
|
@ -305,8 +300,8 @@ func (fi *FileInfoStore) GetInfo(itemPath string) (*FileInfo, error) {
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*FileInfo, error) {
|
||||
infos := map[string]*FileInfo{}
|
||||
func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*db.FileInfo, error) {
|
||||
infos := map[string]*db.FileInfo{}
|
||||
for _, itemPath := range itemPaths {
|
||||
info, err := fi.GetInfo(itemPath)
|
||||
if err != nil {
|
||||
|
@ -321,13 +316,13 @@ func (fi *FileInfoStore) GetInfos(itemPaths []string) (map[string]*FileInfo, err
|
|||
return infos, nil
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) SetInfo(itemPath string, info *FileInfo) error {
|
||||
func (fi *FileInfoStore) SetInfo(itemPath string, info *db.FileInfo) error {
|
||||
infoStr, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return fmt.Errorf("set file info: %w", err)
|
||||
}
|
||||
|
||||
err = fi.store.SetStringIn(InfoNs, itemPath, string(infoStr))
|
||||
err = fi.store.SetStringIn(db.InfoNs, itemPath, string(infoStr))
|
||||
if err != nil {
|
||||
return fmt.Errorf("set file info: %w", err)
|
||||
}
|
||||
|
@ -335,7 +330,7 @@ func (fi *FileInfoStore) SetInfo(itemPath string, info *FileInfo) error {
|
|||
}
|
||||
|
||||
func (fi *FileInfoStore) DelInfo(itemPath string) error {
|
||||
return fi.store.DelStringIn(InfoNs, itemPath)
|
||||
return fi.store.DelStringIn(db.InfoNs, itemPath)
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) SetSha1(itemPath, sign string) error {
|
||||
|
@ -347,7 +342,7 @@ func (fi *FileInfoStore) SetSha1(itemPath, sign string) error {
|
|||
if !IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
info = &FileInfo{
|
||||
info = &db.FileInfo{
|
||||
IsDir: false,
|
||||
Shared: false,
|
||||
}
|
||||
|
@ -370,7 +365,7 @@ func (fi *FileInfoStore) getShareID(payload string) (string, error) {
|
|||
}
|
||||
|
||||
shareID := fmt.Sprintf("%x", h.Sum(nil))[:7]
|
||||
shareDir, ok := fi.store.GetStringIn(ShareIDNs, shareID)
|
||||
shareDir, ok := fi.store.GetStringIn(db.ShareIDNs, shareID)
|
||||
if !ok {
|
||||
return shareID, nil
|
||||
} else if ok && shareDir == payload {
|
||||
|
@ -382,7 +377,7 @@ func (fi *FileInfoStore) getShareID(payload string) (string, error) {
|
|||
}
|
||||
|
||||
func (fi *FileInfoStore) GetSharingDir(hashID string) (string, error) {
|
||||
dirPath, ok := fi.store.GetStringIn(ShareIDNs, hashID)
|
||||
dirPath, ok := fi.store.GetStringIn(db.ShareIDNs, hashID)
|
||||
if !ok {
|
||||
return "", ErrSharingNotFound
|
||||
}
|
||||
|
|
|
@ -3,29 +3,17 @@ package fileinfostore
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCreateExisting = errors.New("create upload info which already exists")
|
||||
ErrGreaterThanSize = errors.New("uploaded is greater than file size")
|
||||
ErrUploadNotFound = errors.New("upload info not found")
|
||||
|
||||
uploadsPrefix = "uploads"
|
||||
)
|
||||
|
||||
type UploadInfo struct {
|
||||
RealFilePath string `json:"realFilePath"`
|
||||
Size int64 `json:"size"`
|
||||
Uploaded int64 `json:"uploaded"`
|
||||
}
|
||||
|
||||
func UploadNS(user string) string {
|
||||
return fmt.Sprintf("%s/%s", uploadsPrefix, user)
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) AddUploadInfo(user, filePath, tmpPath string, fileSize int64) error {
|
||||
ns := UploadNS(user)
|
||||
ns := db.UploadNS(user)
|
||||
err := fi.store.AddNamespace(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -33,10 +21,10 @@ func (fi *FileInfoStore) AddUploadInfo(user, filePath, tmpPath string, fileSize
|
|||
|
||||
_, ok := fi.store.GetStringIn(ns, tmpPath)
|
||||
if ok {
|
||||
return ErrCreateExisting
|
||||
return db.ErrCreateExisting
|
||||
}
|
||||
|
||||
info := &UploadInfo{
|
||||
info := &db.UploadInfo{
|
||||
RealFilePath: filePath,
|
||||
Size: fileSize,
|
||||
Uploaded: 0,
|
||||
|
@ -57,7 +45,7 @@ func (fi *FileInfoStore) SetUploadInfo(user, filePath string, newUploaded int64)
|
|||
return ErrGreaterThanSize
|
||||
}
|
||||
|
||||
newInfo := &UploadInfo{
|
||||
newInfo := &db.UploadInfo{
|
||||
RealFilePath: realFilePath,
|
||||
Size: fileSize,
|
||||
Uploaded: newUploaded,
|
||||
|
@ -66,17 +54,17 @@ func (fi *FileInfoStore) SetUploadInfo(user, filePath string, newUploaded int64)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fi.store.SetStringIn(UploadNS(user), filePath, string(newInfoBytes))
|
||||
return fi.store.SetStringIn(db.UploadNS(user), filePath, string(newInfoBytes))
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) GetUploadInfo(user, filePath string) (string, int64, int64, error) {
|
||||
ns := UploadNS(user)
|
||||
ns := db.UploadNS(user)
|
||||
infoBytes, ok := fi.store.GetStringIn(ns, filePath)
|
||||
if !ok {
|
||||
return "", 0, 0, ErrUploadNotFound
|
||||
}
|
||||
|
||||
info := &UploadInfo{}
|
||||
info := &db.UploadInfo{}
|
||||
err := json.Unmarshal([]byte(infoBytes), info)
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
|
@ -86,11 +74,11 @@ func (fi *FileInfoStore) GetUploadInfo(user, filePath string) (string, int64, in
|
|||
}
|
||||
|
||||
func (fi *FileInfoStore) DelUploadInfo(user, filePath string) error {
|
||||
return fi.store.DelInt64In(UploadNS(user), filePath)
|
||||
return fi.store.DelInt64In(db.UploadNS(user), filePath)
|
||||
}
|
||||
|
||||
func (fi *FileInfoStore) ListUploadInfo(user string) ([]*UploadInfo, error) {
|
||||
ns := UploadNS(user)
|
||||
func (fi *FileInfoStore) ListUploadInfo(user string) ([]*db.UploadInfo, error) {
|
||||
ns := db.UploadNS(user)
|
||||
if !fi.store.HasNamespace(ns) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -100,9 +88,9 @@ func (fi *FileInfoStore) ListUploadInfo(user string) ([]*UploadInfo, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
infos := []*UploadInfo{}
|
||||
infos := []*db.UploadInfo{}
|
||||
for _, infoStr := range infoMap {
|
||||
info := &UploadInfo{}
|
||||
info := &db.UploadInfo{}
|
||||
err = json.Unmarshal([]byte(infoStr), info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db"
|
||||
"github.com/ihexxa/quickshare/src/db/sitestore"
|
||||
"github.com/ihexxa/quickshare/src/kvstore"
|
||||
)
|
||||
|
@ -17,7 +18,6 @@ const (
|
|||
VisitorRole = "visitor"
|
||||
InitNs = "usersInit"
|
||||
IDsNs = "ids"
|
||||
UsersNs = "users"
|
||||
RoleListNs = "roleList"
|
||||
InitTimeKey = "initTime"
|
||||
VisitorID = uint64(1)
|
||||
|
@ -34,7 +34,7 @@ var (
|
|||
ErrReachedLimit = errors.New("reached space limit")
|
||||
ErrNotFound = errors.New("not found")
|
||||
|
||||
DefaultPreferences = Preferences{
|
||||
DefaultPreferences = db.Preferences{
|
||||
Bg: &sitestore.BgConfig{
|
||||
Url: "",
|
||||
Repeat: "no-repeat",
|
||||
|
@ -51,48 +51,25 @@ func IsReachedLimitErr(err error) bool {
|
|||
return err == ErrReachedLimit
|
||||
}
|
||||
|
||||
type Quota struct {
|
||||
SpaceLimit int64 `json:"spaceLimit,string"`
|
||||
UploadSpeedLimit int `json:"uploadSpeedLimit"`
|
||||
DownloadSpeedLimit int `json:"downloadSpeedLimit"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Bg *sitestore.BgConfig `json:"bg"`
|
||||
CSSURL string `json:"cssURL"`
|
||||
LanPackURL string `json:"lanPackURL"`
|
||||
Lan string `json:"lan"`
|
||||
}
|
||||
|
||||
type UserCfg struct {
|
||||
Name string `json:"name"`
|
||||
Role string `json:"role"`
|
||||
Pwd string `json:"pwd"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uint64 `json:"id,string"`
|
||||
Name string `json:"name"`
|
||||
Pwd string `json:"pwd"`
|
||||
Role string `json:"role"`
|
||||
UsedSpace int64 `json:"usedSpace,string"`
|
||||
Quota *Quota `json:"quota"`
|
||||
Preferences *Preferences `json:"preferences"`
|
||||
}
|
||||
|
||||
type IUserStore interface {
|
||||
Init(rootName, rootPwd string) error
|
||||
IsInited() bool
|
||||
AddUser(user *User) error
|
||||
AddUser(user *db.User) error
|
||||
DelUser(id uint64) error
|
||||
GetUser(id uint64) (*User, error)
|
||||
GetUserByName(name string) (*User, error)
|
||||
SetInfo(id uint64, user *User) error
|
||||
GetUser(id uint64) (*db.User, error)
|
||||
GetUserByName(name string) (*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
|
||||
SetPwd(id uint64, pwd string) error
|
||||
SetPreferences(id uint64, settings *Preferences) error
|
||||
ListUsers() ([]*User, error)
|
||||
SetPreferences(id uint64, settings *db.Preferences) error
|
||||
ListUsers() ([]*db.User, error)
|
||||
ListUserIDs() (map[string]string, error)
|
||||
AddRole(role string) error
|
||||
DelRole(role string) error
|
||||
|
@ -110,7 +87,7 @@ func NewKVUserStore(store kvstore.IKVStore) (*KVUserStore, error) {
|
|||
var err error
|
||||
for _, nsName := range []string{
|
||||
IDsNs,
|
||||
UsersNs,
|
||||
db.UsersNs,
|
||||
InitNs,
|
||||
RoleListNs,
|
||||
} {
|
||||
|
@ -129,12 +106,12 @@ func NewKVUserStore(store kvstore.IKVStore) (*KVUserStore, error) {
|
|||
func (us *KVUserStore) Init(rootName, rootPwd string) error {
|
||||
var err error
|
||||
adminPreferences := DefaultPreferences
|
||||
admin := &User{
|
||||
admin := &db.User{
|
||||
ID: 0,
|
||||
Name: rootName,
|
||||
Pwd: rootPwd,
|
||||
Role: AdminRole,
|
||||
Quota: &Quota{
|
||||
Quota: &db.Quota{
|
||||
SpaceLimit: defaultSpaceLimit,
|
||||
UploadSpeedLimit: defaultUploadSpeedLimit,
|
||||
DownloadSpeedLimit: defaultDownloadSpeedLimit,
|
||||
|
@ -143,12 +120,12 @@ func (us *KVUserStore) Init(rootName, rootPwd string) error {
|
|||
}
|
||||
|
||||
visitorPreferences := DefaultPreferences
|
||||
visitor := &User{
|
||||
visitor := &db.User{
|
||||
ID: VisitorID,
|
||||
Name: VisitorName,
|
||||
Pwd: rootPwd,
|
||||
Role: VisitorRole,
|
||||
Quota: &Quota{
|
||||
Quota: &db.Quota{
|
||||
SpaceLimit: 0,
|
||||
UploadSpeedLimit: visitorUploadSpeedLimit,
|
||||
DownloadSpeedLimit: visitorDownloadSpeedLimit,
|
||||
|
@ -156,7 +133,7 @@ func (us *KVUserStore) Init(rootName, rootPwd string) error {
|
|||
Preferences: &visitorPreferences,
|
||||
}
|
||||
|
||||
for _, user := range []*User{admin, visitor} {
|
||||
for _, user := range []*db.User{admin, visitor} {
|
||||
err = us.AddUser(user)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -178,12 +155,12 @@ func (us *KVUserStore) IsInited() bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
func (us *KVUserStore) AddUser(user *User) error {
|
||||
func (us *KVUserStore) AddUser(user *db.User) error {
|
||||
us.mtx.Lock()
|
||||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(user.ID)
|
||||
_, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
_, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if ok {
|
||||
return fmt.Errorf("userID (%d) exists", user.ID)
|
||||
}
|
||||
|
@ -203,7 +180,7 @@ func (us *KVUserStore) AddUser(user *User) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return us.store.SetStringIn(UsersNs, userID, string(userBytes))
|
||||
return us.store.SetStringIn(db.UsersNs, userID, string(userBytes))
|
||||
}
|
||||
|
||||
func (us *KVUserStore) DelUser(id uint64) error {
|
||||
|
@ -211,11 +188,11 @@ func (us *KVUserStore) DelUser(id uint64) error {
|
|||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return fmt.Errorf("userID (%s) does not exist", userID)
|
||||
}
|
||||
user := &User{}
|
||||
user := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), user)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -223,24 +200,24 @@ func (us *KVUserStore) DelUser(id uint64) error {
|
|||
|
||||
// TODO: add complement operations if part of the actions fails
|
||||
err1 := us.store.DelStringIn(IDsNs, user.Name)
|
||||
err2 := us.store.DelStringIn(UsersNs, userID)
|
||||
err2 := us.store.DelStringIn(db.UsersNs, userID)
|
||||
if err1 != nil || err2 != nil {
|
||||
return fmt.Errorf("DelUser: err1(%s) err2(%s)", err1, err2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us *KVUserStore) GetUser(id uint64) (*User, error) {
|
||||
func (us *KVUserStore) GetUser(id uint64) (*db.User, error) {
|
||||
us.mtx.RLock()
|
||||
defer us.mtx.RUnlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user (%s) not found", userID)
|
||||
}
|
||||
user := &User{}
|
||||
user := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -258,7 +235,7 @@ func (us *KVUserStore) GetUser(id uint64) (*User, error) {
|
|||
|
||||
}
|
||||
|
||||
func (us *KVUserStore) GetUserByName(name string) (*User, error) {
|
||||
func (us *KVUserStore) GetUserByName(name string) (*db.User, error) {
|
||||
us.mtx.RLock()
|
||||
defer us.mtx.RUnlock()
|
||||
|
||||
|
@ -266,12 +243,12 @@ func (us *KVUserStore) GetUserByName(name string) (*User, error) {
|
|||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
user := &User{}
|
||||
user := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -290,11 +267,11 @@ func (us *KVUserStore) SetPwd(id uint64, pwd string) error {
|
|||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return fmt.Errorf("user (%d) does not exist", id)
|
||||
}
|
||||
gotUser := &User{}
|
||||
gotUser := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), gotUser)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -307,19 +284,19 @@ func (us *KVUserStore) SetPwd(id uint64, pwd string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return us.store.SetStringIn(UsersNs, userID, string(infoBytes))
|
||||
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
|
||||
}
|
||||
|
||||
func (us *KVUserStore) SetPreferences(id uint64, prefers *Preferences) error {
|
||||
func (us *KVUserStore) SetPreferences(id uint64, prefers *db.Preferences) error {
|
||||
us.mtx.Lock()
|
||||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return fmt.Errorf("user (%d) does not exist", id)
|
||||
}
|
||||
gotUser := &User{}
|
||||
gotUser := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), gotUser)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -332,19 +309,19 @@ func (us *KVUserStore) SetPreferences(id uint64, prefers *Preferences) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return us.store.SetStringIn(UsersNs, userID, string(infoBytes))
|
||||
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
|
||||
}
|
||||
|
||||
func (us *KVUserStore) CanIncrUsed(id uint64, capacity int64) (bool, error) {
|
||||
us.mtx.Lock()
|
||||
defer us.mtx.Unlock()
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("user (%d) does not exist", id)
|
||||
}
|
||||
|
||||
gotUser := &User{}
|
||||
gotUser := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), gotUser)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -360,12 +337,12 @@ func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error {
|
|||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return fmt.Errorf("user (%d) does not exist", id)
|
||||
}
|
||||
|
||||
gotUser := &User{}
|
||||
gotUser := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), gotUser)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -389,19 +366,19 @@ func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return us.store.SetStringIn(UsersNs, userID, string(infoBytes))
|
||||
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
|
||||
}
|
||||
|
||||
func (us *KVUserStore) SetInfo(id uint64, user *User) error {
|
||||
func (us *KVUserStore) SetInfo(id uint64, user *db.User) error {
|
||||
us.mtx.Lock()
|
||||
defer us.mtx.Unlock()
|
||||
|
||||
userID := fmt.Sprint(id)
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
|
||||
if !ok {
|
||||
return fmt.Errorf("user (%d) does not exist", id)
|
||||
}
|
||||
gotUser := &User{}
|
||||
gotUser := &db.User{}
|
||||
err := json.Unmarshal([]byte(infoStr), gotUser)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -425,14 +402,14 @@ func (us *KVUserStore) SetInfo(id uint64, user *User) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return us.store.SetStringIn(UsersNs, userID, string(infoBytes))
|
||||
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
|
||||
}
|
||||
|
||||
func (us *KVUserStore) ListUsers() ([]*User, error) {
|
||||
func (us *KVUserStore) ListUsers() ([]*db.User, error) {
|
||||
us.mtx.RLock()
|
||||
defer us.mtx.RUnlock()
|
||||
|
||||
idToInfo, err := us.store.ListStringsIn(UsersNs)
|
||||
idToInfo, err := us.store.ListStringsIn(db.UsersNs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -441,9 +418,9 @@ func (us *KVUserStore) ListUsers() ([]*User, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
users := []*User{}
|
||||
users := []*db.User{}
|
||||
for _, infoStr := range idToInfo {
|
||||
user := &User{}
|
||||
user := &db.User{}
|
||||
err = json.Unmarshal([]byte(infoStr), user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -459,7 +436,7 @@ func (us *KVUserStore) ListUsers() ([]*User, error) {
|
|||
for _, user := range users {
|
||||
_, ok := nameToID[user.Name]
|
||||
if !ok {
|
||||
err = us.store.DelStringIn(UsersNs, fmt.Sprint(user.ID))
|
||||
err = us.store.DelStringIn(db.UsersNs, fmt.Sprint(user.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue