From 6aec4a2874c4e5af7958cca1a9f6a0e0bf3f41a8 Mon Sep 17 00:00:00 2001 From: Tobias Pfeifer Date: Sun, 28 Mar 2021 21:38:39 +0200 Subject: [PATCH 1/2] Add 'format' function to PostgresModule #184 --- .../zio/sql/postgresql/PostgresModule.scala | 6 ++ .../zio/sql/postgresql/FunctionDefSpec.scala | 102 +++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala b/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala index 3d00da854..e78ff2105 100644 --- a/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala +++ b/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala @@ -227,6 +227,12 @@ trait PostgresModule extends Jdbc { self => FunctionDef[Timestampz, Timestampz](FunctionName("make_timestamptz")) val Encode = FunctionDef[(Chunk[Byte], String), String](FunctionName("encode")) val Decode = FunctionDef[(String, String), Chunk[Byte]](FunctionName("decode")) + val Format0 = FunctionDef[String, String](FunctionName("format")) // TODO: varargs + val Format1 = FunctionDef[(String, Any), String](FunctionName("format")) + val Format2 = FunctionDef[(String, Any, Any), String](FunctionName("format")) + val Format3 = FunctionDef[(String, Any, Any, Any), String](FunctionName("format")) + val Format4 = FunctionDef[(String, Any, Any, Any, Any), String](FunctionName("format")) + val Format5 = FunctionDef[(String, Any, Any, Any, Any, Any), String](FunctionName("format")) } override def renderRead(read: self.Read[_]): String = { diff --git a/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala b/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala index e399fb3a5..5c1d946f7 100644 --- a/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala +++ b/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala @@ -151,7 +151,105 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema { } yield assert(r.head)(equalTo(expected)) assertion.mapErrorCause(cause => Cause.stackless(cause.untraced)) - } + }, + suite("format function")( + testM("format0") { + import Expr._ + + val query = select(Format0("Person")) from customers + + val expected = Seq( + "Person", + "Person", + "Person", + "Person", + "Person" + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + }, + testM("format1") { + import Expr._ + + val query = select(Format1("Person: %s", Customers.fName)) from customers + + val expected = Seq( + "Person: Ronald", + "Person: Terrence", + "Person: Mila", + "Person: Alana", + "Person: Jose" + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + }, + testM("format2") { + import Expr._ + + val query = select(Format2("Person: %s %s", Customers.fName, Customers.lName)) from customers + + val expected = Seq( + "Person: Ronald Russell", + "Person: Terrence Noel", + "Person: Mila Paterso", + "Person: Alana Murray", + "Person: Jose Wiggins" + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + }, + testM("format3") { + import Expr._ + + val query = select(Format3("Person: %s %s with double quoted %I ", Customers.fName, Customers.lName, "identi fier")) from customers + + val expected = Seq( + s"""Person: Ronald Russell with double quoted "identi fier" """, + s"""Person: Terrence Noel with double quoted "identi fier" """, + s"""Person: Mila Paterso with double quoted "identi fier" """, + s"""Person: Alana Murray with double quoted "identi fier" """, + s"""Person: Jose Wiggins with double quoted "identi fier" """ + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + }, + testM("format4") { + import Expr._ + + val query = select(Format4("Person: %s %s with null-literal %L and non-null-literal %L ", Customers.fName, Customers.lName, "FIXME: NULL", "literal")) from customers + + val expected = Seq( + s"""Person: Ronald Russell with null-literal 'FIXME: NULL' and non-null-literal 'literal' """, + s"""Person: Terrence Noel with null-literal 'FIXME: NULL' and non-null-literal 'literal' """, + s"""Person: Mila Paterso with null-literal 'FIXME: NULL' and non-null-literal 'literal' """, + s"""Person: Alana Murray with null-literal 'FIXME: NULL' and non-null-literal 'literal' """, + s"""Person: Jose Wiggins with null-literal 'FIXME: NULL' and non-null-literal 'literal' """ + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + }, + testM("format5") { + import Expr._ + + val query = select(Format5("Person: %s %s with more arguments than placeholders: %I %L ", Customers.fName, Customers.lName, "identifier", Reverse(Customers.fName), "unused")) from customers + + val expected = Seq( + s"""Person: Ronald Russell with more arguments than placeholders: identifier 'dlanoR' """, + s"""Person: Terrence Noel with more arguments than placeholders: identifier 'ecnerreT' """, + s"""Person: Mila Paterso with more arguments than placeholders: identifier 'aliM' """, + s"""Person: Alana Murray with more arguments than placeholders: identifier 'analA' """, + s"""Person: Jose Wiggins with more arguments than placeholders: identifier 'esoJ' """ + ) + + val testResult = execute(query.to[String, String](identity)) + collectAndCompare(expected, testResult) + } + ) ), testM("abs") { val query = select(Abs(-3.14159)) from customers @@ -358,7 +456,7 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema { r <- testResult.runCollect } yield assert(r.head)( matchesRegex( - "[A-Za-z]{3}\\s[A-Za-z]{3}\\s[0-9]{2}\\s(2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9].[0-9]{6}\\s[0-9]{4}\\s[A-Za-z]{3}" + "[A-Za-z]{3}\\s[A-Za-z]{3}\\s[0-9]{2}\\s(2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9].[0-9]{6}\\s[0-9]{4}\\s[A-Za-z]{3,4}" ) ) assertion.mapErrorCause(cause => Cause.stackless(cause.untraced)) From b1671e5c1cd87bbfd9751238c75f2d978b56b00e Mon Sep 17 00:00:00 2001 From: Tobias Pfeifer Date: Sun, 28 Mar 2021 22:14:41 +0200 Subject: [PATCH 2/2] fix formatting --- .../zio/sql/postgresql/PostgresModule.scala | 12 ++++----- .../zio/sql/postgresql/FunctionDefSpec.scala | 25 ++++++++++++++++--- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala b/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala index e78ff2105..9cbdec184 100644 --- a/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala +++ b/postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala @@ -227,12 +227,12 @@ trait PostgresModule extends Jdbc { self => FunctionDef[Timestampz, Timestampz](FunctionName("make_timestamptz")) val Encode = FunctionDef[(Chunk[Byte], String), String](FunctionName("encode")) val Decode = FunctionDef[(String, String), Chunk[Byte]](FunctionName("decode")) - val Format0 = FunctionDef[String, String](FunctionName("format")) // TODO: varargs - val Format1 = FunctionDef[(String, Any), String](FunctionName("format")) - val Format2 = FunctionDef[(String, Any, Any), String](FunctionName("format")) - val Format3 = FunctionDef[(String, Any, Any, Any), String](FunctionName("format")) - val Format4 = FunctionDef[(String, Any, Any, Any, Any), String](FunctionName("format")) - val Format5 = FunctionDef[(String, Any, Any, Any, Any, Any), String](FunctionName("format")) + val Format0 = FunctionDef[String, String](FunctionName("format")) // TODO: varargs + val Format1 = FunctionDef[(String, Any), String](FunctionName("format")) + val Format2 = FunctionDef[(String, Any, Any), String](FunctionName("format")) + val Format3 = FunctionDef[(String, Any, Any, Any), String](FunctionName("format")) + val Format4 = FunctionDef[(String, Any, Any, Any, Any), String](FunctionName("format")) + val Format5 = FunctionDef[(String, Any, Any, Any, Any, Any), String](FunctionName("format")) } override def renderRead(read: self.Read[_]): String = { diff --git a/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala b/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala index 5c1d946f7..fb900d8a3 100644 --- a/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala +++ b/postgres/src/test/scala/zio/sql/postgresql/FunctionDefSpec.scala @@ -204,7 +204,9 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema { testM("format3") { import Expr._ - val query = select(Format3("Person: %s %s with double quoted %I ", Customers.fName, Customers.lName, "identi fier")) from customers + val query = select( + Format3("Person: %s %s with double quoted %I ", Customers.fName, Customers.lName, "identi fier") + ) from customers val expected = Seq( s"""Person: Ronald Russell with double quoted "identi fier" """, @@ -220,7 +222,15 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema { testM("format4") { import Expr._ - val query = select(Format4("Person: %s %s with null-literal %L and non-null-literal %L ", Customers.fName, Customers.lName, "FIXME: NULL", "literal")) from customers + val query = select( + Format4( + "Person: %s %s with null-literal %L and non-null-literal %L ", + Customers.fName, + Customers.lName, + "FIXME: NULL", + "literal" + ) + ) from customers val expected = Seq( s"""Person: Ronald Russell with null-literal 'FIXME: NULL' and non-null-literal 'literal' """, @@ -236,7 +246,16 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema { testM("format5") { import Expr._ - val query = select(Format5("Person: %s %s with more arguments than placeholders: %I %L ", Customers.fName, Customers.lName, "identifier", Reverse(Customers.fName), "unused")) from customers + val query = select( + Format5( + "Person: %s %s with more arguments than placeholders: %I %L ", + Customers.fName, + Customers.lName, + "identifier", + Reverse(Customers.fName), + "unused" + ) + ) from customers val expected = Seq( s"""Person: Ronald Russell with more arguments than placeholders: identifier 'dlanoR' """,