module Orville.PostgreSQL.Marshall.SqlType
( SqlType
( SqlType
, sqlTypeExpr
, sqlTypeReferenceExpr
, sqlTypeOid
, sqlTypeMaximumLength
, sqlTypeToSql
, sqlTypeFromSql
, sqlTypeDontDropImplicitDefaultDuringMigrate
)
, integer
, serial
, bigInteger
, bigSerial
, smallInteger
, double
, boolean
, unboundedText
, fixedText
, boundedText
, textSearchVector
, uuid
, date
, timestamp
, timestampWithoutZone
, jsonb
, oid
, foreignRefType
, convertSqlType
, tryConvertSqlType
)
where
import Data.Int (Int16, Int32, Int64)
import Data.Text (Text)
import qualified Data.Time as Time
import qualified Data.UUID as UUID
import qualified Database.PostgreSQL.LibPQ as LibPQ
import qualified Foreign.C.Types as CTypes
import qualified Orville.PostgreSQL.Expr as Expr
import Orville.PostgreSQL.Raw.SqlValue (SqlValue)
import qualified Orville.PostgreSQL.Raw.SqlValue as SqlValue
data SqlType a = SqlType
{ forall a. SqlType a -> DataType
sqlTypeExpr :: Expr.DataType
, forall a. SqlType a -> Maybe DataType
sqlTypeReferenceExpr :: Maybe Expr.DataType
, forall a. SqlType a -> Oid
sqlTypeOid :: LibPQ.Oid
, forall a. SqlType a -> Maybe Int32
sqlTypeMaximumLength :: Maybe Int32
, forall a. SqlType a -> a -> SqlValue
sqlTypeToSql :: a -> SqlValue
, forall a. SqlType a -> SqlValue -> Either String a
sqlTypeFromSql :: SqlValue -> Either String a
, forall a. SqlType a -> Bool
sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
}
integer :: SqlType Int32
integer :: SqlType Int32
integer =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.int
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
23
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Int32 -> SqlValue
sqlTypeToSql = Int32 -> SqlValue
SqlValue.fromInt32
, sqlTypeFromSql :: SqlValue -> Either String Int32
sqlTypeFromSql = SqlValue -> Either String Int32
SqlValue.toInt32
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
serial :: SqlType Int32
serial :: SqlType Int32
serial =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.serial
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = DataType -> Maybe DataType
forall a. a -> Maybe a
Just DataType
Expr.int
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
23
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Int32 -> SqlValue
sqlTypeToSql = Int32 -> SqlValue
SqlValue.fromInt32
, sqlTypeFromSql :: SqlValue -> Either String Int32
sqlTypeFromSql = SqlValue -> Either String Int32
SqlValue.toInt32
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
True
}
bigInteger :: SqlType Int64
bigInteger :: SqlType Int64
bigInteger =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.bigInt
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
20
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Int64 -> SqlValue
sqlTypeToSql = Int64 -> SqlValue
SqlValue.fromInt64
, sqlTypeFromSql :: SqlValue -> Either String Int64
sqlTypeFromSql = SqlValue -> Either String Int64
SqlValue.toInt64
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
bigSerial :: SqlType Int64
bigSerial :: SqlType Int64
bigSerial =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.bigSerial
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = DataType -> Maybe DataType
forall a. a -> Maybe a
Just DataType
Expr.bigInt
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
20
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Int64 -> SqlValue
sqlTypeToSql = Int64 -> SqlValue
SqlValue.fromInt64
, sqlTypeFromSql :: SqlValue -> Either String Int64
sqlTypeFromSql = SqlValue -> Either String Int64
SqlValue.toInt64
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
True
}
smallInteger :: SqlType Int16
smallInteger :: SqlType Int16
smallInteger =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.smallint
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
21
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Int16 -> SqlValue
sqlTypeToSql = Int16 -> SqlValue
SqlValue.fromInt16
, sqlTypeFromSql :: SqlValue -> Either String Int16
sqlTypeFromSql = SqlValue -> Either String Int16
SqlValue.toInt16
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
double :: SqlType Double
double :: SqlType Double
double =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.doublePrecision
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
701
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Double -> SqlValue
sqlTypeToSql = Double -> SqlValue
SqlValue.fromDouble
, sqlTypeFromSql :: SqlValue -> Either String Double
sqlTypeFromSql = SqlValue -> Either String Double
SqlValue.toDouble
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
boolean :: SqlType Bool
boolean :: SqlType Bool
boolean =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.boolean
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
16
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Bool -> SqlValue
sqlTypeToSql = Bool -> SqlValue
SqlValue.fromBool
, sqlTypeFromSql :: SqlValue -> Either String Bool
sqlTypeFromSql = SqlValue -> Either String Bool
SqlValue.toBool
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
unboundedText :: SqlType Text
unboundedText :: SqlType Text
unboundedText =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.text
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
25
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Text -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText
, sqlTypeFromSql :: SqlValue -> Either String Text
sqlTypeFromSql = SqlValue -> Either String Text
SqlValue.toText
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
fixedText :: Int32 -> SqlType Text
fixedText :: Int32 -> SqlType Text
fixedText Int32
len =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = Int32 -> DataType
Expr.char Int32
len
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
1042
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Int32 -> Maybe Int32
forall a. a -> Maybe a
Just Int32
len
, sqlTypeToSql :: Text -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText
, sqlTypeFromSql :: SqlValue -> Either String Text
sqlTypeFromSql = SqlValue -> Either String Text
SqlValue.toText
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
boundedText :: Int32 -> SqlType Text
boundedText :: Int32 -> SqlType Text
boundedText Int32
len =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = Int32 -> DataType
Expr.varchar Int32
len
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
1043
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Int32 -> Maybe Int32
forall a. a -> Maybe a
Just Int32
len
, sqlTypeToSql :: Text -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText
, sqlTypeFromSql :: SqlValue -> Either String Text
sqlTypeFromSql = SqlValue -> Either String Text
SqlValue.toText
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
textSearchVector :: SqlType Text
textSearchVector :: SqlType Text
textSearchVector =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.tsvector
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
3614
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Text -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText
, sqlTypeFromSql :: SqlValue -> Either String Text
sqlTypeFromSql = SqlValue -> Either String Text
SqlValue.toText
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
uuid :: SqlType UUID.UUID
uuid :: SqlType UUID
uuid =
let
uuidFromText :: Text -> Either String UUID
uuidFromText Text
t =
case Text -> Maybe UUID
UUID.fromText Text
t of
Maybe UUID
Nothing -> String -> Either String UUID
forall a b. a -> Either a b
Left String
"Invalid UUID value"
Just UUID
validUuid -> UUID -> Either String UUID
forall a b. b -> Either a b
Right UUID
validUuid
in
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.uuid
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
2950
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: UUID -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText (Text -> SqlValue) -> (UUID -> Text) -> UUID -> SqlValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> Text
UUID.toText
, sqlTypeFromSql :: SqlValue -> Either String UUID
sqlTypeFromSql = \SqlValue
a -> Text -> Either String UUID
uuidFromText (Text -> Either String UUID)
-> Either String Text -> Either String UUID
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SqlValue -> Either String Text
SqlValue.toText SqlValue
a
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
date :: SqlType Time.Day
date :: SqlType Day
date =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.date
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
1082
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Day -> SqlValue
sqlTypeToSql = Day -> SqlValue
SqlValue.fromDay
, sqlTypeFromSql :: SqlValue -> Either String Day
sqlTypeFromSql = SqlValue -> Either String Day
SqlValue.toDay
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
timestamp :: SqlType Time.UTCTime
timestamp :: SqlType UTCTime
timestamp =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.timestampWithZone
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
1184
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: UTCTime -> SqlValue
sqlTypeToSql = UTCTime -> SqlValue
SqlValue.fromUTCTime
, sqlTypeFromSql :: SqlValue -> Either String UTCTime
sqlTypeFromSql = SqlValue -> Either String UTCTime
SqlValue.toUTCTime
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
timestampWithoutZone :: SqlType Time.LocalTime
timestampWithoutZone :: SqlType LocalTime
timestampWithoutZone =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.timestampWithoutZone
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
1114
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: LocalTime -> SqlValue
sqlTypeToSql = LocalTime -> SqlValue
SqlValue.fromLocalTime
, sqlTypeFromSql :: SqlValue -> Either String LocalTime
sqlTypeFromSql = SqlValue -> Either String LocalTime
SqlValue.toLocalTime
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
jsonb :: SqlType Text
jsonb :: SqlType Text
jsonb =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.jsonb
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
3802
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Text -> SqlValue
sqlTypeToSql = Text -> SqlValue
SqlValue.fromText
, sqlTypeFromSql :: SqlValue -> Either String Text
sqlTypeFromSql = SqlValue -> Either String Text
SqlValue.toText
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
oid :: SqlType LibPQ.Oid
oid :: SqlType Oid
oid =
SqlType
{ sqlTypeExpr :: DataType
sqlTypeExpr = DataType
Expr.oid
, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing
, sqlTypeOid :: Oid
sqlTypeOid = CUInt -> Oid
LibPQ.Oid CUInt
26
, sqlTypeMaximumLength :: Maybe Int32
sqlTypeMaximumLength = Maybe Int32
forall a. Maybe a
Nothing
, sqlTypeToSql :: Oid -> SqlValue
sqlTypeToSql = \(LibPQ.Oid (CTypes.CUInt Word32
word)) -> Word32 -> SqlValue
SqlValue.fromWord32 Word32
word
, sqlTypeFromSql :: SqlValue -> Either String Oid
sqlTypeFromSql = (Word32 -> Oid) -> Either String Word32 -> Either String Oid
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CUInt -> Oid
LibPQ.Oid (CUInt -> Oid) -> (Word32 -> CUInt) -> Word32 -> Oid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> CUInt
CTypes.CUInt) (Either String Word32 -> Either String Oid)
-> (SqlValue -> Either String Word32)
-> SqlValue
-> Either String Oid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlValue -> Either String Word32
SqlValue.toWord32
, sqlTypeDontDropImplicitDefaultDuringMigrate :: Bool
sqlTypeDontDropImplicitDefaultDuringMigrate = Bool
False
}
foreignRefType :: SqlType a -> SqlType a
foreignRefType :: forall a. SqlType a -> SqlType a
foreignRefType SqlType a
sqlType =
case SqlType a -> Maybe DataType
forall a. SqlType a -> Maybe DataType
sqlTypeReferenceExpr SqlType a
sqlType of
Maybe DataType
Nothing -> SqlType a
sqlType
Just DataType
refExpr -> SqlType a
sqlType {sqlTypeExpr :: DataType
sqlTypeExpr = DataType
refExpr, sqlTypeReferenceExpr :: Maybe DataType
sqlTypeReferenceExpr = Maybe DataType
forall a. Maybe a
Nothing}
tryConvertSqlType :: (b -> a) -> (a -> Either String b) -> SqlType a -> SqlType b
tryConvertSqlType :: forall b a.
(b -> a) -> (a -> Either String b) -> SqlType a -> SqlType b
tryConvertSqlType b -> a
bToA a -> Either String b
aToB SqlType a
sqlType =
SqlType a
sqlType
{ sqlTypeToSql :: b -> SqlValue
sqlTypeToSql = SqlType a -> a -> SqlValue
forall a. SqlType a -> a -> SqlValue
sqlTypeToSql SqlType a
sqlType (a -> SqlValue) -> (b -> a) -> b -> SqlValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
bToA
, sqlTypeFromSql :: SqlValue -> Either String b
sqlTypeFromSql = \SqlValue
sql -> do
a
a <- SqlType a -> SqlValue -> Either String a
forall a. SqlType a -> SqlValue -> Either String a
sqlTypeFromSql SqlType a
sqlType SqlValue
sql
a -> Either String b
aToB a
a
}
convertSqlType :: (b -> a) -> (a -> b) -> SqlType a -> SqlType b
convertSqlType :: forall b a. (b -> a) -> (a -> b) -> SqlType a -> SqlType b
convertSqlType b -> a
bToA a -> b
aToB =
(b -> a) -> (a -> Either String b) -> SqlType a -> SqlType b
forall b a.
(b -> a) -> (a -> Either String b) -> SqlType a -> SqlType b
tryConvertSqlType b -> a
bToA (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (a -> b) -> a -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
aToB)