* use AfterLoad instead of AfterSet on Structs * fix the comments on AfterLoad * fix the comments on action AfterLoadtags/v1.21.12.1
@@ -16,7 +16,6 @@ import ( | |||
"github.com/Unknwon/com" | |||
"github.com/go-xorm/builder" | |||
"github.com/go-xorm/xorm" | |||
"code.gitea.io/git" | |||
api "code.gitea.io/sdk/gitea" | |||
@@ -91,12 +90,9 @@ type Action struct { | |||
CreatedUnix int64 `xorm:"INDEX created"` | |||
} | |||
// AfterSet updates the webhook object upon setting a column. | |||
func (a *Action) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
a.Created = time.Unix(a.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (a *Action) AfterLoad() { | |||
a.Created = time.Unix(a.CreatedUnix, 0).Local() | |||
} | |||
// GetOpType gets the ActionType of this action. | |||
@@ -12,7 +12,6 @@ import ( | |||
"code.gitea.io/gitea/modules/util" | |||
"github.com/Unknwon/com" | |||
"github.com/go-xorm/xorm" | |||
) | |||
//NoticeType describes the notice type | |||
@@ -32,12 +31,9 @@ type Notice struct { | |||
CreatedUnix int64 `xorm:"INDEX created"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (n *Notice) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
n.Created = time.Unix(n.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (n *Notice) AfterLoad() { | |||
n.Created = time.Unix(n.CreatedUnix, 0).Local() | |||
} | |||
// TrStr returns a translation format string. | |||
@@ -12,7 +12,6 @@ import ( | |||
"path" | |||
"time" | |||
"github.com/go-xorm/xorm" | |||
gouuid "github.com/satori/go.uuid" | |||
"code.gitea.io/gitea/modules/setting" | |||
@@ -31,13 +30,10 @@ type Attachment struct { | |||
CreatedUnix int64 `xorm:"created"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of | |||
// AfterLoad is invoked from XORM after setting the value of a field of | |||
// this object. | |||
func (a *Attachment) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
a.Created = time.Unix(a.CreatedUnix, 0).Local() | |||
} | |||
func (a *Attachment) AfterLoad() { | |||
a.Created = time.Unix(a.CreatedUnix, 0).Local() | |||
} | |||
// IncreaseDownloadCount is update download count + 1 | |||
@@ -133,6 +129,10 @@ func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) { | |||
// GetAttachmentsByCommentID returns all attachments if comment by given ID. | |||
func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) { | |||
return getAttachmentsByCommentID(x, commentID) | |||
} | |||
func getAttachmentsByCommentID(e Engine, commentID int64) ([]*Attachment, error) { | |||
attachments := make([]*Attachment, 0, 10) | |||
return attachments, x.Where("comment_id=?", commentID).Find(&attachments) | |||
} | |||
@@ -52,17 +52,15 @@ func (key *GPGKey) BeforeInsert() { | |||
key.CreatedUnix = key.Created.Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (key *GPGKey) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "key_id": | |||
x.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey) | |||
case "added_unix": | |||
key.Added = time.Unix(key.AddedUnix, 0).Local() | |||
case "expired_unix": | |||
key.Expired = time.Unix(key.ExpiredUnix, 0).Local() | |||
case "created_unix": | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (key *GPGKey) AfterLoad(session *xorm.Session) { | |||
key.Added = time.Unix(key.AddedUnix, 0).Local() | |||
key.Expired = time.Unix(key.ExpiredUnix, 0).Local() | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey) | |||
if err != nil { | |||
log.Error(3, "Find Sub GPGkeys[%d]: %v", key.KeyID, err) | |||
} | |||
} | |||
@@ -67,17 +67,12 @@ func (issue *Issue) BeforeUpdate() { | |||
issue.DeadlineUnix = issue.Deadline.Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of | |||
// AfterLoad is invoked from XORM after setting the value of a field of | |||
// this object. | |||
func (issue *Issue) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "deadline_unix": | |||
issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local() | |||
case "created_unix": | |||
issue.Created = time.Unix(issue.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local() | |||
} | |||
func (issue *Issue) AfterLoad() { | |||
issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local() | |||
issue.Created = time.Unix(issue.CreatedUnix, 0).Local() | |||
issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local() | |||
} | |||
func (issue *Issue) loadRepo(e Engine) (err error) { | |||
@@ -112,30 +112,25 @@ type Comment struct { | |||
ShowTag CommentTag `xorm:"-"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (c *Comment) AfterSet(colName string, _ xorm.Cell) { | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (c *Comment) AfterLoad(session *xorm.Session) { | |||
c.Created = time.Unix(c.CreatedUnix, 0).Local() | |||
c.Updated = time.Unix(c.UpdatedUnix, 0).Local() | |||
var err error | |||
switch colName { | |||
case "id": | |||
c.Attachments, err = GetAttachmentsByCommentID(c.ID) | |||
if err != nil { | |||
log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err) | |||
} | |||
c.Attachments, err = getAttachmentsByCommentID(session, c.ID) | |||
if err != nil { | |||
log.Error(3, "getAttachmentsByCommentID[%d]: %v", c.ID, err) | |||
} | |||
case "poster_id": | |||
c.Poster, err = GetUserByID(c.PosterID) | |||
if err != nil { | |||
if IsErrUserNotExist(err) { | |||
c.PosterID = -1 | |||
c.Poster = NewGhostUser() | |||
} else { | |||
log.Error(3, "GetUserByID[%d]: %v", c.ID, err) | |||
} | |||
c.Poster, err = getUserByID(session, c.PosterID) | |||
if err != nil { | |||
if IsErrUserNotExist(err) { | |||
c.PosterID = -1 | |||
c.Poster = NewGhostUser() | |||
} else { | |||
log.Error(3, "getUserByID[%d]: %v", c.ID, err) | |||
} | |||
case "created_unix": | |||
c.Created = time.Unix(c.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
c.Updated = time.Unix(c.UpdatedUnix, 0).Local() | |||
} | |||
} | |||
@@ -51,27 +51,21 @@ func (m *Milestone) BeforeUpdate() { | |||
m.ClosedDateUnix = m.ClosedDate.Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of | |||
// AfterLoad is invoked from XORM after setting the value of a field of | |||
// this object. | |||
func (m *Milestone) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "num_closed_issues": | |||
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues | |||
case "deadline_unix": | |||
m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() | |||
if m.Deadline.Year() == 9999 { | |||
return | |||
} | |||
m.DeadlineString = m.Deadline.Format("2006-01-02") | |||
if time.Now().Local().After(m.Deadline) { | |||
m.IsOverDue = true | |||
} | |||
func (m *Milestone) AfterLoad() { | |||
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues | |||
m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() | |||
if m.Deadline.Year() == 9999 { | |||
return | |||
} | |||
case "closed_date_unix": | |||
m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() | |||
m.DeadlineString = m.Deadline.Format("2006-01-02") | |||
if time.Now().Local().After(m.Deadline) { | |||
m.IsOverDue = true | |||
} | |||
m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() | |||
} | |||
// State returns string representation of milestone status. | |||
@@ -7,8 +7,6 @@ package models | |||
import ( | |||
"fmt" | |||
"time" | |||
"github.com/go-xorm/xorm" | |||
) | |||
// Stopwatch represents a stopwatch for time tracking. | |||
@@ -26,13 +24,9 @@ func (s *Stopwatch) BeforeInsert() { | |||
s.CreatedUnix = time.Now().Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (s *Stopwatch) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
s.Created = time.Unix(s.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (s *Stopwatch) AfterLoad() { | |||
s.Created = time.Unix(s.CreatedUnix, 0).Local() | |||
} | |||
func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { | |||
@@ -8,7 +8,6 @@ import ( | |||
"time" | |||
"github.com/go-xorm/builder" | |||
"github.com/go-xorm/xorm" | |||
) | |||
// TrackedTime represents a time that was spent for a specific issue. | |||
@@ -17,22 +16,13 @@ type TrackedTime struct { | |||
IssueID int64 `xorm:"INDEX" json:"issue_id"` | |||
UserID int64 `xorm:"INDEX" json:"user_id"` | |||
Created time.Time `xorm:"-" json:"created"` | |||
CreatedUnix int64 `json:"-"` | |||
CreatedUnix int64 `xorm:"created" json:"-"` | |||
Time int64 `json:"time"` | |||
} | |||
// BeforeInsert will be invoked by XORM before inserting a record | |||
// representing this object. | |||
func (t *TrackedTime) BeforeInsert() { | |||
t.CreatedUnix = time.Now().Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (t *TrackedTime) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (t *TrackedTime) AfterLoad() { | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
} | |||
// FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored. | |||
@@ -3,8 +3,6 @@ package models | |||
import ( | |||
"errors" | |||
"time" | |||
"github.com/go-xorm/xorm" | |||
) | |||
// LFSMetaObject stores metadata for LFS tracked files. | |||
@@ -109,10 +107,7 @@ func RemoveLFSMetaObjectByOid(oid string) error { | |||
return sess.Commit() | |||
} | |||
// AfterSet stores the LFSMetaObject creation time in the database as local time. | |||
func (m *LFSMetaObject) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
m.Created = time.Unix(m.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad stores the LFSMetaObject creation time in the database as local time. | |||
func (m *LFSMetaObject) AfterLoad() { | |||
m.Created = time.Unix(m.CreatedUnix, 0).Local() | |||
} |
@@ -183,14 +183,10 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | |||
} | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (source *LoginSource) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
source.Created = time.Unix(source.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
source.Updated = time.Unix(source.UpdatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (source *LoginSource) AfterLoad() { | |||
source.Created = time.Unix(source.CreatedUnix, 0).Local() | |||
source.Updated = time.Unix(source.UpdatedUnix, 0).Local() | |||
} | |||
// TypeName return name of this login source type. | |||
@@ -80,17 +80,14 @@ func (pr *PullRequest) BeforeUpdate() { | |||
pr.MergedUnix = pr.Merged.Unix() | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
// Note: don't try to get Issue because will end up recursive querying. | |||
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "merged_unix": | |||
if !pr.HasMerged { | |||
return | |||
} | |||
pr.Merged = time.Unix(pr.MergedUnix, 0).Local() | |||
func (pr *PullRequest) AfterLoad() { | |||
if !pr.HasMerged { | |||
return | |||
} | |||
pr.Merged = time.Unix(pr.MergedUnix, 0).Local() | |||
} | |||
// Note: don't try to get Issue because will end up recursive querying. | |||
@@ -15,7 +15,6 @@ import ( | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/sdk/gitea" | |||
"github.com/go-xorm/builder" | |||
"github.com/go-xorm/xorm" | |||
) | |||
// Release represents a release of repository. | |||
@@ -50,12 +49,9 @@ func (r *Release) BeforeInsert() { | |||
} | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (r *Release) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
r.Created = time.Unix(r.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (r *Release) AfterLoad() { | |||
r.Created = time.Unix(r.CreatedUnix, 0).Local() | |||
} | |||
func (r *Release) loadAttributes(e Engine) error { | |||
@@ -216,25 +216,18 @@ type Repository struct { | |||
UpdatedUnix int64 `xorm:"INDEX updated"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "default_branch": | |||
// FIXME: use models migration to solve all at once. | |||
if len(repo.DefaultBranch) == 0 { | |||
repo.DefaultBranch = "master" | |||
} | |||
case "num_closed_issues": | |||
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | |||
case "num_closed_pulls": | |||
repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls | |||
case "num_closed_milestones": | |||
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones | |||
case "created_unix": | |||
repo.Created = time.Unix(repo.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
repo.Updated = time.Unix(repo.UpdatedUnix, 0) | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (repo *Repository) AfterLoad() { | |||
// FIXME: use models migration to solve all at once. | |||
if len(repo.DefaultBranch) == 0 { | |||
repo.DefaultBranch = "master" | |||
} | |||
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | |||
repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls | |||
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones | |||
repo.Created = time.Unix(repo.CreatedUnix, 0).Local() | |||
repo.Updated = time.Unix(repo.UpdatedUnix, 0) | |||
} | |||
// MustOwner always returns a valid *User object to avoid | |||
@@ -55,24 +55,20 @@ func (m *Mirror) BeforeUpdate() { | |||
} | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (m *Mirror) AfterSet(colName string, _ xorm.Cell) { | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (m *Mirror) AfterLoad(session *xorm.Session) { | |||
if m == nil { | |||
return | |||
} | |||
var err error | |||
switch colName { | |||
case "repo_id": | |||
m.Repo, err = GetRepositoryByID(m.RepoID) | |||
if err != nil { | |||
log.Error(3, "GetRepositoryByID[%d]: %v", m.ID, err) | |||
} | |||
case "updated_unix": | |||
m.Updated = time.Unix(m.UpdatedUnix, 0).Local() | |||
case "next_update_unix": | |||
m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local() | |||
m.Repo, err = getRepositoryByID(session, m.RepoID) | |||
if err != nil { | |||
log.Error(3, "getRepositoryByID[%d]: %v", m.ID, err) | |||
} | |||
m.Updated = time.Unix(m.UpdatedUnix, 0).Local() | |||
m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local() | |||
} | |||
// ScheduleNextUpdate calculates and sets next update time. | |||
@@ -106,12 +106,9 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { | |||
} | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (r *RepoUnit) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
r.Created = time.Unix(r.CreatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (r *RepoUnit) AfterLoad() { | |||
r.Created = time.Unix(r.CreatedUnix, 0).Local() | |||
} | |||
// Unit returns Unit | |||
@@ -56,22 +56,18 @@ type PublicKey struct { | |||
Created time.Time `xorm:"-"` | |||
CreatedUnix int64 `xorm:"created"` | |||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. | |||
Updated time.Time `xorm:"-"` | |||
UpdatedUnix int64 `xorm:"updated"` | |||
HasRecentActivity bool `xorm:"-"` | |||
HasUsed bool `xorm:"-"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (key *PublicKey) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
key.Updated = time.Unix(key.UpdatedUnix, 0).Local() | |||
key.HasUsed = key.Updated.After(key.Created) | |||
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (key *PublicKey) AfterLoad() { | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
key.Updated = time.Unix(key.UpdatedUnix, 0).Local() | |||
key.HasUsed = key.Updated.After(key.Created) | |||
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// OmitEmail returns content of public key without email address. | |||
@@ -612,22 +608,18 @@ type DeployKey struct { | |||
Created time.Time `xorm:"-"` | |||
CreatedUnix int64 `xorm:"created"` | |||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. | |||
Updated time.Time `xorm:"-"` | |||
UpdatedUnix int64 `xorm:"updated"` | |||
HasRecentActivity bool `xorm:"-"` | |||
HasUsed bool `xorm:"-"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (key *DeployKey) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
key.Updated = time.Unix(key.UpdatedUnix, 0).Local() | |||
key.HasUsed = key.Updated.After(key.Created) | |||
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (key *DeployKey) AfterLoad() { | |||
key.Created = time.Unix(key.CreatedUnix, 0).Local() | |||
key.Updated = time.Unix(key.UpdatedUnix, 0).Local() | |||
key.HasUsed = key.Updated.After(key.Created) | |||
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// GetContent gets associated public key content. | |||
@@ -71,15 +71,11 @@ type CommitStatus struct { | |||
UpdatedUnix int64 `xorm:"INDEX updated"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of | |||
// AfterLoad is invoked from XORM after setting the value of a field of | |||
// this object. | |||
func (status *CommitStatus) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
status.Created = time.Unix(status.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
status.Updated = time.Unix(status.UpdatedUnix, 0).Local() | |||
} | |||
func (status *CommitStatus) AfterLoad() { | |||
status.Created = time.Unix(status.CreatedUnix, 0).Local() | |||
status.Updated = time.Unix(status.UpdatedUnix, 0).Local() | |||
} | |||
func (status *CommitStatus) loadRepo(e Engine) (err error) { | |||
@@ -7,7 +7,6 @@ package models | |||
import ( | |||
"time" | |||
"github.com/go-xorm/xorm" | |||
gouuid "github.com/satori/go.uuid" | |||
"code.gitea.io/gitea/modules/base" | |||
@@ -22,22 +21,18 @@ type AccessToken struct { | |||
Created time.Time `xorm:"-"` | |||
CreatedUnix int64 `xorm:"INDEX created"` | |||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. | |||
Updated time.Time `xorm:"-"` | |||
UpdatedUnix int64 `xorm:"INDEX updated"` | |||
HasRecentActivity bool `xorm:"-"` | |||
HasUsed bool `xorm:"-"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
t.Updated = time.Unix(t.UpdatedUnix, 0).Local() | |||
t.HasUsed = t.Updated.After(t.Created) | |||
t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (t *AccessToken) AfterLoad() { | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
t.Updated = time.Unix(t.UpdatedUnix, 0).Local() | |||
t.HasUsed = t.Updated.After(t.Created) | |||
t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now()) | |||
} | |||
// NewAccessToken creates new access token. | |||
@@ -11,7 +11,6 @@ import ( | |||
"time" | |||
"github.com/Unknwon/com" | |||
"github.com/go-xorm/xorm" | |||
"github.com/pquerna/otp/totp" | |||
"code.gitea.io/gitea/modules/base" | |||
@@ -27,18 +26,14 @@ type TwoFactor struct { | |||
Created time.Time `xorm:"-"` | |||
CreatedUnix int64 `xorm:"INDEX created"` | |||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. | |||
Updated time.Time `xorm:"-"` | |||
UpdatedUnix int64 `xorm:"INDEX updated"` | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (t *TwoFactor) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
t.Updated = time.Unix(t.UpdatedUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (t *TwoFactor) AfterLoad() { | |||
t.Created = time.Unix(t.CreatedUnix, 0).Local() | |||
t.Updated = time.Unix(t.UpdatedUnix, 0).Local() | |||
} | |||
// GenerateScratchToken recreates the scratch token the user is using. | |||
@@ -153,16 +153,11 @@ func (u *User) UpdateDiffViewStyle(style string) error { | |||
return UpdateUserCols(u, "diff_view_style") | |||
} | |||
// AfterSet is invoked from XORM after setting the value of a field of this object. | |||
func (u *User) AfterSet(colName string, _ xorm.Cell) { | |||
switch colName { | |||
case "created_unix": | |||
u.Created = time.Unix(u.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
u.Updated = time.Unix(u.UpdatedUnix, 0).Local() | |||
case "last_login_unix": | |||
u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local() | |||
} | |||
// AfterLoad is invoked from XORM after setting the values of all fields of this object. | |||
func (u *User) AfterLoad() { | |||
u.Created = time.Unix(u.CreatedUnix, 0).Local() | |||
u.Updated = time.Unix(u.UpdatedUnix, 0).Local() | |||
u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local() | |||
} | |||
// getEmail returns an noreply email, if the user has set to keep his | |||
@@ -19,7 +19,6 @@ import ( | |||
"code.gitea.io/gitea/modules/sync" | |||
api "code.gitea.io/sdk/gitea" | |||
"github.com/go-xorm/xorm" | |||
gouuid "github.com/satori/go.uuid" | |||
) | |||
@@ -112,20 +111,15 @@ type Webhook struct { | |||
UpdatedUnix int64 `xorm:"INDEX updated"` | |||
} | |||
// AfterSet updates the webhook object upon setting a column | |||
func (w *Webhook) AfterSet(colName string, _ xorm.Cell) { | |||
var err error | |||
switch colName { | |||
case "events": | |||
w.HookEvent = &HookEvent{} | |||
if err = json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { | |||
log.Error(3, "Unmarshal[%d]: %v", w.ID, err) | |||
} | |||
case "created_unix": | |||
w.Created = time.Unix(w.CreatedUnix, 0).Local() | |||
case "updated_unix": | |||
w.Updated = time.Unix(w.UpdatedUnix, 0).Local() | |||
// AfterLoad updates the webhook object upon setting a column | |||
func (w *Webhook) AfterLoad() { | |||
w.HookEvent = &HookEvent{} | |||
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { | |||
log.Error(3, "Unmarshal[%d]: %v", w.ID, err) | |||
} | |||
w.Created = time.Unix(w.CreatedUnix, 0).Local() | |||
w.Updated = time.Unix(w.UpdatedUnix, 0).Local() | |||
} | |||
// GetSlackHook returns slack metadata | |||
@@ -432,32 +426,17 @@ func (t *HookTask) BeforeUpdate() { | |||
} | |||
} | |||
// AfterSet updates the webhook object upon setting a column | |||
func (t *HookTask) AfterSet(colName string, _ xorm.Cell) { | |||
var err error | |||
switch colName { | |||
case "delivered": | |||
t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST") | |||
case "request_content": | |||
if len(t.RequestContent) == 0 { | |||
return | |||
} | |||
t.RequestInfo = &HookRequest{} | |||
if err = json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil { | |||
log.Error(3, "Unmarshal[%d]: %v", t.ID, err) | |||
} | |||
// AfterLoad updates the webhook object upon setting a column | |||
func (t *HookTask) AfterLoad() { | |||
t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST") | |||
case "response_content": | |||
if len(t.ResponseContent) == 0 { | |||
return | |||
} | |||
if len(t.RequestContent) == 0 { | |||
return | |||
} | |||
t.ResponseInfo = &HookResponse{} | |||
if err = json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil { | |||
log.Error(3, "Unmarshal [%d]: %v", t.ID, err) | |||
} | |||
t.RequestInfo = &HookRequest{} | |||
if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil { | |||
log.Error(3, "Unmarshal[%d]: %v", t.ID, err) | |||
} | |||
} | |||
@@ -1516,10 +1516,14 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) { | |||
return results, lastError | |||
} | |||
// NowTime2 return current time | |||
func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) { | |||
// nowTime return current time | |||
func (engine *Engine) nowTime(col *core.Column) (interface{}, time.Time) { | |||
t := time.Now() | |||
return engine.formatTime(sqlTypeName, t.In(engine.DatabaseTZ)), t.In(engine.TZLocation) | |||
var tz = engine.DatabaseTZ | |||
if !col.DisableTimeZone && col.TimeZone != nil { | |||
tz = col.TimeZone | |||
} | |||
return engine.formatTime(col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation) | |||
} | |||
func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) { | |||
@@ -1574,3 +1578,10 @@ func (engine *Engine) CondDeleted(colName string) builder.Cond { | |||
} | |||
return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1}) | |||
} | |||
// BufferSize sets buffer size for iterate | |||
func (engine *Engine) BufferSize(size int) *Session { | |||
session := engine.NewSession() | |||
session.isAutoClose = true | |||
return session.BufferSize(size) | |||
} |
@@ -422,7 +422,7 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, | |||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { | |||
// if time is non-empty, then set to auto time | |||
val, t := session.engine.NowTime2(col.SQLType.Name) | |||
val, t := session.engine.nowTime(col) | |||
args = append(args, val) | |||
var colName = col.Name | |||
@@ -29,13 +29,6 @@ type AfterSetProcessor interface { | |||
AfterSet(string, Cell) | |||
} | |||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations | |||
//// Executed before an object is validated | |||
//type BeforeValidateProcessor interface { | |||
// BeforeValidate() | |||
//} | |||
// -- | |||
// AfterInsertProcessor executed after an object is persisted to the database | |||
type AfterInsertProcessor interface { | |||
AfterInsert() | |||
@@ -50,3 +43,36 @@ type AfterUpdateProcessor interface { | |||
type AfterDeleteProcessor interface { | |||
AfterDelete() | |||
} | |||
// AfterLoadProcessor executed after an ojbect has been loaded from database | |||
type AfterLoadProcessor interface { | |||
AfterLoad() | |||
} | |||
// AfterLoadSessionProcessor executed after an ojbect has been loaded from database with session parameter | |||
type AfterLoadSessionProcessor interface { | |||
AfterLoad(*Session) | |||
} | |||
type executedProcessorFunc func(*Session, interface{}) error | |||
type executedProcessor struct { | |||
fun executedProcessorFunc | |||
session *Session | |||
bean interface{} | |||
} | |||
func (executor *executedProcessor) execute() error { | |||
return executor.fun(executor.session, executor.bean) | |||
} | |||
func (session *Session) executeProcessors() error { | |||
processors := session.afterProcessors | |||
session.afterProcessors = make([]executedProcessor, 0) | |||
for _, processor := range processors { | |||
if err := processor.execute(); err != nil { | |||
return err | |||
} | |||
} | |||
return nil | |||
} |
@@ -99,13 +99,17 @@ func (rows *Rows) Scan(bean interface{}) error { | |||
return err | |||
} | |||
scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, len(rows.fields), bean) | |||
scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, bean) | |||
if err != nil { | |||
return err | |||
} | |||
_, err = rows.session.slice2Bean(scanResults, rows.fields, len(rows.fields), bean, &dataStruct, rows.session.statement.RefTable) | |||
return err | |||
_, err = rows.session.slice2Bean(scanResults, rows.fields, bean, &dataStruct, rows.session.statement.RefTable) | |||
if err != nil { | |||
return err | |||
} | |||
return rows.session.executeProcessors() | |||
} | |||
// Close session if session.IsAutoClose is true, and claimed any opened resources | |||
@@ -41,6 +41,8 @@ type Session struct { | |||
beforeClosures []func(interface{}) | |||
afterClosures []func(interface{}) | |||
afterProcessors []executedProcessor | |||
prepareStmt bool | |||
stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr)) | |||
@@ -75,6 +77,8 @@ func (session *Session) Init() { | |||
session.beforeClosures = make([]func(interface{}), 0) | |||
session.afterClosures = make([]func(interface{}), 0) | |||
session.afterProcessors = make([]executedProcessor, 0) | |||
session.lastSQL = "" | |||
session.lastSQLArgs = []interface{}{} | |||
} | |||
@@ -296,37 +300,40 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c | |||
// Cell cell is a result of one column field | |||
type Cell *interface{} | |||
func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int, | |||
func (session *Session) rows2Beans(rows *core.Rows, fields []string, | |||
table *core.Table, newElemFunc func([]string) reflect.Value, | |||
sliceValueSetFunc func(*reflect.Value, core.PK) error) error { | |||
for rows.Next() { | |||
var newValue = newElemFunc(fields) | |||
bean := newValue.Interface() | |||
dataStruct := rValue(bean) | |||
dataStruct := newValue.Elem() | |||
// handle beforeClosures | |||
scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean) | |||
scanResults, err := session.row2Slice(rows, fields, bean) | |||
if err != nil { | |||
return err | |||
} | |||
pk, err := session.slice2Bean(scanResults, fields, fieldsCount, bean, &dataStruct, table) | |||
if err != nil { | |||
return err | |||
} | |||
err = sliceValueSetFunc(&newValue, pk) | |||
pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table) | |||
if err != nil { | |||
return err | |||
} | |||
session.afterProcessors = append(session.afterProcessors, executedProcessor{ | |||
fun: func(*Session, interface{}) error { | |||
return sliceValueSetFunc(&newValue, pk) | |||
}, | |||
session: session, | |||
bean: bean, | |||
}) | |||
} | |||
return nil | |||
} | |||
func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) ([]interface{}, error) { | |||
func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) { | |||
for _, closure := range session.beforeClosures { | |||
closure(bean) | |||
} | |||
scanResults := make([]interface{}, fieldsCount) | |||
scanResults := make([]interface{}, len(fields)) | |||
for i := 0; i < len(fields); i++ { | |||
var cell interface{} | |||
scanResults[i] = &cell | |||
@@ -343,20 +350,49 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount | |||
return scanResults, nil | |||
} | |||
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { | |||
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { | |||
defer func() { | |||
if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet { | |||
for ii, key := range fields { | |||
b.AfterSet(key, Cell(scanResults[ii].(*interface{}))) | |||
} | |||
} | |||
// handle afterClosures | |||
for _, closure := range session.afterClosures { | |||
closure(bean) | |||
} | |||
}() | |||
// handle afterClosures | |||
for _, closure := range session.afterClosures { | |||
session.afterProcessors = append(session.afterProcessors, executedProcessor{ | |||
fun: func(sess *Session, bean interface{}) error { | |||
closure(bean) | |||
return nil | |||
}, | |||
session: session, | |||
bean: bean, | |||
}) | |||
} | |||
if a, has := bean.(AfterLoadProcessor); has { | |||
session.afterProcessors = append(session.afterProcessors, executedProcessor{ | |||
fun: func(sess *Session, bean interface{}) error { | |||
a.AfterLoad() | |||
return nil | |||
}, | |||
session: session, | |||
bean: bean, | |||
}) | |||
} | |||
if a, has := bean.(AfterLoadSessionProcessor); has { | |||
session.afterProcessors = append(session.afterProcessors, executedProcessor{ | |||
fun: func(sess *Session, bean interface{}) error { | |||
a.AfterLoad(sess) | |||
return nil | |||
}, | |||
session: session, | |||
bean: bean, | |||
}) | |||
} | |||
var tempMap = make(map[string]int) | |||
var pk core.PK | |||
for ii, key := range fields { | |||
@@ -184,12 +184,12 @@ func (session *Session) Delete(bean interface{}) (int64, error) { | |||
} | |||
} | |||
// !oinume! Insert NowTime to the head of session.statement.Params | |||
// !oinume! Insert nowTime to the head of session.statement.Params | |||
condArgs = append(condArgs, "") | |||
paramsLen := len(condArgs) | |||
copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1]) | |||
val, t := session.engine.NowTime2(deletedColumn.SQLType.Name) | |||
val, t := session.engine.nowTime(deletedColumn) | |||
condArgs[0] = val | |||
var colName = deletedColumn.Name | |||
@@ -239,7 +239,12 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va | |||
if err != nil { | |||
return err | |||
} | |||
return session.rows2Beans(rows, fields, len(fields), tb, newElemFunc, containerValueSetFunc) | |||
err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc) | |||
rows.Close() | |||
if err != nil { | |||
return err | |||
} | |||
return session.executeProcessors() | |||
} | |||
for rows.Next() { | |||
@@ -87,7 +87,7 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea | |||
return true, err | |||
} | |||
scanResults, err := session.row2Slice(rows, fields, len(fields), bean) | |||
scanResults, err := session.row2Slice(rows, fields, bean) | |||
if err != nil { | |||
return false, err | |||
} | |||
@@ -95,7 +95,12 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea | |||
rows.Close() | |||
dataStruct := rValue(bean) | |||
_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, table) | |||
_, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table) | |||
if err != nil { | |||
return true, err | |||
} | |||
return true, session.executeProcessors() | |||
case reflect.Slice: | |||
err = rows.ScanSlice(bean) | |||
case reflect.Map: | |||
@@ -126,7 +126,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | |||
} | |||
} | |||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { | |||
val, t := session.engine.NowTime2(col.SQLType.Name) | |||
val, t := session.engine.nowTime(col) | |||
args = append(args, val) | |||
var colName = col.Name | |||
@@ -181,7 +181,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | |||
} | |||
} | |||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { | |||
val, t := session.engine.NowTime2(col.SQLType.Name) | |||
val, t := session.engine.nowTime(col) | |||
args = append(args, val) | |||
var colName = col.Name | |||
@@ -23,6 +23,10 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error { | |||
defer session.Close() | |||
} | |||
if session.statement.bufferSize > 0 { | |||
return session.bufferIterate(bean, fun) | |||
} | |||
rows, err := session.Rows(bean) | |||
if err != nil { | |||
return err | |||
@@ -44,3 +48,49 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error { | |||
} | |||
return err | |||
} | |||
// BufferSize sets the buffersize for iterate | |||
func (session *Session) BufferSize(size int) *Session { | |||
session.statement.bufferSize = size | |||
return session | |||
} | |||
func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { | |||
if session.isAutoClose { | |||
defer session.Close() | |||
} | |||
var bufferSize = session.statement.bufferSize | |||
var limit = session.statement.LimitN | |||
if limit > 0 && bufferSize > limit { | |||
bufferSize = limit | |||
} | |||
var start = session.statement.Start | |||
v := rValue(bean) | |||
sliceType := reflect.SliceOf(v.Type()) | |||
var idx = 0 | |||
for { | |||
slice := reflect.New(sliceType) | |||
if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil { | |||
return err | |||
} | |||
for i := 0; i < slice.Elem().Len(); i++ { | |||
if err := fun(idx, slice.Elem().Index(i).Addr().Interface()); err != nil { | |||
return err | |||
} | |||
idx++ | |||
} | |||
start = start + slice.Elem().Len() | |||
if limit > 0 && idx+bufferSize > limit { | |||
bufferSize = limit - idx | |||
} | |||
if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit { | |||
break | |||
} | |||
} | |||
return nil | |||
} |
@@ -205,7 +205,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | |||
if _, ok := session.statement.columnMap[strings.ToLower(table.Updated)]; !ok { | |||
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?") | |||
col := table.UpdatedColumn() | |||
val, t := session.engine.NowTime2(col.SQLType.Name) | |||
val, t := session.engine.nowTime(col) | |||
args = append(args, val) | |||
var colName = col.Name | |||
@@ -73,6 +73,7 @@ type Statement struct { | |||
decrColumns map[string]decrParam | |||
exprColumns map[string]exprParam | |||
cond builder.Cond | |||
bufferSize int | |||
} | |||
// Init reset all the statement's fields | |||
@@ -111,6 +112,7 @@ func (statement *Statement) Init() { | |||
statement.decrColumns = make(map[string]decrParam) | |||
statement.exprColumns = make(map[string]exprParam) | |||
statement.cond = builder.NewCond() | |||
statement.bufferSize = 0 | |||
} | |||
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function | |||
@@ -474,10 +474,10 @@ | |||
"revisionTime": "2016-08-11T02:11:45Z" | |||
}, | |||
{ | |||
"checksumSHA1": "lAzHeuH461JyawhsGLi27JpWsgs=", | |||
"checksumSHA1": "+KmPfckyKvrUZPIHBYHylg/7V8o=", | |||
"path": "github.com/go-xorm/xorm", | |||
"revision": "3101e3bc440f16f151687d97bce94da063c486f5", | |||
"revisionTime": "2017-09-15T01:51:15Z" | |||
"revision": "29d4a0330a00b9be468b70e3fb0f74109348c358", | |||
"revisionTime": "2017-09-30T01:26:13Z" | |||
}, | |||
{ | |||
"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=", | |||