Package registry changes (#19305)
* removed debug logs * fixed SELECT * removed unneeded error type * use common SearchVersions method * remove empty container upload versions * return err
This commit is contained in:
		
							parent
							
								
									8ddcd37f13
								
							
						
					
					
						commit
						5e242e021b
					
				
					 17 changed files with 185 additions and 150 deletions
				
			
		| 
						 | 
				
			
			@ -9,11 +9,15 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models/packages"
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	packages_model "code.gitea.io/gitea/models/packages"
 | 
			
		||||
	container_model "code.gitea.io/gitea/models/packages/container"
 | 
			
		||||
	"code.gitea.io/gitea/models/unittest"
 | 
			
		||||
	user_model "code.gitea.io/gitea/models/user"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	packages_service "code.gitea.io/gitea/services/packages"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +47,7 @@ func TestPackageAPI(t *testing.T) {
 | 
			
		|||
		DecodeJSON(t, resp, &apiPackages)
 | 
			
		||||
 | 
			
		||||
		assert.Len(t, apiPackages, 1)
 | 
			
		||||
		assert.Equal(t, string(packages.TypeGeneric), apiPackages[0].Type)
 | 
			
		||||
		assert.Equal(t, string(packages_model.TypeGeneric), apiPackages[0].Type)
 | 
			
		||||
		assert.Equal(t, packageName, apiPackages[0].Name)
 | 
			
		||||
		assert.Equal(t, packageVersion, apiPackages[0].Version)
 | 
			
		||||
		assert.NotNil(t, apiPackages[0].Creator)
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +66,7 @@ func TestPackageAPI(t *testing.T) {
 | 
			
		|||
		var p *api.Package
 | 
			
		||||
		DecodeJSON(t, resp, &p)
 | 
			
		||||
 | 
			
		||||
		assert.Equal(t, string(packages.TypeGeneric), p.Type)
 | 
			
		||||
		assert.Equal(t, string(packages_model.TypeGeneric), p.Type)
 | 
			
		||||
		assert.Equal(t, packageName, p.Name)
 | 
			
		||||
		assert.Equal(t, packageVersion, p.Version)
 | 
			
		||||
		assert.NotNil(t, p.Creator)
 | 
			
		||||
| 
						 | 
				
			
			@ -100,3 +104,26 @@ func TestPackageAPI(t *testing.T) {
 | 
			
		|||
		MakeRequest(t, req, http.StatusNoContent)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPackageCleanup(t *testing.T) {
 | 
			
		||||
	defer prepareTestEnv(t)()
 | 
			
		||||
 | 
			
		||||
	time.Sleep(time.Second)
 | 
			
		||||
 | 
			
		||||
	pbs, err := packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, time.Duration(0))
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
	assert.NotEmpty(t, pbs)
 | 
			
		||||
 | 
			
		||||
	_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, 2, packages_model.TypeContainer, "test", container_model.UploadVersion)
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	err = packages_service.Cleanup(nil, time.Duration(0))
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	pbs, err = packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, time.Duration(0))
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
	assert.Empty(t, pbs)
 | 
			
		||||
 | 
			
		||||
	_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, 2, packages_model.TypeContainer, "test", container_model.UploadVersion)
 | 
			
		||||
	assert.ErrorIs(t, err, packages_model.ErrPackageNotExist)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,14 +65,14 @@ func findPropertyValues(ctx context.Context, propertyName string, ownerID int64,
 | 
			
		|||
	in2 := builder.
 | 
			
		||||
		Select("package_file.id").
 | 
			
		||||
		From("package_file").
 | 
			
		||||
		Join("INNER", "package_version", "package_version.id = package_file.version_id").
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		InnerJoin("package_version", "package_version.id = package_file.version_id").
 | 
			
		||||
		InnerJoin("package", "package.id = package_version.package_id").
 | 
			
		||||
		Where(cond)
 | 
			
		||||
 | 
			
		||||
	query := builder.
 | 
			
		||||
		Select("package_property.value, MAX(package_file.created_unix) AS created_unix").
 | 
			
		||||
		From("package_property").
 | 
			
		||||
		Join("INNER", "package_file", "package_file.id = package_property.ref_id").
 | 
			
		||||
		InnerJoin("package_file", "package_file.id = package_property.ref_id").
 | 
			
		||||
		Where(builder.Eq{"package_property.name": propertyName}.And(builder.In("package_property.ref_id", in2))).
 | 
			
		||||
		GroupBy("package_property.value").
 | 
			
		||||
		OrderBy("created_unix DESC")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,8 +74,8 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
 | 
			
		|||
	query := builder.
 | 
			
		||||
		Select("package.name, package_version.version, package_file.id").
 | 
			
		||||
		From("package_file").
 | 
			
		||||
		Join("INNER", "package_version", "package_version.id = package_file.version_id").
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		InnerJoin("package_version", "package_version.id = package_file.version_id").
 | 
			
		||||
		InnerJoin("package", "package.id = package_version.package_id").
 | 
			
		||||
		Where(cond)
 | 
			
		||||
 | 
			
		||||
	results := make([]struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,13 +190,15 @@ func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([]
 | 
			
		|||
// DeletePackagesIfUnreferenced deletes a package if there are no associated versions
 | 
			
		||||
func DeletePackagesIfUnreferenced(ctx context.Context) error {
 | 
			
		||||
	in := builder.
 | 
			
		||||
		Select("package_version.package_id").
 | 
			
		||||
		Select("package.id").
 | 
			
		||||
		From("package").
 | 
			
		||||
		Join("LEFT", "package_version", "package_version.package_id = package.id").
 | 
			
		||||
		LeftJoin("package_version", "package_version.package_id = package.id").
 | 
			
		||||
		Where(builder.Expr("package_version.id IS NULL"))
 | 
			
		||||
 | 
			
		||||
	_, err := db.GetEngine(ctx).
 | 
			
		||||
		Where(builder.In("package.id", in)).
 | 
			
		||||
		// 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ func FindExpiredUnreferencedBlobs(ctx context.Context, olderThan time.Duration)
 | 
			
		|||
	pbs := make([]*PackageBlob, 0, 10)
 | 
			
		||||
	return pbs, db.GetEngine(ctx).
 | 
			
		||||
		Table("package_blob").
 | 
			
		||||
		Join("LEFT OUTER", "package_file", "package_file.blob_id = package_blob.id").
 | 
			
		||||
		Join("LEFT", "package_file", "package_file.blob_id = package_blob.id").
 | 
			
		||||
		Where("package_file.id IS NULL AND package_blob.created_unix < ?", time.Now().Add(-olderThan).Unix()).
 | 
			
		||||
		Find(&pbs)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ func (opts *PackageFileSearchOptions) toConds() builder.Cond {
 | 
			
		|||
		in := builder.
 | 
			
		||||
			Select("package_version.id").
 | 
			
		||||
			From("package_version").
 | 
			
		||||
			Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
			InnerJoin("package", "package.id = package_version.package_id").
 | 
			
		||||
			Where(versionCond)
 | 
			
		||||
 | 
			
		||||
		cond = cond.And(builder.In("package_file.version_id", in))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,13 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"xorm.io/builder"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrDuplicatePackageVersion indicates a duplicated package version error
 | 
			
		||||
	ErrDuplicatePackageVersion = errors.New("Package version does exist already")
 | 
			
		||||
	// ErrPackageVersionNotExist indicates a package version not exist error
 | 
			
		||||
	ErrPackageVersionNotExist = errors.New("Package version does not exist")
 | 
			
		||||
)
 | 
			
		||||
// ErrDuplicatePackageVersion indicates a duplicated package version error
 | 
			
		||||
var ErrDuplicatePackageVersion = errors.New("Package version already exists")
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	db.RegisterModel(new(PackageVersion))
 | 
			
		||||
| 
						 | 
				
			
			@ -99,75 +96,49 @@ func GetInternalVersionByNameAndVersion(ctx context.Context, ownerID int64, pack
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType Type, name, version string, isInternal bool) (*PackageVersion, error) {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{
 | 
			
		||||
		"package.owner_id":            ownerID,
 | 
			
		||||
		"package.type":                packageType,
 | 
			
		||||
		"package.lower_name":          strings.ToLower(name),
 | 
			
		||||
		"package_version.is_internal": isInternal,
 | 
			
		||||
	}
 | 
			
		||||
	pv := &PackageVersion{
 | 
			
		||||
		LowerVersion: strings.ToLower(version),
 | 
			
		||||
	}
 | 
			
		||||
	has, err := db.GetEngine(ctx).
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		Where(cond).
 | 
			
		||||
		Get(pv)
 | 
			
		||||
	pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
 | 
			
		||||
		OwnerID: ownerID,
 | 
			
		||||
		Type:    packageType,
 | 
			
		||||
		Name: SearchValue{
 | 
			
		||||
			ExactMatch: true,
 | 
			
		||||
			Value:      name,
 | 
			
		||||
		},
 | 
			
		||||
		Version: SearchValue{
 | 
			
		||||
			ExactMatch: true,
 | 
			
		||||
			Value:      version,
 | 
			
		||||
		},
 | 
			
		||||
		IsInternal: isInternal,
 | 
			
		||||
		Paginator:  db.NewAbsoluteListOptions(0, 1),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if !has {
 | 
			
		||||
	if len(pvs) == 0 {
 | 
			
		||||
		return nil, ErrPackageNotExist
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pv, nil
 | 
			
		||||
	return pvs[0], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetVersionsByPackageType gets all versions of a specific type
 | 
			
		||||
func GetVersionsByPackageType(ctx context.Context, ownerID int64, packageType Type) ([]*PackageVersion, error) {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{
 | 
			
		||||
		"package.owner_id":            ownerID,
 | 
			
		||||
		"package.type":                packageType,
 | 
			
		||||
		"package_version.is_internal": false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pvs := make([]*PackageVersion, 0, 10)
 | 
			
		||||
	return pvs, db.GetEngine(ctx).
 | 
			
		||||
		Where(cond).
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		Find(&pvs)
 | 
			
		||||
	pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
 | 
			
		||||
		OwnerID: ownerID,
 | 
			
		||||
		Type:    packageType,
 | 
			
		||||
	})
 | 
			
		||||
	return pvs, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetVersionsByPackageName gets all versions of a specific package
 | 
			
		||||
func GetVersionsByPackageName(ctx context.Context, ownerID int64, packageType Type, name string) ([]*PackageVersion, error) {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{
 | 
			
		||||
		"package.owner_id":            ownerID,
 | 
			
		||||
		"package.type":                packageType,
 | 
			
		||||
		"package.lower_name":          strings.ToLower(name),
 | 
			
		||||
		"package_version.is_internal": false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pvs := make([]*PackageVersion, 0, 10)
 | 
			
		||||
	return pvs, db.GetEngine(ctx).
 | 
			
		||||
		Where(cond).
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		Find(&pvs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetVersionsByFilename gets all versions which are linked to a filename
 | 
			
		||||
func GetVersionsByFilename(ctx context.Context, ownerID int64, packageType Type, filename string) ([]*PackageVersion, error) {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{
 | 
			
		||||
		"package.owner_id":            ownerID,
 | 
			
		||||
		"package.type":                packageType,
 | 
			
		||||
		"package_file.lower_name":     strings.ToLower(filename),
 | 
			
		||||
		"package_version.is_internal": false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pvs := make([]*PackageVersion, 0, 10)
 | 
			
		||||
	return pvs, db.GetEngine(ctx).
 | 
			
		||||
		Where(cond).
 | 
			
		||||
		Join("INNER", "package_file", "package_file.version_id = package_version.id").
 | 
			
		||||
		Join("INNER", "package", "package.id = package_version.package_id").
 | 
			
		||||
		Find(&pvs)
 | 
			
		||||
	pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
 | 
			
		||||
		OwnerID: ownerID,
 | 
			
		||||
		Type:    packageType,
 | 
			
		||||
		Name: SearchValue{
 | 
			
		||||
			ExactMatch: true,
 | 
			
		||||
			Value:      name,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	return pvs, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteVersionByID deletes a version by id
 | 
			
		||||
| 
						 | 
				
			
			@ -183,21 +154,32 @@ func HasVersionFileReferences(ctx context.Context, versionID int64) (bool, error
 | 
			
		|||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SearchValue describes a value to search
 | 
			
		||||
// If ExactMatch is true, the field must match the value otherwise a LIKE search is performed.
 | 
			
		||||
type SearchValue struct {
 | 
			
		||||
	Value      string
 | 
			
		||||
	ExactMatch bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PackageSearchOptions are options for SearchXXX methods
 | 
			
		||||
// Besides IsInternal are all fields optional and are not used if they have their default value (nil, "", 0)
 | 
			
		||||
type PackageSearchOptions struct {
 | 
			
		||||
	OwnerID      int64
 | 
			
		||||
	RepoID       int64
 | 
			
		||||
	Type         string
 | 
			
		||||
	PackageID    int64
 | 
			
		||||
	QueryName    string
 | 
			
		||||
	QueryVersion string
 | 
			
		||||
	Properties   map[string]string
 | 
			
		||||
	Sort         string
 | 
			
		||||
	OwnerID         int64
 | 
			
		||||
	RepoID          int64
 | 
			
		||||
	Type            Type
 | 
			
		||||
	PackageID       int64
 | 
			
		||||
	Name            SearchValue       // only results with the specific name are found
 | 
			
		||||
	Version         SearchValue       // only results with the specific version are found
 | 
			
		||||
	Properties      map[string]string // only results are found which contain all listed version properties with the specific value
 | 
			
		||||
	IsInternal      bool
 | 
			
		||||
	HasFileWithName string            // only results are found which are associated with a file with the specific name
 | 
			
		||||
	HasFiles        util.OptionalBool // only results are found which have associated files
 | 
			
		||||
	Sort            string
 | 
			
		||||
	db.Paginator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (opts *PackageSearchOptions) toConds() builder.Cond {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{"package_version.is_internal": false}
 | 
			
		||||
	var cond builder.Cond = builder.Eq{"package_version.is_internal": opts.IsInternal}
 | 
			
		||||
 | 
			
		||||
	if opts.OwnerID != 0 {
 | 
			
		||||
		cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID})
 | 
			
		||||
| 
						 | 
				
			
			@ -211,11 +193,19 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
 | 
			
		|||
	if opts.PackageID != 0 {
 | 
			
		||||
		cond = cond.And(builder.Eq{"package.id": opts.PackageID})
 | 
			
		||||
	}
 | 
			
		||||
	if opts.QueryName != "" {
 | 
			
		||||
		cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.QueryName)})
 | 
			
		||||
	if opts.Name.Value != "" {
 | 
			
		||||
		if opts.Name.ExactMatch {
 | 
			
		||||
			cond = cond.And(builder.Eq{"package.lower_name": strings.ToLower(opts.Name.Value)})
 | 
			
		||||
		} else {
 | 
			
		||||
			cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.Name.Value)})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if opts.QueryVersion != "" {
 | 
			
		||||
		cond = cond.And(builder.Like{"package_version.lower_version", strings.ToLower(opts.QueryVersion)})
 | 
			
		||||
	if opts.Version.Value != "" {
 | 
			
		||||
		if opts.Version.ExactMatch {
 | 
			
		||||
			cond = cond.And(builder.Eq{"package_version.lower_version": strings.ToLower(opts.Version.Value)})
 | 
			
		||||
		} else {
 | 
			
		||||
			cond = cond.And(builder.Like{"package_version.lower_version", strings.ToLower(opts.Version.Value)})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(opts.Properties) != 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -238,6 +228,22 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
 | 
			
		|||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if opts.HasFileWithName != "" {
 | 
			
		||||
		fileCond := builder.Expr("package_file.version_id = package_version.id").And(builder.Eq{"package_file.lower_name": strings.ToLower(opts.HasFileWithName)})
 | 
			
		||||
 | 
			
		||||
		cond = cond.And(builder.Exists(builder.Select("package_file.id").From("package_file").Where(fileCond)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !opts.HasFiles.IsNone() {
 | 
			
		||||
		var filesCond builder.Cond = builder.Exists(builder.Select("package_file.id").From("package_file").Where(builder.Expr("package_file.version_id = package_version.id")))
 | 
			
		||||
 | 
			
		||||
		if opts.HasFiles.IsFalse() {
 | 
			
		||||
			filesCond = builder.Not{filesCond}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cond = cond.And(filesCond)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cond
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -297,20 +303,3 @@ func SearchLatestVersions(ctx context.Context, opts *PackageSearchOptions) ([]*P
 | 
			
		|||
	count, err := sess.FindAndCount(&pvs)
 | 
			
		||||
	return pvs, count, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindVersionsByPropertyNameAndValue gets all package versions which are associated with a specific property + value
 | 
			
		||||
func FindVersionsByPropertyNameAndValue(ctx context.Context, packageID int64, name, value string) ([]*PackageVersion, error) {
 | 
			
		||||
	var cond builder.Cond = builder.Eq{
 | 
			
		||||
		"package_property.ref_type":   PropertyTypeVersion,
 | 
			
		||||
		"package_property.name":       name,
 | 
			
		||||
		"package_property.value":      value,
 | 
			
		||||
		"package_version.package_id":  packageID,
 | 
			
		||||
		"package_version.is_internal": false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pvs := make([]*PackageVersion, 0, 5)
 | 
			
		||||
	return pvs, db.GetEngine(ctx).
 | 
			
		||||
		Where(cond).
 | 
			
		||||
		Join("INNER", "package_property", "package_property.ref_id = package_version.id").
 | 
			
		||||
		Find(&pvs)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,8 +63,8 @@ func SearchPackages(ctx *context.Context) {
 | 
			
		|||
 | 
			
		||||
	opts := &packages_model.PackageSearchOptions{
 | 
			
		||||
		OwnerID:   ctx.Package.Owner.ID,
 | 
			
		||||
		Type:      string(packages_model.TypeComposer),
 | 
			
		||||
		QueryName: ctx.FormTrim("q"),
 | 
			
		||||
		Type:      packages_model.TypeComposer,
 | 
			
		||||
		Name:      packages_model.SearchValue{Value: ctx.FormTrim("q")},
 | 
			
		||||
		Paginator: &paginator,
 | 
			
		||||
	}
 | 
			
		||||
	if ctx.FormTrim("type") != "" {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,7 +256,12 @@ func setPackageTag(tag string, pv *packages_model.PackageVersion, deleteOnly boo
 | 
			
		|||
	}
 | 
			
		||||
	defer committer.Close()
 | 
			
		||||
 | 
			
		||||
	pvs, err := packages_model.FindVersionsByPropertyNameAndValue(ctx, pv.PackageID, npm_module.TagProperty, tag)
 | 
			
		||||
	pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		PackageID: pv.PackageID,
 | 
			
		||||
		Properties: map[string]string{
 | 
			
		||||
			npm_module.TagProperty: tag,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,9 +39,9 @@ func ServiceIndex(ctx *context.Context) {
 | 
			
		|||
// SearchService https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-for-packages
 | 
			
		||||
func SearchService(ctx *context.Context) {
 | 
			
		||||
	pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		OwnerID:   ctx.Package.Owner.ID,
 | 
			
		||||
		Type:      string(packages_model.TypeNuGet),
 | 
			
		||||
		QueryName: ctx.FormTrim("q"),
 | 
			
		||||
		OwnerID: ctx.Package.Owner.ID,
 | 
			
		||||
		Type:    packages_model.TypeNuGet,
 | 
			
		||||
		Name:    packages_model.SearchValue{Value: ctx.FormTrim("q")},
 | 
			
		||||
		Paginator: db.NewAbsoluteListOptions(
 | 
			
		||||
			ctx.FormInt("skip"),
 | 
			
		||||
			ctx.FormInt("take"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ func EnumeratePackages(ctx *context.Context) {
 | 
			
		|||
func EnumeratePackagesLatest(ctx *context.Context) {
 | 
			
		||||
	pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		OwnerID: ctx.Package.Owner.ID,
 | 
			
		||||
		Type:    string(packages_model.TypeRubyGems),
 | 
			
		||||
		Type:    packages_model.TypeRubyGems,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		apiError(ctx, http.StatusInternalServerError, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ func ServePackageSpecification(ctx *context.Context) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pvs, err := packages_model.GetVersionsByFilename(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, filename[:len(filename)-10]+"gem")
 | 
			
		||||
	pvs, err := getVersionsByFilename(ctx, filename[:len(filename)-10]+"gem")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		apiError(ctx, http.StatusInternalServerError, err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ func ServePackageSpecification(ctx *context.Context) {
 | 
			
		|||
func DownloadPackageFile(ctx *context.Context) {
 | 
			
		||||
	filename := ctx.Params("filename")
 | 
			
		||||
 | 
			
		||||
	pvs, err := packages_model.GetVersionsByFilename(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, filename)
 | 
			
		||||
	pvs, err := getVersionsByFilename(ctx, filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		apiError(ctx, http.StatusInternalServerError, err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -283,3 +283,12 @@ func DeletePackage(ctx *context.Context) {
 | 
			
		|||
		apiError(ctx, http.StatusInternalServerError, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getVersionsByFilename(ctx *context.Context, filename string) ([]*packages_model.PackageVersion, error) {
 | 
			
		||||
	pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		OwnerID:         ctx.Package.Owner.ID,
 | 
			
		||||
		Type:            packages_model.TypeRubyGems,
 | 
			
		||||
		HasFileWithName: filename,
 | 
			
		||||
	})
 | 
			
		||||
	return pvs, err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,8 +56,8 @@ func ListPackages(ctx *context.APIContext) {
 | 
			
		|||
 | 
			
		||||
	pvs, count, err := packages.SearchVersions(ctx, &packages.PackageSearchOptions{
 | 
			
		||||
		OwnerID:   ctx.Package.Owner.ID,
 | 
			
		||||
		Type:      packageType,
 | 
			
		||||
		QueryName: query,
 | 
			
		||||
		Type:      packages.Type(packageType),
 | 
			
		||||
		Name:      packages.SearchValue{Value: query},
 | 
			
		||||
		Paginator: &listOptions,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,9 +31,9 @@ func Packages(ctx *context.Context) {
 | 
			
		|||
	sort := ctx.FormTrim("sort")
 | 
			
		||||
 | 
			
		||||
	pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		QueryName: query,
 | 
			
		||||
		Type:      packageType,
 | 
			
		||||
		Sort:      sort,
 | 
			
		||||
		Type: packages_model.Type(packageType),
 | 
			
		||||
		Name: packages_model.SearchValue{Value: query},
 | 
			
		||||
		Sort: sort,
 | 
			
		||||
		Paginator: &db.ListOptions{
 | 
			
		||||
			PageSize: setting.UI.PackagesPagingNum,
 | 
			
		||||
			Page:     page,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,10 +32,10 @@ func Packages(ctx *context.Context) {
 | 
			
		|||
			PageSize: setting.UI.PackagesPagingNum,
 | 
			
		||||
			Page:     page,
 | 
			
		||||
		},
 | 
			
		||||
		OwnerID:   ctx.ContextUser.ID,
 | 
			
		||||
		RepoID:    ctx.Repo.Repository.ID,
 | 
			
		||||
		QueryName: query,
 | 
			
		||||
		Type:      packageType,
 | 
			
		||||
		OwnerID: ctx.ContextUser.ID,
 | 
			
		||||
		RepoID:  ctx.Repo.Repository.ID,
 | 
			
		||||
		Type:    packages.Type(packageType),
 | 
			
		||||
		Name:    packages.SearchValue{Value: query},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("SearchLatestVersions", err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,9 +43,9 @@ func ListPackages(ctx *context.Context) {
 | 
			
		|||
			PageSize: setting.UI.PackagesPagingNum,
 | 
			
		||||
			Page:     page,
 | 
			
		||||
		},
 | 
			
		||||
		OwnerID:   ctx.ContextUser.ID,
 | 
			
		||||
		Type:      packageType,
 | 
			
		||||
		QueryName: query,
 | 
			
		||||
		OwnerID: ctx.ContextUser.ID,
 | 
			
		||||
		Type:    packages_model.Type(packageType),
 | 
			
		||||
		Name:    packages_model.SearchValue{Value: query},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("SearchLatestVersions", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -219,9 +219,12 @@ func ListPackageVersions(ctx *context.Context) {
 | 
			
		|||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
			Paginator:    pagination,
 | 
			
		||||
			PackageID:    p.ID,
 | 
			
		||||
			QueryVersion: query,
 | 
			
		||||
			Paginator: pagination,
 | 
			
		||||
			PackageID: p.ID,
 | 
			
		||||
			Version: packages_model.SearchValue{
 | 
			
		||||
				ExactMatch: false,
 | 
			
		||||
				Value:      query,
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.ServerError("SearchVersions", err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	packages_model "code.gitea.io/gitea/models/packages"
 | 
			
		||||
	container_model "code.gitea.io/gitea/models/packages/container"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Cleanup removes expired container data
 | 
			
		||||
| 
						 | 
				
			
			@ -43,10 +44,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	versions := make(map[int64]struct{})
 | 
			
		||||
	for _, pf := range pfs {
 | 
			
		||||
		versions[pf.VersionID] = struct{}{}
 | 
			
		||||
 | 
			
		||||
		if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -55,19 +53,26 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for versionID := range versions {
 | 
			
		||||
		has, err := packages_model.HasVersionFileReferences(ctx, versionID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
	pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
 | 
			
		||||
		Type: packages_model.TypeContainer,
 | 
			
		||||
		Version: packages_model.SearchValue{
 | 
			
		||||
			ExactMatch: true,
 | 
			
		||||
			Value:      container_model.UploadVersion,
 | 
			
		||||
		},
 | 
			
		||||
		IsInternal: true,
 | 
			
		||||
		HasFiles:   util.OptionalBoolFalse,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, pv := range pvs {
 | 
			
		||||
		if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, pv.ID); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if !has {
 | 
			
		||||
			if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, versionID); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err := packages_model.DeleteVersionByID(ctx, versionID); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		if err := packages_model.DeleteVersionByID(ctx, pv.ID); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,7 +336,7 @@ func DeletePackageFile(ctx context.Context, pf *packages_model.PackageFile) erro
 | 
			
		|||
	return packages_model.DeleteFileByID(ctx, pf.ID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cleanup removes old unreferenced package blobs
 | 
			
		||||
// Cleanup removes expired package data
 | 
			
		||||
func Cleanup(unused context.Context, olderThan time.Duration) error {
 | 
			
		||||
	ctx, committer, err := db.TxContext()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -345,24 +345,20 @@ func Cleanup(unused context.Context, olderThan time.Duration) error {
 | 
			
		|||
	defer committer.Close()
 | 
			
		||||
 | 
			
		||||
	if err := container_service.Cleanup(ctx, olderThan); err != nil {
 | 
			
		||||
		log.Error("hier")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := packages_model.DeletePackagesIfUnreferenced(ctx); err != nil {
 | 
			
		||||
		log.Error("hier2")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("hier3")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, pb := range pbs {
 | 
			
		||||
		if err := packages_model.DeleteBlobByID(ctx, pb.ID); err != nil {
 | 
			
		||||
			log.Error("hier4")
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -403,10 +399,9 @@ func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_mod
 | 
			
		|||
 | 
			
		||||
	pv, err := packages_model.GetVersionByID(ctx, versionID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if err == packages_model.ErrPackageVersionNotExist {
 | 
			
		||||
			return nil, nil, packages_model.ErrPackageNotExist
 | 
			
		||||
		if err != packages_model.ErrPackageNotExist {
 | 
			
		||||
			log.Error("Error getting package version: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		log.Error("Error getting package version: %v", err)
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue