Start working on graphql paging
This commit is contained in:
@@ -14,6 +14,8 @@ import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger
|
||||
import org.jetbrains.exposed.sql.addLogger
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.CategoryNodeList
|
||||
import suwayomi.tachidesk.graphql.types.CategoryNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.CategoryType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||
@@ -32,9 +34,9 @@ class CategoryDataLoader : KotlinDataLoader<Int, CategoryType> {
|
||||
}
|
||||
}
|
||||
|
||||
class CategoriesForMangaDataLoader : KotlinDataLoader<Int, List<CategoryType>> {
|
||||
class CategoriesForMangaDataLoader : KotlinDataLoader<Int, CategoryNodeList> {
|
||||
override val dataLoaderName = "CategoriesForMangaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, List<CategoryType>> = DataLoaderFactory.newDataLoader<Int, List<CategoryType>> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, CategoryNodeList> = DataLoaderFactory.newDataLoader<Int, CategoryNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
@@ -43,7 +45,7 @@ class CategoriesForMangaDataLoader : KotlinDataLoader<Int, List<CategoryType>> {
|
||||
.map { Pair(it[CategoryMangaTable.manga].value, CategoryType(it)) }
|
||||
.groupBy { it.first }
|
||||
.mapValues { it.value.map { pair -> pair.second } }
|
||||
ids.map { itemsByRef[it] ?: emptyList() }
|
||||
ids.map { (itemsByRef[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger
|
||||
import org.jetbrains.exposed.sql.addLogger
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.ChapterNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ChapterNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ChapterType
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
@@ -31,16 +33,16 @@ class ChapterDataLoader : KotlinDataLoader<Int, ChapterType> {
|
||||
}
|
||||
}
|
||||
|
||||
class ChaptersForMangaDataLoader : KotlinDataLoader<Int, List<ChapterType>> {
|
||||
class ChaptersForMangaDataLoader : KotlinDataLoader<Int, ChapterNodeList> {
|
||||
override val dataLoaderName = "ChaptersForMangaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, List<ChapterType>> = DataLoaderFactory.newDataLoader<Int, List<ChapterType>> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, ChapterNodeList> = DataLoaderFactory.newDataLoader<Int, ChapterNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val chaptersByMangaId = ChapterTable.select { ChapterTable.manga inList ids }
|
||||
.map { ChapterType(it) }
|
||||
.groupBy { it.mangaId }
|
||||
ids.map { chaptersByMangaId[it] ?: emptyList() }
|
||||
ids.map { (chaptersByMangaId[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger
|
||||
import org.jetbrains.exposed.sql.addLogger
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.MangaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MangaNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MangaType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
@@ -32,9 +34,9 @@ class MangaDataLoader : KotlinDataLoader<Int, MangaType> {
|
||||
}
|
||||
}
|
||||
|
||||
class MangaForCategoryDataLoader : KotlinDataLoader<Int, List<MangaType>> {
|
||||
class MangaForCategoryDataLoader : KotlinDataLoader<Int, MangaNodeList> {
|
||||
override val dataLoaderName = "MangaForCategoryDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, List<MangaType>> = DataLoaderFactory.newDataLoader<Int, List<MangaType>> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, MangaNodeList> = DataLoaderFactory.newDataLoader<Int, MangaNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
@@ -42,7 +44,7 @@ class MangaForCategoryDataLoader : KotlinDataLoader<Int, List<MangaType>> {
|
||||
.map { Pair(it[CategoryMangaTable.category].value, MangaType(it)) }
|
||||
.groupBy { it.first }
|
||||
.mapValues { it.value.map { pair -> pair.second } }
|
||||
ids.map { itemsByRef[it] ?: emptyList() }
|
||||
ids.map { (itemsByRef[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ 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.MetaType
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
@@ -33,46 +34,46 @@ class GlobalMetaDataLoader : KotlinDataLoader<String, MetaItem?> {
|
||||
}
|
||||
}
|
||||
|
||||
class ChapterMetaDataLoader : KotlinDataLoader<Int, MetaType> {
|
||||
class ChapterMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
override val dataLoaderName = "ChapterMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaType> = DataLoaderFactory.newDataLoader<Int, MetaType> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = ChapterMetaTable.select { ChapterMetaTable.ref inList ids }
|
||||
.map { ChapterMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { metasByRefId[it] ?: emptyList() }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MangaMetaDataLoader : KotlinDataLoader<Int, MetaType> {
|
||||
class MangaMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
override val dataLoaderName = "MangaMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaType> = DataLoaderFactory.newDataLoader<Int, MetaType> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
|
||||
.map { MangaMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { metasByRefId[it] ?: emptyList() }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryMetaDataLoader : KotlinDataLoader<Int, MetaType> {
|
||||
class CategoryMetaDataLoader : KotlinDataLoader<Int, MetaNodeList> {
|
||||
override val dataLoaderName = "CategoryMetaDataLoader"
|
||||
override fun getDataLoader(): DataLoader<Int, MetaType> = DataLoaderFactory.newDataLoader<Int, MetaType> { ids ->
|
||||
override fun getDataLoader(): DataLoader<Int, MetaNodeList> = DataLoaderFactory.newDataLoader<Int, MetaNodeList> { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
val metasByRefId = MangaMetaTable.select { MangaMetaTable.ref inList ids }
|
||||
.map { CategoryMetaItem(it) }
|
||||
.groupBy { it.ref }
|
||||
ids.map { metasByRefId[it] ?: emptyList() }
|
||||
ids.map { (metasByRefId[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger
|
||||
import org.jetbrains.exposed.sql.addLogger
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.SourceNodeList
|
||||
import suwayomi.tachidesk.graphql.types.SourceNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.SourceType
|
||||
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
@@ -63,9 +65,9 @@ class SourceForMangaDataLoader : KotlinDataLoader<Int, SourceType?> {
|
||||
}
|
||||
}
|
||||
|
||||
class SourcesForExtensionDataLoader : KotlinDataLoader<String, List<SourceType>> {
|
||||
class SourcesForExtensionDataLoader : KotlinDataLoader<String, SourceNodeList> {
|
||||
override val dataLoaderName = "SourcesForExtensionDataLoader"
|
||||
override fun getDataLoader(): DataLoader<String, List<SourceType>> = DataLoaderFactory.newDataLoader { ids ->
|
||||
override fun getDataLoader(): DataLoader<String, SourceNodeList> = DataLoaderFactory.newDataLoader { ids ->
|
||||
future {
|
||||
transaction {
|
||||
addLogger(Slf4jSqlDebugLogger)
|
||||
@@ -76,7 +78,7 @@ class SourcesForExtensionDataLoader : KotlinDataLoader<String, List<SourceType>>
|
||||
.groupBy { it.first }
|
||||
.mapValues { it.value.mapNotNull { pair -> pair.second } }
|
||||
|
||||
ids.map { sourcesByExtensionPkg[it] ?: emptyList() }
|
||||
ids.map { (sourcesByExtensionPkg[it] ?: emptyList()).toNodeList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.jetbrains.exposed.sql.SortOrder
|
||||
import org.jetbrains.exposed.sql.andWhere
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.CategoryNodeList
|
||||
import suwayomi.tachidesk.graphql.types.CategoryNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.CategoryType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -48,7 +50,7 @@ class CategoryQuery {
|
||||
val query: String? = null
|
||||
)
|
||||
|
||||
fun categories(input: CategoriesQueryInput? = null): List<CategoryType> {
|
||||
fun categories(input: CategoriesQueryInput? = null): CategoryNodeList {
|
||||
val results = transaction {
|
||||
val res = CategoryTable.selectAll()
|
||||
|
||||
@@ -72,6 +74,6 @@ class CategoryQuery {
|
||||
res.toList()
|
||||
}
|
||||
|
||||
return results.map { CategoryType(it) }
|
||||
return results.map { CategoryType(it) }.toNodeList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.jetbrains.exposed.sql.SortOrder
|
||||
import org.jetbrains.exposed.sql.andWhere
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.ChapterNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ChapterNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ChapterType
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -56,7 +58,7 @@ class ChapterQuery {
|
||||
val count: Int? = null
|
||||
)
|
||||
|
||||
fun chapters(input: ChapterQueryInput? = null): List<ChapterType> {
|
||||
fun chapters(input: ChapterQueryInput? = null): ChapterNodeList {
|
||||
val results = transaction {
|
||||
var res = ChapterTable.selectAll()
|
||||
|
||||
@@ -97,6 +99,6 @@ class ChapterQuery {
|
||||
res.toList()
|
||||
}
|
||||
|
||||
return results.map { ChapterType(it) }
|
||||
return results.map { ChapterType(it) }.toNodeList() // todo paged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ 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.ExtensionNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ExtensionNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.ExtensionType
|
||||
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -37,11 +39,11 @@ class ExtensionQuery {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, ExtensionType>("ExtensionDataLoader", pkgName)
|
||||
}
|
||||
|
||||
fun extensions(): List<ExtensionType> {
|
||||
fun extensions(): ExtensionNodeList {
|
||||
val results = transaction {
|
||||
ExtensionTable.selectAll().toList()
|
||||
}
|
||||
|
||||
return results.map { ExtensionType(it) }
|
||||
return results.map { ExtensionType(it) }.toNodeList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.queries.util.GreaterOrLessThanLong
|
||||
import suwayomi.tachidesk.graphql.queries.util.andWhereGreaterOrLessThen
|
||||
import suwayomi.tachidesk.graphql.types.MangaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MangaNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MangaType
|
||||
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
@@ -60,7 +62,7 @@ class MangaQuery {
|
||||
val count: Int? = null
|
||||
)
|
||||
|
||||
fun mangas(input: MangaQueryInput? = null): List<MangaType> {
|
||||
fun mangas(input: MangaQueryInput? = null): MangaNodeList {
|
||||
val results = transaction {
|
||||
var res = MangaTable.selectAll()
|
||||
|
||||
@@ -102,6 +104,6 @@ class MangaQuery {
|
||||
res.toList()
|
||||
}
|
||||
|
||||
return results.map { MangaType(it) }
|
||||
return results.map { MangaType(it) }.toNodeList() // todo paged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.global.model.table.GlobalMetaTable
|
||||
import suwayomi.tachidesk.graphql.types.GlobalMetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaItem
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList
|
||||
import suwayomi.tachidesk.graphql.types.MetaNodeList.Companion.toNodeList
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
@@ -30,11 +32,11 @@ class MetaQuery {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, MetaItem?>("GlobalMetaDataLoader", key)
|
||||
}
|
||||
|
||||
fun metas(): List<GlobalMetaItem> {
|
||||
fun metas(): MetaNodeList {
|
||||
val results = transaction {
|
||||
GlobalMetaTable.selectAll().toList()
|
||||
}
|
||||
|
||||
return results.map { GlobalMetaItem(it) }
|
||||
return results.map { GlobalMetaItem(it) }.toNodeList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ 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.SourceNodeList
|
||||
import suwayomi.tachidesk.graphql.types.SourceNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.SourceType
|
||||
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -33,11 +35,11 @@ class SourceQuery {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Long, SourceType?>("SourceDataLoader", id)
|
||||
}
|
||||
|
||||
fun sources(): List<SourceType> {
|
||||
fun sources(): SourceNodeList {
|
||||
val results = transaction {
|
||||
SourceTable.selectAll().toList().mapNotNull { SourceType(it) }
|
||||
}
|
||||
|
||||
return results
|
||||
return results.toNodeList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import org.jetbrains.exposed.sql.SortOrder
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.types.UpdatesNodeList
|
||||
import suwayomi.tachidesk.graphql.types.UpdatesNodeList.Companion.toNodeList
|
||||
import suwayomi.tachidesk.graphql.types.UpdatesType
|
||||
import suwayomi.tachidesk.manga.model.dataclass.PaginationFactor
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
@@ -31,7 +33,7 @@ class UpdatesQuery {
|
||||
val page: Int
|
||||
)
|
||||
|
||||
fun updates(input: UpdatesQueryInput): List<UpdatesType> {
|
||||
fun updates(input: UpdatesQueryInput): UpdatesNodeList {
|
||||
val results = transaction {
|
||||
ChapterTable.innerJoin(MangaTable)
|
||||
.select { (MangaTable.inLibrary eq true) and (ChapterTable.fetchedAt greater MangaTable.inLibraryAt) }
|
||||
@@ -42,6 +44,6 @@ class UpdatesQuery {
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
return results.toNodeList() // todo paged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class CategoryType(
|
||||
val order: Int,
|
||||
val name: String,
|
||||
val default: Boolean
|
||||
) {
|
||||
) : Node {
|
||||
constructor(row: ResultRow) : this(
|
||||
row[CategoryTable.id].value,
|
||||
row[CategoryTable.order],
|
||||
@@ -26,11 +26,42 @@ class CategoryType(
|
||||
row[CategoryTable.isDefault]
|
||||
)
|
||||
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<MangaType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<MangaType>>("MangaForCategoryDataLoader", id)
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MangaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MangaNodeList>("MangaForCategoryDataLoader", id)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaType>("CategoryMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("CategoryMetaDataLoader", id)
|
||||
}
|
||||
}
|
||||
|
||||
data class CategoryNodeList(
|
||||
override val nodes: List<CategoryType>,
|
||||
override val edges: CategoryEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class CategoryEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: CategoryType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<CategoryType>.toNodeList(): CategoryNodeList {
|
||||
return CategoryNodeList(
|
||||
nodes = this,
|
||||
edges = CategoryEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ChapterType(
|
||||
val isDownloaded: Boolean,
|
||||
val pageCount: Int
|
||||
// val chapterCount: Int?,
|
||||
) {
|
||||
) : Node {
|
||||
constructor(row: ResultRow) : this(
|
||||
row[ChapterTable.id].value,
|
||||
row[ChapterTable.url],
|
||||
@@ -73,7 +73,38 @@ class ChapterType(
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MangaType>("MangaDataLoader", mangaId)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaType>("ChapterMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("ChapterMetaDataLoader", id)
|
||||
}
|
||||
}
|
||||
|
||||
data class ChapterNodeList(
|
||||
override val nodes: List<ChapterType>,
|
||||
override val edges: ChapterEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class ChapterEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: ChapterType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<ChapterType>.toNodeList(): ChapterNodeList {
|
||||
return ChapterNodeList(
|
||||
nodes = this,
|
||||
edges = ChapterEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class DownloadType(
|
||||
var mangaDataClass: MangaDataClass,
|
||||
@GraphQLIgnore
|
||||
var chapterDataClass: ChapterDataClass
|
||||
) {
|
||||
) : Node {
|
||||
constructor(downloadChapter: DownloadChapter) : this(
|
||||
downloadChapter.chapter.id,
|
||||
downloadChapter.chapterIndex,
|
||||
@@ -44,3 +44,34 @@ class DownloadType(
|
||||
return ChapterType(chapterDataClass)
|
||||
}
|
||||
}
|
||||
|
||||
data class DownloadNodeList(
|
||||
override val nodes: List<DownloadType>,
|
||||
override val edges: DownloadEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class DownloadEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: DownloadType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<DownloadType>.toNodeList(): DownloadNodeList {
|
||||
return DownloadNodeList(
|
||||
nodes = this,
|
||||
edges = DownloadEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class ExtensionType(
|
||||
val installed: Boolean,
|
||||
val hasUpdate: Boolean,
|
||||
val obsolete: Boolean
|
||||
) {
|
||||
) : Node {
|
||||
constructor(row: ResultRow) : this(
|
||||
apkName = row[ExtensionTable.apkName],
|
||||
iconUrl = row[ExtensionTable.iconUrl],
|
||||
@@ -42,7 +42,38 @@ class ExtensionType(
|
||||
obsolete = row[ExtensionTable.isObsolete]
|
||||
)
|
||||
|
||||
fun source(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<SourceType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, List<SourceType>>("SourcesForExtensionDataLoader", pkgName)
|
||||
fun source(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<SourceNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<String, SourceNodeList>("SourcesForExtensionDataLoader", pkgName)
|
||||
}
|
||||
}
|
||||
|
||||
data class ExtensionNodeList(
|
||||
override val nodes: List<ExtensionType>,
|
||||
override val edges: ExtensionEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class ExtensionEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: ExtensionType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<ExtensionType>.toNodeList(): ExtensionNodeList {
|
||||
return ExtensionNodeList(
|
||||
nodes = this,
|
||||
edges = ExtensionEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class MangaType(
|
||||
val realUrl: String?,
|
||||
var lastFetchedAt: Long?,
|
||||
var chaptersLastFetchedAt: Long?
|
||||
) {
|
||||
) : Node {
|
||||
constructor(row: ResultRow) : this(
|
||||
row[MangaTable.id].value,
|
||||
row[MangaTable.sourceReference],
|
||||
@@ -88,15 +88,46 @@ class MangaType(
|
||||
return Instant.now().epochSecond.minus(chaptersLastFetchedAt!!)
|
||||
}
|
||||
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaType> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaType>("MangaMetaDataLoader", id)
|
||||
fun meta(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MetaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, MetaNodeList>("MangaMetaDataLoader", id)
|
||||
}
|
||||
|
||||
fun categories(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<CategoryType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, List<CategoryType>>("CategoriesForMangaDataLoader", id)
|
||||
fun categories(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<CategoryNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, CategoryNodeList>("CategoriesForMangaDataLoader", id)
|
||||
}
|
||||
|
||||
fun source(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<SourceType?> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Int, SourceType?>("SourceForMangaDataLoader", id)
|
||||
}
|
||||
}
|
||||
|
||||
data class MangaNodeList(
|
||||
override val nodes: List<MangaType>,
|
||||
override val edges: MangaEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class MangaEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: MangaType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<MangaType>.toNodeList(): MangaNodeList {
|
||||
return MangaNodeList(
|
||||
nodes = this,
|
||||
edges = MangaEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,12 @@ import suwayomi.tachidesk.manga.model.table.CategoryMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||
|
||||
typealias MetaType = List<MetaItem>
|
||||
|
||||
open class MetaItem(
|
||||
val key: String,
|
||||
val value: String,
|
||||
@GraphQLIgnore
|
||||
val ref: Int?
|
||||
)
|
||||
) : Node
|
||||
|
||||
class ChapterMetaItem(
|
||||
private val row: ResultRow
|
||||
@@ -31,3 +29,34 @@ class CategoryMetaItem(
|
||||
class GlobalMetaItem(
|
||||
private val row: ResultRow
|
||||
) : MetaItem(row[GlobalMetaTable.key], row[GlobalMetaTable.value], null)
|
||||
|
||||
data class MetaNodeList(
|
||||
override val nodes: List<MetaItem>,
|
||||
override val edges: MetaEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class MetaEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: MetaItem?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<MetaItem>.toNodeList(): MetaNodeList {
|
||||
return MetaNodeList(
|
||||
nodes = this,
|
||||
edges = MetaEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package suwayomi.tachidesk.graphql.types
|
||||
|
||||
import com.expediagroup.graphql.generator.annotations.GraphQLDescription
|
||||
|
||||
interface Node
|
||||
|
||||
typealias Cursor = Int
|
||||
|
||||
abstract class NodeList {
|
||||
@GraphQLDescription("A list of [T] objects.")
|
||||
abstract val nodes: List<Node>
|
||||
|
||||
@GraphQLDescription("A list of edges which contains the [T] and cursor to aid in pagination.")
|
||||
abstract val edges: Edges
|
||||
|
||||
@GraphQLDescription("Information to aid in pagination.")
|
||||
abstract val pageInfo: PageInfo
|
||||
|
||||
@GraphQLDescription("The count of all nodes you could get from the connection.")
|
||||
abstract val totalCount: Int
|
||||
}
|
||||
|
||||
data class PageInfo(
|
||||
@GraphQLDescription("When paginating forwards, are there more items?")
|
||||
val hasNextPage: Boolean,
|
||||
@GraphQLDescription("When paginating backwards, are there more items?")
|
||||
val hasPreviousPage: Boolean,
|
||||
@GraphQLDescription("When paginating backwards, the cursor to continue.")
|
||||
val startCursor: Cursor,
|
||||
@GraphQLDescription("When paginating forwards, the cursor to continue.")
|
||||
val endCursor: Cursor
|
||||
)
|
||||
|
||||
abstract class Edges {
|
||||
@GraphQLDescription("A cursor for use in pagination.")
|
||||
abstract val cursor: Cursor
|
||||
|
||||
@GraphQLDescription("The [T] at the end of the edge.")
|
||||
abstract val node: Node?
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class SourceType(
|
||||
val isConfigurable: Boolean,
|
||||
val isNsfw: Boolean,
|
||||
val displayName: String
|
||||
) {
|
||||
) : Node {
|
||||
constructor(source: SourceDataClass) : this(
|
||||
id = source.id.toLong(),
|
||||
name = source.name,
|
||||
@@ -52,8 +52,8 @@ class SourceType(
|
||||
displayName = catalogueSource.toString()
|
||||
)
|
||||
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<List<MangaType>> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Long, List<MangaType>>("MangaForSourceDataLoader", id)
|
||||
fun manga(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MangaNodeList> {
|
||||
return dataFetchingEnvironment.getValueFromDataLoader<Long, MangaNodeList>("MangaForSourceDataLoader", id)
|
||||
}
|
||||
|
||||
fun extension(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<ExtensionType> {
|
||||
@@ -75,3 +75,34 @@ fun SourceType(row: ResultRow): SourceType? {
|
||||
|
||||
return SourceType(row, sourceExtension, catalogueSource)
|
||||
}
|
||||
|
||||
data class SourceNodeList(
|
||||
override val nodes: List<SourceType>,
|
||||
override val edges: SourceEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class SourceEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: SourceType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<SourceType>.toNodeList(): SourceNodeList {
|
||||
return SourceNodeList(
|
||||
nodes = this,
|
||||
edges = SourceEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,40 @@ import org.jetbrains.exposed.sql.ResultRow
|
||||
class UpdatesType(
|
||||
val manga: MangaType,
|
||||
val chapter: ChapterType
|
||||
) {
|
||||
) : Node {
|
||||
constructor(row: ResultRow) : this(
|
||||
manga = MangaType(row),
|
||||
chapter = ChapterType(row)
|
||||
)
|
||||
}
|
||||
|
||||
data class UpdatesNodeList(
|
||||
override val nodes: List<UpdatesType>,
|
||||
override val edges: UpdatesEdges,
|
||||
override val pageInfo: PageInfo,
|
||||
override val totalCount: Int
|
||||
) : NodeList() {
|
||||
data class UpdatesEdges(
|
||||
override val cursor: Cursor,
|
||||
override val node: UpdatesType?
|
||||
) : Edges()
|
||||
|
||||
companion object {
|
||||
fun List<UpdatesType>.toNodeList(): UpdatesNodeList {
|
||||
return UpdatesNodeList(
|
||||
nodes = this,
|
||||
edges = UpdatesEdges(
|
||||
cursor = lastIndex,
|
||||
node = lastOrNull()
|
||||
),
|
||||
pageInfo = PageInfo(
|
||||
hasNextPage = false,
|
||||
hasPreviousPage = false,
|
||||
startCursor = 0,
|
||||
endCursor = lastIndex
|
||||
),
|
||||
totalCount = size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user