Skip to content

Commit

Permalink
Add EXTRACT function to Rel8.Expr.Time
Browse files Browse the repository at this point in the history
This adds unsafe EXTRACT function to Rel8.Expr.Time, using the low-level
Opaleye functions. Should solve #236.
  • Loading branch information
guaraqe committed Dec 10, 2024
1 parent 06af0ea commit 019f5f7
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions src/Rel8/Expr/Time.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Rel8.Expr.Time
, addTime
, diffTime
, subtractTime
, unsafeExtractFromTime

-- * Working with @CalendarDiffTime@
, scaleInterval
Expand All @@ -24,6 +25,7 @@ module Rel8.Expr.Time
, week, weeks
, month, months
, year, years
, unsafeExtractFromInterval
) where

-- base
Expand All @@ -32,8 +34,10 @@ import Prelude

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Function (binaryOperator, function)
import Rel8.Expr.Opaleye ( castExpr, unsafeCastExpr, unsafeLiteral )
import Rel8.Expr.Function ( binaryOperator, function )
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 )
Expand Down Expand Up @@ -90,6 +94,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 "*"
Expand Down Expand Up @@ -167,3 +179,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]]

0 comments on commit 019f5f7

Please sign in to comment.