如何定义受多个隐式转换影响的类型?

时间:2015-03-29 12:01:32

标签: scala slick

我正在使用slick 3.0。我只是想将一些数据库设置代码集中到一个特征中。

以下是我所拥有的:

import slick.driver.H2Driver.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration

object EventFixtures {

  val table = TableQuery[EventsTable]
  val data = Seq(...)

  def insertFixtures(db: Database): Int = {

    Await.result(db.run(table.schema.create), Duration.Inf)  
    Await.result(db.run(table ++= data), Duration.Inf).get
  }
}

我已经举起并将其转移到一个特性:

import slick.driver.H2Driver.api._

import scala.concurrent.Await
import scala.concurrent.duration.Duration


trait FixtureHelper {

  val data: Seq
  val table: ???

  def insertFixtures(db: Database) = {

    Await.result(db.run(table.schema.create), Duration.Inf)
    Await.result(db.run(table ++= data), Duration.Inf).get
  }
}

我希望像以下一样使用它:

object EventFixtures extends FixtureHelper {
  val data = Seq(...)
  val table = TableQuery[EventsTable]
}

// in test code:
EventFixtures.insertFixtures()

问题是table的类型。

  1. table的类型为slick.lifted.TableQuery[_ <: AbstractTable],只有在我使用此类型时才会找到行++=,但无论如何都不会发生seq的隐式转换。< / LI>
  2. table.schema的类型为slick.profile.RelationalProfile#TableQueryExtensionMethods,如果我在第1点声明table,则找不到此属性。
  3. table.schema.create的类型为slick.driver.JdbcActionComponent$SchemaActionExtensionMethodsImpl,如果我在第2点声明table,则找不到此属性。
  4. 在原始代码中,table被实例化为TableQuery,slick使用一些隐式转换来添加其他属性。它还必须将data seq转换为E#TableElementType的Iterable。

    那么我怎么能一般地输入table以便这个特性可以编译并且可以找到所有这些隐式添加的成员呢?

    我认为这很简单,但似乎除非我用一个具体的类来实例化TableQuery,否则整个事情就会崩溃。实际上,在我的不同fixture文件中,我用一个具体的表来实例化TableQuery,所以我需要的是让编译器知道它可用的属性和方法。

1 个答案:

答案 0 :(得分:0)

如果您的表类外观定义为:

,您可以传递tableTag并将其用于创建TableQuery。
case class Events(....)

class EventsTable(tag: Tag)
  extends Table[Sample](tag, "sample_table") {
    .....
} 

这是您可以实施的方式:

import slick.driver.H2Driver.api._
import scala.slick.driver.H2Driver.simple.Tag
import scala.concurrent.Await
import scala.concurrent.duration.Duration

trait FixtureHelper {

  val data: Seq

  def insertFixtures[T,A <: Table[T]](tag : Tag => A ,db: Database) = {
  val table : TableQuery[A] = TableQuery(tag) // create the tableQuery from the tag
    Await.result(db.run(table.schema.create), Duration.Inf)
    Await.result(db.run(table ++= data.toIterable), Duration.Inf).get // ++= accepts only Iterable[] values
  }
}

你可以像

一样使用它
object EventFixtures extends FixtureHelper {
  val data = Seq(...)
}

// in test code:
val tag= new EventsTable(_)
EventFixtures.insertFixtures[Events,EventsTable](tag)