{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE CPP #-}

-- | Postgres-specific types, functions, and operators
module Database.Beam.Postgres.PgSpecific
  ( -- ** Full-text search
    -- $full-text-search

    -- *** @TSVECTOR@ data type
    TsVectorConfig, TsVector(..)
  , toTsVector, english

    -- *** @TSQUERY@ data type
  , TsQuery(..), (@@)
  , toTsQuery

    -- ** @JSON@ and @JSONB@ data types
    -- $json
  , PgJSON(..), PgJSONB(..)
  , IsPgJSON(..)
  , PgJSONEach(..), PgJSONKey(..), PgJSONElement(..)

  , (@>), (<@), (->#), (->$)
  , (->>#), (->>$), (#>), (#>>)
  , (?), (?|), (?&)

  , withoutKey, withoutIdx
  , withoutKeys

  , pgJsonArrayLength
  , pgArrayToJson
  , pgJsonbUpdate, pgJsonbSet
  , pgJsonbPretty

    -- ** @MONEY@ data type
  , PgMoney(..), pgMoney

  , pgScaleMoney_
  , pgDivideMoney_, pgDivideMoneys_

  , pgAddMoney_, pgSubtractMoney_
  , pgSumMoneyOver_, pgAvgMoneyOver_
  , pgSumMoney_, pgAvgMoney_

    -- ** Geometry types (not PostGIS)
  , PgPoint(..), PgLine(..), PgLineSegment(..)
  , PgBox(..), PgPath(..), PgPolygon(..)
  , PgCircle(..)

    -- ** Regular expressions
  , PgRegex(..), pgRegex_
  , (~.), (~*.), (!~.), (!~*.)
  , pgRegexpReplace_, pgRegexpMatch_
  , pgRegexpSplitToTable, pgRegexpSplitToArray

    -- ** Set-valued functions
    -- $set-valued-funs
  , PgSetOf, pgUnnest
  , pgUnnestArray, pgUnnestArrayWithOrdinality

    -- ** @ARRAY@ types
    -- $arrays
  , PgArrayValueContext, PgIsArrayContext

    -- *** Building @ARRAY@s
  , array_, arrayOf_, (++.)
  , pgArrayAgg, pgArrayAggOver

    -- *** Array operators and functions
  , (!.), arrayDims_
  , arrayUpper_, arrayLower_
  , arrayUpperUnsafe_, arrayLowerUnsafe_
  , arrayLength_, arrayLengthUnsafe_

  , isSupersetOf_, isSubsetOf_

    -- ** @RANGE@ types
    -- $ranges
  , PgRange(..), PgRangeBound(..), PgBoundType(..)
  , PgIsRange(..)
  , PgInt4Range, PgInt8Range, PgNumRange
  , PgTsRange, PgTsTzRange, PgDateRange

    -- *** Building ranges from expressions
  , range_

    -- *** Building @PgRangeBound@s
  , inclusive, exclusive, unbounded

    -- *** Range operators and functions
  , (-@>-), (-@>), (-<@-), (<@-)
  , (-&&-), (-<<-), (->>-)
  , (-&<-), (-&>-), (--|--)
  , (-+-), (-*-), (-.-)
  , rLower_, rUpper_, isEmpty_
  , lowerInc_, upperInc_, lowerInf_, upperInf_
  , rangeMerge_

    -- * Postgres @EXTRACT@ fields
  , century_, decade_, dow_, doy_, epoch_, isodow_, isoyear_
  , microseconds_, milliseconds_, millennium_, quarter_, week_

    -- ** Postgres functions and aggregates
  , pgBoolOr, pgBoolAnd, pgStringAgg, pgStringAggOver

  , pgNubBy_

  , now_, ilike_, ilike_'
  )
where

import           Database.Beam hiding (char, double)
import           Database.Beam.Backend.SQL
import           Database.Beam.Migrate ( HasDefaultSqlDataType(..) )
import           Database.Beam.Postgres.Syntax
import           Database.Beam.Postgres.Types
import           Database.Beam.Query.Internal
import           Database.Beam.Schema.Tables

import           Control.Monad.Free
import           Control.Monad.State.Strict (evalState, put, get)

import           Data.Aeson
import           Data.Attoparsec.ByteString
import           Data.Attoparsec.ByteString.Char8
import           Data.ByteString (ByteString)
import           Data.ByteString.Builder
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as BL
import           Data.Foldable
import           Data.Functor
import           Data.Hashable
import           Data.Int
import qualified Data.List.NonEmpty as NE
import           Data.Proxy
import           Data.Scientific (Scientific, formatScientific, FPFormat(Fixed))
import           Data.String
import qualified Data.Text as T
import           Data.Time (LocalTime, NominalDiffTime)
import           Data.Type.Bool
import qualified Data.Vector as V
#if !MIN_VERSION_base(4, 11, 0)
import           Data.Semigroup
#endif

import qualified Database.PostgreSQL.Simple.FromField as Pg
import qualified Database.PostgreSQL.Simple.ToField as Pg
import qualified Database.PostgreSQL.Simple.TypeInfo.Static as Pg
import qualified Database.PostgreSQL.Simple.Range as Pg

import           GHC.TypeLits
import           GHC.Exts hiding (toList)

-- ** Postgres-specific functions

-- | Postgres @NOW()@ function. Returns the server's timestamp
now_ :: QExpr Postgres s LocalTime
now_ :: forall s. QExpr Postgres s LocalTime
now_ = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
_ -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"NOW()"))

-- | Postgres @ILIKE@ operator. A case-insensitive version of 'like_'.
ilike_
  :: BeamSqlBackendIsString Postgres text
  => QExpr Postgres s text
  -> QExpr Postgres s text
  -> QExpr Postgres s Bool
ilike_ :: forall text s.
BeamSqlBackendIsString Postgres text =>
QExpr Postgres s text
-> QExpr Postgres s text -> QExpr Postgres s Bool
ilike_ = forall left right s.
(BeamSqlBackendIsString Postgres left,
 BeamSqlBackendIsString Postgres right) =>
QExpr Postgres s left
-> QExpr Postgres s right -> QExpr Postgres s Bool
ilike_'

-- | Postgres @ILIKE@ operator. A case-insensitive version of 'like_''.
ilike_'
  :: ( BeamSqlBackendIsString Postgres left
     , BeamSqlBackendIsString Postgres right
     )
  => QExpr Postgres s left
  -> QExpr Postgres s right
  -> QExpr Postgres s Bool
ilike_' :: forall left right s.
(BeamSqlBackendIsString Postgres left,
 BeamSqlBackendIsString Postgres right) =>
QExpr Postgres s left
-> QExpr Postgres s right -> QExpr Postgres s Bool
ilike_' (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"ILIKE" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- ** TsVector type

-- | The type of a document preprocessed for full-text search. The contained
-- 'ByteString' is the Postgres representation of the @TSVECTOR@ type. Use
-- 'toTsVector' to construct these on-the-fly from strings.
--
-- When this field is embedded in a beam table, 'defaultMigratableDbSettings'
-- will give the column the postgres @TSVECTOR@ type.
newtype TsVector = TsVector ByteString
  deriving (Int -> TsVector -> ShowS
[TsVector] -> ShowS
TsVector -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TsVector] -> ShowS
$cshowList :: [TsVector] -> ShowS
show :: TsVector -> String
$cshow :: TsVector -> String
showsPrec :: Int -> TsVector -> ShowS
$cshowsPrec :: Int -> TsVector -> ShowS
Show, TsVector -> TsVector -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TsVector -> TsVector -> Bool
$c/= :: TsVector -> TsVector -> Bool
== :: TsVector -> TsVector -> Bool
$c== :: TsVector -> TsVector -> Bool
Eq, Eq TsVector
TsVector -> TsVector -> Bool
TsVector -> TsVector -> Ordering
TsVector -> TsVector -> TsVector
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TsVector -> TsVector -> TsVector
$cmin :: TsVector -> TsVector -> TsVector
max :: TsVector -> TsVector -> TsVector
$cmax :: TsVector -> TsVector -> TsVector
>= :: TsVector -> TsVector -> Bool
$c>= :: TsVector -> TsVector -> Bool
> :: TsVector -> TsVector -> Bool
$c> :: TsVector -> TsVector -> Bool
<= :: TsVector -> TsVector -> Bool
$c<= :: TsVector -> TsVector -> Bool
< :: TsVector -> TsVector -> Bool
$c< :: TsVector -> TsVector -> Bool
compare :: TsVector -> TsVector -> Ordering
$ccompare :: TsVector -> TsVector -> Ordering
Ord)

-- | The identifier of a Postgres text search configuration.
--
-- Use the 'IsString' instance to construct new values of this type
newtype TsVectorConfig = TsVectorConfig ByteString
  deriving (Int -> TsVectorConfig -> ShowS
[TsVectorConfig] -> ShowS
TsVectorConfig -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TsVectorConfig] -> ShowS
$cshowList :: [TsVectorConfig] -> ShowS
show :: TsVectorConfig -> String
$cshow :: TsVectorConfig -> String
showsPrec :: Int -> TsVectorConfig -> ShowS
$cshowsPrec :: Int -> TsVectorConfig -> ShowS
Show, TsVectorConfig -> TsVectorConfig -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TsVectorConfig -> TsVectorConfig -> Bool
$c/= :: TsVectorConfig -> TsVectorConfig -> Bool
== :: TsVectorConfig -> TsVectorConfig -> Bool
$c== :: TsVectorConfig -> TsVectorConfig -> Bool
Eq, Eq TsVectorConfig
TsVectorConfig -> TsVectorConfig -> Bool
TsVectorConfig -> TsVectorConfig -> Ordering
TsVectorConfig -> TsVectorConfig -> TsVectorConfig
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TsVectorConfig -> TsVectorConfig -> TsVectorConfig
$cmin :: TsVectorConfig -> TsVectorConfig -> TsVectorConfig
max :: TsVectorConfig -> TsVectorConfig -> TsVectorConfig
$cmax :: TsVectorConfig -> TsVectorConfig -> TsVectorConfig
>= :: TsVectorConfig -> TsVectorConfig -> Bool
$c>= :: TsVectorConfig -> TsVectorConfig -> Bool
> :: TsVectorConfig -> TsVectorConfig -> Bool
$c> :: TsVectorConfig -> TsVectorConfig -> Bool
<= :: TsVectorConfig -> TsVectorConfig -> Bool
$c<= :: TsVectorConfig -> TsVectorConfig -> Bool
< :: TsVectorConfig -> TsVectorConfig -> Bool
$c< :: TsVectorConfig -> TsVectorConfig -> Bool
compare :: TsVectorConfig -> TsVectorConfig -> Ordering
$ccompare :: TsVectorConfig -> TsVectorConfig -> Ordering
Ord, String -> TsVectorConfig
forall a. (String -> a) -> IsString a
fromString :: String -> TsVectorConfig
$cfromString :: String -> TsVectorConfig
IsString)

instance Pg.FromField TsVector where
  fromField :: FieldParser TsVector
fromField Field
field Maybe ByteString
d =
    if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
pgTsVectorTypeInfo
    then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
    else case Maybe ByteString
d of
           Just ByteString
d' -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> TsVector
TsVector ByteString
d')
           Maybe ByteString
Nothing -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""

instance Pg.ToField TsVector where
  toField :: TsVector -> Action
toField (TsVector ByteString
d) =
    [Action] -> Action
Pg.Many [ Builder -> Action
Pg.Plain Builder
"($$"
            , Builder -> Action
Pg.Plain (ByteString -> Builder
byteString ByteString
d)
            , Builder -> Action
Pg.Plain Builder
"$$::tsvector)" ]

instance FromBackendRow Postgres TsVector

instance HasSqlEqualityCheck Postgres TsVectorConfig
instance HasSqlQuantifiedEqualityCheck Postgres TsVectorConfig

instance HasSqlEqualityCheck Postgres TsVector
instance HasSqlQuantifiedEqualityCheck Postgres TsVector

-- | A full-text search configuration with sensible defaults for english
english :: TsVectorConfig
english :: TsVectorConfig
english = ByteString -> TsVectorConfig
TsVectorConfig ByteString
"english"

-- | The Postgres @to_tsvector@ function. Given a configuration and string,
-- return the @TSVECTOR@ that represents the contents of the string.
toTsVector :: BeamSqlBackendIsString Postgres str
           => Maybe TsVectorConfig -> QGenExpr context Postgres s str
           -> QGenExpr context Postgres s TsVector
toTsVector :: forall str context s.
BeamSqlBackendIsString Postgres str =>
Maybe TsVectorConfig
-> QGenExpr context Postgres s str
-> QGenExpr context Postgres s TsVector
toTsVector Maybe TsVectorConfig
Nothing (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
x) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgExpressionSyntax PgSyntax
x') ->
                 PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
                 ByteString -> PgSyntax
emit ByteString
"to_tsvector(" forall a. Semigroup a => a -> a -> a
<> PgSyntax
x' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")") Text -> BeamSqlBackendExpressionSyntax Postgres
x)
toTsVector (Just (TsVectorConfig ByteString
configNm)) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
x) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgExpressionSyntax PgSyntax
x') -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
                 ByteString -> PgSyntax
emit ByteString
"to_tsvector('" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
escapeString ByteString
configNm forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"', " forall a. Semigroup a => a -> a -> a
<> PgSyntax
x' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")") Text -> BeamSqlBackendExpressionSyntax Postgres
x)

-- | Determine if the given @TSQUERY@ matches the document represented by the
-- @TSVECTOR@. Behaves exactly like the similarly-named operator in postgres.
(@@) :: QGenExpr context Postgres s TsVector
     -> QGenExpr context Postgres s TsQuery
     -> QGenExpr context Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
vec @@ :: forall context s.
QGenExpr context Postgres s TsVector
-> QGenExpr context Postgres s TsQuery
-> QGenExpr context Postgres s Bool
@@ QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
q =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"@@" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
vec forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
q)

-- ** TsQuery type

-- | A query that can be run against a document contained in a 'TsVector'.
--
-- When this field is embedded in a beam table, 'defaultMigratableDbSettings'
-- will give the column the postgres @TSVECTOR@ type
newtype TsQuery = TsQuery ByteString
  deriving (Int -> TsQuery -> ShowS
[TsQuery] -> ShowS
TsQuery -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TsQuery] -> ShowS
$cshowList :: [TsQuery] -> ShowS
show :: TsQuery -> String
$cshow :: TsQuery -> String
showsPrec :: Int -> TsQuery -> ShowS
$cshowsPrec :: Int -> TsQuery -> ShowS
Show, TsQuery -> TsQuery -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TsQuery -> TsQuery -> Bool
$c/= :: TsQuery -> TsQuery -> Bool
== :: TsQuery -> TsQuery -> Bool
$c== :: TsQuery -> TsQuery -> Bool
Eq, Eq TsQuery
TsQuery -> TsQuery -> Bool
TsQuery -> TsQuery -> Ordering
TsQuery -> TsQuery -> TsQuery
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TsQuery -> TsQuery -> TsQuery
$cmin :: TsQuery -> TsQuery -> TsQuery
max :: TsQuery -> TsQuery -> TsQuery
$cmax :: TsQuery -> TsQuery -> TsQuery
>= :: TsQuery -> TsQuery -> Bool
$c>= :: TsQuery -> TsQuery -> Bool
> :: TsQuery -> TsQuery -> Bool
$c> :: TsQuery -> TsQuery -> Bool
<= :: TsQuery -> TsQuery -> Bool
$c<= :: TsQuery -> TsQuery -> Bool
< :: TsQuery -> TsQuery -> Bool
$c< :: TsQuery -> TsQuery -> Bool
compare :: TsQuery -> TsQuery -> Ordering
$ccompare :: TsQuery -> TsQuery -> Ordering
Ord)

instance HasSqlEqualityCheck Postgres TsQuery
instance HasSqlQuantifiedEqualityCheck Postgres TsQuery

instance Pg.FromField TsQuery where
  fromField :: FieldParser TsQuery
fromField Field
field Maybe ByteString
d =
    if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
pgTsQueryTypeInfo
    then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
    else case Maybe ByteString
d of
           Just ByteString
d' -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> TsQuery
TsQuery ByteString
d')
           Maybe ByteString
Nothing -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""

instance FromBackendRow Postgres TsQuery

-- | The Postgres @to_tsquery@ function. Given a configuration and string,
-- return the @TSQUERY@ that represents the contents of the string.
toTsQuery :: BeamSqlBackendIsString Postgres str
          => Maybe TsVectorConfig -> QGenExpr context Postgres s str
          -> QGenExpr context Postgres s TsQuery
toTsQuery :: forall str context s.
BeamSqlBackendIsString Postgres str =>
Maybe TsVectorConfig
-> QGenExpr context Postgres s str
-> QGenExpr context Postgres s TsQuery
toTsQuery Maybe TsVectorConfig
Nothing (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
x) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgExpressionSyntax PgSyntax
x') ->
                 PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
                 ByteString -> PgSyntax
emit ByteString
"to_tsquery(" forall a. Semigroup a => a -> a -> a
<> PgSyntax
x' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")") Text -> BeamSqlBackendExpressionSyntax Postgres
x)
toTsQuery (Just (TsVectorConfig ByteString
configNm)) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
x) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgExpressionSyntax PgSyntax
x') -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
                 ByteString -> PgSyntax
emit ByteString
"to_tsquery('" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
escapeString ByteString
configNm forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"', " forall a. Semigroup a => a -> a -> a
<> PgSyntax
x' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")") Text -> BeamSqlBackendExpressionSyntax Postgres
x)

-- ** Array operators

-- TODO this should be robust to slices

-- | Index into the given array. This translates to the @<array>[<index>]@
-- syntax in postgres. The beam operator name has been chosen to match the
-- 'Data.Vector.(!)' operator.
(!.) :: Integral ix
     => QGenExpr context Postgres s (V.Vector a)
     -> QGenExpr context Postgres s ix
     -> QGenExpr context Postgres s a
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v !. :: forall ix context s a.
Integral ix =>
QGenExpr context Postgres s (Vector a)
-> QGenExpr context Postgres s ix -> QGenExpr context Postgres s a
!. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
ix =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
index forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
v forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
ix)
  where
    index :: PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
index (PgExpressionSyntax PgSyntax
v') (PgExpressionSyntax PgSyntax
ix') =
      PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"(" forall a. Semigroup a => a -> a -> a
<> PgSyntax
v' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")[" forall a. Semigroup a => a -> a -> a
<> PgSyntax
ix' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"]")

-- | Postgres @array_dims()@ function. Returns a textual representation of the
-- dimensions of the array.
arrayDims_ :: BeamSqlBackendIsString Postgres text
           => QGenExpr context Postgres s (V.Vector a)
           -> QGenExpr context Postgres s text
arrayDims_ :: forall text context s a.
BeamSqlBackendIsString Postgres text =>
QGenExpr context Postgres s (Vector a)
-> QGenExpr context Postgres s text
arrayDims_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgExpressionSyntax PgSyntax
v') -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"array_dims(" forall a. Semigroup a => a -> a -> a
<> PgSyntax
v' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")) Text -> BeamSqlBackendExpressionSyntax Postgres
v)

type family CountDims (v :: *) :: Nat where
  CountDims (V.Vector a) = 1 + CountDims a
  CountDims a = 0
type family WithinBounds (dim :: Nat) (v :: *) :: Constraint where
  WithinBounds dim v =
    If ((dim <=? CountDims v) && (1 <=? dim))
       (() :: Constraint)
       (TypeError ( ('Text "Dimension " ':<>: 'ShowType dim ':<>: 'Text " is out of bounds.") ':$$:
                    ('Text "The type " ':<>: 'ShowType v ':<>: 'Text " has " ':<>: 'ShowType (CountDims v) ':<>: 'Text " dimension(s).") ':$$:
                    ('Text "Hint: The dimension should be a natural between 1 and " ':<>: 'ShowType (CountDims v)) ))

-- | Return the upper or lower bound of the given array at the given dimension
--  (statically supplied as a type application on a 'GHC.TypeLits.Nat'). Note
--  that beam will attempt to statically determine if the dimension is in range.
--  GHC errors will be thrown if this cannot be proved.
--
-- For example, to get the upper bound of the 2nd-dimension of an array:
--
-- @
-- arrayUpper_ @2 vectorValuedExpression
-- @
arrayUpper_, arrayLower_
  :: forall (dim :: Nat) context num v s.
     (KnownNat dim, WithinBounds dim (V.Vector v), Integral num)
  => QGenExpr context Postgres s (V.Vector v)
  -> QGenExpr context Postgres s num
arrayUpper_ :: forall (dim :: Nat) context num v s.
(KnownNat dim, WithinBounds dim (Vector v), Integral num) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s num
arrayUpper_ QGenExpr context Postgres s (Vector v)
v =
  forall ctxt be s a a'.
QGenExpr ctxt be s a -> QGenExpr ctxt be s a'
unsafeRetype (forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayUpperUnsafe_ QGenExpr context Postgres s (Vector v)
v (forall a. SqlValable a => HaskellLiteralForQExpr a -> a
val_ (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @dim) :: Integer)) :: QGenExpr context Postgres s (Maybe Integer))
arrayLower_ :: forall (dim :: Nat) context num v s.
(KnownNat dim, WithinBounds dim (Vector v), Integral num) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s num
arrayLower_ QGenExpr context Postgres s (Vector v)
v =
  forall ctxt be s a a'.
QGenExpr ctxt be s a -> QGenExpr ctxt be s a'
unsafeRetype (forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayLowerUnsafe_ QGenExpr context Postgres s (Vector v)
v (forall a. SqlValable a => HaskellLiteralForQExpr a -> a
val_ (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @dim) :: Integer)) :: QGenExpr context Postgres s (Maybe Integer))

-- | These functions can be used to find the lower and upper bounds of an array
-- where the dimension number is not known until run-time. They are marked
-- unsafe because they may cause query processing to fail at runtime, even if
-- they typecheck successfully.
arrayUpperUnsafe_, arrayLowerUnsafe_
  :: (Integral dim, Integral length)
  => QGenExpr context Postgres s (V.Vector v)
  -> QGenExpr context Postgres s dim
  -> QGenExpr context Postgres s (Maybe length)
arrayUpperUnsafe_ :: forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayUpperUnsafe_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
dim) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$
         [ forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
"array_upper(")
         , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
v
         , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", ")
         , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
dim
         , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
")") ])
arrayLowerUnsafe_ :: forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayLowerUnsafe_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
dim) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$
         [ forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
"array_lower(")
         , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
v
         , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", ")
         , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
dim
         , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
")") ])

-- | Get the size of the array at the given (statically known) dimension,
-- provided as a type-level 'Nat'. Like the 'arrayUpper_' and 'arrayLower_'
-- functions,throws a compile-time error if the dimension is out of bounds.
arrayLength_
  :: forall (dim :: Nat) ctxt num v s.
     (KnownNat dim, WithinBounds dim (V.Vector v), Integral num)
  => QGenExpr ctxt Postgres s (V.Vector v)
  -> QGenExpr ctxt Postgres s num
arrayLength_ :: forall (dim :: Nat) context num v s.
(KnownNat dim, WithinBounds dim (Vector v), Integral num) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s num
arrayLength_ QGenExpr ctxt Postgres s (Vector v)
v =
  forall ctxt be s a a'.
QGenExpr ctxt be s a -> QGenExpr ctxt be s a'
unsafeRetype (forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayLengthUnsafe_ QGenExpr ctxt Postgres s (Vector v)
v (forall a. SqlValable a => HaskellLiteralForQExpr a -> a
val_ (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @dim) :: Integer)) :: QGenExpr ctxt Postgres s (Maybe Integer))

-- | Get the size of an array at a dimension not known until run-time. Marked
-- unsafe as this may cause runtime errors even if it type checks.
arrayLengthUnsafe_
  :: (Integral dim, Integral num)
  => QGenExpr ctxt Postgres s (V.Vector v)
  -> QGenExpr ctxt Postgres s dim
  -> QGenExpr ctxt Postgres s (Maybe num)
arrayLengthUnsafe_ :: forall dim length context s v.
(Integral dim, Integral length) =>
QGenExpr context Postgres s (Vector v)
-> QGenExpr context Postgres s dim
-> QGenExpr context Postgres s (Maybe length)
arrayLengthUnsafe_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
dim) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$
  [ forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
"array_length(")
  , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a
  , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", ")
  , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
dim
  , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
")") ]

-- | The Postgres @&#x40;>@ operator. Returns true if every member of the second
-- array is present in the first.
isSupersetOf_ :: QGenExpr ctxt Postgres s (V.Vector a)
              -> QGenExpr ctxt Postgres s (V.Vector a)
              -> QGenExpr ctxt Postgres s Bool
isSupersetOf_ :: forall ctxt s a.
QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s Bool
isSupersetOf_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
haystack) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
needles) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"@>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
haystack forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
needles)

-- | The Postgres @<&#x40;@ operator. Returns true if every member of the first
-- array is present in the second.
isSubsetOf_ :: QGenExpr ctxt Postgres s (V.Vector a)
            -> QGenExpr ctxt Postgres s (V.Vector a)
            -> QGenExpr ctxt Postgres s Bool
isSubsetOf_ :: forall ctxt s a.
QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s Bool
isSubsetOf_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
needles) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
haystack) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"<@" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
needles forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
haystack)

-- | Postgres @||@ operator. Concatenates two vectors and returns their result.
(++.) :: QGenExpr ctxt Postgres s (V.Vector a)
      -> QGenExpr ctxt Postgres s (V.Vector a)
      -> QGenExpr ctxt Postgres s (V.Vector a)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ++. :: forall ctxt s a.
QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s (Vector a)
-> QGenExpr ctxt Postgres s (Vector a)
++. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"||" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- ** Array expressions

-- | An expression context that determines which types of expressions can be put
-- inside an array element. Any scalar, aggregate, or window expression can be
-- placed within an array.
data PgArrayValueContext

-- | If you are extending beam-postgres and provide another expression context
-- that can be represented in an array, provide an empty instance of this class.
class PgIsArrayContext ctxt where
  mkArraySyntax :: Proxy ctxt -> PgSyntax -> PgSyntax
  mkArraySyntax Proxy ctxt
_ PgSyntax
s = ByteString -> PgSyntax
emit ByteString
"ARRAY" forall a. Semigroup a => a -> a -> a
<> PgSyntax
s
instance PgIsArrayContext PgArrayValueContext where
  mkArraySyntax :: Proxy PgArrayValueContext -> PgSyntax -> PgSyntax
mkArraySyntax Proxy PgArrayValueContext
_ = forall a. a -> a
id
instance PgIsArrayContext QValueContext
instance PgIsArrayContext QAggregateContext
instance PgIsArrayContext QWindowingContext

-- | Build a 1-dimensional postgres array from an arbitrary 'Foldable'
-- containing expressions.
array_ :: forall context f s a.
          (PgIsArrayContext context, Foldable f)
       => f (QGenExpr context Postgres s a)
       -> QGenExpr context Postgres s (V.Vector a)
array_ :: forall context (f :: * -> *) s a.
(PgIsArrayContext context, Foldable f) =>
f (QGenExpr context Postgres s a)
-> QGenExpr context Postgres s (Vector a)
array_ f (QGenExpr context Postgres s a)
vs =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (ctxt :: k).
PgIsArrayContext ctxt =>
Proxy ctxt -> PgSyntax -> PgSyntax
mkArraySyntax (forall {k} (t :: k). Proxy t
Proxy @context) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$
  forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [ forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
"[")
            , PgSyntax -> [PgSyntax] -> PgSyntax
pgSepBy (ByteString -> PgSyntax
emit ByteString
", ") forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
e) -> PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
e) (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f (QGenExpr context Postgres s a)
vs)
            , forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
"]") ]

-- | Build a 1-dimensional postgres array from a subquery
arrayOf_ :: Q Postgres db s (QExpr Postgres s a)
         -> QGenExpr context Postgres s (V.Vector a)
arrayOf_ :: forall (db :: (* -> *) -> *) s a context.
Q Postgres db s (QExpr Postgres s a)
-> QGenExpr context Postgres s (Vector a)
arrayOf_ Q Postgres db s (QExpr Postgres s a)
q =
  let QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
sub = forall be s a (db :: (* -> *) -> *) ctxt.
(BeamSqlBackend be, HasQBuilder be,
 Projectible be (QExpr be s a)) =>
Q be db s (QExpr be s a) -> QGenExpr ctxt be s a
subquery_ Q Postgres db s (QExpr Postgres s a)
q
  in forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
t -> let PgExpressionSyntax PgSyntax
sub' = Text -> BeamSqlBackendExpressionSyntax Postgres
sub Text
t
                  in PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"ARRAY(" forall a. Semigroup a => a -> a -> a
<> PgSyntax
sub' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")"))

-- ** Ranges

-- | Represents the types of bounds a range can have. A range can and often does have mis-matched
-- bound types.
data PgBoundType
  = Inclusive
  | Exclusive
  deriving (PgBoundType -> PgBoundType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgBoundType -> PgBoundType -> Bool
$c/= :: PgBoundType -> PgBoundType -> Bool
== :: PgBoundType -> PgBoundType -> Bool
$c== :: PgBoundType -> PgBoundType -> Bool
Eq, Int -> PgBoundType -> ShowS
[PgBoundType] -> ShowS
PgBoundType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgBoundType] -> ShowS
$cshowList :: [PgBoundType] -> ShowS
show :: PgBoundType -> String
$cshow :: PgBoundType -> String
showsPrec :: Int -> PgBoundType -> ShowS
$cshowsPrec :: Int -> PgBoundType -> ShowS
Show, forall x. Rep PgBoundType x -> PgBoundType
forall x. PgBoundType -> Rep PgBoundType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PgBoundType x -> PgBoundType
$cfrom :: forall x. PgBoundType -> Rep PgBoundType x
Generic)
instance Hashable PgBoundType

lBound :: PgBoundType -> ByteString
lBound :: PgBoundType -> ByteString
lBound PgBoundType
Inclusive = ByteString
"["
lBound PgBoundType
Exclusive = ByteString
"("

uBound :: PgBoundType -> ByteString
uBound :: PgBoundType -> ByteString
uBound PgBoundType
Inclusive = ByteString
"]"
uBound PgBoundType
Exclusive = ByteString
")"

-- | Represents a single bound on a Range. A bound always has a type, but may not have a value
-- (the absense of a value represents unbounded).
data PgRangeBound a = PgRangeBound PgBoundType (Maybe a) deriving (PgRangeBound a -> PgRangeBound a -> Bool
forall a. Eq a => PgRangeBound a -> PgRangeBound a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgRangeBound a -> PgRangeBound a -> Bool
$c/= :: forall a. Eq a => PgRangeBound a -> PgRangeBound a -> Bool
== :: PgRangeBound a -> PgRangeBound a -> Bool
$c== :: forall a. Eq a => PgRangeBound a -> PgRangeBound a -> Bool
Eq, Int -> PgRangeBound a -> ShowS
forall a. Show a => Int -> PgRangeBound a -> ShowS
forall a. Show a => [PgRangeBound a] -> ShowS
forall a. Show a => PgRangeBound a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgRangeBound a] -> ShowS
$cshowList :: forall a. Show a => [PgRangeBound a] -> ShowS
show :: PgRangeBound a -> String
$cshow :: forall a. Show a => PgRangeBound a -> String
showsPrec :: Int -> PgRangeBound a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PgRangeBound a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (PgRangeBound a) x -> PgRangeBound a
forall a x. PgRangeBound a -> Rep (PgRangeBound a) x
$cto :: forall a x. Rep (PgRangeBound a) x -> PgRangeBound a
$cfrom :: forall a x. PgRangeBound a -> Rep (PgRangeBound a) x
Generic)

inclusive :: a -> PgRangeBound a
inclusive :: forall a. a -> PgRangeBound a
inclusive = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Inclusive forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just

exclusive :: a -> PgRangeBound a
exclusive :: forall a. a -> PgRangeBound a
exclusive = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Exclusive forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just

unbounded :: PgRangeBound a
unbounded :: forall a. PgRangeBound a
unbounded = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Exclusive forall a. Maybe a
Nothing

-- | A range of a given Haskell type (represented by @a@) stored as a given Postgres Range Type
-- (represented by @n@).
--
-- A reasonable example might be @Range PgInt8Range Int64@.
-- This represents a range of Haskell @Int64@ values stored as a range of 'bigint' in Postgres.
data PgRange (n :: *) a
  = PgEmptyRange
  | PgRange (PgRangeBound a) (PgRangeBound a)
  deriving (PgRange n a -> PgRange n a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall n a. Eq a => PgRange n a -> PgRange n a -> Bool
/= :: PgRange n a -> PgRange n a -> Bool
$c/= :: forall n a. Eq a => PgRange n a -> PgRange n a -> Bool
== :: PgRange n a -> PgRange n a -> Bool
$c== :: forall n a. Eq a => PgRange n a -> PgRange n a -> Bool
Eq, Int -> PgRange n a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall n a. Show a => Int -> PgRange n a -> ShowS
forall n a. Show a => [PgRange n a] -> ShowS
forall n a. Show a => PgRange n a -> String
showList :: [PgRange n a] -> ShowS
$cshowList :: forall n a. Show a => [PgRange n a] -> ShowS
show :: PgRange n a -> String
$cshow :: forall n a. Show a => PgRange n a -> String
showsPrec :: Int -> PgRange n a -> ShowS
$cshowsPrec :: forall n a. Show a => Int -> PgRange n a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall n a x. Rep (PgRange n a) x -> PgRange n a
forall n a x. PgRange n a -> Rep (PgRange n a) x
$cto :: forall n a x. Rep (PgRange n a) x -> PgRange n a
$cfrom :: forall n a x. PgRange n a -> Rep (PgRange n a) x
Generic)

instance Hashable a => Hashable (PgRangeBound a)

instance Hashable a => Hashable (PgRange n a)

-- | A class representing Postgres Range types and how to refer to them when speaking to the
-- database.
--
-- For custom Range types, create an uninhabited type, and make it an instance of this class.
class PgIsRange n where
  -- | The range type name in the database.
  rangeName :: ByteString

data PgInt4Range
instance PgIsRange PgInt4Range where
  rangeName :: ByteString
rangeName = ByteString
"int4range"

data PgInt8Range
instance PgIsRange PgInt8Range where
  rangeName :: ByteString
rangeName = ByteString
"int8range"

data PgNumRange
instance PgIsRange PgNumRange where
  rangeName :: ByteString
rangeName = ByteString
"numrange"

data PgTsRange
instance PgIsRange PgTsRange where
  rangeName :: ByteString
rangeName = ByteString
"tsrange"

data PgTsTzRange
instance PgIsRange PgTsTzRange where
  rangeName :: ByteString
rangeName = ByteString
"tstzrange"

data PgDateRange
instance PgIsRange PgDateRange where
  rangeName :: ByteString
rangeName = ByteString
"daterange"

instance (Pg.FromField a, Typeable a, Typeable n, Ord a) => Pg.FromField (PgRange n a) where
  fromField :: FieldParser (PgRange n a)
fromField Field
field Maybe ByteString
d = do
    PGRange a
pgR :: Pg.PGRange a <- forall a. FromField a => FieldParser a
Pg.fromField Field
field Maybe ByteString
d
    if forall a. Ord a => PGRange a -> Bool
Pg.isEmpty PGRange a
pgR
    then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall n a. PgRange n a
PgEmptyRange
    else let Pg.PGRange RangeBound a
lRange RangeBound a
rRange = PGRange a
pgR
         in forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall n a. PgRangeBound a -> PgRangeBound a -> PgRange n a
PgRange (forall a. RangeBound a -> PgRangeBound a
boundConv RangeBound a
lRange) (forall a. RangeBound a -> PgRangeBound a
boundConv RangeBound a
rRange)

-- According to Postgres docs, there is no such thing as an inclusive infinite bound.
-- https://www.postgresql.org/docs/10/static/rangetypes.html#RANGETYPES-INFINITE
boundConv :: Pg.RangeBound a -> PgRangeBound a
boundConv :: forall a. RangeBound a -> PgRangeBound a
boundConv RangeBound a
Pg.NegInfinity = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Exclusive forall a. Maybe a
Nothing
boundConv RangeBound a
Pg.PosInfinity = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Exclusive forall a. Maybe a
Nothing
boundConv (Pg.Inclusive a
a) = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Inclusive (forall a. a -> Maybe a
Just a
a)
boundConv (Pg.Exclusive a
a) = forall a. PgBoundType -> Maybe a -> PgRangeBound a
PgRangeBound PgBoundType
Exclusive (forall a. a -> Maybe a
Just a
a)

instance (Pg.ToField (Pg.PGRange a)) => Pg.ToField (PgRange n a) where
  toField :: PgRange n a -> Action
toField PgRange n a
PgEmptyRange = forall a. ToField a => a -> Action
Pg.toField (forall a. PGRange a
Pg.empty :: Pg.PGRange a)
  toField (PgRange (PgRangeBound PgBoundType
lt Maybe a
lb) (PgRangeBound PgBoundType
ut Maybe a
ub)) = forall a. ToField a => a -> Action
Pg.toField PGRange a
r'
    where
      r' :: PGRange a
r' = forall a. RangeBound a -> RangeBound a -> PGRange a
Pg.PGRange RangeBound a
lb' RangeBound a
ub'
      lb' :: RangeBound a
lb' = case (PgBoundType
lt, Maybe a
lb) of (PgBoundType
_, Maybe a
Nothing) -> forall a. RangeBound a
Pg.NegInfinity
                             (PgBoundType
Inclusive, Just a
a) -> forall a. a -> RangeBound a
Pg.Inclusive a
a
                             (PgBoundType
Exclusive, Just a
a) -> forall a. a -> RangeBound a
Pg.Exclusive a
a
      ub' :: RangeBound a
ub' = case (PgBoundType
ut, Maybe a
ub) of (PgBoundType
_, Maybe a
Nothing) -> forall a. RangeBound a
Pg.PosInfinity
                             (PgBoundType
Inclusive, Just a
a) -> forall a. a -> RangeBound a
Pg.Inclusive a
a
                             (PgBoundType
Exclusive, Just a
a) -> forall a. a -> RangeBound a
Pg.Exclusive a
a

instance HasSqlEqualityCheck Postgres (PgRange n a)
instance HasSqlQuantifiedEqualityCheck Postgres (PgRange n a)

instance (Pg.FromField a, Typeable a, Typeable n, Ord a) => FromBackendRow Postgres (PgRange n a)
instance (HasSqlValueSyntax PgValueSyntax a, PgIsRange n) =>
  HasSqlValueSyntax PgValueSyntax (PgRange n a) where
  sqlValueSyntax :: PgRange n a -> PgValueSyntax
sqlValueSyntax PgRange n a
PgEmptyRange =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$
    ByteString -> PgSyntax
emit ByteString
"'empty'::" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
escapeIdentifier (forall {k} (n :: k). PgIsRange n => ByteString
rangeName @n)
  sqlValueSyntax (PgRange (PgRangeBound PgBoundType
lbt Maybe a
mlBound) (PgRangeBound PgBoundType
rbt Maybe a
muBound)) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$
    ByteString -> PgSyntax
escapeIdentifier (forall {k} (n :: k). PgIsRange n => ByteString
rangeName @n) forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgSyntax -> [PgSyntax] -> PgSyntax
pgSepBy (ByteString -> PgSyntax
emit ByteString
", ") [PgSyntax
lb, PgSyntax
rb, PgSyntax
bounds])
    where
      lb :: PgSyntax
lb = Maybe a -> PgSyntax
sqlValueSyntax' Maybe a
mlBound
      rb :: PgSyntax
rb = Maybe a -> PgSyntax
sqlValueSyntax' Maybe a
muBound
      bounds :: PgSyntax
bounds = ByteString -> PgSyntax
emit ByteString
"'" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit (PgBoundType -> ByteString
lBound PgBoundType
lbt forall a. Semigroup a => a -> a -> a
<> PgBoundType -> ByteString
uBound PgBoundType
rbt) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"'"
      sqlValueSyntax' :: Maybe a -> PgSyntax
sqlValueSyntax' = PgValueSyntax -> PgSyntax
fromPgValue forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall expr ty. HasSqlValueSyntax expr ty => ty -> expr
sqlValueSyntax


binOpDefault :: ByteString
             -> QGenExpr context Postgres s a
             -> QGenExpr context Postgres s b
             -> QGenExpr context Postgres s c
binOpDefault :: forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
symbol (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
r1) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
r2)  = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
symbol forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
r1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
r2)

(-@>-) :: QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s Bool
-@>- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-@>-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"@>"

(-@>) :: QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s a
      -> QGenExpr context Postgres s Bool
-@> :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s Bool
(-@>) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"@>"

(-<@-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
-<@- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-<@-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"<@"

(<@-) :: QGenExpr context Postgres s a
      -> QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s Bool
<@- :: forall context s a n.
QGenExpr context Postgres s a
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(<@-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"<@"

(-&&-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
-&&- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-&&-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"&&"

(-<<-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
-<<- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-<<-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"<<"

(->>-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
->>- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(->>-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
">>"

(-&<-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
-&<- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-&<-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"&<"

(-&>-) :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s Bool
-&>- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(-&>-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"&>"

(--|--) :: QGenExpr context Postgres s (PgRange n a)
        -> QGenExpr context Postgres s (PgRange n a)
        -> QGenExpr context Postgres s Bool
--|-- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
(--|--) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"-|-"

(-+-) :: QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
-+- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
(-+-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"+"

(-*-) :: QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
-*- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
(-*-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"*"

-- | The postgres range operator @-@ .
(-.-) :: QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
      -> QGenExpr context Postgres s (PgRange n a)
-.- :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
(-.-) = forall context s a b c.
ByteString
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s b
-> QGenExpr context Postgres s c
binOpDefault ByteString
"-"

defUnaryFn :: ByteString
           -> QGenExpr context Postgres s a
           -> QGenExpr context Postgres s b
defUnaryFn :: forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
fn (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
s) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
s)
  where
    pgExprFrom :: PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom PgExpressionSyntax
s' = PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
fn forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression PgExpressionSyntax
s' forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

rLower_ :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (Maybe a)
rLower_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (Maybe a)
rLower_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"LOWER"

rUpper_ :: QGenExpr context Postgres s (PgRange n a)
       -> QGenExpr context Postgres s (Maybe a)
rUpper_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (Maybe a)
rUpper_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"UPPER"

isEmpty_ :: QGenExpr context Postgres s (PgRange n a)
         -> QGenExpr context Postgres s Bool
isEmpty_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
isEmpty_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"ISEMPTY"

lowerInc_ :: QGenExpr context Postgres s (PgRange n a)
          -> QGenExpr context Postgres s Bool
lowerInc_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
lowerInc_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"LOWER_INC"

upperInc_ :: QGenExpr context Postgres s (PgRange n a)
          -> QGenExpr context Postgres s Bool
upperInc_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
upperInc_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"UPPER_INC"

lowerInf_ :: QGenExpr context Postgres s (PgRange n a)
          -> QGenExpr context Postgres s Bool
lowerInf_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
lowerInf_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"LOWER_INF"

upperInf_ :: QGenExpr context Postgres s (PgRange n a)
          -> QGenExpr context Postgres s Bool
upperInf_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s Bool
upperInf_ = forall context s a b.
ByteString
-> QGenExpr context Postgres s a -> QGenExpr context Postgres s b
defUnaryFn ByteString
"UPPER_INF"

rangeMerge_ :: QGenExpr context Postgres s (PgRange n a)
            -> QGenExpr context Postgres s (PgRange n a)
            -> QGenExpr context Postgres s (PgRange n a)
rangeMerge_ :: forall context s n a.
QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
-> QGenExpr context Postgres s (PgRange n a)
rangeMerge_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
r1) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
r2) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
r1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
r2)
  where
    pgExprFrom :: PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom PgExpressionSyntax
r1' PgExpressionSyntax
r2' =
      PgSyntax -> PgExpressionSyntax
PgExpressionSyntax
      (ByteString -> PgSyntax
emit ByteString
"RANGE_MERGE(" forall a. Semigroup a => a -> a -> a
<>
       PgExpressionSyntax -> PgSyntax
fromPgExpression PgExpressionSyntax
r1' forall a. Semigroup a => a -> a -> a
<>
       ByteString -> PgSyntax
emit ByteString
", " forall a. Semigroup a => a -> a -> a
<>
       PgExpressionSyntax -> PgSyntax
fromPgExpression PgExpressionSyntax
r2' forall a. Semigroup a => a -> a -> a
<>
       ByteString -> PgSyntax
emit ByteString
")")

range_ :: forall n a context s. PgIsRange n
       => PgBoundType -- ^ Lower bound type
       -> PgBoundType -- ^ Upper bound type
       -> QGenExpr context Postgres s (Maybe a) -- ^. Lower bound value
       -> QGenExpr context Postgres s (Maybe a) -- ^. Upper bound value
       -> QGenExpr context Postgres s (PgRange n a)
range_ :: forall n a context s.
PgIsRange n =>
PgBoundType
-> PgBoundType
-> QGenExpr context Postgres s (Maybe a)
-> QGenExpr context Postgres s (Maybe a)
-> QGenExpr context Postgres s (PgRange n a)
range_ PgBoundType
lbt PgBoundType
ubt (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
e1) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
e2) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
e1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
e2)
  where
    bounds :: PgSyntax
bounds = ByteString -> PgSyntax
emit ByteString
"'" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit (PgBoundType -> ByteString
lBound PgBoundType
lbt forall a. Semigroup a => a -> a -> a
<> PgBoundType -> ByteString
uBound PgBoundType
ubt) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"'"
    pgExprFrom :: PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgExprFrom PgExpressionSyntax
e1' PgExpressionSyntax
e2' =
      PgSyntax -> PgExpressionSyntax
PgExpressionSyntax
      (ByteString -> PgSyntax
escapeIdentifier (forall {k} (n :: k). PgIsRange n => ByteString
rangeName @n) forall a. Semigroup a => a -> a -> a
<>
       PgSyntax -> PgSyntax
pgParens (PgSyntax -> [PgSyntax] -> PgSyntax
pgSepBy (ByteString -> PgSyntax
emit ByteString
", ") [PgExpressionSyntax -> PgSyntax
fromPgExpression PgExpressionSyntax
e1', PgExpressionSyntax -> PgSyntax
fromPgExpression PgExpressionSyntax
e2', PgSyntax
bounds]))

-- ** JSON

-- | The Postgres @JSON@ type, which stores textual values that represent JSON
-- objects. The type parameter indicates the Haskell type which the JSON
-- encodes. This type must be a member of 'FromJSON' and 'ToJSON' in order for
-- deserialization and serialization to work as expected.
--
-- The 'defaultMigratableDbSettings' function automatically assigns the postgres
-- @JSON@ type to fields with this type.
newtype PgJSON a = PgJSON a
  deriving ( Int -> PgJSON a -> ShowS
forall a. Show a => Int -> PgJSON a -> ShowS
forall a. Show a => [PgJSON a] -> ShowS
forall a. Show a => PgJSON a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgJSON a] -> ShowS
$cshowList :: forall a. Show a => [PgJSON a] -> ShowS
show :: PgJSON a -> String
$cshow :: forall a. Show a => PgJSON a -> String
showsPrec :: Int -> PgJSON a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PgJSON a -> ShowS
Show, PgJSON a -> PgJSON a -> Bool
forall a. Eq a => PgJSON a -> PgJSON a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgJSON a -> PgJSON a -> Bool
$c/= :: forall a. Eq a => PgJSON a -> PgJSON a -> Bool
== :: PgJSON a -> PgJSON a -> Bool
$c== :: forall a. Eq a => PgJSON a -> PgJSON a -> Bool
Eq, PgJSON a -> PgJSON a -> Bool
PgJSON a -> PgJSON a -> Ordering
PgJSON a -> PgJSON a -> PgJSON a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (PgJSON a)
forall a. Ord a => PgJSON a -> PgJSON a -> Bool
forall a. Ord a => PgJSON a -> PgJSON a -> Ordering
forall a. Ord a => PgJSON a -> PgJSON a -> PgJSON a
min :: PgJSON a -> PgJSON a -> PgJSON a
$cmin :: forall a. Ord a => PgJSON a -> PgJSON a -> PgJSON a
max :: PgJSON a -> PgJSON a -> PgJSON a
$cmax :: forall a. Ord a => PgJSON a -> PgJSON a -> PgJSON a
>= :: PgJSON a -> PgJSON a -> Bool
$c>= :: forall a. Ord a => PgJSON a -> PgJSON a -> Bool
> :: PgJSON a -> PgJSON a -> Bool
$c> :: forall a. Ord a => PgJSON a -> PgJSON a -> Bool
<= :: PgJSON a -> PgJSON a -> Bool
$c<= :: forall a. Ord a => PgJSON a -> PgJSON a -> Bool
< :: PgJSON a -> PgJSON a -> Bool
$c< :: forall a. Ord a => PgJSON a -> PgJSON a -> Bool
compare :: PgJSON a -> PgJSON a -> Ordering
$ccompare :: forall a. Ord a => PgJSON a -> PgJSON a -> Ordering
Ord, Int -> PgJSON a -> Int
PgJSON a -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall {a}. Hashable a => Eq (PgJSON a)
forall a. Hashable a => Int -> PgJSON a -> Int
forall a. Hashable a => PgJSON a -> Int
hash :: PgJSON a -> Int
$chash :: forall a. Hashable a => PgJSON a -> Int
hashWithSalt :: Int -> PgJSON a -> Int
$chashWithSalt :: forall a. Hashable a => Int -> PgJSON a -> Int
Hashable, PgJSON a
[PgJSON a] -> PgJSON a
PgJSON a -> PgJSON a -> PgJSON a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall {a}. Monoid a => Semigroup (PgJSON a)
forall a. Monoid a => PgJSON a
forall a. Monoid a => [PgJSON a] -> PgJSON a
forall a. Monoid a => PgJSON a -> PgJSON a -> PgJSON a
mconcat :: [PgJSON a] -> PgJSON a
$cmconcat :: forall a. Monoid a => [PgJSON a] -> PgJSON a
mappend :: PgJSON a -> PgJSON a -> PgJSON a
$cmappend :: forall a. Monoid a => PgJSON a -> PgJSON a -> PgJSON a
mempty :: PgJSON a
$cmempty :: forall a. Monoid a => PgJSON a
Monoid, NonEmpty (PgJSON a) -> PgJSON a
PgJSON a -> PgJSON a -> PgJSON a
forall b. Integral b => b -> PgJSON a -> PgJSON a
forall a. Semigroup a => NonEmpty (PgJSON a) -> PgJSON a
forall a. Semigroup a => PgJSON a -> PgJSON a -> PgJSON a
forall a b. (Semigroup a, Integral b) => b -> PgJSON a -> PgJSON a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> PgJSON a -> PgJSON a
$cstimes :: forall a b. (Semigroup a, Integral b) => b -> PgJSON a -> PgJSON a
sconcat :: NonEmpty (PgJSON a) -> PgJSON a
$csconcat :: forall a. Semigroup a => NonEmpty (PgJSON a) -> PgJSON a
<> :: PgJSON a -> PgJSON a -> PgJSON a
$c<> :: forall a. Semigroup a => PgJSON a -> PgJSON a -> PgJSON a
Semigroup )

instance HasSqlEqualityCheck Postgres (PgJSON a)
instance HasSqlQuantifiedEqualityCheck Postgres (PgJSON a)

instance (Typeable x, FromJSON x) => Pg.FromField (PgJSON x) where
  fromField :: FieldParser (PgJSON x)
fromField Field
field Maybe ByteString
d =
    if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
Pg.json
    then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
    else case forall a. FromJSON a => ByteString -> Either String a
eitherDecodeStrict forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
d of
           Maybe (Either String x)
Nothing -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""
           Just (Left String
e) -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.ConversionFailed Field
field String
e
           Just (Right x
d') -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> PgJSON a
PgJSON x
d')

instance (Typeable a, FromJSON a) => FromBackendRow Postgres (PgJSON a)
instance ToJSON a => HasSqlValueSyntax PgValueSyntax (PgJSON a) where
  sqlValueSyntax :: PgJSON a -> PgValueSyntax
sqlValueSyntax (PgJSON a
a) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$
    ByteString -> PgSyntax
emit ByteString
"'" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
escapeString (ByteString -> ByteString
BL.toStrict (forall a. ToJSON a => a -> ByteString
encode a
a)) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"'::json"

-- | The Postgres @JSONB@ type, which stores JSON-encoded data in a
-- postgres-specific binary format. Like 'PgJSON', the type parameter indicates
-- the Haskell type which the JSON encodes.
--
-- Fields with this type are automatically given the Postgres @JSONB@ type
newtype PgJSONB a = PgJSONB a
  deriving ( Int -> PgJSONB a -> ShowS
forall a. Show a => Int -> PgJSONB a -> ShowS
forall a. Show a => [PgJSONB a] -> ShowS
forall a. Show a => PgJSONB a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgJSONB a] -> ShowS
$cshowList :: forall a. Show a => [PgJSONB a] -> ShowS
show :: PgJSONB a -> String
$cshow :: forall a. Show a => PgJSONB a -> String
showsPrec :: Int -> PgJSONB a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PgJSONB a -> ShowS
Show, PgJSONB a -> PgJSONB a -> Bool
forall a. Eq a => PgJSONB a -> PgJSONB a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgJSONB a -> PgJSONB a -> Bool
$c/= :: forall a. Eq a => PgJSONB a -> PgJSONB a -> Bool
== :: PgJSONB a -> PgJSONB a -> Bool
$c== :: forall a. Eq a => PgJSONB a -> PgJSONB a -> Bool
Eq, PgJSONB a -> PgJSONB a -> Bool
PgJSONB a -> PgJSONB a -> Ordering
PgJSONB a -> PgJSONB a -> PgJSONB a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (PgJSONB a)
forall a. Ord a => PgJSONB a -> PgJSONB a -> Bool
forall a. Ord a => PgJSONB a -> PgJSONB a -> Ordering
forall a. Ord a => PgJSONB a -> PgJSONB a -> PgJSONB a
min :: PgJSONB a -> PgJSONB a -> PgJSONB a
$cmin :: forall a. Ord a => PgJSONB a -> PgJSONB a -> PgJSONB a
max :: PgJSONB a -> PgJSONB a -> PgJSONB a
$cmax :: forall a. Ord a => PgJSONB a -> PgJSONB a -> PgJSONB a
>= :: PgJSONB a -> PgJSONB a -> Bool
$c>= :: forall a. Ord a => PgJSONB a -> PgJSONB a -> Bool
> :: PgJSONB a -> PgJSONB a -> Bool
$c> :: forall a. Ord a => PgJSONB a -> PgJSONB a -> Bool
<= :: PgJSONB a -> PgJSONB a -> Bool
$c<= :: forall a. Ord a => PgJSONB a -> PgJSONB a -> Bool
< :: PgJSONB a -> PgJSONB a -> Bool
$c< :: forall a. Ord a => PgJSONB a -> PgJSONB a -> Bool
compare :: PgJSONB a -> PgJSONB a -> Ordering
$ccompare :: forall a. Ord a => PgJSONB a -> PgJSONB a -> Ordering
Ord, Int -> PgJSONB a -> Int
PgJSONB a -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall {a}. Hashable a => Eq (PgJSONB a)
forall a. Hashable a => Int -> PgJSONB a -> Int
forall a. Hashable a => PgJSONB a -> Int
hash :: PgJSONB a -> Int
$chash :: forall a. Hashable a => PgJSONB a -> Int
hashWithSalt :: Int -> PgJSONB a -> Int
$chashWithSalt :: forall a. Hashable a => Int -> PgJSONB a -> Int
Hashable, PgJSONB a
[PgJSONB a] -> PgJSONB a
PgJSONB a -> PgJSONB a -> PgJSONB a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall {a}. Monoid a => Semigroup (PgJSONB a)
forall a. Monoid a => PgJSONB a
forall a. Monoid a => [PgJSONB a] -> PgJSONB a
forall a. Monoid a => PgJSONB a -> PgJSONB a -> PgJSONB a
mconcat :: [PgJSONB a] -> PgJSONB a
$cmconcat :: forall a. Monoid a => [PgJSONB a] -> PgJSONB a
mappend :: PgJSONB a -> PgJSONB a -> PgJSONB a
$cmappend :: forall a. Monoid a => PgJSONB a -> PgJSONB a -> PgJSONB a
mempty :: PgJSONB a
$cmempty :: forall a. Monoid a => PgJSONB a
Monoid, NonEmpty (PgJSONB a) -> PgJSONB a
PgJSONB a -> PgJSONB a -> PgJSONB a
forall b. Integral b => b -> PgJSONB a -> PgJSONB a
forall a. Semigroup a => NonEmpty (PgJSONB a) -> PgJSONB a
forall a. Semigroup a => PgJSONB a -> PgJSONB a -> PgJSONB a
forall a b.
(Semigroup a, Integral b) =>
b -> PgJSONB a -> PgJSONB a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> PgJSONB a -> PgJSONB a
$cstimes :: forall a b.
(Semigroup a, Integral b) =>
b -> PgJSONB a -> PgJSONB a
sconcat :: NonEmpty (PgJSONB a) -> PgJSONB a
$csconcat :: forall a. Semigroup a => NonEmpty (PgJSONB a) -> PgJSONB a
<> :: PgJSONB a -> PgJSONB a -> PgJSONB a
$c<> :: forall a. Semigroup a => PgJSONB a -> PgJSONB a -> PgJSONB a
Semigroup )

instance HasSqlEqualityCheck Postgres (PgJSONB a)
instance HasSqlQuantifiedEqualityCheck Postgres (PgJSONB a)

instance (Typeable x, FromJSON x) => Pg.FromField (PgJSONB x) where
  fromField :: FieldParser (PgJSONB x)
fromField Field
field Maybe ByteString
d =
    if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
Pg.jsonb
    then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
    else case forall a. FromJSON a => ByteString -> Either String a
eitherDecodeStrict forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
d of
           Maybe (Either String x)
Nothing -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""
           Just (Left String
e) -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.ConversionFailed Field
field String
e
           Just (Right x
d') -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> PgJSONB a
PgJSONB x
d')

instance (Typeable a, FromJSON a) => FromBackendRow Postgres (PgJSONB a)
instance ToJSON a => HasSqlValueSyntax PgValueSyntax (PgJSONB a) where
  sqlValueSyntax :: PgJSONB a -> PgValueSyntax
sqlValueSyntax (PgJSONB a
a) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$
    ByteString -> PgSyntax
emit ByteString
"'" forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
escapeString (ByteString -> ByteString
BL.toStrict (forall a. ToJSON a => a -> ByteString
encode a
a)) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
"'::jsonb"

-- | Key-value pair, used as output of 'pgJsonEachText' and 'pgJsonEach'
data PgJSONEach valType f
  = PgJSONEach
  { forall valType (f :: * -> *). PgJSONEach valType f -> C f Text
pgJsonEachKey :: C f T.Text
  , forall valType (f :: * -> *). PgJSONEach valType f -> C f valType
pgJsonEachValue :: C f valType
  } deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall valType (f :: * -> *) x.
Rep (PgJSONEach valType f) x -> PgJSONEach valType f
forall valType (f :: * -> *) x.
PgJSONEach valType f -> Rep (PgJSONEach valType f) x
$cto :: forall valType (f :: * -> *) x.
Rep (PgJSONEach valType f) x -> PgJSONEach valType f
$cfrom :: forall valType (f :: * -> *) x.
PgJSONEach valType f -> Rep (PgJSONEach valType f) x
Generic
instance Beamable (PgJSONEach valType)

-- | Output row of 'pgJsonKeys'
data PgJSONKey f = PgJSONKey { forall (f :: * -> *). PgJSONKey f -> C f Text
pgJsonKey :: C f T.Text }
  deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (f :: * -> *) x. Rep (PgJSONKey f) x -> PgJSONKey f
forall (f :: * -> *) x. PgJSONKey f -> Rep (PgJSONKey f) x
$cto :: forall (f :: * -> *) x. Rep (PgJSONKey f) x -> PgJSONKey f
$cfrom :: forall (f :: * -> *) x. PgJSONKey f -> Rep (PgJSONKey f) x
Generic
instance Beamable PgJSONKey

-- | Output row of 'pgJsonArrayElements' and 'pgJsonArrayElementsText'
data PgJSONElement a f = PgJSONElement { forall a (f :: * -> *). PgJSONElement a f -> C f a
pgJsonElement :: C f a }
  deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a (f :: * -> *) x.
Rep (PgJSONElement a f) x -> PgJSONElement a f
forall a (f :: * -> *) x.
PgJSONElement a f -> Rep (PgJSONElement a f) x
$cto :: forall a (f :: * -> *) x.
Rep (PgJSONElement a f) x -> PgJSONElement a f
$cfrom :: forall a (f :: * -> *) x.
PgJSONElement a f -> Rep (PgJSONElement a f) x
Generic
instance Beamable (PgJSONElement a)

-- | Postgres provides separate @json_@ and @jsonb_@ functions. However, we know
-- what we're dealing with based on the type of data, so we can be less obtuse.
--
-- For more information on how these functions behave, see the Postgres manual
-- section on
-- <https://www.postgresql.org/docs/current/static/functions-json.html JSON>.
--
class IsPgJSON (json :: * -> *) where
  -- | The @json_each@ or @jsonb_each@ function. Values returned as @json@ or
  -- @jsonb@ respectively. Use 'pgUnnest' to join against the result
  pgJsonEach     :: QGenExpr ctxt Postgres s (json a)
                 -> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach (json Value)))

  -- | Like 'pgJsonEach', but returning text values instead
  pgJsonEachText :: QGenExpr ctxt Postgres s (json a)
                 -> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach T.Text))

  -- | The @json_object_keys@ and @jsonb_object_keys@ function. Use 'pgUnnest'
  -- to join against the result.
  pgJsonKeys     :: QGenExpr ctxt Postgres s (json a)
                 -> QGenExpr ctxt Postgres s (PgSetOf PgJSONKey)

  -- | The @json_array_elements@ and @jsonb_array_elements@ function. Use
  -- 'pgUnnest' to join against the result
  pgJsonArrayElements :: QGenExpr ctxt Postgres s (json a)
                      -> QGenExpr ctxt Postgres s (PgSetOf (PgJSONElement (json Value)))

  -- | Like 'pgJsonArrayElements', but returning the values as 'T.Text'
  pgJsonArrayElementsText :: QGenExpr ctxt Postgres s (json a)
                          -> QGenExpr ctxt Postgres s (PgSetOf (PgJSONElement T.Text))
--  pgJsonToRecord
--  pgJsonToRecordSet

  -- | The @json_typeof@ or @jsonb_typeof@ function
  pgJsonTypeOf :: QGenExpr ctxt Postgres s (json a) -> QGenExpr ctxt Postgres s T.Text

  -- | The @json_strip_nulls@ or @jsonb_strip_nulls@ function.
  pgJsonStripNulls :: QGenExpr ctxt Postgres s (json a)
                   -> QGenExpr ctxt Postgres s (json b)

  -- | The @json_agg@ or @jsonb_agg@ aggregate.
  pgJsonAgg :: QExpr Postgres s a -> QAgg Postgres s (json a)

  -- | The @json_object_agg@ or @jsonb_object_agg@. The first argument gives the
  -- key source and the second the corresponding values.
  pgJsonObjectAgg :: QExpr Postgres s key -> QExpr Postgres s value
                  -> QAgg Postgres s (json a)

instance IsPgJSON PgJSON where
  pgJsonEach :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach (PgJSON Value)))
pgJsonEach (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_each") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonEachText :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach Text))
pgJsonEachText (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_each_text") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonKeys :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s (PgSetOf PgJSONKey)
pgJsonKeys (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_object_keys") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonArrayElements :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr
     ctxt Postgres s (PgSetOf (PgJSONElement (PgJSON Value)))
pgJsonArrayElements (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_array_elements") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonArrayElementsText :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONElement Text))
pgJsonArrayElementsText (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_array_elements_text") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonTypeOf :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s Text
pgJsonTypeOf (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_typeof") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonStripNulls :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSON a)
-> QGenExpr ctxt Postgres s (PgJSON b)
pgJsonStripNulls (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_strip_nulls") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonAgg :: forall s a. QExpr Postgres s a -> QAgg Postgres s (PgJSON a)
pgJsonAgg (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_agg") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonObjectAgg :: forall s key value a.
QExpr Postgres s key
-> QExpr Postgres s value -> QAgg Postgres s (PgJSON a)
pgJsonObjectAgg (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
keys) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
values) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"json_object_agg") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$
    forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$ [ PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
keys, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", ")
                , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
values ]

instance IsPgJSON PgJSONB where
  pgJsonEach :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach (PgJSONB Value)))
pgJsonEach (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_each") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonEachText :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONEach Text))
pgJsonEachText (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_each_text") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonKeys :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgSetOf PgJSONKey)
pgJsonKeys (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_object_keys") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonArrayElements :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr
     ctxt Postgres s (PgSetOf (PgJSONElement (PgJSONB Value)))
pgJsonArrayElements (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_array_elements") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonArrayElementsText :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgSetOf (PgJSONElement Text))
pgJsonArrayElementsText (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_array_elements_text") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonTypeOf :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s Text
pgJsonTypeOf (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_typeof") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonStripNulls :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgJSONB b)
pgJsonStripNulls (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_strip_nulls") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonAgg :: forall s a. QExpr Postgres s a -> QAgg Postgres s (PgJSONB a)
pgJsonAgg (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_agg") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgExpressionSyntax -> PgSyntax
fromPgExpression) Text -> BeamSqlBackendExpressionSyntax Postgres
a

  pgJsonObjectAgg :: forall s key value a.
QExpr Postgres s key
-> QExpr Postgres s value -> QAgg Postgres s (PgJSONB a)
pgJsonObjectAgg (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
keys) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
values) =
    forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_object_agg") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$
    forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$ [ PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
keys, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", ")
                , PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
values ]

-- | Postgres @&#x40;>@ and @<&#x40;@ operators for JSON. Return true if the
-- json object pointed to by the arrow is completely contained in the other. See
-- the Postgres documentation for more in formation on what this means.
(@>), (<@)
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s (PgJSONB b)
  -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a @> :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgJSONB b)
-> QGenExpr ctxt Postgres s Bool
@> QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"@>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a <@ :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (PgJSONB b)
-> QGenExpr ctxt Postgres s Bool
<@ QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"<@" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Access a JSON array by index. Corresponds to the Postgres @->@ operator.
-- See '(->$)' for the corresponding operator for object access.
(->#) :: IsPgJSON json
      => QGenExpr ctxt Postgres s (json a)
      -> QGenExpr ctxt Postgres s Int32
      -> QGenExpr ctxt Postgres s (json b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a -># :: forall (json :: * -> *) ctxt s a b.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s Int32
-> QGenExpr ctxt Postgres s (json b)
-># QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"->" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Acces a JSON object by key. Corresponds to the Postgres @->@ operator. See
-- '(->#)' for the corresponding operator for arrays.
(->$) :: IsPgJSON json
      => QGenExpr ctxt Postgres s (json a)
      -> QGenExpr ctxt Postgres s T.Text
      -> QGenExpr ctxt Postgres s (json b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ->$ :: forall (json :: * -> *) ctxt s a b.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s Text
-> QGenExpr ctxt Postgres s (json b)
->$ QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"->" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Access a JSON array by index, returning the embedded object as a string.
-- Corresponds to the Postgres @->>@ operator. See '(->>$)' for the
-- corresponding operator on objects.
(->>#) :: IsPgJSON json
       => QGenExpr ctxt Postgres s (json a)
       -> QGenExpr ctxt Postgres s Int32
       -> QGenExpr ctxt Postgres s T.Text
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ->># :: forall (json :: * -> *) ctxt s a.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s Int32 -> QGenExpr ctxt Postgres s Text
->># QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"->>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Access a JSON object by key, returning the embedded object as a string.
-- Corresponds to the Postgres @->>@ operator. See '(->>#)' for the
-- corresponding operator on arrays.
(->>$) :: IsPgJSON json
       => QGenExpr ctxt Postgres s (json a)
       -> QGenExpr ctxt Postgres s T.Text
       -> QGenExpr ctxt Postgres s T.Text
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ->>$ :: forall (json :: * -> *) ctxt s a.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s Text -> QGenExpr ctxt Postgres s Text
->>$ QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"->>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Access a deeply nested JSON object. The first argument is the JSON object
-- to look within, the second is the path of keys from the first argument to the
-- target. Returns the result as a new json value. Note that the postgres
-- function allows etiher string keys or integer indices, but this function only
-- allows string keys. PRs to improve this functionality are welcome.
(#>) :: IsPgJSON json
     => QGenExpr ctxt Postgres s (json a)
     -> QGenExpr ctxt Postgres s (V.Vector T.Text)
     -> QGenExpr ctxt Postgres s (json b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a #> :: forall (json :: * -> *) ctxt s a b.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s (json b)
#> QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"#>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Like '(#>)' but returns the result as a string.
(#>>) :: IsPgJSON json
      => QGenExpr ctxt Postgres s (json a)
      -> QGenExpr ctxt Postgres s (V.Vector T.Text)
      -> QGenExpr ctxt Postgres s T.Text
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a #>> :: forall (json :: * -> *) ctxt s a.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s Text
#>> QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"#>>" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @?@ operator. Checks if the given string exists as top-level key
-- of the json object.
(?)
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s T.Text
  -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ? :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s Text -> QGenExpr ctxt Postgres s Bool
? QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"?" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @?|@ and @?&@ operators. Check if any or all of the given strings
-- exist as top-level keys of the json object respectively.
(?|), (?&)
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s (V.Vector T.Text)
  -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ?| :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s Bool
?| QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"?|" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a ?& :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s Bool
?& QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"?&" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @-@ operator on json objects. Returns the supplied json object
-- with the supplied key deleted. See 'withoutIdx' for the corresponding
-- operator on arrays.
withoutKey
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s T.Text
  -> QGenExpr ctxt Postgres s (PgJSONB b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a withoutKey :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s Text
-> QGenExpr ctxt Postgres s (PgJSONB b)
`withoutKey` QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"-" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @-@ operator on json arrays. See 'withoutKey' for the
-- corresponding operator on objects.
withoutIdx
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s Int32
  -> QGenExpr ctxt Postgres s (PgJSONB b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a withoutIdx :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s Int32
-> QGenExpr ctxt Postgres s (PgJSONB b)
`withoutIdx` QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"-" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @#-@ operator. Removes all the keys specificied from the JSON
-- object and returns the result.
withoutKeys
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s (V.Vector T.Text)
  -> QGenExpr ctxt Postgres s (PgJSONB b)
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a withoutKeys :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s (PgJSONB b)
`withoutKeys` QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"#-" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @json_array_length@ function. The supplied json object should be
-- an array, but this isn't checked at compile-time.
pgJsonArrayLength :: IsPgJSON json => QGenExpr ctxt Postgres s (json a)
                  -> QGenExpr ctxt Postgres s Int32
pgJsonArrayLength :: forall (json :: * -> *) ctxt s a.
IsPgJSON json =>
QGenExpr ctxt Postgres s (json a) -> QGenExpr ctxt Postgres s Int32
pgJsonArrayLength (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ \Text
tbl ->
  PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"json_array_length(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
a Text
tbl) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

-- | Postgres @array_to_json@ function.
pgArrayToJson
  :: QGenExpr ctxt Postgres s (V.Vector e)
  -> QGenExpr ctxt Postgres s (PgJSON a)
pgArrayToJson :: forall ctxt s e a.
QGenExpr ctxt Postgres s (Vector e)
-> QGenExpr ctxt Postgres s (PgJSON a)
pgArrayToJson (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"array_to_json") forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  PgExpressionSyntax -> PgSyntax
fromPgExpression

-- | The postgres @jsonb_set@ function. 'pgJsonUpdate' expects the value
-- specified by the path in the second argument to exist. If it does not, the
-- first argument is not modified. 'pgJsonbSet' will create any intermediate
-- objects necessary. This corresponds to the @create_missing@ argument of
-- @jsonb_set@ being set to false or true respectively.
pgJsonbUpdate, pgJsonbSet
  :: QGenExpr ctxt Postgres s (PgJSONB a)
  -> QGenExpr ctxt Postgres s (V.Vector T.Text)
  -> QGenExpr ctxt Postgres s (PgJSONB b)
  -> QGenExpr ctxt Postgres s (PgJSONB a)
pgJsonbUpdate :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s (PgJSONB b)
-> QGenExpr ctxt Postgres s (PgJSONB a)
pgJsonbUpdate (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
path) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
newVal) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_set") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$
  [ PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", "), PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
path, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", "), PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
newVal ]
pgJsonbSet :: forall ctxt s a b.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s (Vector Text)
-> QGenExpr ctxt Postgres s (PgJSONB b)
-> QGenExpr ctxt Postgres s (PgJSONB a)
pgJsonbSet (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
path) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
newVal) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => a -> a -> a
mappend (ByteString -> PgSyntax
emit ByteString
"jsonb_set") forall b c a. (b -> c) -> (a -> b) -> a -> c
. PgSyntax -> PgSyntax
pgParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat) forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall a b. (a -> b) -> a -> b
$
  [ PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", "), PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
path, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", "), PgExpressionSyntax -> PgSyntax
fromPgExpression forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
newVal, forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgSyntax
emit ByteString
", true") ]

-- | Postgres @jsonb_pretty@ function
pgJsonbPretty :: QGenExpr ctxt Postgres s (PgJSONB a)
              -> QGenExpr ctxt Postgres s T.Text
pgJsonbPretty :: forall ctxt s a.
QGenExpr ctxt Postgres s (PgJSONB a)
-> QGenExpr ctxt Postgres s Text
pgJsonbPretty (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
tbl -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax (ByteString -> PgSyntax
emit ByteString
"jsonb_pretty" forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
a Text
tbl))))

-- ** Postgresql aggregates

-- | An aggregate that adds each value to the resulting array. See 'pgArrayOver'
-- if you want to specify a quantifier. Corresponds to the Postgres @ARRAY_AGG@
-- function.
pgArrayAgg :: QExpr Postgres s a
           -> QAgg Postgres s (V.Vector a)
pgArrayAgg :: forall s a. QExpr Postgres s a -> QAgg Postgres s (Vector a)
pgArrayAgg = forall s a.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s a -> QAgg Postgres s (Vector a)
pgArrayAggOver forall s. IsSql92AggregationSetQuantifierSyntax s => Maybe s
allInGroup_

-- | Postgres @ARRAY_AGG@ with an explicit quantifier. Includes each row that
-- meets the quantification criteria in the result.
pgArrayAggOver :: Maybe PgAggregationSetQuantifierSyntax
               -> QExpr Postgres s a
               -> QAgg Postgres s (V.Vector a)
pgArrayAggOver :: forall s a.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s a -> QAgg Postgres s (Vector a)
pgArrayAggOver Maybe PgAggregationSetQuantifierSyntax
quantifier (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ \Text
tbl ->
  PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
    ByteString -> PgSyntax
emit ByteString
"array_agg" forall a. Semigroup a => a -> a -> a
<>
    PgSyntax -> PgSyntax
pgParens ( forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty (\PgAggregationSetQuantifierSyntax
q -> PgAggregationSetQuantifierSyntax -> PgSyntax
fromPgAggregationSetQuantifier PgAggregationSetQuantifierSyntax
q forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
" ") Maybe PgAggregationSetQuantifierSyntax
quantifier forall a. Semigroup a => a -> a -> a
<>
               PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
a Text
tbl))

-- | Postgres @bool_or@ aggregate. Returns true if any of the rows are true.
pgBoolOr :: QExpr Postgres s a
         -> QAgg Postgres s (Maybe Bool)
pgBoolOr :: forall s a. QExpr Postgres s a -> QAgg Postgres s (Maybe Bool)
pgBoolOr (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ \Text
tbl -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
  ByteString -> PgSyntax
emit ByteString
"bool_or" forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
a Text
tbl))

-- | Postgres @bool_and@ aggregate. Returns false unless every row is true.
pgBoolAnd :: QExpr Postgres s a
          -> QAgg Postgres s (Maybe Bool)
pgBoolAnd :: forall s a. QExpr Postgres s a -> QAgg Postgres s (Maybe Bool)
pgBoolAnd (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ \Text
tbl -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
  ByteString -> PgSyntax
emit ByteString
"bool_and" forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
a Text
tbl))

-- *** String aggregations

-- | Joins the string value in each row of the first argument, using the second
-- argument as a delimiter. See 'pgStringAggOver' if you want to provide
-- explicit quantification.
pgStringAgg :: BeamSqlBackendIsString Postgres str
            => QExpr Postgres s str
            -> QExpr Postgres s str
            -> QAgg Postgres s (Maybe str)
pgStringAgg :: forall str s.
BeamSqlBackendIsString Postgres str =>
QExpr Postgres s str
-> QExpr Postgres s str -> QAgg Postgres s (Maybe str)
pgStringAgg = forall str s.
BeamSqlBackendIsString Postgres str =>
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s str
-> QExpr Postgres s str
-> QAgg Postgres s (Maybe str)
pgStringAggOver forall s. IsSql92AggregationSetQuantifierSyntax s => Maybe s
allInGroup_

-- | The Postgres @string_agg@ function, with an explicit quantifier. Joins the
-- values of the second argument using the delimiter given by the third.
pgStringAggOver :: BeamSqlBackendIsString Postgres str
                => Maybe PgAggregationSetQuantifierSyntax
                -> QExpr Postgres s str
                -> QExpr Postgres s str
                -> QAgg Postgres s (Maybe str)
pgStringAggOver :: forall str s.
BeamSqlBackendIsString Postgres str =>
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s str
-> QExpr Postgres s str
-> QAgg Postgres s (Maybe str)
pgStringAggOver Maybe PgAggregationSetQuantifierSyntax
quantifier (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
delim) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr forall a b. (a -> b) -> a -> b
$ \Text
tbl -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
  ByteString -> PgSyntax
emit ByteString
"string_agg" forall a. Semigroup a => a -> a -> a
<>
  PgSyntax -> PgSyntax
pgParens ( forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty (\PgAggregationSetQuantifierSyntax
q -> PgAggregationSetQuantifierSyntax -> PgSyntax
fromPgAggregationSetQuantifier PgAggregationSetQuantifierSyntax
q forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
" ") Maybe PgAggregationSetQuantifierSyntax
quantifier forall a. Semigroup a => a -> a -> a
<>
             PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
v Text
tbl) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", " forall a. Semigroup a => a -> a -> a
<>
             PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
delim Text
tbl))

-- ** Postgresql SELECT DISTINCT ON

-- | Modify a query to only return rows where the supplied key function returns
-- a unique value. This corresponds to the Postgres @DISTINCT ON@ support.
pgNubBy_ :: ( Projectible Postgres key
            , Projectible Postgres r )
         => (r -> key)
         -> Q Postgres db s r
         -> Q Postgres db s r
pgNubBy_ :: forall key r (db :: (* -> *) -> *) s.
(Projectible Postgres key, Projectible Postgres r) =>
(r -> key) -> Q Postgres db s r -> Q Postgres db s r
pgNubBy_ r -> key
mkKey (Q QM Postgres db s r
q) =
    forall be (db :: (* -> *) -> *) s a. QM be db s a -> Q be db s a
Q forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
liftF forall a b. (a -> b) -> a -> b
$
    forall be r (db :: (* -> *) -> *) s next.
Projectible be r =>
(r -> WithExprContext (BeamSqlBackendSetQuantifierSyntax be))
-> QM be db s r -> (r -> next) -> QF be db s next
QDistinct (\r
r Text
pfx -> [PgExpressionSyntax] -> PgSelectSetQuantifierSyntax
pgSelectSetQuantifierDistinctOn
                            (forall be a.
Projectible be a =>
Proxy be
-> a -> WithExprContext [BeamSqlBackendExpressionSyntax be]
project (forall {k} (t :: k). Proxy t
Proxy @Postgres) (r -> key
mkKey r
r) Text
pfx))
              QM Postgres db s r
q forall a. a -> a
id

-- ** PostgreSql @MONEY@ data type

-- | Postgres @MONEY@ data type. A simple wrapper over 'ByteString', because
--   Postgres money format is locale-dependent, and we don't handle currency
--   symbol placement, digit grouping, or decimal separation.
--
--   The 'pgMoney' function can be used to convert a number to 'PgMoney'.
newtype PgMoney = PgMoney { PgMoney -> ByteString
fromPgMoney :: ByteString }
  deriving (Int -> PgMoney -> ShowS
[PgMoney] -> ShowS
PgMoney -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgMoney] -> ShowS
$cshowList :: [PgMoney] -> ShowS
show :: PgMoney -> String
$cshow :: PgMoney -> String
showsPrec :: Int -> PgMoney -> ShowS
$cshowsPrec :: Int -> PgMoney -> ShowS
Show, ReadPrec [PgMoney]
ReadPrec PgMoney
Int -> ReadS PgMoney
ReadS [PgMoney]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PgMoney]
$creadListPrec :: ReadPrec [PgMoney]
readPrec :: ReadPrec PgMoney
$creadPrec :: ReadPrec PgMoney
readList :: ReadS [PgMoney]
$creadList :: ReadS [PgMoney]
readsPrec :: Int -> ReadS PgMoney
$creadsPrec :: Int -> ReadS PgMoney
Read, PgMoney -> PgMoney -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgMoney -> PgMoney -> Bool
$c/= :: PgMoney -> PgMoney -> Bool
== :: PgMoney -> PgMoney -> Bool
$c== :: PgMoney -> PgMoney -> Bool
Eq, Eq PgMoney
PgMoney -> PgMoney -> Bool
PgMoney -> PgMoney -> Ordering
PgMoney -> PgMoney -> PgMoney
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgMoney -> PgMoney -> PgMoney
$cmin :: PgMoney -> PgMoney -> PgMoney
max :: PgMoney -> PgMoney -> PgMoney
$cmax :: PgMoney -> PgMoney -> PgMoney
>= :: PgMoney -> PgMoney -> Bool
$c>= :: PgMoney -> PgMoney -> Bool
> :: PgMoney -> PgMoney -> Bool
$c> :: PgMoney -> PgMoney -> Bool
<= :: PgMoney -> PgMoney -> Bool
$c<= :: PgMoney -> PgMoney -> Bool
< :: PgMoney -> PgMoney -> Bool
$c< :: PgMoney -> PgMoney -> Bool
compare :: PgMoney -> PgMoney -> Ordering
$ccompare :: PgMoney -> PgMoney -> Ordering
Ord)

instance Pg.FromField PgMoney where
 fromField :: FieldParser PgMoney
fromField Field
field Maybe ByteString
Nothing = forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""
 fromField Field
field (Just ByteString
d) =
   if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
Pg.money
   then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
   else forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> PgMoney
PgMoney ByteString
d)
instance Pg.ToField PgMoney where
  toField :: PgMoney -> Action
toField (PgMoney ByteString
a) = forall a. ToField a => a -> Action
Pg.toField ByteString
a

instance HasSqlEqualityCheck Postgres PgMoney
instance HasSqlQuantifiedEqualityCheck Postgres PgMoney

instance FromBackendRow Postgres PgMoney
instance HasSqlValueSyntax PgValueSyntax PgMoney where
  sqlValueSyntax :: PgMoney -> PgValueSyntax
sqlValueSyntax (PgMoney ByteString
a) = forall expr ty. HasSqlValueSyntax expr ty => ty -> expr
sqlValueSyntax ByteString
a

-- | Attempt to pack a floating point value as a 'PgMoney' value, paying no
-- attention to the locale-dependent currency symbol, digit grouping, or decimal
-- point. This will use the @.@ symbol as the decimal separator.
pgMoney :: Real a => a -> PgMoney
pgMoney :: forall a. Real a => a -> PgMoney
pgMoney a
val = ByteString -> PgMoney
PgMoney (String -> ByteString
BC.pack (FPFormat -> Maybe Int -> Scientific -> String
formatScientific FPFormat
Fixed forall a. Maybe a
Nothing Scientific
exactVal))
  where
    exactVal :: Scientific
exactVal = forall a. Fractional a => Rational -> a
fromRational (forall a. Real a => a -> Rational
toRational a
val) :: Scientific

-- | Multiply a @MONEY@ value by a numeric value. Corresponds to the Postgres
-- @*@ operator.
pgScaleMoney_ :: Num a
              => QGenExpr context Postgres s a
              -> QGenExpr context Postgres s PgMoney
              -> QGenExpr context Postgres s PgMoney
pgScaleMoney_ :: forall a context s.
Num a =>
QGenExpr context Postgres s a
-> QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
pgScaleMoney_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
scale) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"*" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
scale forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
v)

-- | Divide a @MONEY@ value by a numeric value. Corresponds to Postgres @/@
-- where the numerator has type @MONEY@ and the denominator is a number. If you
-- would like to divide two @MONEY@ values and have their units cancel out, use
-- 'pgDivideMoneys_'.
pgDivideMoney_ :: Num a
               => QGenExpr context Postgres s PgMoney
               -> QGenExpr context Postgres s a
               -> QGenExpr context Postgres s PgMoney
pgDivideMoney_ :: forall a context s.
Num a =>
QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s a
-> QGenExpr context Postgres s PgMoney
pgDivideMoney_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
v) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
scale) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"/" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
v forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
scale)

-- | Dividing two @MONEY@ value results in a number. Corresponds to Postgres @/@
-- on two @MONEY@ values. If you would like to divide @MONEY@ by a scalar, use 'pgDivideMoney_'
pgDivideMoneys_ :: Num a
                => QGenExpr context Postgres s PgMoney
                -> QGenExpr context Postgres s PgMoney
                -> QGenExpr context Postgres s a
pgDivideMoneys_ :: forall a context s.
Num a =>
QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s a
pgDivideMoneys_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"/" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | Postgres @+@ and @-@ operators on money.
pgAddMoney_, pgSubtractMoney_
  :: QGenExpr context Postgres s PgMoney
  -> QGenExpr context Postgres s PgMoney
  -> QGenExpr context Postgres s PgMoney
pgAddMoney_ :: forall context s.
QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
pgAddMoney_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"+" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)
pgSubtractMoney_ :: forall context s.
QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
-> QGenExpr context Postgres s PgMoney
pgSubtractMoney_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
b) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"-" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
b)

-- | The Postgres @MONEY@ type can be summed or averaged in an aggregation.
-- These functions provide the quantified aggregations. See 'pgSumMoney_' and
-- 'pgAvgMoney_' for the unquantified versions.
pgSumMoneyOver_, pgAvgMoneyOver_
  :: Maybe PgAggregationSetQuantifierSyntax
  -> QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgSumMoneyOver_ :: forall s.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgSumMoneyOver_ Maybe PgAggregationSetQuantifierSyntax
q (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall expr.
IsSql92AggregationExpressionSyntax expr =>
Maybe (Sql92AggregationSetQuantifierSyntax expr) -> expr -> expr
sumE Maybe PgAggregationSetQuantifierSyntax
q forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a)
pgAvgMoneyOver_ :: forall s.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgAvgMoneyOver_ Maybe PgAggregationSetQuantifierSyntax
q (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
a) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall expr.
IsSql92AggregationExpressionSyntax expr =>
Maybe (Sql92AggregationSetQuantifierSyntax expr) -> expr -> expr
avgE Maybe PgAggregationSetQuantifierSyntax
q forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
a)

-- | The Postgres @MONEY@ type can be summed or averaged in an aggregation. To
-- provide an explicit quantification, see 'pgSumMoneyOver_' and
-- 'pgAvgMoneyOver_'.
pgSumMoney_, pgAvgMoney_ :: QExpr Postgres s PgMoney
                         -> QExpr Postgres s PgMoney
pgSumMoney_ :: forall s. QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgSumMoney_ = forall s.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgSumMoneyOver_ forall s. IsSql92AggregationSetQuantifierSyntax s => Maybe s
allInGroup_
pgAvgMoney_ :: forall s. QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgAvgMoney_ = forall s.
Maybe PgAggregationSetQuantifierSyntax
-> QExpr Postgres s PgMoney -> QExpr Postgres s PgMoney
pgAvgMoneyOver_ forall s. IsSql92AggregationSetQuantifierSyntax s => Maybe s
allInGroup_

-- ** Geometry types

data PgPoint = PgPoint {-# UNPACK #-} !Double {-# UNPACK #-} !Double
  deriving (Int -> PgPoint -> ShowS
[PgPoint] -> ShowS
PgPoint -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgPoint] -> ShowS
$cshowList :: [PgPoint] -> ShowS
show :: PgPoint -> String
$cshow :: PgPoint -> String
showsPrec :: Int -> PgPoint -> ShowS
$cshowsPrec :: Int -> PgPoint -> ShowS
Show, PgPoint -> PgPoint -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgPoint -> PgPoint -> Bool
$c/= :: PgPoint -> PgPoint -> Bool
== :: PgPoint -> PgPoint -> Bool
$c== :: PgPoint -> PgPoint -> Bool
Eq, Eq PgPoint
PgPoint -> PgPoint -> Bool
PgPoint -> PgPoint -> Ordering
PgPoint -> PgPoint -> PgPoint
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgPoint -> PgPoint -> PgPoint
$cmin :: PgPoint -> PgPoint -> PgPoint
max :: PgPoint -> PgPoint -> PgPoint
$cmax :: PgPoint -> PgPoint -> PgPoint
>= :: PgPoint -> PgPoint -> Bool
$c>= :: PgPoint -> PgPoint -> Bool
> :: PgPoint -> PgPoint -> Bool
$c> :: PgPoint -> PgPoint -> Bool
<= :: PgPoint -> PgPoint -> Bool
$c<= :: PgPoint -> PgPoint -> Bool
< :: PgPoint -> PgPoint -> Bool
$c< :: PgPoint -> PgPoint -> Bool
compare :: PgPoint -> PgPoint -> Ordering
$ccompare :: PgPoint -> PgPoint -> Ordering
Ord)

data PgLine = PgLine {-# UNPACK #-} !Double -- A
                     {-# UNPACK #-} !Double -- B
                     {-# UNPACK #-} !Double -- C
  deriving (Int -> PgLine -> ShowS
[PgLine] -> ShowS
PgLine -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgLine] -> ShowS
$cshowList :: [PgLine] -> ShowS
show :: PgLine -> String
$cshow :: PgLine -> String
showsPrec :: Int -> PgLine -> ShowS
$cshowsPrec :: Int -> PgLine -> ShowS
Show, PgLine -> PgLine -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgLine -> PgLine -> Bool
$c/= :: PgLine -> PgLine -> Bool
== :: PgLine -> PgLine -> Bool
$c== :: PgLine -> PgLine -> Bool
Eq, Eq PgLine
PgLine -> PgLine -> Bool
PgLine -> PgLine -> Ordering
PgLine -> PgLine -> PgLine
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgLine -> PgLine -> PgLine
$cmin :: PgLine -> PgLine -> PgLine
max :: PgLine -> PgLine -> PgLine
$cmax :: PgLine -> PgLine -> PgLine
>= :: PgLine -> PgLine -> Bool
$c>= :: PgLine -> PgLine -> Bool
> :: PgLine -> PgLine -> Bool
$c> :: PgLine -> PgLine -> Bool
<= :: PgLine -> PgLine -> Bool
$c<= :: PgLine -> PgLine -> Bool
< :: PgLine -> PgLine -> Bool
$c< :: PgLine -> PgLine -> Bool
compare :: PgLine -> PgLine -> Ordering
$ccompare :: PgLine -> PgLine -> Ordering
Ord)

data PgLineSegment = PgLineSegment {-# UNPACK #-} !PgPoint {-# UNPACK #-} !PgPoint
  deriving (Int -> PgLineSegment -> ShowS
[PgLineSegment] -> ShowS
PgLineSegment -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgLineSegment] -> ShowS
$cshowList :: [PgLineSegment] -> ShowS
show :: PgLineSegment -> String
$cshow :: PgLineSegment -> String
showsPrec :: Int -> PgLineSegment -> ShowS
$cshowsPrec :: Int -> PgLineSegment -> ShowS
Show, PgLineSegment -> PgLineSegment -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgLineSegment -> PgLineSegment -> Bool
$c/= :: PgLineSegment -> PgLineSegment -> Bool
== :: PgLineSegment -> PgLineSegment -> Bool
$c== :: PgLineSegment -> PgLineSegment -> Bool
Eq, Eq PgLineSegment
PgLineSegment -> PgLineSegment -> Bool
PgLineSegment -> PgLineSegment -> Ordering
PgLineSegment -> PgLineSegment -> PgLineSegment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgLineSegment -> PgLineSegment -> PgLineSegment
$cmin :: PgLineSegment -> PgLineSegment -> PgLineSegment
max :: PgLineSegment -> PgLineSegment -> PgLineSegment
$cmax :: PgLineSegment -> PgLineSegment -> PgLineSegment
>= :: PgLineSegment -> PgLineSegment -> Bool
$c>= :: PgLineSegment -> PgLineSegment -> Bool
> :: PgLineSegment -> PgLineSegment -> Bool
$c> :: PgLineSegment -> PgLineSegment -> Bool
<= :: PgLineSegment -> PgLineSegment -> Bool
$c<= :: PgLineSegment -> PgLineSegment -> Bool
< :: PgLineSegment -> PgLineSegment -> Bool
$c< :: PgLineSegment -> PgLineSegment -> Bool
compare :: PgLineSegment -> PgLineSegment -> Ordering
$ccompare :: PgLineSegment -> PgLineSegment -> Ordering
Ord)

data PgBox = PgBox {-# UNPACK #-} !PgPoint {-# UNPACK #-} !PgPoint
  deriving (Int -> PgBox -> ShowS
[PgBox] -> ShowS
PgBox -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgBox] -> ShowS
$cshowList :: [PgBox] -> ShowS
show :: PgBox -> String
$cshow :: PgBox -> String
showsPrec :: Int -> PgBox -> ShowS
$cshowsPrec :: Int -> PgBox -> ShowS
Show)

instance Eq PgBox where
    PgBox PgPoint
a1 PgPoint
b1 == :: PgBox -> PgBox -> Bool
== PgBox PgPoint
a2 PgPoint
b2 =
        (PgPoint
a1 forall a. Eq a => a -> a -> Bool
== PgPoint
a2 Bool -> Bool -> Bool
&& PgPoint
b1 forall a. Eq a => a -> a -> Bool
== PgPoint
b2) Bool -> Bool -> Bool
||
        (PgPoint
a1 forall a. Eq a => a -> a -> Bool
== PgPoint
b2 Bool -> Bool -> Bool
&& PgPoint
b1 forall a. Eq a => a -> a -> Bool
== PgPoint
a2)

data PgPath
  = PgPathOpen   (NE.NonEmpty PgPoint)
  | PgPathClosed (NE.NonEmpty PgPoint)
  deriving (Int -> PgPath -> ShowS
[PgPath] -> ShowS
PgPath -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgPath] -> ShowS
$cshowList :: [PgPath] -> ShowS
show :: PgPath -> String
$cshow :: PgPath -> String
showsPrec :: Int -> PgPath -> ShowS
$cshowsPrec :: Int -> PgPath -> ShowS
Show, PgPath -> PgPath -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgPath -> PgPath -> Bool
$c/= :: PgPath -> PgPath -> Bool
== :: PgPath -> PgPath -> Bool
$c== :: PgPath -> PgPath -> Bool
Eq, Eq PgPath
PgPath -> PgPath -> Bool
PgPath -> PgPath -> Ordering
PgPath -> PgPath -> PgPath
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgPath -> PgPath -> PgPath
$cmin :: PgPath -> PgPath -> PgPath
max :: PgPath -> PgPath -> PgPath
$cmax :: PgPath -> PgPath -> PgPath
>= :: PgPath -> PgPath -> Bool
$c>= :: PgPath -> PgPath -> Bool
> :: PgPath -> PgPath -> Bool
$c> :: PgPath -> PgPath -> Bool
<= :: PgPath -> PgPath -> Bool
$c<= :: PgPath -> PgPath -> Bool
< :: PgPath -> PgPath -> Bool
$c< :: PgPath -> PgPath -> Bool
compare :: PgPath -> PgPath -> Ordering
$ccompare :: PgPath -> PgPath -> Ordering
Ord)

data PgPolygon
  = PgPolygon (NE.NonEmpty PgPoint)
  deriving (Int -> PgPolygon -> ShowS
[PgPolygon] -> ShowS
PgPolygon -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgPolygon] -> ShowS
$cshowList :: [PgPolygon] -> ShowS
show :: PgPolygon -> String
$cshow :: PgPolygon -> String
showsPrec :: Int -> PgPolygon -> ShowS
$cshowsPrec :: Int -> PgPolygon -> ShowS
Show, PgPolygon -> PgPolygon -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgPolygon -> PgPolygon -> Bool
$c/= :: PgPolygon -> PgPolygon -> Bool
== :: PgPolygon -> PgPolygon -> Bool
$c== :: PgPolygon -> PgPolygon -> Bool
Eq, Eq PgPolygon
PgPolygon -> PgPolygon -> Bool
PgPolygon -> PgPolygon -> Ordering
PgPolygon -> PgPolygon -> PgPolygon
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgPolygon -> PgPolygon -> PgPolygon
$cmin :: PgPolygon -> PgPolygon -> PgPolygon
max :: PgPolygon -> PgPolygon -> PgPolygon
$cmax :: PgPolygon -> PgPolygon -> PgPolygon
>= :: PgPolygon -> PgPolygon -> Bool
$c>= :: PgPolygon -> PgPolygon -> Bool
> :: PgPolygon -> PgPolygon -> Bool
$c> :: PgPolygon -> PgPolygon -> Bool
<= :: PgPolygon -> PgPolygon -> Bool
$c<= :: PgPolygon -> PgPolygon -> Bool
< :: PgPolygon -> PgPolygon -> Bool
$c< :: PgPolygon -> PgPolygon -> Bool
compare :: PgPolygon -> PgPolygon -> Ordering
$ccompare :: PgPolygon -> PgPolygon -> Ordering
Ord)

data PgCircle = PgCircle {-# UNPACK #-} !PgPoint {-# UNPACK #-} !Double
  deriving (Int -> PgCircle -> ShowS
[PgCircle] -> ShowS
PgCircle -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgCircle] -> ShowS
$cshowList :: [PgCircle] -> ShowS
show :: PgCircle -> String
$cshow :: PgCircle -> String
showsPrec :: Int -> PgCircle -> ShowS
$cshowsPrec :: Int -> PgCircle -> ShowS
Show, PgCircle -> PgCircle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgCircle -> PgCircle -> Bool
$c/= :: PgCircle -> PgCircle -> Bool
== :: PgCircle -> PgCircle -> Bool
$c== :: PgCircle -> PgCircle -> Bool
Eq, Eq PgCircle
PgCircle -> PgCircle -> Bool
PgCircle -> PgCircle -> Ordering
PgCircle -> PgCircle -> PgCircle
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgCircle -> PgCircle -> PgCircle
$cmin :: PgCircle -> PgCircle -> PgCircle
max :: PgCircle -> PgCircle -> PgCircle
$cmax :: PgCircle -> PgCircle -> PgCircle
>= :: PgCircle -> PgCircle -> Bool
$c>= :: PgCircle -> PgCircle -> Bool
> :: PgCircle -> PgCircle -> Bool
$c> :: PgCircle -> PgCircle -> Bool
<= :: PgCircle -> PgCircle -> Bool
$c<= :: PgCircle -> PgCircle -> Bool
< :: PgCircle -> PgCircle -> Bool
$c< :: PgCircle -> PgCircle -> Bool
compare :: PgCircle -> PgCircle -> Ordering
$ccompare :: PgCircle -> PgCircle -> Ordering
Ord)

encodePgPoint :: PgPoint -> Builder
encodePgPoint :: PgPoint -> Builder
encodePgPoint (PgPoint Double
x Double
y) =
  Builder
"(" forall a. Semigroup a => a -> a -> a
<> Double -> Builder
doubleDec Double
x forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> Double -> Builder
doubleDec Double
y forall a. Semigroup a => a -> a -> a
<> Builder
")"

instance HasSqlValueSyntax PgValueSyntax PgPoint where
  sqlValueSyntax :: PgPoint -> PgValueSyntax
sqlValueSyntax PgPoint
pt =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$ Builder -> PgSyntax
emitBuilder (Builder
"'" forall a. Semigroup a => a -> a -> a
<> PgPoint -> Builder
encodePgPoint PgPoint
pt forall a. Semigroup a => a -> a -> a
<> Builder
"'")
instance HasSqlValueSyntax PgValueSyntax PgLine where
  sqlValueSyntax :: PgLine -> PgValueSyntax
sqlValueSyntax (PgLine Double
a Double
b Double
c) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$ Builder -> PgSyntax
emitBuilder (Builder
"'{" forall a. Semigroup a => a -> a -> a
<> Double -> Builder
doubleDec Double
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> Double -> Builder
doubleDec Double
b forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> Double -> Builder
doubleDec Double
c forall a. Semigroup a => a -> a -> a
<> Builder
"}'")
instance HasSqlValueSyntax PgValueSyntax PgLineSegment where
  sqlValueSyntax :: PgLineSegment -> PgValueSyntax
sqlValueSyntax (PgLineSegment PgPoint
a PgPoint
b) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$ Builder -> PgSyntax
emitBuilder (Builder
"'(" forall a. Semigroup a => a -> a -> a
<> PgPoint -> Builder
encodePgPoint PgPoint
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> PgPoint -> Builder
encodePgPoint PgPoint
b forall a. Semigroup a => a -> a -> a
<> Builder
")'")
instance HasSqlValueSyntax PgValueSyntax PgBox where
  sqlValueSyntax :: PgBox -> PgValueSyntax
sqlValueSyntax (PgBox PgPoint
a PgPoint
b) =
    PgSyntax -> PgValueSyntax
PgValueSyntax forall a b. (a -> b) -> a -> b
$ Builder -> PgSyntax
emitBuilder (Builder
"'(" forall a. Semigroup a => a -> a -> a
<> PgPoint -> Builder
encodePgPoint PgPoint
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> PgPoint -> Builder
encodePgPoint PgPoint
b forall a. Semigroup a => a -> a -> a
<> Builder
")'")

-- TODO Pg polygon and such

-- TODO frombackendrow

instance Pg.FromField PgPoint where
    fromField :: FieldParser PgPoint
fromField Field
field Maybe ByteString
Nothing = forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""
    fromField Field
field (Just ByteString
d) =
        if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
Pg.point
        then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
        else case forall a. Parser a -> ByteString -> Either String a
parseOnly Parser PgPoint
pgPointParser ByteString
d of
               Left String
err -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.ConversionFailed Field
field (String
"PgPoint: " forall a. [a] -> [a] -> [a]
++ String
err)
               Right PgPoint
pt -> forall (f :: * -> *) a. Applicative f => a -> f a
pure PgPoint
pt
instance FromBackendRow Postgres PgPoint

pgPointParser :: Parser PgPoint
pgPointParser :: Parser PgPoint
pgPointParser = Double -> Double -> PgPoint
PgPoint forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Parser Char
char Char
'(' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Double
double forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Char
char Char
',')
                        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser ByteString Double
double forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Char
char Char
')')

instance Pg.FromField PgBox where
    fromField :: FieldParser PgBox
fromField Field
field Maybe ByteString
Nothing = forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.UnexpectedNull Field
field String
""
    fromField Field
field (Just ByteString
d) =
        if Field -> Oid
Pg.typeOid Field
field forall a. Eq a => a -> a -> Bool
/= TypeInfo -> Oid
Pg.typoid TypeInfo
Pg.box
        then forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.Incompatible Field
field String
""
        else case forall a. Parser a -> ByteString -> Either String a
parseOnly Parser ByteString PgBox
boxParser ByteString
d of
               Left  String
err -> forall a err.
(Typeable a, Exception err) =>
(String -> Maybe Oid -> String -> String -> String -> err)
-> Field -> String -> Conversion a
Pg.returnError String -> Maybe Oid -> String -> String -> String -> ResultError
Pg.ConversionFailed Field
field (String
"PgBox: " forall a. [a] -> [a] -> [a]
++ String
err)
               Right PgBox
box -> forall (f :: * -> *) a. Applicative f => a -> f a
pure PgBox
box

        where
          boxParser :: Parser ByteString PgBox
boxParser = PgPoint -> PgPoint -> PgBox
PgBox forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser PgPoint
pgPointParser forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Char
char Char
',')
                            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser PgPoint
pgPointParser
instance FromBackendRow Postgres PgBox

-- ** Regular expressions

-- | The type of Postgres regular expressions. Only a
-- 'HasSqlValueSyntax' instance is supplied, because you won't need to
-- be reading these back from the database.
--
-- If you're generating regexes dynamically, then use 'pgRegex_' to
-- convert a string expression into a regex one.
newtype PgRegex = PgRegex T.Text
  deriving (Int -> PgRegex -> ShowS
[PgRegex] -> ShowS
PgRegex -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgRegex] -> ShowS
$cshowList :: [PgRegex] -> ShowS
show :: PgRegex -> String
$cshow :: PgRegex -> String
showsPrec :: Int -> PgRegex -> ShowS
$cshowsPrec :: Int -> PgRegex -> ShowS
Show, PgRegex -> PgRegex -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgRegex -> PgRegex -> Bool
$c/= :: PgRegex -> PgRegex -> Bool
== :: PgRegex -> PgRegex -> Bool
$c== :: PgRegex -> PgRegex -> Bool
Eq, Eq PgRegex
PgRegex -> PgRegex -> Bool
PgRegex -> PgRegex -> Ordering
PgRegex -> PgRegex -> PgRegex
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PgRegex -> PgRegex -> PgRegex
$cmin :: PgRegex -> PgRegex -> PgRegex
max :: PgRegex -> PgRegex -> PgRegex
$cmax :: PgRegex -> PgRegex -> PgRegex
>= :: PgRegex -> PgRegex -> Bool
$c>= :: PgRegex -> PgRegex -> Bool
> :: PgRegex -> PgRegex -> Bool
$c> :: PgRegex -> PgRegex -> Bool
<= :: PgRegex -> PgRegex -> Bool
$c<= :: PgRegex -> PgRegex -> Bool
< :: PgRegex -> PgRegex -> Bool
$c< :: PgRegex -> PgRegex -> Bool
compare :: PgRegex -> PgRegex -> Ordering
$ccompare :: PgRegex -> PgRegex -> Ordering
Ord, String -> PgRegex
forall a. (String -> a) -> IsString a
fromString :: String -> PgRegex
$cfromString :: String -> PgRegex
IsString)

instance HasSqlValueSyntax PgValueSyntax PgRegex where
  sqlValueSyntax :: PgRegex -> PgValueSyntax
sqlValueSyntax (PgRegex Text
r) = forall expr ty. HasSqlValueSyntax expr ty => ty -> expr
sqlValueSyntax Text
r

-- | Convert a string valued expression (which could be generated
-- dynamically) into a 'PgRegex'-typed one.
pgRegex_ :: BeamSqlBackendIsString Postgres text => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
pgRegex_ :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
pgRegex_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
e) = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
e

-- | Match regular expression, case-sensitive
(~.) :: BeamSqlBackendIsString Postgres text
     => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
     -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
t ~. :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s Bool
~. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"~" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
t forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
re)

-- | Match regular expression, case-insensitive
(~*.) :: BeamSqlBackendIsString Postgres text
      => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
      -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
t ~*. :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s Bool
~*. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"~*" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
t forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
re)

-- | Does not match regular expression, case-sensitive
(!~.) :: BeamSqlBackendIsString Postgres text
      => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
      -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
t !~. :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s Bool
!~. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"!~" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
t forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
re)

-- | Does not match regular expression, case-insensitive
(!~*.) :: BeamSqlBackendIsString Postgres text
       => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
       -> QGenExpr ctxt Postgres s Bool
QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
t !~*. :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s Bool
!~*. QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re = forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (ByteString
-> PgExpressionSyntax -> PgExpressionSyntax -> PgExpressionSyntax
pgBinOp ByteString
"!~*" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> BeamSqlBackendExpressionSyntax Postgres
t forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> BeamSqlBackendExpressionSyntax Postgres
re)

-- | Postgres @regexp_replace@. Replaces all instances of the regex in
-- the first argument with the third argument. The fourth argument is
-- the postgres regex options to provide.
pgRegexpReplace_ :: BeamSqlBackendIsString Postgres text
                 => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
                 -> QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s T.Text
                 -> QGenExpr ctxt Postgres s txt
pgRegexpReplace_ :: forall text ctxt s txt.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s Text
-> QGenExpr ctxt Postgres s txt
pgRegexpReplace_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
haystack) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
needle) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
replacement) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
opts) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
t -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
               ByteString -> PgSyntax
emit ByteString
"regexp_replace(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
haystack Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                      forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
needle Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                      forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
replacement Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                      forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
opts Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

-- | Postgres @regexp_match@. Matches the regular expression against
-- the string given and returns an array where each element
-- corresponds to a match in the string, or @NULL@ if nothing was
-- found
pgRegexpMatch_ :: BeamSqlBackendIsString Postgres text
               => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
               -> QGenExpr ctxt Postgres s (Maybe (V.Vector text))
pgRegexpMatch_ :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s (Maybe (Vector text))
pgRegexpMatch_ (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
s) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
t -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
               ByteString -> PgSyntax
emit ByteString
"regexp_match(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
s Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                    forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
re Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

-- | Postgres @regexp_split_to_array@. Splits the given string by the
-- given regex and returns the result as an array.
pgRegexpSplitToArray :: BeamSqlBackendIsString Postgres text
                     => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex
                     -> QGenExpr ctxt Postgres s (V.Vector text)
pgRegexpSplitToArray :: forall text ctxt s.
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> QGenExpr ctxt Postgres s (Vector text)
pgRegexpSplitToArray (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
s) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re) =
  forall context be s t.
(Text -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (\Text
t -> PgSyntax -> PgExpressionSyntax
PgExpressionSyntax forall a b. (a -> b) -> a -> b
$
               ByteString -> PgSyntax
emit ByteString
"regexp_split_to_array(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
s Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                             forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
re Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

newtype PgReResultT f
  = PgReResultT { forall (f :: * -> *). PgReResultT f -> C f Text
reResult :: C f T.Text }
  deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (f :: * -> *) x. Rep (PgReResultT f) x -> PgReResultT f
forall (f :: * -> *) x. PgReResultT f -> Rep (PgReResultT f) x
$cto :: forall (f :: * -> *) x. Rep (PgReResultT f) x -> PgReResultT f
$cfrom :: forall (f :: * -> *) x. PgReResultT f -> Rep (PgReResultT f) x
Generic
instance Beamable PgReResultT

-- | Postgres @regexp_split_to_table@. Splits the given string by the
-- given regex and return a result set that can be joined against.
pgRegexpSplitToTable :: BeamSqlBackendIsString Postgres text
                     => QGenExpr ctxt Postgres s text -> QGenExpr ctxt Postgres s PgRegex

                     -> Q Postgres db s (QExpr Postgres s T.Text)
pgRegexpSplitToTable :: forall text ctxt s (db :: (* -> *) -> *).
BeamSqlBackendIsString Postgres text =>
QGenExpr ctxt Postgres s text
-> QGenExpr ctxt Postgres s PgRegex
-> Q Postgres db s (QExpr Postgres s Text)
pgRegexpSplitToTable (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
s) (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
re) =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *). PgReResultT f -> C f Text
reResult forall a b. (a -> b) -> a -> b
$
  forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
(Text -> PgSyntax) -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' (\Text
t -> ByteString -> PgSyntax
emit ByteString
"regexp_split_to_table(" forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
s Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
", "
                                                 forall a. Semigroup a => a -> a -> a
<> PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
re Text
t) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
")")

-- ** Set-valued functions

data PgSetOf (tbl :: (* -> *) -> *)

pgUnnest' :: forall tbl db s
           . Beamable tbl
          => (TablePrefix -> PgSyntax)
          -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' :: forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
(Text -> PgSyntax) -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' Text -> PgSyntax
q =
  forall be (db :: (* -> *) -> *) s a. QM be db s a -> Q be db s a
Q (forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
liftF (forall be r next (db :: (* -> *) -> *) s.
Projectible be r =>
(Text -> Text -> BeamSqlBackendFromSyntax be)
-> (Text -> r)
-> (r
    -> Maybe (WithExprContext (BeamSqlBackendExpressionSyntax be)))
-> ((Text, r) -> next)
-> QF be db s next
QAll (\Text
pfx Text
alias ->
                    PgSyntax -> PgFromSyntax
PgFromSyntax forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$
                    [ Text -> PgSyntax
q Text
pfx, ByteString -> PgSyntax
emit ByteString
" "
                    , Text -> PgSyntax
pgQuotedIdentifier Text
alias
                    , PgSyntax -> PgSyntax
pgParens (PgSyntax -> [PgSyntax] -> PgSyntax
pgSepBy (ByteString -> PgSyntax
emit ByteString
", ") (forall (table :: (* -> *) -> *) (f :: * -> *) b.
Beamable table =>
(forall a. Columnar' f a -> b) -> table f -> [b]
allBeamValues (\(Columnar' (TableField NonEmpty Text
_ Text
nm)) -> Text -> PgSyntax
pgQuotedIdentifier Text
nm) TableSettings tbl
tblFields))
                    ])
                 (forall be (table :: (* -> *) -> *) ctxt s.
(BeamSqlBackend be, Beamable table) =>
TableSettings table -> Text -> table (QGenExpr ctxt be s)
tableFieldsToExpressions TableSettings tbl
tblFields)
                 (\tbl (QGenExpr QValueContext Postgres s)
_ -> forall a. Maybe a
Nothing) forall a b. (a, b) -> b
snd))
  where
    tblFields :: TableSettings tbl
    tblFields :: TableSettings tbl
tblFields =
      forall s a. State s a -> s -> a
evalState (forall (table :: (* -> *) -> *) (m :: * -> *) (f :: * -> *)
       (g :: * -> *) (h :: * -> *).
(Beamable table, Applicative m) =>
(forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a))
-> table f -> table g -> m (table h)
zipBeamFieldsM (\Columnar' Ignored a
_ Columnar' Ignored a
_ ->
                                   do Int
i <- forall s (m :: * -> *). MonadState s m => m s
get
                                      forall s (m :: * -> *). MonadState s m => s -> m ()
put (Int
i forall a. Num a => a -> a -> a
+ Int
1)
                                      let fieldNm :: Text
fieldNm = forall a. IsString a => String -> a
fromString (String
"r" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i)
                                      forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall (f :: * -> *) a. Columnar f a -> Columnar' f a
Columnar' (forall (table :: (* -> *) -> *) ty.
NonEmpty Text -> Text -> TableField table ty
TableField (forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
fieldNm) Text
fieldNm)))
                                forall (table :: (* -> *) -> *).
Beamable table =>
TableSkeleton table
tblSkeleton forall (table :: (* -> *) -> *).
Beamable table =>
TableSkeleton table
tblSkeleton) (Int
0 :: Int)

-- | Join the results of the given set-valued function to the query
pgUnnest :: forall tbl db s
          . Beamable tbl
         => QExpr Postgres s (PgSetOf tbl)
         -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest :: forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
QExpr Postgres s (PgSetOf tbl)
-> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
q) = forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
(Text -> PgSyntax) -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' forall a b. (a -> b) -> a -> b
$ PgExpressionSyntax -> PgSyntax
fromPgExpression forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> BeamSqlBackendExpressionSyntax Postgres
q

data PgUnnestArrayTbl a f = PgUnnestArrayTbl (C f a)
  deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a (f :: * -> *) x.
Rep (PgUnnestArrayTbl a f) x -> PgUnnestArrayTbl a f
forall a (f :: * -> *) x.
PgUnnestArrayTbl a f -> Rep (PgUnnestArrayTbl a f) x
$cto :: forall a (f :: * -> *) x.
Rep (PgUnnestArrayTbl a f) x -> PgUnnestArrayTbl a f
$cfrom :: forall a (f :: * -> *) x.
PgUnnestArrayTbl a f -> Rep (PgUnnestArrayTbl a f) x
Generic
instance Beamable (PgUnnestArrayTbl a)

-- | Introduce each element of the array as a row
pgUnnestArray :: QExpr Postgres s (V.Vector a)
              -> Q Postgres db s (QExpr Postgres s a)
pgUnnestArray :: forall s a (db :: (* -> *) -> *).
QExpr Postgres s (Vector a) -> Q Postgres db s (QExpr Postgres s a)
pgUnnestArray (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
q) =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgUnnestArrayTbl C (QGenExpr QValueContext Postgres s) a
x) -> C (QGenExpr QValueContext Postgres s) a
x) forall a b. (a -> b) -> a -> b
$
  forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
(Text -> PgSyntax) -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' (\Text
t -> ByteString -> PgSyntax
emit ByteString
"UNNEST" forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
q Text
t)))

data PgUnnestArrayWithOrdinalityTbl a f = PgUnnestArrayWithOrdinalityTbl (C f Int64) (C f a)
  deriving forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a (f :: * -> *) x.
Rep (PgUnnestArrayWithOrdinalityTbl a f) x
-> PgUnnestArrayWithOrdinalityTbl a f
forall a (f :: * -> *) x.
PgUnnestArrayWithOrdinalityTbl a f
-> Rep (PgUnnestArrayWithOrdinalityTbl a f) x
$cto :: forall a (f :: * -> *) x.
Rep (PgUnnestArrayWithOrdinalityTbl a f) x
-> PgUnnestArrayWithOrdinalityTbl a f
$cfrom :: forall a (f :: * -> *) x.
PgUnnestArrayWithOrdinalityTbl a f
-> Rep (PgUnnestArrayWithOrdinalityTbl a f) x
Generic
instance Beamable (PgUnnestArrayWithOrdinalityTbl a)

-- | Introduce each element of the array as a row, along with the
-- element's index
pgUnnestArrayWithOrdinality :: QExpr Postgres s (V.Vector a)
                            -> Q Postgres db s (QExpr Postgres s Int64, QExpr Postgres s a)
pgUnnestArrayWithOrdinality :: forall s a (db :: (* -> *) -> *).
QExpr Postgres s (Vector a)
-> Q Postgres db s (QExpr Postgres s Int64, QExpr Postgres s a)
pgUnnestArrayWithOrdinality (QExpr Text -> BeamSqlBackendExpressionSyntax Postgres
q) =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(PgUnnestArrayWithOrdinalityTbl C (QGenExpr QValueContext Postgres s) Int64
i C (QGenExpr QValueContext Postgres s) a
x) -> (C (QGenExpr QValueContext Postgres s) Int64
i, C (QGenExpr QValueContext Postgres s) a
x)) forall a b. (a -> b) -> a -> b
$
  forall (tbl :: (* -> *) -> *) (db :: (* -> *) -> *) s.
Beamable tbl =>
(Text -> PgSyntax) -> Q Postgres db s (QExprTable Postgres s tbl)
pgUnnest' (\Text
t -> ByteString -> PgSyntax
emit ByteString
"UNNEST" forall a. Semigroup a => a -> a -> a
<> PgSyntax -> PgSyntax
pgParens (PgExpressionSyntax -> PgSyntax
fromPgExpression (Text -> BeamSqlBackendExpressionSyntax Postgres
q Text
t)) forall a. Semigroup a => a -> a -> a
<> ByteString -> PgSyntax
emit ByteString
" WITH ORDINALITY")

instance HasDefaultSqlDataType Postgres PgPoint where
  defaultSqlDataType :: Proxy PgPoint
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy PgPoint
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgPointType

instance HasDefaultSqlDataType Postgres PgLine where
  defaultSqlDataType :: Proxy PgLine
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy PgLine
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgLineType

instance HasDefaultSqlDataType Postgres PgLineSegment where
  defaultSqlDataType :: Proxy PgLineSegment
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy PgLineSegment
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgLineSegmentType

instance HasDefaultSqlDataType Postgres PgBox where
  defaultSqlDataType :: Proxy PgBox
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy PgBox
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgBoxType

instance HasDefaultSqlDataType Postgres TsQuery where
  defaultSqlDataType :: Proxy TsQuery
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy TsQuery
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgTsQueryType

instance HasDefaultSqlDataType Postgres TsVector where
  defaultSqlDataType :: Proxy TsVector
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy TsVector
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgTsVectorType

instance HasDefaultSqlDataType Postgres (PgJSON a) where
  defaultSqlDataType :: Proxy (PgJSON a)
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy (PgJSON a)
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgJsonType

instance HasDefaultSqlDataType Postgres (PgJSONB a) where
  defaultSqlDataType :: Proxy (PgJSONB a)
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy (PgJSONB a)
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgJsonbType

instance HasDefaultSqlDataType Postgres PgMoney where
  defaultSqlDataType :: Proxy PgMoney
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy PgMoney
_ Proxy Postgres
_ Bool
_ = PgDataTypeSyntax
pgMoneyType

instance HasDefaultSqlDataType Postgres a
    => HasDefaultSqlDataType Postgres (V.Vector a) where
  defaultSqlDataType :: Proxy (Vector a)
-> Proxy Postgres -> Bool -> BeamSqlBackendDataTypeSyntax Postgres
defaultSqlDataType Proxy (Vector a)
_ Proxy Postgres
be Bool
embedded =
      PgDataTypeSyntax -> PgDataTypeSyntax
pgUnboundedArrayType (forall be ty.
HasDefaultSqlDataType be ty =>
Proxy ty -> Proxy be -> Bool -> BeamSqlBackendDataTypeSyntax be
defaultSqlDataType (forall {k} (t :: k). Proxy t
Proxy :: Proxy a) Proxy Postgres
be Bool
embedded)

-- ** Extract

century_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
century_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
century_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"CENTURY"))

decade_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
decade_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
decade_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"DECADE"))

dow_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
dow_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
dow_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"DOW"))

doy_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
doy_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
doy_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"DOY"))

epoch_ :: HasSqlTime tgt => ExtractField Postgres tgt NominalDiffTime
epoch_ :: forall tgt.
HasSqlTime tgt =>
ExtractField Postgres tgt NominalDiffTime
epoch_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"EPOCH"))

isodow_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
isodow_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
isodow_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"ISODOW"))

isoyear_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
isoyear_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
isoyear_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"ISOYEAR"))

microseconds_ :: HasSqlTime tgt => ExtractField Postgres tgt Int32
microseconds_ :: forall tgt. HasSqlTime tgt => ExtractField Postgres tgt Int32
microseconds_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"MICROSECONDS"))

milliseconds_ :: HasSqlTime tgt => ExtractField Postgres tgt Int32
milliseconds_ :: forall tgt. HasSqlTime tgt => ExtractField Postgres tgt Int32
milliseconds_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"MILLISECONDS"))

millennium_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
millennium_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
millennium_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"MILLENNIUM"))

quarter_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
quarter_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
quarter_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"QUARTER"))

week_ :: HasSqlDate tgt => ExtractField Postgres tgt Int32
week_ :: forall tgt. HasSqlDate tgt => ExtractField Postgres tgt Int32
week_ = forall be tgt a.
Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be)
-> ExtractField be tgt a
ExtractField (PgSyntax -> PgExtractFieldSyntax
PgExtractFieldSyntax (ByteString -> PgSyntax
emit ByteString
"WEEK"))

-- $full-text-search
--
-- Postgres has comprehensive, and thus complicated, support for full text
-- search. The types and functions in this section map closely to the underlying
-- Postgres API, which is described in the
-- <https://www.postgresql.org/docs/current/static/textsearch-intro.html documentation>.
--

-- $arrays
--
-- The functions and types in this section map Postgres @ARRAY@ types to
-- Haskell. An array is serialized and deserialized to a 'Data.Vector.Vector'
-- object. This type most closely matches the semantics of Postgres @ARRAY@s. In
-- general, the names of functions in this section closely match names of the
-- native Postgres functions they map to. As with most beam expression
-- functions, names are suffixed with an underscore and CamelCased.
--
-- Note that Postgres supports arbitrary nesting of vectors. For example, two,
-- three, or higher dimensional arrays can be expressed, manipulated, and stored
-- in tables. Beam fully supports this use case. A two-dimensional postgres
-- array is represented as @Vector (Vector a)@. Simply nest another 'Vector' for
-- higher dimensions. Some functions that return data on arrays expect a
-- dimension number as a parameter. Since beam can check the dimension at
-- compile time, these functions expect a type-level 'Nat' in the expression
-- DSL. The unsafe versions of these functions are also provided with the
-- @Unsafe_@ suffix. The safe versions are guaranteed not to fail at run-time
-- due to dimension mismatches, the unsafe ones may.
--
-- For more information on Postgres array support, refer to the postgres
-- <https://www.postgresql.org/docs/current/static/functions-array.html manual>.

-- $ranges
--
-- Postgres supports storing Range types in columns. There are serveral
-- predefined Range types and users may create their own. @beam-postgres@
-- fully supports these types, including user-defined range types. In general,
-- the names of functions in this section closely match names of the native
-- Postgres functions they map to. As with most beam expression functions,
-- names are suffixed with an underscore and CamelCased. Where ambiguous,
-- functions are prefixed with an @r@. Operators closely match their native
-- Postgres counterparts, except they are prefixed and/or suffixed with an @-@
-- to indicate the expression on that side is a Range. For example @-<\@-@ maps
-- to the native operator @<\@@ when both arguments are Ranges, while @<\@-@ maps
-- to the same operator when the first argument is an element, not a range.
--
-- For more information on Postgres range support, refer to the postgres
-- <https://www.postgresql.org/docs/current/static/rangetypes.html manual>.

-- $json
--
-- Postgres supports storing JSON in columns, as either a text-based type
-- (@JSON@) or a specialized binary encoding (@JSONB@). @beam-postgres@
-- accordingly provides the 'PgJSON' and 'PgJSONB' data types. Each of these
-- types takes a type parameter indicating the Haskell object represented by the
-- JSON object stored in the column. In order for serialization to work, be sure
-- to provide 'FromJSON' and 'ToJSON' instances for this type. If you do not
-- know the shape of the data stored, substitute 'Value' for this type
-- parameter.
--
-- For more information on Postgres JSON support see the postgres
-- <https://www.postgresql.org/docs/current/static/functions-json.html manual>.


-- $set-valued-funs
--
-- Postgres supports functions that returns /sets/. We can join directly against
-- these sets or arrays. @beam-postgres@ supports this feature via the
-- 'pgUnnest' and 'pgUnnestArray' functions.
--
-- Any function that returns a set can be typed as an expression returning
-- 'PgSetOf'. This polymorphic type takes one argument, which is a 'Beamable'
-- type that represents the shape of the data in the rows. For example, the
-- @json_each@ function returns a key and a value, so the corresponding
-- @beam-postgres@ function ('pgJsonEach') returns a value of type 'PgSetOf
-- (PgJSONEach Value)', which represents a set containing 'PgJSONEach'
-- rows. 'PgJSONEach' is a table with a column for keys ('pgJsonEachKey') and
-- one for values ('pgJsonEachValue').
--
-- Any 'PgSetOf' value can be introduced into the 'Q' monad using the 'pgUnnest'
-- function.
--
-- Postgres arrays (represented by the 'V.Vector' type) can also be joined
-- against using the 'pgUnnestArray' function. This directly corresponds to the
-- SQL @UNNEST@ keyword. Unlike sets, arrays have a sense of order. The
-- 'pgUnnestArrayWithOrdinality' function allows you to join against the
-- elements of an array along with its index. This corresponds to the
-- @UNNEST .. WITH ORDINALITY@ clause.