diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt index 02714d31..94a148f1 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -27,6 +28,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -80,6 +82,11 @@ class CategoryQuery { } } + data class CategoryOrder( + override val by: CategoryOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class CategoryCondition( val id: Int? = null, val order: Int? = null, @@ -119,8 +126,17 @@ class CategoryQuery { fun categories( condition: CategoryCondition? = null, filter: CategoryFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: CategoryOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -133,17 +149,15 @@ class CategoryQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: CategoryTable.id - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(CategoryOrder(CategoryOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { CategoryOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == CategoryOrderBy.ID || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - CategoryTable.id to SortOrder.ASC, - ) } } @@ -154,8 +168,8 @@ class CategoryQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: CategoryOrderBy.ID, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: CategoryOrderBy.ID, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -167,7 +181,7 @@ class CategoryQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (CategoryType) -> Cursor = (orderBy ?: CategoryOrderBy.ID)::asCursor + val getAsCursor: (CategoryType) -> Cursor = (order?.firstOrNull()?.by ?: CategoryOrderBy.ID)::asCursor val resultsAsType = queryResults.results.map { CategoryType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt index 3e086873..832e81f2 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -30,6 +31,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -105,6 +107,11 @@ class ChapterQuery { } } + data class ChapterOrder( + override val by: ChapterOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class ChapterCondition( val id: Int? = null, val url: String? = null, @@ -195,8 +202,17 @@ class ChapterQuery { fun chapters( condition: ChapterCondition? = null, filter: ChapterFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: ChapterOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -217,17 +233,15 @@ class ChapterQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: ChapterTable.id - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(ChapterOrder(ChapterOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { ChapterOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == ChapterOrderBy.ID || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - ChapterTable.id to SortOrder.ASC, - ) } } @@ -238,8 +252,8 @@ class ChapterQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: ChapterOrderBy.ID, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: ChapterOrderBy.ID, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -251,7 +265,7 @@ class ChapterQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (ChapterType) -> Cursor = (orderBy ?: ChapterOrderBy.ID)::asCursor + val getAsCursor: (ChapterType) -> Cursor = (order?.firstOrNull()?.by ?: ChapterOrderBy.ID)::asCursor val resultsAsType = queryResults.results.map { ChapterType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt index 92e7ffc3..caec1b3f 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import eu.kanade.tachiyomi.source.local.LocalSource import graphql.schema.DataFetchingEnvironment @@ -28,6 +29,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -81,6 +83,11 @@ class ExtensionQuery { } } + data class ExtensionOrder( + override val by: ExtensionOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class ExtensionCondition( val repo: String? = null, val apkName: String? = null, @@ -151,8 +158,17 @@ class ExtensionQuery { fun extensions( condition: ExtensionCondition? = null, filter: ExtensionFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: ExtensionOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -167,17 +183,15 @@ class ExtensionQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: ExtensionTable.pkgName - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(ExtensionOrder(ExtensionOrderBy.PKG_NAME, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { ExtensionOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == ExtensionOrderBy.PKG_NAME || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - ExtensionTable.pkgName to SortOrder.ASC, - ) } } @@ -188,8 +202,8 @@ class ExtensionQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: ExtensionOrderBy.PKG_NAME, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: ExtensionOrderBy.PKG_NAME, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -201,7 +215,7 @@ class ExtensionQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (ExtensionType) -> Cursor = (orderBy ?: ExtensionOrderBy.PKG_NAME)::asCursor + val getAsCursor: (ExtensionType) -> Cursor = (order?.firstOrNull()?.by ?: ExtensionOrderBy.PKG_NAME)::asCursor val resultsAsType = queryResults.results.map { ExtensionType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt index 4e50098f..13deecdc 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -30,6 +31,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.queries.util.distinctOn import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -89,6 +91,11 @@ class MangaQuery { } } + data class MangaOrder( + override val by: MangaOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class MangaCondition( val id: Int? = null, val sourceId: Long? = null, @@ -208,8 +215,17 @@ class MangaQuery { fun mangas( condition: MangaCondition? = null, filter: MangaFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: MangaOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -227,17 +243,15 @@ class MangaQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: MangaTable.id - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(MangaOrder(MangaOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { MangaOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == MangaOrderBy.ID || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - MangaTable.id to SortOrder.ASC, - ) } } @@ -248,8 +262,8 @@ class MangaQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: MangaOrderBy.ID, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: MangaOrderBy.ID, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -261,7 +275,7 @@ class MangaQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (MangaType) -> Cursor = (orderBy ?: MangaOrderBy.ID)::asCursor + val getAsCursor: (MangaType) -> Cursor = (order?.firstOrNull()?.by ?: MangaOrderBy.ID)::asCursor val resultsAsType = queryResults.results.map { MangaType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt index 160d00c6..94798544 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -24,6 +25,7 @@ import suwayomi.tachidesk.graphql.queries.filter.StringFilter import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -72,6 +74,11 @@ class MetaQuery { } } + data class MetaOrder( + override val by: MetaOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class MetaCondition( val key: String? = null, val value: String? = null, @@ -103,8 +110,17 @@ class MetaQuery { fun metas( condition: MetaCondition? = null, filter: MetaFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: MetaOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -117,17 +133,15 @@ class MetaQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: GlobalMetaTable.key - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(MetaOrder(MetaOrderBy.KEY, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { MetaOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == MetaOrderBy.KEY || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - GlobalMetaTable.key to SortOrder.ASC, - ) } } @@ -138,8 +152,8 @@ class MetaQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: MetaOrderBy.KEY, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: MetaOrderBy.KEY, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -151,7 +165,7 @@ class MetaQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (GlobalMetaType) -> Cursor = (orderBy ?: MetaOrderBy.KEY)::asCursor + val getAsCursor: (GlobalMetaType) -> Cursor = (order?.firstOrNull()?.by ?: MetaOrderBy.KEY)::asCursor val resultsAsType = queryResults.results.map { GlobalMetaType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt index 116932cd..6c8099f3 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt @@ -7,6 +7,7 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -27,6 +28,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -80,6 +82,11 @@ class SourceQuery { } } + data class SourceOrder( + override val by: SourceOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class SourceCondition( val id: Long? = null, val name: String? = null, @@ -119,8 +126,17 @@ class SourceQuery { fun sources( condition: SourceCondition? = null, filter: SourceFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: SourceOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -133,17 +149,15 @@ class SourceQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: SourceTable.id - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(SourceOrder(SourceOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { SourceOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == SourceOrderBy.ID || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - SourceTable.id to SortOrder.ASC, - ) } } @@ -154,8 +168,8 @@ class SourceQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: SourceOrderBy.ID, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: SourceOrderBy.ID, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -169,7 +183,7 @@ class SourceQuery { } } - val getAsCursor: (SourceType) -> Cursor = (orderBy ?: SourceOrderBy.ID)::asCursor + val getAsCursor: (SourceType) -> Cursor = (order?.firstOrNull()?.by ?: SourceOrderBy.ID)::asCursor return SourceNodeList( resultsAsType, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt index 3a65e991..59aabb7e 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt @@ -1,5 +1,6 @@ package suwayomi.tachidesk.graphql.queries +import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.server.extensions.getValueFromDataLoader import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.Column @@ -22,6 +23,7 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps import suwayomi.tachidesk.graphql.server.primitives.Cursor +import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.graphql.server.primitives.QueryResults @@ -93,6 +95,11 @@ class TrackQuery { } } + data class TrackerOrder( + val by: TrackerOrderBy, + val byType: SortOrder? = null, + ) + data class TrackerCondition( val id: Int? = null, val name: String? = null, @@ -113,8 +120,17 @@ class TrackQuery { fun trackers( condition: TrackerCondition? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: TrackerOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -135,35 +151,40 @@ class TrackQuery { } } - if (orderBy != null || (last != null || before != null)) { - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(TrackerOrder(TrackerOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { TrackerOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderType = orderByType.maybeSwap(last ?: before) - res = - when (orderType) { - SortOrder.DESC, SortOrder.DESC_NULLS_FIRST, SortOrder.DESC_NULLS_LAST -> - when (orderBy) { - TrackerOrderBy.ID, null -> res.sortedByDescending { it.id } - TrackerOrderBy.NAME -> res.sortedByDescending { it.name } - TrackerOrderBy.IS_LOGGED_IN -> res.sortedByDescending { it.isLoggedIn } - } - SortOrder.ASC, SortOrder.ASC_NULLS_FIRST, SortOrder.ASC_NULLS_LAST -> - when (orderBy) { - TrackerOrderBy.ID, null -> res.sortedBy { it.id } - TrackerOrderBy.NAME -> res.sortedBy { it.name } - TrackerOrderBy.IS_LOGGED_IN -> res.sortedBy { it.isLoggedIn } - } - } + res = + when (orderType) { + SortOrder.DESC, SortOrder.DESC_NULLS_FIRST, SortOrder.DESC_NULLS_LAST -> + when (orderBy) { + TrackerOrderBy.ID -> res.sortedByDescending { it.id } + TrackerOrderBy.NAME -> res.sortedByDescending { it.name } + TrackerOrderBy.IS_LOGGED_IN -> res.sortedByDescending { it.isLoggedIn } + } + SortOrder.ASC, SortOrder.ASC_NULLS_FIRST, SortOrder.ASC_NULLS_LAST -> + when (orderBy) { + TrackerOrderBy.ID -> res.sortedBy { it.id } + TrackerOrderBy.NAME -> res.sortedBy { it.name } + TrackerOrderBy.IS_LOGGED_IN -> res.sortedBy { it.isLoggedIn } + } + } + } } val total = res.size val firstResult = res.firstOrNull() val lastResult = res.lastOrNull() - val realOrderBy = orderBy ?: TrackerOrderBy.ID + val realOrderBy = order?.firstOrNull()?.by ?: TrackerOrderBy.ID if (after != null) { res = res.filter { - when (orderByType) { + when (order?.firstOrNull()?.byType) { SortOrder.DESC, SortOrder.DESC_NULLS_FIRST, SortOrder.DESC_NULLS_LAST -> realOrderBy.less(it, after) null, SortOrder.ASC, SortOrder.ASC_NULLS_FIRST, SortOrder.ASC_NULLS_LAST -> realOrderBy.greater(it, after) } @@ -171,7 +192,7 @@ class TrackQuery { } else if (before != null) { res = res.filter { - when (orderByType) { + when (order?.firstOrNull()?.byType) { SortOrder.DESC, SortOrder.DESC_NULLS_FIRST, SortOrder.DESC_NULLS_LAST -> realOrderBy.greater(it, before) null, SortOrder.ASC, SortOrder.ASC_NULLS_FIRST, SortOrder.ASC_NULLS_LAST -> realOrderBy.less(it, before) } @@ -187,7 +208,7 @@ class TrackQuery { QueryResults(total.toLong(), firstResult, lastResult, emptyList()) to res } - val getAsCursor: (TrackerType) -> Cursor = (orderBy ?: TrackerOrderBy.ID)::asCursor + val getAsCursor: (TrackerType) -> Cursor = (order?.firstOrNull()?.by ?: TrackerOrderBy.ID)::asCursor return TrackerNodeList( resultsAsType, @@ -288,6 +309,11 @@ class TrackQuery { } } + data class TrackRecordOrder( + override val by: TrackRecordOrderBy, + override val byType: SortOrder? = null, + ) : Order + data class TrackRecordCondition( val id: Int? = null, val mangaId: Int? = null, @@ -363,8 +389,17 @@ class TrackQuery { fun trackRecords( condition: TrackRecordCondition? = null, filter: TrackRecordFilter? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderBy: TrackRecordOrderBy? = null, + @GraphQLDeprecated( + "Replaced with order", + replaceWith = ReplaceWith("order"), + ) orderByType: SortOrder? = null, + order: List? = null, before: Cursor? = null, after: Cursor? = null, first: Int? = null, @@ -377,17 +412,15 @@ class TrackQuery { res.applyOps(condition, filter) - if (orderBy != null || (last != null || before != null)) { - val orderByColumn = orderBy?.column ?: TrackRecordTable.id - val orderType = orderByType.maybeSwap(last ?: before) + if (order != null || (last != null || before != null)) { + val baseSort = listOf(TrackRecordOrder(TrackRecordOrderBy.ID, SortOrder.ASC)) + val deprecatedSort = listOfNotNull(orderBy?.let { TrackRecordOrder(orderBy, orderByType) }) + val actualSort = (order.orEmpty() + deprecatedSort + baseSort) + actualSort.forEach { (orderBy, orderByType) -> + val orderByColumn = orderBy.column + val orderType = orderByType.maybeSwap(last ?: before) - if (orderBy == TrackRecordOrderBy.ID || orderBy == null) { res.orderBy(orderByColumn to orderType) - } else { - res.orderBy( - orderByColumn to orderType, - TrackRecordTable.id to SortOrder.ASC, - ) } } @@ -398,8 +431,8 @@ class TrackQuery { res.applyBeforeAfter( before = before, after = after, - orderBy = orderBy ?: TrackRecordOrderBy.ID, - orderByType = orderByType, + orderBy = order?.firstOrNull()?.by ?: TrackRecordOrderBy.ID, + orderByType = order?.firstOrNull()?.byType, ) if (first != null) { @@ -411,7 +444,7 @@ class TrackQuery { QueryResults(total, firstResult, lastResult, res.toList()) } - val getAsCursor: (TrackRecordType) -> Cursor = (orderBy ?: TrackRecordOrderBy.ID)::asCursor + val getAsCursor: (TrackRecordType) -> Cursor = (order?.firstOrNull()?.by ?: TrackRecordOrderBy.ID)::asCursor val resultsAsType = queryResults.results.map { TrackRecordType(it) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/primitives/OrderBy.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/primitives/OrderBy.kt index 37f13169..328045f0 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/primitives/OrderBy.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/primitives/OrderBy.kt @@ -22,6 +22,11 @@ interface OrderBy { fun less(cursor: Cursor): Op } +interface Order> { + val by: By + val byType: SortOrder? +} + fun SortOrder?.maybeSwap(value: Any?): SortOrder { return if (value != null) { when (this) {