code.gitea.io/gitea@v1.22.3/models/packages/package_property.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package packages
     5  
     6  import (
     7  	"context"
     8  
     9  	"code.gitea.io/gitea/models/db"
    10  
    11  	"xorm.io/builder"
    12  )
    13  
    14  func init() {
    15  	db.RegisterModel(new(PackageProperty))
    16  }
    17  
    18  type PropertyType int64
    19  
    20  const (
    21  	// PropertyTypeVersion means the reference is a package version
    22  	PropertyTypeVersion PropertyType = iota // 0
    23  	// PropertyTypeFile means the reference is a package file
    24  	PropertyTypeFile // 1
    25  	// PropertyTypePackage means the reference is a package
    26  	PropertyTypePackage // 2
    27  )
    28  
    29  // PackageProperty represents a property of a package, version or file
    30  type PackageProperty struct {
    31  	ID      int64        `xorm:"pk autoincr"`
    32  	RefType PropertyType `xorm:"INDEX NOT NULL"`
    33  	RefID   int64        `xorm:"INDEX NOT NULL"`
    34  	Name    string       `xorm:"INDEX NOT NULL"`
    35  	Value   string       `xorm:"TEXT NOT NULL"`
    36  }
    37  
    38  // InsertProperty creates a property
    39  func InsertProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) (*PackageProperty, error) {
    40  	pp := &PackageProperty{
    41  		RefType: refType,
    42  		RefID:   refID,
    43  		Name:    name,
    44  		Value:   value,
    45  	}
    46  
    47  	_, err := db.GetEngine(ctx).Insert(pp)
    48  	return pp, err
    49  }
    50  
    51  // GetProperties gets all properties
    52  func GetProperties(ctx context.Context, refType PropertyType, refID int64) ([]*PackageProperty, error) {
    53  	pps := make([]*PackageProperty, 0, 10)
    54  	return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Find(&pps)
    55  }
    56  
    57  // GetPropertiesByName gets all properties with a specific name
    58  func GetPropertiesByName(ctx context.Context, refType PropertyType, refID int64, name string) ([]*PackageProperty, error) {
    59  	pps := make([]*PackageProperty, 0, 10)
    60  	return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Find(&pps)
    61  }
    62  
    63  // UpdateProperty updates a property
    64  func UpdateProperty(ctx context.Context, pp *PackageProperty) error {
    65  	_, err := db.GetEngine(ctx).ID(pp.ID).Update(pp)
    66  	return err
    67  }
    68  
    69  // DeleteAllProperties deletes all properties of a ref
    70  func DeleteAllProperties(ctx context.Context, refType PropertyType, refID int64) error {
    71  	_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Delete(&PackageProperty{})
    72  	return err
    73  }
    74  
    75  // DeletePropertyByID deletes a property
    76  func DeletePropertyByID(ctx context.Context, propertyID int64) error {
    77  	_, err := db.GetEngine(ctx).ID(propertyID).Delete(&PackageProperty{})
    78  	return err
    79  }
    80  
    81  // DeletePropertyByName deletes properties by name
    82  func DeletePropertyByName(ctx context.Context, refType PropertyType, refID int64, name string) error {
    83  	_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Delete(&PackageProperty{})
    84  	return err
    85  }
    86  
    87  type DistinctPropertyDependency struct {
    88  	Name  string
    89  	Value string
    90  }
    91  
    92  // GetDistinctPropertyValues returns all distinct property values for a given type.
    93  // Optional: Search only in dependence of another property.
    94  func GetDistinctPropertyValues(ctx context.Context, packageType Type, ownerID int64, refType PropertyType, propertyName string, dep *DistinctPropertyDependency) ([]string, error) {
    95  	var cond builder.Cond = builder.Eq{
    96  		"package_property.ref_type": refType,
    97  		"package_property.name":     propertyName,
    98  		"package.type":              packageType,
    99  		"package.owner_id":          ownerID,
   100  	}
   101  	if dep != nil {
   102  		innerCond := builder.
   103  			Expr("pp.ref_id = package_property.ref_id").
   104  			And(builder.Eq{
   105  				"pp.ref_type": refType,
   106  				"pp.name":     dep.Name,
   107  				"pp.value":    dep.Value,
   108  			})
   109  		cond = cond.And(builder.Exists(builder.Select("pp.ref_id").From("package_property pp").Where(innerCond)))
   110  	}
   111  
   112  	values := make([]string, 0, 5)
   113  	return values, db.GetEngine(ctx).
   114  		Table("package_property").
   115  		Distinct("package_property.value").
   116  		Join("INNER", "package_file", "package_file.id = package_property.ref_id").
   117  		Join("INNER", "package_version", "package_version.id = package_file.version_id").
   118  		Join("INNER", "package", "package.id = package_version.package_id").
   119  		Where(cond).
   120  		Find(&values)
   121  }