code.gitea.io/gitea@v1.21.7/models/migrations/v1_14/v157.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package v1_14 //nolint
     5  
     6  import (
     7  	"xorm.io/xorm"
     8  )
     9  
    10  func FixRepoTopics(x *xorm.Engine) error {
    11  	type Topic struct { //nolint:unused
    12  		ID        int64  `xorm:"pk autoincr"`
    13  		Name      string `xorm:"UNIQUE VARCHAR(25)"`
    14  		RepoCount int
    15  	}
    16  
    17  	type RepoTopic struct { //nolint:unused
    18  		RepoID  int64 `xorm:"pk"`
    19  		TopicID int64 `xorm:"pk"`
    20  	}
    21  
    22  	type Repository struct {
    23  		ID     int64    `xorm:"pk autoincr"`
    24  		Topics []string `xorm:"TEXT JSON"`
    25  	}
    26  
    27  	const batchSize = 100
    28  	sess := x.NewSession()
    29  	defer sess.Close()
    30  	repos := make([]*Repository, 0, batchSize)
    31  	topics := make([]string, 0, batchSize)
    32  	for start := 0; ; start += batchSize {
    33  		repos = repos[:0]
    34  
    35  		if err := sess.Begin(); err != nil {
    36  			return err
    37  		}
    38  
    39  		if err := sess.Limit(batchSize, start).Find(&repos); err != nil {
    40  			return err
    41  		}
    42  
    43  		if len(repos) == 0 {
    44  			break
    45  		}
    46  
    47  		for _, repo := range repos {
    48  			topics = topics[:0]
    49  			if err := sess.Select("name").Table("topic").
    50  				Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
    51  				Where("repo_topic.repo_id = ?", repo.ID).Desc("topic.repo_count").Find(&topics); err != nil {
    52  				return err
    53  			}
    54  			repo.Topics = topics
    55  			if _, err := sess.ID(repo.ID).Cols("topics").Update(repo); err != nil {
    56  				return err
    57  			}
    58  		}
    59  
    60  		if err := sess.Commit(); err != nil {
    61  			return err
    62  		}
    63  	}
    64  
    65  	return nil
    66  }