1212{-# LANGUAGE TypeOperators #-}
1313{-# LANGUAGE ScopedTypeVariables #-}
1414{-# LANGUAGE FlexibleInstances #-}
15+ {-# LANGUAGE RecordWildCards #-}
16+ {-# LANGUAGE LambdaCase #-}
1517
1618{-|
1719 Module: Database.PostgreSQL.Simple.Bind.Representation
@@ -58,19 +60,33 @@ data PostgresBindException
5860instance Exception PostgresBindException
5961
6062
61- -- | Representation of a function's argument (name, type, is optional).
62- data PGArgument = PGArgument String String Bool deriving (Show , Eq )
63+ -- | Representation of a function's argument.
64+ data PGArgument = PGArgument {
65+ pgaName :: String
66+ , pgaType :: String
67+ , pgaOptional :: Bool
68+ } deriving (Show , Eq )
6369
6470-- | Representation of a PostrgeSQL function signature (schema, name, arguments, result).
65- data PGFunction = PGFunction String String [PGArgument ] PGResult deriving (Show , Eq )
71+ data PGFunction = PGFunction {
72+ pgfSchema :: String
73+ , pgfName :: String
74+ , pgfArguments :: [PGArgument ]
75+ , pgfResult :: PGResult
76+ } deriving (Show , Eq )
6677
6778-- | Representation of a resultant's column (name, type).
68- data PGColumn = PGColumn String String deriving (Show , Eq )
79+ data PGColumn = PGColumn {
80+ pgcName :: String
81+ , pgcType :: String
82+ } deriving (Show , Eq )
6983
7084-- | Representation of a function's return value.
71- data PGResult = PGSingle String
72- | PGSetOf String
73- | PGTable [PGColumn ] deriving (Show , Eq )
85+ data PGResult
86+ = PGSingle { pgrSinlgeType :: String }
87+ | PGSetOf { pgrSetOfTypes :: String }
88+ | PGTable { pgrTable :: [PGColumn ] }
89+ deriving (Show , Eq )
7490
7591-- | Takes PostgreSQL function signature and represent it as an algebraic data type.
7692parsePGFunction :: (MonadThrow m ) => Text -> m PGFunction
@@ -81,39 +97,36 @@ parsePGFunction s = either
8197 ss = skipSpace
8298
8399 function = do
84- _ <- asciiCI " function"
85- schema <- ss *> ((identifier <* (char ' .' )) <|> (string " " ))
86- name <- ss *> identifier
87- args <- ss *> char ' (' *> (arguments `sepBy` (char ' ,' ))
88- ret <- ss *> char ' )' *> returnType
89- _ <- ss
90- return $ PGFunction (unpack schema) (unpack name) args ret
100+ _ <- asciiCI " function"
101+ pgfSchema <- fmap unpack $ ss *> ((identifier <* (char ' .' )) <|> (string " " ))
102+ pgfName <- fmap unpack $ ss *> identifier
103+ pgfArguments <- ss *> char ' (' *> (arguments `sepBy` (char ' ,' ))
104+ pgfResult <- ss *> char ' )' *> returnType
105+ _ <- ss
106+ return PGFunction { .. }
91107
92108 arguments = do
93- name <- ss *> identifier
94- datatype <- ss *> postgresType
95- def <- ss *> ((asciiCI " default" <|> string " =" ) *> (takeTill (inClass " ,)" ))
96- <|> (string " " ))
109+ pgaName <- fmap unpack $ ss *> identifier
110+ pgaType <- fmap unpack $ ss *> postgresType
111+ pgaOptional <- fmap (( > 0 ) . length ) $ ss *> (
112+ (asciiCI " default" <|> string " =" ) *> (takeTill (inClass " ,)" ))
113+ <|> (string " " ))
97114 -- WARNING: parsing default values requires ability to parse almost arbitraty expressions.
98115 -- Here is a quick and dirty implementation of the parser.
99-
100- return $ PGArgument (unpack name) (unpack datatype) ((length def) > 0 )
116+ return PGArgument {.. }
101117
102118 cols = do
103- name <- ss *> identifier
104- datatype <- ss *> postgresType <* ss
105- return $ PGColumn (unpack name) (unpack datatype)
106-
107- returnType = do
108- ret <- ss *> asciiCI " returns" *> ss *> (
109- asciiCI " setof"
110- <|> asciiCI " table"
111- <|> postgresType)
112-
113- case toLower(ret) of
114- " setof" -> (PGSetOf . unpack) <$> (ss *> postgresType)
115- " table" -> PGTable <$> (ss *> char ' (' *> cols `sepBy` (char ' ,' ) <* ss <* char ' )' )
116- t -> return $ PGSingle (unpack t)
119+ pgcName <- fmap unpack $ ss *> identifier
120+ pgcType <- fmap unpack $ ss *> postgresType <* ss
121+ return PGColumn {.. }
122+
123+ returnType = ss *> asciiCI " returns" *> ss *> (fmap toLower $
124+ asciiCI " setof"
125+ <|> asciiCI " table"
126+ <|> postgresType) >>= \ case
127+ " setof" -> (PGSetOf . unpack) <$> (ss *> postgresType)
128+ " table" -> PGTable <$> (ss *> char ' (' *> cols `sepBy` (char ' ,' ) <* ss <* char ' )' )
129+ t -> return $ PGSingle (unpack t)
117130
118131 identifier = do
119132 s1 <- takeWhile1 (inClass " a-zA-Z_" )
@@ -170,3 +183,4 @@ parsePGFunction s = either
170183 _ -> (modifiers $ Just (n - 1 )))
171184
172185 modifier = (decimal :: Parser Int ) *> ss
186+
0 commit comments