Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 214 and 205 #290

Merged
merged 13 commits into from
Nov 28, 2020
7 changes: 6 additions & 1 deletion core/jvm/src/main/scala/zio/sql/expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ trait ExprModule extends NewtypesModule with FeaturesModule with OpsModule {
def typeTag: TypeTag[Z] = implicitly[TypeTag[Z]]
}

sealed case class ParenlessFunctionCall0[Z: TypeTag](function: FunctionName)
extends InvariantExpr[Features.Function0, Any, Z] {
def typeTag: TypeTag[Z] = implicitly[TypeTag[Z]]
}

sealed case class FunctionCall0[Z: TypeTag](function: FunctionDef[Any, Z])
extends InvariantExpr[Features.Function0, Any, Z] {
def typeTag: TypeTag[Z] = implicitly[TypeTag[Z]]
Expand Down Expand Up @@ -219,7 +224,7 @@ trait ExprModule extends NewtypesModule with FeaturesModule with OpsModule {

sealed case class FunctionDef[-A, +B](name: FunctionName) { self =>

def apply[B1 >: B]()(implicit typeTag: TypeTag[B1]): Expr[Features.Function0, Any, B1] =
def apply[B1 >: B]()(implicit ev: Any <:< A, typeTag: TypeTag[B1]): Expr[Features.Function0, Any, B1] =
Expr.FunctionCall0(self.asInstanceOf[FunctionDef[Any, B1]])

def apply[F, Source, B1 >: B](param1: Expr[F, Source, A])(implicit typeTag: TypeTag[B1]): Expr[F, Source, B1] =
Expand Down
19 changes: 13 additions & 6 deletions postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package zio.sql.postgresql

import zio.sql.{ Jdbc, Renderer }
import java.time._

import java.time.{ Instant, LocalDate, LocalTime, ZonedDateTime }
import zio.sql.{ Jdbc, Renderer }

/**
*/
trait PostgresModule extends Jdbc { self =>

object PostgresFunctionDef {
val TimeOfDay = FunctionDef[Any, String](FunctionName("timeofday"))
val CurrentTime = Expr.ParenlessFunctionCall0[OffsetTime](FunctionName("current_time"))
val CharLength = FunctionDef[String, Int](FunctionName("character_length"))
val Localtime = FunctionDef[Any, LocalTime](FunctionName("localtime"))
val Localtime = Expr.ParenlessFunctionCall0[LocalTime](FunctionName("localtime"))
val LocaltimeWithPrecision = FunctionDef[Int, LocalTime](FunctionName("localtime"))
val Localtimestamp = FunctionDef[Any, Instant](FunctionName("localtimestamp"))
val Localtimestamp = Expr.ParenlessFunctionCall0[Instant](FunctionName("localtimestamp"))
val LocaltimestampWithPrecision = FunctionDef[Int, Instant](FunctionName("localtimestamp"))
val Md5 = FunctionDef[String, String](FunctionName("md5"))
val ParseIdent = FunctionDef[String, String](FunctionName("parse_ident"))
val Chr = FunctionDef[Int, String](FunctionName("chr"))
val CurrentDate = FunctionDef[Any, LocalDate](FunctionName("current_date"))
val CurrentDate = Expr.ParenlessFunctionCall0[LocalDate](FunctionName("current_date"))
val Initcap = FunctionDef[String, String](FunctionName("initcap"))
val Repeat = FunctionDef[(String, Int), String](FunctionName("repeat"))
val Reverse = FunctionDef[String, String](FunctionName("reverse"))
Expand Down Expand Up @@ -160,7 +162,12 @@ trait PostgresModule extends Jdbc { self =>
render(aggregation.name.name, "(")
renderExpr(p)
render(")")
case Expr.FunctionCall0(fn) => render(fn.name.name) //todo parens or no parens?
case Expr.ParenlessFunctionCall0(fn) =>
val _ = render(fn.name)
case Expr.FunctionCall0(fn) =>
render(fn.name.name)
render("(")
val _ = render(")")
case Expr.FunctionCall1(p, fn) =>
render(fn.name.name, "(")
renderExpr(p)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,23 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {

assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("timeofday") {
val query = select(TimeOfDay()) from customers

val testResult = execute(query).to[String, String](identity)

val assertion =
for {
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}"
robmwalsh marked this conversation as resolved.
Show resolved Hide resolved
)
)
assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("localtime") {
val query = select(Localtime()) from customers
val query = select(Localtime) from customers

val testResult = execute(query).to[LocalTime, LocalTime](identity)

Expand All @@ -236,7 +251,7 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("localtimestamp") {
val query = select(Localtimestamp()) from customers
val query = select(Localtimestamp) from customers

val testResult = execute(query).to[Instant, Instant](identity)

Expand Down Expand Up @@ -270,6 +285,22 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {

assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("current_time") {
val query = select(CurrentTime) from customers

val testResult = execute(query).to[OffsetTime, OffsetTime](identity)

val assertion =
for {
r <- testResult.runCollect
} yield assert(r.head.toString)(
matchesRegex(
"(2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]Z"
)
)

assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("md5") {
val query = select(Md5("hello, world!")) from customers

Expand Down Expand Up @@ -343,7 +374,7 @@ object FunctionDefSpec extends PostgresRunnableSpec with ShopSchema {
assertion.mapErrorCause(cause => Cause.stackless(cause.untraced))
},
testM("current_date") {
val query = select(CurrentDate()) from customers
val query = select(CurrentDate) from customers

val expected = LocalDate.now()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ trait SqlServerModule extends Jdbc { self =>
builder.append("(")
buildExpr(param)
val _ = builder.append(")")
case Expr.ParenlessFunctionCall0(function) =>
val _ = builder.append(function.name)
case Expr.FunctionCall0(function) =>
val _ = builder.append(function.name.name)
builder.append(function.name.name)
builder.append("(")
val _ = builder.append(")")
case Expr.FunctionCall1(param, function) =>
builder.append(function.name.name)
builder.append("(")
Expand Down