Add favorite entry alternative handling, allowing parennt versions to take priority for favorites sync
This commit is contained in:
parent
e9a3463455
commit
282a0c4e16
@ -52,6 +52,7 @@ import tachiyomi.domain.manga.interactor.InsertFlatMetadata
|
|||||||
import tachiyomi.domain.manga.interactor.InsertMergedReference
|
import tachiyomi.domain.manga.interactor.InsertMergedReference
|
||||||
import tachiyomi.domain.manga.interactor.SetCustomMangaInfo
|
import tachiyomi.domain.manga.interactor.SetCustomMangaInfo
|
||||||
import tachiyomi.domain.manga.interactor.SetMangaFilteredScanlators
|
import tachiyomi.domain.manga.interactor.SetMangaFilteredScanlators
|
||||||
|
import tachiyomi.domain.manga.interactor.InsertFavoriteEntryAlternative
|
||||||
import tachiyomi.domain.manga.interactor.UpdateMergedSettings
|
import tachiyomi.domain.manga.interactor.UpdateMergedSettings
|
||||||
import tachiyomi.domain.manga.repository.CustomMangaRepository
|
import tachiyomi.domain.manga.repository.CustomMangaRepository
|
||||||
import tachiyomi.domain.manga.repository.FavoritesEntryRepository
|
import tachiyomi.domain.manga.repository.FavoritesEntryRepository
|
||||||
@ -140,6 +141,7 @@ class SYDomainModule : InjektModule {
|
|||||||
addFactory { GetFavoriteEntries(get()) }
|
addFactory { GetFavoriteEntries(get()) }
|
||||||
addFactory { InsertFavoriteEntries(get()) }
|
addFactory { InsertFavoriteEntries(get()) }
|
||||||
addFactory { DeleteFavoriteEntries(get()) }
|
addFactory { DeleteFavoriteEntries(get()) }
|
||||||
|
addFactory { InsertFavoriteEntryAlternative(get()) }
|
||||||
|
|
||||||
addSingletonFactory<SavedSearchRepository> { SavedSearchRepositoryImpl(get()) }
|
addSingletonFactory<SavedSearchRepository> { SavedSearchRepositoryImpl(get()) }
|
||||||
addFactory { GetSavedSearchById(get()) }
|
addFactory { GetSavedSearchById(get()) }
|
||||||
|
@ -2,6 +2,7 @@ package exh.eh
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
@ -18,6 +19,8 @@ import tachiyomi.domain.history.interactor.UpsertHistory
|
|||||||
import tachiyomi.domain.history.model.History
|
import tachiyomi.domain.history.model.History
|
||||||
import tachiyomi.domain.history.model.HistoryUpdate
|
import tachiyomi.domain.history.model.HistoryUpdate
|
||||||
import tachiyomi.domain.manga.interactor.GetManga
|
import tachiyomi.domain.manga.interactor.GetManga
|
||||||
|
import tachiyomi.domain.manga.interactor.InsertFavoriteEntryAlternative
|
||||||
|
import tachiyomi.domain.manga.model.FavoriteEntryAlternative
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -41,6 +44,7 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
private val upsertHistory: UpsertHistory by injectLazy()
|
private val upsertHistory: UpsertHistory by injectLazy()
|
||||||
private val removeHistory: RemoveHistory by injectLazy()
|
private val removeHistory: RemoveHistory by injectLazy()
|
||||||
private val getHistoryByMangaId: GetHistoryByMangaId by injectLazy()
|
private val getHistoryByMangaId: GetHistoryByMangaId by injectLazy()
|
||||||
|
private val insertFavoriteEntryAlternative: InsertFavoriteEntryAlternative by injectLazy()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param chapters Cannot be an empty list!
|
* @param chapters Cannot be an empty list!
|
||||||
@ -123,6 +127,12 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
upsertHistory.await(it)
|
upsertHistory.await(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update favorites entry database
|
||||||
|
val favoriteEntryUpdate = getFavoriteEntryAlternative(accepted, toDiscard)
|
||||||
|
if (favoriteEntryUpdate != null) {
|
||||||
|
insertFavoriteEntryAlternative.await(favoriteEntryUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
// Copy categories from all chains to accepted manga
|
// Copy categories from all chains to accepted manga
|
||||||
|
|
||||||
val newCategories = rootsToMutate.flatMap { chapterChain ->
|
val newCategories = rootsToMutate.flatMap { chapterChain ->
|
||||||
@ -145,7 +155,24 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHistory(
|
private fun getFavoriteEntryAlternative(
|
||||||
|
accepted: ChapterChain,
|
||||||
|
toDiscard: List<ChapterChain>,
|
||||||
|
): FavoriteEntryAlternative? {
|
||||||
|
val favorite = toDiscard.find { it.manga.favorite } ?: return null
|
||||||
|
|
||||||
|
val gid = EHentaiSearchMetadata.galleryId(accepted.manga.url)
|
||||||
|
val token = EHentaiSearchMetadata.galleryToken(accepted.manga.url)
|
||||||
|
|
||||||
|
return FavoriteEntryAlternative(
|
||||||
|
otherGid = gid,
|
||||||
|
otherToken = token,
|
||||||
|
gid = EHentaiSearchMetadata.galleryId(favorite.manga.url),
|
||||||
|
token = EHentaiSearchMetadata.galleryToken(favorite.manga.url),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHistory(
|
||||||
currentChapters: List<Chapter>,
|
currentChapters: List<Chapter>,
|
||||||
chainsAsChapters: List<Chapter>,
|
chainsAsChapters: List<Chapter>,
|
||||||
chainsAsHistory: List<History>,
|
chainsAsHistory: List<History>,
|
||||||
|
@ -19,14 +19,16 @@ import tachiyomi.domain.manga.interactor.GetFavorites
|
|||||||
import tachiyomi.domain.manga.interactor.InsertFavoriteEntries
|
import tachiyomi.domain.manga.interactor.InsertFavoriteEntries
|
||||||
import tachiyomi.domain.manga.model.FavoriteEntry
|
import tachiyomi.domain.manga.model.FavoriteEntry
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class LocalFavoritesStorage {
|
class LocalFavoritesStorage(
|
||||||
private val getFavorites: GetFavorites by injectLazy()
|
private val getFavorites: GetFavorites = Injekt.get(),
|
||||||
private val getCategories: GetCategories by injectLazy()
|
private val getCategories: GetCategories = Injekt.get(),
|
||||||
private val deleteFavoriteEntries: DeleteFavoriteEntries by injectLazy()
|
private val deleteFavoriteEntries: DeleteFavoriteEntries = Injekt.get(),
|
||||||
private val getFavoriteEntries: GetFavoriteEntries by injectLazy()
|
private val getFavoriteEntries: GetFavoriteEntries = Injekt.get(),
|
||||||
private val insertFavoriteEntries: InsertFavoriteEntries by injectLazy()
|
private val insertFavoriteEntries: InsertFavoriteEntries = Injekt.get(),
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun getChangedDbEntries() = getFavorites.await()
|
suspend fun getChangedDbEntries() = getFavorites.await()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
@ -67,27 +69,29 @@ class LocalFavoritesStorage {
|
|||||||
|
|
||||||
val databaseEntries = getFavoriteEntries.await()
|
val databaseEntries = getFavoriteEntries.await()
|
||||||
|
|
||||||
val added = terminated.filter {
|
val added = terminated.groupBy { it.gid to it.token }
|
||||||
queryListForEntry(databaseEntries, it) == null
|
.filter { (_, values) ->
|
||||||
|
values.all { queryListForEntry(databaseEntries, it) == null }
|
||||||
}
|
}
|
||||||
|
.map { it.value.first() }
|
||||||
|
|
||||||
val removed = databaseEntries
|
val removed = databaseEntries
|
||||||
.filter {
|
.groupBy { it.gid to it.token }
|
||||||
queryListForEntry(terminated, it) == null
|
.filter { (_, values) ->
|
||||||
} /*.map {
|
values.all { queryListForEntry(terminated, it) == null }
|
||||||
todo see what this does
|
}
|
||||||
realm.copyFromRealm(it)
|
.map { it.value.first() }
|
||||||
}*/
|
|
||||||
|
|
||||||
return ChangeSet(added, removed)
|
return ChangeSet(added, removed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FavoriteEntry.urlEquals(other: FavoriteEntry) = (gid == other.gid && token == other.token) ||
|
||||||
|
(otherGid != null && otherToken != null && (otherGid == other.gid && otherToken == other.token)) ||
|
||||||
|
(other.otherGid != null && other.otherToken != null && (gid == other.otherGid && token == other.otherToken)) ||
|
||||||
|
(otherGid != null && otherToken != null && other.otherGid != null && other.otherToken != null && otherGid == other.otherGid && otherToken == other.otherToken)
|
||||||
|
|
||||||
private fun queryListForEntry(list: List<FavoriteEntry>, entry: FavoriteEntry) =
|
private fun queryListForEntry(list: List<FavoriteEntry>, entry: FavoriteEntry) =
|
||||||
list.find {
|
list.find { it.urlEquals(entry) && it.category == entry.category }
|
||||||
it.gid == entry.gid &&
|
|
||||||
it.token == entry.token &&
|
|
||||||
it.category == entry.category
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun Flow<Manga>.loadDbCategories(): Flow<Pair<Int, Manga>> {
|
private suspend fun Flow<Manga>.loadDbCategories(): Flow<Pair<Int, Manga>> {
|
||||||
val dbCategories = getCategories.await()
|
val dbCategories = getCategories.await()
|
||||||
|
178
app/src/test/kotlin/Tester.kt
Normal file
178
app/src/test/kotlin/Tester.kt
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||||
|
import exh.favorites.LocalFavoritesStorage
|
||||||
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
|
import exh.source.EXH_SOURCE_ID
|
||||||
|
import io.kotest.inspectors.shouldForAll
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.serialization.protobuf.ProtoBuf
|
||||||
|
import okio.buffer
|
||||||
|
import okio.gzip
|
||||||
|
import okio.sink
|
||||||
|
import okio.source
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import tachiyomi.domain.category.interactor.GetCategories
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.manga.interactor.GetCustomMangaInfo
|
||||||
|
import tachiyomi.domain.manga.interactor.GetFavoriteEntries
|
||||||
|
import tachiyomi.domain.manga.interactor.GetFavorites
|
||||||
|
import tachiyomi.domain.manga.model.CustomMangaInfo
|
||||||
|
import tachiyomi.domain.manga.model.FavoriteEntry
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.CustomMangaRepository
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.addSingletonFactory
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
|
||||||
|
@Disabled
|
||||||
|
@Test
|
||||||
|
fun stripBackup() {
|
||||||
|
val bytes = File("D:\\Downloads\\pacthiyomi_2023-05-08_13-30.proto (1).gz")
|
||||||
|
.inputStream().source().buffer()
|
||||||
|
.gzip().buffer()
|
||||||
|
.readByteArray()
|
||||||
|
val backup = ProtoBuf.decodeFromByteArray(BackupSerializer, bytes)
|
||||||
|
val newBytes = ProtoBuf.encodeToByteArray(
|
||||||
|
BackupSerializer,
|
||||||
|
backup.copy(
|
||||||
|
backupManga = backup.backupManga.filter { it.favorite },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
File("D:\\Downloads\\pacthiyomi_2023-05-08_13-30 (2).proto.gz").outputStream().sink().gzip().buffer().use {
|
||||||
|
it.write(newBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun localFavoritesStorageTester(): Unit = runBlocking {
|
||||||
|
val favorites = listOf(
|
||||||
|
Manga.create().copy(
|
||||||
|
id = 1,
|
||||||
|
favorite = true,
|
||||||
|
source = EXH_SOURCE_ID,
|
||||||
|
url = "/g/gid/token",
|
||||||
|
),
|
||||||
|
// an alias for gid2/token2
|
||||||
|
Manga.create().copy(
|
||||||
|
id = 3,
|
||||||
|
favorite = true,
|
||||||
|
source = EXH_SOURCE_ID,
|
||||||
|
url = "/g/gid3/token3",
|
||||||
|
),
|
||||||
|
// add this one to library
|
||||||
|
Manga.create().copy(
|
||||||
|
id = 3,
|
||||||
|
favorite = true,
|
||||||
|
source = EXH_SOURCE_ID,
|
||||||
|
url = "/g/gid4/token4",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
val categories = listOf(
|
||||||
|
Category(
|
||||||
|
id = 1,
|
||||||
|
name = "a",
|
||||||
|
order = 1,
|
||||||
|
flags = 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
val favoriteEntries = listOf(
|
||||||
|
FavoriteEntry(
|
||||||
|
gid = "gid",
|
||||||
|
token = "token",
|
||||||
|
title = "a",
|
||||||
|
category = 0,
|
||||||
|
),
|
||||||
|
FavoriteEntry(
|
||||||
|
gid = "gid2",
|
||||||
|
token = "token2",
|
||||||
|
title = "a",
|
||||||
|
category = 0,
|
||||||
|
),
|
||||||
|
// the alias for gid2/token2
|
||||||
|
FavoriteEntry(
|
||||||
|
gid = "gid2",
|
||||||
|
token = "token2",
|
||||||
|
title = "a",
|
||||||
|
category = 0,
|
||||||
|
otherGid = "gid3",
|
||||||
|
otherToken = "token3",
|
||||||
|
),
|
||||||
|
// removed on remote and local
|
||||||
|
FavoriteEntry(
|
||||||
|
gid = "gid6",
|
||||||
|
token = "token6",
|
||||||
|
title = "a",
|
||||||
|
category = 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
val getFavorites = mockk<GetFavorites>()
|
||||||
|
coEvery { getFavorites.await() } returns favorites
|
||||||
|
|
||||||
|
val getCategories = mockk<GetCategories>()
|
||||||
|
coEvery { getCategories.await() } returns categories
|
||||||
|
coEvery { getCategories.await(any()) } returns categories
|
||||||
|
|
||||||
|
val getFavoriteEntries = mockk<GetFavoriteEntries>()
|
||||||
|
coEvery { getFavoriteEntries.await() } returns favoriteEntries
|
||||||
|
|
||||||
|
val storage = LocalFavoritesStorage(
|
||||||
|
getFavorites = getFavorites,
|
||||||
|
getCategories = getCategories,
|
||||||
|
deleteFavoriteEntries = mockk(),
|
||||||
|
getFavoriteEntries = getFavoriteEntries,
|
||||||
|
insertFavoriteEntries = mockk(),
|
||||||
|
)
|
||||||
|
|
||||||
|
val (added, removed) = storage.getChangedDbEntries()
|
||||||
|
added.shouldForAll { it.gid == "gid4" && it.token == "token4" }
|
||||||
|
removed.shouldForAll { it.gid == "gid6" && it.token == "token6" }
|
||||||
|
|
||||||
|
val (remoteAdded, remoteRemoved) = storage.getChangedRemoteEntries(
|
||||||
|
listOf(
|
||||||
|
EHentai.ParsedManga(
|
||||||
|
0,
|
||||||
|
SManga("/g/gid/token", "a"),
|
||||||
|
EHentaiSearchMetadata(),
|
||||||
|
),
|
||||||
|
EHentai.ParsedManga(
|
||||||
|
0,
|
||||||
|
SManga("/g/gid2/token2", "a"),
|
||||||
|
EHentaiSearchMetadata(),
|
||||||
|
),
|
||||||
|
// added on remote
|
||||||
|
EHentai.ParsedManga(
|
||||||
|
0,
|
||||||
|
SManga("/g/gid5/token5", "a"),
|
||||||
|
EHentaiSearchMetadata(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
remoteAdded.shouldForAll { it.gid == "gid5" && it.token == "token5" }
|
||||||
|
remoteRemoved.shouldForAll { it.gid == "gid6" && it.token == "token6" }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@BeforeAll
|
||||||
|
fun before() {
|
||||||
|
Injekt.addSingletonFactory {
|
||||||
|
GetCustomMangaInfo(
|
||||||
|
object : CustomMangaRepository {
|
||||||
|
override fun get(mangaId: Long) = null
|
||||||
|
override fun set(mangaInfo: CustomMangaInfo) = Unit
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,14 @@ package tachiyomi.data.manga
|
|||||||
|
|
||||||
import tachiyomi.domain.manga.model.FavoriteEntry
|
import tachiyomi.domain.manga.model.FavoriteEntry
|
||||||
|
|
||||||
val favoriteEntryMapper: (Long, String, String, String, Long) -> FavoriteEntry =
|
val favoriteEntryMapper: (String, String, String, Long, String?, String?) -> FavoriteEntry =
|
||||||
{ id, title, gid, token, category ->
|
{ gid, token, title, category, otherGid, otherToken ->
|
||||||
FavoriteEntry(
|
FavoriteEntry(
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
gid = gid,
|
gid = gid,
|
||||||
token = token,
|
token = token,
|
||||||
|
title = title,
|
||||||
category = category.toInt(),
|
category = category.toInt(),
|
||||||
|
otherGid = otherGid,
|
||||||
|
otherToken = otherToken,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package tachiyomi.data.manga
|
|||||||
|
|
||||||
import tachiyomi.data.DatabaseHandler
|
import tachiyomi.data.DatabaseHandler
|
||||||
import tachiyomi.domain.manga.model.FavoriteEntry
|
import tachiyomi.domain.manga.model.FavoriteEntry
|
||||||
|
import tachiyomi.domain.manga.model.FavoriteEntryAlternative
|
||||||
import tachiyomi.domain.manga.repository.FavoritesEntryRepository
|
import tachiyomi.domain.manga.repository.FavoritesEntryRepository
|
||||||
|
|
||||||
class FavoritesEntryRepositoryImpl(
|
class FavoritesEntryRepositoryImpl(
|
||||||
@ -14,7 +15,12 @@ class FavoritesEntryRepositoryImpl(
|
|||||||
override suspend fun insertAll(favoriteEntries: List<FavoriteEntry>) {
|
override suspend fun insertAll(favoriteEntries: List<FavoriteEntry>) {
|
||||||
handler.await(true) {
|
handler.await(true) {
|
||||||
favoriteEntries.forEach {
|
favoriteEntries.forEach {
|
||||||
eh_favoritesQueries.insertEhFavorites(it.id, it.title, it.gid, it.token, it.category.toLong())
|
eh_favoritesQueries.insertEhFavorites(
|
||||||
|
title = it.title,
|
||||||
|
gid = it.gid,
|
||||||
|
token = it.token,
|
||||||
|
category = it.category.toLong(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,4 +28,15 @@ class FavoritesEntryRepositoryImpl(
|
|||||||
override suspend fun selectAll(): List<FavoriteEntry> {
|
override suspend fun selectAll(): List<FavoriteEntry> {
|
||||||
return handler.awaitList { eh_favoritesQueries.selectAll(favoriteEntryMapper) }
|
return handler.awaitList { eh_favoritesQueries.selectAll(favoriteEntryMapper) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun addAlternative(favoriteEntryAlternative: FavoriteEntryAlternative) {
|
||||||
|
handler.await {
|
||||||
|
eh_favoritesQueries.addAlternative(
|
||||||
|
otherGid = favoriteEntryAlternative.otherGid,
|
||||||
|
otherToken = favoriteEntryAlternative.otherToken,
|
||||||
|
gid = favoriteEntryAlternative.gid,
|
||||||
|
token = favoriteEntryAlternative.token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,34 @@
|
|||||||
CREATE TABLE eh_favorites (
|
CREATE TABLE eh_favorites (
|
||||||
_id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
gid TEXT NOT NULL,
|
gid TEXT NOT NULL,
|
||||||
token TEXT NOT NULL,
|
token TEXT NOT NULL,
|
||||||
category INTEGER NOT NULL
|
title TEXT NOT NULL,
|
||||||
|
category INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (gid, token)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE eh_favorites_alternatives (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
gid TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
otherGid TEXT NOT NULL,
|
||||||
|
otherToken TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (gid, token) REFERENCES eh_favorites(gid, token)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX eh_favorites_alternatives_gid_token_index ON eh_favorites_alternatives(gid, token);
|
||||||
|
CREATE INDEX eh_favorites_alternatives_other_gid_token_index ON eh_favorites_alternatives(otherGid, otherToken);
|
||||||
|
|
||||||
selectAll:
|
selectAll:
|
||||||
SELECT * FROM eh_favorites;
|
SELECT f.gid, f.token, f.title, f.category, a.otherGid, a.otherToken
|
||||||
|
FROM eh_favorites AS f
|
||||||
|
LEFT JOIN eh_favorites_alternatives AS a ON f.gid = a.gid AND f.token = a.token;
|
||||||
|
|
||||||
insertEhFavorites:
|
insertEhFavorites:
|
||||||
INSERT INTO eh_favorites (_id, title, gid, token, category) VALUES (?, ?, ?, ?, ?);
|
INSERT INTO eh_favorites (title, gid, token, category) VALUES (?, ?, ?, ?);
|
||||||
|
|
||||||
deleteAll:
|
deleteAll:
|
||||||
DELETE FROM eh_favorites;
|
DELETE FROM eh_favorites;
|
||||||
|
|
||||||
|
addAlternative:
|
||||||
|
INSERT INTO eh_favorites_alternatives (gid, token, otherGid, otherToken)
|
||||||
|
VALUES (:gid, :token, :otherGid, :otherToken);
|
25
data/src/main/sqldelight/tachiyomi/migrations/26.sqm
Normal file
25
data/src/main/sqldelight/tachiyomi/migrations/26.sqm
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
ALTER TABLE eh_favorites RENAME TO eh_favorites_temp;
|
||||||
|
CREATE TABLE eh_favorites (
|
||||||
|
gid TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
category INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (gid, token)
|
||||||
|
);
|
||||||
|
INSERT INTO eh_favorites
|
||||||
|
SELECT gid, token, title, category
|
||||||
|
FROM eh_favorites_temp;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS eh_favorites_temp;
|
||||||
|
|
||||||
|
CREATE TABLE eh_favorites_alternatives (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
gid TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
otherGid TEXT NOT NULL,
|
||||||
|
otherToken TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (gid, token) REFERENCES eh_favorites(gid, token)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX eh_favorites_alternatives_gid_token_index ON eh_favorites_alternatives(gid, token);
|
||||||
|
CREATE INDEX eh_favorites_alternatives_other_gid_token_index ON eh_favorites_alternatives(otherGid, otherToken);
|
@ -0,0 +1,13 @@
|
|||||||
|
package tachiyomi.domain.manga.interactor
|
||||||
|
|
||||||
|
import tachiyomi.domain.manga.model.FavoriteEntryAlternative
|
||||||
|
import tachiyomi.domain.manga.repository.FavoritesEntryRepository
|
||||||
|
|
||||||
|
class InsertFavoriteEntryAlternative(
|
||||||
|
private val favoriteEntryRepository: FavoritesEntryRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun await(entry: FavoriteEntryAlternative) {
|
||||||
|
return favoriteEntryRepository.addAlternative(entry)
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ package tachiyomi.domain.manga.model
|
|||||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
|
|
||||||
data class FavoriteEntry(
|
data class FavoriteEntry(
|
||||||
val id: Long? = null,
|
|
||||||
|
|
||||||
val title: String,
|
val title: String,
|
||||||
|
|
||||||
@ -11,6 +10,10 @@ data class FavoriteEntry(
|
|||||||
|
|
||||||
val token: String,
|
val token: String,
|
||||||
|
|
||||||
|
val otherGid: String? = null,
|
||||||
|
|
||||||
|
val otherToken: String? = null,
|
||||||
|
|
||||||
val category: Int = -1,
|
val category: Int = -1,
|
||||||
) {
|
) {
|
||||||
fun getUrl() = EHentaiSearchMetadata.idAndTokenToUrl(gid, token)
|
fun getUrl() = EHentaiSearchMetadata.idAndTokenToUrl(gid, token)
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package tachiyomi.domain.manga.model
|
||||||
|
|
||||||
|
data class FavoriteEntryAlternative(
|
||||||
|
val otherGid: String,
|
||||||
|
val otherToken: String,
|
||||||
|
val gid: String,
|
||||||
|
val token: String,
|
||||||
|
)
|
@ -1,6 +1,7 @@
|
|||||||
package tachiyomi.domain.manga.repository
|
package tachiyomi.domain.manga.repository
|
||||||
|
|
||||||
import tachiyomi.domain.manga.model.FavoriteEntry
|
import tachiyomi.domain.manga.model.FavoriteEntry
|
||||||
|
import tachiyomi.domain.manga.model.FavoriteEntryAlternative
|
||||||
|
|
||||||
interface FavoritesEntryRepository {
|
interface FavoritesEntryRepository {
|
||||||
suspend fun deleteAll()
|
suspend fun deleteAll()
|
||||||
@ -8,4 +9,6 @@ interface FavoritesEntryRepository {
|
|||||||
suspend fun insertAll(favoriteEntries: List<FavoriteEntry>)
|
suspend fun insertAll(favoriteEntries: List<FavoriteEntry>)
|
||||||
|
|
||||||
suspend fun selectAll(): List<FavoriteEntry>
|
suspend fun selectAll(): List<FavoriteEntry>
|
||||||
|
|
||||||
|
suspend fun addAlternative(favoriteEntryAlternative: FavoriteEntryAlternative)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user