code.gitea.io/gitea@v1.22.3/models/packages/cran/search.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package cran 5 6 import ( 7 "context" 8 "strconv" 9 "strings" 10 11 "code.gitea.io/gitea/models/db" 12 "code.gitea.io/gitea/models/packages" 13 cran_module "code.gitea.io/gitea/modules/packages/cran" 14 15 "xorm.io/builder" 16 ) 17 18 type SearchOptions struct { 19 OwnerID int64 20 FileType string 21 Platform string 22 RVersion string 23 Filename string 24 } 25 26 func (opts *SearchOptions) toConds() builder.Cond { 27 var cond builder.Cond = builder.Eq{ 28 "package.type": packages.TypeCran, 29 "package.owner_id": opts.OwnerID, 30 "package_version.is_internal": false, 31 } 32 33 if opts.Filename != "" { 34 cond = cond.And(builder.Eq{"package_file.lower_name": strings.ToLower(opts.Filename)}) 35 } 36 37 var propsCond builder.Cond = builder.Eq{ 38 "package_property.ref_type": packages.PropertyTypeFile, 39 } 40 propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id")) 41 42 count := 1 43 propsCondBlock := builder.Eq{"package_property.name": cran_module.PropertyType}.And(builder.Eq{"package_property.value": opts.FileType}) 44 45 if opts.Platform != "" { 46 count += 2 47 propsCondBlock = propsCondBlock. 48 Or(builder.Eq{"package_property.name": cran_module.PropertyPlatform}.And(builder.Eq{"package_property.value": opts.Platform})). 49 Or(builder.Eq{"package_property.name": cran_module.PropertyRVersion}.And(builder.Eq{"package_property.value": opts.RVersion})) 50 } 51 52 propsCond = propsCond.And(propsCondBlock) 53 54 cond = cond.And(builder.Eq{ 55 strconv.Itoa(count): builder.Select("COUNT(*)").Where(propsCond).From("package_property"), 56 }) 57 58 return cond 59 } 60 61 func SearchLatestVersions(ctx context.Context, opts *SearchOptions) ([]*packages.PackageVersion, error) { 62 sess := db.GetEngine(ctx). 63 Table("package_version"). 64 Select("package_version.*"). 65 Join("LEFT", "package_version pv2", builder.Expr("package_version.package_id = pv2.package_id AND pv2.is_internal = ? AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))", false)). 66 Join("INNER", "package", "package.id = package_version.package_id"). 67 Join("INNER", "package_file", "package_file.version_id = package_version.id"). 68 Where(opts.toConds().And(builder.Expr("pv2.id IS NULL"))). 69 Asc("package.name") 70 71 pvs := make([]*packages.PackageVersion, 0, 10) 72 return pvs, sess.Find(&pvs) 73 } 74 75 func SearchFile(ctx context.Context, opts *SearchOptions) (*packages.PackageFile, error) { 76 sess := db.GetEngine(ctx). 77 Table("package_version"). 78 Select("package_file.*"). 79 Join("INNER", "package", "package.id = package_version.package_id"). 80 Join("INNER", "package_file", "package_file.version_id = package_version.id"). 81 Where(opts.toConds()) 82 83 pf := &packages.PackageFile{} 84 if has, err := sess.Get(pf); err != nil { 85 return nil, err 86 } else if !has { 87 return nil, packages.ErrPackageFileNotExist 88 } 89 return pf, nil 90 }