Johan J
Johan J

Reputation: 101

Using Phantom 2 with an existing Cassandra session

I am trying to migrate our current implementation from Phantom 1.28.16 to 2.16.4 but I'm running into problems with the setup.

Our framework is providing us with the Cassandra session object during startup which doesn't seem to fit with Phantom. I am trying to get Phantom to accept that already instantiated session instead of going through the regular CassandraConnection object.

I'm assuming that we can't use the Phantom Database class because of this but I am hoping that there still is some way to set up and use the Tables without using that class.

Is this doable?

Upvotes: 3

Views: 185

Answers (1)

Johan J
Johan J

Reputation: 101

I ended up doing the following to be able to use Phantom with an existing connection:

Defined a new trait PhantomTable to be used instead of Phantoms 'Table' trait. They are identical except for removal of the RootConnector

trait PhantomTable[T <: PhantomTable[T, R], R] extends CassandraTable[T, R] with TableAliases[T, R]

Defined my tables by extending the PhantomTable trait and also made it to an object. Here I had to import all of the TableHelper macro to get it to compile

...
import com.outworkers.phantom.macros.TableHelper._

final case class Foo(id: String, name: Option[String])

sealed class FooTable extends PhantomTable[FooTable, Foo] {
  override val tableName = "foo"

  object id              extends StringColumn with PartitionKey
  object name            extends OptionalStringColumn
}

object FooTable extends FooTable

After that it is possible to use all the wanted methods on the FooTable object as long as an implicit Keyspace and Session exists in the scope.

This is a simple main program that shows how the tables can be used

object Main extends App {
  val ks = "foo_keyspace"
  val cluster = Cluster.builder().addContactPoints("127.0.0.1").build()

  implicit val keyspace: KeySpace = KeySpace(ks)
  implicit val session: Session   = cluster.connect(ks)

  val res = for {
    _ <- FooTable.create.ifNotExists.future
    _ <- FooTable.insert.value(_.id, "1").value(_.name, Some("data")).future
    row <- FooTable.select.where(_.id eqs "1").one
  } yield row

  val r = Await.result(res, 10.seconds)
  println(s"Row: $r")
}

Upvotes: 0

Related Questions