Просмотр исходного кода

修复已删除 TTS 引擎重启后恢复

5151561 3 месяцев назад
Родитель
Сommit
064efe3a0c

+ 15 - 0
app/src/main/java/io/legado/app/data/dao/CloudTtsEngineDao.kt

@@ -22,6 +22,21 @@ interface CloudTtsEngineDao {
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun upsert(engine: CloudTtsEngineEntity)
 
+    @Query(
+        """
+        update cloud_tts_engines
+        set apiKey = :newApiKey, secretKey = :newSecretKey
+        where id = :id and apiKey = :oldApiKey and secretKey = :oldSecretKey
+        """
+    )
+    suspend fun updateCredentials(
+        id: String,
+        oldApiKey: String,
+        oldSecretKey: String,
+        newApiKey: String,
+        newSecretKey: String,
+    )
+
     @Delete
     suspend fun delete(engine: CloudTtsEngineEntity)
 }

+ 13 - 2
app/src/main/java/io/legado/app/data/repository/CloudTtsEngineRepository.kt

@@ -28,7 +28,7 @@ class CloudTtsEngineRepository(
     override suspend fun get(id: String): CloudTtsEngine? = withContext(Dispatchers.IO) {
         dao.get(id)?.let { engine ->
             val encrypted = engine.encryptCredentials(credentialCipher)
-            if (encrypted != engine) dao.upsert(encrypted)
+            if (encrypted != engine) dao.updateCredentials(engine, encrypted)
             toDomain(engine)
         }
     }
@@ -46,9 +46,20 @@ class CloudTtsEngineRepository(
     private suspend fun encryptLegacyCredentials(engines: List<CloudTtsEngineEntity>) {
         engines.forEach { engine ->
             val encrypted = engine.encryptCredentials(credentialCipher)
-            if (encrypted != engine) dao.upsert(encrypted)
+            if (encrypted != engine) dao.updateCredentials(engine, encrypted)
         }
     }
+
+    private suspend fun CloudTtsEngineDao.updateCredentials(
+        old: CloudTtsEngineEntity,
+        new: CloudTtsEngineEntity,
+    ) = updateCredentials(
+        id = old.id,
+        oldApiKey = old.apiKey,
+        oldSecretKey = old.secretKey,
+        newApiKey = new.apiKey,
+        newSecretKey = new.secretKey,
+    )
 }
 
 private fun CloudTtsEngineEntity.encryptCredentials(cipher: CloudTtsCredentialCipher) = copy(

+ 60 - 0
app/src/test/java/io/legado/app/data/dao/CloudTtsEngineDaoTest.kt

@@ -0,0 +1,60 @@
+package io.legado.app.data.dao
+
+import android.app.Application
+import androidx.room.Room
+import io.legado.app.data.AppDatabase
+import io.legado.app.data.entities.CloudTtsEngineEntity
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.RuntimeEnvironment
+import org.robolectric.annotation.Config
+
+@RunWith(RobolectricTestRunner::class)
+@Config(application = Application::class, sdk = [35])
+class CloudTtsEngineDaoTest {
+
+    private lateinit var database: AppDatabase
+    private lateinit var dao: CloudTtsEngineDao
+
+    @Before
+    fun setUp() {
+        database = Room.inMemoryDatabaseBuilder(
+            RuntimeEnvironment.getApplication(),
+            AppDatabase::class.java,
+        ).allowMainThreadQueries().build()
+        dao = database.cloudTtsEngineDao
+    }
+
+    @After
+    fun tearDown() {
+        database.close()
+    }
+
+    @Test
+    fun `旧凭据迁移不会恢复已删除的引擎`() = runBlocking {
+        val engine = CloudTtsEngineEntity(
+            id = "deleted-engine",
+            name = "Deleted engine",
+            provider = "openai_speech",
+            apiKey = "plain-api-key",
+            secretKey = "plain-secret-key",
+        )
+        dao.upsert(engine)
+        dao.delete(engine)
+
+        dao.updateCredentials(
+            id = engine.id,
+            oldApiKey = engine.apiKey,
+            oldSecretKey = engine.secretKey,
+            newApiKey = "enc:v1:api-key",
+            newSecretKey = "enc:v1:secret-key",
+        )
+
+        assertNull(dao.get(engine.id))
+    }
+}