mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-05-02 05:14:17 +00:00
100 lines
1.9 KiB
Go
100 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/haiwen/seafile-server/fileserver/repomgr"
|
|
)
|
|
|
|
// InfiniteQuota indicates that the quota is unlimited.
|
|
const (
|
|
InfiniteQuota = -2
|
|
)
|
|
|
|
func checkQuota(repoID string, delta int64) (int, error) {
|
|
if repoID == "" {
|
|
err := fmt.Errorf("bad argumets")
|
|
return -1, err
|
|
}
|
|
|
|
vInfo, err := repomgr.GetVirtualRepoInfo(repoID)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get virtual repo: %v", err)
|
|
return -1, err
|
|
}
|
|
rRepoID := repoID
|
|
if vInfo != nil {
|
|
rRepoID = vInfo.OriginRepoID
|
|
}
|
|
|
|
user, err := repomgr.GetRepoOwner(rRepoID)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get repo owner: %v", err)
|
|
return -1, err
|
|
}
|
|
if user == "" {
|
|
err := fmt.Errorf("repo %s has no owner", repoID)
|
|
return -1, err
|
|
}
|
|
quota, err := getUserQuota(user)
|
|
if err != nil {
|
|
err := fmt.Errorf("failed to get user quota: %v", err)
|
|
return -1, err
|
|
}
|
|
|
|
if quota == InfiniteQuota {
|
|
return 0, nil
|
|
}
|
|
usage, err := getUserUsage(user)
|
|
if err != nil || usage < 0 {
|
|
err := fmt.Errorf("failed to get user usage: %v", err)
|
|
return -1, err
|
|
}
|
|
usage += delta
|
|
if usage >= quota {
|
|
return 1, nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
func getUserQuota(user string) (int64, error) {
|
|
var quota int64
|
|
sqlStr := "SELECT quota FROM UserQuota WHERE user=?"
|
|
row := seafileDB.QueryRow(sqlStr, user)
|
|
if err := row.Scan("a); err != nil {
|
|
if err != sql.ErrNoRows {
|
|
return -1, err
|
|
}
|
|
}
|
|
|
|
if quota <= 0 {
|
|
quota = options.defaultQuota
|
|
}
|
|
|
|
return quota, nil
|
|
}
|
|
|
|
func getUserUsage(user string) (int64, error) {
|
|
var usage sql.NullInt64
|
|
sqlStr := "SELECT SUM(size) FROM " +
|
|
"RepoOwner o LEFT JOIN VirtualRepo v ON o.repo_id=v.repo_id, " +
|
|
"RepoSize WHERE " +
|
|
"owner_id=? AND o.repo_id=RepoSize.repo_id " +
|
|
"AND v.repo_id IS NULL"
|
|
|
|
row := seafileDB.QueryRow(sqlStr, user)
|
|
if err := row.Scan(&usage); err != nil {
|
|
if err != sql.ErrNoRows {
|
|
return -1, err
|
|
}
|
|
}
|
|
|
|
if usage.Valid {
|
|
return usage.Int64, nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|