| @@ -3,7 +3,7 @@ Gogs - Go Git Service [ | |||
| ##### Current version: 0.9.1 | |||
| ##### Current version: 0.9.2 | |||
| | Web | UI | Preview | | |||
| |:-------------:|:-------:|:-------:| | |||
| @@ -26,6 +26,7 @@ Hamid Feizabadi <hamidfzm AT gmail DOT com> | |||
| Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp> | |||
| ilko <kontact-mr.k AT outlook DOT com"> | |||
| Ilya Makarov | |||
| Robert Nuske <robert DOT nuske AT web DOT de> | |||
| Robin Hübner <profan AT prfn DOT se> | |||
| Jamie Mansfield <dev AT jamierocks DOT uk> | |||
| Jean THOMAS <contact AT tibounise DOT com> | |||
| @@ -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()) | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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. | |||
| @@ -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. | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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] | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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{} | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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 { | |||
| @@ -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()) | |||
| } | |||
| @@ -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. | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -1 +1 @@ | |||
| 0.9.1.0306 | |||
| 0.9.2.0309 | |||