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 }