mirror of
1
Fork 0
forgejo/models/quota/used.go

253 lines
6.4 KiB
Go

// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package quota
import (
"context"
action_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
package_model "code.gitea.io/gitea/models/packages"
repo_model "code.gitea.io/gitea/models/repo"
"xorm.io/builder"
)
type Used struct {
Size UsedSize
}
type UsedSize struct {
Repos UsedSizeRepos
Git UsedSizeGit
Assets UsedSizeAssets
}
func (u UsedSize) All() int64 {
return u.Repos.All() + u.Git.All(u.Repos) + u.Assets.All()
}
type UsedSizeRepos struct {
Public int64
Private int64
}
func (u UsedSizeRepos) All() int64 {
return u.Public + u.Private
}
type UsedSizeGit struct {
LFS int64
}
func (u UsedSizeGit) All(r UsedSizeRepos) int64 {
return u.LFS + r.All()
}
type UsedSizeAssets struct {
Attachments UsedSizeAssetsAttachments
Artifacts int64
Packages UsedSizeAssetsPackages
}
func (u UsedSizeAssets) All() int64 {
return u.Attachments.All() + u.Artifacts + u.Packages.All
}
type UsedSizeAssetsAttachments struct {
Issues int64
Releases int64
}
func (u UsedSizeAssetsAttachments) All() int64 {
return u.Issues + u.Releases
}
type UsedSizeAssetsPackages struct {
All int64
}
func (u Used) CalculateFor(subject LimitSubject) int64 {
switch subject {
case LimitSubjectNone:
return 0
case LimitSubjectSizeAll:
return u.Size.All()
case LimitSubjectSizeReposAll:
return u.Size.Repos.All()
case LimitSubjectSizeReposPublic:
return u.Size.Repos.Public
case LimitSubjectSizeReposPrivate:
return u.Size.Repos.Private
case LimitSubjectSizeGitAll:
return u.Size.Git.All(u.Size.Repos)
case LimitSubjectSizeGitLFS:
return u.Size.Git.LFS
case LimitSubjectSizeAssetsAll:
return u.Size.Assets.All()
case LimitSubjectSizeAssetsAttachmentsAll:
return u.Size.Assets.Attachments.All()
case LimitSubjectSizeAssetsAttachmentsIssues:
return u.Size.Assets.Attachments.Issues
case LimitSubjectSizeAssetsAttachmentsReleases:
return u.Size.Assets.Attachments.Releases
case LimitSubjectSizeAssetsArtifacts:
return u.Size.Assets.Artifacts
case LimitSubjectSizeAssetsPackagesAll:
return u.Size.Assets.Packages.All
case LimitSubjectSizeWiki:
return 0
}
return 0
}
func makeUserOwnedCondition(q string, userID int64) builder.Cond {
switch q {
case "repositories", "attachments", "artifacts":
return builder.Eq{"`repository`.owner_id": userID}
case "packages":
return builder.Or(
builder.Eq{"`repository`.owner_id": userID},
builder.And(
builder.Eq{"`package`.repo_id": 0},
builder.Eq{"`package`.owner_id": userID},
),
)
}
return builder.NewCond()
}
func createQueryFor(ctx context.Context, userID int64, q string) db.Engine {
session := db.GetEngine(ctx)
switch q {
case "repositories":
session = session.Table("repository")
case "attachments":
session = session.
Table("attachment").
Join("INNER", "`repository`", "`attachment`.repo_id = `repository`.id")
case "artifacts":
session = session.
Table("action_artifact").
Join("INNER", "`repository`", "`action_artifact`.repo_id = `repository`.id")
case "packages":
session = session.
Table("package_version").
Join("INNER", "`package_file`", "`package_file`.version_id = `package_version`.id").
Join("INNER", "`package_blob`", "`package_file`.blob_id = `package_blob`.id").
Join("INNER", "`package`", "`package_version`.package_id = `package`.id").
Join("LEFT OUTER", "`repository`", "`package`.repo_id = `repository`.id")
}
return session.Where(makeUserOwnedCondition(q, userID))
}
func GetQuotaAttachmentsForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*repo_model.Attachment, error) {
var attachments []*repo_model.Attachment
sess := createQueryFor(ctx, userID, "attachments").
OrderBy("`attachment`.size DESC")
if opts.PageSize > 0 {
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
}
count, err := sess.FindAndCount(&attachments)
if err != nil {
return 0, nil, err
}
return count, &attachments, nil
}
func GetQuotaPackagesForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*package_model.PackageVersion, error) {
var pkgs []*package_model.PackageVersion
sess := createQueryFor(ctx, userID, "packages").
OrderBy("`package_blob`.size DESC")
if opts.PageSize > 0 {
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
}
count, err := sess.FindAndCount(&pkgs)
if err != nil {
return 0, nil, err
}
return count, &pkgs, nil
}
func GetQuotaArtifactsForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*action_model.ActionArtifact, error) {
var artifacts []*action_model.ActionArtifact
sess := createQueryFor(ctx, userID, "artifacts").
OrderBy("`action_artifact`.file_compressed_size DESC")
if opts.PageSize > 0 {
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
}
count, err := sess.FindAndCount(&artifacts)
if err != nil {
return 0, nil, err
}
return count, &artifacts, nil
}
func GetUsedForUser(ctx context.Context, userID int64) (*Used, error) {
var used Used
_, err := createQueryFor(ctx, userID, "repositories").
Where("`repository`.is_private = ?", true).
Select("SUM(git_size) AS code").
Get(&used.Size.Repos.Private)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "repositories").
Where("`repository`.is_private = ?", false).
Select("SUM(git_size) AS code").
Get(&used.Size.Repos.Public)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "repositories").
Select("SUM(lfs_size) AS lfs").
Get(&used.Size.Git.LFS)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "attachments").
Select("SUM(`attachment`.size) AS size").
Where("`attachment`.release_id != 0").
Get(&used.Size.Assets.Attachments.Releases)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "attachments").
Select("SUM(`attachment`.size) AS size").
Where("`attachment`.release_id = 0").
Get(&used.Size.Assets.Attachments.Issues)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "artifacts").
Select("SUM(file_compressed_size) AS size").
Get(&used.Size.Assets.Artifacts)
if err != nil {
return nil, err
}
_, err = createQueryFor(ctx, userID, "packages").
Select("SUM(package_blob.size) AS size").
Get(&used.Size.Assets.Packages.All)
if err != nil {
return nil, err
}
return &used, nil
}