feat(db): add default rdb layer
This commit is contained in:
parent
61757aff4a
commit
5cae5be837
7 changed files with 732 additions and 561 deletions
|
@ -2,14 +2,15 @@ package sqlite
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db"
|
||||
)
|
||||
|
||||
func (st *SQLiteStore) getCfg(ctx context.Context) (*db.SiteConfig, error) {
|
||||
func (st *SQLiteStore) getCfg(ctx context.Context, tx *sql.Tx) (*db.SiteConfig, error) {
|
||||
var configStr string
|
||||
err := st.db.QueryRowContext(
|
||||
err := tx.QueryRowContext(
|
||||
ctx,
|
||||
`select config
|
||||
from t_config
|
||||
|
@ -31,7 +32,7 @@ func (st *SQLiteStore) getCfg(ctx context.Context) (*db.SiteConfig, error) {
|
|||
return config, nil
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) setCfg(ctx context.Context, cfg *db.SiteConfig) error {
|
||||
func (st *SQLiteStore) setCfg(ctx context.Context, tx *sql.Tx, cfg *db.SiteConfig) error {
|
||||
if err := db.CheckSiteCfg(cfg, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -41,7 +42,7 @@ func (st *SQLiteStore) setCfg(ctx context.Context, cfg *db.SiteConfig) error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_config
|
||||
set config=?
|
||||
|
@ -52,21 +53,32 @@ func (st *SQLiteStore) setCfg(ctx context.Context, cfg *db.SiteConfig) error {
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) SetClientCfg(ctx context.Context, cfg *db.ClientConfig) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
siteCfg, err := st.getCfg(ctx)
|
||||
siteCfg, err := st.getCfg(ctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
siteCfg.ClientCfg = cfg
|
||||
|
||||
return st.setCfg(ctx, siteCfg)
|
||||
err = st.setCfg(ctx, tx, siteCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) GetCfg(ctx context.Context) (*db.SiteConfig, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
|
||||
return st.getCfg(ctx)
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
return st.getCfg(ctx, tx)
|
||||
}
|
|
@ -12,13 +12,13 @@ import (
|
|||
"github.com/ihexxa/quickshare/src/db"
|
||||
)
|
||||
|
||||
func (st *SQLiteStore) getFileInfo(ctx context.Context, itemPath string) (*db.FileInfo, error) {
|
||||
func (st *SQLiteStore) getFileInfo(ctx context.Context, tx *sql.Tx, itemPath string) (*db.FileInfo, error) {
|
||||
var infoStr string
|
||||
fInfo := &db.FileInfo{}
|
||||
var isDir bool
|
||||
var size int64
|
||||
var shareId string
|
||||
err := st.db.QueryRowContext(
|
||||
err := tx.QueryRowContext(
|
||||
ctx,
|
||||
`select is_dir, size, share_id, info
|
||||
from t_file_info
|
||||
|
@ -49,15 +49,21 @@ func (st *SQLiteStore) getFileInfo(ctx context.Context, itemPath string) (*db.Fi
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) GetFileInfo(ctx context.Context, itemPath string) (*db.FileInfo, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
return st.getFileInfo(ctx, itemPath)
|
||||
return st.getFileInfo(ctx, tx, itemPath)
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListFileInfos(ctx context.Context, itemPaths []string) (map[string]*db.FileInfo, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// TODO: add pagination
|
||||
placeholders := []string{}
|
||||
|
@ -66,7 +72,7 @@ func (st *SQLiteStore) ListFileInfos(ctx context.Context, itemPaths []string) (m
|
|||
placeholders = append(placeholders, "?")
|
||||
values = append(values, itemPaths[i])
|
||||
}
|
||||
rows, err := st.db.QueryContext(
|
||||
rows, err := tx.QueryContext(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`select path, is_dir, size, share_id, info
|
||||
|
@ -88,7 +94,6 @@ func (st *SQLiteStore) ListFileInfos(ctx context.Context, itemPaths []string) (m
|
|||
fInfos := map[string]*db.FileInfo{}
|
||||
for rows.Next() {
|
||||
fInfo := &db.FileInfo{}
|
||||
|
||||
err = rows.Scan(&itemPath, &isDir, &size, &shareId, &fInfoStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -111,7 +116,7 @@ func (st *SQLiteStore) ListFileInfos(ctx context.Context, itemPaths []string) (m
|
|||
return fInfos, nil
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) addFileInfo(ctx context.Context, userId uint64, itemPath string, info *db.FileInfo) error {
|
||||
func (st *SQLiteStore) addFileInfo(ctx context.Context, tx *sql.Tx, userId uint64, itemPath string, info *db.FileInfo) error {
|
||||
infoStr, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -123,7 +128,7 @@ func (st *SQLiteStore) addFileInfo(ctx context.Context, userId uint64, itemPath
|
|||
}
|
||||
|
||||
dirPath, itemName := path.Split(itemPath)
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`insert into t_file_info (
|
||||
path, user, location, parent, name,
|
||||
|
@ -140,20 +145,27 @@ func (st *SQLiteStore) addFileInfo(ctx context.Context, userId uint64, itemPath
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) AddFileInfo(ctx context.Context, userId uint64, itemPath string, info *db.FileInfo) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
err := st.addFileInfo(ctx, userId, itemPath, info)
|
||||
err = st.addFileInfo(ctx, tx, userId, itemPath, info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// increase used space
|
||||
err = st.setUsed(ctx, tx, userId, true, info.Size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// increase used space
|
||||
return st.setUsed(ctx, userId, true, info.Size)
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) delFileInfo(ctx context.Context, itemPath string) error {
|
||||
_, err := st.db.ExecContext(
|
||||
func (st *SQLiteStore) delFileInfo(ctx context.Context, tx *sql.Tx, itemPath string) error {
|
||||
_, err := tx.ExecContext(
|
||||
ctx,
|
||||
`delete from t_file_info
|
||||
where path=?
|
||||
|
@ -164,10 +176,13 @@ func (st *SQLiteStore) delFileInfo(ctx context.Context, itemPath string) error {
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) SetSha1(ctx context.Context, itemPath, sign string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
info, err := st.getFileInfo(ctx, itemPath)
|
||||
info, err := st.getFileInfo(ctx, tx, itemPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -178,7 +193,7 @@ func (st *SQLiteStore) SetSha1(ctx context.Context, itemPath, sign string) error
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_file_info
|
||||
set info=?
|
||||
|
@ -186,15 +201,21 @@ func (st *SQLiteStore) SetSha1(ctx context.Context, itemPath, sign string) error
|
|||
infoStr,
|
||||
itemPath,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) DelFileInfo(ctx context.Context, userID uint64, itemPath string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// get all children and size
|
||||
rows, err := st.db.QueryContext(
|
||||
rows, err := tx.QueryContext(
|
||||
ctx,
|
||||
`select path, size
|
||||
from t_file_info
|
||||
|
@ -224,13 +245,13 @@ func (st *SQLiteStore) DelFileInfo(ctx context.Context, userID uint64, itemPath
|
|||
}
|
||||
|
||||
// decrease used space
|
||||
err = st.setUsed(ctx, userID, false, decrSize)
|
||||
err = st.setUsed(ctx, tx, userID, false, decrSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete file info entries
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`delete from t_file_info
|
||||
|
@ -239,14 +260,20 @@ func (st *SQLiteStore) DelFileInfo(ctx context.Context, userID uint64, itemPath
|
|||
),
|
||||
values...,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) MoveFileInfo(ctx context.Context, userId uint64, oldPath, newPath string, isDir bool) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
info, err := st.getFileInfo(ctx, oldPath)
|
||||
info, err := st.getFileInfo(ctx, tx, oldPath)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrFileInfoNotFound) {
|
||||
// info for file does not exist so no need to move it
|
||||
|
@ -256,11 +283,18 @@ func (st *SQLiteStore) MoveFileInfo(ctx context.Context, userId uint64, oldPath,
|
|||
}
|
||||
return err
|
||||
}
|
||||
err = st.delFileInfo(ctx, oldPath)
|
||||
|
||||
err = st.delFileInfo(ctx, tx, oldPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return st.addFileInfo(ctx, userId, newPath, info)
|
||||
|
||||
err = st.addFileInfo(ctx, tx, userId, newPath, info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func getLocation(itemPath string) (string, error) {
|
|
@ -30,11 +30,14 @@ func (st *SQLiteStore) generateShareID(payload string) (string, error) {
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) IsSharing(ctx context.Context, dirPath string) (bool, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var shareId string
|
||||
err := st.db.QueryRowContext(
|
||||
err = tx.QueryRowContext(
|
||||
ctx,
|
||||
`select share_id
|
||||
from t_file_info
|
||||
|
@ -54,11 +57,14 @@ func (st *SQLiteStore) IsSharing(ctx context.Context, dirPath string) (bool, err
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) GetSharingDir(ctx context.Context, hashID string) (string, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var sharedPath string
|
||||
err := st.db.QueryRowContext(
|
||||
err = tx.QueryRowContext(
|
||||
ctx,
|
||||
`select path
|
||||
from t_file_info
|
||||
|
@ -79,8 +85,11 @@ func (st *SQLiteStore) GetSharingDir(ctx context.Context, hashID string) (string
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
shareID, err := st.generateShareID(dirPath)
|
||||
if err != nil {
|
||||
|
@ -92,7 +101,7 @@ func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath st
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = st.getFileInfo(ctx, dirPath)
|
||||
_, err = st.getFileInfo(ctx, tx, dirPath)
|
||||
if err != nil && !errors.Is(err, db.ErrFileInfoNotFound) {
|
||||
return err
|
||||
}
|
||||
|
@ -106,7 +115,7 @@ func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath st
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`insert into t_file_info (
|
||||
path, user, location, parent, name,
|
||||
|
@ -119,38 +128,53 @@ func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath st
|
|||
dirPath, userId, location, parentPath, name,
|
||||
true, 0, shareID, infoStr,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
} else {
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_file_info
|
||||
set share_id=?
|
||||
where path=?`,
|
||||
shareID, dirPath,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) DelSharing(ctx context.Context, userId uint64, dirPath string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, err := st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_file_info
|
||||
set share_id=''
|
||||
where path=?`,
|
||||
dirPath,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListSharingsByLocation(ctx context.Context, location string) (map[string]string, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
rows, err := st.db.QueryContext(
|
||||
rows, err := tx.QueryContext(
|
||||
ctx,
|
||||
`select path, share_id
|
||||
from t_file_info
|
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/ihexxa/quickshare/src/db"
|
||||
)
|
||||
|
||||
func (st *SQLiteStore) addUploadInfoOnly(ctx context.Context, userId uint64, tmpPath, filePath string, fileSize int64) error {
|
||||
_, err := st.db.ExecContext(
|
||||
func (st *SQLiteStore) addUploadInfoOnly(ctx context.Context, tx *sql.Tx, userId uint64, tmpPath, filePath string, fileSize int64) error {
|
||||
_, err := tx.ExecContext(
|
||||
ctx,
|
||||
`insert into t_file_uploading (
|
||||
real_path, tmp_path, user, size, uploaded
|
||||
|
@ -23,17 +23,20 @@ func (st *SQLiteStore) addUploadInfoOnly(ctx context.Context, userId uint64, tmp
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) AddUploadInfos(ctx context.Context, userId uint64, tmpPath, filePath string, info *db.FileInfo) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
userInfo, err := st.getUser(ctx, userId)
|
||||
userInfo, err := st.getUser(ctx, tx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if userInfo.UsedSpace+info.Size > int64(userInfo.Quota.SpaceLimit) {
|
||||
return db.ErrQuota
|
||||
}
|
||||
|
||||
_, _, _, err = st.getUploadInfo(ctx, userId, filePath)
|
||||
_, _, _, err = st.getUploadInfo(ctx, tx, userId, filePath)
|
||||
if err == nil {
|
||||
return db.ErrKeyExisting
|
||||
} else if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
|
@ -41,43 +44,56 @@ func (st *SQLiteStore) AddUploadInfos(ctx context.Context, userId uint64, tmpPat
|
|||
}
|
||||
|
||||
userInfo.UsedSpace += info.Size
|
||||
err = st.setUser(ctx, userInfo)
|
||||
err = st.setUser(ctx, tx, userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return st.addUploadInfoOnly(ctx, userId, tmpPath, filePath, info.Size)
|
||||
err = st.addUploadInfoOnly(ctx, tx, userId, tmpPath, filePath, info.Size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) DelUploadingInfos(ctx context.Context, userId uint64, realPath string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
return st.delUploadingInfos(ctx, userId, realPath)
|
||||
err = st.delUploadingInfos(ctx, tx, userId, realPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) delUploadingInfos(ctx context.Context, userId uint64, realPath string) error {
|
||||
_, size, _, err := st.getUploadInfo(ctx, userId, realPath)
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) delUploadingInfos(ctx context.Context, tx *sql.Tx, userId uint64, realPath string) error {
|
||||
_, size, _, err := st.getUploadInfo(ctx, tx, userId, realPath)
|
||||
if err != nil {
|
||||
// info may not exist
|
||||
return err
|
||||
}
|
||||
|
||||
err = st.delUploadInfoOnly(ctx, userId, realPath)
|
||||
err = st.delUploadInfoOnly(ctx, tx, userId, realPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userInfo, err := st.getUser(ctx, userId)
|
||||
userInfo, err := st.getUser(ctx, tx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
userInfo.UsedSpace -= size
|
||||
return st.setUser(ctx, userInfo)
|
||||
return st.setUser(ctx, tx, userInfo)
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) delUploadInfoOnly(ctx context.Context, userId uint64, filePath string) error {
|
||||
_, err := st.db.ExecContext(
|
||||
func (st *SQLiteStore) delUploadInfoOnly(ctx context.Context, tx *sql.Tx, userId uint64, filePath string) error {
|
||||
_, err := tx.ExecContext(
|
||||
ctx,
|
||||
`delete from t_file_uploading
|
||||
where real_path=? and user=?`,
|
||||
|
@ -87,28 +103,39 @@ func (st *SQLiteStore) delUploadInfoOnly(ctx context.Context, userId uint64, fil
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) MoveUploadingInfos(ctx context.Context, userId uint64, uploadPath, itemPath string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, size, _, err := st.getUploadInfo(ctx, userId, itemPath)
|
||||
_, size, _, err := st.getUploadInfo(ctx, tx, userId, itemPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = st.delUploadInfoOnly(ctx, userId, itemPath)
|
||||
err = st.delUploadInfoOnly(ctx, tx, userId, itemPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return st.addFileInfo(ctx, userId, itemPath, &db.FileInfo{
|
||||
err = st.addFileInfo(ctx, tx, userId, itemPath, &db.FileInfo{
|
||||
Size: size,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) SetUploadInfo(ctx context.Context, userId uint64, filePath string, newUploaded int64) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var size, uploaded int64
|
||||
err := st.db.QueryRowContext(
|
||||
err = tx.QueryRowContext(
|
||||
ctx,
|
||||
`select size, uploaded
|
||||
from t_file_uploading
|
||||
|
@ -121,19 +148,24 @@ func (st *SQLiteStore) SetUploadInfo(ctx context.Context, userId uint64, filePat
|
|||
return db.ErrGreaterThanSize
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_file_uploading
|
||||
set uploaded=?
|
||||
where real_path=? and user=?`,
|
||||
newUploaded, filePath, userId,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) getUploadInfo(ctx context.Context, userId uint64, filePath string) (string, int64, int64, error) {
|
||||
func (st *SQLiteStore) getUploadInfo(
|
||||
ctx context.Context, tx *sql.Tx, userId uint64, filePath string,
|
||||
) (string, int64, int64, error) {
|
||||
var size, uploaded int64
|
||||
err := st.db.QueryRowContext(
|
||||
err := tx.QueryRowContext(
|
||||
ctx,
|
||||
`select size, uploaded
|
||||
from t_file_uploading
|
||||
|
@ -148,16 +180,23 @@ func (st *SQLiteStore) getUploadInfo(ctx context.Context, userId uint64, filePat
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) GetUploadInfo(ctx context.Context, userId uint64, filePath string) (string, int64, int64, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
return st.getUploadInfo(ctx, userId, filePath)
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
return st.getUploadInfo(ctx, tx, userId, filePath)
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListUploadInfos(ctx context.Context, userId uint64) ([]*db.UploadInfo, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
rows, err := st.db.QueryContext(
|
||||
rows, err := tx.QueryContext(
|
||||
ctx,
|
||||
`select real_path, size, uploaded
|
||||
from t_file_uploading
|
|
@ -16,7 +16,7 @@ type SQLiteStore struct {
|
|||
mtx *sync.RWMutex
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) setUser(ctx context.Context, user *db.User) error {
|
||||
func (st *SQLiteStore) setUser(ctx context.Context, tx *sql.Tx, user *db.User) error {
|
||||
var err error
|
||||
if err = db.CheckUser(user, false); err != nil {
|
||||
return err
|
||||
|
@ -30,7 +30,7 @@ func (st *SQLiteStore) setUser(ctx context.Context, user *db.User) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set name=?, pwd=?, role=?, used_space=?, quota=?, preference=?
|
||||
|
@ -46,10 +46,10 @@ func (st *SQLiteStore) setUser(ctx context.Context, user *db.User) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) getUser(ctx context.Context, id uint64) (*db.User, error) {
|
||||
func (st *SQLiteStore) getUser(ctx context.Context, tx *sql.Tx, id uint64) (*db.User, error) {
|
||||
user := &db.User{}
|
||||
var quotaStr, preferenceStr string
|
||||
err := st.db.QueryRowContext(
|
||||
err := tx.QueryRowContext(
|
||||
ctx,
|
||||
`select id, name, pwd, role, used_space, quota, preference
|
||||
from t_user
|
||||
|
@ -83,8 +83,11 @@ func (st *SQLiteStore) getUser(ctx context.Context, id uint64) (*db.User, error)
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) AddUser(ctx context.Context, user *db.User) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
quotaStr, err := json.Marshal(user.Quota)
|
||||
if err != nil {
|
||||
|
@ -94,7 +97,7 @@ func (st *SQLiteStore) AddUser(ctx context.Context, user *db.User) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`insert into t_user (id, name, pwd, role, used_space, quota, preference) values (?, ?, ?, ?, ?, ?, ?)`,
|
||||
user.ID,
|
||||
|
@ -105,26 +108,40 @@ func (st *SQLiteStore) AddUser(ctx context.Context, user *db.User) error {
|
|||
quotaStr,
|
||||
preferenceStr,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) DelUser(ctx context.Context, id uint64) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
_, err := st.db.ExecContext(
|
||||
func (st *SQLiteStore) DelUser(ctx context.Context, id uint64) error {
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`delete from t_user where id=?`,
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) GetUser(ctx context.Context, id uint64) (*db.User, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
user, err := st.getUser(ctx, id)
|
||||
func (st *SQLiteStore) GetUser(ctx context.Context, id uint64) (*db.User, error) {
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
user, err := st.getUser(ctx, tx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -133,12 +150,15 @@ func (st *SQLiteStore) GetUser(ctx context.Context, id uint64) (*db.User, error)
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) GetUserByName(ctx context.Context, name string) (*db.User, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
user := &db.User{}
|
||||
var quotaStr, preferenceStr string
|
||||
err := st.db.QueryRowContext(
|
||||
err = tx.QueryRowContext(
|
||||
ctx,
|
||||
`select id, name, pwd, role, used_space, quota, preference
|
||||
from t_user
|
||||
|
@ -172,10 +192,13 @@ func (st *SQLiteStore) GetUserByName(ctx context.Context, name string) (*db.User
|
|||
}
|
||||
|
||||
func (st *SQLiteStore) SetPwd(ctx context.Context, id uint64, pwd string) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, err := st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set pwd=?
|
||||
|
@ -183,20 +206,27 @@ func (st *SQLiteStore) SetPwd(ctx context.Context, id uint64, pwd string) error
|
|||
pwd,
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// role + quota
|
||||
func (st *SQLiteStore) SetInfo(ctx context.Context, id uint64, user *db.User) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
quotaStr, err := json.Marshal(user.Quota)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set role=?, quota=?
|
||||
|
@ -204,19 +234,26 @@ func (st *SQLiteStore) SetInfo(ctx context.Context, id uint64, user *db.User) er
|
|||
user.Role, quotaStr,
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) SetPreferences(ctx context.Context, id uint64, prefers *db.Preferences) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
preferenceStr, err := json.Marshal(prefers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set preference=?
|
||||
|
@ -224,17 +261,29 @@ func (st *SQLiteStore) SetPreferences(ctx context.Context, id uint64, prefers *d
|
|||
preferenceStr,
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) SetUsed(ctx context.Context, id uint64, incr bool, capacity int64) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
return st.setUsed(ctx, id, incr, capacity)
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) setUsed(ctx context.Context, id uint64, incr bool, capacity int64) error {
|
||||
gotUser, err := st.getUser(ctx, id)
|
||||
func (st *SQLiteStore) SetUsed(ctx context.Context, id uint64, incr bool, capacity int64) error {
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
err = st.setUsed(ctx, tx, id, incr, capacity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) setUsed(ctx context.Context, tx *sql.Tx, id uint64, incr bool, capacity int64) error {
|
||||
gotUser, err := st.getUser(ctx, tx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -252,7 +301,7 @@ func (st *SQLiteStore) setUsed(ctx context.Context, id uint64, incr bool, capaci
|
|||
gotUser.UsedSpace = gotUser.UsedSpace - capacity
|
||||
}
|
||||
|
||||
_, err = st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set used_space=?
|
||||
|
@ -260,18 +309,17 @@ func (st *SQLiteStore) setUsed(ctx context.Context, id uint64, incr bool, capaci
|
|||
gotUser.UsedSpace,
|
||||
gotUser.ID,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ResetUsed(ctx context.Context, id uint64, used int64) error {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, err := st.db.ExecContext(
|
||||
_, err = tx.ExecContext(
|
||||
ctx,
|
||||
`update t_user
|
||||
set used_space=?
|
||||
|
@ -279,15 +327,16 @@ func (st *SQLiteStore) ResetUsed(ctx context.Context, id uint64, used int64) err
|
|||
used,
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListUsers(ctx context.Context) ([]*db.User, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) listUsers(ctx context.Context, tx *sql.Tx) ([]*db.User, error) {
|
||||
// TODO: support pagination
|
||||
rows, err := st.db.QueryContext(
|
||||
rows, err := tx.QueryContext(
|
||||
ctx,
|
||||
`select id, name, role, used_space, quota, preference
|
||||
from t_user`,
|
||||
|
@ -329,11 +378,24 @@ func (st *SQLiteStore) ListUsers(ctx context.Context) ([]*db.User, error) {
|
|||
return users, nil
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListUserIDs(ctx context.Context) (map[string]string, error) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
func (st *SQLiteStore) ListUsers(ctx context.Context) ([]*db.User, error) {
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
users, err := st.ListUsers(ctx)
|
||||
return st.listUsers(ctx, tx)
|
||||
}
|
||||
|
||||
func (st *SQLiteStore) ListUserIDs(ctx context.Context) (map[string]string, error) {
|
||||
tx, err := st.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
users, err := st.listUsers(ctx, tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
|
@ -15,7 +15,36 @@ import (
|
|||
)
|
||||
|
||||
func TestFileStore(t *testing.T) {
|
||||
testSharingMethods := func(t *testing.T, store db.IDBQuickshare) {
|
||||
t.Run("testing file info store - sqlite", func(t *testing.T) {
|
||||
rootPath, err := ioutil.TempDir("./", "qs_sqlite_test_")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(rootPath)
|
||||
|
||||
dbPath := filepath.Join(rootPath, "files.sqlite")
|
||||
sqliteDB, err := sqlite.NewSQLite(dbPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sqliteDB.Close()
|
||||
|
||||
store, err := sqlite.NewSQLiteStore(sqliteDB)
|
||||
if err != nil {
|
||||
t.Fatal("fail to new sqlite store", err)
|
||||
}
|
||||
err = store.Init(context.TODO(), "admin", "1234", testSiteConfig)
|
||||
if err != nil {
|
||||
t.Fatal("fail to init", err)
|
||||
}
|
||||
|
||||
testSharingMethods(t, store)
|
||||
testFileInfoMethods(t, store)
|
||||
testUploadingMethods(t, store)
|
||||
})
|
||||
}
|
||||
|
||||
func testSharingMethods(t *testing.T, store db.IDBQuickshare) {
|
||||
dirPaths := []string{"admin/path1", "admin/path1/path2"}
|
||||
var err error
|
||||
location := "admin"
|
||||
|
@ -48,7 +77,7 @@ func TestFileStore(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(dirToID) != len(dirPaths) {
|
||||
t.Fatal("share size not match")
|
||||
t.Fatalf("share size not match %d %d", len(dirToID), len(dirPaths))
|
||||
}
|
||||
|
||||
for _, sharingDir := range dirPaths {
|
||||
|
@ -124,7 +153,149 @@ func TestFileStore(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
testFileInfoMethods := func(t *testing.T, store db.IDBQuickshare) {
|
||||
func testUploadingMethods(t *testing.T, store db.IDBQuickshare) {
|
||||
pathInfos := map[string]*db.FileInfo{
|
||||
"admin/origin/item1": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(7),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
"admin/origin/item2": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(3),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
"admin/origin/to_delete/item3": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(11),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
}
|
||||
var err error
|
||||
|
||||
adminId := uint64(0)
|
||||
ctx := context.TODO()
|
||||
|
||||
// add infos
|
||||
usedSpace := int64(0)
|
||||
usedSpaceAfterDeleting := int64(0)
|
||||
itemPaths := []string{}
|
||||
pathToTmpPath := map[string]string{}
|
||||
for itemPath, info := range pathInfos {
|
||||
tmpPath := strings.ReplaceAll(itemPath, "origin", "uploads")
|
||||
pathToTmpPath[itemPath] = tmpPath
|
||||
err = store.AddUploadInfos(ctx, adminId, tmpPath, itemPath, info)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
usedSpace += info.Size
|
||||
if !strings.Contains(itemPath, "delete") {
|
||||
usedSpaceAfterDeleting += info.Size
|
||||
}
|
||||
itemPaths = append(itemPaths, itemPath)
|
||||
}
|
||||
|
||||
// get infos
|
||||
for itemPath, info := range pathInfos {
|
||||
gotPath, size, uploaded, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if size != info.Size ||
|
||||
uploaded != int64(0) ||
|
||||
gotPath != itemPath {
|
||||
t.Fatalf("info not equaled (%v)", info)
|
||||
}
|
||||
}
|
||||
|
||||
// list infos
|
||||
uploadInfos, err := store.ListUploadInfos(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(uploadInfos) != len(pathInfos) {
|
||||
t.Fatalf("list result size not match (%v) (%d)", uploadInfos, len(pathInfos))
|
||||
}
|
||||
for _, uploadInfo := range uploadInfos {
|
||||
expected, ok := pathInfos[uploadInfo.RealFilePath]
|
||||
if !ok {
|
||||
t.Fatalf("path not found (%s)", uploadInfo.RealFilePath)
|
||||
}
|
||||
if uploadInfo.Uploaded != int64(0) ||
|
||||
expected.Size != uploadInfo.Size {
|
||||
t.Fatalf("info not equaled (%d) (%d)", uploadInfo.Uploaded, uploadInfo.Size)
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err := store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != usedSpace {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, usedSpace)
|
||||
}
|
||||
|
||||
// set uploading
|
||||
for itemPath, info := range pathInfos {
|
||||
err := store.SetUploadInfo(ctx, adminId, itemPath, int64(info.Size/2))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gotPath, size, uploaded, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if gotPath != itemPath || size != info.Size || uploaded != info.Size/2 {
|
||||
t.Fatal("uploaded info not match")
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err = store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != usedSpace {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, usedSpace)
|
||||
}
|
||||
|
||||
// del info
|
||||
for itemPath := range pathInfos {
|
||||
err = store.DelUploadingInfos(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err = store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != int64(0) {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, int64(0))
|
||||
}
|
||||
|
||||
// list infos
|
||||
uploadInfos, err = store.ListUploadInfos(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(uploadInfos) != 0 {
|
||||
t.Fatalf("list result size not match (%v) (%d)", uploadInfos, 0)
|
||||
}
|
||||
|
||||
for itemPath := range pathInfos {
|
||||
_, _, _, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testFileInfoMethods(t *testing.T, store db.IDBQuickshare) {
|
||||
pathInfos := map[string]*db.FileInfo{
|
||||
"admin/origin/item1": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
|
@ -272,174 +443,3 @@ func TestFileStore(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
testUploadingMethods := func(t *testing.T, store db.IDBQuickshare) {
|
||||
pathInfos := map[string]*db.FileInfo{
|
||||
"admin/origin/item1": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(7),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
"admin/origin/item2": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(3),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
"admin/origin/to_delete/item3": &db.FileInfo{
|
||||
// Shared: false, // deprecated
|
||||
IsDir: false,
|
||||
Size: int64(11),
|
||||
ShareID: "",
|
||||
Sha1: "",
|
||||
},
|
||||
}
|
||||
var err error
|
||||
|
||||
adminId := uint64(0)
|
||||
ctx := context.TODO()
|
||||
|
||||
// add infos
|
||||
usedSpace := int64(0)
|
||||
usedSpaceAfterDeleting := int64(0)
|
||||
itemPaths := []string{}
|
||||
pathToTmpPath := map[string]string{}
|
||||
for itemPath, info := range pathInfos {
|
||||
tmpPath := strings.ReplaceAll(itemPath, "origin", "uploads")
|
||||
pathToTmpPath[itemPath] = tmpPath
|
||||
err = store.AddUploadInfos(ctx, adminId, tmpPath, itemPath, info)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
usedSpace += info.Size
|
||||
if !strings.Contains(itemPath, "delete") {
|
||||
usedSpaceAfterDeleting += info.Size
|
||||
}
|
||||
itemPaths = append(itemPaths, itemPath)
|
||||
}
|
||||
|
||||
// get infos
|
||||
for itemPath, info := range pathInfos {
|
||||
gotPath, size, uploaded, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if size != info.Size ||
|
||||
uploaded != int64(0) ||
|
||||
gotPath != itemPath {
|
||||
t.Fatalf("info not equaled (%v)", info)
|
||||
}
|
||||
}
|
||||
|
||||
// list infos
|
||||
uploadInfos, err := store.ListUploadInfos(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(uploadInfos) != len(pathInfos) {
|
||||
t.Fatalf("list result size not match (%v) (%d)", uploadInfos, len(pathInfos))
|
||||
}
|
||||
for _, uploadInfo := range uploadInfos {
|
||||
expected, ok := pathInfos[uploadInfo.RealFilePath]
|
||||
if !ok {
|
||||
t.Fatalf("path not found (%s)", uploadInfo.RealFilePath)
|
||||
}
|
||||
if uploadInfo.Uploaded != int64(0) ||
|
||||
expected.Size != uploadInfo.Size {
|
||||
t.Fatalf("info not equaled (%d) (%d)", uploadInfo.Uploaded, uploadInfo.Size)
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err := store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != usedSpace {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, usedSpace)
|
||||
}
|
||||
|
||||
// set uploading
|
||||
for itemPath, info := range pathInfos {
|
||||
err := store.SetUploadInfo(ctx, adminId, itemPath, int64(info.Size/2))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gotPath, size, uploaded, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if gotPath != itemPath || size != info.Size || uploaded != info.Size/2 {
|
||||
t.Fatal("uploaded info not match")
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err = store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != usedSpace {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, usedSpace)
|
||||
}
|
||||
|
||||
// del info
|
||||
for itemPath := range pathInfos {
|
||||
err = store.DelUploadingInfos(ctx, adminId, itemPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check used space
|
||||
adminInfo, err = store.GetUser(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if adminInfo.UsedSpace != int64(0) {
|
||||
t.Fatalf("used space not match (%d) (%d)", adminInfo.UsedSpace, int64(0))
|
||||
}
|
||||
|
||||
// list infos
|
||||
uploadInfos, err = store.ListUploadInfos(ctx, adminId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(uploadInfos) != 0 {
|
||||
t.Fatalf("list result size not match (%v) (%d)", uploadInfos, 0)
|
||||
}
|
||||
|
||||
for itemPath := range pathInfos {
|
||||
_, _, _, err := store.GetUploadInfo(ctx, adminId, itemPath)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("testing file info store - sqlite", func(t *testing.T) {
|
||||
rootPath, err := ioutil.TempDir("./", "qs_sqlite_test_")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(rootPath)
|
||||
|
||||
dbPath := filepath.Join(rootPath, "files.sqlite")
|
||||
sqliteDB, err := sqlite.NewSQLite(dbPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sqliteDB.Close()
|
||||
|
||||
store, err := sqlite.NewSQLiteStore(sqliteDB)
|
||||
if err != nil {
|
||||
t.Fatal("fail to new sqlite store", err)
|
||||
}
|
||||
err = store.Init(context.TODO(), "admin", "1234", testSiteConfig)
|
||||
if err != nil {
|
||||
t.Fatal("fail to init", err)
|
||||
}
|
||||
|
||||
testSharingMethods(t, store)
|
||||
testFileInfoMethods(t, store)
|
||||
testUploadingMethods(t, store)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue