typelevel / doobie

Functional JDBC layer for Scala.
MIT License
2.16k stars 355 forks source link

Inspecting bound placeholder values #645

Open mirosval opened 6 years ago

mirosval commented 6 years ago

Hi and thank you for this amazing library!

In my application I have built a layer that takes some parameters (like order by, offset, limit) and builds out a Fragment with the full SQL query from them. A lightweight SQL DSL if you will.

My problem is with writing tests for this - I can test something like this:

req.whereColumnFragment.toString shouldBe Fragment.const("column = ?").toString

but, I can not test that the placeholder has been properly passed in. I would like to do something like:

val abc = "abc"
val correct = fr"column = $abc"
req.whereColumnFragment.placeholders.head shouldBe correct.placeholders.head

Here placeholders is essentially equivalent to the protected def a: A on the Fragment sealed trait.

Problem is that it is protected so I can only access it from tests using reflection.

tpolecat commented 6 years ago

A is existential here which is essential in the treatment of Fragment as a monoid. But it's not a list; it's usually going to be a 2-way branching tree with an associated Composite, both of which are built up on the fly.

However this is more structure than we need. It's a monoid so we don't need a tree; associativity doesn't matter. So we could refactor Fragment to build up a list, and have a member like args: List[(A, Composite[A]) forSome { type A }] which would give you a way to inspect the arguments (up to erasure). This would also solve the pref/overflow problem when you build up a fragment with 7283654876 values.