gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package conan
  4. import (
  5. "context"
  6. "strconv"
  7. "strings"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/packages"
  10. conan_module "code.gitea.io/gitea/modules/packages/conan"
  11. "code.gitea.io/gitea/modules/timeutil"
  12. "code.gitea.io/gitea/modules/util"
  13. "xorm.io/builder"
  14. )
  15. var (
  16. ErrRecipeReferenceNotExist = util.NewNotExistErrorf("recipe reference does not exist")
  17. ErrPackageReferenceNotExist = util.NewNotExistErrorf("package reference does not exist")
  18. )
  19. // RecipeExists checks if a recipe exists
  20. func RecipeExists(ctx context.Context, ownerID int64, ref *conan_module.RecipeReference) (bool, error) {
  21. revisions, err := GetRecipeRevisions(ctx, ownerID, ref)
  22. if err != nil {
  23. return false, err
  24. }
  25. return len(revisions) != 0, nil
  26. }
  27. type PropertyValue struct {
  28. Value string
  29. CreatedUnix timeutil.TimeStamp
  30. }
  31. func findPropertyValues(ctx context.Context, propertyName string, ownerID int64, name, version string, propertyFilter map[string]string) ([]*PropertyValue, error) {
  32. var propsCond builder.Cond = builder.Eq{
  33. "package_property.ref_type": packages.PropertyTypeFile,
  34. }
  35. propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id"))
  36. propsCondBlock := builder.NewCond()
  37. for name, value := range propertyFilter {
  38. propsCondBlock = propsCondBlock.Or(builder.Eq{
  39. "package_property.name": name,
  40. "package_property.value": value,
  41. })
  42. }
  43. propsCond = propsCond.And(propsCondBlock)
  44. var cond builder.Cond = builder.Eq{
  45. "package.type": packages.TypeConan,
  46. "package.owner_id": ownerID,
  47. "package.lower_name": strings.ToLower(name),
  48. "package_version.lower_version": strings.ToLower(version),
  49. "package_version.is_internal": false,
  50. strconv.Itoa(len(propertyFilter)): builder.Select("COUNT(*)").Where(propsCond).From("package_property"),
  51. }
  52. in2 := builder.
  53. Select("package_file.id").
  54. From("package_file").
  55. InnerJoin("package_version", "package_version.id = package_file.version_id").
  56. InnerJoin("package", "package.id = package_version.package_id").
  57. Where(cond)
  58. query := builder.
  59. Select("package_property.value, MAX(package_file.created_unix) AS created_unix").
  60. From("package_property").
  61. InnerJoin("package_file", "package_file.id = package_property.ref_id").
  62. Where(builder.Eq{"package_property.name": propertyName}.And(builder.In("package_property.ref_id", in2))).
  63. GroupBy("package_property.value").
  64. OrderBy("created_unix DESC")
  65. var values []*PropertyValue
  66. return values, db.GetEngine(ctx).SQL(query).Find(&values)
  67. }
  68. // GetRecipeRevisions gets all revisions of a recipe
  69. func GetRecipeRevisions(ctx context.Context, ownerID int64, ref *conan_module.RecipeReference) ([]*PropertyValue, error) {
  70. values, err := findPropertyValues(
  71. ctx,
  72. conan_module.PropertyRecipeRevision,
  73. ownerID,
  74. ref.Name,
  75. ref.Version,
  76. map[string]string{
  77. conan_module.PropertyRecipeUser: ref.User,
  78. conan_module.PropertyRecipeChannel: ref.Channel,
  79. },
  80. )
  81. if err != nil {
  82. return nil, err
  83. }
  84. return values, nil
  85. }
  86. // GetLastRecipeRevision gets the latest recipe revision
  87. func GetLastRecipeRevision(ctx context.Context, ownerID int64, ref *conan_module.RecipeReference) (*PropertyValue, error) {
  88. revisions, err := GetRecipeRevisions(ctx, ownerID, ref)
  89. if err != nil {
  90. return nil, err
  91. }
  92. if len(revisions) == 0 {
  93. return nil, ErrRecipeReferenceNotExist
  94. }
  95. return revisions[0], nil
  96. }
  97. // GetPackageReferences gets all package references of a recipe
  98. func GetPackageReferences(ctx context.Context, ownerID int64, ref *conan_module.RecipeReference) ([]*PropertyValue, error) {
  99. values, err := findPropertyValues(
  100. ctx,
  101. conan_module.PropertyPackageReference,
  102. ownerID,
  103. ref.Name,
  104. ref.Version,
  105. map[string]string{
  106. conan_module.PropertyRecipeUser: ref.User,
  107. conan_module.PropertyRecipeChannel: ref.Channel,
  108. conan_module.PropertyRecipeRevision: ref.Revision,
  109. },
  110. )
  111. if err != nil {
  112. return nil, err
  113. }
  114. return values, nil
  115. }
  116. // GetPackageRevisions gets all revision of a package
  117. func GetPackageRevisions(ctx context.Context, ownerID int64, ref *conan_module.PackageReference) ([]*PropertyValue, error) {
  118. values, err := findPropertyValues(
  119. ctx,
  120. conan_module.PropertyPackageRevision,
  121. ownerID,
  122. ref.Recipe.Name,
  123. ref.Recipe.Version,
  124. map[string]string{
  125. conan_module.PropertyRecipeUser: ref.Recipe.User,
  126. conan_module.PropertyRecipeChannel: ref.Recipe.Channel,
  127. conan_module.PropertyRecipeRevision: ref.Recipe.Revision,
  128. conan_module.PropertyPackageReference: ref.Reference,
  129. },
  130. )
  131. if err != nil {
  132. return nil, err
  133. }
  134. return values, nil
  135. }
  136. // GetLastPackageRevision gets the latest package revision
  137. func GetLastPackageRevision(ctx context.Context, ownerID int64, ref *conan_module.PackageReference) (*PropertyValue, error) {
  138. revisions, err := GetPackageRevisions(ctx, ownerID, ref)
  139. if err != nil {
  140. return nil, err
  141. }
  142. if len(revisions) == 0 {
  143. return nil, ErrPackageReferenceNotExist
  144. }
  145. return revisions[0], nil
  146. }