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

imagnusson.kuzminki-pekko_3.0.9.5.source-code.stream.scala Maven / Gradle / Ivy

The newest version!
/*
* Copyright 2021 Kári Magnússon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package kuzminki.pekko

import scala.deriving.Mirror.ProductOf
import scala.concurrent.{Future, ExecutionContext}
import org.apache.pekko.{Done, NotUsed}
import org.apache.pekko.stream.scaladsl.{Source, Sink}
import kuzminki.api.Kuzminki
import kuzminki.select.{Pages, Offset}
import kuzminki.insert.StoredInsert
import kuzminki.delete.StoredDelete
import kuzminki.update.StoredUpdate


package object stream {

  extension [P](query: StoredInsert[P]) {

    def asSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[P, Future[Done]] = {
      Sink.foreachAsync(1) { (p: P) =>
        db.exec(query.render(p))
      }
    }

    def asChunkSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Seq[P], Future[Done]] = {
      Sink.foreachAsync(1) { (chunk: Seq[P]) =>
        db.execList(
          chunk.map { (p: P) => query.render(p) }
        )
      }
    }

    def asTypeSink[T <: Product](
      using mirror: ProductOf[T],
            ev: P <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Sink[T, Future[Done]] = {
      Sink.foreachAsync(1) { (t: T) =>
        db.exec(
          query.render(
            Tuple.fromProductTyped(t).asInstanceOf[P]
          )
        )
      }
    }

    def asTypeChunkSink[T <: Product](
      using mirror: ProductOf[T],
            ev: P <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Seq[T], Future[Done]] = {
      Sink.foreachAsync(1) { (chunk: Seq[T]) =>
        db.execList(
          chunk.toList.map { (t: T) =>
            query.render(
              Tuple.fromProductTyped(t).asInstanceOf[P]
            )
          }
        )
      }
    }
  }

  extension [P](query: StoredDelete[P]) {

    def asSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[P, Future[Done]] = {
      Sink.foreachAsync(1) { (p: P) =>
        db.exec(query.render(p))
      }
    }

    def asChunkSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Seq[P], Future[Done]] = {
      Sink.foreachAsync(1) { (chunk: Seq[P]) =>
        db.execList(
          chunk.map { (p: P) => query.render(p) }
        )
      }
    }

    def asTypeSink[T <: Product](
      using mirror: ProductOf[T],
            ev: P <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Sink[T, Future[Done]] = {
      Sink.foreachAsync(1) { (t: T) =>
        db.exec(
          query.render(
            Tuple.fromProductTyped(t).asInstanceOf[P]
          )
        )
      }
    }

    def asTypeChunkSink[T <: Product](
      using mirror: ProductOf[T],
            ev: P <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Seq[T], Future[Done]] = {
      Sink.foreachAsync(1) { (chunk: Seq[T]) =>
        db.execList(
          chunk.toList.map { (t: T) =>
            query.render(
              Tuple.fromProductTyped(t).asInstanceOf[P]
            )
          }
        )
      }
    }
  }

  extension [P1, P2](query: StoredUpdate[P1, P2]) {

    def asSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Tuple2[P1, P2], Future[Done]] = {
      Sink.foreachAsync(1) { (p: Tuple2[P1, P2]) =>
        db.exec(query.render(p._1, p._2))
      }
    }

    def asChunkSink(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Sink[Seq[Tuple2[P1, P2]], Future[Done]] = {
      Sink.foreachAsync(1) { (chunk: Seq[Tuple2[P1, P2]]) =>
        db.execList(
          chunk.toList.map { (p: Tuple2[P1, P2]) =>
            query.render(p._1, p._2)
          }
        )
      }
    }
  }

  extension [M, R](query: Offset[M, R]) {

    def stream(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Source[R, NotUsed] = {
      stream(100)
    }

    def stream(size: Int)(
      using db: Kuzminki,
            ec: ExecutionContext
    ): Source[R, NotUsed] = {
      val pages = Pages(query.render, size)
      Source
        .unfoldAsync(pages) { pages =>
          pages.next.map {
            case Nil => None
            case items => Some((pages, items))
          }
        }
        .mapConcat(i => i)
    }

    def streamType[T <: Product](
      using mirror: ProductOf[T],
            ev: R <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Source[T, NotUsed] = {
      stream.map((r: R) => mirror.fromProduct(r))
    }

    def streamType[T <: Product](size: Int)(
      using mirror: ProductOf[T],
            ev: R <:< mirror.MirroredElemTypes,
            db: Kuzminki,
            ec: ExecutionContext
    ): Source[T, NotUsed] = {
      stream(size).map((r: R) => mirror.fromProduct(r))
    }
  }
}









© 2015 - 2024 Weber Informatics LLC | Privacy Policy