Skip to content

Commit

Permalink
Ensure every parameterized value is set
Browse files Browse the repository at this point in the history
Some JDBC drivers require that every parameterized value has a value
explicitly set so ensure that an optional `Write` instance sets its
columns to `null` if given no value.
  • Loading branch information
guymers authored Mar 26, 2023
1 parent 1fb7f21 commit 58fa1ee
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
10 changes: 6 additions & 4 deletions modules/core/src/main/scala/doobie/util/write.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@ sealed trait Write1 extends WritePlatform { this: Write.type =>
case o => Option(o)
}
}
override def unsafeSet(ps: PreparedStatement, i: Int, a: Option[A]) = {
a.foreach(W.unsafeSet(ps, i, _))
override def unsafeSet(ps: PreparedStatement, i: Int, a: Option[A]) = a match {
case None => W.puts.zipWithIndex.foreach { case ((p, _), o) => p.unsafeSetNullable(ps, i + o, None) }
case Some(a) => W.unsafeSet(ps, i, a)
}
override def unsafeUpdate(rs: ResultSet, i: Int, a: Option[A]) = {
a.foreach(W.unsafeUpdate(rs, i, _))
override def unsafeUpdate(rs: ResultSet, i: Int, a: Option[A]) = a match {
case None => W.puts.zipWithIndex.foreach { case ((p, _), o) => p.unsafeUpdateNullable(rs, i + o, None) }
case Some(a) => W.unsafeUpdate(rs, i, a)
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions modules/core/src/test/scala/doobie/util/WriteSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ object WriteSuite extends H2DatabaseSpec with WriteSuitePlatform {
},
suite("write correctly")(
test("fragment") {

def insert[A](a: A)(implicit W: Write[A]) = {
fr"INSERT INTO test_write (v, s) VALUES ($a)".update.withUniqueGeneratedKeys[Test]("v", "s")
}
Expand Down Expand Up @@ -187,6 +188,30 @@ object WriteSuite extends H2DatabaseSpec with WriteSuitePlatform {
}
conn.transact
},
test("nested") {

def insert(a: TestNested) = {
fr"INSERT INTO test_write_n (v, s) VALUES ($a)".update.withUniqueGeneratedKeys[TestNested]("v", "s")
}

val conn = for {
_ <- Update0(
"CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS test_write_n(v INT, s VARCHAR) NOT PERSISTENT",
None,
).run

t0 <- insert(TestNested(None))
t1 <- insert(TestNested(Some(Test(None, None))))
t2 <- insert(TestNested(Some(Test(None, Some("str")))))
t3 <- insert(TestNested(Some(Test(Some(3), Some("str")))))
} yield {
assertTrue(t0 == TestNested(None)) &&
assertTrue(t1 == TestNested(None)) &&
assertTrue(t2 == TestNested(Some(Test(None, Some("str"))))) &&
assertTrue(t3 == TestNested(Some(Test(Some(3), Some("str")))))
}
conn.transact
},
),
suite("platform specific")(platformTests*),
)
Expand All @@ -198,4 +223,11 @@ object WriteSuite extends H2DatabaseSpec with WriteSuitePlatform {
val writeTuple = (Write[Option[Int]], Write[Option[String]]).tupled
}

case class TestNested(n: Option[Test])
object TestNested {
implicit val read: Read[TestNested] = Read.derived
implicit val writeTest: Write[Test] = Test.write
implicit val write: Write[TestNested] = Write.derived
}

}

0 comments on commit 58fa1ee

Please sign in to comment.