packages feed

mysql-simple 0.2.0.2 → 0.2.1.0

raw patch · 2 files changed

+109/−28 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Database.MySQL.Simple: fold :: (QueryParams q, QueryResults r) => Connection -> Query -> q -> a -> (a -> r -> IO a) -> IO a
+ Database.MySQL.Simple: fold_ :: QueryResults r => Connection -> Query -> a -> (a -> r -> IO a) -> IO a
+ Database.MySQL.Simple: forEach :: (QueryParams q, QueryResults r) => Connection -> Query -> q -> (r -> IO ()) -> IO ()
+ Database.MySQL.Simple: forEach_ :: QueryResults r => Connection -> Query -> (r -> IO ()) -> IO ()

Files

Database/MySQL/Simple.hs view
@@ -60,6 +60,11 @@     -- * Queries that return results     , query     , query_+    -- * Queries that stream results+    , fold+    , fold_+    , forEach+    , forEach_     -- * Statements that do not return results     , execute     , execute_@@ -78,14 +83,15 @@ import Blaze.ByteString.Builder (Builder, fromByteString, toByteString) import Blaze.ByteString.Builder.Char8 (fromChar) import Control.Applicative ((<$>), pure)-import Control.Exception (Exception, onException, throw)+import Control.Exception (Exception, bracket, onException, throw, throwIO) import Control.Monad.Fix (fix) import Data.ByteString (ByteString) import Data.Int (Int64) import Data.List (intersperse) import Data.Monoid (mappend, mconcat) import Data.Typeable (Typeable)-import Database.MySQL.Base (Connection)+import Database.MySQL.Base (Connection, Result)+import Database.MySQL.Base.Types (Field) import Database.MySQL.Simple.Param (Action(..), inQuotes) import Database.MySQL.Simple.QueryParams (QueryParams(..)) import Database.MySQL.Simple.QueryResults (QueryResults(..))@@ -182,13 +188,13 @@ execute :: (QueryParams q) => Connection -> Query -> q -> IO Int64 execute conn template qs = do   Base.query conn =<< formatQuery conn template qs-  finishExecute template conn+  finishExecute conn template  -- | A version of 'execute' that does not perform query substitution. execute_ :: Connection -> Query -> IO Int64 execute_ conn q@(Query stmt) = do   Base.query conn stmt-  finishExecute q conn+  finishExecute conn q  -- | Execute a multi-row @INSERT@, @UPDATE@, or other SQL query that is not -- expected to return results.@@ -200,21 +206,22 @@ executeMany _ _ [] = return 0 executeMany conn q qs = do   Base.query conn =<< formatMany conn q qs-  finishExecute q conn+  finishExecute conn q -finishExecute :: Query -> Connection -> IO Int64-finishExecute q conn = do+finishExecute :: Connection -> Query -> IO Int64+finishExecute conn q = do   ncols <- Base.fieldCount (Left conn)   if ncols /= 0-    then throw $ QueryError ("execute resulted in " ++ show ncols ++-                             "-column result") q+    then throwIO $ QueryError ("execute resulted in " ++ show ncols +++                               "-column result") q     else Base.affectedRows conn  -- | Perform a @SELECT@ or other SQL query that is expected to return--- results.+-- results. All results are retrieved and converted before this+-- function returns. ----- All results are retrieved and converted before this function--- returns.+-- When processing large results, this function will consume a lot of+-- client-side memory.  Consider using 'fold' instead. -- -- Exceptions that may be thrown: --@@ -228,28 +235,102 @@          => Connection -> Query -> q -> IO [r] query conn template qs = do   Base.query conn =<< formatQuery conn template qs-  finishQuery template conn+  finishQuery conn template  -- | A version of 'query' that does not perform query substitution. query_ :: (QueryResults r) => Connection -> Query -> IO [r] query_ conn q@(Query que) = do   Base.query conn que-  finishQuery q conn+  finishQuery conn q -finishQuery :: (QueryResults r) => Query -> Connection -> IO [r]-finishQuery q conn = do-  r <- Base.storeResult conn+-- | Perform a @SELECT@ or other SQL query that is expected to return+-- results. Results are streamed incrementally from the server, and+-- consumed via a left fold.+--+-- The result consumer must be carefully written to execute+-- quickly. If the consumer is slow, server resources will be tied up,+-- and other clients may not be able to update the tables from which+-- the results are being streamed.+--+-- When dealing with small results, it may be simpler (and perhaps+-- faster) to use 'query' instead.+--+-- This fold is /not/ strict. The stream consumer is responsible for+-- forcing the evaluation of its result to avoid space leaks.+--+-- Exceptions that may be thrown:+--+-- * 'FormatError': the query string could not be formatted correctly.+--+-- * 'QueryError': the result contains no columns (i.e. you should be+--   using 'execute' instead of 'query').+--+-- * 'ResultError': result conversion failed.+fold :: (QueryParams q, QueryResults r) =>+        Connection+     -> Query                   -- ^ Query template.+     -> q                       -- ^ Query parameters.+     -> a                       -- ^ Initial state for result consumer.+     -> (a -> r -> IO a)        -- ^ Result consumer.+     -> IO a+fold conn template qs z f = do+  Base.query conn =<< formatQuery conn template qs+  finishFold conn template z f++-- | A version of 'fold' that does not perform query substitution.+fold_ :: (QueryResults r) =>+         Connection+      -> Query                  -- ^ Query.+      -> a                      -- ^ Initial state for result consumer.+      -> (a -> r -> IO a)       -- ^ Result consumer.+      -> IO a+fold_ conn q@(Query que) z f = do+  Base.query conn que+  finishFold conn q z f++-- | A version of 'fold' that does not transform a state value.+forEach :: (QueryParams q, QueryResults r) =>+           Connection+        -> Query                -- ^ Query template.+        -> q                    -- ^ Query parameters.+        -> (r -> IO ())         -- ^ Result consumer.+        -> IO ()+forEach conn template qs = fold conn template qs () . const+{-# INLINE forEach #-}++-- | A version of 'forEach' that does not perform query substitution.+forEach_ :: (QueryResults r) =>+            Connection+         -> Query                -- ^ Query template.+         -> (r -> IO ())         -- ^ Result consumer.+         -> IO ()+forEach_ conn template = fold_ conn template () . const+{-# INLINE forEach_ #-}++finishQuery :: (QueryResults r) => Connection -> Query -> IO [r]+finishQuery conn q = withResult (Base.storeResult conn) q $ \r fs ->+  flip fix [] $ \loop acc -> do+    row <- Base.fetchRow r+    case row of+      [] -> return (reverse acc)+      _  -> let !c = convertResults fs row+            in loop (c:acc)++finishFold :: (QueryResults r) =>+                Connection -> Query -> a -> (a -> r -> IO a) -> IO a+finishFold conn q z0 f = withResult (Base.useResult conn) q $ \r fs ->+  flip fix z0 $ \loop z -> do+    row <- Base.fetchRow r+    case row of+      [] -> return z+      _  -> (f z $! convertResults fs row) >>= loop++withResult :: (IO Result) -> Query -> (Result -> [Field] -> IO a) -> IO a+withResult fetchResult q act = bracket fetchResult Base.freeResult $ \r -> do   ncols <- Base.fieldCount (Right r)   if ncols == 0-    then throw $ QueryError "query resulted in zero-column result" q-    else do-      fs <- Base.fetchFields r-      flip fix [] $ \loop acc -> do-        row <- Base.fetchRow r-        case row of-          [] -> return (reverse acc)-          _  -> let !c = convertResults fs row-                in loop (c:acc)+    then throwIO $ QueryError "query resulted in zero-column result" q+    else act r =<< Base.fetchFields r  -- | Execute an action inside a SQL transaction. --@@ -263,7 +344,7 @@ -- 'Base.rollback', then the exception will be rethrown. withTransaction :: Connection -> IO a -> IO a withTransaction conn act = do-  execute_ conn "start transaction"+  _ <- execute_ conn "start transaction"   r <- act `onException` Base.rollback conn   Base.commit conn   return r
mysql-simple.cabal view
@@ -1,5 +1,5 @@ name:           mysql-simple-version:        0.2.0.2+version:        0.2.1.0 homepage:       https://github.com/mailrank/mysql-simple bug-reports:    https://github.com/mailrank/mysql-simple/issues synopsis:       A mid-level MySQL client library.