Skip to content

Commit

Permalink
add +~+ fragment concat op
Browse files Browse the repository at this point in the history
  • Loading branch information
satorg committed Jan 11, 2025
1 parent 0f190f4 commit 8398f06
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
17 changes: 17 additions & 0 deletions modules/core/src/main/scala/doobie/util/fragment.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ object fragment {
def ++(fb: Fragment): Fragment =
new Fragment(sql + fb.sql, elems ++ fb.elems, pos orElse fb.pos)

/** Concatenate this fragment with another, yielding a larger fragment and making sure there is at least one
* whitespace between the source fragments.
*/
def +~+(that: Fragment): Fragment = {
val res =
if (sql.isEmpty) that.sql
else if (that.sql.isEmpty) sql
else if (sql.last.isWhitespace || that.sql.head.isWhitespace) sql + that.sql
else sql + " " + that.sql

new Fragment(
res,
elems ++ that.elems,
pos orElse that.pos
)
}

def stripMargin(marginChar: Char): Fragment =
new Fragment(sql.stripMargin(marginChar), elems, pos)

Expand Down
21 changes: 19 additions & 2 deletions modules/core/src/test/scala/doobie/util/FragmentSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

package doobie.util

import cats.syntax.all.*
import cats.effect.IO
import cats.syntax.all.*
import doobie.*
import doobie.Fragment.const0
import doobie.implicits.*
import doobie.testutils.VoidExtensions

Expand Down Expand Up @@ -34,9 +35,25 @@ class FragmentSuite extends munit.FunSuite {
assertEquals(fr"foo $a $b bar".query[Unit].sql, "foo ? ? bar ")
}

test("Fragment must concatenate properly") {
test("Fragment builders DO NOT treat backslashes as escape characters") {
assertEquals(fr0"foo\\bar".query[Unit].sql, """foo\\bar""")
assertEquals(fr0"foo\nbar".query[Unit].sql, """foo\nbar""")
}
test("Fragment must concatenate properly with `++`") {
assertEquals((fr"foo" ++ fr"bar $a baz").query[Unit].sql, "foo bar ? baz ")
}
test("Fragment must concatenate properly enforcing at least 1 whitespace in between with `+~+`") {
// Since `fr"..."` do not parse backslashes as escape characters, so we need to use `const0` to test them.
assertEquals((const0("") +~+ const0("bar")).query[Unit].sql, "bar")
assertEquals((const0("foo") +~+ const0("")).query[Unit].sql, "foo")
assertEquals((const0("foo") +~+ const0("bar")).query[Unit].sql, "foo bar")
assertEquals((const0("foo ") +~+ const0("bar")).query[Unit].sql, "foo bar")
assertEquals((const0("foo\n") +~+ const0("bar")).query[Unit].sql, "foo\nbar")
assertEquals((const0("foo") +~+ const0(" bar")).query[Unit].sql, "foo bar")
assertEquals((const0("foo") +~+ const0("\tbar")).query[Unit].sql, "foo\tbar")
assertEquals((const0("foo ") +~+ const0(" bar")).query[Unit].sql, "foo bar")
assertEquals((const0("foo\r") +~+ const0("\fbar")).query[Unit].sql, "foo\r\fbar")
}

test("Fragment must interpolate fragments properly") {
assertEquals(fr"foo ${fr0"bar $a baz"}".query[Unit].sql, "foo bar ? baz ")
Expand Down

0 comments on commit 8398f06

Please sign in to comment.