]> source.dussan.org Git - gitea.git/commitdiff
first pass work on migration #925
authorUnknwon <joe2010xtmf@163.com>
Thu, 12 Feb 2015 02:58:37 +0000 (21:58 -0500)
committerUnknwon <joe2010xtmf@163.com>
Thu, 12 Feb 2015 02:58:37 +0000 (21:58 -0500)
cmd/serve.go
models/access.go
models/issue.go
models/migrations/migrations.go
models/models.go
models/repo.go
models/user.go
modules/setting/setting.go
templates/ng/base/footer.tmpl

index 25f7dd9191dc05ea82b783cb41c19e227eede83c..e957d45de77fec86d15402287b9b5efe5c86f973 100644 (file)
@@ -43,7 +43,7 @@ func setup(logPath string) {
 
        models.LoadModelsConfig()
 
-       if models.UseSQLite3 {
+       if setting.UseSQLite3 {
                workDir, _ := setting.WorkDir()
                os.Chdir(workDir)
        }
index 64bb921409f2a0256be64216179766980b94e473..6df1da29bca742f0511b200f6c7999e149b2cf5d 100644 (file)
@@ -7,8 +7,6 @@ package models
 import (
        "strings"
        "time"
-
-       "github.com/go-xorm/xorm"
 )
 
 type AccessType int
@@ -27,35 +25,40 @@ type Access struct {
        Created  time.Time  `xorm:"CREATED"`
 }
 
-// AddAccess adds new access record.
-func AddAccess(access *Access) error {
+func addAccess(e Engine, access *Access) error {
        access.UserName = strings.ToLower(access.UserName)
        access.RepoName = strings.ToLower(access.RepoName)
-       _, err := x.Insert(access)
+       _, err := e.Insert(access)
        return err
 }
 
+// AddAccess adds new access record.
+func AddAccess(access *Access) error {
+       return addAccess(x, access)
+}
+
+func updateAccess(e Engine, access *Access) error {
+       if _, err := e.Id(access.Id).Update(access); err != nil {
+               return err
+       }
+       return nil
+}
+
 // UpdateAccess updates access information.
 func UpdateAccess(access *Access) error {
        access.UserName = strings.ToLower(access.UserName)
        access.RepoName = strings.ToLower(access.RepoName)
-       _, err := x.Id(access.Id).Update(access)
-       return err
+       return updateAccess(x, access)
 }
 
-// DeleteAccess deletes access record.
-func DeleteAccess(access *Access) error {
-       _, err := x.Delete(access)
+func deleteAccess(e Engine, access *Access) error {
+       _, err := e.Delete(access)
        return err
 }
 
-// UpdateAccess updates access information with session for rolling back.
-func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
-       if _, err := sess.Id(access.Id).Update(access); err != nil {
-               sess.Rollback()
-               return err
-       }
-       return nil
+// DeleteAccess deletes access record.
+func DeleteAccess(access *Access) error {
+       return deleteAccess(x, access)
 }
 
 // HasAccess returns true if someone can read or write to given repository.
@@ -93,9 +96,10 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessType, error) {
                if err != nil {
                        return nil, err
                }
-               err = repo.GetOwner()
-               if err != nil {
+               if err = repo.GetOwner(); err != nil {
                        return nil, err
+               } else if repo.OwnerId == u.Id {
+                       continue
                }
                repos[repo] = access.Mode
        }
index 9e1d52260f8304838f3155a70a47c7f36b4f90eb..3cd71d8aa4712ab06a33ca419608f00eee3e2a04 100644 (file)
@@ -282,30 +282,33 @@ type IssueUser struct {
 }
 
 // NewIssueUserPairs adds new issue-user pairs for new issue of repository.
-func NewIssueUserPairs(repo *Repository, iid, oid, pid, aid int64) (err error) {
-       iu := &IssueUser{IssueId: iid, RepoId: repo.Id}
-
-       us, err := repo.GetCollaborators()
+func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) (err error) {
+       users, err := repo.GetCollaborators()
        if err != nil {
                return err
        }
 
+       iu := &IssueUser{
+               IssueId: issueID,
+               RepoId:  repo.Id,
+       }
+
        isNeedAddPoster := true
-       for _, u := range us {
+       for _, u := range users {
                iu.Uid = u.Id
-               iu.IsPoster = iu.Uid == pid
+               iu.IsPoster = iu.Uid == posterID
                if isNeedAddPoster && iu.IsPoster {
                        isNeedAddPoster = false
                }
-               iu.IsAssigned = iu.Uid == aid
+               iu.IsAssigned = iu.Uid == assigneeID
                if _, err = x.Insert(iu); err != nil {
                        return err
                }
        }
        if isNeedAddPoster {
-               iu.Uid = pid
+               iu.Uid = posterID
                iu.IsPoster = true
-               iu.IsAssigned = iu.Uid == aid
+               iu.IsAssigned = iu.Uid == assigneeID
                if _, err = x.Insert(iu); err != nil {
                        return err
                }
index f0ed10b7aa58675d61e3b131059ccd331da75cf6..27ab36c8442fd725abd41455713e632552de1e5d 100644 (file)
@@ -1,14 +1,23 @@
+// Copyright 2015 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
 package migrations
 
 import (
        "errors"
-       "strconv"
+       "fmt"
        "strings"
        "time"
 
+       "github.com/Unknwon/com"
        "github.com/go-xorm/xorm"
+
+       "github.com/gogits/gogs/modules/setting"
 )
 
+const _DB_VER = 1
+
 type migration func(*xorm.Engine) error
 
 // The version table. Should have only one row with id==1
@@ -26,39 +35,38 @@ var migrations = []migration{
 // Migrate database to current version
 func Migrate(x *xorm.Engine) error {
        if err := x.Sync(new(Version)); err != nil {
-               return err
+               return fmt.Errorf("sync: %v", err)
        }
 
        currentVersion := &Version{Id: 1}
        has, err := x.Get(currentVersion)
        if err != nil {
-               return err
+               return fmt.Errorf("get: %v", err)
        } else if !has {
                needsMigration, err := x.IsTableExist("user")
                if err != nil {
                        return err
                }
-               if needsMigration {
-                       isEmpty, err := x.IsTableEmpty("user")
-                       if err != nil {
-                               return err
-                       }
-                       needsMigration = !isEmpty
-               }
+               // if needsMigration {
+               //      isEmpty, err := x.IsTableEmpty("user")
+               //      if err != nil {
+               //              return err
+               //      }
+               //      needsMigration = !isEmpty
+               // }
                if !needsMigration {
                        currentVersion.Version = int64(len(migrations))
                }
 
                if _, err = x.InsertOne(currentVersion); err != nil {
-                       return err
+                       return fmt.Errorf("insert: %v", err)
                }
        }
 
        v := currentVersion.Version
-
        for i, migration := range migrations[v:] {
                if err = migration(x); err != nil {
-                       return err
+                       return fmt.Errorf("run migration: %v", err)
                }
                currentVersion.Version = v + int64(i) + 1
                if _, err = x.Id(1).Update(currentVersion); err != nil {
@@ -72,48 +80,48 @@ func expiredMigration(x *xorm.Engine) error {
        return errors.New("You are migrating from a too old gogs version")
 }
 
-func mustParseInt64(in []byte) int64 {
-       i, err := strconv.ParseInt(string(in), 10, 64)
-       if err != nil {
-               i = 0
-       }
-       return i
-}
-
 func accessToCollaboration(x *xorm.Engine) error {
        type Collaboration struct {
-               ID      int64     `xorm:"pk autoincr"`
-               RepoID  int64     `xorm:"UNIQUE(s) INDEX NOT NULL"`
-               UserID  int64     `xorm:"UNIQUE(s) INDEX 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"`
+               Created time.Time
        }
 
        x.Sync(new(Collaboration))
 
-       sql := `SELECT u.id AS uid, a.repo_name AS repo, a.mode AS mode, a.created as created FROM access a JOIN user u ON a.user_name=u.lower_name`
-       results, err := x.Query(sql)
+       results, err := x.Query("SELECT u.id AS `uid`, a.repo_name AS `repo`, a.mode AS `mode`, a.created as `created` FROM `access` a JOIN `user` u ON a.user_name=u.lower_name")
        if err != nil {
                return err
        }
 
+       offset := strings.Split(time.Now().String(), " ")[2]
        for _, result := range results {
-               userID := mustParseInt64(result["uid"])
-               repoRefName := string(result["repo"])
-               mode := mustParseInt64(result["mode"])
-               created := result["created"]
-
-               //Collaborators must have write access
+               mode := com.StrTo(result["mode"]).MustInt64()
+               // Collaborators must have write access.
                if mode < 2 {
                        continue
                }
 
+               userID := com.StrTo(result["uid"]).MustInt64()
+               repoRefName := string(result["repo"])
+
+               var created time.Time
+               switch {
+               case setting.UseSQLite3:
+                       created, _ = time.Parse(time.RFC3339, string(result["created"]))
+               case setting.UseMySQL:
+                       created, _ = time.Parse("2006-01-02 15:04:05-0700", string(result["created"])+offset)
+               case setting.UsePostgreSQL:
+                       created, _ = time.Parse("2006-01-02T15:04:05Z-0700", string(result["created"])+offset)
+               }
+
                // find owner of repository
                parts := strings.SplitN(repoRefName, "/", 2)
                ownerName := parts[0]
                repoName := parts[1]
 
-               sql = `SELECT u.id as uid, ou.uid as memberid FROM user u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?`
-               results, err := x.Query(sql, ownerName)
+               results, err := x.Query("SELECT u.id as `uid`, ou.uid as `memberid` FROM `user` u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?", ownerName)
                if err != nil {
                        return err
                }
@@ -121,7 +129,7 @@ func accessToCollaboration(x *xorm.Engine) error {
                        continue
                }
 
-               ownerID := mustParseInt64(results[0]["uid"])
+               ownerID := com.StrTo(results[0]["uid"]).MustInt64()
                if ownerID == userID {
                        continue
                }
@@ -129,7 +137,7 @@ func accessToCollaboration(x *xorm.Engine) error {
                // test if user is member of owning organization
                isMember := false
                for _, member := range results {
-                       memberID := mustParseInt64(member["memberid"])
+                       memberID := com.StrTo(member["memberid"]).MustInt64()
                        // We can skip all cases that a user is member of the owning organization
                        if memberID == userID {
                                isMember = true
@@ -139,8 +147,7 @@ func accessToCollaboration(x *xorm.Engine) error {
                        continue
                }
 
-               sql = `SELECT id FROM repository WHERE owner_id=? AND lower_name=?`
-               results, err = x.Query(sql, ownerID, repoName)
+               results, err = x.Query("SELECT id FROM `repository` WHERE owner_id=? AND lower_name=?", ownerID, repoName)
                if err != nil {
                        return err
                }
@@ -148,11 +155,11 @@ func accessToCollaboration(x *xorm.Engine) error {
                        continue
                }
 
-               repoID := results[0]["id"]
-
-               sql = `INSERT INTO collaboration (user_id, repo_id, created) VALUES (?,?,?)`
-               _, err = x.Exec(sql, userID, repoID, created)
-               if err != nil {
+               if _, err = x.InsertOne(&Collaboration{
+                       UserID:  userID,
+                       RepoID:  com.StrTo(results[0]["id"]).MustInt64(),
+                       Created: created,
+               }); err != nil {
                        return err
                }
        }
index dbe3947495e842b06203902e439c45afdd533913..141e3ac49758985fb02d33fc0efc6cba4a26ab92 100644 (file)
@@ -40,24 +40,29 @@ var (
        }
 
        EnableSQLite3 bool
-       UseSQLite3    bool
 )
 
 func init() {
        tables = append(tables,
-               new(User), new(PublicKey), new(Follow), new(Oauth2), new(AccessToken),
-               new(Repository), new(Watch), new(Star), new(Action), new(Access),
+               new(User), new(PublicKey), new(Oauth2), new(AccessToken),
+               new(Repository), new(Collaboration), new(Access),
+               new(Watch), new(Star), new(Follow), new(Action),
                new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
                new(Mirror), new(Release), new(LoginSource), new(Webhook),
                new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
-               new(Notice), new(EmailAddress), new(Collaboration))
+               new(Notice), new(EmailAddress))
 }
 
 func LoadModelsConfig() {
        sec := setting.Cfg.Section("database")
        DbCfg.Type = sec.Key("DB_TYPE").String()
-       if DbCfg.Type == "sqlite3" {
-               UseSQLite3 = true
+       switch DbCfg.Type {
+       case "sqlite3":
+               setting.UseSQLite3 = true
+       case "mysql":
+               setting.UseMySQL = true
+       case "postgres":
+               setting.UsePostgreSQL = true
        }
        DbCfg.Host = sec.Key("HOST").String()
        DbCfg.Name = sec.Key("NAME").String()
@@ -141,7 +146,7 @@ func NewEngine() (err error) {
        }
 
        if err = migrations.Migrate(x); err != nil {
-               return err
+               return fmt.Errorf("migrate: %v", err)
        }
 
        if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
index d3faa09bba2544464c7ae298a632de3c4b1bf6ec..35ee871fd47fadf26b40903cd235a0774b79f5e2 100644 (file)
@@ -847,7 +847,8 @@ func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error)
 
        for i := range accesses {
                accesses[i].RepoName = userName + "/" + newRepoName
-               if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
+               if err = updateAccess(sess, &accesses[i]); err != nil {
+                       sess.Rollback()
                        return err
                }
        }
@@ -1062,76 +1063,6 @@ func GetRepositoryCount(user *User) (int64, error) {
        return x.Count(&Repository{OwnerId: user.Id})
 }
 
-// GetCollaborators returns the collaborators for a repository
-func (r *Repository) GetCollaborators() ([]*User, error) {
-       collaborations := make([]*Collaboration, 0)
-       if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
-               return nil, err
-       }
-
-       users := make([]*User, len(collaborations))
-       for i, c := range collaborations {
-               user, err := GetUserById(c.UserID)
-               if err != nil {
-                       return nil, err
-               }
-               users[i] = user
-       }
-       return users, nil
-}
-
-// Add collaborator and accompanying access
-func (r *Repository) AddCollaborator(u *User) error {
-       collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
-       has, err := x.Get(collaboration)
-       if err != nil {
-               return err
-       }
-       if has {
-               return nil
-       }
-
-       if _, err = x.InsertOne(collaboration); err != nil {
-               return err
-       }
-
-       if err = r.GetOwner(); err != nil {
-               return err
-       }
-
-       return AddAccess(&Access{UserName: u.LowerName, RepoName: path.Join(r.Owner.LowerName, r.LowerName), Mode: WRITABLE})
-}
-
-// Delete collaborator and accompanying access
-func (r *Repository) DeleteCollaborator(u *User) error {
-       collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
-       if has, err := x.Delete(collaboration); err != nil || has == 0 {
-               return err
-       }
-
-       if err := r.GetOwner(); err != nil {
-               return err
-       }
-
-       needDelete := true
-       if r.Owner.IsOrganization() {
-               auth, err := GetHighestAuthorize(r.Owner.Id, u.Id, r.Id, 0)
-               if err != nil {
-                       return err
-               }
-               if auth > 0 {
-                       needDelete = false
-               }
-       }
-       if needDelete {
-               return DeleteAccess(&Access{UserName: u.LowerName, RepoName: path.Join(r.Owner.LowerName, r.LowerName), Mode: WRITABLE})
-       }
-
-       return nil
-}
-
 type SearchOption struct {
        Keyword string
        Uid     int64
@@ -1279,6 +1210,120 @@ func GitGcRepos() error {
                })
 }
 
+// _________        .__  .__        ___.                        __  .__
+// \_   ___ \  ____ |  | |  | _____ \_ |__   ________________ _/  |_|__| ____   ____
+// /    \  \/ /  _ \|  | |  | \__  \ | __ \ /  _ \_  __ \__  \\   __\  |/  _ \ /    \
+// \     \___(  <_> )  |_|  |__/ __ \| \_\ (  <_> )  | \// __ \|  | |  (  <_> )   |  \
+//  \______  /\____/|____/____(____  /___  /\____/|__|  (____  /__| |__|\____/|___|  /
+//         \/                      \/    \/                  \/                    \/
+
+// A Collaboration is a 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"`
+       Created time.Time `xorm:"CREATED"`
+}
+
+// Add collaborator and accompanying access
+func (r *Repository) AddCollaborator(u *User) error {
+       collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+       has, err := x.Get(collaboration)
+       if err != nil {
+               return err
+       } else if has {
+               return nil
+       }
+
+       if err = r.GetOwner(); err != nil {
+               return err
+       }
+
+       sess := x.NewSession()
+       defer sess.Close()
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if _, err = sess.InsertOne(collaboration); err != nil {
+               sess.Rollback()
+               return err
+       } else if err = addAccess(sess, &Access{
+               UserName: u.LowerName,
+               RepoName: path.Join(r.Owner.LowerName, r.LowerName),
+               Mode:     WRITABLE}); err != nil {
+               sess.Rollback()
+               return err
+       }
+
+       return sess.Commit()
+}
+
+// GetCollaborators returns the collaborators for a repository
+func (r *Repository) GetCollaborators() ([]*User, error) {
+       collaborations := make([]*Collaboration, 0, 5)
+       if err := x.Where("repo_id=?", r.Id).Find(&collaborations); err != nil {
+               return nil, err
+       }
+
+       users := make([]*User, len(collaborations))
+       for i, c := range collaborations {
+               user, err := GetUserById(c.UserID)
+               if err != nil {
+                       return nil, err
+               }
+               users[i] = user
+       }
+       return users, nil
+}
+
+// Delete collaborator and accompanying access
+func (r *Repository) DeleteCollaborator(u *User) (err error) {
+       collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+       has, err := x.Get(collaboration)
+       if err != nil {
+               return err
+       } else if !has {
+               return nil
+       }
+
+       if err = r.GetOwner(); err != nil {
+               return err
+       }
+
+       sess := x.NewSession()
+       defer sess.Close()
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       needDelete := true
+       if r.Owner.IsOrganization() {
+               auth, err := getHighestAuthorize(sess, r.Owner.Id, u.Id, r.Id, 0)
+               if err != nil {
+                       sess.Rollback()
+                       return err
+               }
+               if auth > 0 {
+                       needDelete = false
+               }
+       }
+       if needDelete {
+               if err = deleteAccess(sess, &Access{
+                       UserName: u.LowerName,
+                       RepoName: path.Join(r.Owner.LowerName, r.LowerName),
+                       Mode:     WRITABLE}); err != nil {
+                       sess.Rollback()
+                       return err
+               } else if _, err = sess.Delete(collaboration); err != nil {
+                       sess.Rollback()
+                       return err
+               }
+       }
+
+       return sess.Commit()
+}
+
 //  __      __         __         .__
 // /  \    /  \_____ _/  |_  ____ |  |__
 // \   \/\/   /\__  \\   __\/ ___\|  |  \
@@ -1559,11 +1604,3 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
 
        return repo, nil
 }
-
-// A Collaboration is a 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"`
-       Created time.Time `xorm:"CREATED"`
-}
index 2da0881c81865b0d34e4e09efe703a8c1b81c19c..5606cea3799be02ffce9c9224ec08ff9da40ff53 100644 (file)
@@ -415,7 +415,8 @@ func ChangeUserName(u *User, newUserName string) (err error) {
                if strings.HasPrefix(accesses[i].RepoName, u.LowerName+"/") {
                        accesses[i].RepoName = strings.Replace(accesses[i].RepoName, u.LowerName, newUserName, 1)
                }
-               if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
+               if err = updateAccess(sess, &accesses[i]); err != nil {
+                       sess.Rollback()
                        return err
                }
        }
@@ -435,7 +436,8 @@ func ChangeUserName(u *User, newUserName string) (err error) {
                        // if the access is not the user's access (already updated above)
                        if accesses[j].UserName != u.LowerName {
                                accesses[j].RepoName = newUserName + "/" + repos[i].LowerName
-                               if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil {
+                               if err = updateAccess(sess, &accesses[j]); err != nil {
+                                       sess.Rollback()
                                        return err
                                }
                        }
@@ -564,8 +566,7 @@ func UserPath(userName string) string {
 
 func GetUserByKeyId(keyId int64) (*User, error) {
        user := new(User)
-       rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?"
-       has, err := x.Sql(rawSql, keyId).Get(user)
+       has, err := x.Sql("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyId).Get(user)
        if err != nil {
                return nil, err
        } else if !has {
index 6664c419077500d68db36586f60b53a248de5342..795bcc5ba21d37897721bb448b6df7651744ae32 100644 (file)
@@ -67,6 +67,11 @@ var (
        CookieRememberName   string
        ReverseProxyAuthUser string
 
+       // Database settings.
+       UseSQLite3    bool
+       UseMySQL      bool
+       UsePostgreSQL bool
+
        // Webhook settings.
        Webhook struct {
                TaskInterval   int
index e152a4ded177aa422e564a22a5991aa50c47cc36..89836fca23313fec0bcfaaaab57dd36e65b4483e 100644 (file)
@@ -1,7 +1,7 @@
                </div>
                <footer id="footer">
                    <div class="container clear">
-                       <p class="left" id="footer-rights">© 2015 GoGits · {{.i18n.Tr "version"}}: {{AppVer}} · {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> ·
+                       <p class="left" id="footer-rights">© 2015 Gogs · {{.i18n.Tr "version"}}: {{AppVer}} · {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> ·
                            {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong></p>
 
                        <div class="right" id="footer-links">