{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFunctor, GeneralizedNewtypeDeriving #-}

------------------------------------------------------------------------------
-- |
-- Module:      Database.PostgreSQL.Simple.Types
-- Copyright:   (c) 2011 MailRank, Inc.
--              (c) 2011-2012 Leon P Smith
-- License:     BSD3
-- Maintainer:  Leon P Smith <leon@melding-monads.com>
-- Stability:   experimental
--
-- Basic types.
--
------------------------------------------------------------------------------

module Database.PostgreSQL.Simple.Types
    (
      Null(..)
    , Default(..)
    , Only(..)
    , In(..)
    , Binary(..)
    , Identifier(..)
    , QualifiedIdentifier(..)
    , Query(..)
    , Oid(..)
    , (:.)(..)
    , Savepoint(..)
    , PGArray(..)
    , Values(..)
    ) where

import           Control.Arrow (first)
import           Data.ByteString (ByteString)
import           Data.Hashable (Hashable(hashWithSalt))
import           Data.Foldable (toList)
import           Data.Monoid (Monoid(..))
import           Data.Semigroup
import           Data.String (IsString(..))
import           Data.Typeable (Typeable)
import           Data.ByteString.Builder ( stringUtf8 )
import qualified Data.ByteString as B
import           Data.Text (Text)
import qualified Data.Text as T
import           Data.Tuple.Only (Only(..))
import           Database.PostgreSQL.LibPQ (Oid(..))
import           Database.PostgreSQL.Simple.Compat (toByteString)

-- | A placeholder for the SQL @NULL@ value.
data Null = Null
          deriving (ReadPrec [Null]
ReadPrec Null
Int -> ReadS Null
ReadS [Null]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Null]
$creadListPrec :: ReadPrec [Null]
readPrec :: ReadPrec Null
$creadPrec :: ReadPrec Null
readList :: ReadS [Null]
$creadList :: ReadS [Null]
readsPrec :: Int -> ReadS Null
$creadsPrec :: Int -> ReadS Null
Read, Int -> Null -> ShowS
[Null] -> ShowS
Null -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Null] -> ShowS
$cshowList :: [Null] -> ShowS
show :: Null -> String
$cshow :: Null -> String
showsPrec :: Int -> Null -> ShowS
$cshowsPrec :: Int -> Null -> ShowS
Show, Typeable)

instance Eq Null where
    Null
_ == :: Null -> Null -> Bool
== Null
_ = Bool
False
    Null
_ /= :: Null -> Null -> Bool
/= Null
_ = Bool
False

-- | A placeholder for the PostgreSQL @DEFAULT@ value.
data Default = Default
           deriving (ReadPrec [Default]
ReadPrec Default
Int -> ReadS Default
ReadS [Default]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Default]
$creadListPrec :: ReadPrec [Default]
readPrec :: ReadPrec Default
$creadPrec :: ReadPrec Default
readList :: ReadS [Default]
$creadList :: ReadS [Default]
readsPrec :: Int -> ReadS Default
$creadsPrec :: Int -> ReadS Default
Read, Int -> Default -> ShowS
[Default] -> ShowS
Default -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Default] -> ShowS
$cshowList :: [Default] -> ShowS
show :: Default -> String
$cshow :: Default -> String
showsPrec :: Int -> Default -> ShowS
$cshowsPrec :: Int -> Default -> ShowS
Show, Typeable)

-- | A query string. This type is intended to make it difficult to
-- construct a SQL query by concatenating string fragments, as that is
-- an extremely common way to accidentally introduce SQL injection
-- vulnerabilities into an application.
--
-- This type is an instance of 'IsString', so the easiest way to
-- construct a query is to enable the @OverloadedStrings@ language
-- extension and then simply write the query in double quotes.
--
-- > {-# LANGUAGE OverloadedStrings #-}
-- >
-- > import Database.PostgreSQL.Simple
-- >
-- > q :: Query
-- > q = "select ?"
--
-- The underlying type is a 'ByteString', and literal Haskell strings
-- that contain Unicode characters will be correctly transformed to
-- UTF-8.
newtype Query = Query {
      Query -> ByteString
fromQuery :: ByteString
    } deriving (Query -> Query -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Query -> Query -> Bool
$c/= :: Query -> Query -> Bool
== :: Query -> Query -> Bool
$c== :: Query -> Query -> Bool
Eq, Eq Query
Query -> Query -> Bool
Query -> Query -> Ordering
Query -> Query -> Query
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 :: Query -> Query -> Query
$cmin :: Query -> Query -> Query
max :: Query -> Query -> Query
$cmax :: Query -> Query -> Query
>= :: Query -> Query -> Bool
$c>= :: Query -> Query -> Bool
> :: Query -> Query -> Bool
$c> :: Query -> Query -> Bool
<= :: Query -> Query -> Bool
$c<= :: Query -> Query -> Bool
< :: Query -> Query -> Bool
$c< :: Query -> Query -> Bool
compare :: Query -> Query -> Ordering
$ccompare :: Query -> Query -> Ordering
Ord, Typeable)

instance Show Query where
    show :: Query -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. Query -> ByteString
fromQuery

instance Read Query where
    readsPrec :: Int -> ReadS Query
readsPrec Int
i = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ByteString -> Query
Query) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Read a => Int -> ReadS a
readsPrec Int
i

instance IsString Query where
    fromString :: String -> Query
fromString = ByteString -> Query
Query forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toByteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder
stringUtf8

instance Semigroup Query where
    Query ByteString
a <> :: Query -> Query -> Query
<> Query ByteString
b = ByteString -> Query
Query (ByteString -> ByteString -> ByteString
B.append ByteString
a ByteString
b)
    {-# INLINE (<>) #-}
    sconcat :: NonEmpty Query -> Query
sconcat NonEmpty Query
xs = ByteString -> Query
Query ([ByteString] -> ByteString
B.concat forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Query -> ByteString
fromQuery forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Query
xs)

instance Monoid Query where
    mempty :: Query
mempty = ByteString -> Query
Query ByteString
B.empty
#if !(MIN_VERSION_base(4,11,0))
    mappend = (<>)
#endif

-- | Wrap a list of values for use in an @IN@ clause.  Replaces a
-- single \"@?@\" character with a parenthesized list of rendered
-- values.
--
-- Example:
--
-- > query c "select * from whatever where id in ?" (Only (In [3,4,5]))
--
-- Note that @In []@ expands to @(null)@, which works as expected in
-- the query above, but evaluates to the logical null value on every
-- row instead of @TRUE@.  This means that changing the query above
-- to @... id NOT in ?@ and supplying the empty list as the parameter
-- returns zero rows, instead of all of them as one would expect.
--
-- Since postgresql doesn't seem to provide a syntax for actually specifying
-- an empty list,  which could solve this completely,  there are two
-- workarounds particularly worth mentioning,  namely:
--
-- 1.  Use postgresql-simple's 'Values' type instead,  which can handle the
--     empty case correctly.  Note however that while specifying the
--     postgresql type @"int4"@ is mandatory in the empty case,  specifying
--     the haskell type @Values (Only Int)@ would not normally be needed in
--     realistic use cases.
--
--     > query c "select * from whatever where id not in ?"
--     >         (Only (Values ["int4"] [] :: Values (Only Int)))
--
--
-- 2.  Use sql's @COALESCE@ operator to turn a logical @null@ into the correct
--     boolean.  Note however that the correct boolean depends on the use
--     case:
--
--     > query c "select * from whatever where coalesce(id NOT in ?, TRUE)"
--     >         (Only (In [] :: In [Int]))
--
--     > query c "select * from whatever where coalesce(id IN ?, FALSE)"
--     >         (Only (In [] :: In [Int]))
--
--     Note that at as of PostgreSQL 9.4,  the query planner cannot see inside
--     the @COALESCE@ operator,  so if you have an index on @id@ then you
--     probably don't want to write the last example with @COALESCE@,  which
--     would result in a table scan.   There are further caveats if @id@ can
--     be null or you want null treated sensibly as a component of @IN@ or
--     @NOT IN@.

newtype In a = In a
    deriving (In a -> In a -> Bool
forall a. Eq a => In a -> In a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: In a -> In a -> Bool
$c/= :: forall a. Eq a => In a -> In a -> Bool
== :: In a -> In a -> Bool
$c== :: forall a. Eq a => In a -> In a -> Bool
Eq, In a -> In a -> Bool
In a -> In a -> Ordering
In a -> In a -> In 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 (In a)
forall a. Ord a => In a -> In a -> Bool
forall a. Ord a => In a -> In a -> Ordering
forall a. Ord a => In a -> In a -> In a
min :: In a -> In a -> In a
$cmin :: forall a. Ord a => In a -> In a -> In a
max :: In a -> In a -> In a
$cmax :: forall a. Ord a => In a -> In a -> In a
>= :: In a -> In a -> Bool
$c>= :: forall a. Ord a => In a -> In a -> Bool
> :: In a -> In a -> Bool
$c> :: forall a. Ord a => In a -> In a -> Bool
<= :: In a -> In a -> Bool
$c<= :: forall a. Ord a => In a -> In a -> Bool
< :: In a -> In a -> Bool
$c< :: forall a. Ord a => In a -> In a -> Bool
compare :: In a -> In a -> Ordering
$ccompare :: forall a. Ord a => In a -> In a -> Ordering
Ord, ReadPrec [In a]
ReadPrec (In a)
ReadS [In a]
forall a. Read a => ReadPrec [In a]
forall a. Read a => ReadPrec (In a)
forall a. Read a => Int -> ReadS (In a)
forall a. Read a => ReadS [In a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [In a]
$creadListPrec :: forall a. Read a => ReadPrec [In a]
readPrec :: ReadPrec (In a)
$creadPrec :: forall a. Read a => ReadPrec (In a)
readList :: ReadS [In a]
$creadList :: forall a. Read a => ReadS [In a]
readsPrec :: Int -> ReadS (In a)
$creadsPrec :: forall a. Read a => Int -> ReadS (In a)
Read, Int -> In a -> ShowS
forall a. Show a => Int -> In a -> ShowS
forall a. Show a => [In a] -> ShowS
forall a. Show a => In a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [In a] -> ShowS
$cshowList :: forall a. Show a => [In a] -> ShowS
show :: In a -> String
$cshow :: forall a. Show a => In a -> String
showsPrec :: Int -> In a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> In a -> ShowS
Show, Typeable, forall a b. a -> In b -> In a
forall a b. (a -> b) -> In a -> In b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> In b -> In a
$c<$ :: forall a b. a -> In b -> In a
fmap :: forall a b. (a -> b) -> In a -> In b
$cfmap :: forall a b. (a -> b) -> In a -> In b
Functor)

-- | Wrap binary data for use as a @bytea@ value.
newtype Binary a = Binary {forall a. Binary a -> a
fromBinary :: a}
    deriving (Binary a -> Binary a -> Bool
forall a. Eq a => Binary a -> Binary a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Binary a -> Binary a -> Bool
$c/= :: forall a. Eq a => Binary a -> Binary a -> Bool
== :: Binary a -> Binary a -> Bool
$c== :: forall a. Eq a => Binary a -> Binary a -> Bool
Eq, Binary a -> Binary a -> Bool
Binary a -> Binary a -> Ordering
Binary a -> Binary a -> Binary 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 (Binary a)
forall a. Ord a => Binary a -> Binary a -> Bool
forall a. Ord a => Binary a -> Binary a -> Ordering
forall a. Ord a => Binary a -> Binary a -> Binary a
min :: Binary a -> Binary a -> Binary a
$cmin :: forall a. Ord a => Binary a -> Binary a -> Binary a
max :: Binary a -> Binary a -> Binary a
$cmax :: forall a. Ord a => Binary a -> Binary a -> Binary a
>= :: Binary a -> Binary a -> Bool
$c>= :: forall a. Ord a => Binary a -> Binary a -> Bool
> :: Binary a -> Binary a -> Bool
$c> :: forall a. Ord a => Binary a -> Binary a -> Bool
<= :: Binary a -> Binary a -> Bool
$c<= :: forall a. Ord a => Binary a -> Binary a -> Bool
< :: Binary a -> Binary a -> Bool
$c< :: forall a. Ord a => Binary a -> Binary a -> Bool
compare :: Binary a -> Binary a -> Ordering
$ccompare :: forall a. Ord a => Binary a -> Binary a -> Ordering
Ord, ReadPrec [Binary a]
ReadPrec (Binary a)
ReadS [Binary a]
forall a. Read a => ReadPrec [Binary a]
forall a. Read a => ReadPrec (Binary a)
forall a. Read a => Int -> ReadS (Binary a)
forall a. Read a => ReadS [Binary a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Binary a]
$creadListPrec :: forall a. Read a => ReadPrec [Binary a]
readPrec :: ReadPrec (Binary a)
$creadPrec :: forall a. Read a => ReadPrec (Binary a)
readList :: ReadS [Binary a]
$creadList :: forall a. Read a => ReadS [Binary a]
readsPrec :: Int -> ReadS (Binary a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Binary a)
Read, Int -> Binary a -> ShowS
forall a. Show a => Int -> Binary a -> ShowS
forall a. Show a => [Binary a] -> ShowS
forall a. Show a => Binary a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Binary a] -> ShowS
$cshowList :: forall a. Show a => [Binary a] -> ShowS
show :: Binary a -> String
$cshow :: forall a. Show a => Binary a -> String
showsPrec :: Int -> Binary a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Binary a -> ShowS
Show, Typeable, forall a b. a -> Binary b -> Binary a
forall a b. (a -> b) -> Binary a -> Binary b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Binary b -> Binary a
$c<$ :: forall a b. a -> Binary b -> Binary a
fmap :: forall a b. (a -> b) -> Binary a -> Binary b
$cfmap :: forall a b. (a -> b) -> Binary a -> Binary b
Functor)

-- | Wrap text for use as sql identifier, i.e. a table or column name.
newtype Identifier = Identifier {Identifier -> Text
fromIdentifier :: Text}
    deriving (Identifier -> Identifier -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Identifier -> Identifier -> Bool
$c/= :: Identifier -> Identifier -> Bool
== :: Identifier -> Identifier -> Bool
$c== :: Identifier -> Identifier -> Bool
Eq, Eq Identifier
Identifier -> Identifier -> Bool
Identifier -> Identifier -> Ordering
Identifier -> Identifier -> Identifier
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 :: Identifier -> Identifier -> Identifier
$cmin :: Identifier -> Identifier -> Identifier
max :: Identifier -> Identifier -> Identifier
$cmax :: Identifier -> Identifier -> Identifier
>= :: Identifier -> Identifier -> Bool
$c>= :: Identifier -> Identifier -> Bool
> :: Identifier -> Identifier -> Bool
$c> :: Identifier -> Identifier -> Bool
<= :: Identifier -> Identifier -> Bool
$c<= :: Identifier -> Identifier -> Bool
< :: Identifier -> Identifier -> Bool
$c< :: Identifier -> Identifier -> Bool
compare :: Identifier -> Identifier -> Ordering
$ccompare :: Identifier -> Identifier -> Ordering
Ord, ReadPrec [Identifier]
ReadPrec Identifier
Int -> ReadS Identifier
ReadS [Identifier]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Identifier]
$creadListPrec :: ReadPrec [Identifier]
readPrec :: ReadPrec Identifier
$creadPrec :: ReadPrec Identifier
readList :: ReadS [Identifier]
$creadList :: ReadS [Identifier]
readsPrec :: Int -> ReadS Identifier
$creadsPrec :: Int -> ReadS Identifier
Read, Int -> Identifier -> ShowS
[Identifier] -> ShowS
Identifier -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Identifier] -> ShowS
$cshowList :: [Identifier] -> ShowS
show :: Identifier -> String
$cshow :: Identifier -> String
showsPrec :: Int -> Identifier -> ShowS
$cshowsPrec :: Int -> Identifier -> ShowS
Show, Typeable, String -> Identifier
forall a. (String -> a) -> IsString a
fromString :: String -> Identifier
$cfromString :: String -> Identifier
IsString)

instance Hashable Identifier where
    hashWithSalt :: Int -> Identifier -> Int
hashWithSalt Int
i (Identifier Text
t) = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i Text
t

-- | Wrap text for use as (maybe) qualified identifier, i.e. a table
-- with schema, or column with table.
data QualifiedIdentifier = QualifiedIdentifier (Maybe Text) Text
    deriving (QualifiedIdentifier -> QualifiedIdentifier -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c/= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
== :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c== :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
Eq, Eq QualifiedIdentifier
QualifiedIdentifier -> QualifiedIdentifier -> Bool
QualifiedIdentifier -> QualifiedIdentifier -> Ordering
QualifiedIdentifier -> QualifiedIdentifier -> QualifiedIdentifier
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 :: QualifiedIdentifier -> QualifiedIdentifier -> QualifiedIdentifier
$cmin :: QualifiedIdentifier -> QualifiedIdentifier -> QualifiedIdentifier
max :: QualifiedIdentifier -> QualifiedIdentifier -> QualifiedIdentifier
$cmax :: QualifiedIdentifier -> QualifiedIdentifier -> QualifiedIdentifier
>= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c>= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
> :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c> :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
<= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c<= :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
< :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
$c< :: QualifiedIdentifier -> QualifiedIdentifier -> Bool
compare :: QualifiedIdentifier -> QualifiedIdentifier -> Ordering
$ccompare :: QualifiedIdentifier -> QualifiedIdentifier -> Ordering
Ord, ReadPrec [QualifiedIdentifier]
ReadPrec QualifiedIdentifier
Int -> ReadS QualifiedIdentifier
ReadS [QualifiedIdentifier]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [QualifiedIdentifier]
$creadListPrec :: ReadPrec [QualifiedIdentifier]
readPrec :: ReadPrec QualifiedIdentifier
$creadPrec :: ReadPrec QualifiedIdentifier
readList :: ReadS [QualifiedIdentifier]
$creadList :: ReadS [QualifiedIdentifier]
readsPrec :: Int -> ReadS QualifiedIdentifier
$creadsPrec :: Int -> ReadS QualifiedIdentifier
Read, Int -> QualifiedIdentifier -> ShowS
[QualifiedIdentifier] -> ShowS
QualifiedIdentifier -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QualifiedIdentifier] -> ShowS
$cshowList :: [QualifiedIdentifier] -> ShowS
show :: QualifiedIdentifier -> String
$cshow :: QualifiedIdentifier -> String
showsPrec :: Int -> QualifiedIdentifier -> ShowS
$cshowsPrec :: Int -> QualifiedIdentifier -> ShowS
Show, Typeable)

instance Hashable QualifiedIdentifier where
    hashWithSalt :: Int -> QualifiedIdentifier -> Int
hashWithSalt Int
i (QualifiedIdentifier Maybe Text
q Text
t) = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i (Maybe Text
q, Text
t)

-- | @\"foo.bar\"@ will get turned into
-- @QualifiedIdentifier (Just \"foo\") \"bar\"@,  while @\"foo\"@ will get
-- turned into @QualifiedIdentifier Nothing \"foo\"@.   Note this instance
-- is for convenience,  and does not match postgres syntax.   It
-- only examines the first period character,  and thus cannot be used if the
-- qualifying identifier contains a period for example.

instance IsString QualifiedIdentifier where
    fromString :: String -> QualifiedIdentifier
fromString String
str = let (Text
x,Text
y) = (Char -> Bool) -> Text -> (Text, Text)
T.break (forall a. Eq a => a -> a -> Bool
== Char
'.') (forall a. IsString a => String -> a
fromString String
str)
                      in if Text -> Bool
T.null Text
y
                         then Maybe Text -> Text -> QualifiedIdentifier
QualifiedIdentifier forall a. Maybe a
Nothing Text
x
                         else Maybe Text -> Text -> QualifiedIdentifier
QualifiedIdentifier (forall a. a -> Maybe a
Just Text
x) (Text -> Text
T.tail Text
y)

-- | Wrap a list for use as a PostgreSQL array.
newtype PGArray a = PGArray {forall a. PGArray a -> [a]
fromPGArray :: [a]}
    deriving (PGArray a -> PGArray a -> Bool
forall a. Eq a => PGArray a -> PGArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PGArray a -> PGArray a -> Bool
$c/= :: forall a. Eq a => PGArray a -> PGArray a -> Bool
== :: PGArray a -> PGArray a -> Bool
$c== :: forall a. Eq a => PGArray a -> PGArray a -> Bool
Eq, PGArray a -> PGArray a -> Bool
PGArray a -> PGArray a -> Ordering
PGArray a -> PGArray a -> PGArray 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 (PGArray a)
forall a. Ord a => PGArray a -> PGArray a -> Bool
forall a. Ord a => PGArray a -> PGArray a -> Ordering
forall a. Ord a => PGArray a -> PGArray a -> PGArray a
min :: PGArray a -> PGArray a -> PGArray a
$cmin :: forall a. Ord a => PGArray a -> PGArray a -> PGArray a
max :: PGArray a -> PGArray a -> PGArray a
$cmax :: forall a. Ord a => PGArray a -> PGArray a -> PGArray a
>= :: PGArray a -> PGArray a -> Bool
$c>= :: forall a. Ord a => PGArray a -> PGArray a -> Bool
> :: PGArray a -> PGArray a -> Bool
$c> :: forall a. Ord a => PGArray a -> PGArray a -> Bool
<= :: PGArray a -> PGArray a -> Bool
$c<= :: forall a. Ord a => PGArray a -> PGArray a -> Bool
< :: PGArray a -> PGArray a -> Bool
$c< :: forall a. Ord a => PGArray a -> PGArray a -> Bool
compare :: PGArray a -> PGArray a -> Ordering
$ccompare :: forall a. Ord a => PGArray a -> PGArray a -> Ordering
Ord, ReadPrec [PGArray a]
ReadPrec (PGArray a)
ReadS [PGArray a]
forall a. Read a => ReadPrec [PGArray a]
forall a. Read a => ReadPrec (PGArray a)
forall a. Read a => Int -> ReadS (PGArray a)
forall a. Read a => ReadS [PGArray a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PGArray a]
$creadListPrec :: forall a. Read a => ReadPrec [PGArray a]
readPrec :: ReadPrec (PGArray a)
$creadPrec :: forall a. Read a => ReadPrec (PGArray a)
readList :: ReadS [PGArray a]
$creadList :: forall a. Read a => ReadS [PGArray a]
readsPrec :: Int -> ReadS (PGArray a)
$creadsPrec :: forall a. Read a => Int -> ReadS (PGArray a)
Read, Int -> PGArray a -> ShowS
forall a. Show a => Int -> PGArray a -> ShowS
forall a. Show a => [PGArray a] -> ShowS
forall a. Show a => PGArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PGArray a] -> ShowS
$cshowList :: forall a. Show a => [PGArray a] -> ShowS
show :: PGArray a -> String
$cshow :: forall a. Show a => PGArray a -> String
showsPrec :: Int -> PGArray a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PGArray a -> ShowS
Show, Typeable, forall a b. a -> PGArray b -> PGArray a
forall a b. (a -> b) -> PGArray a -> PGArray b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> PGArray b -> PGArray a
$c<$ :: forall a b. a -> PGArray b -> PGArray a
fmap :: forall a b. (a -> b) -> PGArray a -> PGArray b
$cfmap :: forall a b. (a -> b) -> PGArray a -> PGArray b
Functor)

-- | A composite type to parse your custom data structures without
-- having to define dummy newtype wrappers every time.
--
--
-- > instance FromRow MyData where ...
--
-- > instance FromRow MyData2 where ...
--
--
-- then I can do the following for free:
--
-- @
-- res <- query' c "..."
-- forM res $ \\(MyData{..} :. MyData2{..}) -> do
--   ....
-- @
data h :. t = h :. t deriving ((h :. t) -> (h :. t) -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall h t. (Eq h, Eq t) => (h :. t) -> (h :. t) -> Bool
/= :: (h :. t) -> (h :. t) -> Bool
$c/= :: forall h t. (Eq h, Eq t) => (h :. t) -> (h :. t) -> Bool
== :: (h :. t) -> (h :. t) -> Bool
$c== :: forall h t. (Eq h, Eq t) => (h :. t) -> (h :. t) -> Bool
Eq,(h :. t) -> (h :. t) -> Bool
(h :. t) -> (h :. t) -> Ordering
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 {h} {t}. (Ord h, Ord t) => Eq (h :. t)
forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Bool
forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Ordering
forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> h :. t
min :: (h :. t) -> (h :. t) -> h :. t
$cmin :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> h :. t
max :: (h :. t) -> (h :. t) -> h :. t
$cmax :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> h :. t
>= :: (h :. t) -> (h :. t) -> Bool
$c>= :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Bool
> :: (h :. t) -> (h :. t) -> Bool
$c> :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Bool
<= :: (h :. t) -> (h :. t) -> Bool
$c<= :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Bool
< :: (h :. t) -> (h :. t) -> Bool
$c< :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Bool
compare :: (h :. t) -> (h :. t) -> Ordering
$ccompare :: forall h t. (Ord h, Ord t) => (h :. t) -> (h :. t) -> Ordering
Ord,Int -> (h :. t) -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall h t. (Show h, Show t) => Int -> (h :. t) -> ShowS
forall h t. (Show h, Show t) => [h :. t] -> ShowS
forall h t. (Show h, Show t) => (h :. t) -> String
showList :: [h :. t] -> ShowS
$cshowList :: forall h t. (Show h, Show t) => [h :. t] -> ShowS
show :: (h :. t) -> String
$cshow :: forall h t. (Show h, Show t) => (h :. t) -> String
showsPrec :: Int -> (h :. t) -> ShowS
$cshowsPrec :: forall h t. (Show h, Show t) => Int -> (h :. t) -> ShowS
Show,ReadPrec [h :. t]
ReadPrec (h :. t)
ReadS [h :. t]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall h t. (Read h, Read t) => ReadPrec [h :. t]
forall h t. (Read h, Read t) => ReadPrec (h :. t)
forall h t. (Read h, Read t) => Int -> ReadS (h :. t)
forall h t. (Read h, Read t) => ReadS [h :. t]
readListPrec :: ReadPrec [h :. t]
$creadListPrec :: forall h t. (Read h, Read t) => ReadPrec [h :. t]
readPrec :: ReadPrec (h :. t)
$creadPrec :: forall h t. (Read h, Read t) => ReadPrec (h :. t)
readList :: ReadS [h :. t]
$creadList :: forall h t. (Read h, Read t) => ReadS [h :. t]
readsPrec :: Int -> ReadS (h :. t)
$creadsPrec :: forall h t. (Read h, Read t) => Int -> ReadS (h :. t)
Read,Typeable)

infixr 3 :.

newtype Savepoint = Savepoint Query
    deriving (Savepoint -> Savepoint -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Savepoint -> Savepoint -> Bool
$c/= :: Savepoint -> Savepoint -> Bool
== :: Savepoint -> Savepoint -> Bool
$c== :: Savepoint -> Savepoint -> Bool
Eq, Eq Savepoint
Savepoint -> Savepoint -> Bool
Savepoint -> Savepoint -> Ordering
Savepoint -> Savepoint -> Savepoint
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 :: Savepoint -> Savepoint -> Savepoint
$cmin :: Savepoint -> Savepoint -> Savepoint
max :: Savepoint -> Savepoint -> Savepoint
$cmax :: Savepoint -> Savepoint -> Savepoint
>= :: Savepoint -> Savepoint -> Bool
$c>= :: Savepoint -> Savepoint -> Bool
> :: Savepoint -> Savepoint -> Bool
$c> :: Savepoint -> Savepoint -> Bool
<= :: Savepoint -> Savepoint -> Bool
$c<= :: Savepoint -> Savepoint -> Bool
< :: Savepoint -> Savepoint -> Bool
$c< :: Savepoint -> Savepoint -> Bool
compare :: Savepoint -> Savepoint -> Ordering
$ccompare :: Savepoint -> Savepoint -> Ordering
Ord, Int -> Savepoint -> ShowS
[Savepoint] -> ShowS
Savepoint -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Savepoint] -> ShowS
$cshowList :: [Savepoint] -> ShowS
show :: Savepoint -> String
$cshow :: Savepoint -> String
showsPrec :: Int -> Savepoint -> ShowS
$cshowsPrec :: Int -> Savepoint -> ShowS
Show, ReadPrec [Savepoint]
ReadPrec Savepoint
Int -> ReadS Savepoint
ReadS [Savepoint]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Savepoint]
$creadListPrec :: ReadPrec [Savepoint]
readPrec :: ReadPrec Savepoint
$creadPrec :: ReadPrec Savepoint
readList :: ReadS [Savepoint]
$creadList :: ReadS [Savepoint]
readsPrec :: Int -> ReadS Savepoint
$creadsPrec :: Int -> ReadS Savepoint
Read, Typeable)

-- | Represents a @VALUES@ table literal,  usable as an alternative to
--   'Database.PostgreSQL.Simple.executeMany' and
--   'Database.PostgreSQL.Simple.returning'.  The main advantage is that
--   you can parametrize more than just a single @VALUES@ expression.
--   For example,  here's a query to insert a thing into one table
--   and some attributes of that thing into another,   returning the
--   new id generated by the database:
--
--
-- > query c [sql|
-- >     WITH new_thing AS (
-- >       INSERT INTO thing (name) VALUES (?) RETURNING id
-- >     ), new_attributes AS (
-- >       INSERT INTO thing_attributes
-- >          SELECT new_thing.id, attrs.*
-- >            FROM new_thing JOIN ? attrs ON TRUE
-- >     ) SELECT * FROM new_thing
-- >  |] ("foo", Values [  "int4", "text"    ]
-- >                    [ ( 1    , "hello" )
-- >                    , ( 2    , "world" ) ])
--
--   (Note this example uses writable common table expressions,
--    which were added in PostgreSQL 9.1)
--
--   The second parameter gets expanded into the following SQL syntax:
--
-- > (VALUES (1::"int4",'hello'::"text"),(2,'world'))
--
--   When the list of attributes is empty,  the second parameter expands to:
--
-- > (VALUES (null::"int4",null::"text") LIMIT 0)
--
--   By contrast, @executeMany@ and @returning@ don't issue the query
--   in the empty case, and simply return @0@ and @[]@ respectively.
--   This behavior is usually correct given their intended use cases,
--   but would certainly be wrong in the example above.
--
--   The first argument is a list of postgresql type names.  Because this
--   is turned into a properly quoted identifier,  the type name is case
--   sensitive and must be as it appears in the @pg_type@ table.   Thus,
--   you must write @timestamptz@ instead of @timestamp with time zone@,
--   @int4@ instead of @integer@ or @serial@, @_int8@ instead of @bigint[]@,
--   etcetera.
--
--   You may omit the type names,  however,  if you do so the list
--   of values must be non-empty,  and postgresql must be able to infer
--   the types of the columns from the surrounding context.   If the first
--   condition is not met,  postgresql-simple will throw an exception
--   without issuing the query.   In the second case,  the postgres server
--   will return an error which will be turned into a @SqlError@ exception.
--
--   See <https://www.postgresql.org/docs/9.5/static/sql-values.html> for
--   more information.
data Values a = Values [QualifiedIdentifier] [a]
    deriving (Values a -> Values a -> Bool
forall a. Eq a => Values a -> Values a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Values a -> Values a -> Bool
$c/= :: forall a. Eq a => Values a -> Values a -> Bool
== :: Values a -> Values a -> Bool
$c== :: forall a. Eq a => Values a -> Values a -> Bool
Eq, Values a -> Values a -> Bool
Values a -> Values a -> Ordering
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 (Values a)
forall a. Ord a => Values a -> Values a -> Bool
forall a. Ord a => Values a -> Values a -> Ordering
forall a. Ord a => Values a -> Values a -> Values a
min :: Values a -> Values a -> Values a
$cmin :: forall a. Ord a => Values a -> Values a -> Values a
max :: Values a -> Values a -> Values a
$cmax :: forall a. Ord a => Values a -> Values a -> Values a
>= :: Values a -> Values a -> Bool
$c>= :: forall a. Ord a => Values a -> Values a -> Bool
> :: Values a -> Values a -> Bool
$c> :: forall a. Ord a => Values a -> Values a -> Bool
<= :: Values a -> Values a -> Bool
$c<= :: forall a. Ord a => Values a -> Values a -> Bool
< :: Values a -> Values a -> Bool
$c< :: forall a. Ord a => Values a -> Values a -> Bool
compare :: Values a -> Values a -> Ordering
$ccompare :: forall a. Ord a => Values a -> Values a -> Ordering
Ord, Int -> Values a -> ShowS
forall a. Show a => Int -> Values a -> ShowS
forall a. Show a => [Values a] -> ShowS
forall a. Show a => Values a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Values a] -> ShowS
$cshowList :: forall a. Show a => [Values a] -> ShowS
show :: Values a -> String
$cshow :: forall a. Show a => Values a -> String
showsPrec :: Int -> Values a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Values a -> ShowS
Show, ReadPrec [Values a]
ReadPrec (Values a)
ReadS [Values a]
forall a. Read a => ReadPrec [Values a]
forall a. Read a => ReadPrec (Values a)
forall a. Read a => Int -> ReadS (Values a)
forall a. Read a => ReadS [Values a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Values a]
$creadListPrec :: forall a. Read a => ReadPrec [Values a]
readPrec :: ReadPrec (Values a)
$creadPrec :: forall a. Read a => ReadPrec (Values a)
readList :: ReadS [Values a]
$creadList :: forall a. Read a => ReadS [Values a]
readsPrec :: Int -> ReadS (Values a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Values a)
Read, Typeable)