Browse Source

Use AfterLoad instead of AfterSet on Structs (#2628)

* use AfterLoad instead of AfterSet on Structs

* fix the comments on AfterLoad

* fix the comments on action AfterLoad
Lunny Xiao 1 year ago
parent
commit
a8717e5e3a

+ 3 - 7
models/action.go

@@ -16,7 +16,6 @@ import (
16 16
 
17 17
 	"github.com/Unknwon/com"
18 18
 	"github.com/go-xorm/builder"
19
-	"github.com/go-xorm/xorm"
20 19
 
21 20
 	"code.gitea.io/git"
22 21
 	api "code.gitea.io/sdk/gitea"
@@ -91,12 +90,9 @@ type Action struct {
91 90
 	CreatedUnix int64     `xorm:"INDEX created"`
92 91
 }
93 92
 
94
-// AfterSet updates the webhook object upon setting a column.
95
-func (a *Action) AfterSet(colName string, _ xorm.Cell) {
96
-	switch colName {
97
-	case "created_unix":
98
-		a.Created = time.Unix(a.CreatedUnix, 0).Local()
99
-	}
93
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
94
+func (a *Action) AfterLoad() {
95
+	a.Created = time.Unix(a.CreatedUnix, 0).Local()
100 96
 }
101 97
 
102 98
 // GetOpType gets the ActionType of this action.

+ 3 - 7
models/admin.go

@@ -12,7 +12,6 @@ import (
12 12
 	"code.gitea.io/gitea/modules/util"
13 13
 
14 14
 	"github.com/Unknwon/com"
15
-	"github.com/go-xorm/xorm"
16 15
 )
17 16
 
18 17
 //NoticeType describes the notice type
@@ -32,12 +31,9 @@ type Notice struct {
32 31
 	CreatedUnix int64     `xorm:"INDEX created"`
33 32
 }
34 33
 
35
-// AfterSet is invoked from XORM after setting the value of a field of this object.
36
-func (n *Notice) AfterSet(colName string, _ xorm.Cell) {
37
-	switch colName {
38
-	case "created_unix":
39
-		n.Created = time.Unix(n.CreatedUnix, 0).Local()
40
-	}
34
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
35
+func (n *Notice) AfterLoad() {
36
+	n.Created = time.Unix(n.CreatedUnix, 0).Local()
41 37
 }
42 38
 
43 39
 // TrStr returns a translation format string.

+ 7 - 7
models/attachment.go

@@ -12,7 +12,6 @@ import (
12 12
 	"path"
13 13
 	"time"
14 14
 
15
-	"github.com/go-xorm/xorm"
16 15
 	gouuid "github.com/satori/go.uuid"
17 16
 
18 17
 	"code.gitea.io/gitea/modules/setting"
@@ -31,13 +30,10 @@ type Attachment struct {
31 30
 	CreatedUnix   int64     `xorm:"created"`
32 31
 }
33 32
 
34
-// AfterSet is invoked from XORM after setting the value of a field of
33
+// AfterLoad is invoked from XORM after setting the value of a field of
35 34
 // this object.
36
-func (a *Attachment) AfterSet(colName string, _ xorm.Cell) {
37
-	switch colName {
38
-	case "created_unix":
39
-		a.Created = time.Unix(a.CreatedUnix, 0).Local()
40
-	}
35
+func (a *Attachment) AfterLoad() {
36
+	a.Created = time.Unix(a.CreatedUnix, 0).Local()
41 37
 }
42 38
 
43 39
 // IncreaseDownloadCount is update download count + 1
@@ -133,6 +129,10 @@ func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) {
133 129
 
134 130
 // GetAttachmentsByCommentID returns all attachments if comment by given ID.
135 131
 func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) {
132
+	return getAttachmentsByCommentID(x, commentID)
133
+}
134
+
135
+func getAttachmentsByCommentID(e Engine, commentID int64) ([]*Attachment, error) {
136 136
 	attachments := make([]*Attachment, 0, 10)
137 137
 	return attachments, x.Where("comment_id=?", commentID).Find(&attachments)
138 138
 }

+ 9 - 11
models/gpg_key.go

@@ -52,17 +52,15 @@ func (key *GPGKey) BeforeInsert() {
52 52
 	key.CreatedUnix = key.Created.Unix()
53 53
 }
54 54
 
55
-// AfterSet is invoked from XORM after setting the value of a field of this object.
56
-func (key *GPGKey) AfterSet(colName string, _ xorm.Cell) {
57
-	switch colName {
58
-	case "key_id":
59
-		x.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey)
60
-	case "added_unix":
61
-		key.Added = time.Unix(key.AddedUnix, 0).Local()
62
-	case "expired_unix":
63
-		key.Expired = time.Unix(key.ExpiredUnix, 0).Local()
64
-	case "created_unix":
65
-		key.Created = time.Unix(key.CreatedUnix, 0).Local()
55
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
56
+func (key *GPGKey) AfterLoad(session *xorm.Session) {
57
+	key.Added = time.Unix(key.AddedUnix, 0).Local()
58
+	key.Expired = time.Unix(key.ExpiredUnix, 0).Local()
59
+	key.Created = time.Unix(key.CreatedUnix, 0).Local()
60
+
61
+	err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey)
62
+	if err != nil {
63
+		log.Error(3, "Find Sub GPGkeys[%d]: %v", key.KeyID, err)
66 64
 	}
67 65
 }
68 66
 

+ 5 - 10
models/issue.go

@@ -67,17 +67,12 @@ func (issue *Issue) BeforeUpdate() {
67 67
 	issue.DeadlineUnix = issue.Deadline.Unix()
68 68
 }
69 69
 
70
-// AfterSet is invoked from XORM after setting the value of a field of
70
+// AfterLoad is invoked from XORM after setting the value of a field of
71 71
 // this object.
72
-func (issue *Issue) AfterSet(colName string, _ xorm.Cell) {
73
-	switch colName {
74
-	case "deadline_unix":
75
-		issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local()
76
-	case "created_unix":
77
-		issue.Created = time.Unix(issue.CreatedUnix, 0).Local()
78
-	case "updated_unix":
79
-		issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local()
80
-	}
72
+func (issue *Issue) AfterLoad() {
73
+	issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local()
74
+	issue.Created = time.Unix(issue.CreatedUnix, 0).Local()
75
+	issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local()
81 76
 }
82 77
 
83 78
 func (issue *Issue) loadRepo(e Engine) (err error) {

+ 16 - 21
models/issue_comment.go

@@ -112,30 +112,25 @@ type Comment struct {
112 112
 	ShowTag CommentTag `xorm:"-"`
113 113
 }
114 114
 
115
-// AfterSet is invoked from XORM after setting the value of a field of this object.
116
-func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
115
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
116
+func (c *Comment) AfterLoad(session *xorm.Session) {
117
+	c.Created = time.Unix(c.CreatedUnix, 0).Local()
118
+	c.Updated = time.Unix(c.UpdatedUnix, 0).Local()
119
+
117 120
 	var err error
118
-	switch colName {
119
-	case "id":
120
-		c.Attachments, err = GetAttachmentsByCommentID(c.ID)
121
-		if err != nil {
122
-			log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err)
123
-		}
121
+	c.Attachments, err = getAttachmentsByCommentID(session, c.ID)
122
+	if err != nil {
123
+		log.Error(3, "getAttachmentsByCommentID[%d]: %v", c.ID, err)
124
+	}
124 125
 
125
-	case "poster_id":
126
-		c.Poster, err = GetUserByID(c.PosterID)
127
-		if err != nil {
128
-			if IsErrUserNotExist(err) {
129
-				c.PosterID = -1
130
-				c.Poster = NewGhostUser()
131
-			} else {
132
-				log.Error(3, "GetUserByID[%d]: %v", c.ID, err)
133
-			}
126
+	c.Poster, err = getUserByID(session, c.PosterID)
127
+	if err != nil {
128
+		if IsErrUserNotExist(err) {
129
+			c.PosterID = -1
130
+			c.Poster = NewGhostUser()
131
+		} else {
132
+			log.Error(3, "getUserByID[%d]: %v", c.ID, err)
134 133
 		}
135
-	case "created_unix":
136
-		c.Created = time.Unix(c.CreatedUnix, 0).Local()
137
-	case "updated_unix":
138
-		c.Updated = time.Unix(c.UpdatedUnix, 0).Local()
139 134
 	}
140 135
 }
141 136
 

+ 12 - 18
models/issue_milestone.go

@@ -51,27 +51,21 @@ func (m *Milestone) BeforeUpdate() {
51 51
 	m.ClosedDateUnix = m.ClosedDate.Unix()
52 52
 }
53 53
 
54
-// AfterSet is invoked from XORM after setting the value of a field of
54
+// AfterLoad is invoked from XORM after setting the value of a field of
55 55
 // this object.
56
-func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
57
-	switch colName {
58
-	case "num_closed_issues":
59
-		m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
60
-
61
-	case "deadline_unix":
62
-		m.Deadline = time.Unix(m.DeadlineUnix, 0).Local()
63
-		if m.Deadline.Year() == 9999 {
64
-			return
65
-		}
66
-
67
-		m.DeadlineString = m.Deadline.Format("2006-01-02")
68
-		if time.Now().Local().After(m.Deadline) {
69
-			m.IsOverDue = true
70
-		}
56
+func (m *Milestone) AfterLoad() {
57
+	m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
58
+	m.Deadline = time.Unix(m.DeadlineUnix, 0).Local()
59
+	if m.Deadline.Year() == 9999 {
60
+		return
61
+	}
71 62
 
72
-	case "closed_date_unix":
73
-		m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local()
63
+	m.DeadlineString = m.Deadline.Format("2006-01-02")
64
+	if time.Now().Local().After(m.Deadline) {
65
+		m.IsOverDue = true
74 66
 	}
67
+
68
+	m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local()
75 69
 }
76 70
 
77 71
 // State returns string representation of milestone status.

+ 3 - 9
models/issue_stopwatch.go

@@ -7,8 +7,6 @@ package models
7 7
 import (
8 8
 	"fmt"
9 9
 	"time"
10
-
11
-	"github.com/go-xorm/xorm"
12 10
 )
13 11
 
14 12
 // Stopwatch represents a stopwatch for time tracking.
@@ -26,13 +24,9 @@ func (s *Stopwatch) BeforeInsert() {
26 24
 	s.CreatedUnix = time.Now().Unix()
27 25
 }
28 26
 
29
-// AfterSet is invoked from XORM after setting the value of a field of this object.
30
-func (s *Stopwatch) AfterSet(colName string, _ xorm.Cell) {
31
-	switch colName {
32
-
33
-	case "created_unix":
34
-		s.Created = time.Unix(s.CreatedUnix, 0).Local()
35
-	}
27
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
28
+func (s *Stopwatch) AfterLoad() {
29
+	s.Created = time.Unix(s.CreatedUnix, 0).Local()
36 30
 }
37 31
 
38 32
 func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) {

+ 4 - 14
models/issue_tracked_time.go

@@ -8,7 +8,6 @@ import (
8 8
 	"time"
9 9
 
10 10
 	"github.com/go-xorm/builder"
11
-	"github.com/go-xorm/xorm"
12 11
 )
13 12
 
14 13
 // TrackedTime represents a time that was spent for a specific issue.
@@ -17,22 +16,13 @@ type TrackedTime struct {
17 16
 	IssueID     int64     `xorm:"INDEX" json:"issue_id"`
18 17
 	UserID      int64     `xorm:"INDEX" json:"user_id"`
19 18
 	Created     time.Time `xorm:"-" json:"created"`
20
-	CreatedUnix int64     `json:"-"`
19
+	CreatedUnix int64     `xorm:"created" json:"-"`
21 20
 	Time        int64     `json:"time"`
22 21
 }
23 22
 
24
-// BeforeInsert will be invoked by XORM before inserting a record
25
-// representing this object.
26
-func (t *TrackedTime) BeforeInsert() {
27
-	t.CreatedUnix = time.Now().Unix()
28
-}
29
-
30
-// AfterSet is invoked from XORM after setting the value of a field of this object.
31
-func (t *TrackedTime) AfterSet(colName string, _ xorm.Cell) {
32
-	switch colName {
33
-	case "created_unix":
34
-		t.Created = time.Unix(t.CreatedUnix, 0).Local()
35
-	}
23
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
24
+func (t *TrackedTime) AfterLoad() {
25
+	t.Created = time.Unix(t.CreatedUnix, 0).Local()
36 26
 }
37 27
 
38 28
 // FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored.

+ 3 - 8
models/lfs.go

@@ -3,8 +3,6 @@ package models
3 3
 import (
4 4
 	"errors"
5 5
 	"time"
6
-
7
-	"github.com/go-xorm/xorm"
8 6
 )
9 7
 
10 8
 // LFSMetaObject stores metadata for LFS tracked files.
@@ -109,10 +107,7 @@ func RemoveLFSMetaObjectByOid(oid string) error {
109 107
 	return sess.Commit()
110 108
 }
111 109
 
112
-// AfterSet stores the LFSMetaObject creation time in the database as local time.
113
-func (m *LFSMetaObject) AfterSet(colName string, _ xorm.Cell) {
114
-	switch colName {
115
-	case "created_unix":
116
-		m.Created = time.Unix(m.CreatedUnix, 0).Local()
117
-	}
110
+// AfterLoad stores the LFSMetaObject creation time in the database as local time.
111
+func (m *LFSMetaObject) AfterLoad() {
112
+	m.Created = time.Unix(m.CreatedUnix, 0).Local()
118 113
 }

+ 4 - 8
models/login_source.go

@@ -183,14 +183,10 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
183 183
 	}
184 184
 }
185 185
 
186
-// AfterSet is invoked from XORM after setting the value of a field of this object.
187
-func (source *LoginSource) AfterSet(colName string, _ xorm.Cell) {
188
-	switch colName {
189
-	case "created_unix":
190
-		source.Created = time.Unix(source.CreatedUnix, 0).Local()
191
-	case "updated_unix":
192
-		source.Updated = time.Unix(source.UpdatedUnix, 0).Local()
193
-	}
186
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
187
+func (source *LoginSource) AfterLoad() {
188
+	source.Created = time.Unix(source.CreatedUnix, 0).Local()
189
+	source.Updated = time.Unix(source.UpdatedUnix, 0).Local()
194 190
 }
195 191
 
196 192
 // TypeName return name of this login source type.

+ 6 - 9
models/pull.go

@@ -80,17 +80,14 @@ func (pr *PullRequest) BeforeUpdate() {
80 80
 	pr.MergedUnix = pr.Merged.Unix()
81 81
 }
82 82
 
83
-// AfterSet is invoked from XORM after setting the value of a field of this object.
83
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
84 84
 // Note: don't try to get Issue because will end up recursive querying.
85
-func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
86
-	switch colName {
87
-	case "merged_unix":
88
-		if !pr.HasMerged {
89
-			return
90
-		}
91
-
92
-		pr.Merged = time.Unix(pr.MergedUnix, 0).Local()
85
+func (pr *PullRequest) AfterLoad() {
86
+	if !pr.HasMerged {
87
+		return
93 88
 	}
89
+
90
+	pr.Merged = time.Unix(pr.MergedUnix, 0).Local()
94 91
 }
95 92
 
96 93
 // Note: don't try to get Issue because will end up recursive querying.

+ 3 - 7
models/release.go

@@ -15,7 +15,6 @@ import (
15 15
 	"code.gitea.io/gitea/modules/setting"
16 16
 	api "code.gitea.io/sdk/gitea"
17 17
 	"github.com/go-xorm/builder"
18
-	"github.com/go-xorm/xorm"
19 18
 )
20 19
 
21 20
 // Release represents a release of repository.
@@ -50,12 +49,9 @@ func (r *Release) BeforeInsert() {
50 49
 	}
51 50
 }
52 51
 
53
-// AfterSet is invoked from XORM after setting the value of a field of this object.
54
-func (r *Release) AfterSet(colName string, _ xorm.Cell) {
55
-	switch colName {
56
-	case "created_unix":
57
-		r.Created = time.Unix(r.CreatedUnix, 0).Local()
58
-	}
52
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
53
+func (r *Release) AfterLoad() {
54
+	r.Created = time.Unix(r.CreatedUnix, 0).Local()
59 55
 }
60 56
 
61 57
 func (r *Release) loadAttributes(e Engine) error {

+ 12 - 19
models/repo.go

@@ -216,25 +216,18 @@ type Repository struct {
216 216
 	UpdatedUnix int64     `xorm:"INDEX updated"`
217 217
 }
218 218
 
219
-// AfterSet is invoked from XORM after setting the value of a field of this object.
220
-func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
221
-	switch colName {
222
-	case "default_branch":
223
-		// FIXME: use models migration to solve all at once.
224
-		if len(repo.DefaultBranch) == 0 {
225
-			repo.DefaultBranch = "master"
226
-		}
227
-	case "num_closed_issues":
228
-		repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
229
-	case "num_closed_pulls":
230
-		repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
231
-	case "num_closed_milestones":
232
-		repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
233
-	case "created_unix":
234
-		repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
235
-	case "updated_unix":
236
-		repo.Updated = time.Unix(repo.UpdatedUnix, 0)
237
-	}
219
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
220
+func (repo *Repository) AfterLoad() {
221
+	// FIXME: use models migration to solve all at once.
222
+	if len(repo.DefaultBranch) == 0 {
223
+		repo.DefaultBranch = "master"
224
+	}
225
+
226
+	repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
227
+	repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
228
+	repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
229
+	repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
230
+	repo.Updated = time.Unix(repo.UpdatedUnix, 0)
238 231
 }
239 232
 
240 233
 // MustOwner always returns a valid *User object to avoid

+ 8 - 12
models/repo_mirror.go

@@ -55,24 +55,20 @@ func (m *Mirror) BeforeUpdate() {
55 55
 	}
56 56
 }
57 57
 
58
-// AfterSet is invoked from XORM after setting the value of a field of this object.
59
-func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
58
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
59
+func (m *Mirror) AfterLoad(session *xorm.Session) {
60 60
 	if m == nil {
61 61
 		return
62 62
 	}
63 63
 
64 64
 	var err error
65
-	switch colName {
66
-	case "repo_id":
67
-		m.Repo, err = GetRepositoryByID(m.RepoID)
68
-		if err != nil {
69
-			log.Error(3, "GetRepositoryByID[%d]: %v", m.ID, err)
70
-		}
71
-	case "updated_unix":
72
-		m.Updated = time.Unix(m.UpdatedUnix, 0).Local()
73
-	case "next_update_unix":
74
-		m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local()
65
+	m.Repo, err = getRepositoryByID(session, m.RepoID)
66
+	if err != nil {
67
+		log.Error(3, "getRepositoryByID[%d]: %v", m.ID, err)
75 68
 	}
69
+
70
+	m.Updated = time.Unix(m.UpdatedUnix, 0).Local()
71
+	m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local()
76 72
 }
77 73
 
78 74
 // ScheduleNextUpdate calculates and sets next update time.

+ 3 - 6
models/repo_unit.go

@@ -106,12 +106,9 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
106 106
 	}
107 107
 }
108 108
 
109
-// AfterSet is invoked from XORM after setting the value of a field of this object.
110
-func (r *RepoUnit) AfterSet(colName string, _ xorm.Cell) {
111
-	switch colName {
112
-	case "created_unix":
113
-		r.Created = time.Unix(r.CreatedUnix, 0).Local()
114
-	}
109
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
110
+func (r *RepoUnit) AfterLoad() {
111
+	r.Created = time.Unix(r.CreatedUnix, 0).Local()
115 112
 }
116 113
 
117 114
 // Unit returns Unit

+ 14 - 22
models/ssh_key.go

@@ -56,22 +56,18 @@ type PublicKey struct {
56 56
 
57 57
 	Created           time.Time `xorm:"-"`
58 58
 	CreatedUnix       int64     `xorm:"created"`
59
-	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
59
+	Updated           time.Time `xorm:"-"`
60 60
 	UpdatedUnix       int64     `xorm:"updated"`
61 61
 	HasRecentActivity bool      `xorm:"-"`
62 62
 	HasUsed           bool      `xorm:"-"`
63 63
 }
64 64
 
65
-// AfterSet is invoked from XORM after setting the value of a field of this object.
66
-func (key *PublicKey) AfterSet(colName string, _ xorm.Cell) {
67
-	switch colName {
68
-	case "created_unix":
69
-		key.Created = time.Unix(key.CreatedUnix, 0).Local()
70
-	case "updated_unix":
71
-		key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
72
-		key.HasUsed = key.Updated.After(key.Created)
73
-		key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
74
-	}
65
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
66
+func (key *PublicKey) AfterLoad() {
67
+	key.Created = time.Unix(key.CreatedUnix, 0).Local()
68
+	key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
69
+	key.HasUsed = key.Updated.After(key.Created)
70
+	key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
75 71
 }
76 72
 
77 73
 // OmitEmail returns content of public key without email address.
@@ -612,22 +608,18 @@ type DeployKey struct {
612 608
 
613 609
 	Created           time.Time `xorm:"-"`
614 610
 	CreatedUnix       int64     `xorm:"created"`
615
-	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
611
+	Updated           time.Time `xorm:"-"`
616 612
 	UpdatedUnix       int64     `xorm:"updated"`
617 613
 	HasRecentActivity bool      `xorm:"-"`
618 614
 	HasUsed           bool      `xorm:"-"`
619 615
 }
620 616
 
621
-// AfterSet is invoked from XORM after setting the value of a field of this object.
622
-func (key *DeployKey) AfterSet(colName string, _ xorm.Cell) {
623
-	switch colName {
624
-	case "created_unix":
625
-		key.Created = time.Unix(key.CreatedUnix, 0).Local()
626
-	case "updated_unix":
627
-		key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
628
-		key.HasUsed = key.Updated.After(key.Created)
629
-		key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
630
-	}
617
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
618
+func (key *DeployKey) AfterLoad() {
619
+	key.Created = time.Unix(key.CreatedUnix, 0).Local()
620
+	key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
621
+	key.HasUsed = key.Updated.After(key.Created)
622
+	key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
631 623
 }
632 624
 
633 625
 // GetContent gets associated public key content.

+ 4 - 8
models/status.go

@@ -71,15 +71,11 @@ type CommitStatus struct {
71 71
 	UpdatedUnix int64     `xorm:"INDEX updated"`
72 72
 }
73 73
 
74
-// AfterSet is invoked from XORM after setting the value of a field of
74
+// AfterLoad is invoked from XORM after setting the value of a field of
75 75
 // this object.
76
-func (status *CommitStatus) AfterSet(colName string, _ xorm.Cell) {
77
-	switch colName {
78
-	case "created_unix":
79
-		status.Created = time.Unix(status.CreatedUnix, 0).Local()
80
-	case "updated_unix":
81
-		status.Updated = time.Unix(status.UpdatedUnix, 0).Local()
82
-	}
76
+func (status *CommitStatus) AfterLoad() {
77
+	status.Created = time.Unix(status.CreatedUnix, 0).Local()
78
+	status.Updated = time.Unix(status.UpdatedUnix, 0).Local()
83 79
 }
84 80
 
85 81
 func (status *CommitStatus) loadRepo(e Engine) (err error) {

+ 7 - 12
models/token.go

@@ -7,7 +7,6 @@ package models
7 7
 import (
8 8
 	"time"
9 9
 
10
-	"github.com/go-xorm/xorm"
11 10
 	gouuid "github.com/satori/go.uuid"
12 11
 
13 12
 	"code.gitea.io/gitea/modules/base"
@@ -22,22 +21,18 @@ type AccessToken struct {
22 21
 
23 22
 	Created           time.Time `xorm:"-"`
24 23
 	CreatedUnix       int64     `xorm:"INDEX created"`
25
-	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
24
+	Updated           time.Time `xorm:"-"`
26 25
 	UpdatedUnix       int64     `xorm:"INDEX updated"`
27 26
 	HasRecentActivity bool      `xorm:"-"`
28 27
 	HasUsed           bool      `xorm:"-"`
29 28
 }
30 29
 
31
-// AfterSet is invoked from XORM after setting the value of a field of this object.
32
-func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
33
-	switch colName {
34
-	case "created_unix":
35
-		t.Created = time.Unix(t.CreatedUnix, 0).Local()
36
-	case "updated_unix":
37
-		t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
38
-		t.HasUsed = t.Updated.After(t.Created)
39
-		t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
40
-	}
30
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
31
+func (t *AccessToken) AfterLoad() {
32
+	t.Created = time.Unix(t.CreatedUnix, 0).Local()
33
+	t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
34
+	t.HasUsed = t.Updated.After(t.Created)
35
+	t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
41 36
 }
42 37
 
43 38
 // NewAccessToken creates new access token.

+ 5 - 10
models/twofactor.go

@@ -11,7 +11,6 @@ import (
11 11
 	"time"
12 12
 
13 13
 	"github.com/Unknwon/com"
14
-	"github.com/go-xorm/xorm"
15 14
 	"github.com/pquerna/otp/totp"
16 15
 
17 16
 	"code.gitea.io/gitea/modules/base"
@@ -27,18 +26,14 @@ type TwoFactor struct {
27 26
 
28 27
 	Created     time.Time `xorm:"-"`
29 28
 	CreatedUnix int64     `xorm:"INDEX created"`
30
-	Updated     time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
29
+	Updated     time.Time `xorm:"-"`
31 30
 	UpdatedUnix int64     `xorm:"INDEX updated"`
32 31
 }
33 32
 
34
-// AfterSet is invoked from XORM after setting the value of a field of this object.
35
-func (t *TwoFactor) AfterSet(colName string, _ xorm.Cell) {
36
-	switch colName {
37
-	case "created_unix":
38
-		t.Created = time.Unix(t.CreatedUnix, 0).Local()
39
-	case "updated_unix":
40
-		t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
41
-	}
33
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
34
+func (t *TwoFactor) AfterLoad() {
35
+	t.Created = time.Unix(t.CreatedUnix, 0).Local()
36
+	t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
42 37
 }
43 38
 
44 39
 // GenerateScratchToken recreates the scratch token the user is using.

+ 5 - 10
models/user.go

@@ -153,16 +153,11 @@ func (u *User) UpdateDiffViewStyle(style string) error {
153 153
 	return UpdateUserCols(u, "diff_view_style")
154 154
 }
155 155
 
156
-// AfterSet is invoked from XORM after setting the value of a field of this object.
157
-func (u *User) AfterSet(colName string, _ xorm.Cell) {
158
-	switch colName {
159
-	case "created_unix":
160
-		u.Created = time.Unix(u.CreatedUnix, 0).Local()
161
-	case "updated_unix":
162
-		u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
163
-	case "last_login_unix":
164
-		u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local()
165
-	}
156
+// AfterLoad is invoked from XORM after setting the values of all fields of this object.
157
+func (u *User) AfterLoad() {
158
+	u.Created = time.Unix(u.CreatedUnix, 0).Local()
159
+	u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
160
+	u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local()
166 161
 }
167 162
 
168 163
 // getEmail returns an noreply email, if the user has set to keep his

+ 17 - 38
models/webhook.go

@@ -19,7 +19,6 @@ import (
19 19
 	"code.gitea.io/gitea/modules/sync"
20 20
 	api "code.gitea.io/sdk/gitea"
21 21
 
22
-	"github.com/go-xorm/xorm"
23 22
 	gouuid "github.com/satori/go.uuid"
24 23
 )
25 24
 
@@ -112,20 +111,15 @@ type Webhook struct {
112 111
 	UpdatedUnix int64     `xorm:"INDEX updated"`
113 112
 }
114 113
 
115
-// AfterSet updates the webhook object upon setting a column
116
-func (w *Webhook) AfterSet(colName string, _ xorm.Cell) {
117
-	var err error
118
-	switch colName {
119
-	case "events":
120
-		w.HookEvent = &HookEvent{}
121
-		if err = json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
122
-			log.Error(3, "Unmarshal[%d]: %v", w.ID, err)
123
-		}
124
-	case "created_unix":
125
-		w.Created = time.Unix(w.CreatedUnix, 0).Local()
126
-	case "updated_unix":
127
-		w.Updated = time.Unix(w.UpdatedUnix, 0).Local()
114
+// AfterLoad updates the webhook object upon setting a column
115
+func (w *Webhook) AfterLoad() {
116
+	w.HookEvent = &HookEvent{}
117
+	if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
118
+		log.Error(3, "Unmarshal[%d]: %v", w.ID, err)
128 119
 	}
120
+
121
+	w.Created = time.Unix(w.CreatedUnix, 0).Local()
122
+	w.Updated = time.Unix(w.UpdatedUnix, 0).Local()
129 123
 }
130 124
 
131 125
 // GetSlackHook returns slack metadata
@@ -432,32 +426,17 @@ func (t *HookTask) BeforeUpdate() {
432 426
 	}
433 427
 }
434 428
 
435
-// AfterSet updates the webhook object upon setting a column
436
-func (t *HookTask) AfterSet(colName string, _ xorm.Cell) {
437
-	var err error
438
-	switch colName {
439
-	case "delivered":
440
-		t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST")
441
-
442
-	case "request_content":
443
-		if len(t.RequestContent) == 0 {
444
-			return
445
-		}
446
-
447
-		t.RequestInfo = &HookRequest{}
448
-		if err = json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil {
449
-			log.Error(3, "Unmarshal[%d]: %v", t.ID, err)
450
-		}
429
+// AfterLoad updates the webhook object upon setting a column
430
+func (t *HookTask) AfterLoad() {
431
+	t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST")
451 432
 
452
-	case "response_content":
453
-		if len(t.ResponseContent) == 0 {
454
-			return
455
-		}
433
+	if len(t.RequestContent) == 0 {
434
+		return
435
+	}
456 436
 
457
-		t.ResponseInfo = &HookResponse{}
458
-		if err = json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil {
459
-			log.Error(3, "Unmarshal [%d]: %v", t.ID, err)
460
-		}
437
+	t.RequestInfo = &HookRequest{}
438
+	if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil {
439
+		log.Error(3, "Unmarshal[%d]: %v", t.ID, err)
461 440
 	}
462 441
 }
463 442
 

+ 14 - 3
vendor/github.com/go-xorm/xorm/engine.go

@@ -1516,10 +1516,14 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
1516 1516
 	return results, lastError
1517 1517
 }
1518 1518
 
1519
-// NowTime2 return current time
1520
-func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
1519
+// nowTime return current time
1520
+func (engine *Engine) nowTime(col *core.Column) (interface{}, time.Time) {
1521 1521
 	t := time.Now()
1522
-	return engine.formatTime(sqlTypeName, t.In(engine.DatabaseTZ)), t.In(engine.TZLocation)
1522
+	var tz = engine.DatabaseTZ
1523
+	if !col.DisableTimeZone && col.TimeZone != nil {
1524
+		tz = col.TimeZone
1525
+	}
1526
+	return engine.formatTime(col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation)
1523 1527
 }
1524 1528
 
1525 1529
 func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) {
@@ -1574,3 +1578,10 @@ func (engine *Engine) CondDeleted(colName string) builder.Cond {
1574 1578
 	}
1575 1579
 	return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1})
1576 1580
 }
1581
+
1582
+// BufferSize sets buffer size for iterate
1583
+func (engine *Engine) BufferSize(size int) *Session {
1584
+	session := engine.NewSession()
1585
+	session.isAutoClose = true
1586
+	return session.BufferSize(size)
1587
+}

+ 1 - 1
vendor/github.com/go-xorm/xorm/helpers.go

@@ -422,7 +422,7 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool,
422 422
 
423 423
 		if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
424 424
 			// if time is non-empty, then set to auto time
425
-			val, t := session.engine.NowTime2(col.SQLType.Name)
425
+			val, t := session.engine.nowTime(col)
426 426
 			args = append(args, val)
427 427
 
428 428
 			var colName = col.Name

+ 33 - 7
vendor/github.com/go-xorm/xorm/processors.go

@@ -29,13 +29,6 @@ type AfterSetProcessor interface {
29 29
 	AfterSet(string, Cell)
30 30
 }
31 31
 
32
-// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
33
-//// Executed before an object is validated
34
-//type BeforeValidateProcessor interface {
35
-//    BeforeValidate()
36
-//}
37
-// --
38
-
39 32
 // AfterInsertProcessor executed after an object is persisted to the database
40 33
 type AfterInsertProcessor interface {
41 34
 	AfterInsert()
@@ -50,3 +43,36 @@ type AfterUpdateProcessor interface {
50 43
 type AfterDeleteProcessor interface {
51 44
 	AfterDelete()
52 45
 }
46
+
47
+// AfterLoadProcessor executed after an ojbect has been loaded from database
48
+type AfterLoadProcessor interface {
49
+	AfterLoad()
50
+}
51
+
52
+// AfterLoadSessionProcessor executed after an ojbect has been loaded from database with session parameter
53
+type AfterLoadSessionProcessor interface {
54
+	AfterLoad(*Session)
55
+}
56
+
57
+type executedProcessorFunc func(*Session, interface{}) error
58
+
59
+type executedProcessor struct {
60
+	fun     executedProcessorFunc
61
+	session *Session
62
+	bean    interface{}
63
+}
64
+
65
+func (executor *executedProcessor) execute() error {
66
+	return executor.fun(executor.session, executor.bean)
67
+}
68
+
69
+func (session *Session) executeProcessors() error {
70
+	processors := session.afterProcessors
71
+	session.afterProcessors = make([]executedProcessor, 0)
72
+	for _, processor := range processors {
73
+		if err := processor.execute(); err != nil {
74
+			return err
75
+		}
76
+	}
77
+	return nil
78
+}

+ 7 - 3
vendor/github.com/go-xorm/xorm/rows.go

@@ -99,13 +99,17 @@ func (rows *Rows) Scan(bean interface{}) error {
99 99
 		return err
100 100
 	}
101 101
 
102
-	scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, len(rows.fields), bean)
102
+	scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, bean)
103 103
 	if err != nil {
104 104
 		return err
105 105
 	}
106 106
 
107
-	_, err = rows.session.slice2Bean(scanResults, rows.fields, len(rows.fields), bean, &dataStruct, rows.session.statement.RefTable)
108
-	return err
107
+	_, err = rows.session.slice2Bean(scanResults, rows.fields, bean, &dataStruct, rows.session.statement.RefTable)
108
+	if err != nil {
109
+		return err
110
+	}
111
+
112
+	return rows.session.executeProcessors()
109 113
 }
110 114
 
111 115
 // Close session if session.IsAutoClose is true, and claimed any opened resources

+ 52 - 16
vendor/github.com/go-xorm/xorm/session.go

@@ -41,6 +41,8 @@ type Session struct {
41 41
 	beforeClosures []func(interface{})
42 42
 	afterClosures  []func(interface{})
43 43
 
44
+	afterProcessors []executedProcessor
45
+
44 46
 	prepareStmt bool
45 47
 	stmtCache   map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr))
46 48
 
@@ -75,6 +77,8 @@ func (session *Session) Init() {
75 77
 	session.beforeClosures = make([]func(interface{}), 0)
76 78
 	session.afterClosures = make([]func(interface{}), 0)
77 79
 
80
+	session.afterProcessors = make([]executedProcessor, 0)
81
+
78 82
 	session.lastSQL = ""
79 83
 	session.lastSQLArgs = []interface{}{}
80 84
 }
@@ -296,37 +300,40 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c
296 300
 // Cell cell is a result of one column field
297 301
 type Cell *interface{}
298 302
 
299
-func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
303
+func (session *Session) rows2Beans(rows *core.Rows, fields []string,
300 304
 	table *core.Table, newElemFunc func([]string) reflect.Value,
301 305
 	sliceValueSetFunc func(*reflect.Value, core.PK) error) error {
302 306
 	for rows.Next() {
303 307
 		var newValue = newElemFunc(fields)
304 308
 		bean := newValue.Interface()
305
-		dataStruct := rValue(bean)
309
+		dataStruct := newValue.Elem()
306 310
 
307 311
 		// handle beforeClosures
308
-		scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
312
+		scanResults, err := session.row2Slice(rows, fields, bean)
309 313
 		if err != nil {
310 314
 			return err
311 315
 		}
312
-		pk, err := session.slice2Bean(scanResults, fields, fieldsCount, bean, &dataStruct, table)
313
-		if err != nil {
314
-			return err
315
-		}
316
-		err = sliceValueSetFunc(&newValue, pk)
316
+		pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
317 317
 		if err != nil {
318 318
 			return err
319 319
 		}
320
+		session.afterProcessors = append(session.afterProcessors, executedProcessor{
321
+			fun: func(*Session, interface{}) error {
322
+				return sliceValueSetFunc(&newValue, pk)
323
+			},
324
+			session: session,
325
+			bean:    bean,
326
+		})
320 327
 	}
321 328
 	return nil
322 329
 }
323 330
 
324
-func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) ([]interface{}, error) {
331
+func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) {
325 332
 	for _, closure := range session.beforeClosures {
326 333
 		closure(bean)
327 334
 	}
328 335
 
329
-	scanResults := make([]interface{}, fieldsCount)
336
+	scanResults := make([]interface{}, len(fields))
330 337
 	for i := 0; i < len(fields); i++ {
331 338
 		var cell interface{}
332 339
 		scanResults[i] = &cell
@@ -343,20 +350,49 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount
343 350
 	return scanResults, nil
344 351
 }
345 352
 
346
-func (session *Session) slice2Bean(scanResults []interface{}, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
353
+func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
347 354
 	defer func() {
348 355
 		if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
349 356
 			for ii, key := range fields {
350 357
 				b.AfterSet(key, Cell(scanResults[ii].(*interface{})))
351 358
 			}
352 359
 		}
353
-
354
-		// handle afterClosures
355
-		for _, closure := range session.afterClosures {
356
-			closure(bean)
357
-		}
358 360
 	}()
359 361
 
362
+	// handle afterClosures
363
+	for _, closure := range session.afterClosures {
364
+		session.afterProcessors = append(session.afterProcessors, executedProcessor{
365
+			fun: func(sess *Session, bean interface{}) error {
366
+				closure(bean)
367
+				return nil
368
+			},
369
+			session: session,
370
+			bean:    bean,
371
+		})
372
+	}
373
+
374
+	if a, has := bean.(AfterLoadProcessor); has {
375
+		session.afterProcessors = append(session.afterProcessors, executedProcessor{
376
+			fun: func(sess *Session, bean interface{}) error {
377
+				a.AfterLoad()
378
+				return nil
379
+			},
380
+			session: session,
381
+			bean:    bean,
382
+		})
383
+	}
384
+
385
+	if a, has := bean.(AfterLoadSessionProcessor); has {
386
+		session.afterProcessors = append(session.afterProcessors, executedProcessor{
387
+			fun: func(sess *Session, bean interface{}) error {
388
+				a.AfterLoad(sess)
389
+				return nil
390
+			},
391
+			session: session,
392
+			bean:    bean,
393
+		})
394
+	}
395
+
360 396
 	var tempMap = make(map[string]int)
361 397
 	var pk core.PK
362 398
 	for ii, key := range fields {

+ 2 - 2
vendor/github.com/go-xorm/xorm/session_delete.go

@@ -184,12 +184,12 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
184 184
 			}
185 185
 		}
186 186
 
187
-		// !oinume! Insert NowTime to the head of session.statement.Params
187
+		// !oinume! Insert nowTime to the head of session.statement.Params
188 188
 		condArgs = append(condArgs, "")
189 189
 		paramsLen := len(condArgs)
190 190
 		copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
191 191
 
192
-		val, t := session.engine.NowTime2(deletedColumn.SQLType.Name)
192
+		val, t := session.engine.nowTime(deletedColumn)
193 193
 		condArgs[0] = val
194 194
 
195 195
 		var colName = deletedColumn.Name

+ 6 - 1
vendor/github.com/go-xorm/xorm/session_find.go

@@ -239,7 +239,12 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
239 239
 		if err != nil {
240 240
 			return err
241 241
 		}
242
-		return session.rows2Beans(rows, fields, len(fields), tb, newElemFunc, containerValueSetFunc)
242
+		err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc)
243
+		rows.Close()
244
+		if err != nil {
245
+			return err
246
+		}
247
+		return session.executeProcessors()
243 248
 	}
244 249
 
245 250
 	for rows.Next() {

+ 7 - 2
vendor/github.com/go-xorm/xorm/session_get.go

@@ -87,7 +87,7 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
87 87
 			return true, err
88 88
 		}
89 89
 
90
-		scanResults, err := session.row2Slice(rows, fields, len(fields), bean)
90
+		scanResults, err := session.row2Slice(rows, fields, bean)
91 91
 		if err != nil {
92 92
 			return false, err
93 93
 		}
@@ -95,7 +95,12 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
95 95
 		rows.Close()
96 96
 
97 97
 		dataStruct := rValue(bean)
98
-		_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, table)
98
+		_, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
99
+		if err != nil {
100
+			return true, err
101
+		}
102
+
103
+		return true, session.executeProcessors()
99 104
 	case reflect.Slice:
100 105
 		err = rows.ScanSlice(bean)
101 106
 	case reflect.Map:

+ 2 - 2
vendor/github.com/go-xorm/xorm/session_insert.go

@@ -126,7 +126,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
126 126
 					}
127 127
 				}
128 128
 				if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
129
-					val, t := session.engine.NowTime2(col.SQLType.Name)
129
+					val, t := session.engine.nowTime(col)
130 130
 					args = append(args, val)
131 131
 
132 132
 					var colName = col.Name
@@ -181,7 +181,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
181 181
 					}
182 182
 				}
183 183
 				if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
184
-					val, t := session.engine.NowTime2(col.SQLType.Name)
184
+					val, t := session.engine.nowTime(col)
185 185
 					args = append(args, val)
186 186
 
187 187
 					var colName = col.Name

+ 50 - 0
vendor/github.com/go-xorm/xorm/session_iterate.go

@@ -23,6 +23,10 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
23 23
 		defer session.Close()
24 24
 	}
25 25
 
26
+	if session.statement.bufferSize > 0 {
27
+		return session.bufferIterate(bean, fun)
28
+	}
29
+
26 30
 	rows, err := session.Rows(bean)
27 31
 	if err != nil {
28 32
 		return err
@@ -44,3 +48,49 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
44 48
 	}
45 49
 	return err
46 50
 }
51
+
52
+// BufferSize sets the buffersize for iterate
53
+func (session *Session) BufferSize(size int) *Session {
54
+	session.statement.bufferSize = size
55
+	return session
56
+}
57
+
58
+func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error {
59
+	if session.isAutoClose {
60
+		defer session.Close()
61
+	}
62
+
63
+	var bufferSize = session.statement.bufferSize
64
+	var limit = session.statement.LimitN
65
+	if limit > 0 && bufferSize > limit {
66
+		bufferSize = limit
67
+	}
68
+	var start = session.statement.Start
69
+	v := rValue(bean)
70
+	sliceType := reflect.SliceOf(v.Type())
71
+	var idx = 0
72
+	for {
73
+		slice := reflect.New(sliceType)
74
+		if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil {
75
+			return err
76
+		}
77
+
78
+		for i := 0; i < slice.Elem().Len(); i++ {
79
+			if err := fun(idx, slice.Elem().Index(i).Addr().Interface()); err != nil {
80
+				return err
81
+			}
82
+			idx++
83
+		}
84
+
85
+		start = start + slice.Elem().Len()
86
+		if limit > 0 && idx+bufferSize > limit {
87
+			bufferSize = limit - idx
88
+		}
89
+
90
+		if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit {
91
+			break
92
+		}
93
+	}
94
+
95
+	return nil
96
+}

+ 1 - 1
vendor/github.com/go-xorm/xorm/session_update.go

@@ -205,7 +205,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
205 205
 		if _, ok := session.statement.columnMap[strings.ToLower(table.Updated)]; !ok {
206 206
 			colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
207 207
 			col := table.UpdatedColumn()
208
-			val, t := session.engine.NowTime2(col.SQLType.Name)
208
+			val, t := session.engine.nowTime(col)
209 209
 			args = append(args, val)
210 210
 
211 211
 			var colName = col.Name

+ 2 - 0
vendor/github.com/go-xorm/xorm/statement.go

@@ -73,6 +73,7 @@ type Statement struct {
73 73
 	decrColumns     map[string]decrParam
74 74
 	exprColumns     map[string]exprParam
75 75
 	cond            builder.Cond
76
+	bufferSize      int
76 77
 }
77 78
 
78 79
 // Init reset all the statement's fields
@@ -111,6 +112,7 @@ func (statement *Statement) Init() {
111 112
 	statement.decrColumns = make(map[string]decrParam)
112 113
 	statement.exprColumns = make(map[string]exprParam)
113 114
 	statement.cond = builder.NewCond()
115
+	statement.bufferSize = 0
114 116
 }
115 117
 
116 118
 // NoAutoCondition if you do not want convert bean's field as query condition, then use this function

+ 3 - 3
vendor/vendor.json

@@ -474,10 +474,10 @@
474 474
 			"revisionTime": "2016-08-11T02:11:45Z"
475 475
 		},
476 476
 		{
477
-			"checksumSHA1": "lAzHeuH461JyawhsGLi27JpWsgs=",
477
+			"checksumSHA1": "+KmPfckyKvrUZPIHBYHylg/7V8o=",
478 478
 			"path": "github.com/go-xorm/xorm",
479
-			"revision": "3101e3bc440f16f151687d97bce94da063c486f5",
480
-			"revisionTime": "2017-09-15T01:51:15Z"
479
+			"revision": "29d4a0330a00b9be468b70e3fb0f74109348c358",
480
+			"revisionTime": "2017-09-30T01:26:13Z"
481 481
 		},
482 482
 		{
483 483
 			"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=",