// Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package debian import ( "context" "strconv" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" debian_module "code.gitea.io/gitea/modules/packages/debian" "xorm.io/builder" ) type PackageSearchOptions struct { OwnerID int64 Distribution string Component string Architecture string } // SearchLatestPackages gets the latest packages matching the search options func SearchLatestPackages(ctx context.Context, opts *PackageSearchOptions) ([]*packages.PackageFileDescriptor, error) { var cond builder.Cond = builder.Eq{ "package_file.is_lead": true, "package.type": packages.TypeDebian, "package.owner_id": opts.OwnerID, "package.is_internal": false, "package_version.is_internal": false, } props := make(map[string]string) if opts.Distribution != "" { props[debian_module.PropertyDistribution] = opts.Distribution } if opts.Component != "" { props[debian_module.PropertyComponent] = opts.Component } if opts.Architecture != "" { props[debian_module.PropertyArchitecture] = opts.Architecture } if len(props) > 0 { var propsCond builder.Cond = builder.Eq{ "package_property.ref_type": packages.PropertyTypeFile, } propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id")) propsCondBlock := builder.NewCond() for name, value := range props { propsCondBlock = propsCondBlock.Or(builder.Eq{ "package_property.name": name, "package_property.value": value, }) } propsCond = propsCond.And(propsCondBlock) cond = cond.And(builder.Eq{ strconv.Itoa(len(props)): builder.Select("COUNT(*)").Where(propsCond).From("package_property"), }) } cond = cond. And(builder.Expr("pv2.id IS NULL")) joinCond := builder. Expr("package_version.package_id = pv2.package_id AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))"). And(builder.Eq{"pv2.is_internal": false}) pfs := make([]*packages.PackageFile, 0, 10) err := db.GetEngine(ctx). Table("package_file"). Select("package_file.*"). Join("INNER", "package_version", "package_version.id = package_file.version_id"). Join("LEFT", "package_version pv2", joinCond). Join("INNER", "package", "package.id = package_version.package_id"). Where(cond). Desc("package_version.created_unix"). Find(&pfs) if err != nil { return nil, err } return packages.GetPackageFileDescriptors(ctx, pfs) } // GetDistributions gets all available distributions func GetDistributions(ctx context.Context, ownerID int64) ([]string, error) { return packages.GetDistinctPropertyValues( ctx, packages.TypeDebian, ownerID, packages.PropertyTypeFile, debian_module.PropertyDistribution, nil, ) } // GetComponents gets all available components for the given distribution func GetComponents(ctx context.Context, ownerID int64, distribution string) ([]string, error) { return packages.GetDistinctPropertyValues( ctx, packages.TypeDebian, ownerID, packages.PropertyTypeFile, debian_module.PropertyComponent, &packages.DistinctPropertyDependency{ Name: debian_module.PropertyDistribution, Value: distribution, }, ) } // GetArchitectures gets all available architectures for the given distribution func GetArchitectures(ctx context.Context, ownerID int64, distribution string) ([]string, error) { return packages.GetDistinctPropertyValues( ctx, packages.TypeDebian, ownerID, packages.PropertyTypeFile, debian_module.PropertyArchitecture, &packages.DistinctPropertyDependency{ Name: debian_module.PropertyDistribution, Value: distribution, }, ) }