diff --git a/client-base/src/main/kotlin/app/cash/backfila/client/spi/BackfillRegistration.kt b/client-base/src/main/kotlin/app/cash/backfila/client/spi/BackfillRegistration.kt index 958af309f..f43761ff6 100644 --- a/client-base/src/main/kotlin/app/cash/backfila/client/spi/BackfillRegistration.kt +++ b/client-base/src/main/kotlin/app/cash/backfila/client/spi/BackfillRegistration.kt @@ -3,10 +3,12 @@ package app.cash.backfila.client.spi import java.time.Instant import kotlin.reflect.KClass -data class BackfillRegistration @JvmOverloads constructor( +data class BackfillRegistration +@JvmOverloads +constructor( val name: String, val description: String?, - val parametersClass: KClass, + val parametersClass: KClass, val deleteBy: Instant?, val unit: String? = null, ) diff --git a/client-base/src/test/kotlin/app/cash/backfila/client/fixedset/FixedSetBackend.kt b/client-base/src/test/kotlin/app/cash/backfila/client/fixedset/FixedSetBackend.kt index e1e20446f..347e21395 100644 --- a/client-base/src/test/kotlin/app/cash/backfila/client/fixedset/FixedSetBackend.kt +++ b/client-base/src/test/kotlin/app/cash/backfila/client/fixedset/FixedSetBackend.kt @@ -18,12 +18,13 @@ import kotlin.reflect.KClass import kotlin.reflect.full.findAnnotation @Singleton -class FixedSetBackend @Inject constructor( +class FixedSetBackend +@Inject +constructor( private val injector: Injector, @ForFixedSetBackend private val backfills: MutableMap>>, private val datastore: FixedSetDatastore, ) : BackfillBackend { - /** Creates Backfill instances. Each backfill ID gets a new Backfill instance. */ private fun getBackfill(name: String): FixedSetBackfill<*>? { val backfillClass = backfills[name] @@ -34,13 +35,16 @@ class FixedSetBackend @Inject constructor( } } - private fun createOperator( - backfill: FixedSetBackfill, - ) = FixedSetBackfillOperator( - backfill = backfill, - datastore = datastore, - parametersOperator = BackfilaParametersOperator(parametersClass(backfill::class)), - ) + @Suppress("UNCHECKED_CAST") + private fun createOperator(backfill: FixedSetBackfill) = + FixedSetBackfillOperator( + backfill = backfill, + datastore = datastore, + parametersOperator = + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, + ) override fun create(backfillName: String): BackfillOperator? { val backfill = getBackfill(backfillName) @@ -53,19 +57,19 @@ class FixedSetBackend @Inject constructor( return null } - override fun backfills(): Set { - return backfills.map { - BackfillRegistration( - name = it.key, - description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), - deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), - unit = BackfillUnit.ITEMS.displayName, - ) - }.toSet() - } + override fun backfills(): Set = + backfills + .map { + BackfillRegistration( + name = it.key, + description = it.value.findAnnotation()?.text, + parametersClass = parametersClass(it.value), + deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), + unit = BackfillUnit.ITEMS.displayName, + ) + }.toSet() - private fun parametersClass(backfillClass: KClass>): KClass { + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -73,6 +77,6 @@ class FixedSetBackend @Inject constructor( val supertype = thisType.getSupertype(FixedSetBackfill::class.java).type as ParameterizedType // Like MyDataClass - return (Types.getRawType(supertype.actualTypeArguments[0]) as Class).kotlin + return (Types.getRawType(supertype.actualTypeArguments[0])).kotlin } } diff --git a/client-dynamodb-v2/src/main/kotlin/app/cash/backfila/client/dynamodbv2/internal/DynamoDbBackend.kt b/client-dynamodb-v2/src/main/kotlin/app/cash/backfila/client/dynamodbv2/internal/DynamoDbBackend.kt index b8b23d847..a30cd4bef 100644 --- a/client-dynamodb-v2/src/main/kotlin/app/cash/backfila/client/dynamodbv2/internal/DynamoDbBackend.kt +++ b/client-dynamodb-v2/src/main/kotlin/app/cash/backfila/client/dynamodbv2/internal/DynamoDbBackend.kt @@ -21,13 +21,14 @@ import kotlin.reflect.full.findAnnotation import software.amazon.awssdk.services.dynamodb.DynamoDbClient @Singleton -class DynamoDbBackend @Inject constructor( +class DynamoDbBackend +@Inject +constructor( private val injector: Injector, @ForDynamoDbBackend private val backfills: MutableMap>>, private val dynamoDbClient: DynamoDbClient, val keyRangeCodec: DynamoDbKeyRangeCodec, ) : BackfillBackend { - /** Creates Backfill instances. Each backfill ID gets a new Backfill instance. */ private fun getBackfill(name: String): DynamoDbBackfill<*, *>? { val backfillClass = backfills[name] @@ -38,14 +39,16 @@ class DynamoDbBackend @Inject constructor( } } - private fun createDynamoDbOperator( - backfill: DynamoDbBackfill, - ) = DynamoDbBackfillOperator( - dynamoDbClient, - backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), - keyRangeCodec, - ) + @Suppress("UNCHECKED_CAST") + private fun createDynamoDbOperator(backfill: DynamoDbBackfill) = + DynamoDbBackfillOperator( + dynamoDbClient, + backfill, + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, + keyRangeCodec, + ) override fun create(backfillName: String): BackfillOperator? { val backfill = getBackfill(backfillName) @@ -58,19 +61,19 @@ class DynamoDbBackend @Inject constructor( return null } - override fun backfills(): Set { - return backfills.map { - BackfillRegistration( - name = it.key, - description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), - deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), - unit = BackfillUnit.SEGMENTS.displayName, - ) - }.toSet() - } + override fun backfills(): Set = + backfills + .map { + BackfillRegistration( + name = it.key, + description = it.value.findAnnotation()?.text, + parametersClass = parametersClass(it.value), + deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), + unit = BackfillUnit.SEGMENTS.displayName, + ) + }.toSet() - private fun

parametersClass(backfillClass: KClass>): KClass

{ + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -78,6 +81,6 @@ class DynamoDbBackend @Inject constructor( val supertype = thisType.getSupertype(DynamoDbBackfill::class.java).type as ParameterizedType // Like MyParameterClass - return (Types.getRawType(supertype.actualTypeArguments[1]) as Class

).kotlin + return (Types.getRawType(supertype.actualTypeArguments[1])).kotlin } } diff --git a/client-dynamodb/src/main/kotlin/app/cash/backfila/client/dynamodb/internal/DynamoDbBackend.kt b/client-dynamodb/src/main/kotlin/app/cash/backfila/client/dynamodb/internal/DynamoDbBackend.kt index 1cbf6f0f9..a957cf174 100644 --- a/client-dynamodb/src/main/kotlin/app/cash/backfila/client/dynamodb/internal/DynamoDbBackend.kt +++ b/client-dynamodb/src/main/kotlin/app/cash/backfila/client/dynamodb/internal/DynamoDbBackend.kt @@ -21,13 +21,14 @@ import kotlin.reflect.KClass import kotlin.reflect.full.findAnnotation @Singleton -class DynamoDbBackend @Inject constructor( +class DynamoDbBackend +@Inject +constructor( private val injector: Injector, @ForDynamoDbBackend private val backfills: MutableMap>>, val dynamoDb: DynamoDBMapper, val keyRangeCodec: DynamoDbKeyRangeCodec, ) : BackfillBackend { - /** Creates Backfill instances. Each backfill ID gets a new Backfill instance. */ private fun getBackfill(name: String): DynamoDbBackfill<*, *>? { val backfillClass = backfills[name] @@ -38,14 +39,16 @@ class DynamoDbBackend @Inject constructor( } } - private fun createDynamoDbOperator( - backfill: DynamoDbBackfill, - ) = DynamoDbBackfillOperator( - dynamoDb, - backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), - keyRangeCodec, - ) + @Suppress("UNCHECKED_CAST") + private fun createDynamoDbOperator(backfill: DynamoDbBackfill) = + DynamoDbBackfillOperator( + dynamoDb, + backfill, + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, + keyRangeCodec, + ) override fun create(backfillName: String): BackfillOperator? { val backfill = getBackfill(backfillName) @@ -58,19 +61,19 @@ class DynamoDbBackend @Inject constructor( return null } - override fun backfills(): Set { - return backfills.map { - BackfillRegistration( - name = it.key, - description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), - deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), - unit = BackfillUnit.SEGMENTS.displayName, - ) - }.toSet() - } + override fun backfills(): Set = + backfills + .map { + BackfillRegistration( + name = it.key, + description = it.value.findAnnotation()?.text, + parametersClass = parametersClass(it.value), + deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), + unit = BackfillUnit.SEGMENTS.displayName, + ) + }.toSet() - private fun

parametersClass(backfillClass: KClass>): KClass

{ + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -78,6 +81,6 @@ class DynamoDbBackend @Inject constructor( val supertype = thisType.getSupertype(DynamoDbBackfill::class.java).type as ParameterizedType // Like MyParameterClass - return (Types.getRawType(supertype.actualTypeArguments[1]) as Class

).kotlin + return (Types.getRawType(supertype.actualTypeArguments[1])).kotlin } } diff --git a/client-jooq/src/main/kotlin/app/cash/backfila/client/jooq/internal/JooqBackend.kt b/client-jooq/src/main/kotlin/app/cash/backfila/client/jooq/internal/JooqBackend.kt index ceb4a6322..e43444576 100644 --- a/client-jooq/src/main/kotlin/app/cash/backfila/client/jooq/internal/JooqBackend.kt +++ b/client-jooq/src/main/kotlin/app/cash/backfila/client/jooq/internal/JooqBackend.kt @@ -36,18 +36,21 @@ class JooqBackend @Inject constructor( BackfillRegistration( name = it.key, description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), + parametersClass = parametersClass(it.value), deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), unit = BackfillUnit.ITEMS.displayName, ) }.toSet() } + @Suppress("UNCHECKED_CAST") private fun createJooqOperator( backfill: JooqBackfill, ) = JooqBackfillOperator( backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, ) /** Creates Backfill instances. Each backfill ID gets a new Backfill instance. */ @@ -60,7 +63,7 @@ class JooqBackend @Inject constructor( } } - private fun parametersClass(backfillClass: KClass>): KClass { + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -68,6 +71,6 @@ class JooqBackend @Inject constructor( val supertype = thisType.getSupertype(JooqBackfill::class.java).type as ParameterizedType // Like MyDataClass - return (Types.getRawType(supertype.actualTypeArguments[1]) as Class).kotlin + return (Types.getRawType(supertype.actualTypeArguments[1])).kotlin } } diff --git a/client-misk-hibernate/src/main/kotlin/app/cash/backfila/client/misk/hibernate/internal/HibernateBackend.kt b/client-misk-hibernate/src/main/kotlin/app/cash/backfila/client/misk/hibernate/internal/HibernateBackend.kt index 37f91b96a..90b587bfe 100644 --- a/client-misk-hibernate/src/main/kotlin/app/cash/backfila/client/misk/hibernate/internal/HibernateBackend.kt +++ b/client-misk-hibernate/src/main/kotlin/app/cash/backfila/client/misk/hibernate/internal/HibernateBackend.kt @@ -36,11 +36,14 @@ internal class HibernateBackend @Inject constructor( return injector.getInstance(backfillClass.java) as HibernateBackfill<*, *, *> } + @Suppress("UNCHECKED_CAST") private fun , Pkey : Any, Param : Any> createHibernateOperator( backfill: HibernateBackfill, ) = HibernateBackfillOperator( backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, this, ) @@ -56,14 +59,14 @@ internal class HibernateBackend @Inject constructor( BackfillRegistration( name = it.key, description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), + parametersClass = parametersClass(it.value), deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), unit = BackfillUnit.ITEMS.displayName, ) }.toSet() } - private fun parametersClass(backfillClass: KClass>): KClass { + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -71,7 +74,7 @@ internal class HibernateBackend @Inject constructor( val supertype = thisType.getSupertype(HibernateBackfill::class.java).type as ParameterizedType // Like MyDataClass - return (Types.getRawType(supertype.actualTypeArguments[2]) as Class).kotlin + return (Types.getRawType(supertype.actualTypeArguments[2])).kotlin } /** This placeholder exists so we can create a backfill without a type parameter. */ diff --git a/client-s3/src/main/kotlin/app/cash/backfila/client/s3/internal/S3DatasourceBackend.kt b/client-s3/src/main/kotlin/app/cash/backfila/client/s3/internal/S3DatasourceBackend.kt index 434d0cc7d..9b83634a7 100644 --- a/client-s3/src/main/kotlin/app/cash/backfila/client/s3/internal/S3DatasourceBackend.kt +++ b/client-s3/src/main/kotlin/app/cash/backfila/client/s3/internal/S3DatasourceBackend.kt @@ -35,18 +35,20 @@ class S3DatasourceBackend @Inject constructor( } } + @Suppress("UNCHECKED_CAST") private fun createS3DatasourceOperator( backfill: S3DatasourceBackfill, ) = S3DatasourceBackfillOperator( backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, s3Service, ) override fun create(backfillName: String): BackfillOperator? { return getBackfill(backfillName)?.let { backfill -> - @Suppress("UNCHECKED_CAST") // We don't know the types statically, so fake them. - return createS3DatasourceOperator(backfill as S3DatasourceBackfill) + return createS3DatasourceOperator(backfill) } } @@ -55,14 +57,14 @@ class S3DatasourceBackend @Inject constructor( BackfillRegistration( name = it.key, description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), + parametersClass = parametersClass(it.value), deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), unit = BackfillUnit.BYTES.displayName, ) }.toSet() } - private fun parametersClass(backfillClass: KClass>): KClass

{ + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -70,6 +72,6 @@ class S3DatasourceBackend @Inject constructor( val supertype = thisType.getSupertype(S3DatasourceBackfill::class.java).type as ParameterizedType // Like MyParameterClass - return (Types.getRawType(supertype.actualTypeArguments[1]) as Class

).kotlin + return (Types.getRawType(supertype.actualTypeArguments[1])).kotlin } } diff --git a/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/SqlDelightDatasourceBackfillModule.kt b/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/SqlDelightDatasourceBackfillModule.kt index d71961c2f..dd46a63e5 100644 --- a/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/SqlDelightDatasourceBackfillModule.kt +++ b/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/SqlDelightDatasourceBackfillModule.kt @@ -34,11 +34,11 @@ class SqlDelightDatasourceBackfillModule>) + backfillBinder().addBinding(backfillClass.jvmName).to(backfillClass.java) backfillRegistrationBinder().addBinding(backfillClass.jvmName).toInstance(registration) } - private fun parametersClass(): KClass { + private fun parametersClass(): KClass { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -48,7 +48,7 @@ class SqlDelightDatasourceBackfillModule).kotlin + return (Types.getRawType(supertype.actualTypeArguments[2])).kotlin } companion object { diff --git a/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/internal/SqlDelightDatasourceBackend.kt b/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/internal/SqlDelightDatasourceBackend.kt index 8ddfda1dc..28e31dc2a 100644 --- a/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/internal/SqlDelightDatasourceBackend.kt +++ b/client-sqldelight/src/main/kotlin/app/cash/backfila/client/sqldelight/internal/SqlDelightDatasourceBackend.kt @@ -6,9 +6,13 @@ import app.cash.backfila.client.spi.BackfillOperator import app.cash.backfila.client.spi.BackfillRegistration import app.cash.backfila.client.sqldelight.ForSqlDelightBackend import app.cash.backfila.client.sqldelight.SqlDelightDatasourceBackfill +import com.google.inject.TypeLiteral +import com.squareup.moshi.Types +import java.lang.reflect.ParameterizedType import javax.inject.Inject import javax.inject.Provider import javax.inject.Singleton +import kotlin.reflect.KClass @Singleton class SqlDelightDatasourceBackend @Inject constructor( @@ -16,16 +20,29 @@ class SqlDelightDatasourceBackend @Inject constructor( @ForSqlDelightBackend private val registrations: Map, ) : BackfillBackend { override fun create(backfillName: String): BackfillOperator? { - val parametersClass = registrations[backfillName]?.parametersClass ?: return null val backfill = providers[backfillName]?.get() ?: return null + return createOperator(backfill) + } + + @Suppress("UNCHECKED_CAST") + private fun createOperator( + backfill: SqlDelightDatasourceBackfill, + ) = SqlDelightDatasourceBackfillOperator( + backfill, + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator

, + ) + + private fun parametersClass(backfill: KClass>): KClass<*> { + // Like MyBackfill. + val thisType = TypeLiteral.get(backfill.java) - @Suppress("UNCHECKED_CAST") // We don't know the types statically, so fake them. - backfill as SqlDelightDatasourceBackfill + // Like S3DatasourceBackfill. + val supertype = thisType.getSupertype(SqlDelightDatasourceBackfill::class.java).type as ParameterizedType - return SqlDelightDatasourceBackfillOperator( - backfill, - BackfilaParametersOperator(parametersClass), - ) + // Like MyParameterClass + return (Types.getRawType(supertype.actualTypeArguments[2])).kotlin } override fun backfills(): Set { diff --git a/client-static/src/main/kotlin/app/cash/backfila/client/stat/internal/StaticDatasourceBackend.kt b/client-static/src/main/kotlin/app/cash/backfila/client/stat/internal/StaticDatasourceBackend.kt index de3bd97ed..2bf3cb48c 100644 --- a/client-static/src/main/kotlin/app/cash/backfila/client/stat/internal/StaticDatasourceBackend.kt +++ b/client-static/src/main/kotlin/app/cash/backfila/client/stat/internal/StaticDatasourceBackend.kt @@ -35,11 +35,14 @@ class StaticDatasourceBackend @Inject constructor( } } + @Suppress("UNCHECKED_CAST") private fun createStaticDatasourceOperator( backfill: StaticDatasourceBackfillBase, ) = StaticDatasourceBackfillOperator( backfill, - BackfilaParametersOperator(parametersClass(backfill::class)), + BackfilaParametersOperator( + parametersClass(backfill::class), + ) as BackfilaParametersOperator, ) override fun create(backfillName: String): BackfillOperator? { @@ -58,14 +61,14 @@ class StaticDatasourceBackend @Inject constructor( BackfillRegistration( name = it.key, description = it.value.findAnnotation()?.text, - parametersClass = parametersClass(it.value as KClass>), + parametersClass = parametersClass(it.value), deleteBy = it.value.findAnnotation()?.parseDeleteByDate(), unit = BackfillUnit.ITEMS.displayName, ) }.toSet() } - private fun

parametersClass(backfillClass: KClass>): KClass

{ + private fun parametersClass(backfillClass: KClass>): KClass<*> { // Like MyBackfill. val thisType = TypeLiteral.get(backfillClass.java) @@ -73,6 +76,6 @@ class StaticDatasourceBackend @Inject constructor( val supertype = thisType.getSupertype(StaticDatasourceBackfillBase::class.java).type as ParameterizedType // Like MyParameterClass - return (Types.getRawType(supertype.actualTypeArguments[1]) as Class

).kotlin + return (Types.getRawType(supertype.actualTypeArguments[1])).kotlin } }