{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}

-- | The various common types commonly used throughout this package are exported here.
module PostgreSQL.Types
  ( Value (..)
  , RegType (..)
  , PackedParam (..)
  , PackedParamPrepared (..)
  , ParserError (..)
  , ParserErrors
  , ProcessorError (..)
  , ProcessorErrors
  , ResultError (..)
  , ResultErrors
  , Error (..)
  , Errors
  , ColumnNum (..)
  , RowNum (..)

    -- * Re-exports
  , PQ.Format (..)
  , PQ.Oid (..)
  , PQ.Connection
  )
where

import           Control.Exception (Exception)
import           Data.ByteString (ByteString)
import           Data.List.NonEmpty (NonEmpty)
import           Data.String (IsString (..))
import           Data.Text (Text)
import qualified Database.PostgreSQL.LibPQ as PQ
import           Foreign.C.Types (CInt)

-- | Value
--
-- @since 0.0.0
data Value
  = Null
  | Value ByteString
  deriving stock
    ( Show -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    )

-- | @since 0.0.0
instance IsString Value where
  fromString :: String -> Value
fromString = ByteString -> Value
Value (ByteString -> Value) -> (String -> ByteString) -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
forall a. IsString a => String -> a
fromString

-- | Postgre's regtype
--
-- @since 0.0.0
newtype RegType = RegType
  { RegType -> Text
unRegType :: Text }
  deriving newtype
    ( Show -- ^ @since 0.0.0
    , Read -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    , IsString -- ^ @since 0.0.0
    )

-- | Packed parameter
--
-- @since 0.0.0
newtype PackedParam = PackedParam (Maybe (PQ.Oid, ByteString, PQ.Format))
  deriving newtype Show -- ^ @since 0.0.0

-- | Packed parameter for a prepared query
--
-- @since 0.0.0
newtype PackedParamPrepared = PackedParamPrepared (Maybe (ByteString, PQ.Format))
  deriving newtype Show -- ^ @since 0.0.0

-- | Error that occurs when parsing a column
--
-- @since 0.0.0
data ParserError
  = UnsupportedFormat PQ.Format
  | UnsupportedOid PQ.Oid
  deriving stock
    ( Show -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    )

type ParserErrors = NonEmpty ParserError

-- | Error that may occur during processing
--
-- @since 0.0.0
data ProcessorError
  = ColumnParserError
    { ProcessorError -> ColumnNum
processorError_column :: ColumnNum
    , ProcessorError -> Oid
processorError_type :: PQ.Oid
    , ProcessorError -> Format
processorError_format :: PQ.Format
    , ProcessorError -> ParserError
processorError_columnError :: ParserError
    }
  | CellParserError
    { processorError_column :: ColumnNum
    , processorError_type :: PQ.Oid
    , processorError_format :: PQ.Format
    , ProcessorError -> RowNum
processorError_row :: RowNum
    , ProcessorError -> Value
processorError_value :: Value
    , ProcessorError -> Text
processorError_cellError :: Text
    }
  | NotEnoughColumns
    { ProcessorError -> ColumnNum
processorError_wantedColumns :: ColumnNum
    , ProcessorError -> ColumnNum
processorError_haveColumns :: ColumnNum
    }
  | MissingNamedColumn
    { ProcessorError -> ByteString
processorError_wantedColumnName :: ByteString
    }
  deriving stock
    ( Show -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    )

type ProcessorErrors = NonEmpty ProcessorError

-- | Error that occurs when validating the result
--
-- @since 0.0.0
data ResultError
  = BadResultStatus
    { ResultError -> ByteString
resultError_status :: ByteString }
  | NoRows
  | MultipleRows
    { ResultError -> RowNum
resultError_numRows :: RowNum }
  | FailedToParseAffectedRows
    { ResultError -> Text
resultError_message :: Text }
  deriving stock
    ( Show -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    )


type ResultErrors = NonEmpty ResultError

-- | @since 0.0.0
data Error
  = ErrorDuringProcessing ProcessorError
  -- ^ Occurs when processing the result table
  | ErrorDuringValidation ResultError
  -- ^ Occurs when validating the result object
  deriving stock
    ( Show -- ^ @since 0.0.0
    , Eq -- ^ @since 0.0.0
    , Ord -- ^ @since 0.0.0
    )
  deriving anyclass Exception -- ^ @since 0.0.0

type Errors = NonEmpty Error

-- | Numberic column identifier
--
-- @since 0.0.0
newtype ColumnNum = ColumnNum
  { ColumnNum -> Column
fromColumnNum :: PQ.Column }
  deriving (Int -> ColumnNum -> ShowS
[ColumnNum] -> ShowS
ColumnNum -> String
(Int -> ColumnNum -> ShowS)
-> (ColumnNum -> String)
-> ([ColumnNum] -> ShowS)
-> Show ColumnNum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColumnNum] -> ShowS
$cshowList :: [ColumnNum] -> ShowS
show :: ColumnNum -> String
$cshow :: ColumnNum -> String
showsPrec :: Int -> ColumnNum -> ShowS
$cshowsPrec :: Int -> ColumnNum -> ShowS
Show, ReadPrec [ColumnNum]
ReadPrec ColumnNum
Int -> ReadS ColumnNum
ReadS [ColumnNum]
(Int -> ReadS ColumnNum)
-> ReadS [ColumnNum]
-> ReadPrec ColumnNum
-> ReadPrec [ColumnNum]
-> Read ColumnNum
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ColumnNum]
$creadListPrec :: ReadPrec [ColumnNum]
readPrec :: ReadPrec ColumnNum
$creadPrec :: ReadPrec ColumnNum
readList :: ReadS [ColumnNum]
$creadList :: ReadS [ColumnNum]
readsPrec :: Int -> ReadS ColumnNum
$creadsPrec :: Int -> ReadS ColumnNum
Read, ColumnNum -> ColumnNum -> Bool
(ColumnNum -> ColumnNum -> Bool)
-> (ColumnNum -> ColumnNum -> Bool) -> Eq ColumnNum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColumnNum -> ColumnNum -> Bool
$c/= :: ColumnNum -> ColumnNum -> Bool
== :: ColumnNum -> ColumnNum -> Bool
$c== :: ColumnNum -> ColumnNum -> Bool
Eq, Eq ColumnNum
Eq ColumnNum
-> (ColumnNum -> ColumnNum -> Ordering)
-> (ColumnNum -> ColumnNum -> Bool)
-> (ColumnNum -> ColumnNum -> Bool)
-> (ColumnNum -> ColumnNum -> Bool)
-> (ColumnNum -> ColumnNum -> Bool)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> Ord ColumnNum
ColumnNum -> ColumnNum -> Bool
ColumnNum -> ColumnNum -> Ordering
ColumnNum -> ColumnNum -> ColumnNum
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 :: ColumnNum -> ColumnNum -> ColumnNum
$cmin :: ColumnNum -> ColumnNum -> ColumnNum
max :: ColumnNum -> ColumnNum -> ColumnNum
$cmax :: ColumnNum -> ColumnNum -> ColumnNum
>= :: ColumnNum -> ColumnNum -> Bool
$c>= :: ColumnNum -> ColumnNum -> Bool
> :: ColumnNum -> ColumnNum -> Bool
$c> :: ColumnNum -> ColumnNum -> Bool
<= :: ColumnNum -> ColumnNum -> Bool
$c<= :: ColumnNum -> ColumnNum -> Bool
< :: ColumnNum -> ColumnNum -> Bool
$c< :: ColumnNum -> ColumnNum -> Bool
compare :: ColumnNum -> ColumnNum -> Ordering
$ccompare :: ColumnNum -> ColumnNum -> Ordering
$cp1Ord :: Eq ColumnNum
Ord, Int -> ColumnNum
ColumnNum -> Int
ColumnNum -> [ColumnNum]
ColumnNum -> ColumnNum
ColumnNum -> ColumnNum -> [ColumnNum]
ColumnNum -> ColumnNum -> ColumnNum -> [ColumnNum]
(ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum)
-> (Int -> ColumnNum)
-> (ColumnNum -> Int)
-> (ColumnNum -> [ColumnNum])
-> (ColumnNum -> ColumnNum -> [ColumnNum])
-> (ColumnNum -> ColumnNum -> [ColumnNum])
-> (ColumnNum -> ColumnNum -> ColumnNum -> [ColumnNum])
-> Enum ColumnNum
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ColumnNum -> ColumnNum -> ColumnNum -> [ColumnNum]
$cenumFromThenTo :: ColumnNum -> ColumnNum -> ColumnNum -> [ColumnNum]
enumFromTo :: ColumnNum -> ColumnNum -> [ColumnNum]
$cenumFromTo :: ColumnNum -> ColumnNum -> [ColumnNum]
enumFromThen :: ColumnNum -> ColumnNum -> [ColumnNum]
$cenumFromThen :: ColumnNum -> ColumnNum -> [ColumnNum]
enumFrom :: ColumnNum -> [ColumnNum]
$cenumFrom :: ColumnNum -> [ColumnNum]
fromEnum :: ColumnNum -> Int
$cfromEnum :: ColumnNum -> Int
toEnum :: Int -> ColumnNum
$ctoEnum :: Int -> ColumnNum
pred :: ColumnNum -> ColumnNum
$cpred :: ColumnNum -> ColumnNum
succ :: ColumnNum -> ColumnNum
$csucc :: ColumnNum -> ColumnNum
Enum, ColumnNum
ColumnNum -> ColumnNum -> Bounded ColumnNum
forall a. a -> a -> Bounded a
maxBound :: ColumnNum
$cmaxBound :: ColumnNum
minBound :: ColumnNum
$cminBound :: ColumnNum
Bounded, Integer -> ColumnNum
ColumnNum -> ColumnNum
ColumnNum -> ColumnNum -> ColumnNum
(ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum)
-> (Integer -> ColumnNum)
-> Num ColumnNum
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> ColumnNum
$cfromInteger :: Integer -> ColumnNum
signum :: ColumnNum -> ColumnNum
$csignum :: ColumnNum -> ColumnNum
abs :: ColumnNum -> ColumnNum
$cabs :: ColumnNum -> ColumnNum
negate :: ColumnNum -> ColumnNum
$cnegate :: ColumnNum -> ColumnNum
* :: ColumnNum -> ColumnNum -> ColumnNum
$c* :: ColumnNum -> ColumnNum -> ColumnNum
- :: ColumnNum -> ColumnNum -> ColumnNum
$c- :: ColumnNum -> ColumnNum -> ColumnNum
+ :: ColumnNum -> ColumnNum -> ColumnNum
$c+ :: ColumnNum -> ColumnNum -> ColumnNum
Num, Enum ColumnNum
Real ColumnNum
Real ColumnNum
-> Enum ColumnNum
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> ColumnNum)
-> (ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum))
-> (ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum))
-> (ColumnNum -> Integer)
-> Integral ColumnNum
ColumnNum -> Integer
ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum)
ColumnNum -> ColumnNum -> ColumnNum
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: ColumnNum -> Integer
$ctoInteger :: ColumnNum -> Integer
divMod :: ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum)
$cdivMod :: ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum)
quotRem :: ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum)
$cquotRem :: ColumnNum -> ColumnNum -> (ColumnNum, ColumnNum)
mod :: ColumnNum -> ColumnNum -> ColumnNum
$cmod :: ColumnNum -> ColumnNum -> ColumnNum
div :: ColumnNum -> ColumnNum -> ColumnNum
$cdiv :: ColumnNum -> ColumnNum -> ColumnNum
rem :: ColumnNum -> ColumnNum -> ColumnNum
$crem :: ColumnNum -> ColumnNum -> ColumnNum
quot :: ColumnNum -> ColumnNum -> ColumnNum
$cquot :: ColumnNum -> ColumnNum -> ColumnNum
$cp2Integral :: Enum ColumnNum
$cp1Integral :: Real ColumnNum
Integral, Num ColumnNum
Ord ColumnNum
Num ColumnNum
-> Ord ColumnNum -> (ColumnNum -> Rational) -> Real ColumnNum
ColumnNum -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: ColumnNum -> Rational
$ctoRational :: ColumnNum -> Rational
$cp2Real :: Ord ColumnNum
$cp1Real :: Num ColumnNum
Real) via CInt

-- | Numberic row identifier
--
-- @since 0.0.0
newtype RowNum = RowNum
  { RowNum -> Row
fromRowNum :: PQ.Row }
  deriving (Int -> RowNum -> ShowS
[RowNum] -> ShowS
RowNum -> String
(Int -> RowNum -> ShowS)
-> (RowNum -> String) -> ([RowNum] -> ShowS) -> Show RowNum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RowNum] -> ShowS
$cshowList :: [RowNum] -> ShowS
show :: RowNum -> String
$cshow :: RowNum -> String
showsPrec :: Int -> RowNum -> ShowS
$cshowsPrec :: Int -> RowNum -> ShowS
Show, ReadPrec [RowNum]
ReadPrec RowNum
Int -> ReadS RowNum
ReadS [RowNum]
(Int -> ReadS RowNum)
-> ReadS [RowNum]
-> ReadPrec RowNum
-> ReadPrec [RowNum]
-> Read RowNum
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RowNum]
$creadListPrec :: ReadPrec [RowNum]
readPrec :: ReadPrec RowNum
$creadPrec :: ReadPrec RowNum
readList :: ReadS [RowNum]
$creadList :: ReadS [RowNum]
readsPrec :: Int -> ReadS RowNum
$creadsPrec :: Int -> ReadS RowNum
Read, RowNum -> RowNum -> Bool
(RowNum -> RowNum -> Bool)
-> (RowNum -> RowNum -> Bool) -> Eq RowNum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RowNum -> RowNum -> Bool
$c/= :: RowNum -> RowNum -> Bool
== :: RowNum -> RowNum -> Bool
$c== :: RowNum -> RowNum -> Bool
Eq, Eq RowNum
Eq RowNum
-> (RowNum -> RowNum -> Ordering)
-> (RowNum -> RowNum -> Bool)
-> (RowNum -> RowNum -> Bool)
-> (RowNum -> RowNum -> Bool)
-> (RowNum -> RowNum -> Bool)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> Ord RowNum
RowNum -> RowNum -> Bool
RowNum -> RowNum -> Ordering
RowNum -> RowNum -> RowNum
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 :: RowNum -> RowNum -> RowNum
$cmin :: RowNum -> RowNum -> RowNum
max :: RowNum -> RowNum -> RowNum
$cmax :: RowNum -> RowNum -> RowNum
>= :: RowNum -> RowNum -> Bool
$c>= :: RowNum -> RowNum -> Bool
> :: RowNum -> RowNum -> Bool
$c> :: RowNum -> RowNum -> Bool
<= :: RowNum -> RowNum -> Bool
$c<= :: RowNum -> RowNum -> Bool
< :: RowNum -> RowNum -> Bool
$c< :: RowNum -> RowNum -> Bool
compare :: RowNum -> RowNum -> Ordering
$ccompare :: RowNum -> RowNum -> Ordering
$cp1Ord :: Eq RowNum
Ord, Int -> RowNum
RowNum -> Int
RowNum -> [RowNum]
RowNum -> RowNum
RowNum -> RowNum -> [RowNum]
RowNum -> RowNum -> RowNum -> [RowNum]
(RowNum -> RowNum)
-> (RowNum -> RowNum)
-> (Int -> RowNum)
-> (RowNum -> Int)
-> (RowNum -> [RowNum])
-> (RowNum -> RowNum -> [RowNum])
-> (RowNum -> RowNum -> [RowNum])
-> (RowNum -> RowNum -> RowNum -> [RowNum])
-> Enum RowNum
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RowNum -> RowNum -> RowNum -> [RowNum]
$cenumFromThenTo :: RowNum -> RowNum -> RowNum -> [RowNum]
enumFromTo :: RowNum -> RowNum -> [RowNum]
$cenumFromTo :: RowNum -> RowNum -> [RowNum]
enumFromThen :: RowNum -> RowNum -> [RowNum]
$cenumFromThen :: RowNum -> RowNum -> [RowNum]
enumFrom :: RowNum -> [RowNum]
$cenumFrom :: RowNum -> [RowNum]
fromEnum :: RowNum -> Int
$cfromEnum :: RowNum -> Int
toEnum :: Int -> RowNum
$ctoEnum :: Int -> RowNum
pred :: RowNum -> RowNum
$cpred :: RowNum -> RowNum
succ :: RowNum -> RowNum
$csucc :: RowNum -> RowNum
Enum, RowNum
RowNum -> RowNum -> Bounded RowNum
forall a. a -> a -> Bounded a
maxBound :: RowNum
$cmaxBound :: RowNum
minBound :: RowNum
$cminBound :: RowNum
Bounded, Integer -> RowNum
RowNum -> RowNum
RowNum -> RowNum -> RowNum
(RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum)
-> (RowNum -> RowNum)
-> (RowNum -> RowNum)
-> (Integer -> RowNum)
-> Num RowNum
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RowNum
$cfromInteger :: Integer -> RowNum
signum :: RowNum -> RowNum
$csignum :: RowNum -> RowNum
abs :: RowNum -> RowNum
$cabs :: RowNum -> RowNum
negate :: RowNum -> RowNum
$cnegate :: RowNum -> RowNum
* :: RowNum -> RowNum -> RowNum
$c* :: RowNum -> RowNum -> RowNum
- :: RowNum -> RowNum -> RowNum
$c- :: RowNum -> RowNum -> RowNum
+ :: RowNum -> RowNum -> RowNum
$c+ :: RowNum -> RowNum -> RowNum
Num, Enum RowNum
Real RowNum
Real RowNum
-> Enum RowNum
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> RowNum)
-> (RowNum -> RowNum -> (RowNum, RowNum))
-> (RowNum -> RowNum -> (RowNum, RowNum))
-> (RowNum -> Integer)
-> Integral RowNum
RowNum -> Integer
RowNum -> RowNum -> (RowNum, RowNum)
RowNum -> RowNum -> RowNum
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: RowNum -> Integer
$ctoInteger :: RowNum -> Integer
divMod :: RowNum -> RowNum -> (RowNum, RowNum)
$cdivMod :: RowNum -> RowNum -> (RowNum, RowNum)
quotRem :: RowNum -> RowNum -> (RowNum, RowNum)
$cquotRem :: RowNum -> RowNum -> (RowNum, RowNum)
mod :: RowNum -> RowNum -> RowNum
$cmod :: RowNum -> RowNum -> RowNum
div :: RowNum -> RowNum -> RowNum
$cdiv :: RowNum -> RowNum -> RowNum
rem :: RowNum -> RowNum -> RowNum
$crem :: RowNum -> RowNum -> RowNum
quot :: RowNum -> RowNum -> RowNum
$cquot :: RowNum -> RowNum -> RowNum
$cp2Integral :: Enum RowNum
$cp1Integral :: Real RowNum
Integral, Num RowNum
Ord RowNum
Num RowNum -> Ord RowNum -> (RowNum -> Rational) -> Real RowNum
RowNum -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: RowNum -> Rational
$ctoRational :: RowNum -> Rational
$cp2Real :: Ord RowNum
$cp1Real :: Num RowNum
Real) via CInt