git.iko.soy/typeable/postgresql-simple
on master help sign in
Convert some mysql-simple documentation to postgresql-simple

This note is a holdover from mysql-simple, and it has been obsolete from the very first release of postgresql-simple. * Ensure that any ResultError that might arise is thrown immediately, rather than some place later in application code that cannot handle it. This issue has been taken care of by the switch to the Either type, Thanks to Doug Beardsley for bringing this to my attention.

commit5f045cc5c80d05b693a3d85a0f7634f7c3bcb471 authorLeon P Smith <leon@melding-monads.com> dateThu 9 Feb 2012, 05:07 (15 years ago) parent226efff
1 file changed+32−19
src/Database/PostgreSQL/Simple/QueryResults.hs+32−19
src/Database/PostgreSQL/Simple/QueryResults.hs+32−19
@@ -30,6 +30,7 @@ import Data.Either()
3030import Database.PostgreSQL.Simple.Internal
3131import Database.PostgreSQL.Simple.Result (ResultError(..), Result(..))
3232import Database.PostgreSQL.Simple.Types (Only(..))
33+import qualified Database.PostgreSQL.LibPQ as LibPQ (Result)
3334
3435-- | A collection type that can be converted from a list of strings.
3536--
@@ -42,41 +43,53 @@ import Database.PostgreSQL.Simple.Types (Only(..))
4243--
4344-- @
4445-- instance ('Result' a, 'Result' b) => 'QueryResults' (a,b) where
45−-- 'convertResults' [fa,fb] [va,vb] = (a,b)
46−-- where !a = 'convert' fa va
47−-- !b = 'convert' fb vb
46+-- 'convertResults' [fa,fb] [va,vb] = do
47+-- !a <- 'convert' fa va
48+-- !b <- 'convert' fb vb
49+-- 'return' (a,b)
4850-- 'convertResults' fs vs = 'convertError' fs vs 2
4951-- @
5052--
5153-- Notice that this instance evaluates each element to WHNF before
52−-- constructing the pair. By doing this, we guarantee two important
53−-- properties:
54+-- constructing the pair. This property is important enough that its
55+-- a rule all 'QueryResult' instances should follow:
5456--
55−-- * Keep resource usage under control by preventing the construction
56−-- of potentially long-lived thunks.
57+-- * Evaluate every 'Result' value to WHNF before constructing
58+-- the result
5759--
58−-- * Ensure that any 'ResultError' that might arise is thrown
59−-- immediately, rather than some place later in application code
60−-- that cannot handle it.
60+-- Doing so keeps resource usage under local control by preventing the
61+-- construction of potentially long-lived thunks that are forced
62+-- (or not) by the consumer.
6163--
62−-- You can also declare Haskell types of your own to be instances of
63−-- 'QueryResults'.
64+-- This is important to postgresql-simple-0.0.4 because a wayward thunk
65+-- causes the entire LibPQ.'LibPQ.Result' to be retained. This could lead
66+-- to a memory leak, depending on how the thunk is consumed.
67+--
68+-- Note that instances can be defined outside of postgresql-simple,
69+-- which is often useful. For example, here is an attempt at an
70+-- instance for a user-defined pair:
6471--
6572-- @
66−--data User { firstName :: String, lastName :: String }
73+-- data User = User { firstName :: String, lastName :: String }
6774--
68−--instance 'QueryResults' User where
69−-- 'convertResults' [fa,fb] [va,vb] = User a b
70−-- where !a = 'convert' fa va
71−-- !b = 'convert' fb vb
72−-- 'convertResults' fs vs = 'convertError' fs vs
75+-- instance 'QueryResults' User where
76+-- 'convertResults' [fa,qfb] [va,vb] = User \<$\> a \<*\> b
77+-- where !a = 'convert' fa va
78+-- !b = 'convert' fb vb
79+-- 'convertResults' fs vs = 'convertError' fs vs 2
7380-- @
81+--
82+-- In this example, the bang patterns are not used correctly. They force
83+-- the data constructors of the 'Either' type, and are not forcing the
84+-- 'Result' values we need to force. This gives the consumer of the
85+-- 'QueryResult' the ability to cause the memory leak, which is an
86+-- undesirable state of affairs.
7487
7588class QueryResults a where
7689 convertResults :: [Field] -> [Maybe ByteString] -> Either SomeException a
7790 -- ^ Convert values from a row into a Haskell collection.
7891 --
79− -- This function will throw a 'ResultError' if conversion of the
92+ -- This function will return a 'ResultError' if conversion of the
8093 -- collection fails.
8194
8295instance (Result a) => QueryResults (Only a) where