packages feed

mysql-haskell 0.8.3.0 → 0.8.4.0

raw patch · 5 files changed

+60/−16 lines, 5 filesdep ~tastyPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: tasty

API changes (from Hackage documentation)

+ Database.MySQL.Base: executeMany_ :: MySQLConn -> Query -> IO [OK]
+ Database.MySQL.Connection: waitCommandReplys :: InputStream Packet -> IO [OK]
+ Database.MySQL.Protocol.Packet: isThereMore :: OK -> Bool
- Database.MySQL.Base: skipToEof :: InputStream a -> IO ()
+ Database.MySQL.Base: skipToEof :: () => InputStream a -> IO ()

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for mysql-haskell +## 0.8.4.0  -- 2018-10-23++* Add `executeMany_` to execute batch SQLs, [#26](https://github.com/winterland1989/mysql-haskell/issues/26).+* Optimize connection closing sequence, [#20](https://github.com/winterland1989/mysql-haskell/pull/20), [#25](https://github.com/winterland1989/mysql-haskell/pull/25).+ ## 0.8.3.0  -- 2017-10-09  * Remove unnecessary exports from `Database.MySQL.Base`.
Database/MySQL/Base.hs view
@@ -37,6 +37,7 @@       -- * Direct query     , execute     , executeMany+    , executeMany_     , execute_     , query_     , queryVector_@@ -121,6 +122,19 @@  {-# SPECIALIZE executeMany :: MySQLConn -> Query -> [[MySQLValue]] -> IO [OK] #-} {-# SPECIALIZE executeMany :: MySQLConn -> Query -> [[Param]]      -> IO [OK] #-}++-- | Execute multiple querys (without param) which don't return result-set.+--+-- This's useful when your want to execute multiple SQLs without params, e.g. from a+-- SQL dump, or a table migration plan.+--+-- @since 0.8.4.0+--+executeMany_ :: MySQLConn -> Query -> IO [OK]+executeMany_ conn@(MySQLConn is os _ _) qry = do+    guardUnconsumed conn+    writeCommand (COM_QUERY (fromQuery qry)) os+    waitCommandReplys is  -- | Execute a MySQL query which don't return a result-set. --
Database/MySQL/Connection.hs view
@@ -13,8 +13,9 @@  module Database.MySQL.Connection where +import           Control.Applicative import           Control.Exception               (Exception, bracketOnError,-                                                  throwIO)+                                                  throwIO, catch, SomeException) import           Control.Monad import qualified Crypto.Hash                     as Crypto import qualified Data.Binary                     as Binary@@ -106,23 +107,29 @@ -- connectDetail :: ConnectInfo -> IO (Greeting, MySQLConn) connectDetail (ConnectInfo host port db user pass charset)-  = bracketOnError open TCP.close go+    = bracketOnError open TCP.close go   where     open  = connectWithBufferSize host port bUFSIZE     go c  = do-      let is = TCP.source c-      is' <- decodeInputStream is-      p <- readPacket is'-      greet <- decodeFromPacket p-      let auth = mkAuth db user pass charset greet-      write c $ encodeToPacket 1 auth-      q <- readPacket is'-      if isOK q-      then do-          consumed <- newIORef True-          let conn = MySQLConn is' (write c) (TCP.close c) consumed-          return (greet, conn)-      else TCP.close c >> decodeFromPacket q >>= throwIO . ERRException+        let is = TCP.source c+        is' <- decodeInputStream is+        p <- readPacket is'+        greet <- decodeFromPacket p+        let auth = mkAuth db user pass charset greet+        write c $ encodeToPacket 1 auth+        q <- readPacket is'+        if isOK q+        then do+            consumed <- newIORef True+            let waitNotMandatoryOK = catch+                    (void (waitCommandReply is'))           -- server will either reply an OK packet+                    ((\ _ -> return ()) :: SomeException -> IO ())   -- or directy close the connection+                conn = MySQLConn is'+                    (write c)+                    (writeCommand COM_QUIT (write c) >> waitNotMandatoryOK >> TCP.close c)+                    consumed+            return (greet, conn)+        else TCP.close c >> decodeFromPacket q >>= throwIO . ERRException      connectWithBufferSize h p bs = TCP.connectSocket h p >>= TCP.socketToConnection bs     write c a = TCP.send c $ Binary.runPut . Binary.put $ a@@ -197,6 +204,17 @@         | isOK  p -> decodeFromPacket p         | otherwise -> throwIO (UnexpectedPacket p) {-# INLINE waitCommandReply #-}++waitCommandReplys :: InputStream Packet -> IO [OK]+waitCommandReplys is = do+    p <- readPacket is+    if  | isERR p -> decodeFromPacket p >>= throwIO . ERRException+        | isOK  p -> do ok <- decodeFromPacket p+                        if isThereMore ok+                        then (ok :) <$> waitCommandReplys is+                        else return [ok]+        | otherwise -> throwIO (UnexpectedPacket p)+{-# INLINE waitCommandReplys #-}  readPacket :: InputStream Packet -> IO Packet readPacket is = Stream.read is >>= maybe
Database/MySQL/Protocol/Packet.hs view
@@ -72,6 +72,13 @@ isEOF p = L.index (pBody p) 0 == 0xFE {-# INLINE isEOF #-} +-- | Is there more packet to be read?+--+--  https://dev.mysql.com/doc/internals/en/status-flags.html+isThereMore :: OK -> Bool+isThereMore p  = okStatus p .&. 0x08 /= 0+{-# INLINE isThereMore #-}+ -- | Decoding packet inside IO, throw 'DecodePacketException' on fail parsing, -- here we choose stability over correctness by omit incomplete consumed case: -- if we successful parse a packet, then we don't care if there're bytes left.
mysql-haskell.cabal view
@@ -1,5 +1,5 @@ name:                mysql-haskell-version:             0.8.3.0+version:             0.8.4.0 synopsis:            pure haskell MySQL driver description:         pure haskell MySQL driver license:             BSD3