diff options
Diffstat (limited to 'models/quota/used.go')
-rw-r--r-- | models/quota/used.go | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/models/quota/used.go b/models/quota/used.go new file mode 100644 index 0000000..ff84ac2 --- /dev/null +++ b/models/quota/used.go @@ -0,0 +1,252 @@ +// 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 +} |