Skip to content
This repository was archived by the owner on Jan 25, 2024. It is now read-only.

Commit 361e088

Browse files
committed
exec, query: factor out common parameter handling helpers
There were two identical copies each of the parameter mangling code.
1 parent 7441ca8 commit 361e088

File tree

1 file changed

+78
-89
lines changed

1 file changed

+78
-89
lines changed

src/Database/PostgreSQL/LibPQ.hsc

Lines changed: 78 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,61 @@ newtype Oid = Oid CUInt deriving (Eq, Ord, Read, Show, Storable, Typeable)
746746
invalidOid :: Oid
747747
invalidOid = Oid (#const InvalidOid)
748748

749+
750+
-- | Convert a list of parameters to the format expected by libpq FFI calls.
751+
withParams :: [Maybe (Oid, B.ByteString, Format)]
752+
-> (CInt -> Ptr Oid -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
753+
-> IO a
754+
withParams params action =
755+
withArray oids $ \ts ->
756+
withMany (maybeWith B.useAsCString) values $ \c_values ->
757+
withArray c_values $ \vs ->
758+
withArray c_lengths $ \ls ->
759+
withArray formats $ \fs ->
760+
action n ts vs ls fs
761+
where
762+
(oids, values, lengths, formats) =
763+
foldl' accum ([],[],[],[]) $ reverse params
764+
!c_lengths = map toEnum lengths :: [CInt]
765+
!n = toEnum $ length params
766+
767+
accum (!a,!b,!c,!d) Nothing = ( invalidOid:a
768+
, Nothing:b
769+
, 0:c
770+
, 0:d
771+
)
772+
accum (!a,!b,!c,!d) (Just (t,v,f)) = ( t:a
773+
, (Just v):b
774+
, (B.length v):c
775+
, (toEnum $ fromEnum f):d
776+
)
777+
778+
-- | Convert a list of parameters to the format expected by libpq FFI calls,
779+
-- prepared statement variant.
780+
withParamsPrepared :: [Maybe (B.ByteString, Format)]
781+
-> (CInt -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
782+
-> IO a
783+
withParamsPrepared params action =
784+
withMany (maybeWith B.useAsCString) values $ \c_values ->
785+
withArray c_values $ \vs ->
786+
withArray c_lengths $ \ls ->
787+
withArray formats $ \fs ->
788+
action n vs ls fs
789+
where
790+
(values, lengths, formats) = foldl' accum ([],[],[]) $ reverse params
791+
!c_lengths = map toEnum lengths :: [CInt]
792+
!n = toEnum $ length params
793+
794+
accum (!a,!b,!c) Nothing = ( Nothing:a
795+
, 0:b
796+
, 0:c
797+
)
798+
accum (!a,!b,!c) (Just (v, f)) = ( (Just v):a
799+
, (B.length v):b
800+
, (toEnum $ fromEnum f):c
801+
)
802+
803+
749804
-- | Submits a command to the server and waits for the result.
750805
--
751806
-- Returns a 'Result' or possibly 'Nothing'. A 'Result' will generally
@@ -812,31 +867,12 @@ execParams :: Connection -- ^ connection
812867
-> Format -- ^ result format
813868
-> IO (Maybe Result) -- ^ result
814869
execParams connection statement params rFmt =
815-
do let (oids, values, lengths, formats) =
816-
foldl' accum ([],[],[],[]) $ reverse params
817-
!c_lengths = map toEnum lengths :: [CInt]
818-
!n = toEnum $ length params
819-
!f = toEnum $ fromEnum rFmt
820-
resultFromConn connection $ \c ->
821-
B.useAsCString statement $ \s ->
822-
withArray oids $ \ts ->
823-
withMany (maybeWith B.useAsCString) values $ \c_values ->
824-
withArray c_values $ \vs ->
825-
withArray c_lengths $ \ls ->
826-
withArray formats $ \fs ->
827-
c_PQexecParams c s n ts vs ls fs f
828-
829-
where
830-
accum (!a,!b,!c,!d) Nothing = ( invalidOid:a
831-
, Nothing:b
832-
, 0:c
833-
, 0:d
834-
)
835-
accum (!a,!b,!c,!d) (Just (t,v,f)) = ( t:a
836-
, (Just v):b
837-
, (B.length v):c
838-
, (toEnum $ fromEnum f):d
839-
)
870+
resultFromConn connection $ \c ->
871+
B.useAsCString statement $ \s ->
872+
withParams params $ \n ts vs ls fs ->
873+
c_PQexecParams c s n ts vs ls fs f
874+
where
875+
!f = toEnum $ fromEnum rFmt
840876

841877

842878
-- | Submits a request to create a prepared statement with the given
@@ -911,28 +947,13 @@ execPrepared :: Connection -- ^ connection
911947
-> [Maybe (B.ByteString, Format)] -- ^ parameters
912948
-> Format -- ^ result format
913949
-> IO (Maybe Result) -- ^ result
914-
execPrepared connection stmtName mPairs rFmt =
915-
do let (values, lengths, formats) = foldl' accum ([],[],[]) $ reverse mPairs
916-
!c_lengths = map toEnum lengths :: [CInt]
917-
!n = toEnum $ length mPairs
918-
!f = toEnum $ fromEnum rFmt
919-
resultFromConn connection $ \c ->
920-
B.useAsCString stmtName $ \s ->
921-
withMany (maybeWith B.useAsCString) values $ \c_values ->
922-
withArray c_values $ \vs ->
923-
withArray c_lengths $ \ls ->
924-
withArray formats $ \fs ->
925-
c_PQexecPrepared c s n vs ls fs f
926-
950+
execPrepared connection stmtName params rFmt =
951+
resultFromConn connection $ \c ->
952+
B.useAsCString stmtName $ \s ->
953+
withParamsPrepared params $ \n vs ls fs ->
954+
c_PQexecPrepared c s n vs ls fs f
927955
where
928-
accum (!a,!b,!c) Nothing = ( Nothing:a
929-
, 0:b
930-
, 0:c
931-
)
932-
accum (!a,!b,!c) (Just (v, f)) = ( (Just v):a
933-
, (B.length v):b
934-
, (toEnum $ fromEnum f):c
935-
)
956+
!f = toEnum $ fromEnum rFmt
936957

937958

938959
-- | Submits a request to obtain information about the specified
@@ -1676,31 +1697,13 @@ sendQueryParams :: Connection
16761697
-> Format
16771698
-> IO Bool
16781699
sendQueryParams connection statement params rFmt =
1679-
do let (oids, values, lengths, formats) =
1680-
foldl' accum ([],[],[],[]) $ reverse params
1681-
!c_lengths = map toEnum lengths :: [CInt]
1682-
!n = toEnum $ length params
1683-
!f = toEnum $ fromEnum rFmt
1684-
enumFromConn connection $ \c ->
1685-
B.useAsCString statement $ \s ->
1686-
withArray oids $ \ts ->
1687-
withMany (maybeWith B.useAsCString) values $ \c_values ->
1688-
withArray c_values $ \vs ->
1689-
withArray c_lengths $ \ls ->
1690-
withArray formats $ \fs ->
1691-
c_PQsendQueryParams c s n ts vs ls fs f
1700+
enumFromConn connection $ \c ->
1701+
B.useAsCString statement $ \s ->
1702+
withParams params $ \n ts vs ls fs ->
1703+
c_PQsendQueryParams c s n ts vs ls fs f
16921704

16931705
where
1694-
accum (!a,!b,!c,!d) Nothing = ( invalidOid:a
1695-
, Nothing:b
1696-
, 0:c
1697-
, 0:d
1698-
)
1699-
accum (!a,!b,!c,!d) (Just (t,v,f)) = ( t:a
1700-
, (Just v):b
1701-
, (B.length v):c
1702-
, (toEnum $ fromEnum f):d
1703-
)
1706+
!f = toEnum $ fromEnum rFmt
17041707

17051708

17061709
-- | Sends a request to create a prepared statement with the given
@@ -1726,28 +1729,14 @@ sendQueryPrepared :: Connection
17261729
-> [Maybe (B.ByteString, Format)]
17271730
-> Format
17281731
-> IO Bool
1729-
sendQueryPrepared connection stmtName mPairs rFmt =
1730-
do let (values, lengths, formats) = foldl' accum ([],[],[]) $ reverse mPairs
1731-
!c_lengths = map toEnum lengths :: [CInt]
1732-
!n = toEnum $ length mPairs
1733-
!f = toEnum $ fromEnum rFmt
1734-
enumFromConn connection $ \c ->
1735-
B.useAsCString stmtName $ \s ->
1736-
withMany (maybeWith B.useAsCString) values $ \c_values ->
1737-
withArray c_values $ \vs ->
1738-
withArray c_lengths $ \ls ->
1739-
withArray formats $ \fs ->
1740-
c_PQsendQueryPrepared c s n vs ls fs f
1732+
sendQueryPrepared connection stmtName params rFmt =
1733+
enumFromConn connection $ \c ->
1734+
B.useAsCString stmtName $ \s ->
1735+
withParamsPrepared params $ \n vs ls fs ->
1736+
c_PQsendQueryPrepared c s n vs ls fs f
17411737

17421738
where
1743-
accum (!a,!b,!c) Nothing = ( Nothing:a
1744-
, 0:b
1745-
, 0:c
1746-
)
1747-
accum (!a,!b,!c) (Just (v, f)) = ( (Just v):a
1748-
, (B.length v):b
1749-
, (toEnum $ fromEnum f):c
1750-
)
1739+
!f = toEnum $ fromEnum rFmt
17511740

17521741

17531742
-- | Submits a request to obtain information about the specified

0 commit comments

Comments
 (0)