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

io.kaizensolutions.virgil.cql.CqlInterpolatedString.scala Maven / Gradle / Ivy

There is a newer version: 1.2.2
Show newest version
package io.kaizensolutions.virgil.cql

import com.datastax.oss.driver.api.core.cql.Row
import io.kaizensolutions.virgil.CQL
import io.kaizensolutions.virgil.MutationResult
import io.kaizensolutions.virgil.codecs.CqlRowDecoder
import io.kaizensolutions.virgil.internal.BindMarkers

import scala.collection.immutable.ListMap
import scala.collection.mutable

/**
 * CqlInterpolatedString is an intermediate representation that can render
 * itself into the final representation that can be submitted to Cassandra for
 * execution.
 *
 * Please note Array is mutable and is used for performance.
 */
final case class CqlInterpolatedString(
  private[cql] val rawQueryRepresentation: Array[CqlPartRepr]
) {
  private[virgil] def render: (String, ListMap[String, ValueInCql]) = {
    val queryString         = new mutable.StringBuilder
    var markers             = ListMap.empty[String, ValueInCql]
    var markerCounter       = 0
    val parameterNamePrefix = "param"
    val colon               = ":"

    rawQueryRepresentation.foreach {
      case CqlPartRepr.Pair(query, marker) =>
        val param = s"$parameterNamePrefix${markerCounter}"
        queryString.append(query + colon + param)
        markers = markers + (param -> marker)
        markerCounter += 1

      case CqlPartRepr.Query(query) =>
        queryString.append(query)

      case CqlPartRepr.Marker(marker) =>
        val param = s"$parameterNamePrefix${markerCounter}"
        queryString.append(colon + param)
        markers = markers + (param -> marker)
        markerCounter += 1
    }

    (queryString.toString(), markers)
  }

  def mutation: CQL[MutationResult] = {
    val (queryString, dataToBeBound) = render
    CQL.cqlMutation(queryString, BindMarkers.from(dataToBeBound))
  }

  def query[Output](implicit evidence: CqlRowDecoder.Object[Output]): CQL[Output] = {
    val (queryString, dataToBeBound) = render
    CQL.cqlQuery(queryString, BindMarkers.from(dataToBeBound))
  }

  def query: CQL[Row] =
    query(CqlRowDecoder.cqlRowDecoderForUnderlyingRow)

  def ++(that: CqlInterpolatedString): CqlInterpolatedString =
    CqlInterpolatedString(rawQueryRepresentation ++ that.rawQueryRepresentation)

  def appendString(that: String): CqlInterpolatedString =
    CqlInterpolatedString(rawQueryRepresentation :+ CqlPartRepr.Query(that))

  def stripMargin: CqlInterpolatedString =
    copy(rawQueryRepresentation = rawQueryRepresentation.map {
      case CqlPartRepr.Pair(query, marker) => CqlPartRepr.Pair(query.stripMargin, marker)
      case CqlPartRepr.Query(query)        => CqlPartRepr.Query(query.stripMargin)
      case m @ CqlPartRepr.Marker(_)       => m
    })
}
trait CqlInterpolatedStringSyntax {
  implicit class CqlInterpolatedStringOpsForString(self: String) {
    def appendCql(that: CqlInterpolatedString): CqlInterpolatedString =
      CqlInterpolatedString(CqlPartRepr.Query(self) +: that.rawQueryRepresentation)

    def asCql: CqlInterpolatedString =
      CqlInterpolatedString(Array(CqlPartRepr.Query(self)))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy