packages feed

beam-postgres 0.3.2.0 → 0.3.2.2

raw patch · 6 files changed

+331/−15 lines, 6 filesdep ~aesondep ~basedep ~beam-corePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, base, beam-core

API changes (from Hackage documentation)

- Database.Beam.Postgres.Syntax: instance Data.Semigroup.Semigroup (Database.Beam.Query.CustomSQL.CustomSqlSyntax Database.Beam.Postgres.Syntax.PgExpressionSyntax)
- Database.Beam.Postgres.Syntax: instance Data.Semigroup.Semigroup Database.Beam.Postgres.Syntax.PgSyntax
+ Database.Beam.Postgres: (-&&-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-&<-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-&>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-*-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a)
+ Database.Beam.Postgres: (-+-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a)
+ Database.Beam.Postgres: (--|--) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-.-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a)
+ Database.Beam.Postgres: (-<<-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-<@-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (->>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-@>) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s a -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (-@>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: (<@-) :: QGenExpr context PgExpressionSyntax s a -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: Exclusive :: PgBoundType
+ Database.Beam.Postgres: Inclusive :: PgBoundType
+ Database.Beam.Postgres: PgEmptyRange :: PgRange a
+ Database.Beam.Postgres: PgRange :: (PgRangeBound a) -> (PgRangeBound a) -> PgRange a
+ Database.Beam.Postgres: PgRangeBound :: PgBoundType -> (Maybe a) -> PgRangeBound a
+ Database.Beam.Postgres: class PgIsRange n
+ Database.Beam.Postgres: data PgBoundType
+ Database.Beam.Postgres: data PgDateRange
+ Database.Beam.Postgres: data PgInt4Range
+ Database.Beam.Postgres: data PgInt8Range
+ Database.Beam.Postgres: data PgNumRange
+ Database.Beam.Postgres: data PgRange (n :: *) a
+ Database.Beam.Postgres: data PgRangeBound a
+ Database.Beam.Postgres: data PgTsRange
+ Database.Beam.Postgres: data PgTsTzRange
+ Database.Beam.Postgres: exclusive :: a -> PgRangeBound a
+ Database.Beam.Postgres: inclusive :: a -> PgRangeBound a
+ Database.Beam.Postgres: isEmpty_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: lowerInc_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: lowerInf_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: rLower_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (Maybe a)
+ Database.Beam.Postgres: rUpper_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (Maybe a)
+ Database.Beam.Postgres: rangeMerge_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s (PgRange n a)
+ Database.Beam.Postgres: rangeName :: PgIsRange n => ByteString
+ Database.Beam.Postgres: range_ :: forall n a context s. PgIsRange n => PgBoundType -> PgBoundType -> QGenExpr context PgExpressionSyntax s (Maybe a) -> QGenExpr context PgExpressionSyntax s (Maybe a) -> QGenExpr context PgExpressionSyntax s (PgRange n a)
+ Database.Beam.Postgres: toTsQuery :: IsSqlExpressionSyntaxStringType PgExpressionSyntax str => Maybe TsVectorConfig -> QGenExpr context PgExpressionSyntax s str -> QGenExpr context PgExpressionSyntax s TsQuery
+ Database.Beam.Postgres: unbounded :: PgRangeBound a
+ Database.Beam.Postgres: upperInc_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres: upperInf_ :: QGenExpr context PgExpressionSyntax s (PgRange n a) -> QGenExpr context PgExpressionSyntax s Bool
+ Database.Beam.Postgres.Full: instance GHC.Base.Semigroup (Database.Beam.Postgres.Full.PgLockedTables s)
+ Database.Beam.Postgres.Syntax: instance GHC.Base.Semigroup (Database.Beam.Query.CustomSQL.CustomSqlSyntax Database.Beam.Postgres.Syntax.PgExpressionSyntax)
+ Database.Beam.Postgres.Syntax: instance GHC.Base.Semigroup Database.Beam.Postgres.Syntax.PgSyntax
- Database.Beam.Postgres: data ConnectInfo :: *
+ Database.Beam.Postgres: data ConnectInfo
- Database.Beam.Postgres: data Connection :: *
+ Database.Beam.Postgres: data Connection
- Database.Beam.Postgres: data ResultError :: *
+ Database.Beam.Postgres: data ResultError
- Database.Beam.Postgres: data SqlError :: *
+ Database.Beam.Postgres: data SqlError
- Database.Beam.Postgres.PgCrypto: PgCrypto :: (forall ctxt s. LiftPg ctxt s (Text -> Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (Text -> Text -> Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (Text -> Text -> Text)) -> (forall ctxt s. LiftPg ctxt s (Text -> Maybe Int -> Text)) -> (forall ctxt s. LiftPg ctxt s (Text -> Text -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> Text)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (Text -> ByteString -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> Maybe Text -> Text)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> Maybe Text -> ByteString)) -> (forall ctxt s. LiftPg ctxt s (ByteString -> Text)) -> (forall ctxt s. PgExpr ctxt s ByteString -> Maybe (PgExpr ctxt s (Vector Text), PgExpr ctxt s (Vector Text)) -> PgExpr ctxt s Text) -> (forall ctxt s. LiftPg ctxt s (Text -> ByteString)) -> (forall ctxt s i. Integral i => PgExpr ctxt s i -> PgExpr ctxt s ByteString) -> (forall ctxt s. PgExpr ctxt s UUID) -> PgCrypto
+ Database.Beam.Postgres.PgCrypto: PgCrypto :: forall ctxt s. LiftPg ctxt s (Text -> Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (Text -> Text -> Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (Text -> Text -> Text) -> forall ctxt s. LiftPg ctxt s (Text -> Maybe Int -> Text) -> forall ctxt s. LiftPg ctxt s (Text -> Text -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> Text) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (Text -> ByteString -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> Maybe Text -> Text) -> forall ctxt s. LiftPg ctxt s (ByteString -> ByteString -> Maybe Text -> Maybe Text -> ByteString) -> forall ctxt s. LiftPg ctxt s (ByteString -> Text) -> forall ctxt s. PgExpr ctxt s ByteString -> Maybe (PgExpr ctxt s (Vector Text), PgExpr ctxt s (Vector Text)) -> PgExpr ctxt s Text -> forall ctxt s. LiftPg ctxt s (Text -> ByteString) -> forall ctxt s i. Integral i => PgExpr ctxt s i -> PgExpr ctxt s ByteString -> forall ctxt s. PgExpr ctxt s UUID -> PgCrypto
- Database.Beam.Postgres.Syntax: PgWindowFrameBoundSyntax :: (ByteString -> PgSyntax) -> PgWindowFrameBoundSyntax
+ Database.Beam.Postgres.Syntax: PgWindowFrameBoundSyntax :: ByteString -> PgSyntax -> PgWindowFrameBoundSyntax

Files

Database/Beam/Postgres.hs view
@@ -7,7 +7,7 @@ -- -- @beam-postgres@ supports most beam features as well as many postgres-specific -- features. For example, @beam-postgres@ provides support for full-text search,--- @DISTINCT ON@, JSON handling, postgres @ARRAY@s, and the @MONEY@ type.+-- @DISTINCT ON@, JSON handling, postgres @ARRAY@s, @RANGE@s, and the @MONEY@ type. -- -- The documentation for @beam-postgres@ functionality below indicates which -- postgres function each function or type wraps. Postgres maintains its own
Database/Beam/Postgres/Full.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}  -- | Module providing (almost) full support for Postgres query and data -- manipulation statements. These functions shadow the functions in@@ -63,9 +64,7 @@ -- function. You can combine these values monoidally to combine multiple locks for use with the -- 'withLocks_' function. newtype PgLockedTables s = PgLockedTables [ T.Text ]-instance Monoid (PgLockedTables s) where-  mempty = PgLockedTables []-  mappend (PgLockedTables a) (PgLockedTables b) = PgLockedTables (a <> b)+  deriving (Semigroup, Monoid)  -- | Combines the result of a query along with a set of locked tables. Used as a -- return value for the 'lockingFor_' function.
Database/Beam/Postgres/Migrate.hs view
@@ -66,6 +66,8 @@ import           Data.Typeable #if !MIN_VERSION_base(4, 11, 0) import           Data.Semigroup+#else+import           Data.Monoid (Endo(..)) #endif  -- | Top-level migration backend for use by @beam-migrate@ tools@@ -276,7 +278,7 @@       columnChecks <-        fmap mconcat . forM tbls $ \(oid, tbl) ->-       do columns <- Pg.query conn "SELECT attname, atttypid, atttypmod, attnotnull, pg_catalog.format_type(atttypid, atttypmod) FROM pg_catalog.pg_attribute att WHERE att.attrelid=? AND att.attnum>0"+       do columns <- Pg.query conn "SELECT attname, atttypid, atttypmod, attnotnull, pg_catalog.format_type(atttypid, atttypmod) FROM pg_catalog.pg_attribute att WHERE att.attrelid=? AND att.attnum>0 AND att.attisdropped='f'"                        (Pg.Only (oid :: Pg.Oid))           let columnChecks = map (\(nm, typId :: Pg.Oid, typmod, _, typ :: ByteString) ->                                     let typmod' = if typmod == -1 then Nothing else Just (typmod - 4)
Database/Beam/Postgres/PgSpecific.hs view
@@ -7,6 +7,7 @@ {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE CPP #-} @@ -21,6 +22,7 @@      -- *** @TSQUERY@ data type   , TsQuery(..), (@@)+  , toTsQuery      -- ** @JSON@ and @JSONB@ data types     -- $json@@ -70,6 +72,28 @@    , 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 functions and aggregates   , pgBoolOr, pgBoolAnd, pgStringAgg, pgStringAggOver @@ -112,6 +136,7 @@ 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)@@ -180,10 +205,10 @@ toTsVector Nothing (QExpr x) =   QExpr (fmap (\(PgExpressionSyntax x') ->                  PgExpressionSyntax $-                 emit "to_tsquery(" <> x' <> emit ")") x)+                 emit "to_tsvector(" <> x' <> emit ")") x) toTsVector (Just (TsVectorConfig configNm)) (QExpr x) =   QExpr (fmap (\(PgExpressionSyntax x') -> PgExpressionSyntax $-                 emit "to_tsquery('" <> escapeString configNm <> emit "', " <> x' <> emit ")") x)+                 emit "to_tsvector('" <> escapeString configNm <> emit "', " <> x' <> emit ")") x)  -- | Determine if the given @TSQUERY@ matches the document represented by the -- @TSVECTOR@. Behaves exactly like the similarly-named operator in postgres.@@ -215,6 +240,19 @@  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 :: IsSqlExpressionSyntaxStringType PgExpressionSyntax str+           => Maybe TsVectorConfig -> QGenExpr context PgExpressionSyntax s str+           -> QGenExpr context PgExpressionSyntax s TsQuery+toTsQuery Nothing (QExpr x) =+  QExpr (fmap (\(PgExpressionSyntax x') ->+                 PgExpressionSyntax $+                 emit "to_tsquery(" <> x' <> emit ")") x)+toTsQuery (Just (TsVectorConfig configNm)) (QExpr x) =+  QExpr (fmap (\(PgExpressionSyntax x') -> PgExpressionSyntax $+                 emit "to_tsquery('" <> escapeString configNm <> emit "', " <> x' <> emit ")") x)+ -- ** Array operators  -- TODO this should be robust to slices@@ -381,6 +419,264 @@   in QExpr (\t -> let PgExpressionSyntax sub' = sub t                   in PgExpressionSyntax (emit "ARRAY(" <> sub' <> emit ")")) +-- ** 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 (Show, Generic)+instance Hashable PgBoundType++lBound :: PgBoundType -> ByteString+lBound Inclusive = "["+lBound Exclusive = "("++uBound :: PgBoundType -> ByteString+uBound Inclusive = "]"+uBound Exclusive = ")"++-- | 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 (Show, Generic)++inclusive :: a -> PgRangeBound a+inclusive = PgRangeBound Inclusive . Just++exclusive :: a -> PgRangeBound a+exclusive = PgRangeBound Exclusive . Just++unbounded :: PgRangeBound a+unbounded = PgRangeBound Exclusive 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 (Show, 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 = "int4range"++data PgInt8Range+instance PgIsRange PgInt8Range where+  rangeName = "int8range"++data PgNumRange+instance PgIsRange PgNumRange where+  rangeName = "numrange"++data PgTsRange+instance PgIsRange PgTsRange where+  rangeName = "tsrange"++data PgTsTzRange+instance PgIsRange PgTsTzRange where+  rangeName = "tstzrange"++data PgDateRange+instance PgIsRange PgDateRange where+  rangeName = "daterange"++instance (Pg.FromField a, Typeable a, Ord a) => Pg.FromField (PgRange n a) where+  fromField field d = do+    pgR :: Pg.PGRange a <- Pg.fromField field d+    if Pg.isEmpty pgR+    then pure PgEmptyRange+    else let Pg.PGRange lRange rRange = pgR+         in pure $ PgRange (boundConv lRange) (boundConv 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 Pg.NegInfinity = PgRangeBound Exclusive Nothing+boundConv Pg.PosInfinity = PgRangeBound Exclusive Nothing+boundConv (Pg.Inclusive a) = PgRangeBound Inclusive (Just a)+boundConv (Pg.Exclusive a) = PgRangeBound Exclusive (Just a)++instance (Pg.ToField (Pg.PGRange a)) => Pg.ToField (PgRange n a) where+  toField PgEmptyRange = Pg.toField (Pg.empty :: Pg.PGRange a)+  toField (PgRange (PgRangeBound lt lb) (PgRangeBound ut ub)) = Pg.toField r'+    where+      r' = Pg.PGRange lb' ub'+      lb' = case (lt, lb) of (_, Nothing) -> Pg.NegInfinity+                             (Inclusive, Just a) -> Pg.Inclusive a+                             (Exclusive, Just a) -> Pg.Exclusive a+      ub' = case (ut, ub) of (_, Nothing) -> Pg.PosInfinity+                             (Inclusive, Just a) -> Pg.Inclusive a+                             (Exclusive, Just a) -> Pg.Exclusive a++instance HasSqlEqualityCheck PgExpressionSyntax (PgRange n a)+instance HasSqlQuantifiedEqualityCheck PgExpressionSyntax (PgRange n a)++instance (Pg.FromField a, Typeable a, Ord a) => FromBackendRow Postgres (PgRange n a)+instance (HasSqlValueSyntax PgValueSyntax a, PgIsRange n) =>+  HasSqlValueSyntax PgValueSyntax (PgRange n a) where+  sqlValueSyntax PgEmptyRange =+    PgValueSyntax $+    emit "'empty'::" <> escapeIdentifier (rangeName @n)+  sqlValueSyntax (PgRange (PgRangeBound lbt mlBound) (PgRangeBound rbt muBound)) =+    PgValueSyntax $+    escapeIdentifier (rangeName @n) <> pgParens (pgSepBy (emit ", ") [lb, rb, bounds])+    where+      lb = sqlValueSyntax' mlBound+      rb = sqlValueSyntax' muBound+      bounds = emit "'" <> emit (lBound lbt <> uBound rbt) <> emit "'"+      sqlValueSyntax' = fromPgValue . sqlValueSyntax+++binOpDefault :: ByteString+             -> QGenExpr context PgExpressionSyntax s a+             -> QGenExpr context PgExpressionSyntax s b+             -> QGenExpr context PgExpressionSyntax s c+binOpDefault symbol (QExpr r1) (QExpr r2)  = QExpr (pgBinOp symbol <$> r1 <*> r2)++(-@>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s Bool+(-@>-) = binOpDefault "@>"++(-@>) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s a+      -> QGenExpr context PgExpressionSyntax s Bool+(-@>) = binOpDefault "@>"++(-<@-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(-<@-) = binOpDefault "<@"++(<@-) :: QGenExpr context PgExpressionSyntax s a+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s Bool+(<@-) = binOpDefault "<@"++(-&&-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(-&&-) = binOpDefault "&&"++(-<<-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(-<<-) = binOpDefault "<<"++(->>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(->>-) = binOpDefault ">>"++(-&<-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(-&<-) = binOpDefault "&<"++(-&>-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s Bool+(-&>-) = binOpDefault "&>"++(--|--) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+        -> QGenExpr context PgExpressionSyntax s (PgRange n a)+        -> QGenExpr context PgExpressionSyntax s Bool+(--|--) = binOpDefault "-|-"++(-+-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+(-+-) = binOpDefault "+"++(-*-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+(-*-) = binOpDefault "*"++-- | The postgres range operator @-@ .+(-.-) :: QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+      -> QGenExpr context PgExpressionSyntax s (PgRange n a)+(-.-) = binOpDefault "-"++defUnaryFn :: ByteString+           -> QGenExpr context PgExpressionSyntax s a+           -> QGenExpr context PgExpressionSyntax s b+defUnaryFn fn (QExpr s) = QExpr (pgExprFrom <$> s)+  where+    pgExprFrom s' = PgExpressionSyntax (emit fn <> emit "(" <> fromPgExpression s' <> emit ")")++rLower_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (Maybe a)+rLower_ = defUnaryFn "LOWER"++rUpper_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+       -> QGenExpr context PgExpressionSyntax s (Maybe a)+rUpper_ = defUnaryFn "UPPER"++isEmpty_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+         -> QGenExpr context PgExpressionSyntax s Bool+isEmpty_ = defUnaryFn "ISEMPTY"++lowerInc_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+          -> QGenExpr context PgExpressionSyntax s Bool+lowerInc_ = defUnaryFn "LOWER_INC"++upperInc_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+          -> QGenExpr context PgExpressionSyntax s Bool+upperInc_ = defUnaryFn "UPPER_INC"++lowerInf_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+          -> QGenExpr context PgExpressionSyntax s Bool+lowerInf_ = defUnaryFn "LOWER_INF"++upperInf_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+          -> QGenExpr context PgExpressionSyntax s Bool+upperInf_ = defUnaryFn "UPPER_INF"++rangeMerge_ :: QGenExpr context PgExpressionSyntax s (PgRange n a)+            -> QGenExpr context PgExpressionSyntax s (PgRange n a)+            -> QGenExpr context PgExpressionSyntax s (PgRange n a)+rangeMerge_ (QExpr r1) (QExpr r2) = QExpr (pgExprFrom <$> r1 <*> r2)+  where+    pgExprFrom r1' r2' =+      PgExpressionSyntax+      (emit "RANGE_MERGE(" <>+       fromPgExpression r1' <>+       emit ", " <>+       fromPgExpression r2' <>+       emit ")")++range_ :: forall n a context s. PgIsRange n+       => PgBoundType -- ^ Lower bound type+       -> PgBoundType -- ^ Upper bound type+       -> QGenExpr context PgExpressionSyntax s (Maybe a) -- ^. Lower bound value+       -> QGenExpr context PgExpressionSyntax s (Maybe a) -- ^. Lower bound value+       -> QGenExpr context PgExpressionSyntax s (PgRange n a)+range_ lbt ubt (QExpr e1) (QExpr e2) = QExpr (pgExprFrom <$> e1 <*> e2)+  where+    bounds = emit "'" <> emit (lBound lbt <> uBound ubt) <> emit "'"+    pgExprFrom e1' e2' =+      PgExpressionSyntax+      (escapeIdentifier (rangeName @n) <>+       pgParens (pgSepBy (emit ", ") [fromPgExpression e1', fromPgExpression e2', bounds]))+ -- ** JSON  -- | The Postgres @JSON@ type, which stores textual values that represent JSON@@ -391,7 +687,7 @@ -- The 'defaultMigratableDbSettings' function automatically assigns the postgres -- @JSON@ type to fields with this type. newtype PgJSON a = PgJSON a-  deriving ( Show, Eq, Ord, Hashable, Monoid )+  deriving ( Show, Eq, Ord, Hashable, Monoid, Semigroup )  instance HasSqlEqualityCheck PgExpressionSyntax (PgJSON a) instance HasSqlQuantifiedEqualityCheck PgExpressionSyntax (PgJSON a)@@ -416,7 +712,7 @@ -- -- Fields with this type are automatically given the Postgres @JSONB@ type newtype PgJSONB a = PgJSONB a-  deriving ( Show, Eq, Ord, Hashable, Monoid )+  deriving ( Show, Eq, Ord, Hashable, Monoid, Semigroup )  instance HasSqlEqualityCheck PgExpressionSyntax (PgJSONB a) instance HasSqlQuantifiedEqualityCheck PgExpressionSyntax (PgJSONB a)@@ -977,6 +1273,23 @@ -- -- 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 --
Database/Beam/Postgres/Syntax.hs view
@@ -178,11 +178,11 @@   = PgSyntax { buildPgSyntax :: PgSyntaxM () }  instance Semigroup PgSyntax where-  (<>) = mappend+  a <> b = PgSyntax (buildPgSyntax a >> buildPgSyntax b)  instance Monoid PgSyntax where   mempty = PgSyntax (pure ())-  mappend a b = PgSyntax (buildPgSyntax a >> buildPgSyntax b)+  mappend = (<>)  instance Eq PgSyntax where   PgSyntax x == PgSyntax y = (fromF x :: Free PgSyntaxF ()) == fromF y@@ -425,10 +425,13 @@ instance IsSql92DeleteSyntax PgDeleteSyntax where   type Sql92DeleteExpressionSyntax PgDeleteSyntax = PgExpressionSyntax -  deleteStmt tbl where_ =+  deleteStmt tbl alias where_ =     PgDeleteSyntax $     emit "DELETE FROM " <> pgQuotedIdentifier tbl <>+    maybe mempty (\alias_ -> emit " AS " <> pgQuotedIdentifier alias_) alias <>     maybe mempty (\where_ -> emit " WHERE " <> fromPgExpression where_) where_++  deleteSupportsAlias _ = True  instance IsSql92SelectSyntax PgSelectSyntax where   type Sql92SelectSelectTableSyntax PgSelectSyntax = PgSelectTableSyntax
beam-postgres.cabal view
@@ -1,5 +1,5 @@ name:                 beam-postgres-version:              0.3.2.0+version:              0.3.2.2 synopsis:             Connection layer between beam and postgres description:          Beam driver for <https://www.postgresql.org/ PostgreSQL>, an advanced open-source RDBMS homepage:             http://tathougies.github.io/beam/user-guide/backends/beam-postgres@@ -43,7 +43,7 @@                       monad-control        >=1.0  && <1.1,                       mtl                  >=2.1  && <2.3,                       conduit              >=1.2  && <1.4,-                      aeson                >=0.11 && <1.3,+                      aeson                >=0.11 && <1.5,                       uuid-types           >=1.0  && <1.1,                       case-insensitive     >=1.2  && <1.3,                       scientific           >=0.3  && <0.4,@@ -70,4 +70,3 @@   type: git   location: https://github.com/tathougies/beam.git   subdir: beam-postgres-