From 551eb564f18073d046dd06d69f87f002ccdb1ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Raphael=20Diaz=20Sim=C3=B5es?= Date: Fri, 12 May 2023 16:25:36 +0500 Subject: [PATCH] Add EXTRACT function to Rel8.Expr.Time This adds unsafe EXTRACT function to Rel8.Expr.Time, using the low-level Opaleye functions. Should solve #236. --- src/Rel8/Expr/Time.hs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Rel8/Expr/Time.hs b/src/Rel8/Expr/Time.hs index c5ad08cf..37d111e4 100644 --- a/src/Rel8/Expr/Time.hs +++ b/src/Rel8/Expr/Time.hs @@ -12,6 +12,7 @@ module Rel8.Expr.Time , addTime , diffTime , subtractTime + , unsafeExtractFromTime -- * Working with @CalendarDiffTime@ , scaleInterval @@ -22,6 +23,7 @@ module Rel8.Expr.Time , week, weeks , month, months , year, years + , unsafeExtractFromInterval ) where -- base @@ -31,7 +33,9 @@ import Prelude -- rel8 import Rel8.Expr ( Expr ) import Rel8.Expr.Function ( binaryOperator, nullaryFunction ) -import Rel8.Expr.Opaleye ( castExpr, unsafeCastExpr, unsafeLiteral ) +import Rel8.Expr.Opaleye ( castExpr, unsafeCastExpr, unsafeLiteral, fromPrimExpr, toPrimExpr ) +import Rel8.Type ( DBType ) +import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye -- time import Data.Time.Calendar ( Day ) @@ -88,6 +92,14 @@ diffTime = binaryOperator "-" subtractTime :: Expr CalendarDiffTime -> Expr UTCTime -> Expr UTCTime subtractTime = flip (binaryOperator "-") +-- | Extract a part of a point in time. See possibilities +-- [here](https://www.postgresqltutorial.com/postgresql-date-functions/postgresql-extract/). +-- This function is unsafe because you must decide yourself the output type. +unsafeExtractFromTime :: DBType a => String -> Expr UTCTime -> Expr a +unsafeExtractFromTime name expr = + castExpr $ + fromPrimExpr $ + Opaleye.FunExpr "EXTRACT" [Opaleye.FunExpr (name <> " FROM") [toPrimExpr expr]] scaleInterval :: Expr Double -> Expr CalendarDiffTime -> Expr CalendarDiffTime scaleInterval = binaryOperator "*" @@ -165,3 +177,13 @@ years = (`scaleInterval` year) singleton :: String -> Expr CalendarDiffTime singleton unit = castExpr $ unsafeLiteral $ "'1 " ++ unit ++ "'" + +-- | Extract a part of an interval. See possibilities +-- [here](https://www.postgresqltutorial.com/postgresql-date-functions/postgresql-extract/). +-- This function is unsafe because you must decide yourself the output type. +unsafeExtractFromInterval :: DBType a => String -> Expr CalendarDiffTime -> Expr a +unsafeExtractFromInterval name expr = + castExpr $ + fromPrimExpr $ + Opaleye.FunExpr "EXTRACT" [Opaleye.FunExpr (name <> " FROM") [toPrimExpr expr]] +