diff --git a/build.sbt b/build.sbt index 3b15c2b3..a7e57097 100644 --- a/build.sbt +++ b/build.sbt @@ -221,7 +221,9 @@ lazy val `anorm-core` = project ProblemFilters.exclude[DirectMissingMethodProblem]("anorm.ToStatement.jodaDateTimeToStatement"), ProblemFilters.exclude[DirectMissingMethodProblem]("anorm.ToStatement.jodaLocalDateTimeToStatement"), ProblemFilters.exclude[DirectMissingMethodProblem]("anorm.ToStatement.jodaLocalDateToStatement"), - ProblemFilters.exclude[DirectMissingMethodProblem]("anorm.ToStatement.jodaInstantToStatement") + ProblemFilters.exclude[DirectMissingMethodProblem]("anorm.ToStatement.jodaInstantToStatement"), + ProblemFilters.exclude[MissingClassProblem]("anorm.Compat"), + ProblemFilters.exclude[MissingClassProblem]("anorm.Compat$") ), libraryDependencies ++= { Seq( diff --git a/core/src/main/scala-2/anorm/macros/Inspect.scala b/core/src/main/scala-2/anorm/macros/Inspect.scala index ea90ec0b..9c0858d1 100644 --- a/core/src/main/scala-2/anorm/macros/Inspect.scala +++ b/core/src/main/scala-2/anorm/macros/Inspect.scala @@ -6,8 +6,6 @@ package anorm.macros import scala.reflect.macros.whitebox -import anorm.Compat - private[anorm] object Inspect { def directKnownSubclasses(c: whitebox.Context)(tpe: c.Type): List[c.Type] = { // Workaround for SI-7046: https://issues.scala-lang.org/browse/SI-7046 @@ -16,7 +14,7 @@ private[anorm] object Inspect { val tpeSym = tpe.typeSymbol.asClass @annotation.tailrec - def allSubclasses(path: Compat.Trav[Symbol], subclasses: Set[Type]): Set[Type] = path.headOption match { + def allSubclasses(path: Iterable[Symbol], subclasses: Set[Type]): Set[Type] = path.headOption match { case Some(cls: ClassSymbol) if tpeSym != cls && cls.selfType.baseClasses.contains(tpeSym) => { val newSub: Set[Type] = if (!cls.isCaseClass) { c.warning(c.enclosingPosition, s"cannot handle class ${cls.fullName}: no case accessor") @@ -74,10 +72,12 @@ private[anorm] object Inspect { if (apply.paramLists.isEmpty) { Map.empty } else { - Compat.toMap(Compat.lazyZip(apply.typeParams, tpeArgs)) { - case (sym, ty) => + apply.typeParams + .lazyZip(tpeArgs) + .map { (sym, ty) => sym.fullName -> ty - } + } + .to(Map) } } } diff --git a/core/src/main/scala-2/anorm/macros/ToParameterListImpl.scala b/core/src/main/scala-2/anorm/macros/ToParameterListImpl.scala index b93092bc..bbd75c71 100644 --- a/core/src/main/scala-2/anorm/macros/ToParameterListImpl.scala +++ b/core/src/main/scala-2/anorm/macros/ToParameterListImpl.scala @@ -6,7 +6,7 @@ package anorm.macros import scala.reflect.macros.whitebox -import anorm.{ Compat, ToParameterList, ToSql, ToStatement } +import anorm.{ ToParameterList, ToSql, ToStatement } import anorm.Macro.{ debugEnabled, ParameterProjection } import anorm.macros.Inspect.pretty @@ -210,25 +210,29 @@ private[anorm] object ToParameterListImpl { val bufVal = q"val ${bufName} = ${ImuList}.newBuilder[${NamedParamTpe}]" // def of functions to append named parameters to a local list buffer - val appendDefs = Compat.mapValues(appendParameters)(_._2).values.toSeq + val appendDefs = appendParameters.view.mapValues(_._2).values.toSeq // applies/call of the functions according the projection val effectiveProj: Map[String, String] = { if (compiledProj.nonEmpty) { - Compat.toMap(compiledProj) { - case ParameterProjection(propName, Some(paramName)) => - propName -> paramName + compiledProj.view + .map { + case ParameterProjection(propName, Some(paramName)) => + propName -> paramName - case ParameterProjection(propName, _) => - propName -> propName - } + case ParameterProjection(propName, _) => + propName -> propName + } + .to(Map) } else - Compat.collectToMap(properties) { - case term: TermSymbol => { - val propName = term.name.toString - propName -> propName + properties.view + .collect { + case term: TermSymbol => { + val propName = term.name.toString + propName -> propName + } } - } + .to(Map) } val appendCalls = effectiveProj.flatMap { diff --git a/core/src/main/scala-3/anorm/macros/Inspect.scala b/core/src/main/scala-3/anorm/macros/Inspect.scala index 0295af2b..b61a4746 100644 --- a/core/src/main/scala-3/anorm/macros/Inspect.scala +++ b/core/src/main/scala-3/anorm/macros/Inspect.scala @@ -6,8 +6,6 @@ package anorm.macros import scala.quoted.{ Expr, Quotes, Type } -import anorm.Compat - private[anorm] object Inspect: /** diff --git a/core/src/main/scala-3/anorm/macros/ToParameterListImpl.scala b/core/src/main/scala-3/anorm/macros/ToParameterListImpl.scala index 725e4f07..d1bd9513 100644 --- a/core/src/main/scala-3/anorm/macros/ToParameterListImpl.scala +++ b/core/src/main/scala-3/anorm/macros/ToParameterListImpl.scala @@ -6,7 +6,7 @@ package anorm.macros import scala.quoted.{ Expr, Quotes, Type } -import anorm.{ Compat, Macro, NamedParameter, ToParameterList, ToParameterValue, ToSql, ToStatement } +import anorm.{ Macro, NamedParameter, ToParameterList, ToParameterValue, ToSql, ToStatement } import Macro.{ debugEnabled, ParameterProjection } diff --git a/core/src/main/scala/anorm/BatchSql.scala b/core/src/main/scala/anorm/BatchSql.scala index f8177735..bc55123d 100644 --- a/core/src/main/scala/anorm/BatchSql.scala +++ b/core/src/main/scala/anorm/BatchSql.scala @@ -58,7 +58,7 @@ sealed trait BatchSql { */ @throws[IllegalArgumentException](BatchSqlErrors.MissingParameter) @throws[IllegalArgumentException](BatchSqlErrors.ParameterNamesNotMatchingPlaceholders) - def addBatchParamsList(args: Compat.Trav[Seq[ParameterValue]]): BatchSql = { + def addBatchParamsList(args: Iterable[Seq[ParameterValue]]): BatchSql = { if (params.isEmpty) { BatchSql.Checked(sql, args.map(Sql.zipParams(sql.paramsInitialOrder, _, Map.empty))) @@ -222,7 +222,7 @@ object BatchSql { @throws[IllegalArgumentException](BatchSqlErrors.HeterogeneousParameterMaps) @throws[IllegalArgumentException](BatchSqlErrors.ParameterNamesNotMatchingPlaceholders) @SuppressWarnings(Array("MethodNames")) - private[anorm] def Checked[M](query: SqlQuery, ps: Compat.Trav[Map[String, ParameterValue]]): BatchSql = + private[anorm] def Checked[M](query: SqlQuery, ps: Iterable[Map[String, ParameterValue]]): BatchSql = ps.headOption.fold(Copy(query, Set.empty, Nil)) { m => val ks = m.keySet @@ -249,7 +249,7 @@ object BatchSql { /** Get parameter names */ @annotation.tailrec - private def paramNames(ps: Compat.Trav[Map[String, ParameterValue]], ns: Set[String]): Either[String, Set[String]] = + private def paramNames(ps: Iterable[Map[String, ParameterValue]], ns: Set[String]): Either[String, Set[String]] = ps.headOption match { case Some(m) => if (ns.intersect(m.keySet).size != m.size) diff --git a/core/src/main/scala/anorm/Column.scala b/core/src/main/scala/anorm/Column.scala index db284091..4a242830 100644 --- a/core/src/main/scala/anorm/Column.scala +++ b/core/src/main/scala/anorm/Column.scala @@ -54,7 +54,7 @@ trait Column[A] extends ((Any, MetaDataItem) => Either[SqlRequestError, A]) { pa */ final def mapResult[B](f: A => Either[SqlRequestError, B]): Column[B] = Column[B] { (v: Any, m: MetaDataItem) => - Compat.rightFlatMap(parent(v, m))(f) + parent(v, m).flatMap(f) } /** @@ -365,7 +365,7 @@ object Column extends JavaTimeColumn { * }}} */ implicit val columnToBigInt: Column[BigInt] = nonNull { (value, meta) => - Compat.rightMap(anyToBigInteger(value, meta))(BigInt(_)) + anyToBigInteger(value, meta).map(BigInt(_)) } implicit val columnToUUID: Column[UUID] = nonNull { (value, meta) => @@ -447,7 +447,7 @@ object Column extends JavaTimeColumn { * }}} */ implicit val columnToScalaBigDecimal: Column[BigDecimal] = - nonNull((value, meta) => Compat.rightMap(anyToBigDecimal(value, meta))(BigDecimal(_))) + nonNull((value, meta) => anyToBigDecimal(value, meta).map(BigDecimal(_))) /** * Parses column as Java Date. @@ -475,7 +475,7 @@ object Column extends JavaTimeColumn { implicit def columnToOption[T](implicit transformer: Column[T]): Column[Option[T]] = Column { (value, meta) => if (value != null) { - Compat.rightMap(transformer(value, meta))(Some(_)) + transformer(value, meta).map(Some(_)) } else Right[SqlRequestError, Option[T]](None) } diff --git a/core/src/main/scala/anorm/Compat.scala b/core/src/main/scala/anorm/Compat.scala deleted file mode 100644 index cb297434..00000000 --- a/core/src/main/scala/anorm/Compat.scala +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ - -package anorm - -import java.util.{ Enumeration => JEnum } - -import scala.collection.immutable.Map - -private[anorm] object Compat { - @inline def toMap[T, K, V](in: Iterable[T])(f: T => (K, V)): Map[K, V] = - in.view.map(f).to(Map) - - @inline def toFlatMap[T, K, V](in: Iterable[T])(f: T => IterableOnce[(K, V)]): Map[K, V] = in.view.flatMap(f).to(Map) - - @inline def lazyZip[A, B](a: Iterable[A], b: Iterable[B]) = a.lazyZip(b) - - @inline def collectToMap[T, K, V](in: Iterable[T])(f: PartialFunction[T, (K, V)]): Map[K, V] = - in.view.collect(f).to(Map) - - @inline def rightMap[L, R1, R2](e: Either[L, R1])(f: R1 => R2): Either[L, R2] = e.map(f) - - @inline def rightFlatMap[L1, L2 >: L1, R1, R2](e: Either[L1, R1])(f: R1 => Either[L2, R2]): Either[L2, R2] = - e.flatMap(f) - - @inline def javaEnumIterator[T](e: JEnum[T]): Iterator[T] = { - import scala.jdk.CollectionConverters._ - e.asScala - } - - @inline def mapValues[K, V1, V2](m: Map[K, V1])(f: V1 => V2) = m.view.mapValues(f) - - /** Scala 2.13 compatibility type alias */ - type Trav[T] = Iterable[T] - - /** Scala 2.13 compatibility type alias */ - type LazyLst[T] = LazyList[T] - - @inline def LazyLst[T](values: T*): LazyLst[T] = LazyList.empty[T] :++ values -} diff --git a/core/src/main/scala/anorm/Cursor.scala b/core/src/main/scala/anorm/Cursor.scala index b37d69c4..030a6af8 100644 --- a/core/src/main/scala/anorm/Cursor.scala +++ b/core/src/main/scala/anorm/Cursor.scala @@ -70,8 +70,8 @@ object Cursor { /** Result row to be parsed. */ private case class ResultRow(metaData: MetaData, data: List[Any]) extends Row { - override lazy val toString = "Row(" + Compat - .lazyZip(metaData.ms, data) + override lazy val toString = "Row(" + metaData.ms + .lazyZip(data) .map((m, v) => s"'${m.column}': ${v} as ${m.clazz}") .mkString(", ") + ")" } diff --git a/core/src/main/scala/anorm/MetaData.scala b/core/src/main/scala/anorm/MetaData.scala index 2b58c882..a99bef62 100644 --- a/core/src/main/scala/anorm/MetaData.scala +++ b/core/src/main/scala/anorm/MetaData.scala @@ -27,19 +27,23 @@ private[anorm] case class MetaData(ms: Seq[MetaDataItem]) { } private lazy val dictionary: Map[String, MetaDataItem] = - Compat.toMap(ms) { m => m.column.qualified.toUpperCase() -> m } + ms.view.map { m => m.column.qualified.toUpperCase() -> m }.to(Map) private lazy val dictionary2: Map[String, MetaDataItem] = - Compat.toMap(ms) { m => - val column = m.column.qualified.split('.').last + ms.view + .map { m => + val column = m.column.qualified.split('.').last - column.toUpperCase() -> m - } + column.toUpperCase() -> m + } + .to(Map) private lazy val aliasedDictionary: Map[String, MetaDataItem] = - Compat.toFlatMap(ms) { m => - m.column.alias.map(a => Map(a.toUpperCase() -> m)).getOrElse(Map.empty) - } + ms.view + .flatMap { m => + m.column.alias.iterator.map(a => a.toUpperCase() -> m) + } + .to(Map) lazy val columnCount = ms.size diff --git a/core/src/main/scala/anorm/Row.scala b/core/src/main/scala/anorm/Row.scala index 5a843376..c2966eb0 100644 --- a/core/src/main/scala/anorm/Row.scala +++ b/core/src/main/scala/anorm/Row.scala @@ -23,8 +23,8 @@ trait Row { * * @see #as */ - lazy val asList: List[Any] = Compat - .lazyZip(data, metaData.ms) + lazy val asList: List[Any] = data + .lazyZip(metaData.ms) .map { (v, m) => if (m.nullable) Option(v) else v } @@ -42,12 +42,14 @@ trait Row { * @see #as */ lazy val asMap: Map[String, Any] = - Compat.toMap(Compat.lazyZip(data, metaData.ms)) { - case (v, m) => + data + .lazyZip(metaData.ms) + .map { (v, m) => val k = m.column.qualified if (m.nullable) k -> Option(v) else k -> v - } + } + .to(Map) /** * Returns row as `T`. @@ -117,10 +119,12 @@ trait Row { // Data per column name private lazy val columnsDictionary: Map[String, Any] = - Compat.toMap(Compat.lazyZip(metaData.ms, data)) { - case (m, v) => + metaData.ms + .lazyZip(data) + .map { (m, v) => m.column.qualified.toUpperCase -> v - } + } + .to(Map) // Data per column alias private lazy val aliasesDictionary: Map[String, Any] = { @@ -138,7 +142,7 @@ trait Row { * @param a Column qualified name, or label/alias */ private[anorm] def get(a: String): Either[SqlRequestError, (Any, MetaDataItem)] = - Compat.rightFlatMap(metaData.get(a.toUpperCase).toRight(ColumnNotFound(a, this))) { m => + metaData.get(a.toUpperCase).toRight(ColumnNotFound(a, this)).flatMap { m => def d = if (a.indexOf(".") > 0) { // if expected to be a qualified (dotted) name columnsDictionary.get(m.column.qualified.toUpperCase).orElse(m.column.alias.flatMap(aliasesDictionary.get(_))) @@ -149,13 +153,13 @@ trait Row { .orElse(columnsDictionary.get(m.column.qualified.toUpperCase)) } - Compat.rightMap(d.toRight(ColumnNotFound(m.column.qualified, metaData.availableColumns))) { _ -> m } + d.toRight(ColumnNotFound(m.column.qualified, metaData.availableColumns)).map { _ -> m } } /** Try to get data matching index. */ private[anorm] def getIndexed(i: Int): Either[SqlRequestError, (Any, MetaDataItem)] = - Compat.rightFlatMap(metaData.ms.lift(i).toRight(ColumnNotFound(s"#${i + 1}", metaData.availableColumns))) { m => - Compat.rightMap(data.lift(i).toRight(ColumnNotFound(m.column.qualified, metaData.availableColumns))) { _ -> m } + metaData.ms.lift(i).toRight(ColumnNotFound(s"#${i + 1}", metaData.availableColumns)).flatMap { m => + data.lift(i).toRight(ColumnNotFound(m.column.qualified, metaData.availableColumns)).map { _ -> m } } } diff --git a/core/src/main/scala/anorm/SqlParser.scala b/core/src/main/scala/anorm/SqlParser.scala index 2236b375..3d2df71d 100644 --- a/core/src/main/scala/anorm/SqlParser.scala +++ b/core/src/main/scala/anorm/SqlParser.scala @@ -28,9 +28,7 @@ object SqlParser extends FunctionAdapter with DeprecatedSqlParser { v <- row.data.headOption } yield v -> m).toRight(NoColumnsInReturnedResult) - val parsed = Compat.rightFlatMap[SqlMappingError, SqlRequestError, (Any, MetaDataItem), T](input) { in => - parseColumn(c, in) - } + val parsed = input.flatMap { in => parseColumn(c, in) } parsed.fold(Error(_), Success(_)) } @@ -488,10 +486,9 @@ object SqlParser extends FunctionAdapter with DeprecatedSqlParser { */ def get[T](name: String)(implicit @deprecatedName(Symbol("extractor")) c: Column[T]): RowParser[T] = RowParser { row => - Compat - .rightFlatMap(row.get(name)) { in => - parseColumn(c, in) - } + row + .get(name) + .flatMap { in => parseColumn(c, in) } .fold(Error(_), Success(_)) } @@ -511,10 +508,9 @@ object SqlParser extends FunctionAdapter with DeprecatedSqlParser { */ def get[T](position: Int)(implicit @deprecatedName(Symbol("extractor")) c: Column[T]): RowParser[T] = RowParser { row => - Compat - .rightFlatMap(row.getIndexed(position - 1)) { in => - parseColumn(c, in) - } + row + .getIndexed(position - 1) + .flatMap { in => parseColumn(c, in) } .fold(Error(_), Success(_)) } diff --git a/core/src/main/scala/anorm/ToSql.scala b/core/src/main/scala/anorm/ToSql.scala index d403adaa..f047557d 100644 --- a/core/src/main/scala/anorm/ToSql.scala +++ b/core/src/main/scala/anorm/ToSql.scala @@ -74,8 +74,8 @@ object ToSql { /** * Returns fragment for each value, separated by ", ". */ - implicit def streamToSql[A](implicit conv: ToSql[A] = ToSql.missing[A]): ToSql[Compat.LazyLst[A]] = - traversableToSql[A, Compat.LazyLst[A]] + implicit def streamToSql[A](implicit conv: ToSql[A] = ToSql.missing[A]): ToSql[LazyList[A]] = + traversableToSql[A, LazyList[A]] /** * Returns fragment for each value, separated by ", ". @@ -109,7 +109,7 @@ object ToSql { sql._1.toString -> sql._2 } - @inline private def traversableToSql[A, T <: Compat.Trav[A]](implicit conv: ToSql[A]) = ToSql[T] { values => + @inline private def traversableToSql[A, T <: Iterable[A]](implicit conv: ToSql[A]) = ToSql[T] { values => val c: A => (String, Int) = if (conv == null) _ => "?" -> 1 else conv.fragment diff --git a/core/src/main/scala/anorm/ToStatementMisc.scala b/core/src/main/scala/anorm/ToStatementMisc.scala index 705a48d4..7bad9535 100644 --- a/core/src/main/scala/anorm/ToStatementMisc.scala +++ b/core/src/main/scala/anorm/ToStatementMisc.scala @@ -659,8 +659,8 @@ sealed trait ToStatementPriority0 { /** * Sets multi-value parameter from stream on statement. */ - implicit def streamToStatement[A](implicit c: ToStatement[A]): ToStatement[Compat.LazyLst[A]] = - traversableToStatement[A, Compat.LazyLst[A]] + implicit def streamToStatement[A](implicit c: ToStatement[A]): ToStatement[LazyList[A]] = + traversableToStatement[A, LazyList[A]] /** * Sets multi-value parameter from vector on statement. @@ -695,10 +695,10 @@ sealed trait ToStatementPriority0 { c.set(s, offset, ps.values) } - @inline private def traversableToStatement[A, T <: Compat.Trav[A]](implicit c: ToStatement[A]) = new ToStatement[T] + @inline private def traversableToStatement[A, T <: Iterable[A]](implicit c: ToStatement[A]) = new ToStatement[T] with NotNullGuard { def set(s: PreparedStatement, offset: Int, ps: T) = - if (ps == (null: Compat.Trav[A])) throw new IllegalArgumentException() + if (ps == (null: Iterable[A])) throw new IllegalArgumentException() else { ps.foldLeft(offset) { (i, p) => c.set(s, i, p); i + 1 } () diff --git a/core/src/main/scala/anorm/TopLevelDefinitions.scala b/core/src/main/scala/anorm/TopLevelDefinitions.scala index 20024404..ca438764 100644 --- a/core/src/main/scala/anorm/TopLevelDefinitions.scala +++ b/core/src/main/scala/anorm/TopLevelDefinitions.scala @@ -9,6 +9,7 @@ import java.util.StringTokenizer import java.lang.reflect.InvocationTargetException import java.sql.{ PreparedStatement, ResultSet, SQLException } +import scala.jdk.CollectionConverters._ import scala.reflect.ClassTag private[anorm] trait TopLevelDefinitions extends PackageCompat { @@ -157,7 +158,7 @@ private[anorm] trait TopLevelDefinitions extends PackageCompat { } else { parts.headOption match { case Some(part) => - val it = Compat.javaEnumIterator[java.lang.Object](new StringTokenizer(part, "%", true)) + val it: Iterator[java.lang.Object] = new StringTokenizer(part, "%", true).asScala if (!it.hasNext /* empty */ ) { tokenize(it, List(StringToken("")), parts.tail, ps, gs, ns, m)