-
Notifications
You must be signed in to change notification settings - Fork 1
Queries and Statements as Interpolated
Let's see how we can define queries as string interpolation:
First we need to mark a CqlSession implicit:
import net.nmoncho.helenus.*
given CqlSession = cqlSession
given Future[CqlSession] = Future.successful(cqlSession)
Then we can define queries as Interpolated Strings, using the cql
prefix:
val hotel = "Rotterdam Marriott"
// hotel: String = "Rotterdam Marriott"
val hotelsByName = cql"SELECT * FROM hotels_cql WHERE name = $hotel"
// hotelsByName: WrappedBoundStatement[Row] = net.nmoncho.helenus.api.cql.WrappedBoundStatement@41d0f3a4
val resultSet = hotelsByName.execute()
// resultSet: PagingIterable[Row] = com.datastax.oss.driver.internal.core.PagingIterableWrapper@692e3baf
val result = resultSet.nextOption()
// result: Option[Row] = Some(
// value = com.datastax.oss.driver.internal.core.cql.DefaultRow@1fd72db0
// )
After we interpolate at statement, we'll receive a ScalaBoundStatement
, which
we cna execute when we see fit.
Interpolated values will be replaced with Named Bind Parameters, making sure the query has been sanitized.
To avoid boilerplate, it's also possible to use constants, defined with final val
, in your queries:
object Keyspace {
final val table = "hotels_cql"
final val country = "country"
final val name = "name"
}
val bstmt =
cql"SELECT ${Keyspace.country}, ${Keyspace.name} FROM ${Keyspace.table} WHERE ${Keyspace.name} = $hotel"
// bstmt: WrappedBoundStatement[Row] = net.nmoncho.helenus.api.cql.WrappedBoundStatement@378cbc01
// Let's take a look at the final query:
bstmt.getPreparedStatement.getQuery
// res3: String = "SELECT country, name FROM hotels_cql WHERE name = :hotel"
val hotelsByNameWithConstants = bstmt.execute().nextOption()
// hotelsByNameWithConstants: Option[Row] = Some(
// value = com.datastax.oss.driver.internal.core.cql.DefaultRow@71873487
// )
Note: Constants will be interpolated as is, even if they are in bind parameter position. This means that depending on the value of your constant, you may have to wrap it in quotes.
We can also define interpolated queries asynchronously with the cqlAsync
prefix:
val asyncBoundStatement = cqlAsync"SELECT * FROM hotels_cql WHERE name = $hotel"
// asyncBoundStatement: Future[WrappedBoundStatement[Row]] = Future(Success(net.nmoncho.helenus.api.cql.WrappedBoundStatement@69ec9a5b))
val asyncResult = for {
query <- asyncBoundStatement
resultSet <- query.executeAsync()
} yield resultSet.currPage.nextOption()
// asyncResult: Future[Option[Row]] = Future(Success(Some(com.datastax.oss.driver.internal.core.cql.DefaultRow@4f70807b)))
Defining and executing queries is one part of the story. The other part is how we make sense
of the Row
s
we get out of these queries.
We can iterate results using some extension methods, and we can map
rows to a more meaningful result using RowMapper
s.