From 055005688aefb186765211f29ab19b28f8b24a7c Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 9 Jun 2026 16:47:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E5=90=8E=E6=9B=B4=E6=96=B0=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/db/migrator/migrator.go | 12 ++++++ internal/db/migrator/migrator_test.go | 59 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) 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) + } +}