Permalink
Browse files

Move simple Fast Path API up to `RelationalProfile`

The old `JdbcFastPath` did not actually require JDBC because it relays
all calls to the specialized ResultConverters that it wraps. It is now
called `SimpleFastPathResultConverter` and it still requires a
`TypeMappingResultConverter` on top of a `ProductResultConverter` to
work but this has always been enforced at runtime (falling back to the
non-FastPath implementation in other cases) and is applicable outside of
`JdbcProfile` as well.
  • Loading branch information...
1 parent d980dbb commit 3e297601d2ce2bf0496356be56f1e553aef65784 @szeiger szeiger committed Oct 2, 2015
@@ -1,7 +1,7 @@
package slick.driver
import slick.ast.TypeUtil.:@
-import slick.relational.CompiledMapping
+import slick.relational.{SimpleFastPathResultConverter, CompiledMapping}
import scala.collection.mutable.Builder
import scala.language.{implicitConversions, higherKinds}
@@ -46,12 +46,9 @@ trait JdbcProfile extends SqlProfile with JdbcActionComponent
}
trait API extends LowPriorityAPI with super.API with ImplicitColumnTypes {
- type FastPath[T] = JdbcFastPath[T]
type SimpleDBIO[+R] = SimpleJdbcAction[R]
val SimpleDBIO = SimpleJdbcAction
- implicit def jdbcFastPathExtensionMethods[T, P](mp: MappedProjection[T, P]) = new JdbcFastPathExtensionMethods[T, P](mp)
-
implicit def queryDeleteActionExtensionMethods[C[_]](q: Query[_ <: RelationalProfile#Table[_], _, C]): DeleteActionExtensionMethods =
createDeleteActionExtensionMethods(deleteCompiler.run(q.toNode).tree, ())
implicit def runnableCompiledDeleteActionExtensionMethods[RU, C[_]](c: RunnableCompiled[_ <: Query[_, _, C], C[RU]]): DeleteActionExtensionMethods =
@@ -69,14 +69,6 @@ trait JdbcMappingCompilerComponent { driver: JdbcDriver =>
(CompiledStatement(ibr.sql, ibr, serverSide.nodeType).infer(), mapping.map(n => mappingCompiler.compileMapping(ib.transformMapping(n))))
}
}
-
- class JdbcFastPathExtensionMethods[T, P](val mp: MappedProjection[T, P]) {
- def fastPath(fpf: (TypeMappingResultConverter[JdbcResultConverterDomain, T, _] => JdbcFastPath[T])): MappedProjection[T, P] = mp.genericFastPath {
- case tm @ TypeMappingResultConverter(_: ProductResultConverter[_, _], _, _) =>
- fpf(tm.asInstanceOf[TypeMappingResultConverter[JdbcResultConverterDomain, T, _]])
-
- }
- }
}
trait JdbcResultConverterDomain extends ResultConverterDomain {
@@ -76,25 +76,3 @@ class IsDefinedResultConverter[@specialized(Byte, Short, Int, Long, Char, Float,
def width = 1
override def getDumpInfo = super.getDumpInfo.copy(mainInfo = s"idx=$idx", attrInfo = ": " + ti)
}
-
-/** A `ResultConverter` that simplifies the implementation of fast path
- * converters for `JdbcProfile`. It always wraps a `TypeMappingResultConverter`
- * on top of a `ProductResultConverter`, allowing direct access to the product
- * elements. */
-abstract class JdbcFastPath[T](protected[this] val rc: TypeMappingResultConverter[JdbcResultConverterDomain, T, _]) extends ResultConverter[JdbcResultConverterDomain, T] {
- private[this] val ch = rc.child.asInstanceOf[ProductResultConverter[JdbcResultConverterDomain, _]].elementConverters
- private[this] var idx = -1
-
- /** Return the next specialized child `ResultConverter` for the specified type. */
- protected[this] def next[C] = {
- idx += 1
- ch(idx).asInstanceOf[ResultConverter[JdbcResultConverterDomain, C]]
- }
-
- def read(pr: Reader) = rc.read(pr)
- def update(value: T, pr: Updater) = rc.update(value, pr)
- def set(value: T, pp: Writer) = rc.set(value, pp)
-
- override def getDumpInfo = super.getDumpInfo.copy(name = "JdbcFastPath", mainInfo = "", children = Vector(("rc", rc)))
- def width = rc.width
-}
@@ -24,6 +24,7 @@ trait RelationalProfile extends BasicProfile with RelationalTableComponent
override protected def computeCapabilities = super.computeCapabilities ++ RelationalProfile.capabilities.all
trait API extends super.API with ImplicitColumnTypes {
+ type FastPath[T] = SimpleFastPathResultConverter[ResultConverterDomain, T]
type Table[T] = driver.Table[T]
type Sequence[T] = driver.Sequence[T]
val Sequence = driver.Sequence
@@ -42,6 +43,8 @@ trait RelationalProfile extends BasicProfile with RelationalTableComponent
implicit def queryInsertActionExtensionMethods[U, C[_]](q: Query[_, U, C]) = createInsertActionExtensionMethods[U](compileInsert(q.toNode))
implicit def schemaActionExtensionMethods(sd: SchemaDescription): SchemaActionExtensionMethods = createSchemaActionExtensionMethods(sd)
+
+ implicit def fastPathExtensionMethods[T, P](mp: MappedProjection[T, P]): FastPathExtensionMethods[ResultConverterDomain, T, P] = new FastPathExtensionMethods[ResultConverterDomain, T, P](mp)
}
val api: API
@@ -72,6 +75,14 @@ trait RelationalProfile extends BasicProfile with RelationalTableComponent
/** Run a query synchronously on the provided session. This is used by DistributedDriver until we
* can make it fully asynchronous. */
def runSynchronousQuery[R](tree: Node, param: Any)(implicit session: Backend#Session): R
+
+ class FastPathExtensionMethods[M <: ResultConverterDomain, T, P](val mp: MappedProjection[T, P]) {
+ def fastPath(fpf: (TypeMappingResultConverter[M, T, _] => SimpleFastPathResultConverter[M, T])): MappedProjection[T, P] = mp.genericFastPath {
+ case tm @ TypeMappingResultConverter(_: ProductResultConverter[_, _], _, _) =>
+ fpf(tm.asInstanceOf[TypeMappingResultConverter[M, T, _]])
+
+ }
+ }
}
object RelationalProfile {
@@ -150,3 +150,25 @@ final case class OptionRebuildingResultConverter[M <: ResultConverterDomain, T](
def width = discriminator.width + data.width
override def getDumpInfo = super.getDumpInfo.copy(children = Vector(("discriminator", discriminator), ("data", data)))
}
+
+/** A `ResultConverter` that simplifies the implementation of fast path
+ * converters. It always wraps a `TypeMappingResultConverter`
+ * on top of a `ProductResultConverter`, allowing direct access to the product
+ * elements. */
+abstract class SimpleFastPathResultConverter[M <: ResultConverterDomain, T](protected[this] val rc: TypeMappingResultConverter[M, T, _]) extends ResultConverter[M, T] {
+ private[this] val ch = rc.child.asInstanceOf[ProductResultConverter[M, _]].elementConverters
+ private[this] var idx = -1
+
+ /** Return the next specialized child `ResultConverter` for the specified type. */
+ protected[this] def next[C] = {
+ idx += 1
+ ch(idx).asInstanceOf[ResultConverter[M, C]]
+ }
+
+ def read(pr: Reader) = rc.read(pr)
+ def update(value: T, pr: Updater) = rc.update(value, pr)
+ def set(value: T, pp: Writer) = rc.set(value, pp)
+
+ override def getDumpInfo = super.getDumpInfo.copy(name = "SimpleFastPathResultConverter", mainInfo = "", children = Vector(("rc", rc)))
+ def width = rc.width
+}

0 comments on commit 3e29760

Please sign in to comment.