Skip to content

Commit 39489f0

Browse files
committed
refactored representation
1 parent 3e5528a commit 39489f0

1 file changed

Lines changed: 48 additions & 34 deletions

File tree

src/Database/PostgreSQL/Simple/Bind/Representation.hs

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
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
5860
instance 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.
7692
parsePGFunction :: (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

Comments
 (0)