Эх сурвалжийг харах

[优化] 避免并发风险

HapeLee 8 сар өмнө
parent
commit
7548462379

+ 27 - 20
app/src/main/java/io/legado/app/help/book/BookExtensions.kt

@@ -127,7 +127,7 @@ fun Book.contains(word: String?): Boolean {
 fun Book.canSafelyRebindTo(newBookUrl: String): Boolean {
     if (newBookUrl == bookUrl) return true
     val targetBook = appDb.bookDao.getBook(newBookUrl) ?: return true
-    if (targetBook.bookUrl == bookUrl) return true
+
     val sameOriginName = originName.isNotBlank() && originName == targetBook.originName
     val sameNameAuthor = name.isNotBlank() && author.isNotBlank()
             && name == targetBook.name && author == targetBook.author
@@ -173,27 +173,31 @@ fun Book.getLocalUri(): Uri {
 
     // 查找书籍保存目录
     if (!defaultBookDir.isNullOrBlank()) {
-        val treeUri = Uri.parse(defaultBookDir)
+        val treeUri = defaultBookDir.toUri()
         val treeFileDoc = FileDoc.fromUri(treeUri, true)
+
         if (!treeFileDoc.exists()) {
             appCtx.toastOnUi("书籍保存目录失效,请重新设置!")
         } else {
             val fileDoc = treeFileDoc.find(originName, 5, 100)
             if (fileDoc != null) {
-                localUriCache[bookUrl] = fileDoc.uri
-                //更新bookUrl时要迁移主键,避免save()按新bookUrl插入重复书籍
-                val oldBook = copy()
                 val newBookUrl = fileDoc.toString()
+                val oldBook = copy()
                 if (!oldBook.canSafelyRebindTo(newBookUrl)) {
                     return fileDoc.uri
                 }
-                bookUrl = newBookUrl
-                if (oldBook.bookUrl == bookUrl) {
-                    save()
-                } else {
-                    appDb.bookDao.replace(oldBook, this)
-                    BookHelp.updateCacheFolder(oldBook, this)
+                appDb.runInTransaction {
+
+                    if (oldBook.bookUrl == newBookUrl) {
+                        save()
+                    } else {
+                        val newBook = oldBook.copy(bookUrl = newBookUrl)
+                        appDb.bookDao.replace(oldBook, newBook)
+                        BookHelp.updateCacheFolder(oldBook, newBook)
+                        this.bookUrl = newBookUrl
+                    }
                 }
+                localUriCache[newBookUrl] = fileDoc.uri
                 return fileDoc.uri
             }
         }
@@ -209,20 +213,23 @@ fun Book.getLocalUri(): Uri {
         val treeFileDoc = FileDoc.fromUri(treeUri, true)
         val fileDoc = treeFileDoc.find(originName, 5, 100)
         if (fileDoc != null) {
-            localUriCache[bookUrl] = fileDoc.uri
-            //更新bookUrl时要迁移主键,避免save()按新bookUrl插入重复书籍
-            val oldBook = copy()
             val newBookUrl = fileDoc.toString()
+            val oldBook = copy()
             if (!oldBook.canSafelyRebindTo(newBookUrl)) {
                 return fileDoc.uri
             }
-            bookUrl = newBookUrl
-            if (oldBook.bookUrl == bookUrl) {
-                save()
-            } else {
-                appDb.bookDao.replace(oldBook, this)
-                BookHelp.updateCacheFolder(oldBook, this)
+
+            appDb.runInTransaction {
+                if (oldBook.bookUrl == newBookUrl) {
+                    save()
+                } else {
+                    val newBook = oldBook.copy(bookUrl = newBookUrl)
+                    appDb.bookDao.replace(oldBook, newBook)
+                    BookHelp.updateCacheFolder(oldBook, newBook)
+                    this.bookUrl = newBookUrl
+                }
             }
+            localUriCache[newBookUrl] = fileDoc.uri
             return fileDoc.uri
         }
     }

+ 20 - 10
app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@@ -53,6 +53,7 @@ import io.legado.app.utils.isAbsUrl
 import io.legado.app.utils.isContentScheme
 import io.legado.app.utils.isDataUrl
 import io.legado.app.utils.printOnDebug
+import kotlinx.coroutines.currentCoroutineContext
 import kotlinx.coroutines.runBlocking
 import org.apache.commons.text.StringEscapeUtils
 import splitties.init.appCtx
@@ -63,7 +64,6 @@ import java.io.FileNotFoundException
 import java.io.FileOutputStream
 import java.io.InputStream
 import java.util.regex.Pattern
-import kotlin.coroutines.coroutineContext
 
 /**
  * 书籍文件导入 目录正文解析
@@ -406,7 +406,7 @@ object LocalBook {
         val inputStream = when {
             str.isAbsUrl() -> AnalyzeUrl(
                 str, source = source, callTimeout = 0,
-                coroutineContext = coroutineContext
+                coroutineContext = currentCoroutineContext()
             ).getInputStreamAwait()
 
             str.isDataUrl() -> ByteArrayInputStream(
@@ -461,7 +461,7 @@ object LocalBook {
     fun isOnBookShelf(
         fileName: String
     ): Boolean {
-        return appDb.bookDao.hasFile(fileName) == true
+        return appDb.bookDao.hasFile(fileName)
     }
 
     //文件类书源 合并在线书籍信息 在线 > 本地
@@ -511,13 +511,23 @@ object LocalBook {
                         localBook.cacheLocalUri(fileUri)
                         return true
                     }
-                    localBook.bookUrl = newBookUrl
-                    localBook.origin = BookType.webDavTag + CustomUrl(webDavUrl).toString()
-                    if (oldBook.bookUrl == localBook.bookUrl) {
-                        localBook.save()
-                    } else {
-                        appDb.bookDao.replace(oldBook, localBook)
-                        BookHelp.updateCacheFolder(oldBook, localBook)
+
+                    appDb.runInTransaction {
+                        if (oldBook.bookUrl == newBookUrl) {
+                            localBook.origin =
+                                BookType.webDavTag + CustomUrl(webDavUrl).toString()
+
+                            localBook.save()
+                        } else {
+                            val newBook = oldBook.copy(
+                                bookUrl = newBookUrl,
+                                origin = BookType.webDavTag + CustomUrl(webDavUrl).toString()
+                            )
+                            appDb.bookDao.replace(oldBook, newBook)
+                            BookHelp.updateCacheFolder(oldBook, newBook)
+                            localBook.bookUrl = newBookUrl
+                            localBook.origin = newBook.origin
+                        }
                     }
                 }
             }