0

我需要帮助来实现使用 phantom 和 cassandra 的通知模型。到目前为止我所做的:

import java.util.UUID

import com.websudos.phantom.dsl._
import com.websudos.phantom.connectors.Connector
import org.joda.time.DateTime

import scala.concurrent.Future

case class Notification(
  id:           UUID,
  userId:       UUID,
  timestamp:    DateTime,
  read:         Boolean,
  actionUser:   List[String],
  verb:         String,
  itemId:       UUID,
  collectionId: String
)

sealed class NotificationTable extends CassandraTable[NotificationTable, Notification] {

  object id extends UUIDColumn(this) with ClusteringOrder[UUID] with Ascending

  object userId extends StringColumn(this) with PartitionKey[String]

  object timestamp extends DateTimeColumn(this) with ClusteringOrder[DateTime] with Descending

  object read extends BooleanColumn(this)

  object actionUser extends ListColumn[NotificationTable, Notification, String](this)

  object verb extends StringColumn(this)

  object itemId extends UUIDColumn(this)

  object collectionId extends StringColumn(this)

  def fromRow(row: Row): Notification =
    Notification(
      id(row),
      userId(row),
      timestamp(row),
      read(row),
      actionUser(row),
      verb(row),
      itemId(row),
      collectionId(row)
    )
}

object NotificationTable extends NotificationTable with Connector {

  override def keySpace: String = "test"
  implicit val keyspace: com.websudos.phantom.connectors.KeySpace = com.websudos.phantom.connectors.KeySpace("test")
  def insertItem(item: Notification): Future[ResultSet] =
    insert
      .value(_.id, item.id)
      .value(_.userId, item.userId)
      .value(_.timestamp, item.timestamp)
      .value(_.read, item.read)
      .value(_.actionUser, item.actionUser) 
      .value(_.verb, item.verb)
      .value(_.itemId, item.itemId)
      .value(_.collectionId, item.collectionId)
      .future()
}

不知何故,我必须定义两个keyspaces,一个用于声明RootConnector,一个用于insert声明。这足够接近:这个例子,。然而,我的代码无法编译。我知道他们在那里使用了一个抽象类,因此它可以编译。

我的问题是我将如何使用那个抽象类?我只想从另一个 scala 源调用插入语句。

4

2 回答 2

2

尝试:

import java.util.UUID

import com.websudos.phantom.dsl._
import com.websudos.phantom.connectors.Connector
import org.joda.time.DateTime

import scala.concurrent.Future

case class Notification(
  id:           UUID,
  userId:       UUID,
  timestamp:    DateTime,
  read:         Boolean,
  actionUser:   List[String],
  verb:         String,
  itemId:       UUID,
  collectionId: String
)

//use normal class
class NotificationTable extends CassandraTable[NotificationTable, Notification] {

  object id extends UUIDColumn(this) with ClusteringOrder[UUID] with Ascending

  object userId extends StringColumn(this) with PartitionKey[String]

  object timestamp extends DateTimeColumn(this) with ClusteringOrder[DateTime] with Descending

  object read extends BooleanColumn(this)

  object actionUser extends ListColumn[NotificationTable, Notification, String](this)

  object verb extends StringColumn(this)

  object itemId extends UUIDColumn(this)

  object collectionId extends StringColumn(this)

  def fromRow(row: Row): Notification =
    Notification(
      id(row),
      userId(row),
      timestamp(row),
      read(row),
      actionUser(row),
      verb(row),
      itemId(row),
      collectionId(row)
    )
}

//use abstract
abstract class NotificationTable extends NotificationTable with Connector {

  def insertItem(item: Notification): Future[ResultSet] =
    insert
      .value(_.id, item.id)
      .value(_.userId, item.userId)
      .value(_.timestamp, item.timestamp)
      .value(_.read, item.read)
      .value(_.actionUser, item.actionUser) 
      .value(_.verb, item.verb)
      .value(_.itemId, item.itemId)
      .value(_.collectionId, item.collectionId)
      .future()
}
于 2016-05-18T11:41:42.730 回答
2

您错过了一个事实,即您应该使用RootConnector而不是那里的随机Connector特征。该类之所以是抽象的,是因为它只能在Database对象内部实例化。

查看本教程以获取更多详细信息,但简而言之,请注意RootConnector此处的 mixin:

abstract class ConcreteNotificationTable extends
  NotificationTable with RootConnector

接着:

class MyDatabase(val connector: KeySpaceDef) extends Database(connector) {
  // And here you inject the real session and keyspace in the table
  object notifications extends ConcreteNotificationsTable with connector.Connector
}

然后你做这样的事情:

object MyDatabase extends MyDatabase(ContactPoint.local.keySpace("my_app"))

从其他所有源文件中:

val notification = Notification(id, //etc...)
MyDatabase.notifications.insertItem(someNotification)

甚至更好的关注点分离,如教程中所述:

trait DbProvider extends DatabaseProvider {
  def database: MyDatabase
}
trait ProductionDbProvider extends DbProvider {
  // this would now point to your object
  override val database = MyDatabase
}

然后每个需要数据库的地方都需要混合DbProvider或直接混合ProductionDbProvider。阅读教程以获取更多详细信息,这不是一个超级琐碎的话题,所有细节都已经存在。

于 2016-05-18T13:45:26.037 回答