diff options
author | Unknwon <u@gogs.io> | 2017-02-26 04:37:05 -0500 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2017-02-27 22:48:19 -0500 |
commit | ca2cfaf71e33f42c00f5baf4792ba8396e6d0042 (patch) | |
tree | 51a06e4506b3d7314a03d7f905a4c35d018a0a3b /models | |
parent | b06f2997489d58cc5a4375044e378c0565ea09d4 (diff) |
cmd: able to backup and restore
Not very robust, must execute under correct workdir.
Addresses #2072, #3708, #648
Diffstat (limited to 'models')
-rw-r--r-- | models/migrations/migrations.go | 2 | ||||
-rw-r--r-- | models/models.go | 91 |
2 files changed, 89 insertions, 4 deletions
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 765ad93c..e543ae62 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -42,7 +42,7 @@ func (m *migration) Migrate(x *xorm.Engine) error { // The version table. Should have only one row with id==1 type Version struct { - ID int64 `xorm:"pk autoincr"` + ID int64 Version int64 } diff --git a/models/models.go b/models/models.go index bf071292..c79a071b 100644 --- a/models/models.go +++ b/models/models.go @@ -5,7 +5,9 @@ package models import ( + "bufio" "database/sql" + "encoding/json" "errors" "fmt" "net/url" @@ -13,6 +15,7 @@ import ( "path" "strings" + "github.com/Unknwon/com" _ "github.com/denisenkom/go-mssqldb" _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/core" @@ -262,7 +265,89 @@ func Ping() error { return x.Ping() } -// DumpDatabase dumps all data from database to file system. -func DumpDatabase(filePath string) error { - return x.DumpAllToFile(filePath) +// The version table. Should have only one row with id==1 +type Version struct { + ID int64 + Version int64 +} + +// DumpDatabase dumps all data from database to file system in JSON format. +func DumpDatabase(dirPath string) (err error) { + os.MkdirAll(dirPath, os.ModePerm) + // Purposely create a local variable to not modify global variable + tables := append(tables, new(Version)) + for _, table := range tables { + tableName := strings.TrimPrefix(fmt.Sprintf("%T", table), "*models.") + tableFile := path.Join(dirPath, tableName+".json") + f, err := os.Create(tableFile) + if err != nil { + return fmt.Errorf("fail to create JSON file: %v", err) + } + + if err = x.Asc("id").Iterate(table, func(idx int, bean interface{}) (err error) { + enc := json.NewEncoder(f) + return enc.Encode(bean) + }); err != nil { + f.Close() + return fmt.Errorf("fail to dump table '%s': %v", tableName, err) + } + f.Close() + } + return nil +} + +// ImportDatabase imports data from backup archive. +func ImportDatabase(dirPath string) (err error) { + // Purposely create a local variable to not modify global variable + tables := append(tables, new(Version)) + for _, table := range tables { + tableName := strings.TrimPrefix(fmt.Sprintf("%T", table), "*models.") + tableFile := path.Join(dirPath, tableName+".json") + if !com.IsExist(tableFile) { + continue + } + + if err = x.DropTables(table); err != nil { + return fmt.Errorf("fail to drop table '%s': %v", tableName, err) + } else if err = x.Sync2(table); err != nil { + return fmt.Errorf("fail to sync table '%s': %v", tableName, err) + } + + f, err := os.Open(tableFile) + if err != nil { + return fmt.Errorf("fail to open JSON file: %v", err) + } + scanner := bufio.NewScanner(f) + for scanner.Scan() { + switch bean := table.(type) { + case *LoginSource: + meta := make(map[string]interface{}) + if err = json.Unmarshal(scanner.Bytes(), &meta); err != nil { + return fmt.Errorf("fail to unmarshal to map: %v", err) + } + + tp := LoginType(com.StrTo(com.ToStr(meta["Type"])).MustInt64()) + switch tp { + case LOGIN_LDAP, LOGIN_DLDAP: + bean.Cfg = new(LDAPConfig) + case LOGIN_SMTP: + bean.Cfg = new(SMTPConfig) + case LOGIN_PAM: + bean.Cfg = new(PAMConfig) + default: + return fmt.Errorf("unrecognized login source type:: %v", tp) + } + table = bean + } + + if err = json.Unmarshal(scanner.Bytes(), table); err != nil { + return fmt.Errorf("fail to unmarshal to struct: %v", err) + } + + if _, err = x.Insert(table); err != nil { + return fmt.Errorf("fail to insert strcut: %v", err) + } + } + } + return nil } |