Prepared single parameter handling.

This commit is contained in:
Oliver Rümpelein 2020-05-01 13:49:55 +02:00
parent 63c7d101a1
commit b3711f965b
10 changed files with 67 additions and 41 deletions

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
enum class Classification( enum class Classification(
override val prettyName: String, override val prettyName: String,
@ -19,7 +19,7 @@ enum class Classification(
} }
} }
fun MultiParamsBuilder.classification(body: ClassificationBuilder.() -> ClassificationBuilder): MultiParamsBuilder { fun ParamsBuilder.classification(body: ClassificationBuilder.() -> ClassificationBuilder): ParamsBuilder {
val builder = ClassificationBuilder() val builder = ClassificationBuilder()
builder.body() builder.body()
this[Classification.staticParamName] = builder.build() this[Classification.staticParamName] = builder.build()

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
@Suppress("unused") @Suppress("unused")
enum class Order( enum class Order(
@ -51,7 +51,7 @@ enum class Order(
} }
} }
fun MultiParamsBuilder.sortBy(body: OrderBuilder.() -> OrderBuilder): MultiParamsBuilder { fun ParamsBuilder.sortBy(body: OrderBuilder.() -> OrderBuilder): ParamsBuilder {
val builder = OrderBuilder() val builder = OrderBuilder()
builder.body() builder.body()
this[Order.staticParamName] = builder.build() this[Order.staticParamName] = builder.build()

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
class Page(override val paramValue: Int) : RcdbParamOption<Int> { class Page(override val paramValue: Int) : RcdbParamOption<Int> {
override val fullName = "The page to show" override val fullName = "The page to show"
@ -11,12 +11,12 @@ class Page(override val paramValue: Int) : RcdbParamOption<Int> {
} }
} }
fun MultiParamsBuilder.page(page: Int) = if (Page.staticParamName !in this.keys()) { fun ParamsBuilder.page(page: Int) = if (Page.staticParamName !in this.keys()) {
also { this[Page.staticParamName] = listOf(Page(page)) } also { this[Page.staticParamName] = listOf(Page(page)) }
} else { } else {
error( error(
"""Only one page must be given! """Only one page must be given!
| Old page: ${this[Page.staticParamName]!![0].paramValue} | Old page: ${this.getMulti(Page.staticParamName)!![0].paramValue}
| New page: $page | New page: $page
""".trimMargin() """.trimMargin()
) )

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
class SearchTerm(override val paramValue: String) : RcdbParamOption<String> { class SearchTerm(override val paramValue: String) : RcdbParamOption<String> {
override val prettyName = "Search Term" override val prettyName = "Search Term"
@ -11,13 +11,13 @@ class SearchTerm(override val paramValue: String) : RcdbParamOption<String> {
} }
} }
fun MultiParamsBuilder.searchTerm(term: String) = fun ParamsBuilder.searchTerm(term: String) =
if (SearchTerm.staticParamName !in this.keys()) { if (SearchTerm.staticParamName !in this.keys()) {
also { this[SearchTerm.staticParamName] = listOf(SearchTerm(term)) } also { this[SearchTerm.staticParamName] = listOf(SearchTerm(term)) }
} else { } else {
error( error(
"""Only one search term must ever be set """Only one search term must ever be set
| Old term: ${this[SearchTerm.staticParamName]!![0].paramValue} | Old term: ${this.getMulti(SearchTerm.staticParamName)!![0].paramValue}
| New term: $term""".trimMargin() | New term: $term""".trimMargin()
) )
} }

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
@Suppress("unused") @Suppress("unused")
enum class SearchType( enum class SearchType(
@ -19,13 +19,13 @@ enum class SearchType(
} }
} }
fun MultiParamsBuilder.searchType(searchType: SearchType) = fun ParamsBuilder.searchType(searchType: SearchType) =
if (SearchType.staticParamName !in this.keys()) { if (SearchType.staticParamName !in this.keys()) {
also { this[SearchType.staticParamName] = listOf(searchType) } also { this[SearchType.staticParamName] = listOf(searchType) }
} else { } else {
error( error(
"""Only one search type must ever be set """Only one search type must ever be set
| Old type: ${this[SearchType.staticParamName]!![0].prettyName} | Old type: ${this.getMulti(SearchType.staticParamName)!![0].prettyName}
| New type: ${searchType.prettyName}""".trimMargin() | New type: ${searchType.prettyName}""".trimMargin()
) )
} }

View file

@ -2,7 +2,7 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
class StartsWith(override val paramValue: String) : RcdbParamOption<String> { class StartsWith(override val paramValue: String) : RcdbParamOption<String> {
override val prettyName = "Starts with" override val prettyName = "Starts with"
@ -13,12 +13,12 @@ class StartsWith(override val paramValue: String) : RcdbParamOption<String> {
} }
} }
fun MultiParamsBuilder.startsWith(term: String) = if (StartsWith.staticParamName !in this.keys()) { fun ParamsBuilder.startsWith(term: String) = if (StartsWith.staticParamName !in this.keys()) {
also { this[StartsWith.staticParamName] = listOf(StartsWith(term)) } also { this[StartsWith.staticParamName] = listOf(StartsWith(term)) }
} else { } else {
error( error(
"""Only one starts with term must ever be set """Only one starts with term must ever be set
| Old term: ${this[StartsWith.staticParamName]!![0].paramValue} | Old term: ${this.getMulti(StartsWith.staticParamName)!![0].paramValue}
| New term: $term""".trimMargin() | New term: $term""".trimMargin()
) )
} }

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
@Suppress("unused") @Suppress("unused")
enum class Status( enum class Status(
@ -29,7 +29,7 @@ enum class Status(
} }
} }
fun MultiParamsBuilder.status(body: StatusBuilder.() -> StatusBuilder): MultiParamsBuilder { fun ParamsBuilder.status(body: StatusBuilder.() -> StatusBuilder): ParamsBuilder {
val builder = StatusBuilder() val builder = StatusBuilder()
builder.body() builder.body()
this[Status.staticParamName] = builder.build() this[Status.staticParamName] = builder.build()

View file

@ -1,6 +1,6 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
@Suppress("unused") @Suppress("unused")
enum class Vendor( enum class Vendor(
@ -254,7 +254,7 @@ enum class Vendor(
} }
} }
fun MultiParamsBuilder.vendors(body: VendorBuilder.() -> VendorBuilder): MultiParamsBuilder { fun ParamsBuilder.vendors(body: VendorBuilder.() -> VendorBuilder): ParamsBuilder {
val builder = VendorBuilder() val builder = VendorBuilder()
builder.body() builder.body()
this[Vendor.staticParamName] = builder.build() this[Vendor.staticParamName] = builder.build()

View file

@ -1,13 +1,13 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
import de.pheerai.rcdbquery.dsl.MultiParamsBuilder import de.pheerai.rcdbquery.dsl.ParamsBuilder
@Suppress("unused") @Suppress("unused")
@Deprecated( @Deprecated(
"The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)", "The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)",
ReplaceWith("sortBy"), DeprecationLevel.ERROR ReplaceWith("sortBy"), DeprecationLevel.ERROR
) )
fun MultiParamsBuilder.extraColumns(orders: List<Order>): Nothing = fun ParamsBuilder.extraColumns(orders: List<Order>): Nothing =
error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)") error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)")
@Suppress("unused") @Suppress("unused")
@ -15,5 +15,5 @@ fun MultiParamsBuilder.extraColumns(orders: List<Order>): Nothing =
"The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)", "The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)",
ReplaceWith("sortBy"), DeprecationLevel.ERROR ReplaceWith("sortBy"), DeprecationLevel.ERROR
) )
fun MultiParamsBuilder.extraColumns(vararg orders: Order): Nothing = fun ParamsBuilder.extraColumns(vararg orders: Order): Nothing =
error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)") error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)")

View file

@ -3,6 +3,25 @@ package de.pheerai.rcdbquery.dsl
import de.pheerai.rcdbquery.dataMappings.RcdbParamOption import de.pheerai.rcdbquery.dataMappings.RcdbParamOption
import de.pheerai.rcdbquery.dataMappings.SearchType import de.pheerai.rcdbquery.dataMappings.SearchType
data class RcdbParams(
val multiParams: MultiParams,
val singleParams: SingleParams
) {
fun toStrings(): List<String> {
val multiParamSequence: Sequence<Pair<String, String>> = this.multiParams
.params
.asSequence()
.map { e -> e.key to e.value.joinToString(separator = ",") }
val singleParamSequence: Sequence<Pair<String,String>> = this.singleParams
.params
.asSequence()
.map { it.toPair() }
return singleParamSequence.plus(multiParamSequence)
.map { p -> "${p.first}=${p.second}" }
.toList()
}
}
// In preparation for new handler // In preparation for new handler
sealed class Params<T> { sealed class Params<T> {
abstract val params: Map<String, T> abstract val params: Map<String, T>
@ -11,44 +30,51 @@ sealed class Params<T> {
class MultiParams(override val params: Map<String, List<String>>) : Params<List<String>>() class MultiParams(override val params: Map<String, List<String>>) : Params<List<String>>()
class SingleParams(override val params: Map<String, String>) : Params<String>() class SingleParams(override val params: Map<String, String>) : Params<String>()
interface ParamsBuilder<out T, in U> { class ParamsBuilder {
fun build(): T
operator fun set(paramName: String, options: U)
}
class MultiParamsBuilder : ParamsBuilder<MultiParams, List<RcdbParamOption<Any>>> {
private val multiParams: MutableMap<String, List<RcdbParamOption<Any>>> = mutableMapOf() private val multiParams: MutableMap<String, List<RcdbParamOption<Any>>> = mutableMapOf()
private val singleParams: MutableMap<String, RcdbParamOption<Any>> = mutableMapOf()
fun build() = RcdbParams(buildMulti(), buildSingle())
/** /**
* Creates the Query Params from this builder. * Creates the Query Params from this builder.
* If no Search type has been set, this will default to "Coaster" * If no Search type has been set, this will default to "Coaster"
*/ */
override fun build() = multiParams.apply { private fun buildMulti() = multiParams.apply {
putIfAbsent(SearchType.staticParamName, listOf(SearchType.COASTER)) putIfAbsent(SearchType.staticParamName, listOf(SearchType.COASTER))
} }
.filter { it.value.isNotEmpty() } .filter { it.value.isNotEmpty() }
.mapValues { e -> e.value.map { o -> o.paramValue.toString() } } .mapValues { e -> e.value.map { o -> o.paramValue.toString() } }
.let { MultiParams(it) } .let { MultiParams(it) }
private fun buildSingle() = singleParams.apply {
// Defaults go here
}
.mapValues { it.toString() }
.let { SingleParams(it) }
override operator fun set(paramName: String, options: List<RcdbParamOption<Any>>) { operator fun set(paramName: String, options: List<RcdbParamOption<Any>>) {
this.multiParams[paramName] = options this.multiParams[paramName] = options
} }
operator fun get(paramName: String) = this.multiParams[paramName] operator fun set(paramName: String, option: RcdbParamOption<Any>) {
this.singleParams[paramName] = option
fun keys() = this.multiParams.keys.toSet()
} }
fun rcdbQuery(body: MultiParamsBuilder.() -> MultiParamsBuilder) = fun getSingle(paramName: String) = this.multiParams[paramName] ?: this.singleParams[paramName]
fun getMulti(paramName: String) = this.multiParams[paramName]
fun keys() = this.multiKeys().plus(singleKeys())
private fun multiKeys() = this.multiParams.keys.toSet()
private fun singleKeys() = this.singleParams.keys.toSet()
}
fun rcdbQuery(body: ParamsBuilder.() -> ParamsBuilder) =
RcdbUrlQuery("https://www.rcdb.com/r.htm?", rcdbQueryParams(body)).toString() RcdbUrlQuery("https://www.rcdb.com/r.htm?", rcdbQueryParams(body)).toString()
data class RcdbUrlQuery(val baseUrl: String, val params: MultiParams) { data class RcdbUrlQuery(val baseUrl: String, val params: RcdbParams) {
override fun toString(): String { override fun toString(): String {
return params.params return params.toStrings()
.asSequence()
.map { e -> e.key to e.value.joinToString(separator = ",") }
.map { p -> "${p.first}=${p.second}" }
.joinToString(prefix = baseUrl, separator = "&") .joinToString(prefix = baseUrl, separator = "&")
} }
} }
@ -56,8 +82,8 @@ data class RcdbUrlQuery(val baseUrl: String, val params: MultiParams) {
/** /**
* Builder for the parameters only (mainly because it might be possilbe in the future to have an API with a POST search object? * Builder for the parameters only (mainly because it might be possilbe in the future to have an API with a POST search object?
*/ */
fun rcdbQueryParams(body: MultiParamsBuilder.() -> MultiParamsBuilder): MultiParams { fun rcdbQueryParams(body: ParamsBuilder.() -> ParamsBuilder): RcdbParams {
val builder = MultiParamsBuilder() val builder = ParamsBuilder()
builder.body() builder.body()
return builder.build() return builder.build()
} }