diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 1808d1d4..bd19ce62 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -23,50 +23,29 @@ jobs: name: Binary Compatibility uses: playframework/.github/.github/workflows/binary-check.yml@v4 - check-docs-8: - name: Docs Java 8 - uses: playframework/.github/.github/workflows/cmd.yml@v4 - with: - java: 8 - scala: 2.12.x - cmd: sbt ++$MATRIX_SCALA docs/test - - check-docs-11: + check-docs: name: Docs uses: playframework/.github/.github/workflows/cmd.yml@v4 with: - java: 11 - scala: 2.12.x, 2.13.x, 3.x + java: 17 + scala: 2.13.x, 3.x cmd: sbt ++$MATRIX_SCALA docs/test - tests-8: - name: Tests - needs: - - "check-code-style" - - "check-binary-compatibility" - - "check-docs-8" - uses: playframework/.github/.github/workflows/cmd.yml@v4 - with: - java: 8 - scala: 2.12.x - cmd: sbt ++$MATRIX_SCALA publishLocal test - - tests-11: + tests: name: Tests needs: - "check-code-style" - "check-binary-compatibility" - - "check-docs-11" + - "check-docs" uses: playframework/.github/.github/workflows/cmd.yml@v4 with: - java: 11 - scala: 2.12.x, 2.13.x, 3.x + java: 17 + scala: 2.13.x, 3.x cmd: sbt ++$MATRIX_SCALA publishLocal test finish: name: Finish if: github.event_name == 'pull_request' needs: # Should be last - - "tests-8" - - "tests-11" + - "tests" uses: playframework/.github/.github/workflows/rtm.yml@v4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index aaea5fc7..2b76f885 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,4 +12,4 @@ jobs: uses: playframework/.github/.github/workflows/publish.yml@v4 secrets: inherit with: - java: 8 + java: 17 diff --git a/akka/src/test/scala-2.13-/AkkaCompat.scala b/akka/src/test/scala-2.13-/AkkaCompat.scala deleted file mode 100644 index 50be3371..00000000 --- a/akka/src/test/scala-2.13-/AkkaCompat.scala +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -package anorm - -private[anorm] object AkkaCompat { - type Seq[T] = _root_.scala.collection.Seq[T] -} diff --git a/akka/src/test/scala-2.13+/AkkaCompat.scala b/akka/src/test/scala/anorm/AkkaCompat.scala similarity index 100% rename from akka/src/test/scala-2.13+/AkkaCompat.scala rename to akka/src/test/scala/anorm/AkkaCompat.scala diff --git a/build.sbt b/build.sbt index 421b000d..c5dfcdea 100644 --- a/build.sbt +++ b/build.sbt @@ -204,20 +204,12 @@ lazy val `anorm-core` = project ProblemFilters.exclude[IncompatibleResultTypeProblem]("anorm.ColumnNotFound.copy$default$2") ), libraryDependencies ++= { - val h2Ver = sys.props.get("java.version") match { - case Some(v) if v.startsWith("1.8") => - "2.2.224" - - case _ => - "2.3.230" - } - Seq( "joda-time" % "joda-time" % "2.14.2", "org.joda" % "joda-convert" % "3.0.1", "org.scala-lang.modules" %% "scala-parser-combinators" % parserCombinatorsVer.value, - "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, - "com.h2database" % "h2" % h2Ver % Test, + "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, + "com.h2database" % "h2" % "2.3.230" % Test, acolyte ) ++ specs2Test }, @@ -225,42 +217,6 @@ lazy val `anorm-core` = project ) .dependsOn(`anorm-tokenizer`) -lazy val `anorm-iteratee` = project - .in(file("iteratee")) - .settings( - Seq( - sourceDirectory := { - val v = scalaBinaryVersion.value - - if (v == "3" || v == "2.13") new java.io.File("/no/sources") - else sourceDirectory.value - }, - mimaPreviousArtifacts := { - val v = scalaBinaryVersion.value - - if (v == "3" || v == "2.13") Set.empty[ModuleID] - else Set(organization.value %% name.value % "2.6.10") - }, - publish / skip := { - val v = scalaBinaryVersion.value - - v == "3" || v == "2.13" - }, - libraryDependencies ++= { - val v = scalaBinaryVersion.value - - if (v == "3" || v == "2.13") Seq.empty[ModuleID] - else - Seq( - "com.typesafe.play" %% "play-iteratees" % "2.6.1", - "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, - acolyte - ) ++ specs2Test - } - ) ++ licensing - ) - .dependsOn(`anorm-core`) - // --- lazy val akkaVer = Def.setting[String] { @@ -291,80 +247,27 @@ lazy val `anorm-akka` = project "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, ("com.typesafe.akka" %% "akka-stream-testkit" % akkaVer.value % Test).exclude("org.scala-lang.modules", "*") ) ++ specs2Test, - scalacOptions ++= Seq("-Wconf:msg=.*(onDownstreamFinish|ActorMaterializer).*:s"), - Test / unmanagedSourceDirectories += { - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n < 13 => - (Test / sourceDirectory).value / "scala-2.13-" - - case _ => - (Test / sourceDirectory).value / "scala-2.13+" - - } - } + scalacOptions ++= Seq("-Wconf:msg=.*(onDownstreamFinish|ActorMaterializer).*:s") ) ++ licensing ) .dependsOn(`anorm-core`) lazy val pekkoVer = Def.setting[String]("1.6.0") -lazy val pekkoEnabled = Def.setting[Boolean] { - val v = scalaBinaryVersion.value - - v != "2.12" -} - lazy val `anorm-pekko` = project .in(file("pekko")) .settings( Seq( mimaPreviousArtifacts := Set.empty, - sourceDirectory := { - if (!pekkoEnabled.value) new java.io.File("/no/sources") - else sourceDirectory.value - }, - publishArtifact := pekkoEnabled.value, - publish := Def.taskDyn { - val ver = scalaBinaryVersion.value - val go = publish.value - - Def.task { - if (pekkoEnabled.value) { - go - } - } - }.value, - libraryDependencies ++= { - if (pekkoEnabled.value) { - Seq("pekko-testkit", "pekko-stream").map { m => - ("org.apache.pekko" %% m % pekkoVer.value % Provided).exclude("org.scala-lang.modules", "*") - } - } else { - Seq.empty - } - }, - libraryDependencies ++= { - if (pekkoEnabled.value) { - Seq( - acolyte, - "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, - "org.apache.pekko" %% "pekko-stream-testkit" % pekkoVer.value % Test - ) ++ specs2Test - } else { - Seq.empty - } + libraryDependencies ++= Seq("pekko-testkit", "pekko-stream").map { m => + ("org.apache.pekko" %% m % pekkoVer.value % Provided).exclude("org.scala-lang.modules", "*") }, - scalacOptions ++= Seq("-Wconf:cat=deprecation&msg=.*(onDownstreamFinish|ActorMaterializer).*:s"), - Test / unmanagedSourceDirectories ++= { - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n < 13 => - Seq((Test / sourceDirectory).value / "scala-2.13-") - - case _ => - Seq((Test / sourceDirectory).value / "scala-2.13+") - - } - } + libraryDependencies ++= Seq( + acolyte, + "org.scala-lang.modules" %% "scala-xml" % xmlVer % Test, + "org.apache.pekko" %% "pekko-stream-testkit" % pekkoVer.value % Test + ) ++ specs2Test, + scalacOptions ++= Seq("-Wconf:cat=deprecation&msg=.*(onDownstreamFinish|ActorMaterializer).*:s") ) ++ licensing ) .dependsOn(`anorm-core`) @@ -422,7 +325,6 @@ lazy val `anorm-parent` = project .aggregate( `anorm-tokenizer`, `anorm-core`, - `anorm-iteratee`, `anorm-akka`, `anorm-pekko`, `anorm-postgres`, @@ -452,19 +354,10 @@ lazy val docs = project (manualDir / "javaGuide" ** "code").get ++ (manualDir / "scalaGuide" ** "code").get }, - libraryDependencies ++= { - if (scalaBinaryVersion.value == "2.12") { - Seq( - "com.typesafe.play" %% "play-jdbc" % "2.8.22" % Test, - "com.typesafe.play" %% "play-specs2" % "2.8.22" % Test - ) - } else { - Seq( - "org.playframework" %% "play-jdbc" % "3.0.10" % Test, - "org.playframework" %% "play-specs2" % "3.0.10" % Test - ) - } - }, + libraryDependencies ++= Seq( + "org.playframework" %% "play-jdbc" % "3.0.10" % Test, + "org.playframework" %% "play-specs2" % "3.0.10" % Test + ), libraryDependencies ++= Seq( "com.h2database" % "h2" % "1.4.199" ), diff --git a/core/src/main/scala-2.13-/Compat.scala b/core/src/main/scala-2.13-/Compat.scala deleted file mode 100644 index cf1accfa..00000000 --- a/core/src/main/scala-2.13-/Compat.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -package anorm - -import java.util.{ Enumeration => JEnum } - -import scala.collection.breakOut -import scala.collection.immutable.Map - -private[anorm] object Compat { - @inline def toMap[T, K, V](in: Traversable[T])(f: T => (K, V)): Map[K, V] = - in.map(f)(breakOut) - - @inline def toFlatMap[T, K, V](in: Traversable[T])(f: T => Map[K, V]): Map[K, V] = in.flatMap(f)(breakOut) - - @inline def lazyZip[A, B](a: Iterable[A], b: Iterable[B]) = (a -> b).zipped - - @inline def collectToMap[T, K, V](in: Traversable[T])(f: PartialFunction[T, (K, V)]): Map[K, V] = - in.collect(f)(breakOut) - - @inline def rightMap[L, R1, R2](e: Either[L, R1])(f: R1 => R2): Either[L, R2] = e.right.map(f) - - @inline def rightFlatMap[L1, L2 >: L1, R1, R2](e: Either[L1, R1])(f: R1 => Either[L2, R2]): Either[L2, R2] = - e.right.flatMap(f) - - @inline def javaEnumIterator[T](e: JEnum[T]): Iterator[T] = { - import scala.collection.JavaConverters.enumerationAsScalaIteratorConverter - e.asScala - } - - @inline def mapValues[K, V1, V2](m: Map[K, V1])(f: V1 => V2) = m.mapValues(f) - - /** Scala 2.13 compatibility type alias */ - type Trav[T] = Traversable[T] - - /** Scala 2.13 compatibility type alias */ - type LazyLst[T] = Stream[T] - - @inline def LazyLst[T](values: T*): LazyLst[T] = Stream.empty[T] ++ values -} diff --git a/core/src/main/scala-2.13+/Compat.scala b/core/src/main/scala/anorm/Compat.scala similarity index 100% rename from core/src/main/scala-2.13+/Compat.scala rename to core/src/main/scala/anorm/Compat.scala diff --git a/docs/manual/working/scalaGuide/main/sql/ScalaAnorm.md b/docs/manual/working/scalaGuide/main/sql/ScalaAnorm.md index 17e898a4..a0751899 100644 --- a/docs/manual/working/scalaGuide/main/sql/ScalaAnorm.md +++ b/docs/manual/working/scalaGuide/main/sql/ScalaAnorm.md @@ -1016,32 +1016,6 @@ def source(implicit m: Materializer, connection: Connection): Source[String, Fut }) ``` -#### Iteratee - -It's possible to use Anorm along with [Play Iteratees](https://www.playframework.com/documentation/latest/Iteratees), using the following dependencies. - -```scala -libraryDependencies ++= Seq( - "org.playframework.anorm" %% "anorm-iteratee" % "ANORM_VERSION", - "com.typesafe.play" %% "play-iteratees" % "ITERATEES_VERSION") -``` - -> For a Play application, as `play-iteratees` is provided there is no need to add this dependency. - -> Since Scala 2.13, `play-iteratees` is no longer available. - -Then the parsed results from Anorm can be turned into [`Enumerator`](https://www.playframework.com/documentation/latest/api/scala/index.html#play.api.libs.iteratee.Enumerator). - -```scala -import java.sql.Connection -import scala.concurrent.ExecutionContext.Implicits.global -import anorm._ -import play.api.libs.iteratee._ - -def resultAsEnumerator(implicit con: Connection): Enumerator[String] = - Iteratees.from(SQL"SELECT * FROM Test", SqlParser.scalar[String]) -``` - ### Retrieving data along with execution context Moreover data, query execution involves context information like SQL warnings that may be raised (and may be fatal or not), especially when working with stored SQL procedure. diff --git a/iteratee/src/main/scala/anorm/Iteratees.scala b/iteratee/src/main/scala/anorm/Iteratees.scala deleted file mode 100644 index fc692be9..00000000 --- a/iteratee/src/main/scala/anorm/Iteratees.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -package anorm - -import java.sql.Connection - -import scala.concurrent.{ ExecutionContext, Future } - -import play.api.libs.iteratee.Enumerator - -/** Anorm companion for the [[https://www.playframework.com/documentation/2.4.x/Iteratees]]. */ -object Iteratees { - import scala.util.{ Failure, Success } - import play.api.libs.iteratee.Concurrent - - /** - * Returns the rows parsed from the `sql` query as an enumerator. - * - * @tparam T the type of the result elements - * @param sql the SQL query - * @param parser the result (row) parser - * @param ec the execution context - * @param connection the JDBC connection, which must not be closed until the returned enumerator is [[https://www.playframework.com/documentation/2.4.0/api/scala/index.html#play.api.libs.iteratee.Enumerator@onDoneEnumerating%28callback:=%3EUnit%29%28implicitec:scala.concurrent.ExecutionContext%29:play.api.libs.iteratee.Enumerator[E] done]]. - * - * {{{ - * import java.sql.Connection - * import scala.concurrent.ExecutionContext.Implicits.global - * import anorm._ - * import play.api.libs.iteratee._ - * - * def resultAsEnumerator(implicit con: Connection): Enumerator[String] = - * Iteratees.from(SQL"SELECT * FROM Test", SqlParser.scalar[String]) - * }}} - */ - def from[T](sql: => Sql, parser: RowParser[T])(implicit ec: ExecutionContext, con: Connection): Enumerator[T] = { - val (resultEnum, chan): (Enumerator[T], Concurrent.Channel[T]) = - Concurrent.broadcast[T] - - @annotation.tailrec - def pushToChannel(cursor: Option[Cursor]): Unit = cursor match { - case Some(cursor) => - cursor.row.as(parser) match { - case Success(elem) => { - chan.push(elem) - pushToChannel(cursor.next) - } - case Failure(err) => chan.end(err) - } - case _ => chan.eofAndEnd() - } - - Future(sql.withResult(pushToChannel)) // async consumption - - resultEnum - } - - /** - * Returns the result rows from the `sql` query as an enumerator. - * - * @param sql the SQL query - * @param ec the execution context - * @param connection the JDBC connection, which must not be closed until the returned enumerator is [[https://www.playframework.com/documentation/2.4.0/api/scala/index.html#play.api.libs.iteratee.Enumerator@onDoneEnumerating%28callback:=%3EUnit%29%28implicitec:scala.concurrent.ExecutionContext%29:play.api.libs.iteratee.Enumerator[E] done]]. - */ - def from(sql: => Sql)(implicit ec: ExecutionContext, connnection: Connection): Enumerator[Row] = - from(sql, RowParser.successful) - -} diff --git a/iteratee/src/test/scala/anorm/IterateeSpec.scala b/iteratee/src/test/scala/anorm/IterateeSpec.scala deleted file mode 100644 index 2eca0df5..00000000 --- a/iteratee/src/test/scala/anorm/IterateeSpec.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -import scala.concurrent.duration._ - -import play.api.libs.iteratee.Iteratee - -import acolyte.jdbc.AcolyteDSL.withQueryResult -import acolyte.jdbc.Implicits._ -import acolyte.jdbc.RowLists.stringList - -import org.specs2.concurrent.ExecutionEnv - -import anorm._ - -class IterateeSpec(implicit ee: ExecutionEnv) extends org.specs2.mutable.Specification { - - "Play Iteratee".title - - "Iteratees" should { - "broadcast the streaming result" in { - withQueryResult(stringList :+ "A" :+ "B" :+ "C") { implicit con => - Iteratees - .from(SQL"SELECT * FROM Test", SqlParser.scalar[String]) - .run(Iteratee.getChunks[String]) must beEqualTo(List("A", "B", "C")).await(0, 5.second) - } - } - } -} diff --git a/pekko/src/test/scala-2.13-/PekkoCompat.scala b/pekko/src/test/scala-2.13-/PekkoCompat.scala deleted file mode 100644 index 59c192cf..00000000 --- a/pekko/src/test/scala-2.13-/PekkoCompat.scala +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -package anorm - -private[anorm] object PekkoCompat { - type Seq[T] = _root_.scala.collection.Seq[T] -} diff --git a/pekko/src/test/scala-2.13+/PekkoCompat.scala b/pekko/src/test/scala/anorm/PekkoCompat.scala similarity index 100% rename from pekko/src/test/scala-2.13+/PekkoCompat.scala rename to pekko/src/test/scala/anorm/PekkoCompat.scala diff --git a/project/Common.scala b/project/Common.scala index 048f7a5f..9caf177a 100644 --- a/project/Common.scala +++ b/project/Common.scala @@ -17,24 +17,16 @@ object Common extends AutoPlugin { override def projectSettings = Seq( organization := "org.playframework.anorm", - scalaVersion := "2.12.21", - crossScalaVersions := Seq(scalaVersion.value, "2.13.18", "3.3.7"), - Compile / unmanagedSourceDirectories ++= { - val sv = scalaVersion.value - - scalaUnmanaged(sv, (Compile / sourceDirectory).value) - }, - Test / unmanagedSourceDirectories ++= scalaUnmanaged(scalaVersion.value, (Test / sourceDirectory).value), + scalaVersion := "2.13.18", + crossScalaVersions := Seq(scalaVersion.value, "3.3.7"), scalacOptions ++= Seq("-Xfatal-warnings"), scalacOptions ++= { val v = scalaBinaryVersion.value if (v == "2.13") { - Seq("-release", "8") :+ "-Xlint" - } else if (v == "3") { - Seq("-release", "8") + Seq("-release", "17") :+ "-Xlint" } else { - Seq("-target:jvm-1.8", "-g:vars") :+ "-Xlint" + Seq("-release", "17") } }, scalacOptions ++= { @@ -49,20 +41,7 @@ object Common extends AutoPlugin { "-Wconf:msg=.*vararg\\ splices.*:s", "-Wconf:cat=deprecation&msg=.*(reflectiveSelectableFromLangReflectiveCalls|DeprecatedSqlParser|missing .*ToSql|deprecatedName).*:s" ) - } else if (v == "2.12") { - Seq( - "-Xmax-classfile-name", - "128", - "-Ywarn-numeric-widen", - "-Ywarn-dead-code", - "-Ywarn-value-discard", - "-Ywarn-infer-any", - "-Ywarn-unused", - "-Ywarn-unused-import", - "-Ywarn-macros:after" - ) } else { - // 2.13 Seq( "-explaintypes", "-Werror", @@ -102,18 +81,6 @@ object Common extends AutoPlugin { @inline def incoRet(n: String) = ProblemFilters.exclude[IncompatibleResultTypeProblem](n) - def scalaUnmanaged(ver: String, base: File): Seq[File] = - CrossVersion.partialVersion(ver) match { - case Some((2, 12)) => - Seq(base / "scala-2.13-") - - case Some((3, _) | (2, 13)) => - Seq(base / "scala-2.13+") - - case _ => - sys.error(s"Unexpected version: $ver") - } - } object AnormGeneration {