mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
Fixes https://github.com/go-gitea/gitea/issues/35728 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
103 lines
3.0 KiB
Go
103 lines
3.0 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package cran
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gitea.dev/models/db"
|
|
"gitea.dev/models/packages"
|
|
cran_module "gitea.dev/modules/packages/cran"
|
|
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
type SearchOptions struct {
|
|
OwnerID int64
|
|
FileType string
|
|
Platform string
|
|
RVersion string
|
|
Filename string
|
|
}
|
|
|
|
func (opts *SearchOptions) toConds() builder.Cond {
|
|
var cond builder.Cond = builder.Eq{
|
|
"package.type": packages.TypeCran,
|
|
"package.owner_id": opts.OwnerID,
|
|
"package_version.is_internal": false,
|
|
}
|
|
|
|
if opts.Filename != "" {
|
|
cond = cond.And(builder.Eq{"package_file.lower_name": strings.ToLower(opts.Filename)})
|
|
}
|
|
|
|
var propsCond builder.Cond = builder.Eq{
|
|
"package_property.ref_type": packages.PropertyTypeFile,
|
|
}
|
|
propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id"))
|
|
|
|
count := 1
|
|
propsCondBlock := builder.Eq{"package_property.name": cran_module.PropertyType}.And(builder.Eq{"package_property.value": opts.FileType})
|
|
|
|
if opts.Platform != "" {
|
|
count += 2
|
|
propsCondBlock = propsCondBlock.
|
|
Or(builder.Eq{"package_property.name": cran_module.PropertyPlatform}.And(builder.Eq{"package_property.value": opts.Platform})).
|
|
Or(builder.Eq{"package_property.name": cran_module.PropertyRVersion}.And(builder.Eq{"package_property.value": opts.RVersion}))
|
|
}
|
|
|
|
propsCond = propsCond.And(propsCondBlock)
|
|
|
|
cond = cond.And(builder.Eq{
|
|
strconv.Itoa(count): builder.Select("COUNT(*)").Where(propsCond).From("package_property"),
|
|
})
|
|
|
|
return cond
|
|
}
|
|
|
|
func SearchLatestVersions(ctx context.Context, opts *SearchOptions) (latest []*packages.PackageVersion, err error) {
|
|
var allPkgVers []*packages.PackageVersion
|
|
err = db.GetEngine(ctx).
|
|
Table("package_version").
|
|
Select("package_version.*").
|
|
Join("INNER", "package", "package.id = package_version.package_id").
|
|
Join("INNER", "package_file", "package_file.version_id = package_version.id").
|
|
Where(opts.toConds()).
|
|
Asc("package.name", "package.id").
|
|
Find(&allPkgVers)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// SQL can't order R version strings, so pick the highest version per package here
|
|
for _, pv := range allPkgVers {
|
|
curIdx := len(latest) - 1
|
|
if curIdx == -1 || latest[curIdx].PackageID != pv.PackageID {
|
|
latest = append(latest, pv) // start a new package version
|
|
} else if cran_module.CompareVersions(pv.Version, latest[curIdx].Version) > 0 {
|
|
latest[curIdx] = pv // replace with a higher version
|
|
}
|
|
}
|
|
return latest, nil
|
|
}
|
|
|
|
func SearchFile(ctx context.Context, opts *SearchOptions) (*packages.PackageFile, error) {
|
|
sess := db.GetEngine(ctx).
|
|
Table("package_version").
|
|
Select("package_file.*").
|
|
Join("INNER", "package", "package.id = package_version.package_id").
|
|
Join("INNER", "package_file", "package_file.version_id = package_version.id").
|
|
Where(opts.toConds())
|
|
|
|
pf := &packages.PackageFile{}
|
|
if has, err := sess.Get(pf); err != nil {
|
|
return nil, err
|
|
} else if !has {
|
|
return nil, packages.ErrPackageFileNotExist
|
|
}
|
|
return pf, nil
|
|
}
|