Move more implementation to data module (#8971)

(cherry picked from commit aee785a8bbf95bd8b2ce975a25cf68dc302f363b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt
This commit is contained in:
Andreas
2023-01-22 17:44:39 +01:00
committed by Jobobby04
parent 8d4e51d4fc
commit 120ea4c768
14 changed files with 19 additions and 16 deletions
+1
View File
@@ -23,6 +23,7 @@ android {
dependencies {
implementation(project(":source-api"))
implementation(project(":domain"))
implementation(project(":core"))
api(libs.sqldelight.android.driver)
api(libs.sqldelight.coroutines)
api(libs.sqldelight.android.paging)
@@ -0,0 +1,37 @@
package tachiyomi.data.history
import tachiyomi.domain.history.model.History
import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.domain.manga.model.MangaCover
import java.util.Date
val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readAt, readDuration ->
History(
id = id,
chapterId = chapterId,
readAt = readAt,
readDuration = readDuration,
)
}
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?, Long) -> HistoryWithRelations = {
historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
HistoryWithRelations(
id = historyId,
chapterId = chapterId,
mangaId = mangaId,
// SY -->
ogTitle = title,
// SY <--
chapterNumber = chapterNumber,
readAt = readAt,
readDuration = readDuration,
coverData = MangaCover(
mangaId = mangaId,
sourceId = sourceId,
isMangaFavorite = isFavorite,
url = thumbnailUrl,
lastModified = coverLastModified,
),
)
}
@@ -0,0 +1,77 @@
package tachiyomi.data.history
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
import tachiyomi.data.DatabaseHandler
import tachiyomi.domain.history.model.History
import tachiyomi.domain.history.model.HistoryUpdate
import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.domain.history.repository.HistoryRepository
class HistoryRepositoryImpl(
private val handler: DatabaseHandler,
) : HistoryRepository {
override fun getHistory(query: String): Flow<List<HistoryWithRelations>> {
return handler.subscribeToList {
historyViewQueries.history(query, historyWithRelationsMapper)
}
}
override suspend fun getLastHistory(): HistoryWithRelations? {
return handler.awaitOneOrNull {
historyViewQueries.getLatestHistory(historyWithRelationsMapper)
}
}
override suspend fun getTotalReadDuration(): Long {
return handler.awaitOne { historyQueries.getReadDuration() }
}
override suspend fun resetHistory(historyId: Long) {
try {
handler.await { historyQueries.resetHistoryById(historyId) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
override suspend fun resetHistoryByMangaId(mangaId: Long) {
try {
handler.await { historyQueries.resetHistoryByMangaId(mangaId) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
override suspend fun deleteAllHistory(): Boolean {
return try {
handler.await { historyQueries.removeAllHistory() }
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
false
}
}
override suspend fun upsertHistory(historyUpdate: HistoryUpdate) {
try {
handler.await {
historyQueries.upsert(
historyUpdate.chapterId,
historyUpdate.readAt,
historyUpdate.sessionReadDuration,
)
}
} catch (e: Exception) {
logcat(LogPriority.ERROR, throwable = e)
}
}
// SY -->
override suspend fun getByMangaId(mangaId: Long): List<History> {
return handler.awaitList { historyQueries.getHistoryByMangaId(mangaId, historyMapper) }
}
// SY <--
}
@@ -0,0 +1,105 @@
package tachiyomi.data.manga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.view.LibraryView
val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?, UpdateStrategy) -> Manga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy ->
Manga(
id = id,
source = source,
favorite = favorite,
lastUpdate = lastUpdate ?: 0,
dateAdded = dateAdded,
viewerFlags = viewerFlags,
chapterFlags = chapterFlags,
coverLastModified = coverLastModified,
url = url,
// SY -->
ogTitle = title,
ogArtist = artist,
ogAuthor = author,
ogDescription = description,
ogGenre = genre,
ogStatus = status,
// SY <--
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
// SY -->
filteredScanlators = filteredScanlators,
// SY <--
)
}
val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?, UpdateStrategy, Long, Long, Long, Long, Long, Long, Long) -> LibraryManga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy, totalCount, readCount, latestUpload, chapterFetchedAt, lastRead, bookmarkCount, category ->
LibraryManga(
manga = mangaMapper(
id,
source,
url,
artist,
author,
description,
genre,
title,
status,
thumbnailUrl,
favorite,
lastUpdate,
nextUpdate,
initialized,
viewerFlags,
chapterFlags,
coverLastModified,
dateAdded,
// SY -->
filteredScanlators,
// SY <--
updateStrategy,
),
category = category,
totalChapters = totalCount,
readCount = readCount,
bookmarkCount = bookmarkCount,
latestUpload = latestUpload,
chapterFetchedAt = chapterFetchedAt,
lastRead = lastRead,
)
}
val libraryViewMapper: (LibraryView) -> LibraryManga = {
LibraryManga(
Manga(
id = it._id,
source = it.source,
favorite = it.favorite,
lastUpdate = it.last_update ?: 0,
dateAdded = it.date_added,
viewerFlags = it.viewer,
chapterFlags = it.chapter_flags,
coverLastModified = it.cover_last_modified,
url = it.url,
ogTitle = it.title,
ogArtist = it.artist,
ogAuthor = it.author,
ogDescription = it.description,
ogGenre = it.genre,
ogStatus = it.status,
thumbnailUrl = it.thumbnail_url,
updateStrategy = it.update_strategy,
initialized = it.initialized,
filteredScanlators = it.filtered_scanlators,
),
it.category,
it.totalCount,
it.readCount,
it.bookmarkCount,
it.latestUpload,
it.chapterFetchedAt,
it.lastRead,
)
}
@@ -0,0 +1,180 @@
package tachiyomi.data.manga
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.toLong
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import logcat.LogPriority
import tachiyomi.data.AndroidDatabaseHandler
import tachiyomi.data.DatabaseHandler
import tachiyomi.data.listOfStringsAdapter
import tachiyomi.data.listOfStringsAndAdapter
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaUpdate
import tachiyomi.domain.manga.repository.MangaRepository
class MangaRepositoryImpl(
private val handler: DatabaseHandler,
) : MangaRepository {
override suspend fun getMangaById(id: Long): Manga {
return handler.awaitOne { mangasQueries.getMangaById(id, mangaMapper) }
}
override suspend fun getMangaByIdAsFlow(id: Long): Flow<Manga> {
return handler.subscribeToOne { mangasQueries.getMangaById(id, mangaMapper) }
}
override suspend fun getMangaByUrlAndSourceId(url: String, sourceId: Long): Manga? {
return handler.awaitOneOrNull(inTransaction = true) { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
}
override fun getMangaByUrlAndSourceIdAsFlow(url: String, sourceId: Long): Flow<Manga?> {
return handler.subscribeToOneOrNull { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
}
override suspend fun getFavorites(): List<Manga> {
return handler.awaitList { mangasQueries.getFavorites(mangaMapper) }
}
override suspend fun getLibraryManga(): List<LibraryManga> {
return handler.awaitList { (handler as AndroidDatabaseHandler).getLibraryQuery() }.map(libraryViewMapper)
// return handler.awaitList { libraryViewQueries.library(libraryManga) }
}
override fun getLibraryMangaAsFlow(): Flow<List<LibraryManga>> {
return handler.subscribeToList { libraryViewQueries.library(libraryManga) }
// SY -->
.map { getLibraryManga() }
// SY <--
}
override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> {
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
}
override suspend fun getDuplicateLibraryManga(title: String): Manga? {
return handler.awaitOneOrNull {
mangasQueries.getDuplicateLibraryManga(title, mangaMapper)
}
}
override suspend fun resetViewerFlags(): Boolean {
return try {
handler.await { mangasQueries.resetViewerFlags() }
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
override suspend fun setMangaCategories(mangaId: Long, categoryIds: List<Long>) {
handler.await(inTransaction = true) {
mangas_categoriesQueries.deleteMangaCategoryByMangaId(mangaId)
categoryIds.map { categoryId ->
mangas_categoriesQueries.insert(mangaId, categoryId)
}
}
}
override suspend fun insert(manga: Manga): Long? {
return handler.awaitOneOrNull(inTransaction = true) {
// SY -->
if (mangasQueries.getIdByUrlAndSource(manga.url, manga.source).executeAsOneOrNull() != null) {
return@awaitOneOrNull mangasQueries.getIdByUrlAndSource(manga.url, manga.source)
}
// SY <--
mangasQueries.insert(
source = manga.source,
url = manga.url,
artist = manga.artist,
author = manga.author,
description = manga.description,
genre = manga.genre,
title = manga.title,
status = manga.status,
thumbnailUrl = manga.thumbnailUrl,
favorite = manga.favorite,
lastUpdate = manga.lastUpdate,
nextUpdate = null,
initialized = manga.initialized,
viewerFlags = manga.viewerFlags,
chapterFlags = manga.chapterFlags,
coverLastModified = manga.coverLastModified,
dateAdded = manga.dateAdded,
// SY -->
filteredScanlators = manga.filteredScanlators,
// SY <--
updateStrategy = manga.updateStrategy,
)
mangasQueries.selectLastInsertedRowId()
}
}
override suspend fun update(update: MangaUpdate): Boolean {
return try {
partialUpdate(update)
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
override suspend fun updateAll(mangaUpdates: List<MangaUpdate>): Boolean {
return try {
partialUpdate(*mangaUpdates.toTypedArray())
true
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
false
}
}
private suspend fun partialUpdate(vararg mangaUpdates: MangaUpdate) {
handler.await(inTransaction = true) {
mangaUpdates.forEach { value ->
mangasQueries.update(
source = value.source,
url = value.url,
artist = value.artist,
author = value.author,
description = value.description,
genre = value.genre?.let(listOfStringsAdapter::encode),
title = value.title,
status = value.status,
thumbnailUrl = value.thumbnailUrl,
favorite = value.favorite?.toLong(),
lastUpdate = value.lastUpdate,
initialized = value.initialized?.toLong(),
viewer = value.viewerFlags,
chapterFlags = value.chapterFlags,
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
// SY -->
filteredScanlators = value.filteredScanlators?.let(listOfStringsAndAdapter::encode),
// SY <--
mangaId = value.id,
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
)
}
}
}
// SY -->
override suspend fun getMangaBySourceId(sourceId: Long): List<Manga> {
return handler.awaitList { mangasQueries.getBySource(sourceId, mangaMapper) }
}
override suspend fun getAll(): List<Manga> {
return handler.awaitList { mangasQueries.getAll(mangaMapper) }
}
override suspend fun deleteManga(mangaId: Long) {
handler.await { mangasQueries.deleteById(mangaId) }
}
// SY <--
}
@@ -0,0 +1,52 @@
package tachiyomi.data.updates
import tachiyomi.domain.manga.model.MangaCover
import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.view.UpdatesView
val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boolean, Long, Long, Boolean, String?, Long, Long, Long) -> UpdatesWithRelations = {
mangaId, mangaTitle, chapterId, chapterName, scanlator, read, bookmark, lastPageRead, sourceId, favorite, thumbnailUrl, coverLastModified, _, dateFetch ->
UpdatesWithRelations(
mangaId = mangaId,
// SY -->
ogMangaTitle = mangaTitle,
// SY <--
chapterId = chapterId,
chapterName = chapterName,
scanlator = scanlator,
read = read,
bookmark = bookmark,
lastPageRead = lastPageRead,
sourceId = sourceId,
dateFetch = dateFetch,
coverData = MangaCover(
mangaId = mangaId,
sourceId = sourceId,
isMangaFavorite = favorite,
url = thumbnailUrl,
lastModified = coverLastModified,
),
)
}
val updatesViewMapper: (UpdatesView) -> UpdatesWithRelations = {
UpdatesWithRelations(
mangaId = it.mangaId,
ogMangaTitle = it.mangaTitle,
chapterId = it.chapterId,
chapterName = it.chapterName,
scanlator = it.scanlator,
read = it.read,
bookmark = it.bookmark,
lastPageRead = it.last_page_read,
sourceId = it.source,
dateFetch = it.datefetch,
coverData = MangaCover(
mangaId = it.mangaId,
sourceId = it.source,
isMangaFavorite = it.favorite,
url = it.thumbnailUrl,
lastModified = it.coverLastModified,
),
)
}
@@ -0,0 +1,22 @@
package tachiyomi.data.updates
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import tachiyomi.data.AndroidDatabaseHandler
import tachiyomi.data.DatabaseHandler
import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.domain.updates.repository.UpdatesRepository
class UpdatesRepositoryImpl(
val databaseHandler: DatabaseHandler,
) : UpdatesRepository {
override fun subscribeAll(after: Long): Flow<List<UpdatesWithRelations>> {
return databaseHandler.subscribeToList {
updatesViewQueries.updates(after, updateWithRelationMapper)
}.map {
databaseHandler.awaitList { (databaseHandler as AndroidDatabaseHandler).getUpdatesQuery(after) }
.map(updatesViewMapper)
}
}
}