mirror of https://github.com/stashapp/stash.git
93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/stashapp/stash/pkg/database"
|
|
"github.com/stashapp/stash/pkg/logger"
|
|
)
|
|
|
|
type migrateData struct {
|
|
ExistingVersion uint
|
|
MigrateVersion uint
|
|
BackupPath string
|
|
}
|
|
|
|
func getMigrateData() migrateData {
|
|
return migrateData{
|
|
ExistingVersion: database.Version(),
|
|
MigrateVersion: database.AppSchemaVersion(),
|
|
BackupPath: database.DatabaseBackupPath(),
|
|
}
|
|
}
|
|
|
|
func getMigrateHandler(w http.ResponseWriter, r *http.Request) {
|
|
if !database.NeedsMigration() {
|
|
http.Redirect(w, r, "/", 301)
|
|
return
|
|
}
|
|
|
|
data, _ := setupUIBox.Find("migrate.html")
|
|
templ, err := template.New("Migrate").Parse(string(data))
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("error: %s", err), 500)
|
|
return
|
|
}
|
|
|
|
err = templ.Execute(w, getMigrateData())
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("error: %s", err), 500)
|
|
}
|
|
}
|
|
|
|
func doMigrateHandler(w http.ResponseWriter, r *http.Request) {
|
|
err := r.ParseForm()
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("error: %s", err), 500)
|
|
}
|
|
|
|
formBackupPath := r.Form.Get("backuppath")
|
|
|
|
// always backup so that we can roll back to the previous version if
|
|
// migration fails
|
|
backupPath := formBackupPath
|
|
if formBackupPath == "" {
|
|
backupPath = database.DatabaseBackupPath()
|
|
}
|
|
|
|
// perform database backup
|
|
if err = database.Backup(backupPath); err != nil {
|
|
http.Error(w, fmt.Sprintf("error backing up database: %s", err), 500)
|
|
return
|
|
}
|
|
|
|
err = database.RunMigrations()
|
|
if err != nil {
|
|
errStr := fmt.Sprintf("error performing migration: %s", err)
|
|
|
|
// roll back to the backed up version
|
|
restoreErr := database.RestoreFromBackup(backupPath)
|
|
if restoreErr != nil {
|
|
errStr = fmt.Sprintf("ERROR: unable to restore database from backup after migration failure: %s\n%s", restoreErr.Error(), errStr)
|
|
} else {
|
|
errStr = "An error occurred migrating the database to the latest schema version. The backup database file was automatically renamed to restore the database.\n" + errStr
|
|
}
|
|
|
|
http.Error(w, errStr, 500)
|
|
return
|
|
}
|
|
|
|
// if no backup path was provided, then delete the created backup
|
|
if formBackupPath == "" {
|
|
err = os.Remove(backupPath)
|
|
if err != nil {
|
|
logger.Warnf("error removing unwanted database backup (%s): %s", backupPath, err.Error())
|
|
}
|
|
}
|
|
|
|
http.Redirect(w, r, "/", 301)
|
|
}
|