database.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package database // import "miniflux.app/v2/internal/database"
  4. import (
  5. "database/sql"
  6. "fmt"
  7. "log/slog"
  8. )
  9. // Migrate executes database migrations.
  10. func Migrate(db *sql.DB) error {
  11. var currentVersion int
  12. db.QueryRow(`SELECT version FROM schema_version`).Scan(&currentVersion)
  13. slog.Info("Running database migrations",
  14. slog.Int("current_version", currentVersion),
  15. slog.Int("latest_version", schemaVersion),
  16. )
  17. for version := currentVersion; version < schemaVersion; version++ {
  18. newVersion := version + 1
  19. tx, err := db.Begin()
  20. if err != nil {
  21. return fmt.Errorf("[Migration v%d] %v", newVersion, err)
  22. }
  23. if err := migrations[version](tx); err != nil {
  24. tx.Rollback()
  25. return fmt.Errorf("[Migration v%d] %v", newVersion, err)
  26. }
  27. if _, err := tx.Exec(`TRUNCATE schema_version`); err != nil {
  28. tx.Rollback()
  29. return fmt.Errorf("[Migration v%d] %v", newVersion, err)
  30. }
  31. if _, err := tx.Exec(`INSERT INTO schema_version (version) VALUES ($1)`, newVersion); err != nil {
  32. tx.Rollback()
  33. return fmt.Errorf("[Migration v%d] %v", newVersion, err)
  34. }
  35. if err := tx.Commit(); err != nil {
  36. return fmt.Errorf("[Migration v%d] %v", newVersion, err)
  37. }
  38. }
  39. return nil
  40. }
  41. // IsSchemaUpToDate checks if the database schema is up to date.
  42. func IsSchemaUpToDate(db *sql.DB) error {
  43. var currentVersion int
  44. db.QueryRow(`SELECT version FROM schema_version`).Scan(&currentVersion)
  45. if currentVersion < schemaVersion {
  46. return fmt.Errorf(`the database schema is not up to date: current=v%d expected=v%d`, currentVersion, schemaVersion)
  47. }
  48. return nil
  49. }