diff --git a/internal/db/migrator/migrator.go b/internal/db/migrator/migrator.go index 1461727c..0027417a 100644 --- a/internal/db/migrator/migrator.go +++ b/internal/db/migrator/migrator.go @@ -25,6 +25,7 @@ import ( "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" + "github.com/Rain-kl/Wavelet/internal/model" "github.com/pressly/goose/v3" ) @@ -75,5 +76,16 @@ func Migrate() { log.Fatalf("[%s] goose migrate failed: %v\n", dbType(), err) } + clearSystemConfigCache() + log.Printf("[%s] goose migrate success\n", dbType()) } + +func clearSystemConfigCache() { + if db.Redis == nil { + return + } + if err := db.Redis.Del(context.Background(), db.PrefixedKey(model.SystemConfigRedisHashKey)).Err(); err != nil { + log.Printf("[%s] clear system config cache failed: %v\n", dbType(), err) + } +} diff --git a/internal/db/migrator/migrator_test.go b/internal/db/migrator/migrator_test.go index 0c8cb957..525328ca 100644 --- a/internal/db/migrator/migrator_test.go +++ b/internal/db/migrator/migrator_test.go @@ -17,11 +17,15 @@ limitations under the License. package migrator import ( + "context" "testing" "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" + "github.com/Rain-kl/Wavelet/internal/model" + "github.com/alicebob/miniredis/v2" "github.com/glebarez/sqlite" + "github.com/redis/go-redis/v9" "gorm.io/gorm" ) @@ -67,3 +71,58 @@ func TestMigrateInitializesSQLiteDatabase(t *testing.T) { t.Errorf("Migrate() templates count = %d, want %d", templateCount, 2) } } + +func TestMigrateClearsStaleSystemConfigCache(t *testing.T) { + sqliteDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ + DisableForeignKeyConstraintWhenMigrating: true, + }) + if err != nil { + t.Fatalf("gorm.Open(sqlite) error = %v", err) + } + + mr, err := miniredis.Run() + if err != nil { + t.Fatalf("miniredis.Run() error = %v", err) + } + redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + + previousDBEnabled := config.Config.Database.Enabled + previousRedis := db.Redis + config.Config.Database.Enabled = false + db.SetDB(sqliteDB) + db.Redis = redisClient + t.Cleanup(func() { + config.Config.Database.Enabled = previousDBEnabled + db.SetDB(nil) + db.Redis = previousRedis + _ = redisClient.Close() + mr.Close() + }) + + staleConfig := model.SystemConfig{ + Key: model.ConfigKeyCapLoginEnabled, + Value: "true", + Type: "system", + } + if err := db.HSetJSON(context.Background(), model.SystemConfigRedisHashKey, model.ConfigKeyCapLoginEnabled, &staleConfig); err != nil { + t.Fatalf("HSetJSON() error = %v", err) + } + + Migrate() + + exists, err := db.Redis.Exists(context.Background(), db.PrefixedKey(model.SystemConfigRedisHashKey)).Result() + if err != nil { + t.Fatalf("Redis.Exists() error = %v", err) + } + if exists != 0 { + t.Fatalf("system config cache exists = %d, want 0", exists) + } + + enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) + if err != nil { + t.Fatalf("GetBoolByKey(%s) error = %v", model.ConfigKeyCapLoginEnabled, err) + } + if enabled { + t.Fatalf("GetBoolByKey(%s) = true, want false", model.ConfigKeyCapLoginEnabled) + } +}