Skip to content

Commit

Permalink
Add categories to graphql
Browse files Browse the repository at this point in the history
  • Loading branch information
martinek authored and Syer10 committed Mar 30, 2023
1 parent 623172a commit bf7f1a0
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

package suwayomi.tachidesk.graphql.dataLoaders

import com.expediagroup.graphql.dataloader.KotlinDataLoader
import org.dataloader.DataLoader
import org.dataloader.DataLoaderFactory
import org.jetbrains.exposed.sql.StdOutSqlLogger
import org.jetbrains.exposed.sql.addLogger
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.graphql.types.CategoryType
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
import suwayomi.tachidesk.manga.model.table.CategoryTable
import java.util.concurrent.CompletableFuture

class CategoryDataLoader : KotlinDataLoader<Int, CategoryType> {
override val dataLoaderName = "CategoryDataLoader"
override fun getDataLoader(): DataLoader<Int, CategoryType> = DataLoaderFactory.newDataLoader<Int, CategoryType> { ids ->
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
CategoryTable.select { CategoryTable.id inList ids }
.map { CategoryType(it) }
}
}
}
}

class CategoriesForMangaDataLoader : KotlinDataLoader<Int, List<CategoryType>> {
override val dataLoaderName = "CategoriesForMangaDataLoader"
override fun getDataLoader(): DataLoader<Int, List<CategoryType>> = DataLoaderFactory.newDataLoader<Int, List<CategoryType>> { ids ->
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
val itemsByRef = CategoryMangaTable.innerJoin(CategoryTable).select { CategoryMangaTable.manga inList ids }
.map { Pair(it[CategoryMangaTable.manga].value, CategoryType(it)) }
.groupBy { it.first }
.mapValues { it.value.map { pair -> pair.second } }
ids.map { itemsByRef[it] ?: emptyList() }
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ package suwayomi.tachidesk.graphql.dataLoaders
import com.expediagroup.graphql.dataloader.KotlinDataLoader
import org.dataloader.DataLoader
import org.dataloader.DataLoaderFactory
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
import org.jetbrains.exposed.sql.StdOutSqlLogger
import org.jetbrains.exposed.sql.addLogger
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.graphql.types.MangaType
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
import suwayomi.tachidesk.manga.model.table.MangaTable
import java.util.concurrent.CompletableFuture

Expand All @@ -30,3 +32,19 @@ class MangaDataLoader : KotlinDataLoader<Int, MangaType> {
}
}
}

class MangaForCategoryDataLoader : KotlinDataLoader<Int, List<MangaType>> {
override val dataLoaderName = "MangaForCategoryDataLoader"
override fun getDataLoader(): DataLoader<Int, List<MangaType>> = DataLoaderFactory.newDataLoader<Int, List<MangaType>> { ids ->
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
val itemsByRef = CategoryMangaTable.innerJoin(MangaTable).select { CategoryMangaTable.category inList ids }
.map { Pair(it[CategoryMangaTable.category].value, MangaType(it)) }
.groupBy { it.first }
.mapValues { it.value.map { pair -> pair.second } }
ids.map { itemsByRef[it] ?: emptyList() }
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.jetbrains.exposed.sql.StdOutSqlLogger
import org.jetbrains.exposed.sql.addLogger
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.graphql.types.CategoryMetaItem
import suwayomi.tachidesk.graphql.types.ChapterMetaItem
import suwayomi.tachidesk.graphql.types.MangaMetaItem
import suwayomi.tachidesk.graphql.types.MetaType
Expand All @@ -20,10 +21,10 @@ class ChapterMetaDataLoader : KotlinDataLoader<Int, MetaType> {
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
val metasByChapterId = ChapterMetaTable.select { ChapterMetaTable.ref inList ids }
val metasByRefId = ChapterMetaTable.select { ChapterMetaTable.ref inList ids }
.map { ChapterMetaItem(it) }
.groupBy { it.ref }
ids.map { metasByChapterId[it] ?: emptyList() }
ids.map { metasByRefId[it] ?: emptyList() }
}
}
}
Expand All @@ -35,10 +36,25 @@ class MangaMetaDataLoader : KotlinDataLoader<Int, MetaType> {
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
val metasByChapterId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
.map { MangaMetaItem(it) }
.groupBy { it.ref }
ids.map { metasByChapterId[it] ?: emptyList() }
ids.map { metasByRefId[it] ?: emptyList() }
}
}
}
}

class CategoryMetaDataLoader : KotlinDataLoader<Int, MetaType> {
override val dataLoaderName = "CategoryMetaDataLoader"
override fun getDataLoader(): DataLoader<Int, MetaType> = DataLoaderFactory.newDataLoader<Int, MetaType> { ids ->
CompletableFuture.supplyAsync {
transaction {
addLogger(StdOutSqlLogger)
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
.map { CategoryMetaItem(it) }
.groupBy { it.ref }
ids.map { metasByRefId[it] ?: emptyList() }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ val tachideskDataLoaderRegistryFactory = KotlinDataLoaderRegistryFactory(
ChapterDataLoader(),
ChaptersForMangaDataLoader(),
ChapterMetaDataLoader(),
MangaMetaDataLoader()
MangaMetaDataLoader(),
MangaForCategoryDataLoader(),
CategoryMetaDataLoader(),
CategoriesForMangaDataLoader()
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import graphql.GraphQL
import graphql.scalars.ExtendedScalars
import graphql.schema.GraphQLType
import suwayomi.tachidesk.graphql.mutations.ChapterMutation
import suwayomi.tachidesk.graphql.queries.CategoryQuery
import suwayomi.tachidesk.graphql.queries.ChapterQuery
import suwayomi.tachidesk.graphql.queries.MangaQuery
import kotlin.reflect.KClass
Expand All @@ -36,7 +37,8 @@ val schema = toSchema(
),
queries = listOf(
TopLevelObject(MangaQuery()),
TopLevelObject(ChapterQuery())
TopLevelObject(ChapterQuery()),
TopLevelObject(CategoryQuery())
),
mutations = listOf(
TopLevelObject(ChapterMutation())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

package suwayomi.tachidesk.graphql.queries

import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
import graphql.schema.DataFetchingEnvironment
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.graphql.types.CategoryType
import suwayomi.tachidesk.manga.model.table.CategoryTable
import java.util.concurrent.CompletableFuture

class CategoryQuery {
fun category(dataFetchingEnvironment: DataFetchingEnvironment, id: Int): CompletableFuture<CategoryType> {
return dataFetchingEnvironment.getValueFromDataLoader<Int, CategoryType>("CategoryDataLoader", id)
}

fun categories(): List<CategoryType> {
val results = transaction {
CategoryTable.selectAll().toList()
}

return results.map { CategoryType(it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

package suwayomi.tachidesk.graphql.types

import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
import graphql.schema.DataFetchingEnvironment
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.manga.model.table.CategoryTable
import java.util.concurrent.CompletableFuture

class CategoryType(
val id: Int,
val order: Int,
val name: String,
val default: Boolean
) {
constructor(row: ResultRow) : this(
row[CategoryTable.id].value,
row[CategoryTable.order],
row[CategoryTable.name],
row[CategoryTable.isDefault]
)

fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<MangaType>> {
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<MangaType>>("MangaForCategoryDataLoader", id)
}

fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaType> {
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaType>("CategoryMetaDataLoader", id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,8 @@ class MangaType(
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaType> {
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaType>("MangaMetaDataLoader", id)
}

fun categories(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<CategoryType>> {
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<CategoryType>>("CategoriesForMangaDataLoader", id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package suwayomi.tachidesk.graphql.types

import com.expediagroup.graphql.generator.annotations.GraphQLIgnore
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.manga.model.table.CategoryMetaTable
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
import suwayomi.tachidesk.manga.model.table.MangaMetaTable

Expand All @@ -21,3 +22,7 @@ class ChapterMetaItem(
class MangaMetaItem(
private val row: ResultRow
) : MetaItem(row[MangaMetaTable.key], row[MangaMetaTable.value], row[MangaMetaTable.ref].value)

class CategoryMetaItem(
private val row: ResultRow
) : MetaItem(row[CategoryMetaTable.key], row[CategoryMetaTable.value], row[CategoryMetaTable.ref].value)

0 comments on commit bf7f1a0

Please sign in to comment.