Skip to content

Commit

Permalink
WIP: Migration RowParserImpl
Browse files Browse the repository at this point in the history
  • Loading branch information
cchantep committed Aug 18, 2022
1 parent 69a0b1e commit 22d381a
Show file tree
Hide file tree
Showing 19 changed files with 607 additions and 333 deletions.
5 changes: 3 additions & 2 deletions akka/src/test/scala/anorm/AkkaStreamSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ final class AkkaStreamSpec(implicit ee: ExecutionEnv) extends org.specs2.mutable

"on success" in assertAllStagesStopped {
withQueryResult(stringList :+ "A" :+ "B" :+ "C") { implicit con =>
runAsync(Sink.seq[String]) must beLike[ResultSet] { case rs =>
(rs.isClosed must beTrue).and(rs.getStatement.isClosed must beTrue).and(con.isClosed must beFalse)
runAsync(Sink.seq[String]) must beLike[ResultSet] {
case rs =>
(rs.isClosed must beTrue).and(rs.getStatement.isClosed must beTrue).and(con.isClosed must beFalse)
}.await(0, 5.seconds)
}
}
Expand Down
29 changes: 19 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ import com.typesafe.tools.mima.plugin.MimaKeys.{ mimaBinaryIssueFilters, mimaPre
// Scalafix
inThisBuild(
List(
//scalaVersion := "2.13.3",
// scalaVersion := "2.13.3",
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
scalafixDependencies ++= Seq(
"com.github.liancheng" %% "organize-imports" % "0.5.0")
scalafixDependencies ++= Seq("com.github.liancheng" %% "organize-imports" % "0.5.0")
)
)

val specs2Test = Seq(
"specs2-core",
"specs2-junit",
"specs2-matcher-extra"
).map("org.specs2" %% _ % "4.10.6" % Test cross(CrossVersion.for3Use2_13))
).map("org.specs2" %% _ % "4.10.6" % Test cross (CrossVersion.for3Use2_13))

lazy val acolyteVersion = "1.2.1"
lazy val acolyte = "org.eu.acolyte" %% "jdbc-scala" % acolyteVersion % Test
Expand Down Expand Up @@ -50,9 +49,8 @@ lazy val `anorm-tokenizer` = project
// ---

val armShading = Seq(
libraryDependencies += ("com.jsuereth" %% "scala-arm" % "2.1-SNAPSHOT").
cross(CrossVersion.for3Use2_13),
assembly / test := {},
libraryDependencies += ("com.jsuereth" %% "scala-arm" % "2.1-SNAPSHOT").cross(CrossVersion.for3Use2_13),
assembly / test := {},
assembly / assemblyOption ~= {
_.withIncludeScala(false) // java libraries shouldn't include scala
},
Expand Down Expand Up @@ -109,6 +107,14 @@ lazy val coreMimaFilter: ProblemFilter = {
case _ => true
}

lazy val xmlVer = Def.setting[String] {
if (scalaBinaryVersion.value == "2.11") {
"1.3.0"
} else {
"2.1.0"
}
}

lazy val `anorm-core` = project
.in(file("core"))
.settings(
Expand All @@ -120,7 +126,9 @@ lazy val `anorm-core` = project
scalacOptions ++= {
if (scalaBinaryVersion.value == "3") {
Seq.empty
Seq("-Wconf:cat=deprecation&msg=.*(reflectiveSelectableFromLangReflectiveCalls|DeprecatedSqlParser|missing .*ToSql).*:s")
Seq(
"-Wconf:cat=deprecation&msg=.*(reflectiveSelectableFromLangReflectiveCalls|DeprecatedSqlParser|missing .*ToSql).*:s"
)
} else {
Seq(
"-Xlog-free-terms",
Expand Down Expand Up @@ -169,6 +177,7 @@ lazy val `anorm-core` = project
ProblemFilters.exclude[DirectMissingMethodProblem]( // deprecated 2.3.8
"anorm.SqlQuery.statement"
),
incoRet("anorm.ParameterValue.apply"),
// private:
ProblemFilters.exclude[DirectMissingMethodProblem]( // private
"anorm.Sql.asTry"
Expand All @@ -183,8 +192,8 @@ lazy val `anorm-core` = project
"joda-time" % "joda-time" % "2.11.0",
"org.joda" % "joda-convert" % "2.2.2",
"org.scala-lang.modules" %% "scala-parser-combinators" % parserCombinatorsVer.value,
"org.scala-lang.modules" %% "scala-xml" % "2.1.0" % Test,
"com.h2database" % "h2" % "2.1.214" % Test,
"org.scala-lang.modules" %% "scala-xml" % xmlVer.value % Test,
"com.h2database" % "h2" % "2.1.214" % Test,
acolyte
) ++ specs2Test.map(_.exclude("org.scala-lang.modules", "*")),
) ++ armShading
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/scala-2/anorm/Macro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ object Macro extends MacroOptions {
def psz = params.size

if (names.size < psz) {
c.abort(c.enclosingPosition, s"no column name for parameters: ${show(names)} < $params")
c.abort(
c.enclosingPosition,
s"no column name for parameters: ${names.map(n => show(n)).mkString(", ")} < ${params.map(_.name).mkString(", ")}"
)

} else {
parserImpl[T](c) { (t, _, i) =>
Expand Down
6 changes: 1 addition & 5 deletions core/src/main/scala-2/anorm/macros/SealedRowParserImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,8 @@ private[anorm] object SealedRowParserImpl {
val caseName = TermName(c.freshName("discriminated"))
val key = q"$discriminate(${subclass.typeSymbol.fullName})"
val caseDecl = q"val $caseName = $key"
val subtype = { // TODO: typeParams is not supported anyway
if (subclass.typeSymbol.asClass.typeParams.isEmpty) subclass
else subclass.erasure
}

(key, caseDecl, cq"`$caseName` => implicitly[anorm.RowParser[$subtype]]")
(key, caseDecl, cq"`$caseName` => implicitly[anorm.RowParser[$subclass]]")
}

lazy val supported = q"List(..${cases.map(_._1)})"
Expand Down
5 changes: 2 additions & 3 deletions core/src/main/scala-2/anorm/macros/ToParameterListImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ private[anorm] object ToParameterListImpl {

c.inferImplicitValue(ptype) match {
case EmptyTree =>
c.abort(
c.enclosingPosition, s"Missing ToParameterList[${subcls}]")
c.abort(c.enclosingPosition, s"Missing ToParameterList[${subcls}]")

case toParams =>
case toParams =>
cq"v: ${subcls} => $toParams(v)"
}
}
Expand Down
66 changes: 46 additions & 20 deletions core/src/main/scala-3/anorm/Macro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -265,21 +265,28 @@ object Macro extends MacroOptions with macros.ValueColumn with macros.ValueToSta

// ---

private def namedParserImpl[T](using Quotes, Type[T]): Expr[RowParser[T]] =
withColumn[T] { col =>
parserImpl[T] { (n, _) =>
'{ anorm.SqlParser.get[T](${ Expr(n) })($col) }
private def namedParserImpl[T](using q: Quotes, tpe: Type[T]): Expr[RowParser[T]] =
parserImpl[T](q) { (tpr, n, _) =>
tpr.asType match {
case '[t] =>
withColumn[t] { col =>
'{ SqlParser.get[t](${ Expr(n) })($col) }
}
}
}

private def namedParserImpl1[T](
naming: Expr[ColumnNaming]
)(using Quotes, Type[T], Type[ColumnNaming]): Expr[RowParser[T]] =
withColumn[T] { col =>
parserImpl[T] { (n, _) =>
'{ anorm.SqlParser.get[T]($naming(${ Expr(n) }))($col) }
)(using q: Quotes, tpe: Type[T], colNme: Type[ColumnNaming]): Expr[RowParser[T]] = {
parserImpl[T](q) { (tpr, n, _) =>
tpr.asType match {
case '[t] =>
withColumn[t] { col =>
'{ SqlParser.get[t]($naming(${ Expr(n) }))($col) }
}
}
}
}

private def namedParserImpl2[T](
naming: Expr[ColumnNaming],
Expand Down Expand Up @@ -316,13 +323,16 @@ object Macro extends MacroOptions with macros.ValueColumn with macros.ValueToSta
report.errorAndAbort(s"no column name for parameters: ${ns.mkString(", ")} < $params")

} else {
parserImpl[T] { (_, i) =>
parserImpl[T](q) { (tpr, _, i) =>
ns.lift(i) match {
case Some(n) =>
withColumn[T] { col =>
val cn = naming(Expr(n))
tpr.asType match {
case '[t] =>
withColumn[t] { col =>
val cn = naming(Expr(n))

'{ SqlParser.get[T]($cn)($col) }
'{ SqlParser.get[t]($cn)($col) }
}
}

case _ =>
Expand All @@ -332,10 +342,13 @@ object Macro extends MacroOptions with macros.ValueColumn with macros.ValueToSta
}
}

private def offsetParserImpl[T](offset: Expr[Int])(using Quotes, Type[T]): Expr[RowParser[T]] =
withColumn[T] { col =>
parserImpl[T] { (_, i) =>
'{ anorm.SqlParser.get[T]($offset + ${ Expr(i + 1) })($col) }
private def offsetParserImpl[T](offset: Expr[Int])(using q: Quotes, tpe: Type[T]): Expr[RowParser[T]] =
parserImpl[T](q) { (tpr, _, i) =>
tpr.asType match {
case '[t] =>
withColumn[t] { col =>
'{ SqlParser.get[t]($offset + ${ Expr(i + 1) })($col) }
}
}
}

Expand All @@ -361,9 +374,22 @@ object Macro extends MacroOptions with macros.ValueColumn with macros.ValueToSta
): Expr[RowParser[T]] =
macros.SealedRowParserImpl[T](naming, discriminate)

private def parserImpl[T](genGet: (String, Int) => Expr[RowParser[T]])(using Quotes, Type[T]): Expr[RowParser[T]] = {
// TODO: anorm.macros.RowParserImpl[T](c)(genGet)
'{ ??? }
inline private def withParser[T](f: RowParser[T] => (Row => SqlResult[T])): RowParser[T] = new RowParser[T] { self =>
lazy val underlying = f(self)

def apply(row: Row): SqlResult[T] = underlying(row)
}

private def parserImpl[T](
q: Quotes
)(genGet: (q.reflect.TypeRepr, String, Int) => Expr[RowParser[_]])(using Type[T]): Expr[RowParser[T]] = {
given quotes: Quotes = q

'{
withParser { self =>
${ macros.RowParserImpl[T](q, 'self)(genGet) }
}
}
}

// ---
Expand Down Expand Up @@ -516,7 +542,7 @@ object Macro extends MacroOptions with macros.ValueColumn with macros.ValueToSta
}
}

inline private[anorm] def withSelfToParameterList[T](
inline private def withSelfToParameterList[T](
f: ToParameterList[T] => (T => List[NamedParameter])
): ToParameterList[T] = new ToParameterList[T] { self =>
lazy val underlying = f(self)
Expand Down
Loading

0 comments on commit 22d381a

Please sign in to comment.