diff --git a/scalasql/src/dialects/Dialect.scala b/scalasql/src/dialects/Dialect.scala index 3490df5c..08ffeb0c 100644 --- a/scalasql/src/dialects/Dialect.scala +++ b/scalasql/src/dialects/Dialect.scala @@ -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 } } @@ -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 @@ -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 @@ -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 @@ -190,10 +212,13 @@ 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) } } @@ -201,8 +226,13 @@ trait Dialect extends DialectTypeMappers { 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)