Skip to content

Commit

Permalink
review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Łukasz Bigorajski committed Aug 26, 2024
1 parent 16ff01f commit 81add5e
Showing 1 changed file with 39 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,57 @@ import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypingResult}
import java.io.BufferedReader
import java.sql.{Clob, ResultSet, ResultSetMetaData}
import java.time.{Instant, LocalDate, LocalTime}
import java.util.stream.Collectors
import java.{sql, util}
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
import scala.util.Using

object ColumnDefinition {
final case class ColumnDefinition(
name: String,
typing: TypingResult,
valueMapping: Any => Any
) {

def extractValue(resultSet: ResultSet): Any = {
// we could here use method resultSet.getObject(Int) and pass column number as argument
// but in case of ignite db it is not certain which column index corresponds to which column.
val value = resultSet.getObject(name)
Option(value).map(valueMapping).getOrElse(value)
}

private lazy val sqlTypingMap = Map(
classOf[sql.Array].getName -> Typed.typedClass(classOf[util.List[Any]]),
classOf[sql.Time].getName -> Typed.typedClass(classOf[LocalTime]),
classOf[sql.Date].getName -> Typed.typedClass(classOf[LocalDate]),
classOf[sql.Timestamp].getName -> Typed.typedClass(classOf[Instant]),
classOf[sql.Clob].getName -> Typed.typedClass(classOf[String]),
)
}

def apply(columnNo: Int, resultMeta: ResultSetMetaData): ColumnDefinition =
object ColumnDefinition {
private val sqlArrayClassName = classOf[sql.Array].getName
private val sqlTimeClassName = classOf[sql.Time].getName
private val sqlDateClassName = classOf[sql.Date].getName
private val sqlTimestampClassName = classOf[sql.Timestamp].getName
private val sqlClobClassName = classOf[sql.Clob].getName

def apply(columnNo: Int, resultMeta: ResultSetMetaData): ColumnDefinition = {
val (typingResult, valueMapping) = mapValueToSupportedType(resultMeta.getColumnClassName(columnNo))
ColumnDefinition(
name = resultMeta.getColumnName(columnNo),
typing = supportedTypeTypingResult(resultMeta.getColumnClassName(columnNo))
typing = typingResult,
valueMapping = valueMapping
)
}

def apply(typing: (String, String)): ColumnDefinition =
def apply(typing: (String, String)): ColumnDefinition = {
val (typingResult, valueMapping) = mapValueToSupportedType(typing._2)
ColumnDefinition(
name = typing._1,
typing = supportedTypeTypingResult(typing._2)
typing = typingResult,
valueMapping = valueMapping
)

private def supportedTypeTypingResult(className: String): TypingResult =
sqlTypingMap.getOrElse(className, Typed.typedClass(Class.forName(className)))
}

final case class ColumnDefinition(
name: String,
typing: TypingResult
) {

def extractValue(resultSet: ResultSet): Any = {
// we could here use method resultSet.getObject(Int) and pass column number as argument
// but in case of ignite db it is not certain which column index corresponds to which column.
val value = resultSet.getObject(name)
Option(value)
.map(mapValueToSupportedType)
.getOrElse(value)
}

private def mapValueToSupportedType(value: Any): Any = value match {
case v: sql.Array => readArray(v)
case v: sql.Time => v.toLocalTime
case v: sql.Date => v.toLocalDate
case v: sql.Timestamp => v.toInstant
case v: sql.Clob => readClob(v)
case _ => value
private def mapValueToSupportedType(className: String): (TypingResult, Any => Any) = className match {
case `sqlArrayClassName` => (Typed.typedClass(classOf[util.List[Any]]), v => readArray(v.asInstanceOf[sql.Array]))
case `sqlTimeClassName` => (Typed.typedClass(classOf[LocalTime]), v => v.asInstanceOf[sql.Time].toLocalTime)
case `sqlDateClassName` => (Typed.typedClass(classOf[LocalDate]), v => v.asInstanceOf[sql.Date].toLocalDate)
case `sqlTimestampClassName` => (Typed.typedClass(classOf[Instant]), v => v.asInstanceOf[sql.Timestamp].toInstant)
case `sqlClobClassName` => (Typed.typedClass(classOf[String]), v => readClob(v.asInstanceOf[sql.Clob]))
case _ => (Typed.typedClass(Class.forName(className)), identity)
}

private def readArray(v: sql.Array): util.List[AnyRef] = {
Expand All @@ -72,17 +71,6 @@ final case class ColumnDefinition(
Using.resource(new BufferedReader(v.getCharacterStream))(br => readFromStream(br))
}

@tailrec private def readFromStream(
br: BufferedReader,
acc: ArrayBuffer[String] = new ArrayBuffer[String]()
): String = {
val string = br.readLine()
if (string == null) {
acc.mkString(System.lineSeparator)
} else {
acc.append(string)
readFromStream(br, acc)
}
}

private def readFromStream(br: BufferedReader): String =
br.lines().collect(Collectors.joining(System.lineSeparator()))
}

0 comments on commit 81add5e

Please sign in to comment.