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  }