123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- // Copyright 2021 The Gitea Authors. All rights reserved.
- // Use of this source code is governed by a MIT-style
- // license that can be found in the LICENSE file.
-
- package packages
-
- import (
- "context"
- "errors"
- "fmt"
- "strings"
-
- "code.gitea.io/gitea/models/db"
-
- "xorm.io/builder"
- )
-
- func init() {
- db.RegisterModel(new(Package))
- }
-
- var (
- // ErrDuplicatePackage indicates a duplicated package error
- ErrDuplicatePackage = errors.New("Package does exist already")
- // ErrPackageNotExist indicates a package not exist error
- ErrPackageNotExist = errors.New("Package does not exist")
- )
-
- // Type of a package
- type Type string
-
- // List of supported packages
- const (
- TypeComposer Type = "composer"
- TypeConan Type = "conan"
- TypeContainer Type = "container"
- TypeGeneric Type = "generic"
- TypeHelm Type = "helm"
- TypeMaven Type = "maven"
- TypeNpm Type = "npm"
- TypeNuGet Type = "nuget"
- TypePyPI Type = "pypi"
- TypeRubyGems Type = "rubygems"
- )
-
- // Name gets the name of the package type
- func (pt Type) Name() string {
- switch pt {
- case TypeComposer:
- return "Composer"
- case TypeConan:
- return "Conan"
- case TypeContainer:
- return "Container"
- case TypeGeneric:
- return "Generic"
- case TypeHelm:
- return "Helm"
- case TypeMaven:
- return "Maven"
- case TypeNpm:
- return "npm"
- case TypeNuGet:
- return "NuGet"
- case TypePyPI:
- return "PyPI"
- case TypeRubyGems:
- return "RubyGems"
- }
- panic(fmt.Sprintf("unknown package type: %s", string(pt)))
- }
-
- // SVGName gets the name of the package type svg image
- func (pt Type) SVGName() string {
- switch pt {
- case TypeComposer:
- return "gitea-composer"
- case TypeConan:
- return "gitea-conan"
- case TypeContainer:
- return "octicon-container"
- case TypeGeneric:
- return "octicon-package"
- case TypeHelm:
- return "gitea-helm"
- case TypeMaven:
- return "gitea-maven"
- case TypeNpm:
- return "gitea-npm"
- case TypeNuGet:
- return "gitea-nuget"
- case TypePyPI:
- return "gitea-python"
- case TypeRubyGems:
- return "gitea-rubygems"
- }
- panic(fmt.Sprintf("unknown package type: %s", string(pt)))
- }
-
- // Package represents a package
- type Package struct {
- ID int64 `xorm:"pk autoincr"`
- OwnerID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- RepoID int64 `xorm:"INDEX"`
- Type Type `xorm:"UNIQUE(s) INDEX NOT NULL"`
- Name string `xorm:"NOT NULL"`
- LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
- SemverCompatible bool `xorm:"NOT NULL DEFAULT false"`
- }
-
- // TryInsertPackage inserts a package. If a package exists already, ErrDuplicatePackage is returned
- func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
- e := db.GetEngine(ctx)
-
- key := &Package{
- OwnerID: p.OwnerID,
- Type: p.Type,
- LowerName: p.LowerName,
- }
-
- has, err := e.Get(key)
- if err != nil {
- return nil, err
- }
- if has {
- return key, ErrDuplicatePackage
- }
- if _, err = e.Insert(p); err != nil {
- return nil, err
- }
- return p, nil
- }
-
- // SetRepositoryLink sets the linked repository
- func SetRepositoryLink(ctx context.Context, packageID, repoID int64) error {
- _, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: repoID})
- return err
- }
-
- // UnlinkRepositoryFromAllPackages unlinks every package from the repository
- func UnlinkRepositoryFromAllPackages(ctx context.Context, repoID int64) error {
- _, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Cols("repo_id").Update(&Package{})
- return err
- }
-
- // GetPackageByID gets a package by id
- func GetPackageByID(ctx context.Context, packageID int64) (*Package, error) {
- p := &Package{}
-
- has, err := db.GetEngine(ctx).ID(packageID).Get(p)
- if err != nil {
- return nil, err
- }
- if !has {
- return nil, ErrPackageNotExist
- }
- return p, nil
- }
-
- // GetPackageByName gets a package by name
- func GetPackageByName(ctx context.Context, ownerID int64, packageType Type, name string) (*Package, error) {
- var cond builder.Cond = builder.Eq{
- "package.owner_id": ownerID,
- "package.type": packageType,
- "package.lower_name": strings.ToLower(name),
- }
-
- p := &Package{}
-
- has, err := db.GetEngine(ctx).
- Where(cond).
- Get(p)
- if err != nil {
- return nil, err
- }
- if !has {
- return nil, ErrPackageNotExist
- }
- return p, nil
- }
-
- // GetPackagesByType gets all packages of a specific type
- func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([]*Package, error) {
- var cond builder.Cond = builder.Eq{
- "package.owner_id": ownerID,
- "package.type": packageType,
- }
-
- ps := make([]*Package, 0, 10)
- return ps, db.GetEngine(ctx).
- Where(cond).
- Find(&ps)
- }
-
- // DeletePackagesIfUnreferenced deletes a package if there are no associated versions
- func DeletePackagesIfUnreferenced(ctx context.Context) error {
- in := builder.
- Select("package.id").
- From("package").
- LeftJoin("package_version", "package_version.package_id = package.id").
- Where(builder.Expr("package_version.id IS NULL"))
-
- _, err := db.GetEngine(ctx).
- // double select workaround for MySQL
- // https://stackoverflow.com/questions/4471277/mysql-delete-from-with-subquery-as-condition
- Where(builder.In("package.id", builder.Select("id").From(in, "temp"))).
- Delete(&Package{})
-
- return err
- }
-
- // HasOwnerPackages tests if a user/org has packages
- func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) {
- return db.GetEngine(ctx).Where("owner_id = ?", ownerID).Exist(&Package{})
- }
-
- // HasRepositoryPackages tests if a repository has packages
- func HasRepositoryPackages(ctx context.Context, repositoryID int64) (bool, error) {
- return db.GetEngine(ctx).Where("repo_id = ?", repositoryID).Exist(&Package{})
- }
|