mirror of
https://github.com/navidrome/navidrome.git
synced 2026-01-03 06:15:22 +00:00
81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package migrations
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/navidrome/navidrome/consts"
|
|
)
|
|
|
|
// Use this in migrations that need to communicate something important (breaking changes, forced reindexes, etc...)
|
|
func notice(tx *sql.Tx, msg string) {
|
|
if isDBInitialized(tx) {
|
|
line := strings.Repeat("*", len(msg)+8)
|
|
fmt.Printf("\n%s\nNOTICE: %s\n%s\n\n", line, msg, line)
|
|
}
|
|
}
|
|
|
|
// Call this in migrations that requires a full rescan
|
|
func forceFullRescan(tx *sql.Tx) error {
|
|
// If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`.
|
|
_, err := tx.Exec(`ANALYZE;`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(fmt.Sprintf(`
|
|
INSERT OR REPLACE into property (id, value) values ('%s', '1');
|
|
`, consts.FullScanAfterMigrationFlagKey))
|
|
return err
|
|
}
|
|
|
|
// sq := Update(r.tableName).
|
|
// Set("last_scan_started_at", time.Now()).
|
|
// Set("full_scan_in_progress", fullScan).
|
|
// Where(Eq{"id": id})
|
|
|
|
var (
|
|
once sync.Once
|
|
initialized bool
|
|
)
|
|
|
|
func isDBInitialized(tx *sql.Tx) bool {
|
|
once.Do(func() {
|
|
rows, err := tx.Query("select count(*) from property where id=?", consts.InitialSetupFlagKey)
|
|
checkErr(err)
|
|
initialized = checkCount(rows) > 0
|
|
})
|
|
return initialized
|
|
}
|
|
|
|
func checkCount(rows *sql.Rows) (count int) {
|
|
for rows.Next() {
|
|
err := rows.Scan(&count)
|
|
checkErr(err)
|
|
}
|
|
return count
|
|
}
|
|
|
|
func checkErr(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
type (
|
|
execFunc func() error
|
|
execStmtFunc func(stmt string) execFunc
|
|
addColumnFunc func(tableName, columnName, columnType, defaultValue, initialValue string) execFunc
|
|
)
|
|
|
|
func createExecuteFunc(ctx context.Context, tx *sql.Tx) execStmtFunc {
|
|
return func(stmt string) execFunc {
|
|
return func() error {
|
|
_, err := tx.ExecContext(ctx, stmt)
|
|
return err
|
|
}
|
|
}
|
|
}
|