Skip to content

Support NULL-value passthrough for all TypeMappers #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading