All Downloads are FREE. Search and download functionalities are using the official Maven repository.

compstak.kafkastreams4s.debezium.DebeziumTable.scala Maven / Gradle / Ivy

The newest version!
package compstak.kafkastreams4s.debezium

import org.apache.kafka.streams.{KeyValue, StreamsBuilder}
import org.apache.kafka.streams.kstream.{Consumed, Initializer, KTable, Produced, ValueMapper, ValueMapperWithKey}
import org.apache.kafka.common.serialization.Serde
import compstak.kafkastreams4s.circe.CirceSerdes._
import compstak.circe.debezium.{DebeziumKey, DebeziumValue}
import io.circe.{Decoder, Encoder}
import cats.{Functor, FunctorFilter}
import cats.effect.Sync
import compstak.kafkastreams4s.circe.CirceTable

case class DebeziumTable[K: Encoder: Decoder, V: Encoder: Decoder](
  topicName: String,
  idNameOrKeySchema: Either[(String, DebeziumPrimitiveType[K]), DebeziumCompositeType[K]],
  toCirceTable: CirceTable[DebeziumKey[K], V]
) {

  def to[F[_]: Sync](outputTopicName: String): F[Unit] =
    toCirceTable.to(outputTopicName)

  def map[V2: Encoder: Decoder](f: V => V2): DebeziumTable[K, V2] =
    copy(toCirceTable = toCirceTable.map(f))

  def mapWithKey[V2: Encoder: Decoder](f: (DebeziumKey[K], V) => V2): DebeziumTable[K, V2] =
    copy(toCirceTable = toCirceTable.mapWithKey(f))

  def mapFilter[V2: Encoder: Decoder](f: V => Option[V2]): DebeziumTable[K, V2] =
    copy(toCirceTable = toCirceTable.mapFilter(f))

  def mapFilterWithKey[V2: Encoder: Decoder](f: (DebeziumKey[K], V) => Option[V2]): DebeziumTable[K, V2] =
    copy(toCirceTable = toCirceTable.mapFilterWithKey(f))

  def filter(f: V => Boolean): DebeziumTable[K, V] =
    copy(toCirceTable = toCirceTable.filter(f))

  def join[K2, V2, Z: Encoder: Decoder](
    other: DebeziumTable[K2, V2]
  )(f: V => K2)(g: (V, V2) => Z): DebeziumTable[K, Z] =
    other.idNameOrKeySchema match {
      case Left((idName, prim)) =>
        implicit val primK2: DebeziumPrimitiveType[K2] = prim
        copy(toCirceTable = JoinTables.join(toCirceTable, other.toCirceTable, idName, other.topicName)(f)(g))
      case Right(schema) =>
        copy(toCirceTable = JoinTables.joinComposite(toCirceTable, other.toCirceTable, schema, other.topicName)(f)(g))
    }

  def joinOption[K2, V2, Z: Encoder: Decoder](
    other: DebeziumTable[K2, V2]
  )(f: V => Option[K2])(g: (V, V2) => Z): DebeziumTable[K, Z] =
    other.idNameOrKeySchema match {
      case Left((idName, prim)) =>
        implicit val primK2: DebeziumPrimitiveType[K2] = prim
        copy(toCirceTable = JoinTables.joinOption(toCirceTable, other.toCirceTable, idName, other.topicName)(f)(g))
      case Right(schema) =>
        copy(toCirceTable =
          JoinTables.joinOptionComposite(toCirceTable, other.toCirceTable, schema, other.topicName)(f)(g)
        )
    }

  def leftJoin[K2, V2, Z: Encoder: Decoder](
    other: DebeziumTable[K2, V2]
  )(f: V => K2)(g: (V, Option[V2]) => Z): DebeziumTable[K, Z] =
    other.idNameOrKeySchema match {
      case Left((idName, prim)) =>
        implicit val primK2: DebeziumPrimitiveType[K2] = prim
        copy(toCirceTable = JoinTables.leftJoin(toCirceTable, other.toCirceTable, idName, other.topicName)(f)(g))
      case Right(schema) =>
        copy(toCirceTable =
          JoinTables.leftJoinComposite(toCirceTable, other.toCirceTable, schema, other.topicName)(f)(g)
        )
    }

  def leftJoinOption[K2, V2, Z: Encoder: Decoder](
    other: DebeziumTable[K2, V2]
  )(f: V => Option[K2])(g: (V, Option[V2]) => Z): DebeziumTable[K, Z] =
    other.idNameOrKeySchema match {
      case Left((idName, prim)) =>
        implicit val primK2: DebeziumPrimitiveType[K2] = prim
        copy(toCirceTable = JoinTables.leftJoinOption(toCirceTable, other.toCirceTable, idName, other.topicName)(f)(g))
      case Right(schema) =>
        copy(toCirceTable =
          JoinTables.leftJoinOptionComposite(toCirceTable, other.toCirceTable, schema, other.topicName)(f)(g)
        )
    }
}

object DebeziumTable {
  def withCirceDebezium[K: Encoder: Decoder: DebeziumPrimitiveType, V: Encoder: Decoder](
    sb: StreamsBuilder,
    topicName: String,
    idName: String
  ): DebeziumTable[K, DebeziumValue[V]] =
    DebeziumTable(
      topicName,
      Left(idName -> DebeziumPrimitiveType[K]),
      CirceTable[DebeziumKey[K], DebeziumValue[V]](sb, topicName)
    )

  def withCompositeKey[K: Encoder: Decoder, V: Encoder: Decoder](
    sb: StreamsBuilder,
    topicName: String,
    schema: DebeziumCompositeType[K]
  ): DebeziumTable[K, DebeziumValue[V]] =
    DebeziumTable(
      topicName,
      Right(schema),
      CirceTable[DebeziumKey[K], DebeziumValue[V]](sb, topicName)
    )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy