models/migartions: make Migration as interface and use session

This commit is contained in:
Unknwon 2015-02-11 23:10:30 -05:00
parent 7e7160eefd
commit 876a856759
1 changed files with 62 additions and 23 deletions

View File

@ -13,12 +13,33 @@ import (
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const _DB_VER = 1 const _DB_VER = 1
type migration func(*xorm.Engine) error type Migration interface {
Description() string
Migrate(*xorm.Engine) error
}
type migration struct {
description string
migrate func(*xorm.Engine) error
}
func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
return &migration{desc, fn}
}
func (m *migration) Description() string {
return m.description
}
func (m *migration) Migrate(x *xorm.Engine) error {
return m.migrate(x)
}
// The version table. Should have only one row with id==1 // The version table. Should have only one row with id==1
type Version struct { type Version struct {
@ -28,8 +49,8 @@ type Version struct {
// This is a sequence of migrations. Add new migrations to the bottom of the list. // This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, replace it with "expiredMigration" // If you want to "retire" a migration, replace it with "expiredMigration"
var migrations = []migration{ var migrations = []Migration{
accessToCollaboration, NewMigration("generate collaboration from access", accessToCollaboration),
} }
// Migrate database to current version // Migrate database to current version
@ -47,13 +68,13 @@ func Migrate(x *xorm.Engine) error {
if err != nil { if err != nil {
return err return err
} }
// if needsMigration { if needsMigration {
// isEmpty, err := x.IsTableEmpty("user") isEmpty, err := x.IsTableEmpty("user")
// if err != nil { if err != nil {
// return err return err
// } }
// needsMigration = !isEmpty needsMigration = !isEmpty
// } }
if !needsMigration { if !needsMigration {
currentVersion.Version = int64(len(migrations)) currentVersion.Version = int64(len(migrations))
} }
@ -64,9 +85,10 @@ func Migrate(x *xorm.Engine) error {
} }
v := currentVersion.Version v := currentVersion.Version
for i, migration := range migrations[v:] { for i, m := range migrations[v:] {
if err = migration(x); err != nil { log.Info("Migration: %s", m.Description())
return fmt.Errorf("run migration: %v", err) if err = m.Migrate(x); err != nil {
return fmt.Errorf("do migrate: %v", err)
} }
currentVersion.Version = v + int64(i) + 1 currentVersion.Version = v + int64(i) + 1
if _, err = x.Id(1).Update(currentVersion); err != nil { if _, err = x.Id(1).Update(currentVersion); err != nil {
@ -95,6 +117,12 @@ func accessToCollaboration(x *xorm.Engine) error {
return err return err
} }
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
offset := strings.Split(time.Now().String(), " ")[2] offset := strings.Split(time.Now().String(), " ")[2]
for _, result := range results { for _, result := range results {
mode := com.StrTo(result["mode"]).MustInt64() mode := com.StrTo(result["mode"]).MustInt64()
@ -121,8 +149,9 @@ func accessToCollaboration(x *xorm.Engine) error {
ownerName := parts[0] ownerName := parts[0]
repoName := parts[1] repoName := parts[1]
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) results, err := sess.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 { if err != nil {
sess.Rollback()
return err return err
} }
if len(results) < 1 { if len(results) < 1 {
@ -147,21 +176,31 @@ func accessToCollaboration(x *xorm.Engine) error {
continue continue
} }
results, err = x.Query("SELECT id FROM `repository` WHERE owner_id=? AND lower_name=?", ownerID, repoName) results, err = sess.Query("SELECT id FROM `repository` WHERE owner_id=? AND lower_name=?", ownerID, repoName)
if err != nil { if err != nil {
return err return err
} } else if len(results) < 1 {
if len(results) < 1 {
continue continue
} }
if _, err = x.InsertOne(&Collaboration{ collaboration := &Collaboration{
UserID: userID, UserID: userID,
RepoID: com.StrTo(results[0]["id"]).MustInt64(), RepoID: com.StrTo(results[0]["id"]).MustInt64(),
Created: created, }
}); err != nil { has, err := sess.Get(collaboration)
if err != nil {
sess.Rollback()
return err
} else if has {
continue
}
collaboration.Created = created
if _, err = sess.InsertOne(collaboration); err != nil {
sess.Rollback()
return err return err
} }
} }
return nil
return sess.Commit()
} }