summaryrefslogtreecommitdiffstats
path: root/models/migrations/v64.go
blob: 00637ca0461b8b39f61317d7960a59283b0f83b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 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 migrations

import (
	"code.gitea.io/gitea/modules/timeutil"

	"github.com/go-xorm/xorm"
)

func addMultipleAssignees(x *xorm.Engine) error {

	// Redeclare issue struct
	type Issue struct {
		ID          int64  `xorm:"pk autoincr"`
		RepoID      int64  `xorm:"INDEX UNIQUE(repo_index)"`
		Index       int64  `xorm:"UNIQUE(repo_index)"` // Index in one repository.
		PosterID    int64  `xorm:"INDEX"`
		Title       string `xorm:"name"`
		Content     string `xorm:"TEXT"`
		MilestoneID int64  `xorm:"INDEX"`
		Priority    int
		AssigneeID  int64 `xorm:"INDEX"`
		IsClosed    bool  `xorm:"INDEX"`
		IsPull      bool  `xorm:"INDEX"` // Indicates whether is a pull request or not.
		NumComments int

		DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
		CreatedUnix  timeutil.TimeStamp `xorm:"INDEX created"`
		UpdatedUnix  timeutil.TimeStamp `xorm:"INDEX updated"`
		ClosedUnix   timeutil.TimeStamp `xorm:"INDEX"`
	}

	// Updated the comment table
	type Comment struct {
		ID              int64 `xorm:"pk autoincr"`
		Type            int
		PosterID        int64 `xorm:"INDEX"`
		IssueID         int64 `xorm:"INDEX"`
		LabelID         int64
		OldMilestoneID  int64
		MilestoneID     int64
		OldAssigneeID   int64
		AssigneeID      int64
		RemovedAssignee bool
		OldTitle        string
		NewTitle        string

		CommitID        int64
		Line            int64
		Content         string `xorm:"TEXT"`
		RenderedContent string `xorm:"-"`

		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`

		// Reference issue in commit message
		CommitSHA string `xorm:"VARCHAR(40)"`
	}

	// Create the table
	type IssueAssignees struct {
		ID         int64 `xorm:"pk autoincr"`
		AssigneeID int64 `xorm:"INDEX"`
		IssueID    int64 `xorm:"INDEX"`
	}

	if err := x.Sync2(IssueAssignees{}); err != nil {
		return err
	}

	if err := x.Sync2(Comment{}); err != nil {
		return err
	}

	// Range over all issues and insert a new entry for each issue/assignee
	sess := x.NewSession()
	defer sess.Close()

	if err := sess.Begin(); err != nil {
		return err
	}

	allIssues := []*Issue{}
	if err := sess.Find(&allIssues); err != nil {
		return err
	}

	for _, issue := range allIssues {
		if issue.AssigneeID != 0 {
			_, err := sess.Insert(IssueAssignees{IssueID: issue.ID, AssigneeID: issue.AssigneeID})
			if err != nil {
				sess.Rollback()
				return err
			}
		}
	}

	// Migrate comments
	// First update everything to not have nulls in db
	if _, err := sess.Where("type = ?", 9).Cols("removed_assignee").Update(Comment{RemovedAssignee: false}); err != nil {
		return err
	}

	allAssignementComments := []*Comment{}
	if err := sess.Where("type = ?", 9).Find(&allAssignementComments); err != nil {
		return err
	}

	for _, comment := range allAssignementComments {
		// Everytime where OldAssigneeID is > 0, the assignement was removed.
		if comment.OldAssigneeID > 0 {
			_, err := sess.ID(comment.ID).Update(Comment{RemovedAssignee: true})
			if err != nil {
				return err
			}
		}
	}

	// Commit and begin new transaction for dropping columns
	if err := sess.Commit(); err != nil {
		return err
	}
	if err := sess.Begin(); err != nil {
		return err
	}

	if err := dropTableColumns(sess, "issue", "assignee_id"); err != nil {
		return err
	}

	if err := dropTableColumns(sess, "issue_user", "is_assigned"); err != nil {
		return err
	}
	return sess.Commit()
}