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"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"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"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
packages_service "code.gitea.io/gitea/services/packages"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -43,7 +47,7 @@ func TestPackageAPI(t *testing.T) {
|
||||||
DecodeJSON(t, resp, &apiPackages)
|
DecodeJSON(t, resp, &apiPackages)
|
||||||
|
|
||||||
assert.Len(t, apiPackages, 1)
|
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, packageName, apiPackages[0].Name)
|
||||||
assert.Equal(t, packageVersion, apiPackages[0].Version)
|
assert.Equal(t, packageVersion, apiPackages[0].Version)
|
||||||
assert.NotNil(t, apiPackages[0].Creator)
|
assert.NotNil(t, apiPackages[0].Creator)
|
||||||
|
@ -62,7 +66,7 @@ func TestPackageAPI(t *testing.T) {
|
||||||
var p *api.Package
|
var p *api.Package
|
||||||
DecodeJSON(t, resp, &p)
|
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, packageName, p.Name)
|
||||||
assert.Equal(t, packageVersion, p.Version)
|
assert.Equal(t, packageVersion, p.Version)
|
||||||
assert.NotNil(t, p.Creator)
|
assert.NotNil(t, p.Creator)
|
||||||
|
@ -100,3 +104,26 @@ func TestPackageAPI(t *testing.T) {
|
||||||
MakeRequest(t, req, http.StatusNoContent)
|
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.
|
in2 := builder.
|
||||||
Select("package_file.id").
|
Select("package_file.id").
|
||||||
From("package_file").
|
From("package_file").
|
||||||
Join("INNER", "package_version", "package_version.id = package_file.version_id").
|
InnerJoin("package_version", "package_version.id = package_file.version_id").
|
||||||
Join("INNER", "package", "package.id = package_version.package_id").
|
InnerJoin("package", "package.id = package_version.package_id").
|
||||||
Where(cond)
|
Where(cond)
|
||||||
|
|
||||||
query := builder.
|
query := builder.
|
||||||
Select("package_property.value, MAX(package_file.created_unix) AS created_unix").
|
Select("package_property.value, MAX(package_file.created_unix) AS created_unix").
|
||||||
From("package_property").
|
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))).
|
Where(builder.Eq{"package_property.name": propertyName}.And(builder.In("package_property.ref_id", in2))).
|
||||||
GroupBy("package_property.value").
|
GroupBy("package_property.value").
|
||||||
OrderBy("created_unix DESC")
|
OrderBy("created_unix DESC")
|
||||||
|
|
|
@ -74,8 +74,8 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
|
||||||
query := builder.
|
query := builder.
|
||||||
Select("package.name, package_version.version, package_file.id").
|
Select("package.name, package_version.version, package_file.id").
|
||||||
From("package_file").
|
From("package_file").
|
||||||
Join("INNER", "package_version", "package_version.id = package_file.version_id").
|
InnerJoin("package_version", "package_version.id = package_file.version_id").
|
||||||
Join("INNER", "package", "package.id = package_version.package_id").
|
InnerJoin("package", "package.id = package_version.package_id").
|
||||||
Where(cond)
|
Where(cond)
|
||||||
|
|
||||||
results := make([]struct {
|
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
|
// DeletePackagesIfUnreferenced deletes a package if there are no associated versions
|
||||||
func DeletePackagesIfUnreferenced(ctx context.Context) error {
|
func DeletePackagesIfUnreferenced(ctx context.Context) error {
|
||||||
in := builder.
|
in := builder.
|
||||||
Select("package_version.package_id").
|
Select("package.id").
|
||||||
From("package").
|
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"))
|
Where(builder.Expr("package_version.id IS NULL"))
|
||||||
|
|
||||||
_, err := db.GetEngine(ctx).
|
_, 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{})
|
Delete(&Package{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -67,7 +67,7 @@ func FindExpiredUnreferencedBlobs(ctx context.Context, olderThan time.Duration)
|
||||||
pbs := make([]*PackageBlob, 0, 10)
|
pbs := make([]*PackageBlob, 0, 10)
|
||||||
return pbs, db.GetEngine(ctx).
|
return pbs, db.GetEngine(ctx).
|
||||||
Table("package_blob").
|
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()).
|
Where("package_file.id IS NULL AND package_blob.created_unix < ?", time.Now().Add(-olderThan).Unix()).
|
||||||
Find(&pbs)
|
Find(&pbs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ func (opts *PackageFileSearchOptions) toConds() builder.Cond {
|
||||||
in := builder.
|
in := builder.
|
||||||
Select("package_version.id").
|
Select("package_version.id").
|
||||||
From("package_version").
|
From("package_version").
|
||||||
Join("INNER", "package", "package.id = package_version.package_id").
|
InnerJoin("package", "package.id = package_version.package_id").
|
||||||
Where(versionCond)
|
Where(versionCond)
|
||||||
|
|
||||||
cond = cond.And(builder.In("package_file.version_id", in))
|
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/models/db"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// ErrDuplicatePackageVersion indicates a duplicated package version error
|
||||||
// ErrDuplicatePackageVersion indicates a duplicated package version error
|
var ErrDuplicatePackageVersion = errors.New("Package version already exists")
|
||||||
ErrDuplicatePackageVersion = errors.New("Package version does exist already")
|
|
||||||
// ErrPackageVersionNotExist indicates a package version not exist error
|
|
||||||
ErrPackageVersionNotExist = errors.New("Package version does not exist")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
db.RegisterModel(new(PackageVersion))
|
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) {
|
func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType Type, name, version string, isInternal bool) (*PackageVersion, error) {
|
||||||
var cond builder.Cond = builder.Eq{
|
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
|
||||||
"package.owner_id": ownerID,
|
OwnerID: ownerID,
|
||||||
"package.type": packageType,
|
Type: packageType,
|
||||||
"package.lower_name": strings.ToLower(name),
|
Name: SearchValue{
|
||||||
"package_version.is_internal": isInternal,
|
ExactMatch: true,
|
||||||
}
|
Value: name,
|
||||||
pv := &PackageVersion{
|
},
|
||||||
LowerVersion: strings.ToLower(version),
|
Version: SearchValue{
|
||||||
}
|
ExactMatch: true,
|
||||||
has, err := db.GetEngine(ctx).
|
Value: version,
|
||||||
Join("INNER", "package", "package.id = package_version.package_id").
|
},
|
||||||
Where(cond).
|
IsInternal: isInternal,
|
||||||
Get(pv)
|
Paginator: db.NewAbsoluteListOptions(0, 1),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !has {
|
if len(pvs) == 0 {
|
||||||
return nil, ErrPackageNotExist
|
return nil, ErrPackageNotExist
|
||||||
}
|
}
|
||||||
|
return pvs[0], nil
|
||||||
return pv, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersionsByPackageType gets all versions of a specific type
|
// GetVersionsByPackageType gets all versions of a specific type
|
||||||
func GetVersionsByPackageType(ctx context.Context, ownerID int64, packageType Type) ([]*PackageVersion, error) {
|
func GetVersionsByPackageType(ctx context.Context, ownerID int64, packageType Type) ([]*PackageVersion, error) {
|
||||||
var cond builder.Cond = builder.Eq{
|
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
|
||||||
"package.owner_id": ownerID,
|
OwnerID: ownerID,
|
||||||
"package.type": packageType,
|
Type: packageType,
|
||||||
"package_version.is_internal": false,
|
})
|
||||||
}
|
return pvs, err
|
||||||
|
|
||||||
pvs := make([]*PackageVersion, 0, 10)
|
|
||||||
return pvs, db.GetEngine(ctx).
|
|
||||||
Where(cond).
|
|
||||||
Join("INNER", "package", "package.id = package_version.package_id").
|
|
||||||
Find(&pvs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersionsByPackageName gets all versions of a specific package
|
// GetVersionsByPackageName gets all versions of a specific package
|
||||||
func GetVersionsByPackageName(ctx context.Context, ownerID int64, packageType Type, name string) ([]*PackageVersion, error) {
|
func GetVersionsByPackageName(ctx context.Context, ownerID int64, packageType Type, name string) ([]*PackageVersion, error) {
|
||||||
var cond builder.Cond = builder.Eq{
|
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
|
||||||
"package.owner_id": ownerID,
|
OwnerID: ownerID,
|
||||||
"package.type": packageType,
|
Type: packageType,
|
||||||
"package.lower_name": strings.ToLower(name),
|
Name: SearchValue{
|
||||||
"package_version.is_internal": false,
|
ExactMatch: true,
|
||||||
}
|
Value: name,
|
||||||
|
},
|
||||||
pvs := make([]*PackageVersion, 0, 10)
|
})
|
||||||
return pvs, db.GetEngine(ctx).
|
return pvs, err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteVersionByID deletes a version by id
|
// 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
|
// 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 {
|
type PackageSearchOptions struct {
|
||||||
OwnerID int64
|
OwnerID int64
|
||||||
RepoID int64
|
RepoID int64
|
||||||
Type string
|
Type Type
|
||||||
PackageID int64
|
PackageID int64
|
||||||
QueryName string
|
Name SearchValue // only results with the specific name are found
|
||||||
QueryVersion string
|
Version SearchValue // only results with the specific version are found
|
||||||
Properties map[string]string
|
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
|
Sort string
|
||||||
db.Paginator
|
db.Paginator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *PackageSearchOptions) toConds() builder.Cond {
|
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 {
|
if opts.OwnerID != 0 {
|
||||||
cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID})
|
cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID})
|
||||||
|
@ -211,11 +193,19 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
|
||||||
if opts.PackageID != 0 {
|
if opts.PackageID != 0 {
|
||||||
cond = cond.And(builder.Eq{"package.id": opts.PackageID})
|
cond = cond.And(builder.Eq{"package.id": opts.PackageID})
|
||||||
}
|
}
|
||||||
if opts.QueryName != "" {
|
if opts.Name.Value != "" {
|
||||||
cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.QueryName)})
|
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.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 opts.QueryVersion != "" {
|
|
||||||
cond = cond.And(builder.Like{"package_version.lower_version", strings.ToLower(opts.QueryVersion)})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Properties) != 0 {
|
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
|
return cond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,20 +303,3 @@ func SearchLatestVersions(ctx context.Context, opts *PackageSearchOptions) ([]*P
|
||||||
count, err := sess.FindAndCount(&pvs)
|
count, err := sess.FindAndCount(&pvs)
|
||||||
return pvs, count, err
|
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{
|
opts := &packages_model.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
Type: string(packages_model.TypeComposer),
|
Type: packages_model.TypeComposer,
|
||||||
QueryName: ctx.FormTrim("q"),
|
Name: packages_model.SearchValue{Value: ctx.FormTrim("q")},
|
||||||
Paginator: &paginator,
|
Paginator: &paginator,
|
||||||
}
|
}
|
||||||
if ctx.FormTrim("type") != "" {
|
if ctx.FormTrim("type") != "" {
|
||||||
|
|
|
@ -256,7 +256,12 @@ func setPackageTag(tag string, pv *packages_model.PackageVersion, deleteOnly boo
|
||||||
}
|
}
|
||||||
defer committer.Close()
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ func ServiceIndex(ctx *context.Context) {
|
||||||
func SearchService(ctx *context.Context) {
|
func SearchService(ctx *context.Context) {
|
||||||
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
Type: string(packages_model.TypeNuGet),
|
Type: packages_model.TypeNuGet,
|
||||||
QueryName: ctx.FormTrim("q"),
|
Name: packages_model.SearchValue{Value: ctx.FormTrim("q")},
|
||||||
Paginator: db.NewAbsoluteListOptions(
|
Paginator: db.NewAbsoluteListOptions(
|
||||||
ctx.FormInt("skip"),
|
ctx.FormInt("skip"),
|
||||||
ctx.FormInt("take"),
|
ctx.FormInt("take"),
|
||||||
|
|
|
@ -41,7 +41,7 @@ func EnumeratePackages(ctx *context.Context) {
|
||||||
func EnumeratePackagesLatest(ctx *context.Context) {
|
func EnumeratePackagesLatest(ctx *context.Context) {
|
||||||
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
Type: string(packages_model.TypeRubyGems),
|
Type: packages_model.TypeRubyGems,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiError(ctx, http.StatusInternalServerError, err)
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
|
@ -96,7 +96,7 @@ func ServePackageSpecification(ctx *context.Context) {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
apiError(ctx, http.StatusInternalServerError, err)
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
|
@ -158,7 +158,7 @@ func ServePackageSpecification(ctx *context.Context) {
|
||||||
func DownloadPackageFile(ctx *context.Context) {
|
func DownloadPackageFile(ctx *context.Context) {
|
||||||
filename := ctx.Params("filename")
|
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 {
|
if err != nil {
|
||||||
apiError(ctx, http.StatusInternalServerError, err)
|
apiError(ctx, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
|
@ -283,3 +283,12 @@ func DeletePackage(ctx *context.Context) {
|
||||||
apiError(ctx, http.StatusInternalServerError, err)
|
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{
|
pvs, count, err := packages.SearchVersions(ctx, &packages.PackageSearchOptions{
|
||||||
OwnerID: ctx.Package.Owner.ID,
|
OwnerID: ctx.Package.Owner.ID,
|
||||||
Type: packageType,
|
Type: packages.Type(packageType),
|
||||||
QueryName: query,
|
Name: packages.SearchValue{Value: query},
|
||||||
Paginator: &listOptions,
|
Paginator: &listOptions,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -31,8 +31,8 @@ func Packages(ctx *context.Context) {
|
||||||
sort := ctx.FormTrim("sort")
|
sort := ctx.FormTrim("sort")
|
||||||
|
|
||||||
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
QueryName: query,
|
Type: packages_model.Type(packageType),
|
||||||
Type: packageType,
|
Name: packages_model.SearchValue{Value: query},
|
||||||
Sort: sort,
|
Sort: sort,
|
||||||
Paginator: &db.ListOptions{
|
Paginator: &db.ListOptions{
|
||||||
PageSize: setting.UI.PackagesPagingNum,
|
PageSize: setting.UI.PackagesPagingNum,
|
||||||
|
|
|
@ -34,8 +34,8 @@ func Packages(ctx *context.Context) {
|
||||||
},
|
},
|
||||||
OwnerID: ctx.ContextUser.ID,
|
OwnerID: ctx.ContextUser.ID,
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
QueryName: query,
|
Type: packages.Type(packageType),
|
||||||
Type: packageType,
|
Name: packages.SearchValue{Value: query},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("SearchLatestVersions", err)
|
ctx.ServerError("SearchLatestVersions", err)
|
||||||
|
|
|
@ -44,8 +44,8 @@ func ListPackages(ctx *context.Context) {
|
||||||
Page: page,
|
Page: page,
|
||||||
},
|
},
|
||||||
OwnerID: ctx.ContextUser.ID,
|
OwnerID: ctx.ContextUser.ID,
|
||||||
Type: packageType,
|
Type: packages_model.Type(packageType),
|
||||||
QueryName: query,
|
Name: packages_model.SearchValue{Value: query},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("SearchLatestVersions", err)
|
ctx.ServerError("SearchLatestVersions", err)
|
||||||
|
@ -221,7 +221,10 @@ func ListPackageVersions(ctx *context.Context) {
|
||||||
pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
Paginator: pagination,
|
Paginator: pagination,
|
||||||
PackageID: p.ID,
|
PackageID: p.ID,
|
||||||
QueryVersion: query,
|
Version: packages_model.SearchValue{
|
||||||
|
ExactMatch: false,
|
||||||
|
Value: query,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("SearchVersions", err)
|
ctx.ServerError("SearchVersions", err)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
packages_model "code.gitea.io/gitea/models/packages"
|
packages_model "code.gitea.io/gitea/models/packages"
|
||||||
container_model "code.gitea.io/gitea/models/packages/container"
|
container_model "code.gitea.io/gitea/models/packages/container"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cleanup removes expired container data
|
// Cleanup removes expired container data
|
||||||
|
@ -43,10 +44,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
versions := make(map[int64]struct{})
|
|
||||||
for _, pf := range pfs {
|
for _, pf := range pfs {
|
||||||
versions[pf.VersionID] = struct{}{}
|
|
||||||
|
|
||||||
if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil {
|
if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -55,21 +53,28 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for versionID := range versions {
|
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||||
has, err := packages_model.HasVersionFileReferences(ctx, versionID)
|
Type: packages_model.TypeContainer,
|
||||||
|
Version: packages_model.SearchValue{
|
||||||
|
ExactMatch: true,
|
||||||
|
Value: container_model.UploadVersion,
|
||||||
|
},
|
||||||
|
IsInternal: true,
|
||||||
|
HasFiles: util.OptionalBoolFalse,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !has {
|
|
||||||
if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, versionID); err != nil {
|
for _, pv := range pvs {
|
||||||
|
if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeVersion, pv.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := packages_model.DeleteVersionByID(ctx, versionID); err != nil {
|
if err := packages_model.DeleteVersionByID(ctx, pv.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,7 +336,7 @@ func DeletePackageFile(ctx context.Context, pf *packages_model.PackageFile) erro
|
||||||
return packages_model.DeleteFileByID(ctx, pf.ID)
|
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 {
|
func Cleanup(unused context.Context, olderThan time.Duration) error {
|
||||||
ctx, committer, err := db.TxContext()
|
ctx, committer, err := db.TxContext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -345,24 +345,20 @@ func Cleanup(unused context.Context, olderThan time.Duration) error {
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if err := container_service.Cleanup(ctx, olderThan); err != nil {
|
if err := container_service.Cleanup(ctx, olderThan); err != nil {
|
||||||
log.Error("hier")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := packages_model.DeletePackagesIfUnreferenced(ctx); err != nil {
|
if err := packages_model.DeletePackagesIfUnreferenced(ctx); err != nil {
|
||||||
log.Error("hier2")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
|
pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("hier3")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pb := range pbs {
|
for _, pb := range pbs {
|
||||||
if err := packages_model.DeleteBlobByID(ctx, pb.ID); err != nil {
|
if err := packages_model.DeleteBlobByID(ctx, pb.ID); err != nil {
|
||||||
log.Error("hier4")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,10 +399,9 @@ func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_mod
|
||||||
|
|
||||||
pv, err := packages_model.GetVersionByID(ctx, versionID)
|
pv, err := packages_model.GetVersionByID(ctx, versionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == packages_model.ErrPackageVersionNotExist {
|
if err != packages_model.ErrPackageNotExist {
|
||||||
return nil, nil, packages_model.ErrPackageNotExist
|
|
||||||
}
|
|
||||||
log.Error("Error getting package version: %v", err)
|
log.Error("Error getting package version: %v", err)
|
||||||
|
}
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue