-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Helenus is collection of Scala utilities for Apache Cassandra. Its goal is to make interacting with Cassandra easier, in a type-safe manner, while trying to avoid introducing a complex API.
Include the library into you project definition:
libraryDependencies += "net.nmoncho" %% "helenus-core" % "1.8.3"We tried using libraries such as Phantom and Quill, which are great by the way, but they didn't fit entirely our mindset or workflow. We believe the best way to use Cassandra, or any DB for that matter, is to use its Query Language directly.
Helenus takes inspiration from libraries such as Anorm, trying to provide a similar experience by putting CQL first. Our goals are:
- Give users control over the queries that are actually executed.
- Keep the library simple with a concise API.
With this motivation in mind, Helenus builds on top of the concepts defined by the Cassandra Java Driver:
-
PrepareStatement:
The preferred way to define an DML operation (e.g.
SELECT, orINSERT). We use a string literal to define an operation. The driver will parse and validate the query. -
BoundStatement:
Once we have a
PreparedStatement, we can run it against the database by binding all the defined parameters (e.g.?) -
TypeCodec:
A
TypeCodectells the driver how to encode, or decode, a particular JVM type.
Helenus builds on top of these concepts:
- ScalaPreparedStatement: Extends the original
PreparedStatementstatement by introducing helper methods for execution. AScalaPreparedStatementcan be treated as a function, where its input parameters are the bound parameters defined in the statement, and its output as the rows that come out of executing the statement. - ScalaBoundStatement: When a
ScalaPreparedStatementis executed it will produce aScalaBoundStatementwhich carries along the output type defined by the original statement - RowMapper: A
RowMappertells Helenus how to extract desired results out of a Row.RowMappers can be defined explicitly, or derived implicitly (See Extracting Results) - Adapter: Statements are defined with a sequence of parameters. An
Adaptertells Helenus how to adapt a complex type, such as case class, to the parameters a statement expects. - Mapping: A
Mappingbrings both anAdapterand aRowMapperunder the same abstraction. Its goal is to make working with case classes easier.Mappings are specially useful when the statement takes more than 22 parameters (e.g. inserting a case class that has more than 22 fields) - ColumnMapper: By default, implicitly derived
RowMappers will map columns to fields one-to-one. AColumnMappertells Helenus how to convert columns into/from fields in a more controlled fashion. - ColumnNamingScheme: By default, field names are mapped one-to-one to column names (e.g. for a field named
"hotelId"Helenus will expect a column name"hotelId"). With an implicitColumnNamingSchemeyou can control how this mapping is done. - Pager: A
Pagerlet's you query results in a paginated fashion, providing a consistent behavior regardless of how you execute such query. Please read Pagination
With these concepts in mind, let's see how we work with the library.
We can define queries and statements in two ways: as functions, or as interpolated statements.
The main distinction between these two is that with the former we get a ScalaPreparedStatement
which we use as a function to get data in or out of Cassandra, creating a ScalaBoundStatement in
the process (ie. parameters have to be bound before executing the statement). With the latter we
get directly a ScalaBoundStatement as parameters are defined at the same moment as the statement
(the statement is still prepared but everything is done in one step).
The Cassandra Java Driver caches PreparedStatements, so using an Interpolated Statement won't
prepare the query multiple times.
Statements can be executed in three ways:
- Synchronously
- Asynchronously
- Reactively (e.g. Akka or Pekko Streams)
For documentation on TypeCodec, see Codecs.
For Akka Streams integration, see Akka.
For Flink integration, see Flink.
For Monix integration, see Monix.
For Pekko Streams integration, see Pekko.
For ZIO Streams integration, see ZIO.