0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-07-25 10:54:27 -04:00
gitea/models/packages/package_property.go
Lunny Xiao 54fe47fbca
Change some columns from text to longtext and fix column wrong type caused by xorm (#35141)
This PR upgrade xorm to v1.3.10 which fixed a bug when both `longtext
json` tags in the struct field. The `longtext` will be ignored and
`json` will be considered as `text`.

A migration has been introduced to modify the column directly to
longtext. And another two columns should also be migrated from text to
longtext.

All these changes only affect mysql database because for other databases
Gitea supported, text is the same as longtext.

Fix #27244 
Fix #34764 
Fix #35042
2025-07-23 22:24:44 -07:00

136 lines
4.5 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package packages
import (
"context"
"code.gitea.io/gitea/models/db"
"xorm.io/builder"
)
func init() {
db.RegisterModel(new(PackageProperty))
}
type PropertyType int64
const (
// PropertyTypeVersion means the reference is a package version
PropertyTypeVersion PropertyType = iota // 0
// PropertyTypeFile means the reference is a package file
PropertyTypeFile // 1
// PropertyTypePackage means the reference is a package
PropertyTypePackage // 2
)
// PackageProperty represents a property of a package, version or file
type PackageProperty struct {
ID int64 `xorm:"pk autoincr"`
RefType PropertyType `xorm:"INDEX NOT NULL"`
RefID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
Value string `xorm:"LONGTEXT NOT NULL"`
}
// InsertProperty creates a property
func InsertProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) (*PackageProperty, error) {
pp := &PackageProperty{
RefType: refType,
RefID: refID,
Name: name,
Value: value,
}
_, err := db.GetEngine(ctx).Insert(pp)
return pp, err
}
// GetProperties gets all properties
func GetProperties(ctx context.Context, refType PropertyType, refID int64) ([]*PackageProperty, error) {
pps := make([]*PackageProperty, 0, 10)
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Find(&pps)
}
// GetPropertiesByName gets all properties with a specific name
func GetPropertiesByName(ctx context.Context, refType PropertyType, refID int64, name string) ([]*PackageProperty, error) {
pps := make([]*PackageProperty, 0, 10)
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Find(&pps)
}
// UpdateProperty updates a property
func UpdateProperty(ctx context.Context, pp *PackageProperty) error {
_, err := db.GetEngine(ctx).ID(pp.ID).Update(pp)
return err
}
func InsertOrUpdateProperty(ctx context.Context, refType PropertyType, refID int64, name, value string) error {
pp := PackageProperty{RefType: refType, RefID: refID, Name: name}
ok, err := db.GetEngine(ctx).Get(&pp)
if err != nil {
return err
}
if ok {
_, err = db.GetEngine(ctx).Where("ref_type=? AND ref_id=? AND name=?", refType, refID, name).Cols("value").Update(&PackageProperty{Value: value})
return err
}
_, err = InsertProperty(ctx, refType, refID, name, value)
return err
}
// DeleteAllProperties deletes all properties of a ref
func DeleteAllProperties(ctx context.Context, refType PropertyType, refID int64) error {
_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Delete(&PackageProperty{})
return err
}
// DeletePropertyByID deletes a property
func DeletePropertyByID(ctx context.Context, propertyID int64) error {
_, err := db.GetEngine(ctx).ID(propertyID).Delete(&PackageProperty{})
return err
}
// DeletePropertiesByName deletes properties by name
func DeletePropertiesByName(ctx context.Context, refType PropertyType, refID int64, name string) error {
_, err := db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Delete(&PackageProperty{})
return err
}
type DistinctPropertyDependency struct {
Name string
Value string
}
// GetDistinctPropertyValues returns all distinct property values for a given type.
// Optional: Search only in dependence of another property.
func GetDistinctPropertyValues(ctx context.Context, packageType Type, ownerID int64, refType PropertyType, propertyName string, dep *DistinctPropertyDependency) ([]string, error) {
var cond builder.Cond = builder.Eq{
"package_property.ref_type": refType,
"package_property.name": propertyName,
"package.type": packageType,
"package.owner_id": ownerID,
}
if dep != nil {
innerCond := builder.
Expr("pp.ref_id = package_property.ref_id").
And(builder.Eq{
"pp.ref_type": refType,
"pp.name": dep.Name,
"pp.value": dep.Value,
})
cond = cond.And(builder.Exists(builder.Select("pp.ref_id").From("package_property pp").Where(innerCond)))
}
values := make([]string, 0, 5)
return values, db.GetEngine(ctx).
Table("package_property").
Distinct("package_property.value").
Join("INNER", "package_file", "package_file.id = package_property.ref_id").
Join("INNER", "package_version", "package_version.id = package_file.version_id").
Join("INNER", "package", "package.id = package_version.package_id").
Where(cond).
Find(&values)
}