Rewrite meta and add meta mutations (#556)
This commit is contained in:
@@ -21,9 +21,9 @@ import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
|
||||
class CategoryDataLoader : KotlinDataLoader<Int, CategoryType?> {
|
||||
class CategoryDataLoader : KotlinDataLoader<Int, CategoryType> {
|
||||
override val dataLoaderName = "CategoryDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, CategoryType?> = DataLoaderFactory.newDataLoader { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, CategoryType> = DataLoaderFactory.newDataLoader { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
|
||||
@@ -8,25 +8,23 @@ import org.jetbrains.exposed.sql.addLogger
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.global.model.table.GlobalMetaTable
|
||||
import suwayomi.tachidesk.graphql.types.CategoryMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.ChapterMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MangaMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.CategoryMetaType
|
||||
import suwayomi.tachidesk.graphql.types.ChapterMetaType
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaType
|
||||
import suwayomi.tachidesk.graphql.types.MangaMetaType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
|
||||
class GlobalMetaDataLoader : KotlinDataLoader<String, MetaItem?> {
|
||||
class GlobalMetaDataLoader : KotlinDataLoader<String, GlobalMetaType?> {
|
||||
override val dataLoaderName = "GlobalMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<String, MetaItem?> = DataLoaderFactory.newDataLoader<String, MetaItem?> { ids ->
|
||||
override fun getDataLoader(): DataLoader<String, GlobalMetaType?> = DataLoaderFactory.newDataLoader<String, GlobalMetaType?> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = GlobalMetaTable.select { GlobalMetaTable.key inList ids }
|
||||
.map { GlobalMetaItem(it) }
|
||||
.map { GlobalMetaType(it) }
|
||||
.associateBy { it.key }
|
||||
ids.map { metasByRefId[it] }
|
||||
}
|
||||
@@ -34,46 +32,46 @@ class GlobalMetaDataLoader : KotlinDataLoader<String, MetaItem?> {
|
||||
}
|
||||
}
|
||||
|
||||
class ChapterMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
class ChapterMetaDataLoader : KotlinDataLoader<Int, List<ChapterMetaType>> {
|
||||
override val dataLoaderName = "ChapterMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, List<ChapterMetaType>> = DataLoaderFactory.newDataLoader<Int, List<ChapterMetaType>> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = ChapterMetaTable.select { ChapterMetaTable.ref inList ids }
|
||||
.map { ChapterMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
.map { ChapterMetaType(it) }
|
||||
.groupBy { it.chapterId }
|
||||
ids.map { metasByRefId[it].orEmpty() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MangaMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
class MangaMetaDataLoader : KotlinDataLoader<Int, List<MangaMetaType>> {
|
||||
override val dataLoaderName = "MangaMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, List<MangaMetaType>> = DataLoaderFactory.newDataLoader<Int, List<MangaMetaType>> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
|
||||
.map { MangaMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
.map { MangaMetaType(it) }
|
||||
.groupBy { it.mangaId }
|
||||
ids.map { metasByRefId[it].orEmpty() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
class CategoryMetaDataLoader : KotlinDataLoader<Int, List<CategoryMetaType>> {
|
||||
override val dataLoaderName = "CategoryMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, List<CategoryMetaType>> = DataLoaderFactory.newDataLoader<Int, List<CategoryMetaType>> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
|
||||
.map { CategoryMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
val metasByRefId = CategoryMetaTable.select { CategoryMetaTable.ref inList ids }
|
||||
.map { CategoryMetaType(it) }
|
||||
.groupBy { it.categoryId }
|
||||
ids.map { metasByRefId[it].orEmpty() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package suwayomi.tachidesk.graphql.mutations
|
||||
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.CategoryMetaType
|
||||
import suwayomi.tachidesk.manga.impl.Category
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMetaTable
|
||||
|
||||
/**
|
||||
* TODO Mutations
|
||||
* - Name
|
||||
* - Order
|
||||
* - Default
|
||||
* - Create
|
||||
* - Delete
|
||||
*/
|
||||
class CategoryMutation {
|
||||
data class SetCategoryMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val meta: CategoryMetaType
|
||||
)
|
||||
data class SetCategoryMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: CategoryMetaType
|
||||
)
|
||||
fun setCategoryMeta(
|
||||
input: SetCategoryMetaInput
|
||||
): SetCategoryMetaPayload {
|
||||
val (clientMutationId, meta) = input
|
||||
|
||||
Category.modifyMeta(meta.categoryId, meta.key, meta.value)
|
||||
|
||||
return SetCategoryMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
|
||||
data class DeleteCategoryMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val categoryId: Int,
|
||||
val key: String
|
||||
)
|
||||
data class DeleteCategoryMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: CategoryMetaType?
|
||||
)
|
||||
fun deleteCategoryMeta(
|
||||
input: DeleteCategoryMetaInput
|
||||
): DeleteCategoryMetaPayload {
|
||||
val (clientMutationId, categoryId, key) = input
|
||||
|
||||
val meta = transaction {
|
||||
val meta = CategoryMetaTable.select { (CategoryMetaTable.ref eq categoryId) and (CategoryMetaTable.key eq key) }
|
||||
.firstOrNull()
|
||||
|
||||
CategoryMetaTable.deleteWhere { (CategoryMetaTable.ref eq categoryId) and (CategoryMetaTable.key eq key) }
|
||||
|
||||
if (meta != null) {
|
||||
CategoryMetaType(meta)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteCategoryMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,16 @@ package suwayomi.tachidesk.graphql.mutations
|
||||
import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
|
||||
import com.expediagroup.graphql.server.extensions.getValuesFromDataLoader
|
||||
import graphql.schema.DataFetchingEnvironment
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.graphql.types.ChapterMetaType
|
||||
import suwayomi.tachidesk.graphql.types.ChapterType
|
||||
import suwayomi.tachidesk.manga.impl.Chapter
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
import java.time.Instant
|
||||
@@ -15,7 +20,6 @@ import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Mutations
|
||||
* - Check for updates?
|
||||
* - Download
|
||||
* - Delete download
|
||||
*/
|
||||
@@ -124,4 +128,52 @@ class ChapterMutation {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class SetChapterMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val meta: ChapterMetaType
|
||||
)
|
||||
data class SetChapterMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: ChapterMetaType
|
||||
)
|
||||
fun setChapterMeta(
|
||||
input: SetChapterMetaInput
|
||||
): SetChapterMetaPayload {
|
||||
val (clientMutationId, meta) = input
|
||||
|
||||
Chapter.modifyChapterMeta(meta.chapterId, meta.key, meta.value)
|
||||
|
||||
return SetChapterMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
|
||||
data class DeleteChapterMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val chapterId: Int,
|
||||
val key: String
|
||||
)
|
||||
data class DeleteChapterMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: ChapterMetaType?
|
||||
)
|
||||
fun deleteChapterMeta(
|
||||
input: DeleteChapterMetaInput
|
||||
): DeleteChapterMetaPayload {
|
||||
val (clientMutationId, chapterId, key) = input
|
||||
|
||||
val meta = transaction {
|
||||
val meta = ChapterMetaTable.select { (ChapterMetaTable.ref eq chapterId) and (ChapterMetaTable.key eq key) }
|
||||
.firstOrNull()
|
||||
|
||||
ChapterMetaTable.deleteWhere { (ChapterMetaTable.ref eq chapterId) and (ChapterMetaTable.key eq key) }
|
||||
|
||||
if (meta != null) {
|
||||
ChapterMetaType(meta)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteChapterMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package suwayomi.tachidesk.graphql.mutations
|
||||
|
||||
/**
|
||||
* TODO Mutations
|
||||
* - Install
|
||||
* - Update
|
||||
* - Uninstall
|
||||
* - Check for updates (global mutation?)
|
||||
*/
|
||||
class ExtensionMutation
|
||||
@@ -3,12 +3,16 @@ package suwayomi.tachidesk.graphql.mutations
|
||||
import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
|
||||
import com.expediagroup.graphql.server.extensions.getValuesFromDataLoader
|
||||
import graphql.schema.DataFetchingEnvironment
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.graphql.queries.MangaQuery
|
||||
import suwayomi.tachidesk.graphql.types.MangaMetaType
|
||||
import suwayomi.tachidesk.graphql.types.MangaType
|
||||
import suwayomi.tachidesk.manga.impl.Manga
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -17,11 +21,8 @@ import java.util.concurrent.CompletableFuture
|
||||
* TODO Mutations
|
||||
* - Add to category
|
||||
* - Remove from category
|
||||
* - Check for updates
|
||||
* - Download x(all = -1) chapters
|
||||
* - Delete read/all downloaded chapters
|
||||
* - Add/update meta
|
||||
* - Delete meta
|
||||
*/
|
||||
class MangaMutation {
|
||||
data class UpdateMangaPatch(
|
||||
@@ -112,4 +113,52 @@ class MangaMutation {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class SetMangaMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val meta: MangaMetaType
|
||||
)
|
||||
data class SetMangaMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: MangaMetaType
|
||||
)
|
||||
fun setMangaMeta(
|
||||
input: SetMangaMetaInput
|
||||
): SetMangaMetaPayload {
|
||||
val (clientMutationId, meta) = input
|
||||
|
||||
Manga.modifyMangaMeta(meta.mangaId, meta.key, meta.value)
|
||||
|
||||
return SetMangaMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
|
||||
data class DeleteMangaMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val mangaId: Int,
|
||||
val key: String
|
||||
)
|
||||
data class DeleteMangaMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: MangaMetaType?
|
||||
)
|
||||
fun deleteMangaMeta(
|
||||
input: DeleteMangaMetaInput
|
||||
): DeleteMangaMetaPayload {
|
||||
val (clientMutationId, mangaId, key) = input
|
||||
|
||||
val meta = transaction {
|
||||
val meta = MangaMetaTable.select { (MangaMetaTable.ref eq mangaId) and (MangaMetaTable.key eq key) }
|
||||
.firstOrNull()
|
||||
|
||||
MangaMetaTable.deleteWhere { (MangaMetaTable.ref eq mangaId) and (MangaMetaTable.key eq key) }
|
||||
|
||||
if (meta != null) {
|
||||
MangaMetaType(meta)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteMangaMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package suwayomi.tachidesk.graphql.mutations
|
||||
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.global.impl.GlobalMeta
|
||||
import suwayomi.tachidesk.global.model.table.GlobalMetaTable
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaType
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
|
||||
class MetaMutation {
|
||||
|
||||
data class SetGlobalMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val meta: GlobalMetaType
|
||||
)
|
||||
data class SetGlobalMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: GlobalMetaType
|
||||
)
|
||||
fun setGlobalMeta(
|
||||
input: SetGlobalMetaInput
|
||||
): SetGlobalMetaPayload {
|
||||
val (clientMutationId, meta) = input
|
||||
|
||||
GlobalMeta.modifyMeta(meta.key, meta.value)
|
||||
|
||||
return SetGlobalMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
|
||||
data class DeleteGlobalMetaInput(
|
||||
val clientMutationId: String? = null,
|
||||
val key: String
|
||||
)
|
||||
data class DeleteGlobalMetaPayload(
|
||||
val clientMutationId: String?,
|
||||
val meta: GlobalMetaType?
|
||||
)
|
||||
fun deleteGlobalMeta(
|
||||
input: DeleteGlobalMetaInput
|
||||
): DeleteGlobalMetaPayload {
|
||||
val (clientMutationId, key) = input
|
||||
|
||||
val meta = transaction {
|
||||
val meta = GlobalMetaTable.select { MangaMetaTable.key eq key }
|
||||
.firstOrNull()
|
||||
|
||||
GlobalMetaTable.deleteWhere { GlobalMetaTable.key eq key }
|
||||
|
||||
if (meta != null) {
|
||||
GlobalMetaType(meta)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteGlobalMetaPayload(clientMutationId, meta)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package suwayomi.tachidesk.graphql.mutations
|
||||
|
||||
/**
|
||||
* TODO Mutations
|
||||
* - Browse with filters
|
||||
* - Configure settings
|
||||
*/
|
||||
class SourceMutation
|
||||
@@ -39,18 +39,6 @@ import suwayomi.tachidesk.graphql.types.CategoryType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Queries
|
||||
*
|
||||
* TODO Mutations
|
||||
* - Name
|
||||
* - Order
|
||||
* - Default
|
||||
* - Create
|
||||
* - Delete
|
||||
* - Add/update meta
|
||||
* - Delete meta
|
||||
*/
|
||||
class CategoryQuery {
|
||||
fun category(dataFetchingEnvironment: DataFetchingEnvironment, id: Int): CompletableFuture<CategoryType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader("CategoryDataLoader", id)
|
||||
|
||||
@@ -38,15 +38,6 @@ import suwayomi.tachidesk.graphql.types.ExtensionType
|
||||
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Queries
|
||||
*
|
||||
* TODO Mutations
|
||||
* - Install
|
||||
* - Update
|
||||
* - Uninstall
|
||||
* - Check for updates (global mutation?)
|
||||
*/
|
||||
class ExtensionQuery {
|
||||
fun extension(dataFetchingEnvironment: DataFetchingEnvironment, pkgName: String): CompletableFuture<ExtensionType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader("ExtensionDataLoader", pkgName)
|
||||
|
||||
@@ -42,9 +42,6 @@ import suwayomi.tachidesk.manga.model.table.MangaStatus
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Queries
|
||||
*/
|
||||
class MangaQuery {
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment, id: Int): CompletableFuture<MangaType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader("MangaDataLoader", id)
|
||||
|
||||
@@ -31,25 +31,16 @@ import suwayomi.tachidesk.graphql.server.primitives.QueryResults
|
||||
import suwayomi.tachidesk.graphql.server.primitives.greaterNotUnique
|
||||
import suwayomi.tachidesk.graphql.server.primitives.lessNotUnique
|
||||
import suwayomi.tachidesk.graphql.server.primitives.maybeSwap
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaType
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Queries
|
||||
*
|
||||
* TODO Mutations
|
||||
* - Add/update meta
|
||||
* - Delete meta
|
||||
*
|
||||
*/
|
||||
class MetaQuery {
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment, key: String): CompletableFuture<MetaItem?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, MetaItem?>("GlobalMetaDataLoader", key)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment, key: String): CompletableFuture<GlobalMetaType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, GlobalMetaType?>("GlobalMetaDataLoader", key)
|
||||
}
|
||||
|
||||
enum class MetaOrderBy(override val column: Column<out Comparable<*>>) : OrderBy<MetaItem> {
|
||||
enum class MetaOrderBy(override val column: Column<out Comparable<*>>) : OrderBy<GlobalMetaType> {
|
||||
KEY(GlobalMetaTable.key),
|
||||
VALUE(GlobalMetaTable.value);
|
||||
|
||||
@@ -67,7 +58,7 @@ class MetaQuery {
|
||||
}
|
||||
}
|
||||
|
||||
override fun asCursor(type: MetaItem): Cursor {
|
||||
override fun asCursor(type: GlobalMetaType): Cursor {
|
||||
val value = when (this) {
|
||||
KEY -> type.key
|
||||
VALUE -> type.key + "\\-" + type.value
|
||||
@@ -114,7 +105,7 @@ class MetaQuery {
|
||||
first: Int? = null,
|
||||
last: Int? = null,
|
||||
offset: Int? = null
|
||||
): MetaNodeList {
|
||||
): GlobalMetaNodeList {
|
||||
val queryResults = transaction {
|
||||
val res = GlobalMetaTable.selectAll()
|
||||
|
||||
@@ -157,24 +148,24 @@ class MetaQuery {
|
||||
QueryResults(total, firstResult, lastResult, res.toList())
|
||||
}
|
||||
|
||||
val getAsCursor: (MetaItem) -> Cursor = (orderBy ?: MetaOrderBy.KEY)::asCursor
|
||||
val getAsCursor: (GlobalMetaType) -> Cursor = (orderBy ?: MetaOrderBy.KEY)::asCursor
|
||||
|
||||
val resultsAsType = queryResults.results.map { GlobalMetaItem(it) }
|
||||
val resultsAsType = queryResults.results.map { GlobalMetaType(it) }
|
||||
|
||||
return MetaNodeList(
|
||||
return GlobalMetaNodeList(
|
||||
resultsAsType,
|
||||
if (resultsAsType.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
listOfNotNull(
|
||||
resultsAsType.firstOrNull()?.let {
|
||||
MetaNodeList.MetaEdge(
|
||||
GlobalMetaNodeList.MetaEdge(
|
||||
getAsCursor(it),
|
||||
it
|
||||
)
|
||||
},
|
||||
resultsAsType.lastOrNull()?.let {
|
||||
MetaNodeList.MetaEdge(
|
||||
GlobalMetaNodeList.MetaEdge(
|
||||
getAsCursor(it),
|
||||
it
|
||||
)
|
||||
|
||||
@@ -39,14 +39,6 @@ import suwayomi.tachidesk.graphql.types.SourceType
|
||||
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* TODO Queries
|
||||
*
|
||||
* TODO Mutations
|
||||
* - Browse with filters
|
||||
* - Configure settings
|
||||
*
|
||||
*/
|
||||
class SourceQuery {
|
||||
fun source(dataFetchingEnvironment: DataFetchingEnvironment, id: Long): CompletableFuture<SourceType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Long, SourceType?>("SourceDataLoader", id)
|
||||
|
||||
+2
@@ -9,6 +9,7 @@ package suwayomi.tachidesk.graphql.server
|
||||
|
||||
import com.expediagroup.graphql.dataloader.KotlinDataLoaderRegistryFactory
|
||||
import suwayomi.tachidesk.graphql.dataLoaders.CategoriesForMangaDataLoader
|
||||
import suwayomi.tachidesk.graphql.dataLoaders.CategoryDataLoader
|
||||
import suwayomi.tachidesk.graphql.dataLoaders.CategoryMetaDataLoader
|
||||
import suwayomi.tachidesk.graphql.dataLoaders.ChapterDataLoader
|
||||
import suwayomi.tachidesk.graphql.dataLoaders.ChapterMetaDataLoader
|
||||
@@ -33,6 +34,7 @@ class TachideskDataLoaderRegistryFactory {
|
||||
ChapterMetaDataLoader(),
|
||||
MangaMetaDataLoader(),
|
||||
MangaForCategoryDataLoader(),
|
||||
CategoryDataLoader(),
|
||||
CategoryMetaDataLoader(),
|
||||
CategoriesForMangaDataLoader(),
|
||||
SourceDataLoader(),
|
||||
|
||||
@@ -12,8 +12,12 @@ import com.expediagroup.graphql.generator.TopLevelObject
|
||||
import com.expediagroup.graphql.generator.hooks.FlowSubscriptionSchemaGeneratorHooks
|
||||
import com.expediagroup.graphql.generator.toSchema
|
||||
import graphql.schema.GraphQLType
|
||||
import suwayomi.tachidesk.graphql.mutations.CategoryMutation
|
||||
import suwayomi.tachidesk.graphql.mutations.ChapterMutation
|
||||
import suwayomi.tachidesk.graphql.mutations.ExtensionMutation
|
||||
import suwayomi.tachidesk.graphql.mutations.MangaMutation
|
||||
import suwayomi.tachidesk.graphql.mutations.MetaMutation
|
||||
import suwayomi.tachidesk.graphql.mutations.SourceMutation
|
||||
import suwayomi.tachidesk.graphql.queries.CategoryQuery
|
||||
import suwayomi.tachidesk.graphql.queries.ChapterQuery
|
||||
import suwayomi.tachidesk.graphql.queries.ExtensionQuery
|
||||
@@ -42,16 +46,20 @@ val schema = toSchema(
|
||||
hooks = CustomSchemaGeneratorHooks()
|
||||
),
|
||||
queries = listOf(
|
||||
TopLevelObject(MangaQuery()),
|
||||
TopLevelObject(ChapterQuery()),
|
||||
TopLevelObject(CategoryQuery()),
|
||||
TopLevelObject(SourceQuery()),
|
||||
TopLevelObject(ChapterQuery()),
|
||||
TopLevelObject(ExtensionQuery()),
|
||||
TopLevelObject(MetaQuery())
|
||||
TopLevelObject(MangaQuery()),
|
||||
TopLevelObject(MetaQuery()),
|
||||
TopLevelObject(SourceQuery())
|
||||
),
|
||||
mutations = listOf(
|
||||
TopLevelObject(CategoryMutation()),
|
||||
TopLevelObject(ChapterMutation()),
|
||||
TopLevelObject(MangaMutation())
|
||||
TopLevelObject(ExtensionMutation()),
|
||||
TopLevelObject(MangaMutation()),
|
||||
TopLevelObject(MetaMutation()),
|
||||
TopLevelObject(SourceMutation())
|
||||
),
|
||||
subscriptions = listOf(
|
||||
TopLevelObject(DownloadSubscription())
|
||||
|
||||
@@ -35,8 +35,8 @@ class CategoryType(
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MangaNodeList>("MangaForCategoryDataLoader", id)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("CategoryMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<CategoryMetaType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<CategoryMetaType>>("CategoryMetaDataLoader", id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,8 @@ class ChapterType(
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MangaType>("MangaDataLoader", mangaId)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("ChapterMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<ChapterMetaType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<ChapterMetaType>>("ChapterMetaDataLoader", id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ class MangaType(
|
||||
return Instant.now().epochSecond.minus(chaptersLastFetchedAt!!)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("MangaMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<MangaMetaType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<MangaMetaType>>("MangaMetaDataLoader", id)
|
||||
}
|
||||
|
||||
fun categories(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<CategoryNodeList> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package suwayomi.tachidesk.graphql.types
|
||||
|
||||
import com.expediagroup.graphql.generator.annotations.GraphQLIgnore
|
||||
import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
|
||||
import graphql.schema.DataFetchingEnvironment
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import suwayomi.tachidesk.global.model.table.GlobalMetaTable
|
||||
import suwayomi.tachidesk.graphql.server.primitives.Cursor
|
||||
@@ -11,44 +12,85 @@ import suwayomi.tachidesk.graphql.server.primitives.PageInfo
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
open class MetaItem(
|
||||
val key: String,
|
||||
val value: String,
|
||||
@GraphQLIgnore
|
||||
val ref: Int?
|
||||
) : Node
|
||||
interface MetaType : Node {
|
||||
val key: String
|
||||
val value: String
|
||||
}
|
||||
|
||||
class ChapterMetaItem(
|
||||
private val row: ResultRow
|
||||
) : MetaItem(row[ChapterMetaTable.key], row[ChapterMetaTable.value], row[ChapterMetaTable.ref].value)
|
||||
class ChapterMetaType(
|
||||
override val key: String,
|
||||
override val value: String,
|
||||
val chapterId: Int
|
||||
) : MetaType {
|
||||
constructor(row: ResultRow) : this(
|
||||
key = row[ChapterMetaTable.key],
|
||||
value = row[ChapterMetaTable.value],
|
||||
chapterId = row[ChapterMetaTable.ref].value
|
||||
)
|
||||
|
||||
class MangaMetaItem(
|
||||
private val row: ResultRow
|
||||
) : MetaItem(row[MangaMetaTable.key], row[MangaMetaTable.value], row[MangaMetaTable.ref].value)
|
||||
fun chapter(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<ChapterType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, ChapterType>("ChapterDataLoader", chapterId)
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryMetaItem(
|
||||
private val row: ResultRow
|
||||
) : MetaItem(row[CategoryMetaTable.key], row[CategoryMetaTable.value], row[CategoryMetaTable.ref].value)
|
||||
class MangaMetaType(
|
||||
override val key: String,
|
||||
override val value: String,
|
||||
val mangaId: Int
|
||||
) : MetaType {
|
||||
constructor(row: ResultRow) : this(
|
||||
key = row[MangaMetaTable.key],
|
||||
value = row[MangaMetaTable.value],
|
||||
mangaId = row[MangaMetaTable.ref].value
|
||||
)
|
||||
|
||||
class GlobalMetaItem(
|
||||
private val row: ResultRow
|
||||
) : MetaItem(row[GlobalMetaTable.key], row[GlobalMetaTable.value], null)
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MangaType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MangaType>("MangaDataLoader", mangaId)
|
||||
}
|
||||
}
|
||||
|
||||
data class MetaNodeList(
|
||||
override val nodes: List<MetaItem>,
|
||||
class CategoryMetaType(
|
||||
override val key: String,
|
||||
override val value: String,
|
||||
val categoryId: Int
|
||||
) : MetaType {
|
||||
constructor(row: ResultRow) : this(
|
||||
key = row[CategoryMetaTable.key],
|
||||
value = row[CategoryMetaTable.value],
|
||||
categoryId = row[CategoryMetaTable.ref].value
|
||||
)
|
||||
|
||||
fun category(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<CategoryType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, CategoryType>("CategoryDataLoader", categoryId)
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalMetaType(
|
||||
override val key: String,
|
||||
override val value: String
|
||||
) : MetaType {
|
||||
constructor(row: ResultRow) : this(
|
||||
key = row[GlobalMetaTable.key],
|
||||
value = row[GlobalMetaTable.value]
|
||||
)
|
||||
}
|
||||
|
||||
data class GlobalMetaNodeList(
|
||||
override val nodes: List<GlobalMetaType>,
|
||||
override val edges: List<MetaEdge>,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class MetaEdge(
|
||||
override val cursor: Cursor,
|
||||
override val node: MetaItem
|
||||
override val node: GlobalMetaType
|
||||
) : Edge()
|
||||
|
||||
companion object {
|
||||
fun List<MetaItem>.toNodeList(): MetaNodeList {
|
||||
return MetaNodeList(
|
||||
fun List<GlobalMetaType>.toNodeList(): GlobalMetaNodeList {
|
||||
return GlobalMetaNodeList(
|
||||
nodes = this,
|
||||
edges = getEdges(),
|
||||
pageInfo = PageInfo(
|
||||
@@ -61,7 +103,7 @@ data class MetaNodeList(
|
||||
)
|
||||
}
|
||||
|
||||
private fun List<MetaItem>.getEdges(): List<MetaEdge> {
|
||||
private fun List<GlobalMetaType>.getEdges(): List<MetaEdge> {
|
||||
if (isEmpty()) return emptyList()
|
||||
return listOf(
|
||||
MetaEdge(
|
||||
|
||||
@@ -307,6 +307,12 @@ object Chapter {
|
||||
val chapterId =
|
||||
ChapterTable.select { (ChapterTable.manga eq mangaId) and (ChapterTable.sourceOrder eq chapterIndex) }
|
||||
.first()[ChapterTable.id].value
|
||||
modifyChapterMeta(chapterId, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun modifyChapterMeta(chapterId: Int, key: String, value: String) {
|
||||
transaction {
|
||||
val meta =
|
||||
ChapterMetaTable.select { (ChapterMetaTable.ref eq chapterId) and (ChapterMetaTable.key eq key) }
|
||||
.firstOrNull()
|
||||
|
||||
Reference in New Issue
Block a user