git.iko.soy/typeable/postgresql-simple
on master help sign in
Merge pull request #32 from solidsnack/returning

Support for RETURNING: multi-row modify with multi-row output

commitb3b0ef2edea966f7dbbee674e4bbef2e46b329f9 authorLeon P Smith <leon@melding-monads.com> dateThu 9 Aug 2012, 08:25 (14 years ago) parentb58cbb17c9f42d
1 file changed+29−1
src/Database/PostgreSQL/Simple.hs+29−1
src/Database/PostgreSQL/Simple.hs+29−1
@@ -43,6 +43,9 @@ module Database.PostgreSQL.Simple
4343 -- ** Modifying multiple rows at once
4444 -- $many
4545
46+ -- ** @RETURNING@: modifications that returns results
47+ -- $returning
48+
4649 -- * Extracting results
4750 -- $result
4851
@@ -86,6 +89,7 @@ module Database.PostgreSQL.Simple
8689 , foldWithOptions_
8790 , forEach
8891 , forEach_
92+ , returning
8993 -- * Statements that do not return results
9094 , execute
9195 , execute_
@@ -193,7 +197,7 @@ formatMany conn q@(Query template) qs = do
193197 return . toByteString . mconcat $ fromByteString before :
194198 intersperse (fromChar ',') bs ++
195199 [fromByteString after]
196− Nothing -> fmtError "syntax error in query template for executeMany" q []
200+ Nothing -> fmtError "syntax error in multi-row template" q []
197201
198202-- Split the input string into three pieces, @before@, @qbits@, and @after@,
199203-- following this grammar:
@@ -344,6 +348,16 @@ executeMany conn q qs = do
344348 result <- exec conn =<< formatMany conn q qs
345349 finishExecute conn q result
346350
351+-- | Execute @INSERT ... RETURNING@, @UPDATE ... RETURNING@, or other SQL
352+-- query that accepts multi-row input and is expected to return results.
353+--
354+-- Throws 'FormatError' if the query could not be formatted correctly.
355+returning :: (ToRow q, FromRow r) => Connection -> Query -> [q] -> IO [r]
356+returning _ _ [] = return []
357+returning conn q qs = do
358+ result <- exec conn =<< formatMany conn q qs
359+ finishQuery conn q result
360+
347361-- | Perform a @SELECT@ or other SQL query that is expected to return
348362-- results. All results are retrieved and converted before this
349363-- function returns.
@@ -856,6 +870,20 @@ fmtError msg q xs = throw FormatError {
856870-- > insert into users (first_name,last_name) values
857871-- > ('Boris','Karloff'),('Ed','Wood')
858872
873+-- $returning
874+--
875+-- The 'returning' function is similar to 'executeMany' but is
876+-- intended for use with multi-tuple @INSERT@ or @UPDATE@ statements
877+-- that make use of @RETURNING@.
878+--
879+-- For example, were there an auto-incrementing @id@ column and
880+-- timestamp column @t@ that defaulted to the present time for the
881+-- @sales@ table, then the following query would insert two new
882+-- sales records and also return their new @id@s and timestamps.
883+--
884+-- > let q = "insert into sales (amount, label) values (?,?) returning id, t"
885+-- > xs :: [(Int, UTCTime)] <- returning conn q [(20,"Chips"),(300,"Wood")]
886+
859887-- $result
860888--
861889-- The 'query' and 'query_' functions return a list of values in the