Scala connections to your Cassandra database


30 March 2015, by

ORMs can be a complicated part of any app that you are writing, so it is always great to find one which makes life easier. On a recent Scala project, we chose to use Phantom to connect to our Cassandra database. The advantages it offers are that it provides a very simple interface for accessing data, and also creating column families while still being based on the datastax driver. This is great as it means that your code remains very readable, but you are also still free to use any advanced features which may not have found their way into the library yet. The following examples all compile against Phantom version 1.22.0.

Here’s a simple example of a class that could be used to access a column family:

import com.datastax.driver.core.Row
import com.websudos.phantom.CassandraTable
import com.websudos.phantom.connectors.RootConnector
import com.websudos.phantom.dsl._
import java.util.UUID
import scala.concurrent.Future

class FooTable extends CassandraTable[ConcreteFoo, Foo] {
 object id extends UUIDColumn(this) with PartitionKey[UUID]
 object bar extends StringColumn(this)
 object baz extends IntColumn(this)

 def fromRow(row: Row): Foo = {
 Foo(
 id(row),
 bar(row),
 baz(row))
 }
}

abstract class ConcreteFoo extends FooTable with RootConnector {
 def insert(row: Foo): Future[ResultSet] = {
 insert.value(_.id, row.id)
 .value(_.bar, row.bar)
 .value(_.baz, row.baz)
 .future()
 }

 def getById(id: UUID): Future[Option[Foo]] = select.where(_.id eqs id).one()
}

case class Foo(id: UUID, bar: String, baz: Int)

That’s now sufficient for us to do most of the interaction we want with the database. However, before we can interact with it, we’ll also need a database connection. This can be done using the following code (don’t forget to update the connection values to be correct for one of your cassandra nodes).

import com.websudos.phantom.connectors.{KeySpaceDef, ContactPoint}

object DefaultConnector {
 val connector: KeySpaceDef = ContactPoint.local.withClusterBuilder(_.withCredentials("admin", "password")).keySpace("keyspace")
}

class Database(val keyspace: KeySpaceDef) extends Database(keyspace) {
 object foo extends ConcreteFoo with keyspace.Connector
}

object Database extends Database(DefaultConnector.connector)

The Phantom library will take care of handling database connections for you when you access data through these objects.

Now that we’ve got a connection, it’s simple to:

Create the column family in the database:

Database.foo.create.ifNotExists().future()

Put some data into the database:

Database.foo.insert(Foo(UUID.randomUUID(), "new foo", 1234))

Get some data out of the database:

Database.foo.getById(UUID.fromString("uuid1"))

This simple interface should be enough to do most things with your Cassandra database, and hopefully the code snippets above will help in setting you up for easy database interactions!

If you would like to know some more advanced tips on phantom, check out the outworkers’ blog.

Tags: , , , , , ,

Categories: Technical

«
»

Leave a Reply

* Mandatory fields


8 + = sixteen

Submit Comment