Skip to content

Commit

Permalink
Support NULL-value passthrough for all TypeMappers (#39)
Browse files Browse the repository at this point in the history
Similarly to #38, adding support for passing nulls (both ways, via
get/set) through the remaining TypeMappers.
  • Loading branch information
aboisvert authored Oct 21, 2024
1 parent 53cbad7 commit 0e4e39b
Showing 1 changed file with 44 additions and 14 deletions.
58 changes: 44 additions & 14 deletions scalasql/src/dialects/Dialect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ trait Dialect extends DialectTypeMappers {
r.getObject(idx) match {
case u: UUID => u
case s: String => UUID.fromString(s)
case null => null
}
}

Expand All @@ -110,16 +111,29 @@ trait Dialect extends DialectTypeMappers {
implicit def BytesType: TypeMapper[geny.Bytes] = new BytesType
class BytesType extends TypeMapper[geny.Bytes] {
def jdbcType = JDBCType.VARBINARY
def get(r: ResultSet, idx: Int) = new geny.Bytes(r.getBytes(idx))
def put(r: PreparedStatement, idx: Int, v: geny.Bytes) = r.setBytes(idx, v.array)
def get(r: ResultSet, idx: Int) = {
val bytes = r.getBytes(idx)
if (bytes == null) null
else new geny.Bytes(bytes)
}
def put(r: PreparedStatement, idx: Int, v: geny.Bytes) = {
val byteArray = if (v == null) null else v.array
r.setBytes(idx, byteArray)
}
}

implicit def UtilDateType: TypeMapper[java.util.Date] = new UtilDateType
class UtilDateType extends TypeMapper[java.util.Date] {
def jdbcType = JDBCType.TIMESTAMP
def get(r: ResultSet, idx: Int) = new java.util.Date(r.getTimestamp(idx).getTime)
def put(r: PreparedStatement, idx: Int, v: java.util.Date) =
r.setTimestamp(idx, new java.sql.Timestamp(v.getTime))
def get(r: ResultSet, idx: Int) = {
val ts = r.getTimestamp(idx)
if (ts == null) null
else new java.util.Date(ts.getTime)
}
def put(r: PreparedStatement, idx: Int, v: java.util.Date) = {
val time = if (v == null) null else new java.sql.Timestamp(v.getTime)
r.setTimestamp(idx, time)
}
}

implicit def LocalDateType: TypeMapper[LocalDate] = new LocalDateType
Expand Down Expand Up @@ -147,9 +161,15 @@ trait Dialect extends DialectTypeMappers {
class ZonedDateTimeType extends TypeMapper[ZonedDateTime] {
def jdbcType = JDBCType.TIMESTAMP_WITH_TIMEZONE
override def castTypeString = "TIMESTAMP WITH TIME ZONE"
def get(r: ResultSet, idx: Int) = r.getTimestamp(idx).toInstant.atZone(ZoneId.systemDefault())
def put(r: PreparedStatement, idx: Int, v: ZonedDateTime) = r
.setTimestamp(idx, java.sql.Timestamp.from(v.toInstant))
def get(r: ResultSet, idx: Int) = {
val ts = r.getTimestamp(idx)
if (ts == null) null
else ts.toInstant.atZone(ZoneId.systemDefault())
}
def put(r: PreparedStatement, idx: Int, v: ZonedDateTime) = {
val ts = if (v == null) null else java.sql.Timestamp.from(v.toInstant)
r.setTimestamp(idx, ts)
}
}

implicit def InstantType: TypeMapper[Instant] = new InstantType
Expand All @@ -173,8 +193,10 @@ trait Dialect extends DialectTypeMappers {
}
}

def put(r: PreparedStatement, idx: Int, v: Instant) = r
.setTimestamp(idx, java.sql.Timestamp.from(v))
def put(r: PreparedStatement, idx: Int, v: Instant) = {
val ts = if (v == null) null else java.sql.Timestamp.from(v)
r.setTimestamp(idx, ts)
}
}

implicit def OffsetTimeType: TypeMapper[OffsetTime] = new OffsetTimeType
Expand All @@ -190,19 +212,27 @@ trait Dialect extends DialectTypeMappers {
def jdbcType = JDBCType.TIMESTAMP_WITH_TIMEZONE
override def castTypeString = "TIMESTAMP WITH TIME ZONE"
def get(r: ResultSet, idx: Int) = {
r.getTimestamp(idx).toInstant.atOffset(OffsetDateTime.now().getOffset)
val ts = r.getTimestamp(idx)
if (ts == null) null
else ts.toInstant.atOffset(OffsetDateTime.now().getOffset)
}
def put(r: PreparedStatement, idx: Int, v: OffsetDateTime) = {
r.setTimestamp(idx, java.sql.Timestamp.from(v.toInstant))
val ts = if (v == null) null else java.sql.Timestamp.from(v.toInstant)
r.setTimestamp(idx, ts)
}
}

implicit def EnumType[T <: Enumeration#Value](implicit constructor: String => T): TypeMapper[T] =
new EnumType[T]
class EnumType[T](implicit constructor: String => T) extends TypeMapper[T] {
def jdbcType: JDBCType = JDBCType.VARCHAR
def get(r: ResultSet, idx: Int): T = constructor(r.getString(idx))
def put(r: PreparedStatement, idx: Int, v: T) = r.setObject(idx, v, java.sql.Types.OTHER)
def get(r: ResultSet, idx: Int): T = {
val str = r.getString(idx)
if (str == null) null.asInstanceOf[T]
else constructor(str)
}
def put(r: PreparedStatement, idx: Int, v: T) =
r.setObject(idx, v, java.sql.Types.OTHER)
}

implicit def from(x: Byte): Expr[Byte] = Expr(x)
Expand Down

0 comments on commit 0e4e39b

Please sign in to comment.