You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

search.go 2.9KB

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