Skip to content

Commit 0feb385

Browse files
committed
refactored implementation
1 parent 39489f0 commit 0feb385

2 files changed

Lines changed: 72 additions & 40 deletions

File tree

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

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -165,32 +165,47 @@ mkResultT (PostgresBindOptions {..}) fname (PGTable cs) = do
165165

166166
return (names, context, clause)
167167

168-
-- | Example: [PGArgument "x" "varchar" True, PGArgument "y" "bigint" False] -> (
169-
-- ["x1", "x2"]
170-
-- , [PostgresType "varchar" ~ x1, ToField x1, PostgresType "bigint" ~ x2, ToField x2]
171-
-- , [x1, Maybe x2])
168+
169+
-- | Example: [
170+
-- PGArgument { pgaName = "x", pgaType = "varchar", pgaOptional = True }
171+
-- , PGArgument { pgaName = "y", pgaType = "bigint", pgaOptional = False }
172+
-- ] -> (
173+
-- ["x1", "x2"]
174+
-- , [PostgresType "varchar" ~ x1, ToField x1, PostgresType "bigint" ~ x2, ToField x2]
175+
-- , [x1, Maybe x2]
176+
-- )
172177
mkArgsT :: [PGArgument] -> Q ([Name], [Type], [Type])
173178
mkArgsT cs = do
174179
names <- sequence $ replicate (length cs) (newName "x")
175-
let context = concat $ zipWith (\(PGArgument _ t _) n -> mkContextT ''ToField t n) cs names
180+
let context = concat $ zipWith (\PGArgument {..} n -> mkContextT ''ToField pgaType n) cs names
176181

177182
let defWrap d = case d of
178183
True -> AppT (ConT ''Maybe)
179184
False -> id
180185

181-
let clause = zipWith (\(PGArgument _ _ d) -> (defWrap d) . VarT) cs names
186+
let clause = zipWith (\PGArgument {..} -> (defWrap pgaOptional) . VarT) cs names
182187
return (names, context, clause)
183188

184-
-- | Example: (PGFunction "public" "foo"
185-
-- [PGArgument "x" "varchar" True, PGArgument "y" "bigint" False] (PGSingle "varchar")) -> {
186-
-- foo :: forall x1 x2 x3. (
187-
-- PostgresType "varchar" ~ x1, ToField x1
188-
-- , PostgresType "bigint" ~ x2, ToField x2
189-
-- , PostgresType "varchar" ~ x2, FromField x3) => Connection -> x1 -> Maybe x2 -> x3}
189+
190+
-- | Example: PGFunction {
191+
-- pgfSchema = "public"
192+
-- , pgfName = "foo"
193+
-- , pgfResult = PGSingle "varchar"
194+
-- , pgfArguments = [
195+
-- PGArgument { pgaName = "x", pgaType = "varchar", pgaOptional = True }
196+
-- , PGArgument { pgaName = "y", pgaType = "bigint", pgaOptional = False }
197+
-- ]
198+
-- } -> {
199+
-- foo :: forall x1 x2 x3. (
200+
-- PostgresType "varchar" ~ x1, ToField x1
201+
-- , PostgresType "bigint" ~ x2, ToField x2
202+
-- , PostgresType "varchar" ~ x2, FromField x3
203+
-- ) => Connection -> x1 -> Maybe x2 -> x3
204+
-- }
190205
mkFunctionT :: PostgresBindOptions -> PGFunction -> Q Dec
191-
mkFunctionT opt@(PostgresBindOptions {..}) f@(PGFunction _schema fname args ret) = do
192-
(argNames, argContext, argClause) <- mkArgsT args
193-
(retNames, retContext, retClause) <- mkResultT opt fname ret
206+
mkFunctionT opt@(PostgresBindOptions {..}) f@(PGFunction {..}) = do
207+
(argNames, argContext, argClause) <- mkArgsT pgfArguments
208+
(retNames, retContext, retClause) <- mkResultT opt pgfName pgfResult
194209

195210
let vars = map PlainTV (argNames ++ retNames)
196211
let context = argContext ++ retContext
@@ -201,33 +216,40 @@ mkFunctionT opt@(PostgresBindOptions {..}) f@(PGFunction _schema fname args ret)
201216
return $ SigD (mkName $ pboFunctionName f) $ ForallT vars context clause
202217

203218

204-
-- | Example:
205-
-- (PGFunction "public" "foo"
206-
-- [PGArgument "x" "varchar" True, PGArgument "y" "bigint" False] (PGSingle "varchar"))
207-
-- args -> { Query $ BS.pack $ concat ["select public.foo (", (formatArguments args), ")"] }
219+
-- | Example: PGFunction {
220+
-- pgfSchema = "public"
221+
-- , pgfName = "foo"
222+
-- , pgfResult = PGSingle "varchar"
223+
-- , pgfArguments = [
224+
-- PGArgument { pgaName = "x", pgaType = "varchar", pgaOptional = True }
225+
-- , PGArgument { pgaName = "y", pgaType = "bigint", pgaOptional = False }
226+
-- ]
227+
-- } -> {
228+
-- Query $ BS.pack $ concat ["select public.foo (", (formatArguments args), ")"]
229+
-- }
208230
mkSqlQuery :: PostgresBindOptions -> PGFunction -> Maybe Name -> Exp
209-
mkSqlQuery opt (PGFunction schema fname _args ret) argsName =
231+
mkSqlQuery PostgresBindOptions {..} PGFunction {..} argsName =
210232
toQuery . AppE (VarE 'concat) . ListE $ [
211-
mkStrLit $ concat [prefix opt, " ", functionName, "("]
233+
mkStrLit $ concat [prefix, " ", functionName, "("]
212234
, maybe (mkStrLit "") (\args -> foldl1 AppE [
213235
VarE 'formatArguments
214-
, mkStrLit $ if (pboOlderCallSyntax opt) then " := " else " => "
215-
, VarE $ if (pboExplicitCasts opt) then 'typedPlaceholder else 'untypedPlaceholder
236+
, mkStrLit $ if pboOlderCallSyntax then " := " else " => "
237+
, VarE $ if pboExplicitCasts then 'typedPlaceholder else 'untypedPlaceholder
216238
, VarE args
217239
]) argsName
218240
, mkStrLit ")"] where
219241

220-
prefix (PostgresBindOptions {..}) = case ret of
242+
prefix = case pgfResult of
221243
PGTable _ -> mkSelect AsRow
222244
PGSetOf tname -> mkSelect $ pboSetOfReturnType tname
223245
_ -> mkSelect AsField
224246

225247
mkSelect AsRow = "select * from"
226248
mkSelect AsField = "select"
227249

228-
functionName = case schema of
229-
"" -> fname
230-
_ -> schema ++ "." ++ fname
250+
functionName = case pgfSchema of
251+
"" -> pgfName
252+
_ -> pgfSchema ++ "." ++ pgfName
231253

232254
mkStrLit s = LitE (StringL s)
233255
toQuery = AppE (ConE 'Query) . AppE (VarE 'BS.pack)
@@ -258,21 +280,31 @@ wrapArg (PostgresBindOptions {..}) (PGArgument n t d) argName = foldl1 AppE $ [
258280
, VarE argName]
259281

260282

261-
-- | Example: (PGFunction "public" "foo"
262-
-- [PGArgument "x" "varchar" True, PGArgument "y" "bigint" False] (PGSingle "varchar")) -> {
263-
-- foo conn x1 x2 = query conn
264-
-- (Query $ BS.pack $ concat ["select public.foo (", (formatArguments args), ")"])
265-
-- (filterArguments [MandatoryArg "x1" x1, OptionalArg "x2" x2]) }
283+
-- | Example: PGFunction {
284+
-- pgfSchema = "public"
285+
-- , pgfName = "foo"
286+
-- , pgfResult = PGSingle "varchar"
287+
-- , pgfArguments = [
288+
-- PGArgument { pgaName = "x", pgaType = "varchar", pgaOptional = True }
289+
-- , PGArgument { pgaName = "y", pgaType = "bigint", pgaOptional = False }
290+
-- ]
291+
-- } -> {
292+
-- foo conn x1 x2 = query conn
293+
-- (Query $ BS.pack $ concat ["select public.foo (", (formatArguments args), ")"])
294+
-- (filterArguments [MandatoryArg "x1" x1, OptionalArg "x2" x2])
295+
-- }
266296
mkFunctionE :: PostgresBindOptions -> PGFunction -> Q Dec
267-
mkFunctionE opt@(PostgresBindOptions {..}) f@(PGFunction _schema _fname args ret) = do
268-
names <- sequence $ replicate (length args) (newName "x")
297+
mkFunctionE opt@(PostgresBindOptions {..}) f@(PGFunction {..}) = do
298+
names <- sequence $ replicate (length pgfArguments) (newName "x")
269299
connName <- newName "conn"
270300

271-
argsName <- case (null args) of
301+
argsName <- case (null pgfArguments) of
272302
True -> return Nothing
273303
False -> Just <$> newName "args"
274304

275-
let argsExpr = (VarE 'filterArguments) `AppE` (ListE $ zipWith (wrapArg opt) args names)
305+
let argsExpr = AppE
306+
(VarE 'filterArguments)
307+
(ListE $ zipWith (wrapArg opt) pgfArguments names)
276308

277309
sqlQueryName <- newName "sqlQuery"
278310
let sqlQueryExpr = mkSqlQuery opt f argsName
@@ -291,7 +323,7 @@ mkFunctionE opt@(PostgresBindOptions {..}) f@(PGFunction _schema _fname args ret
291323
(\name -> [VarE 'traceIO, VarE 'show, VarE name])
292324
$ argsName
293325

294-
execQuery = unwrapE opt ret $ foldl1 AppE $ [
326+
execQuery = unwrapE opt pgfResult $ foldl1 AppE $ [
295327
VarE $ maybe 'query_ (const 'query) argsName
296328
, VarE connName
297329
, sqlQueryExpr

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ data PGColumn = PGColumn {
8383

8484
-- | Representation of a function's return value.
8585
data PGResult
86-
= PGSingle { pgrSinlgeType :: String }
87-
| PGSetOf { pgrSetOfTypes :: String }
88-
| PGTable { pgrTable :: [PGColumn] }
86+
= PGSingle String
87+
| PGSetOf String
88+
| PGTable [PGColumn]
8989
deriving (Show, Eq)
9090

9191
-- | Takes PostgreSQL function signature and represent it as an algebraic data type.

0 commit comments

Comments
 (0)