如何定义受多个隐式转换影响的类型?
How to define a type that is subject to several implicit conversions?
我正在使用 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
的类型。
table
的类型为:slick.lifted.TableQuery[_ <: AbstractTable]
,并且仅当我使用此类型时才会找到行 ++=
,但无论如何都不会发生 seq 的隐式转换。
table.schema
具有类型:slick.profile.RelationalProfile#TableQueryExtensionMethods
,如果我按照第 1 点声明 table
,则找不到此 属性。
table.schema.create
具有类型:slick.driver.JdbcActionComponent$SchemaActionExtensionMethodsImpl
,如果我按照第 2 点声明 table
,则找不到此 属性。
在原始代码中,table 被实例化为 TableQuery
,slick 使用一些隐式转换来添加其他属性。它还必须将 data
seq 转换为 E#TableElementType
.
的 Iterable
那么我如何才能通用地键入 table
以便编译此特征并且可以找到所有这些隐式添加的成员?
我认为这会很简单,但似乎除非我用具体的 class 实例化 TableQuery
,否则整个事情就会分崩离析。事实上,在我不同的 fixture 文件中,我确实用具体的 table 实例化了 TableQuery,所以我只需要让编译器知道它可以使用哪些属性和方法。
您可以传递 table 标签并将其用于创建 TableQuery ,如果您的 table class 外观定义为:
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)
我正在使用 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
的类型。
table
的类型为:slick.lifted.TableQuery[_ <: AbstractTable]
,并且仅当我使用此类型时才会找到行++=
,但无论如何都不会发生 seq 的隐式转换。table.schema
具有类型:slick.profile.RelationalProfile#TableQueryExtensionMethods
,如果我按照第 1 点声明table
,则找不到此 属性。table.schema.create
具有类型:slick.driver.JdbcActionComponent$SchemaActionExtensionMethodsImpl
,如果我按照第 2 点声明table
,则找不到此 属性。
在原始代码中,table 被实例化为 TableQuery
,slick 使用一些隐式转换来添加其他属性。它还必须将 data
seq 转换为 E#TableElementType
.
那么我如何才能通用地键入 table
以便编译此特征并且可以找到所有这些隐式添加的成员?
我认为这会很简单,但似乎除非我用具体的 class 实例化 TableQuery
,否则整个事情就会分崩离析。事实上,在我不同的 fixture 文件中,我确实用具体的 table 实例化了 TableQuery,所以我只需要让编译器知道它可以使用哪些属性和方法。
您可以传递 table 标签并将其用于创建 TableQuery ,如果您的 table class 外观定义为:
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)