mirror of https://github.com/stashapp/stash.git
177 lines
4.1 KiB
Go
177 lines
4.1 KiB
Go
package migrations
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/stashapp/stash/internal/manager/config"
|
|
"github.com/stashapp/stash/pkg/logger"
|
|
"github.com/stashapp/stash/pkg/sqlite"
|
|
)
|
|
|
|
type schema60Migrator struct {
|
|
migrator
|
|
}
|
|
|
|
func post60(ctx context.Context, db *sqlx.DB) error {
|
|
logger.Info("Running post-migration for schema version 60")
|
|
|
|
m := schema60Migrator{
|
|
migrator: migrator{
|
|
db: db,
|
|
},
|
|
}
|
|
|
|
return m.migrate(ctx)
|
|
}
|
|
|
|
func (m *schema60Migrator) decodeJSON(s string, v interface{}) {
|
|
if s == "" {
|
|
return
|
|
}
|
|
|
|
if err := json.Unmarshal([]byte(s), v); err != nil {
|
|
logger.Errorf("error decoding json %q: %v", s, err)
|
|
}
|
|
}
|
|
|
|
type schema60DefaultFilters map[string]interface{}
|
|
|
|
func (m *schema60Migrator) migrate(ctx context.Context) error {
|
|
|
|
// save default filters into the UI config
|
|
if err := m.withTxn(ctx, func(tx *sqlx.Tx) error {
|
|
query := "SELECT id, mode, find_filter, object_filter, ui_options FROM `saved_filters` WHERE `name` = ''"
|
|
|
|
rows, err := tx.Query(query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
defaultFilters := make(schema60DefaultFilters)
|
|
|
|
for rows.Next() {
|
|
var (
|
|
id int
|
|
mode string
|
|
findFilterStr string
|
|
objectFilterStr string
|
|
uiOptionsStr string
|
|
)
|
|
|
|
if err := rows.Scan(&id, &mode, &findFilterStr, &objectFilterStr, &uiOptionsStr); err != nil {
|
|
return err
|
|
}
|
|
|
|
// convert the filters to the correct format
|
|
findFilter := make(map[string]interface{})
|
|
objectFilter := make(map[string]interface{})
|
|
uiOptions := make(map[string]interface{})
|
|
|
|
m.decodeJSON(findFilterStr, &findFilter)
|
|
m.decodeJSON(objectFilterStr, &objectFilter)
|
|
m.decodeJSON(uiOptionsStr, &uiOptions)
|
|
|
|
o := map[string]interface{}{
|
|
"mode": mode,
|
|
"find_filter": findFilter,
|
|
"object_filter": objectFilter,
|
|
"ui_options": uiOptions,
|
|
}
|
|
|
|
defaultFilters[strings.ToLower(mode)] = o
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := m.saveDefaultFilters(defaultFilters); err != nil {
|
|
return fmt.Errorf("saving default filters: %w", err)
|
|
}
|
|
|
|
// remove the default filters from the database
|
|
query = "DELETE FROM `saved_filters` WHERE `name` = ''"
|
|
if _, err := tx.Exec(query); err != nil {
|
|
return fmt.Errorf("deleting default filters: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *schema60Migrator) saveDefaultFilters(defaultFilters schema60DefaultFilters) error {
|
|
if len(defaultFilters) == 0 {
|
|
logger.Debugf("no default filters to save")
|
|
return nil
|
|
}
|
|
|
|
// save the default filters into the UI config
|
|
config := config.GetInstance()
|
|
|
|
orgPath := config.GetConfigFile()
|
|
|
|
if orgPath == "" {
|
|
// no config file to migrate (usually in a test or new system)
|
|
logger.Debugf("no config file to migrate")
|
|
return nil
|
|
}
|
|
|
|
uiConfig := config.GetUIConfiguration()
|
|
if uiConfig == nil {
|
|
uiConfig = make(map[string]interface{})
|
|
}
|
|
|
|
// if the defaultFilters key already exists, don't overwrite them
|
|
if _, found := uiConfig["defaultFilters"]; found {
|
|
logger.Warn("defaultFilters already exists in the UI config, skipping migration")
|
|
return nil
|
|
}
|
|
|
|
if err := m.backupConfig(orgPath); err != nil {
|
|
return fmt.Errorf("backing up config: %w", err)
|
|
}
|
|
|
|
uiConfig["defaultFilters"] = map[string]interface{}(defaultFilters)
|
|
config.SetUIConfiguration(uiConfig)
|
|
|
|
if err := config.Write(); err != nil {
|
|
return fmt.Errorf("failed to write config: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *schema60Migrator) backupConfig(orgPath string) error {
|
|
c := config.GetInstance()
|
|
|
|
// save a backup of the original config file
|
|
backupPath := fmt.Sprintf("%s.59.%s", orgPath, time.Now().Format("20060102_150405"))
|
|
|
|
data, err := c.Marshal()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal backup config: %w", err)
|
|
}
|
|
|
|
logger.Infof("Backing up config to %s", backupPath)
|
|
if err := os.WriteFile(backupPath, data, 0644); err != nil {
|
|
return fmt.Errorf("failed to write backup config: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func init() {
|
|
sqlite.RegisterPostMigration(60, post60)
|
|
}
|