From ad513a20e939691828ba415c9a565e8ff3daa95f Mon Sep 17 00:00:00 2001 From: Unknwon Date: Wed, 9 Mar 2016 19:53:30 -0500 Subject: [PATCH] #2302 Replace time.Time with Unix Timestamp (int64) --- README.md | 2 +- conf/locale/TRANSLATORS | 1 + gogs.go | 2 +- models/action.go | 11 +- models/admin.go | 15 ++- models/issue.go | 74 ++++++++--- models/issue_comment.go | 16 ++- models/login.go | 25 +++- models/migrations/migrations.go | 220 ++++++++++++++++++++++++++++++++ models/models.go | 24 ---- models/pull.go | 13 +- models/release.go | 12 +- models/repo.go | 49 +++++-- models/repo_collaboration.go | 10 +- models/ssh_key.go | 74 +++++++---- models/token.go | 46 ++++--- models/user.go | 23 +++- models/webhook.go | 22 +++- templates/.VERSION | 2 +- 19 files changed, 516 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index 9597da4ce36..664a3ca2341 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) -##### Current version: 0.9.1 +##### Current version: 0.9.2 | Web | UI | Preview | |:-------------:|:-------:|:-------:| diff --git a/conf/locale/TRANSLATORS b/conf/locale/TRANSLATORS index 5c8d9308925..dec40cf0c90 100644 --- a/conf/locale/TRANSLATORS +++ b/conf/locale/TRANSLATORS @@ -26,6 +26,7 @@ Hamid Feizabadi Huimin Wang ilko Ilya Makarov +Robert Nuske Robin Hübner Jamie Mansfield Jean THOMAS diff --git a/gogs.go b/gogs.go index 1a18d4a55bb..77fa1a97c38 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.9.1.0306" +const APP_VER = "0.9.2.0309" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/action.go b/models/action.go index f83b9ad898d..91d43bae993 100644 --- a/models/action.go +++ b/models/action.go @@ -84,13 +84,18 @@ type Action struct { RefName string IsPrivate bool `xorm:"NOT NULL DEFAULT false"` Content string `xorm:"TEXT"` - Created time.Time `xorm:"created"` + Created time.Time `xorm:"-"` + CreatedUnix int64 +} + +func (a *Action) BeforeInsert() { + a.CreatedUnix = time.Now().UTC().Unix() } func (a *Action) AfterSet(colName string, _ xorm.Cell) { switch colName { - case "created": - a.Created = regulateTimeZone(a.Created) + case "created_unix": + a.Created = time.Unix(a.CreatedUnix, 0).Local() } } diff --git a/models/admin.go b/models/admin.go index 7756cd6ae25..d9e8e529edb 100644 --- a/models/admin.go +++ b/models/admin.go @@ -12,6 +12,7 @@ import ( "time" "github.com/Unknwon/com" + "github.com/go-xorm/xorm" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" @@ -29,7 +30,19 @@ type Notice struct { ID int64 `xorm:"pk autoincr"` Type NoticeType Description string `xorm:"TEXT"` - Created time.Time `xorm:"CREATED"` + Created time.Time `xorm:"-"` + CreatedUnix int64 +} + +func (n *Notice) BeforeInsert() { + n.CreatedUnix = time.Now().UTC().Unix() +} + +func (n *Notice) AfterSet(colName string, _ xorm.Cell) { + switch colName { + case "created_unix": + n.Created = time.Unix(n.CreatedUnix, 0).Local() + } } // TrStr returns a translation format string. diff --git a/models/issue.go b/models/issue.go index 7f1889b3610..9dcff15a3f1 100644 --- a/models/issue.go +++ b/models/issue.go @@ -52,14 +52,28 @@ type Issue struct { RenderedContent string `xorm:"-"` Priority int NumComments int - Deadline time.Time - Created time.Time `xorm:"CREATED"` - Updated time.Time `xorm:"UPDATED"` + + Deadline time.Time `xorm:"-"` + DeadlineUnix int64 + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` + UpdatedUnix int64 Attachments []*Attachment `xorm:"-"` Comments []*Comment `xorm:"-"` } +func (i *Issue) BeforeInsert() { + i.CreatedUnix = time.Now().UTC().Unix() + i.UpdatedUnix = i.CreatedUnix +} + +func (i *Issue) BeforeUpdate() { + i.UpdatedUnix = time.Now().UTC().Unix() + i.DeadlineUnix = i.Deadline.UTC().Unix() +} + func (i *Issue) AfterSet(colName string, _ xorm.Cell) { var err error switch colName { @@ -92,8 +106,12 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) { if err != nil { log.Error(3, "GetUserByID[%d]: %v", i.ID, err) } - case "created": - i.Created = regulateTimeZone(i.Created) + case "deadline_unix": + i.Deadline = time.Unix(i.DeadlineUnix, 0).Local() + case "created_unix": + i.Created = time.Unix(i.CreatedUnix, 0).Local() + case "updated_unix": + i.Updated = time.Unix(i.UpdatedUnix, 0).Local() } } @@ -951,12 +969,19 @@ type Milestone struct { IsClosed bool NumIssues int NumClosedIssues int - NumOpenIssues int `xorm:"-"` - Completeness int // Percentage(1-100). - Deadline time.Time - DeadlineString string `xorm:"-"` - IsOverDue bool `xorm:"-"` - ClosedDate time.Time + NumOpenIssues int `xorm:"-"` + Completeness int // Percentage(1-100). + IsOverDue bool `xorm:"-"` + + DeadlineString string `xorm:"-"` + Deadline time.Time `xorm:"-"` + DeadlineUnix int64 + ClosedDate time.Time `xorm:"-"` + ClosedDateUnix int64 +} + +func (m *Milestone) BeforeInsert() { + m.DeadlineUnix = m.Deadline.UTC().Unix() } func (m *Milestone) BeforeUpdate() { @@ -965,19 +990,25 @@ func (m *Milestone) BeforeUpdate() { } else { m.Completeness = 0 } + + m.DeadlineUnix = m.Deadline.UTC().Unix() + m.ClosedDateUnix = m.ClosedDate.UTC().Unix() } func (m *Milestone) AfterSet(colName string, _ xorm.Cell) { - if colName == "deadline" { + switch colName { + case "deadline_unix": + m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() if m.Deadline.Year() == 9999 { return } - m.Deadline = regulateTimeZone(m.Deadline) m.DeadlineString = m.Deadline.Format("2006-01-02") - if time.Now().After(m.Deadline) { + if time.Now().Local().After(m.Deadline) { m.IsOverDue = true } + case "closed_date_unix": + m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() } } @@ -1252,7 +1283,20 @@ type Attachment struct { CommentID int64 ReleaseID int64 `xorm:"INDEX"` Name string - Created time.Time `xorm:"CREATED"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 +} + +func (a *Attachment) BeforeInsert() { + a.CreatedUnix = time.Now().UTC().Unix() +} + +func (a *Attachment) AfterSet(colName string, _ xorm.Cell) { + switch colName { + case "created_unix": + a.Created = time.Unix(a.CreatedUnix, 0).Local() + } } // AttachmentLocalPath returns where attachment is stored in local file system based on given UUID. diff --git a/models/issue_comment.go b/models/issue_comment.go index e63b39085ba..ef890fd2fc2 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -52,9 +52,11 @@ type Comment struct { IssueID int64 `xorm:"INDEX"` CommitID int64 Line int64 - Content string `xorm:"TEXT"` - RenderedContent string `xorm:"-"` - Created time.Time `xorm:"CREATED"` + Content string `xorm:"TEXT"` + RenderedContent string `xorm:"-"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 // Reference issue in commit message CommitSHA string `xorm:"VARCHAR(40)"` @@ -65,6 +67,10 @@ type Comment struct { ShowTag CommentTag `xorm:"-"` } +func (c *Comment) BeforeInsert() { + c.CreatedUnix = time.Now().UTC().Unix() +} + func (c *Comment) AfterSet(colName string, _ xorm.Cell) { var err error switch colName { @@ -84,8 +90,8 @@ func (c *Comment) AfterSet(colName string, _ xorm.Cell) { log.Error(3, "GetUserByID[%d]: %v", c.ID, err) } } - case "created": - c.Created = regulateTimeZone(c.Created) + case "created_unix": + c.Created = time.Unix(c.CreatedUnix, 0).Local() } } diff --git a/models/login.go b/models/login.go index cbad646d1ed..6ed4fefbdf5 100644 --- a/models/login.go +++ b/models/login.go @@ -101,8 +101,20 @@ type LoginSource struct { Name string `xorm:"UNIQUE"` IsActived bool `xorm:"NOT NULL DEFAULT false"` Cfg core.Conversion `xorm:"TEXT"` - Created time.Time `xorm:"CREATED"` - Updated time.Time `xorm:"UPDATED"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` + UpdatedUnix int64 +} + +func (s *LoginSource) BeforeInsert() { + s.CreatedUnix = time.Now().UTC().Unix() + s.UpdatedUnix = s.CreatedUnix +} + +func (s *LoginSource) BeforeUpdate() { + s.UpdatedUnix = time.Now().UTC().Unix() } // Cell2Int64 converts a xorm.Cell type to int64, @@ -132,6 +144,15 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { } } +func (s *LoginSource) AfterSet(colName string, _ xorm.Cell) { + switch colName { + case "created_unix": + s.Created = time.Unix(s.CreatedUnix, 0).Local() + case "updated_unix": + s.Updated = time.Unix(s.UpdatedUnix, 0).Local() + } +} + func (source *LoginSource) TypeName() string { return LoginNames[source.Type] } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index c8e399e15a9..83314909948 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -13,6 +13,7 @@ import ( "path" "path/filepath" "strings" + "time" "github.com/Unknwon/com" "github.com/go-xorm/xorm" @@ -65,6 +66,7 @@ var migrations = []Migration{ NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16 NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo), // V9 -> V10:v0.6.20 NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5 + NewMigration("convert date to unix timestamp", convertDateToUnix), // V11 -> V12:v0.9.2 } // Migrate database to current version @@ -453,3 +455,221 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) { return sess.Commit() } + +type TAction struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 +} + +func (t *TAction) TableName() string { return "action" } + +type TNotice struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 +} + +func (t *TNotice) TableName() string { return "notice" } + +type TComment struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 +} + +func (t *TComment) TableName() string { return "comment" } + +type TIssue struct { + ID int64 `xorm:"pk autoincr"` + DeadlineUnix int64 + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TIssue) TableName() string { return "issue" } + +type TMilestone struct { + ID int64 `xorm:"pk autoincr"` + DeadlineUnix int64 + ClosedDateUnix int64 +} + +func (t *TMilestone) TableName() string { return "milestone" } + +type TAttachment struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 +} + +func (t *TAttachment) TableName() string { return "attachment" } + +type TLoginSource struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TLoginSource) TableName() string { return "login_source" } + +type TPull struct { + ID int64 `xorm:"pk autoincr"` + MergedUnix int64 +} + +func (t *TPull) TableName() string { return "pull_request" } + +type TRelease struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 +} + +func (t *TRelease) TableName() string { return "release" } + +type TRepo struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TRepo) TableName() string { return "repository" } + +type TMirror struct { + ID int64 `xorm:"pk autoincr"` + UpdatedUnix int64 + NextUpdateUnix int64 +} + +func (t *TMirror) TableName() string { return "mirror" } + +type TPublicKey struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TPublicKey) TableName() string { return "public_key" } + +type TDeployKey struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TDeployKey) TableName() string { return "deploy_key" } + +type TAccessToken struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TAccessToken) TableName() string { return "access_token" } + +type TUser struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TUser) TableName() string { return "user" } + +type TWebhook struct { + ID int64 `xorm:"pk autoincr"` + CreatedUnix int64 + UpdatedUnix int64 +} + +func (t *TWebhook) TableName() string { return "webhook" } + +func convertDateToUnix(x *xorm.Engine) (err error) { + type Bean struct { + ID int64 `xorm:"pk autoincr"` + Created time.Time + Updated time.Time + Merged time.Time + Deadline time.Time + ClosedDate time.Time + NextUpdate time.Time + } + + var tables = []struct { + name string + cols []string + bean interface{} + }{ + {"action", []string{"created"}, new(TAction)}, + {"notice", []string{"created"}, new(TNotice)}, + {"comment", []string{"created"}, new(TComment)}, + {"issue", []string{"deadline", "created", "updated"}, new(TIssue)}, + {"milestone", []string{"deadline", "closed_date"}, new(TMilestone)}, + {"attachment", []string{"created"}, new(TAttachment)}, + {"login_source", []string{"created", "updated"}, new(TLoginSource)}, + {"pull_request", []string{"merged"}, new(TPull)}, + {"release", []string{"created"}, new(TRelease)}, + {"repository", []string{"created", "updated"}, new(TRepo)}, + {"mirror", []string{"updated", "next_update"}, new(TMirror)}, + {"public_key", []string{"created", "updated"}, new(TPublicKey)}, + {"deploy_key", []string{"created", "updated"}, new(TDeployKey)}, + {"access_token", []string{"created", "updated"}, new(TAccessToken)}, + {"user", []string{"created", "updated"}, new(TUser)}, + {"webhook", []string{"created", "updated"}, new(TWebhook)}, + } + + for _, table := range tables { + log.Info("Converting table: %s", table.name) + if err = x.Sync2(table.bean); err != nil { + return fmt.Errorf("Sync [table: %s]: %v", table.name, err) + } + + offset := 0 + for { + beans := make([]*Bean, 0, 100) + if err = x.Sql(fmt.Sprintf("SELECT * FROM `%s` ORDER BY id ASC LIMIT 100 OFFSET %d", + table.name, offset)).Find(&beans); err != nil { + return fmt.Errorf("select beans [table: %s, offset: %d]: %v", table.name, offset, err) + } + log.Trace("Table [%s]: offset: %d, beans: %d", table.name, offset, len(beans)) + if len(beans) == 0 { + break + } + offset += 100 + + baseSQL := "UPDATE `" + table.name + "` SET " + for _, bean := range beans { + valSQLs := make([]string, 0, len(table.cols)) + for _, col := range table.cols { + fieldSQL := "" + fieldSQL += col + "_unix = " + + switch col { + case "deadline": + if bean.Deadline.IsZero() { + continue + } + fieldSQL += com.ToStr(bean.Deadline.UTC().Unix()) + case "created": + fieldSQL += com.ToStr(bean.Created.UTC().Unix()) + case "updated": + fieldSQL += com.ToStr(bean.Updated.UTC().Unix()) + case "closed_date": + fieldSQL += com.ToStr(bean.ClosedDate.UTC().Unix()) + case "merged": + fieldSQL += com.ToStr(bean.Merged.UTC().Unix()) + case "next_update": + fieldSQL += com.ToStr(bean.NextUpdate.UTC().Unix()) + } + + valSQLs = append(valSQLs, fieldSQL) + } + + if len(valSQLs) == 0 { + continue + } + + if _, err = x.Exec(baseSQL + strings.Join(valSQLs, ",") + " WHERE id = " + com.ToStr(bean.ID)); err != nil { + return fmt.Errorf("update bean [table: %s, id: %d]: %v", table.name, bean.ID, err) + } + } + } + } + + return nil +} diff --git a/models/models.go b/models/models.go index 2e91f716902..b705bdad41a 100644 --- a/models/models.go +++ b/models/models.go @@ -11,16 +11,13 @@ import ( "os" "path" "strings" - "time" - "github.com/Unknwon/com" _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/core" "github.com/go-xorm/xorm" _ "github.com/lib/pq" "github.com/gogits/gogs/models/migrations" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -44,27 +41,6 @@ func sessionRelease(sess *xorm.Session) { sess.Close() } -// Note: get back time.Time from database Go sees it at UTC where they are really Local. -// So this function makes correct timezone offset. -func regulateTimeZone(t time.Time) time.Time { - if !setting.UseMySQL { - return t - } - - zone := t.Local().Format("-0700") - if len(zone) != 5 { - log.Error(4, "Unprocessable timezone: %s - %s", t.Local(), zone) - return t - } - hour := com.StrTo(zone[2:3]).MustInt() - minutes := com.StrTo(zone[3:5]).MustInt() - - if zone[0] == '-' { - return t.Add(time.Duration(hour) * time.Hour).Add(time.Duration(minutes) * time.Minute) - } - return t.Add(-1 * time.Duration(hour) * time.Hour).Add(-1 * time.Duration(minutes) * time.Minute) -} - var ( x *xorm.Engine tables []interface{} diff --git a/models/pull.go b/models/pull.go index a3b3d7bce5a..86ddb5d944e 100644 --- a/models/pull.go +++ b/models/pull.go @@ -58,20 +58,25 @@ type PullRequest struct { HasMerged bool MergedCommitID string `xorm:"VARCHAR(40)"` - Merged time.Time MergerID int64 - Merger *User `xorm:"-"` + Merger *User `xorm:"-"` + Merged time.Time `xorm:"-"` + MergedUnix int64 +} + +func (pr *PullRequest) BeforeUpdate() { + pr.MergedUnix = pr.Merged.UTC().Unix() } // Note: don't try to get Pull because will end up recursive querying. func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) { switch colName { - case "merged": + case "merged_unix": if !pr.HasMerged { return } - pr.Merged = regulateTimeZone(pr.Merged) + pr.Merged = time.Unix(pr.MergedUnix, 0).Local() } } diff --git a/models/release.go b/models/release.go index 9fc5d3967b4..b52b63941ae 100644 --- a/models/release.go +++ b/models/release.go @@ -33,13 +33,19 @@ type Release struct { Note string `xorm:"TEXT"` IsDraft bool `xorm:"NOT NULL DEFAULT false"` IsPrerelease bool - Created time.Time `xorm:"CREATED"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 +} + +func (r *Release) BeforeInsert() { + r.CreatedUnix = r.Created.UTC().Unix() } func (r *Release) AfterSet(colName string, _ xorm.Cell) { switch colName { - case "created": - r.Created = regulateTimeZone(r.Created) + case "created_unix": + r.Created = time.Unix(r.CreatedUnix, 0).Local() } } diff --git a/models/repo.go b/models/repo.go index 98b3e0532e8..b5567bf6836 100644 --- a/models/repo.go +++ b/models/repo.go @@ -178,8 +178,19 @@ type Repository struct { ForkID int64 BaseRepo *Repository `xorm:"-"` - Created time.Time `xorm:"CREATED"` - Updated time.Time `xorm:"UPDATED"` + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` + UpdatedUnix int64 +} + +func (repo *Repository) BeforeInsert() { + repo.CreatedUnix = time.Now().UTC().Unix() + repo.UpdatedUnix = repo.CreatedUnix +} + +func (repo *Repository) BeforeUpdate() { + repo.UpdatedUnix = time.Now().UTC().Unix() } func (repo *Repository) AfterSet(colName string, _ xorm.Cell) { @@ -195,8 +206,10 @@ func (repo *Repository) AfterSet(colName string, _ xorm.Cell) { repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls case "num_closed_milestones": repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones - case "updated": - repo.Updated = regulateTimeZone(repo.Updated) + case "created_unix": + repo.Created = time.Unix(repo.CreatedUnix, 0).Local() + case "updated_unix": + repo.Updated = time.Unix(repo.UpdatedUnix, 0) } } @@ -523,16 +536,28 @@ func IsUsableName(name string) error { // Mirror represents a mirror information of repository. type Mirror struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 - Repo *Repository `xorm:"-"` - Interval int // Hour. - Updated time.Time `xorm:"UPDATED"` - NextUpdate time.Time + ID int64 `xorm:"pk autoincr"` + RepoID int64 + Repo *Repository `xorm:"-"` + Interval int // Hour. + + Updated time.Time `xorm:"-"` + UpdatedUnix int64 + NextUpdate time.Time `xorm:"-"` + NextUpdateUnix int64 address string `xorm:"-"` } +func (m *Mirror) BeforeInsert() { + m.NextUpdateUnix = m.NextUpdate.UTC().Unix() +} + +func (m *Mirror) BeforeUpdate() { + m.UpdatedUnix = time.Now().UTC().Unix() + m.NextUpdateUnix = m.NextUpdate.UTC().Unix() +} + func (m *Mirror) AfterSet(colName string, _ xorm.Cell) { var err error switch colName { @@ -541,6 +566,10 @@ func (m *Mirror) AfterSet(colName string, _ xorm.Cell) { 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_updated_unix": + m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local() } } diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index 419169f09c9..b1c5f925afb 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -6,16 +6,14 @@ package models import ( "fmt" - "time" ) // Collaboration represent the relation between an individual and a repository. type Collaboration struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"` - Created time.Time `xorm:"CREATED"` + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"` } func (c *Collaboration) ModeName() string { diff --git a/models/ssh_key.go b/models/ssh_key.go index 86c1a25fe2a..b3021715535 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -45,22 +45,36 @@ const ( // PublicKey represents a SSH or deploy key. type PublicKey struct { - ID int64 `xorm:"pk autoincr"` - OwnerID int64 `xorm:"INDEX NOT NULL"` - Name string `xorm:"NOT NULL"` - Fingerprint string `xorm:"NOT NULL"` - Content string `xorm:"TEXT NOT NULL"` - Mode AccessMode `xorm:"NOT NULL DEFAULT 2"` - Type KeyType `xorm:"NOT NULL DEFAULT 1"` - Created time.Time `xorm:"CREATED"` - Updated time.Time // Note: Updated must below Created for AfterSet. - HasRecentActivity bool `xorm:"-"` - HasUsed bool `xorm:"-"` + ID int64 `xorm:"pk autoincr"` + OwnerID int64 `xorm:"INDEX NOT NULL"` + Name string `xorm:"NOT NULL"` + Fingerprint string `xorm:"NOT NULL"` + Content string `xorm:"TEXT NOT NULL"` + Mode AccessMode `xorm:"NOT NULL DEFAULT 2"` + Type KeyType `xorm:"NOT NULL DEFAULT 1"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. + UpdatedUnix int64 + HasRecentActivity bool `xorm:"-"` + HasUsed bool `xorm:"-"` +} + +func (k *PublicKey) BeforeInsert() { + k.CreatedUnix = time.Now().UTC().Unix() +} + +func (k *PublicKey) BeforeUpdate() { + k.UpdatedUnix = time.Now().UTC().Unix() } func (k *PublicKey) AfterSet(colName string, _ xorm.Cell) { switch colName { - case "created": + case "created_unix": + k.Created = time.Unix(k.CreatedUnix, 0).Local() + case "updated_unix": + k.Updated = time.Unix(k.UpdatedUnix, 0).Local() k.HasUsed = k.Updated.After(k.Created) k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now()) } @@ -608,21 +622,35 @@ func RewriteAllPublicKeys() error { // DeployKey represents deploy key information and its relation with repository. type DeployKey struct { - ID int64 `xorm:"pk autoincr"` - KeyID int64 `xorm:"UNIQUE(s) INDEX"` - RepoID int64 `xorm:"UNIQUE(s) INDEX"` - Name string - Fingerprint string - Content string `xorm:"-"` - Created time.Time `xorm:"CREATED"` - Updated time.Time // Note: Updated must below Created for AfterSet. - HasRecentActivity bool `xorm:"-"` - HasUsed bool `xorm:"-"` + ID int64 `xorm:"pk autoincr"` + KeyID int64 `xorm:"UNIQUE(s) INDEX"` + RepoID int64 `xorm:"UNIQUE(s) INDEX"` + Name string + Fingerprint string + Content string `xorm:"-"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. + UpdatedUnix int64 + HasRecentActivity bool `xorm:"-"` + HasUsed bool `xorm:"-"` +} + +func (k *DeployKey) BeforeInsert() { + k.CreatedUnix = time.Now().UTC().Unix() +} + +func (k *DeployKey) BeforeUpdate() { + k.UpdatedUnix = time.Now().UTC().Unix() } func (k *DeployKey) AfterSet(colName string, _ xorm.Cell) { switch colName { - case "created": + case "created_unix": + k.Created = time.Unix(k.CreatedUnix, 0).Local() + case "updated_unix": + k.Updated = time.Unix(k.UpdatedUnix, 0).Local() k.HasUsed = k.Updated.After(k.Created) k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now()) } diff --git a/models/token.go b/models/token.go index adf50a43212..38d83e2172d 100644 --- a/models/token.go +++ b/models/token.go @@ -7,6 +7,7 @@ package models import ( "time" + "github.com/go-xorm/xorm" gouuid "github.com/satori/go.uuid" "github.com/gogits/gogs/modules/base" @@ -14,16 +15,38 @@ import ( // AccessToken represents a personal access token. type AccessToken struct { - ID int64 `xorm:"pk autoincr"` - UID int64 `xorm:"INDEX"` - Name string - Sha1 string `xorm:"UNIQUE VARCHAR(40)"` - Created time.Time `xorm:"CREATED"` - Updated time.Time + ID int64 `xorm:"pk autoincr"` + UID int64 `xorm:"INDEX"` + Name string + Sha1 string `xorm:"UNIQUE VARCHAR(40)"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet. + UpdatedUnix int64 HasRecentActivity bool `xorm:"-"` HasUsed bool `xorm:"-"` } +func (t *AccessToken) BeforeInsert() { + t.CreatedUnix = time.Now().UTC().Unix() +} + +func (t *AccessToken) BeforeUpdate() { + t.UpdatedUnix = time.Now().UTC().Unix() +} + +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()) + } +} + // NewAccessToken creates new access token. func NewAccessToken(t *AccessToken) error { t.Sha1 = base.EncodeSha1(gouuid.NewV4().String()) @@ -46,16 +69,7 @@ func GetAccessTokenBySHA(sha string) (*AccessToken, error) { // ListAccessTokens returns a list of access tokens belongs to given user. func ListAccessTokens(uid int64) ([]*AccessToken, error) { tokens := make([]*AccessToken, 0, 5) - err := x.Where("uid=?", uid).Desc("id").Find(&tokens) - if err != nil { - return nil, err - } - - for _, t := range tokens { - t.HasUsed = t.Updated.After(t.Created) - t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now()) - } - return tokens, nil + return tokens, x.Where("uid=?", uid).Desc("id").Find(&tokens) } // UpdateAccessToken updates information of access token. diff --git a/models/user.go b/models/user.go index 14a05251a7f..865178b4f55 100644 --- a/models/user.go +++ b/models/user.go @@ -68,10 +68,13 @@ type User struct { Repos []*Repository `xorm:"-"` Location string Website string - Rands string `xorm:"VARCHAR(10)"` - Salt string `xorm:"VARCHAR(10)"` - Created time.Time `xorm:"CREATED"` - Updated time.Time `xorm:"UPDATED"` + Rands string `xorm:"VARCHAR(10)"` + Salt string `xorm:"VARCHAR(10)"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` + UpdatedUnix int64 // Remember visibility choice for convenience, true for private LastRepoVisibility bool @@ -103,18 +106,26 @@ type User struct { Members []*User `xorm:"-"` } +func (u *User) BeforeInsert() { + u.CreatedUnix = time.Now().UTC().Unix() + u.UpdatedUnix = u.CreatedUnix +} + func (u *User) BeforeUpdate() { if u.MaxRepoCreation < -1 { u.MaxRepoCreation = -1 } + u.UpdatedUnix = time.Now().UTC().Unix() } func (u *User) AfterSet(colName string, _ xorm.Cell) { switch colName { case "full_name": u.FullName = markdown.Sanitizer.Sanitize(u.FullName) - case "created": - u.Created = regulateTimeZone(u.Created) + case "created_unix": + u.Created = time.Unix(u.CreatedUnix, 0).Local() + case "updated_unix": + u.Updated = time.Unix(u.UpdatedUnix, 0).Local() } } diff --git a/models/webhook.go b/models/webhook.go index c20a72e97e7..6d8b8c16825 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -94,8 +94,20 @@ type Webhook struct { HookTaskType HookTaskType Meta string `xorm:"TEXT"` // store hook-specific attributes LastStatus HookStatus // Last delivery status - Created time.Time `xorm:"CREATED"` - Updated time.Time `xorm:"UPDATED"` + + Created time.Time `xorm:"-"` + CreatedUnix int64 + Updated time.Time `xorm:"-"` + UpdatedUnix int64 +} + +func (w *Webhook) BeforeInsert() { + w.CreatedUnix = time.Now().UTC().Unix() + w.UpdatedUnix = w.CreatedUnix +} + +func (w *Webhook) BeforeUpdate() { + w.UpdatedUnix = time.Now().UTC().Unix() } func (w *Webhook) AfterSet(colName string, _ xorm.Cell) { @@ -106,8 +118,10 @@ func (w *Webhook) AfterSet(colName string, _ xorm.Cell) { if err = json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { log.Error(3, "Unmarshal[%d]: %v", w.ID, err) } - case "created": - w.Created = regulateTimeZone(w.Created) + case "created_unix": + w.Created = time.Unix(w.CreatedUnix, 0).Local() + case "updated_unix": + w.Updated = time.Unix(w.UpdatedUnix, 0).Local() } } diff --git a/templates/.VERSION b/templates/.VERSION index 873dfc2a760..f78748364ae 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.9.1.0306 \ No newline at end of file +0.9.2.0309 \ No newline at end of file