summaryrefslogtreecommitdiffstats
path: root/models/topic.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-12-12 23:48:20 +0800
committerGitHub <noreply@github.com>2021-12-12 23:48:20 +0800
commit572324049008ac803d3d7c17a7b3a81ef00386fc (patch)
treea9c3709643a23165d27aa67e76f10f26a89936d5 /models/topic.go
parent0a7e8327a017c5dd43e552bbcd0d0f056bc1671b (diff)
downloadgitea-572324049008ac803d3d7c17a7b3a81ef00386fc.tar.gz
gitea-572324049008ac803d3d7c17a7b3a81ef00386fc.zip
Some repository refactors (#17950)
* some repository refactors * remove unnecessary code * Fix test * Remove unnecessary banner
Diffstat (limited to 'models/topic.go')
-rw-r--r--models/topic.go358
1 files changed, 0 insertions, 358 deletions
diff --git a/models/topic.go b/models/topic.go
deleted file mode 100644
index 2767d6c58b..0000000000
--- a/models/topic.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package models
-
-import (
- "fmt"
- "regexp"
- "strings"
-
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/timeutil"
-
- "xorm.io/builder"
-)
-
-func init() {
- db.RegisterModel(new(Topic))
- db.RegisterModel(new(RepoTopic))
-}
-
-var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
-
-// Topic represents a topic of repositories
-type Topic struct {
- ID int64 `xorm:"pk autoincr"`
- Name string `xorm:"UNIQUE VARCHAR(50)"`
- RepoCount int
- CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
- UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
-}
-
-// RepoTopic represents associated repositories and topics
-type RepoTopic struct {
- RepoID int64 `xorm:"pk"`
- TopicID int64 `xorm:"pk"`
-}
-
-// ErrTopicNotExist represents an error that a topic is not exist
-type ErrTopicNotExist struct {
- Name string
-}
-
-// IsErrTopicNotExist checks if an error is an ErrTopicNotExist.
-func IsErrTopicNotExist(err error) bool {
- _, ok := err.(ErrTopicNotExist)
- return ok
-}
-
-// Error implements error interface
-func (err ErrTopicNotExist) Error() string {
- return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
-}
-
-// ValidateTopic checks a topic by length and match pattern rules
-func ValidateTopic(topic string) bool {
- return len(topic) <= 35 && topicPattern.MatchString(topic)
-}
-
-// SanitizeAndValidateTopics sanitizes and checks an array or topics
-func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []string) {
- validTopics = make([]string, 0)
- mValidTopics := make(map[string]struct{})
- invalidTopics = make([]string, 0)
-
- for _, topic := range topics {
- topic = strings.TrimSpace(strings.ToLower(topic))
- // ignore empty string
- if len(topic) == 0 {
- continue
- }
- // ignore same topic twice
- if _, ok := mValidTopics[topic]; ok {
- continue
- }
- if ValidateTopic(topic) {
- validTopics = append(validTopics, topic)
- mValidTopics[topic] = struct{}{}
- } else {
- invalidTopics = append(invalidTopics, topic)
- }
- }
-
- return validTopics, invalidTopics
-}
-
-// GetTopicByName retrieves topic by name
-func GetTopicByName(name string) (*Topic, error) {
- var topic Topic
- if has, err := db.GetEngine(db.DefaultContext).Where("name = ?", name).Get(&topic); err != nil {
- return nil, err
- } else if !has {
- return nil, ErrTopicNotExist{name}
- }
- return &topic, nil
-}
-
-// addTopicByNameToRepo adds a topic name to a repo and increments the topic count.
-// Returns topic after the addition
-func addTopicByNameToRepo(e db.Engine, repoID int64, topicName string) (*Topic, error) {
- var topic Topic
- has, err := e.Where("name = ?", topicName).Get(&topic)
- if err != nil {
- return nil, err
- }
- if !has {
- topic.Name = topicName
- topic.RepoCount = 1
- if _, err := e.Insert(&topic); err != nil {
- return nil, err
- }
- } else {
- topic.RepoCount++
- if _, err := e.ID(topic.ID).Cols("repo_count").Update(&topic); err != nil {
- return nil, err
- }
- }
-
- if _, err := e.Insert(&RepoTopic{
- RepoID: repoID,
- TopicID: topic.ID,
- }); err != nil {
- return nil, err
- }
-
- return &topic, nil
-}
-
-// removeTopicFromRepo remove a topic from a repo and decrements the topic repo count
-func removeTopicFromRepo(e db.Engine, repoID int64, topic *Topic) error {
- topic.RepoCount--
- if _, err := e.ID(topic.ID).Cols("repo_count").Update(topic); err != nil {
- return err
- }
-
- if _, err := e.Delete(&RepoTopic{
- RepoID: repoID,
- TopicID: topic.ID,
- }); err != nil {
- return err
- }
-
- return nil
-}
-
-// removeTopicsFromRepo remove all topics from the repo and decrements respective topics repo count
-func removeTopicsFromRepo(e db.Engine, repoID int64) error {
- _, err := e.Where(
- builder.In("id",
- builder.Select("topic_id").From("repo_topic").Where(builder.Eq{"repo_id": repoID}),
- ),
- ).Cols("repo_count").SetExpr("repo_count", "repo_count-1").Update(&Topic{})
- if err != nil {
- return err
- }
-
- if _, err = e.Delete(&RepoTopic{RepoID: repoID}); err != nil {
- return err
- }
-
- return nil
-}
-
-// FindTopicOptions represents the options when fdin topics
-type FindTopicOptions struct {
- db.ListOptions
- RepoID int64
- Keyword string
-}
-
-func (opts *FindTopicOptions) toConds() builder.Cond {
- cond := builder.NewCond()
- if opts.RepoID > 0 {
- cond = cond.And(builder.Eq{"repo_topic.repo_id": opts.RepoID})
- }
-
- if opts.Keyword != "" {
- cond = cond.And(builder.Like{"topic.name", opts.Keyword})
- }
-
- return cond
-}
-
-// FindTopics retrieves the topics via FindTopicOptions
-func FindTopics(opts *FindTopicOptions) ([]*Topic, int64, error) {
- sess := db.GetEngine(db.DefaultContext).Select("topic.*").Where(opts.toConds())
- if opts.RepoID > 0 {
- sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id")
- }
- if opts.PageSize != 0 && opts.Page != 0 {
- sess = db.SetSessionPagination(sess, opts)
- }
- topics := make([]*Topic, 0, 10)
- total, err := sess.Desc("topic.repo_count").FindAndCount(&topics)
- return topics, total, err
-}
-
-// CountTopics counts the number of topics matching the FindTopicOptions
-func CountTopics(opts *FindTopicOptions) (int64, error) {
- sess := db.GetEngine(db.DefaultContext).Where(opts.toConds())
- if opts.RepoID > 0 {
- sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id")
- }
- return sess.Count(new(Topic))
-}
-
-// GetRepoTopicByName retrieves topic from name for a repo if it exist
-func GetRepoTopicByName(repoID int64, topicName string) (*Topic, error) {
- return getRepoTopicByName(db.GetEngine(db.DefaultContext), repoID, topicName)
-}
-
-func getRepoTopicByName(e db.Engine, repoID int64, topicName string) (*Topic, error) {
- cond := builder.NewCond()
- var topic Topic
- cond = cond.And(builder.Eq{"repo_topic.repo_id": repoID}).And(builder.Eq{"topic.name": topicName})
- sess := e.Table("topic").Where(cond)
- sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id")
- has, err := sess.Get(&topic)
- if has {
- return &topic, err
- }
- return nil, err
-}
-
-// AddTopic adds a topic name to a repository (if it does not already have it)
-func AddTopic(repoID int64, topicName string) (*Topic, error) {
- ctx, committer, err := db.TxContext()
- if err != nil {
- return nil, err
- }
- defer committer.Close()
- sess := db.GetEngine(ctx)
-
- topic, err := getRepoTopicByName(sess, repoID, topicName)
- if err != nil {
- return nil, err
- }
- if topic != nil {
- // Repo already have topic
- return topic, nil
- }
-
- topic, err = addTopicByNameToRepo(sess, repoID, topicName)
- if err != nil {
- return nil, err
- }
-
- topicNames := make([]string, 0, 25)
- if err := sess.Select("name").Table("topic").
- Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
- Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
- return nil, err
- }
-
- if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{
- Topics: topicNames,
- }); err != nil {
- return nil, err
- }
-
- return topic, committer.Commit()
-}
-
-// DeleteTopic removes a topic name from a repository (if it has it)
-func DeleteTopic(repoID int64, topicName string) (*Topic, error) {
- topic, err := GetRepoTopicByName(repoID, topicName)
- if err != nil {
- return nil, err
- }
- if topic == nil {
- // Repo doesn't have topic, can't be removed
- return nil, nil
- }
-
- err = removeTopicFromRepo(db.GetEngine(db.DefaultContext), repoID, topic)
-
- return topic, err
-}
-
-// SaveTopics save topics to a repository
-func SaveTopics(repoID int64, topicNames ...string) error {
- topics, _, err := FindTopics(&FindTopicOptions{
- RepoID: repoID,
- })
- if err != nil {
- return err
- }
-
- ctx, committer, err := db.TxContext()
- if err != nil {
- return err
- }
- defer committer.Close()
- sess := db.GetEngine(ctx)
-
- var addedTopicNames []string
- for _, topicName := range topicNames {
- if strings.TrimSpace(topicName) == "" {
- continue
- }
-
- var found bool
- for _, t := range topics {
- if strings.EqualFold(topicName, t.Name) {
- found = true
- break
- }
- }
- if !found {
- addedTopicNames = append(addedTopicNames, topicName)
- }
- }
-
- var removeTopics []*Topic
- for _, t := range topics {
- var found bool
- for _, topicName := range topicNames {
- if strings.EqualFold(topicName, t.Name) {
- found = true
- break
- }
- }
- if !found {
- removeTopics = append(removeTopics, t)
- }
- }
-
- for _, topicName := range addedTopicNames {
- _, err := addTopicByNameToRepo(sess, repoID, topicName)
- if err != nil {
- return err
- }
- }
-
- for _, topic := range removeTopics {
- err := removeTopicFromRepo(sess, repoID, topic)
- if err != nil {
- return err
- }
- }
-
- topicNames = make([]string, 0, 25)
- if err := sess.Table("topic").Cols("name").
- Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
- Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
- return err
- }
-
- if _, err := sess.ID(repoID).Cols("topics").Update(&repo_model.Repository{
- Topics: topicNames,
- }); err != nil {
- return err
- }
-
- return committer.Commit()
-}