packages feed

mssql-simple 0.4.0.2 → 0.5.0.0

raw patch · 9 files changed

+678/−173 lines, 9 filesdep +mtldep +uuid-typesdep ~ms-tdsPVP ok

version bump matches the API change (PVP)

Dependencies added: mtl, uuid-types

Dependency ranges changed: ms-tds

API changes (from Hackage documentation)

- Database.MSSQLServer.Query.TokenStreamParser: listOfRow :: Row a => Parser [a]
- Database.MSSQLServer.Query.TokenStreamParser: many :: Parser a -> Parser [a]
- Database.MSSQLServer.Query.TokenStreamParser: many1 :: Parser a -> Parser [a]
- Database.MSSQLServer.Query.TokenStreamParser: noResult :: Parser ()
- Database.MSSQLServer.Query.TokenStreamParser: noneOf :: [TokenStream -> Bool] -> Parser TokenStream
- Database.MSSQLServer.Query.TokenStreamParser: oneOf :: [TokenStream -> Bool] -> Parser TokenStream
- Database.MSSQLServer.Query.TokenStreamParser: rowCount :: Parser Int
+ Database.MSSQLServer.Query: ReturnStatus :: Int -> ReturnStatus
+ Database.MSSQLServer.Query: RowCount :: Int -> RowCount
+ Database.MSSQLServer.Query: RpcResponseError :: !Info -> RpcResponse a b
+ Database.MSSQLServer.Query: bigintDefRef :: Integral a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: bigintRef :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: bigintVal :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: binaryDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: binaryRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: binaryVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: bitDefRef :: Integral a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: bitRef :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: bitVal :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: charDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: charRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: charVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: datetimeDefRef :: RpcParamName -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: datetimeRef :: RpcParamName -> Maybe UTCTime -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: datetimeVal :: RpcParamName -> Maybe UTCTime -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: decimalDefRef :: HasResolution a => RpcParamName -> Precision -> Scale -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: decimalRef :: HasResolution a => RpcParamName -> Precision -> Either Scale (Fixed a) -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: decimalVal :: HasResolution a => RpcParamName -> Precision -> Either Scale (Fixed a) -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: doubleDefRef :: Fractional a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: doubleRef :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: doubleVal :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float24DefRef :: Fractional a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float24Ref :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float24Val :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float53DefRef :: Fractional a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float53Ref :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: float53Val :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: imageDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: imageRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: imageVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: intDefRef :: Integral a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: intRef :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: intVal :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: moneyDefRef :: RpcParamName -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: moneyRef :: RpcParamName -> Maybe Money -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: moneyVal :: RpcParamName -> Maybe Money -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: ncharDefRef :: RpcParamName -> Int -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: ncharRef :: RpcParamName -> Int -> Maybe Text -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: ncharVal :: RpcParamName -> Maybe Text -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: newtype ReturnStatus
+ Database.MSSQLServer.Query: newtype RowCount
+ Database.MSSQLServer.Query: ntextDefRef :: RpcParamName -> Int -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: ntextRef :: RpcParamName -> Int -> Maybe Text -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: numericDefRef :: HasResolution a => RpcParamName -> Precision -> Scale -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: numericRef :: HasResolution a => RpcParamName -> Precision -> Either Scale (Fixed a) -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: numericVal :: HasResolution a => RpcParamName -> Precision -> Either Scale (Fixed a) -> RpcParam (Maybe (Fixed a))
+ Database.MSSQLServer.Query: nvarcharDefRef :: RpcParamName -> Int -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: nvarcharRef :: RpcParamName -> Int -> Maybe Text -> RpcParam (Maybe Text)
+ Database.MSSQLServer.Query: realDefRef :: Fractional a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: realRef :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: realVal :: Fractional a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: smalldatetimeDefRef :: RpcParamName -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: smalldatetimeRef :: RpcParamName -> Maybe UTCTime -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: smalldatetimeVal :: RpcParamName -> Maybe UTCTime -> RpcParam (Maybe UTCTime)
+ Database.MSSQLServer.Query: smallintDefRef :: Integral a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: smallintRef :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: smallintVal :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: smallmoneyDefRef :: RpcParamName -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: smallmoneyRef :: RpcParamName -> Maybe Money -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: smallmoneyVal :: RpcParamName -> Maybe Money -> RpcParam (Maybe Money)
+ Database.MSSQLServer.Query: textDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: textRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: tinyintDefRef :: Integral a => RpcParamName -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: tinyintRef :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: tinyintVal :: Integral a => RpcParamName -> Maybe a -> RpcParam (Maybe a)
+ Database.MSSQLServer.Query: uniqueidentifierDefRef :: RpcParamName -> RpcParam (Maybe UUID)
+ Database.MSSQLServer.Query: uniqueidentifierRef :: RpcParamName -> Maybe UUID -> RpcParam (Maybe UUID)
+ Database.MSSQLServer.Query: uniqueidentifierVal :: RpcParamName -> Maybe UUID -> RpcParam (Maybe UUID)
+ Database.MSSQLServer.Query: varbinaryDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: varbinaryRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: varbinaryVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: varcharDefRef :: RpcParamName -> Int -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query: varcharRef :: RpcParamName -> Int -> Maybe ByteString -> RpcParam (Maybe ByteString)
+ Database.MSSQLServer.Query.TokenStreamParser: satisfyNotError :: (TokenStream -> Bool) -> Parser TokenStream
+ Database.MSSQLServer.Query.TokenStreamParser: trySatisfy :: (TokenStream -> Bool) -> Parser' TokenStream
+ Database.MSSQLServer.Query.TokenStreamParser: trySatisfyMany :: (TokenStream -> Bool) -> Parser' [TokenStream]
+ Database.MSSQLServer.Query.TokenStreamParser: type Parser' = ExceptT Info Parser
- Database.MSSQLServer.Query: RpcParamDefRef :: RpcParamName -> TypeInfo -> a -> RpcParam a
+ Database.MSSQLServer.Query: RpcParamDefRef :: !RpcParamName -> !TypeInfo -> !a -> RpcParam a
- Database.MSSQLServer.Query: RpcParamDefVal :: RpcParamName -> TypeInfo -> a -> RpcParam a
+ Database.MSSQLServer.Query: RpcParamDefVal :: !RpcParamName -> !TypeInfo -> !a -> RpcParam a
- Database.MSSQLServer.Query: RpcParamRef :: RpcParamName -> TypeInfo -> a -> RpcParam a
+ Database.MSSQLServer.Query: RpcParamRef :: !RpcParamName -> !TypeInfo -> !a -> RpcParam a
- Database.MSSQLServer.Query: RpcParamVal :: RpcParamName -> TypeInfo -> a -> RpcParam a
+ Database.MSSQLServer.Query: RpcParamVal :: !RpcParamName -> !TypeInfo -> !a -> RpcParam a
- Database.MSSQLServer.Query: RpcQuery :: a -> b -> RpcQuery a b
+ Database.MSSQLServer.Query: RpcQuery :: !a -> !b -> RpcQuery a b
- Database.MSSQLServer.Query: RpcResponse :: Int -> a -> b -> RpcResponse a b
+ Database.MSSQLServer.Query: RpcResponse :: !Int -> !a -> !b -> RpcResponse a b
- Database.MSSQLServer.Query: ntextVal :: RpcParamName -> Text -> RpcParam Text
+ Database.MSSQLServer.Query: ntextVal :: RpcParamName -> Maybe Text -> RpcParam (Maybe Text)
- Database.MSSQLServer.Query: nvarcharVal :: RpcParamName -> Text -> RpcParam Text
+ Database.MSSQLServer.Query: nvarcharVal :: RpcParamName -> Maybe Text -> RpcParam (Maybe Text)
- Database.MSSQLServer.Query: resultParser :: Result a => Parser a
+ Database.MSSQLServer.Query: resultParser :: Result a => Parser' a
- Database.MSSQLServer.Query: resultSetParser :: ResultSet a => Parser a
+ Database.MSSQLServer.Query: resultSetParser :: ResultSet a => Parser' a
- Database.MSSQLServer.Query: rpcResultParser :: RpcResult a => Parser a
+ Database.MSSQLServer.Query: rpcResultParser :: RpcResult a => Parser' a
- Database.MSSQLServer.Query: rpcResultSetParser :: RpcResultSet a => Parser a
+ Database.MSSQLServer.Query: rpcResultSetParser :: RpcResultSet a => Parser' a
- Database.MSSQLServer.Query: textVal :: RpcParamName -> ByteString -> RpcParam ByteString
+ Database.MSSQLServer.Query: textVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)
- Database.MSSQLServer.Query: varcharVal :: RpcParamName -> ByteString -> RpcParam ByteString
+ Database.MSSQLServer.Query: varcharVal :: RpcParamName -> Maybe ByteString -> RpcParam (Maybe ByteString)

Files

mssql-simple.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 3fdeca9ccee2c838ec977f3ba9cecc1833abeb358e2c85be382050d6cf7522ad+-- hash: f7f0ea35f8fb135356688fa555518383d0e49559703ffc5bf54c001806938f54  name:           mssql-simple-version:        0.4.0.2+version:        0.5.0.0 synopsis:       SQL Server client library implemented in Haskell description:    Please see the README on GitHub at <https://github.com/mitsuji/mssql-simple#readme> category:       Database@@ -47,12 +47,14 @@     , binary     , bytestring     , hostname-    , ms-tds >=0.3 && <0.4+    , ms-tds >=0.4 && <0.5+    , mtl     , network     , template-haskell     , text     , time     , tls+    , uuid-types   default-language: Haskell2010  test-suite tds-test@@ -68,11 +70,13 @@     , binary     , bytestring     , hostname-    , ms-tds >=0.3 && <0.4+    , ms-tds >=0.4 && <0.5     , mssql-simple+    , mtl     , network     , template-haskell     , text     , time     , tls+    , uuid-types   default-language: Haskell2010
src/Database/MSSQLServer/Connection.hs view
@@ -19,13 +19,11 @@ import Data.Monoid ((<>),mempty)  import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as LB  import qualified Data.Text as T import qualified Data.Text.IO as T import qualified Data.Text.Encoding as T -import Data.Binary (Binary(..)) import qualified Data.Binary.Put as Put import qualified Data.Binary.Get as Get @@ -104,10 +102,10 @@      Prelogin plResOpts <- performPrelogin sock ps encrypt -  [PLOEncryption modeEnc]  <- case filter isPLOEncryption plResOpts of+  PLOEncryption modeEnc:_  <- case filter isPLOEncryption plResOpts of                                 [] -> throwIO $ ProtocolError "connect: PLOEncryption is necessary"                                 xs -> return xs-  [PLOMars modeMars] <- case filter isPLOMars plResOpts of+  PLOMars modeMars:_ <- case filter isPLOMars plResOpts of                           [] -> throwIO $ ProtocolError "connect: PLOMars is necessary"                           xs -> return xs   when (modeEnc/=encrypt)  $ throwIO $ ProtocolError "connect: Server reported unsupported encryption mode"@@ -207,15 +205,15 @@  validLoginAck :: Login7 -> TokenStreams -> IO () validLoginAck login7 (TokenStreams loginResTokenStreams) = do-  +   let loginAcks   = filter isTSLoginAck loginResTokenStreams   when (null loginAcks) $ do-    [TSError info] <- case filter isTSError loginResTokenStreams of+    TSError info:_ <- case filter isTSError loginResTokenStreams of                         [] -> throwIO $ ProtocolError "validLoginAck: TSError is necessary"                         xs -> return xs     throwIO $ AuthError info -  let [TSLoginAck _ tdsVersion' _ _] = loginAcks+  let (TSLoginAck _ tdsVersion' _ _):_ = loginAcks   when (tdsVersion /= tdsVersion') $ throwIO $ ProtocolError "validLoginAck: Server reported unsupported tds version"    return ()
src/Database/MSSQLServer/Query.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP #-}  module Database.MSSQLServer.Query ( -- * SQL Text Query                                     sql@@ -8,6 +9,8 @@                                   , Result (..)                                   , Row (..)                                   , Only (..)+                                  , RowCount (..)+                                  , ReturnStatus (..)                                                                      -- * RPC Query                                   , rpc@@ -29,38 +32,105 @@                                   , RpcParamSet (..)                                   , RpcParam (..)                                   , RpcParamName-                                  , nvarcharVal-                                  , ntextVal++                                  , bitVal+                                  , tinyintVal+                                  , smallintVal+                                  , intVal+                                  , bigintVal+                                  , smallmoneyVal+                                  , moneyVal+                                  , smalldatetimeVal+                                  , datetimeVal+                                  , float24Val+                                  , realVal+                                  , float53Val+                                  , doubleVal+                                  , uniqueidentifierVal+                                  , decimalVal+                                  , numericVal+                                  , charVal                                   , varcharVal                                   , textVal-                                  +                                  , ncharVal+                                  , nvarcharVal+                                  , ntextVal+                                  , binaryVal+                                  , varbinaryVal+                                  , imageVal++                                  , bitRef+                                  , tinyintRef+                                  , smallintRef+                                  , intRef+                                  , bigintRef+                                  , smallmoneyRef+                                  , moneyRef+                                  , smalldatetimeRef+                                  , datetimeRef+                                  , float24Ref+                                  , realRef+                                  , float53Ref+                                  , doubleRef+                                  , uniqueidentifierRef+                                  , decimalRef+                                  , numericRef+                                  , charRef+                                  , varcharRef+                                  , textRef+                                  , ncharRef+                                  , nvarcharRef+                                  , ntextRef+                                  , binaryRef+                                  , varbinaryRef+                                  , imageRef++                                  , bitDefRef+                                  , tinyintDefRef+                                  , smallintDefRef+                                  , intDefRef+                                  , bigintDefRef+                                  , smallmoneyDefRef+                                  , moneyDefRef+                                  , smalldatetimeDefRef+                                  , datetimeDefRef+                                  , float24DefRef+                                  , realDefRef+                                  , float53DefRef+                                  , doubleDefRef+                                  , uniqueidentifierDefRef+                                  , decimalDefRef+                                  , numericDefRef+                                  , charDefRef+                                  , varcharDefRef+                                  , textDefRef+                                  , ncharDefRef+                                  , nvarcharDefRef+                                  , ntextDefRef+                                  , binaryDefRef+                                  , varbinaryDefRef+                                  , imageDefRef                                   -- * Exceptions                                   , withTransaction                                   , QueryError (..)                                   ) where -import Control.Applicative((<$>))-import Data.Monoid ((<>)) import Data.Typeable(Typeable)  import Network.Socket (Socket) import Network.Socket.ByteString (recv) import Network.Socket.ByteString.Lazy (sendAll) -import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as LB- import qualified Data.Text as T  import qualified Data.Binary.Get as Get import qualified Data.Binary.Put as Put -import Control.Monad (when) import Control.Exception (Exception(..),throwIO,onException)  import Database.Tds.Message -import Database.MSSQLServer.Connection+import Database.MSSQLServer.Connection (Connection(..)) import Database.MSSQLServer.Query.Only import Database.MSSQLServer.Query.Row import Database.MSSQLServer.Query.ResultSet@@ -68,6 +138,12 @@ import Database.MSSQLServer.Query.RpcQuerySet import Database.MSSQLServer.Query.TokenStreamParser +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else+import Control.Monad.Error+runExceptT = runErrorT+#endif  data QueryError = QueryError !Info                 deriving (Show,Typeable)@@ -80,38 +156,25 @@   sendAll sock $ Put.runPut $ putClientMessage ps $ CMSqlBatch $ SqlBatch query   TokenStreams tss <- readMessage sock $ Get.runGetIncremental getServerMessage -  case filter isTSError tss of-    [] -> case parse resultSetParser tss of-      [] -> error "sql: failed to parse token streams"-      (x,_):_ -> return x-    TSError info :_ -> throwIO $ QueryError info+  case parse responseParser tss of+    [] -> fail "sql: failed to parse token streams"+    (Left info,_):_ -> throwIO $ QueryError info+    (Right x,_):_ -> return x +  where+    responseParser :: (ResultSet a) => Parser (Either Info a)+    responseParser = runExceptT $ resultSetParser  + rpc :: (RpcQuerySet a, RpcResponseSet b) => Connection -> a -> IO b rpc (Connection sock ps) queries = do   sendAll sock $ Put.runPut $ putClientMessage ps $ CMRpcRequest $ toRpcRequest queries   TokenStreams tss <- readMessage sock $ Get.runGetIncremental getServerMessage -  case filter isTSError tss of-    [] -> case parse rpcResponseSetParser tss of-      [] -> error "rpc: failed to parse token streams"-      (x,_):_ -> return x-    TSError info :_ -> throwIO $ QueryError info----nvarcharVal :: RpcParamName -> T.Text -> RpcParam T.Text-nvarcharVal name ts = RpcParamVal name (TINVarChar (fromIntegral $ (T.length ts) * 2) (Collation 0x00000000 0x00)) ts--ntextVal :: RpcParamName -> T.Text -> RpcParam T.Text-ntextVal name ts = RpcParamVal name (TINText (fromIntegral $ (T.length ts) * 2) (Collation 0x00000000 0x00)) ts--varcharVal :: RpcParamName -> B.ByteString -> RpcParam B.ByteString-varcharVal name bs = RpcParamVal name (TIBigVarChar (fromIntegral $ B.length bs) (Collation 0x00000000 0x00)) bs--textVal :: RpcParamName -> B.ByteString -> RpcParam B.ByteString-textVal name bs = RpcParamVal name (TIText (fromIntegral $ B.length bs) (Collation 0x00000000 0x00)) bs+  case parse rpcResponseSetParser tss of+    [] -> fail "rpc: failed to parse token streams"+    (x,_):_ -> return x   @@ -127,10 +190,6 @@       rollback = sql conn $ T.pack "ROLLBACK TRANSACTION":: IO ()  --isTSError :: TokenStream -> Bool-isTSError (TSError{}) = True-isTSError _ = False  readMessage :: Socket -> Get.Decoder a -> IO a readMessage sock decoder = do
src/Database/MSSQLServer/Query/ResultSet.hs view
@@ -1,6 +1,7 @@ {-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP #-}   module Database.MSSQLServer.Query.ResultSet ( ResultSet (..)@@ -8,6 +9,7 @@                                             ) where  +import Control.Applicative ((<$>)) import Database.Tds.Message import Database.MSSQLServer.Query.Row import Database.MSSQLServer.Query.Only@@ -17,20 +19,106 @@ import Control.Monad(forM) import Language.Haskell.TH (runIO,pprint) +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else+import Control.Monad.Error+#endif  ++noResult :: Parser' ()+noResult = do+  _ <- trySatisfyMany $ not . isTSDoneOrDoneProc+  _ <- trySatisfy isTSDoneOrDoneProc+  return ()+  where+    isTSDoneOrDoneProc :: TokenStream -> Bool+    isTSDoneOrDoneProc (TSDone{}) = True+    isTSDoneOrDoneProc (TSDoneProc{}) = True+    isTSDoneOrDoneProc _ = False+++returnStatus :: Parser' ReturnStatus+returnStatus = do+  _ <- trySatisfyMany $ not . isTSReturnStatus+  TSReturnStatus rets <- trySatisfy isTSReturnStatus+  _ <- trySatisfy isTSDoneProc+  return $ ReturnStatus $ fromIntegral rets+  where+    isTSReturnStatus :: TokenStream -> Bool+    isTSReturnStatus (TSReturnStatus{}) = True+    isTSReturnStatus _ = False++    isTSDoneProc :: TokenStream -> Bool+    isTSDoneProc (TSDoneProc{}) = True+    isTSDoneProc _ = False+++rowCount :: Parser' RowCount+rowCount = do+  _ <- trySatisfyMany $ not . isTSDone+  TSDone (Done _ _ rc) <- trySatisfy isTSDone+  return $ RowCount $ fromIntegral rc+++listOfRow :: Row a => Parser' ([a])+listOfRow = do+  tsCmd <- trySatisfy isTSColMetaData+  _ <- trySatisfyMany $ not . isTSRow+  tsRows <- trySatisfyMany isTSRow+  _ <- trySatisfyMany $ not . isTSDone -- necesarry ?+  _ <- trySatisfy $ isTSDone+  return $+    let+      (TSColMetaData (maybeCmd)) = tsCmd+      mcds = case (\(ColMetaData x) -> x) <$> maybeCmd of+               Nothing -> error "listOfRow: ColMetaData is necessary"+               Just mcds' -> mcds'+      rows = (\(TSRow row) -> getRawBytes <$> row) <$> tsRows+    in fromListOfRawBytes mcds <$> rows+  where++    isTSColMetaData :: TokenStream -> Bool+    isTSColMetaData (TSColMetaData{}) = True+    isTSColMetaData _ = False++    isTSRow :: TokenStream -> Bool+    isTSRow (TSRow{}) = True+    isTSRow _ = False++    getRawBytes :: RowColumnData -> RawBytes+    getRawBytes (RCDOrdinal dt) = dt+    getRawBytes (RCDLarge _ _ dt) = dt++++isTSDone :: TokenStream -> Bool+isTSDone (TSDone{}) = True+isTSDone _ = False+++++++ class ResultSet a where-  resultSetParser :: Parser a+  resultSetParser :: Parser' a   instance ResultSet () where   resultSetParser = noResult +instance ResultSet RowCount where+  resultSetParser = rowCount++instance ResultSet ReturnStatus where+  resultSetParser = returnStatus+ instance (Row a) => ResultSet [a] where   resultSetParser = listOfRow -instance ResultSet Int where-  resultSetParser = rowCount   -- [MEMO] using Template Haskell@@ -38,23 +126,27 @@   dec <- resultSetTupleQ n --  runIO $ putStrLn $ pprint dec   return dec---instance (Result a, Result b) => ResultSet (a, b) where+--instance (Result a1, Result a2) => ResultSet (a1, a2) where --  resultSetParser = do---    !r1 <- resultParser :: (Result a) => Parser a---    !r2 <- resultParser :: (Result b) => Parser b+--    !r1 <- resultParser :: (Result a1) => Parser' a1+--    !r2 <- resultParser :: (Result a2) => Parser' a2 --    return  (r1,r2) --   class Result a where-  resultParser :: Parser a+  resultParser :: Parser' a  instance Result () where   resultParser = noResult +instance Result RowCount where+  resultParser = rowCount++instance Result ReturnStatus where+  resultParser = returnStatus+ instance Row a => Result [a] where   resultParser = listOfRow -instance Result Int where-  resultParser = rowCount 
src/Database/MSSQLServer/Query/Row.hs view
@@ -3,6 +3,8 @@ {-# LANGUAGE TemplateHaskell #-}  module Database.MSSQLServer.Query.Row ( Row (..)+                                      , RowCount (..)+                                      , ReturnStatus (..)                                       ) where  import Database.Tds.Message@@ -11,6 +13,10 @@  import Control.Monad(forM) import Language.Haskell.TH (runIO,pprint)+++newtype RowCount = RowCount Int+newtype ReturnStatus = ReturnStatus Int  mcdTypeInfo :: MetaColumnData -> TypeInfo mcdTypeInfo (MetaColumnData _ _ ti _ _) = ti
src/Database/MSSQLServer/Query/RpcQuerySet.hs view
@@ -12,10 +12,89 @@                                               , RpcParam (..)                                               , RpcParamName                                               , rpcReqBatchParam++                                              , bitVal+                                              , tinyintVal+                                              , smallintVal+                                              , intVal+                                              , bigintVal+                                              , smallmoneyVal+                                              , moneyVal+                                              , smalldatetimeVal+                                              , datetimeVal+                                              , float24Val+                                              , realVal+                                              , float53Val+                                              , doubleVal+                                              , uniqueidentifierVal+                                              , decimalVal+                                              , numericVal+                                              , charVal+                                              , varcharVal+                                              , textVal+                                              , ncharVal+                                              , nvarcharVal+                                              , ntextVal+                                              , binaryVal+                                              , varbinaryVal+                                              , imageVal++                                              , bitRef+                                              , tinyintRef+                                              , smallintRef+                                              , intRef+                                              , bigintRef+                                              , smallmoneyRef+                                              , moneyRef+                                              , smalldatetimeRef+                                              , datetimeRef+                                              , float24Ref+                                              , realRef+                                              , float53Ref+                                              , doubleRef+                                              , uniqueidentifierRef+                                              , decimalRef+                                              , numericRef+                                              , charRef+                                              , varcharRef+                                              , textRef+                                              , ncharRef+                                              , nvarcharRef+                                              , ntextRef+                                              , binaryRef+                                              , varbinaryRef+                                              , imageRef++                                              , bitDefRef+                                              , tinyintDefRef+                                              , smallintDefRef+                                              , intDefRef+                                              , bigintDefRef+                                              , smallmoneyDefRef+                                              , moneyDefRef+                                              , smalldatetimeDefRef+                                              , datetimeDefRef+                                              , float24DefRef+                                              , realDefRef+                                              , float53DefRef+                                              , doubleDefRef+                                              , uniqueidentifierDefRef+                                              , decimalDefRef+                                              , numericDefRef+                                              , charDefRef+                                              , varcharDefRef+                                              , textDefRef+                                              , ncharDefRef+                                              , nvarcharDefRef+                                              , ntextDefRef+                                              , binaryDefRef+                                              , varbinaryDefRef+                                              , imageDefRef                                               ) where   import qualified Data.Text as T+import qualified Data.ByteString as B import Data.Word (Word16(..))  import Database.Tds.Message@@ -25,8 +104,12 @@ import Control.Monad(forM) import Language.Haskell.TH (runIO,pprint) +import Data.Time (UTCTime(..))+import Data.UUID.Types (UUID)+import Data.Fixed (Fixed(..),HasResolution(..)) -data RpcQuery a b = RpcQuery a b++data RpcQuery a b = RpcQuery !a !b                   deriving (Show)  class RpcQueryId a where@@ -61,10 +144,10 @@  type RpcParamName  = T.Text -data RpcParam a = RpcParamVal RpcParamName TypeInfo a-                | RpcParamRef RpcParamName TypeInfo a-                | RpcParamDefVal RpcParamName TypeInfo a-                | RpcParamDefRef RpcParamName TypeInfo a+data RpcParam a = RpcParamVal !RpcParamName !TypeInfo !a+                | RpcParamRef !RpcParamName !TypeInfo !a+                | RpcParamDefVal !RpcParamName !TypeInfo !a+                | RpcParamDefRef !RpcParamName !TypeInfo !a                 deriving (Show)  @@ -91,7 +174,7 @@       !b1 = rpcReqBatchParam v1  -- [MEMO] using Template Haskell-forM [2..30] $ \n -> do+forM [2..60] $ \n -> do   dec <- rpcParamSetTupleQ n --  runIO $ putStrLn $ pprint dec   return dec@@ -124,3 +207,255 @@ --      !r1 = toRpcReqBatch a1 b1 --      !r2 = toRpcReqBatch a2 b2 --+++decimalScale :: (HasResolution a) => Fixed a -> Scale+decimalScale = digits . resolution+  where+    digits :: Integer -> Scale+    digits = truncate . (logBase 10.0) . fromInteger+++bitVal :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+bitVal name n = RpcParamVal name TIBitN n++tinyintVal :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+tinyintVal name n = RpcParamVal name TIIntN1 n++smallintVal :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+smallintVal name n = RpcParamVal name TIIntN2 n++intVal :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+intVal name n = RpcParamVal name TIIntN4 n++bigintVal :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+bigintVal name n = RpcParamVal name TIIntN8 n++smallmoneyVal :: RpcParamName -> (Maybe Money) -> RpcParam (Maybe Money)+smallmoneyVal name m = RpcParamVal name TIMoneyN4 m++moneyVal :: RpcParamName -> (Maybe Money) -> RpcParam (Maybe Money)+moneyVal name m = RpcParamVal name TIMoneyN8 m++smalldatetimeVal :: RpcParamName -> (Maybe UTCTime) -> RpcParam (Maybe UTCTime)+smalldatetimeVal name dt = RpcParamVal name TIDateTimeN4 dt++datetimeVal :: RpcParamName -> (Maybe UTCTime) -> RpcParam (Maybe UTCTime)+datetimeVal name dt = RpcParamVal name TIDateTimeN8 dt++float24Val :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+float24Val name n = RpcParamVal name TIFltN4 n++realVal :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+realVal = float24Val++float53Val :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+float53Val name n = RpcParamVal name TIFltN8 n++doubleVal :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+doubleVal = float53Val++uniqueidentifierVal :: RpcParamName -> (Maybe UUID) -> RpcParam (Maybe UUID)+uniqueidentifierVal name uuid = RpcParamVal name TIGUID uuid++decimalVal :: (HasResolution a) => RpcParamName -> Precision -> (Either Scale (Fixed a)) -> RpcParam (Maybe (Fixed a))+decimalVal name p (Left s) = RpcParamVal name (TIDecimalN p s) Nothing+decimalVal name p (Right f) = RpcParamVal name (TIDecimalN p (decimalScale f)) (Just f)++numericVal :: (HasResolution a) => RpcParamName -> Precision -> (Either Scale (Fixed a)) -> RpcParam (Maybe (Fixed a))+numericVal name p (Left s) = RpcParamVal name (TINumericN p s) Nothing+numericVal name p (Right f) = RpcParamVal name (TINumericN p (decimalScale f)) (Just f)++charVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+charVal name Nothing = RpcParamVal name (TIBigChar 0xffff (Collation 0x00000000 0x00)) Nothing+charVal name (Just bs) = RpcParamVal name (TIBigChar (fromIntegral $ B.length bs) (Collation 0x00000000 0x00)) (Just bs)++varcharVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+varcharVal name Nothing = RpcParamVal name (TIBigVarChar 0xffff (Collation 0x00000000 0x00)) Nothing+varcharVal name (Just bs) = RpcParamVal name (TIBigVarChar (fromIntegral $ B.length bs) (Collation 0x00000000 0x00)) (Just bs)++textVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+textVal name Nothing = RpcParamVal name (TIText 0xffffffff (Collation 0x00000000 0x00)) Nothing+textVal name (Just bs) = RpcParamVal name (TIText (fromIntegral $ B.length bs) (Collation 0x00000000 0x00)) (Just bs)++ncharVal :: RpcParamName -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+ncharVal name Nothing = RpcParamVal name (TINChar 0xffff (Collation 0x00000000 0x00)) Nothing+ncharVal name (Just ts) = RpcParamVal name (TINChar (fromIntegral $ (T.length ts) * 2) (Collation 0x00000000 0x00)) (Just ts)++nvarcharVal :: RpcParamName -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+nvarcharVal name Nothing = RpcParamVal name (TINVarChar 0xffff (Collation 0x00000000 0x00)) Nothing+nvarcharVal name (Just ts) = RpcParamVal name (TINVarChar (fromIntegral $ (T.length ts) * 2) (Collation 0x00000000 0x00)) (Just ts)++ntextVal :: RpcParamName -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+ntextVal name Nothing = RpcParamVal name (TINText 0xffffffff (Collation 0x00000000 0x00)) Nothing+ntextVal name (Just ts) = RpcParamVal name (TINText (fromIntegral $ (T.length ts) * 2) (Collation 0x00000000 0x00)) (Just ts)++binaryVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+binaryVal name Nothing = RpcParamVal name (TIBigBinary 0xffff) Nothing+binaryVal name (Just bs) = RpcParamVal name (TIBigBinary (fromIntegral $ B.length bs)) (Just bs)++varbinaryVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+varbinaryVal name Nothing = RpcParamVal name (TIBigVarBinary 0xffff) Nothing+varbinaryVal name (Just bs) = RpcParamVal name (TIBigVarBinary (fromIntegral $ B.length bs)) (Just bs)++imageVal :: RpcParamName -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+imageVal name Nothing = RpcParamVal name (TIImage 0xffffffff) Nothing+imageVal name (Just bs) = RpcParamVal name (TIImage (fromIntegral $ B.length bs)) (Just bs)++++bitRef :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+bitRef name n = RpcParamRef name TIBitN n++tinyintRef :: (Integral a)  => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+tinyintRef name n = RpcParamRef name TIIntN1 n++smallintRef :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+smallintRef name n = RpcParamRef name TIIntN2 n++intRef :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+intRef name n = RpcParamRef name TIIntN4 n++bigintRef :: (Integral a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+bigintRef name n = RpcParamRef name TIIntN8 n++smallmoneyRef :: RpcParamName -> (Maybe Money) -> RpcParam (Maybe Money)+smallmoneyRef name m = RpcParamRef name TIMoneyN4 m++moneyRef :: RpcParamName -> (Maybe Money) -> RpcParam (Maybe Money)+moneyRef name m = RpcParamRef name TIMoneyN8 m++smalldatetimeRef :: RpcParamName -> (Maybe UTCTime) -> RpcParam (Maybe UTCTime)+smalldatetimeRef name dt = RpcParamRef name TIDateTimeN4 dt++datetimeRef :: RpcParamName -> (Maybe UTCTime) -> RpcParam (Maybe UTCTime)+datetimeRef name dt = RpcParamRef name TIDateTimeN8 dt++float24Ref :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+float24Ref name n = RpcParamRef name TIFltN4 n++realRef :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+realRef = float24Ref++float53Ref :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+float53Ref name n = RpcParamRef name TIFltN8 n++doubleRef :: (Fractional a) => RpcParamName -> (Maybe a) -> RpcParam (Maybe a)+doubleRef = float53Ref++uniqueidentifierRef :: RpcParamName -> (Maybe UUID) -> RpcParam (Maybe UUID)+uniqueidentifierRef name uuid = RpcParamRef name TIGUID uuid++decimalRef :: (HasResolution a) => RpcParamName -> Precision -> (Either Scale (Fixed a)) -> RpcParam (Maybe (Fixed a))+decimalRef name p (Left s) = RpcParamRef name (TIDecimalN p s) Nothing+decimalRef name p (Right f) = RpcParamRef name (TIDecimalN p (decimalScale f)) (Just f)++numericRef :: (HasResolution a) => RpcParamName -> Precision -> (Either Scale (Fixed a)) -> RpcParam (Maybe (Fixed a))+numericRef name p (Left s) = RpcParamRef name (TINumericN p s) Nothing+numericRef name p (Right f) = RpcParamRef name (TINumericN p (decimalScale f)) (Just f)++charRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+charRef name len bs = RpcParamRef name (TIBigChar (fromIntegral len) (Collation 0x00000000 0x00)) bs++varcharRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+varcharRef name len bs = RpcParamRef name (TIBigVarChar (fromIntegral len) (Collation 0x00000000 0x00)) bs++textRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+textRef name len bs = RpcParamRef name (TIText (fromIntegral len) (Collation 0x00000000 0x00)) bs++ncharRef :: RpcParamName -> Int -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+ncharRef name len ts = RpcParamRef name (TINChar (fromIntegral $ len *2) (Collation 0x00000000 0x00)) ts++nvarcharRef :: RpcParamName -> Int -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+nvarcharRef name len ts = RpcParamRef name (TINVarChar (fromIntegral $ len *2) (Collation 0x00000000 0x00)) ts++ntextRef :: RpcParamName -> Int -> (Maybe T.Text) -> RpcParam (Maybe T.Text)+ntextRef name len ts = RpcParamRef name (TINText (fromIntegral $ len *2) (Collation 0x00000000 0x00)) ts++binaryRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+binaryRef name len bs = RpcParamRef name (TIBigBinary (fromIntegral len)) bs++varbinaryRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+varbinaryRef name len bs = RpcParamRef name (TIBigVarBinary (fromIntegral len)) bs++imageRef :: RpcParamName -> Int -> (Maybe B.ByteString) -> RpcParam (Maybe B.ByteString)+imageRef name len bs = RpcParamRef name (TIImage (fromIntegral len)) bs++++bitDefRef :: (Integral a) => RpcParamName -> RpcParam (Maybe a)+bitDefRef name = RpcParamDefRef name TIBitN Nothing++tinyintDefRef :: (Integral a)  => RpcParamName -> RpcParam (Maybe a)+tinyintDefRef name = RpcParamDefRef name TIIntN1 Nothing++smallintDefRef :: (Integral a) => RpcParamName -> RpcParam (Maybe a)+smallintDefRef name = RpcParamDefRef name TIIntN2 Nothing++intDefRef :: (Integral a) => RpcParamName -> RpcParam (Maybe a)+intDefRef name = RpcParamDefRef name TIIntN4 Nothing++bigintDefRef :: (Integral a) => RpcParamName -> RpcParam (Maybe a)+bigintDefRef name = RpcParamDefRef name TIIntN8 Nothing++smallmoneyDefRef :: RpcParamName -> RpcParam (Maybe Money)+smallmoneyDefRef name = RpcParamDefRef name TIMoneyN4 Nothing++moneyDefRef :: RpcParamName -> RpcParam (Maybe Money)+moneyDefRef name = RpcParamDefRef name TIMoneyN8 Nothing++smalldatetimeDefRef :: RpcParamName -> RpcParam (Maybe UTCTime)+smalldatetimeDefRef name = RpcParamDefRef name TIDateTimeN4 Nothing++datetimeDefRef :: RpcParamName -> RpcParam (Maybe UTCTime)+datetimeDefRef name = RpcParamDefRef name TIDateTimeN8 Nothing++float24DefRef :: (Fractional a) => RpcParamName -> RpcParam (Maybe a)+float24DefRef name = RpcParamDefRef name TIFltN4 Nothing++realDefRef :: (Fractional a) => RpcParamName -> RpcParam (Maybe a)+realDefRef = float24DefRef++float53DefRef :: (Fractional a) => RpcParamName -> RpcParam (Maybe a)+float53DefRef name = RpcParamDefRef name TIFltN8 Nothing++doubleDefRef :: (Fractional a) => RpcParamName -> RpcParam (Maybe a)+doubleDefRef = float53DefRef++uniqueidentifierDefRef :: RpcParamName -> RpcParam (Maybe UUID)+uniqueidentifierDefRef name = RpcParamDefRef name TIGUID Nothing++decimalDefRef :: (HasResolution a) => RpcParamName -> Precision -> Scale -> RpcParam (Maybe (Fixed a))+decimalDefRef name p s = RpcParamDefRef name (TIDecimalN p s) Nothing++numericDefRef :: (HasResolution a) => RpcParamName -> Precision -> Scale -> RpcParam (Maybe (Fixed a))+numericDefRef name p s = RpcParamDefRef name (TINumericN p s) Nothing++charDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+charDefRef name len = RpcParamDefRef name (TIBigChar (fromIntegral len) (Collation 0x00000000 0x00)) Nothing++varcharDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+varcharDefRef name len = RpcParamDefRef name (TIBigVarChar (fromIntegral len) (Collation 0x00000000 0x00)) Nothing++textDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+textDefRef name len = RpcParamDefRef name (TIText (fromIntegral len) (Collation 0x00000000 0x00)) Nothing++ncharDefRef :: RpcParamName -> Int -> RpcParam (Maybe T.Text)+ncharDefRef name len = RpcParamDefRef name (TINChar (fromIntegral $ len *2) (Collation 0x00000000 0x00)) Nothing++nvarcharDefRef :: RpcParamName -> Int -> RpcParam (Maybe T.Text)+nvarcharDefRef name len = RpcParamDefRef name (TINVarChar (fromIntegral $ len *2) (Collation 0x00000000 0x00)) Nothing++ntextDefRef :: RpcParamName -> Int -> RpcParam (Maybe T.Text)+ntextDefRef name len = RpcParamDefRef name (TINText (fromIntegral $ len *2) (Collation 0x00000000 0x00)) Nothing++binaryDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+binaryDefRef name len = RpcParamDefRef name (TIBigBinary (fromIntegral len)) Nothing++varbinaryDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+varbinaryDefRef name len = RpcParamDefRef name (TIBigVarBinary (fromIntegral len)) Nothing++imageDefRef :: RpcParamName -> Int -> RpcParam (Maybe B.ByteString)+imageDefRef name len = RpcParamDefRef name (TIImage (fromIntegral len)) Nothing++
src/Database/MSSQLServer/Query/RpcResponseSet.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP #-}  module Database.MSSQLServer.Query.RpcResponseSet ( RpcResponseSet (..)                                                  , RpcResponse (..)@@ -20,16 +21,60 @@ import Control.Monad(forM) import Language.Haskell.TH (runIO,pprint) +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else+import Control.Monad.Error+runExceptT = runErrorT+#endif   +listOfRow :: Row a => Parser' ([a])+listOfRow = do+  _ <- trySatisfyMany $ not . isTSColMetaData+  tsCmd <- trySatisfy isTSColMetaData+  _ <- trySatisfyMany $ not . isTSRow+  tsRows <- trySatisfyMany isTSRow+  _ <- trySatisfyMany  $ not . isTSDoneInProc -- necesarry ?+  _ <- trySatisfy isTSDoneInProc+  return $+    let+      (TSColMetaData (maybeCmd)) = tsCmd+      mcds = case (\(ColMetaData x) -> x) <$> maybeCmd of+               Nothing -> error "listOfRow: ColMetaData is necessary"+               Just mcds' -> mcds'+      rows = (\(TSRow row) -> getRawBytes <$> row) <$> tsRows+    in fromListOfRawBytes mcds <$> rows+  where++    isTSColMetaData :: TokenStream -> Bool+    isTSColMetaData (TSColMetaData{}) = True+    isTSColMetaData _ = False++    isTSRow :: TokenStream -> Bool+    isTSRow (TSRow{}) = True+    isTSRow _ = False++    isTSDoneInProc :: TokenStream -> Bool+    isTSDoneInProc (TSDoneInProc{}) = True+    isTSDoneInProc _ = False++    getRawBytes :: RowColumnData -> RawBytes+    getRawBytes (RCDOrdinal dt) = dt+    getRawBytes (RCDLarge _ _ dt) = dt++++ class RpcResultSet a where-  rpcResultSetParser :: Parser a+  rpcResultSetParser :: Parser' a   instance RpcResultSet () where-  rpcResultSetParser = noResult+  rpcResultSetParser = return () + instance (Row a) => RpcResultSet [a] where   rpcResultSetParser = listOfRow @@ -41,17 +86,14 @@   return dec --instance (RpcResult a1, RpcResult a2) => RpcResultSet (a1, a2) where --  rpcResultSetParser = do---    !r1 <- rpcResultParser :: (RpcResult a1) => Parser a1---    !r2 <- rpcResultParser :: (RpcResult a2) => Parser a2+--    !r1 <- rpcResultParser :: (RpcResult a1) => Parser' a1+--    !r2 <- rpcResultParser :: (RpcResult a2) => Parser' a2 --    return  (r1,r2) --   class RpcResult a where-  rpcResultParser :: Parser a--instance RpcResult () where-  rpcResultParser = noResult+  rpcResultParser :: Parser' a  instance Row a => RpcResult [a] where   rpcResultParser = listOfRow@@ -96,25 +138,30 @@   -- (RpcOutputSet a, RpcResultSet b) => -data RpcResponse a b = RpcResponse Int a b+data RpcResponse a b = RpcResponse !Int !a !b+                     | RpcResponseError !Info                    deriving (Show)   rpcResponseParser :: (RpcOutputSet a, RpcResultSet b) => Parser (RpcResponse a b)-rpcResponseParser = p-  where-    p = do-      rss <- rpcResultSetParser-      _ <- many $ satisfy $ not . isTSReturnStatus-      TSReturnStatus ret <- satisfy isTSReturnStatus-      _ <- many $ satisfy $ not . isTSReturnValue-      rvs <- many $ satisfy isTSReturnValue-      _ <- many $ satisfy $ not . isTSDoneProc-      _ <- satisfy isTSDoneProc+rpcResponseParser = do+  let rrParser = runExceptT $ do+        rrs <- rpcResultSetParser+        _ <- trySatisfyMany $ not . isTSReturnStatus+        TSReturnStatus ret <- trySatisfy isTSReturnStatus+        _ <- trySatisfyMany $ not . isTSReturnValue+        rvs <- trySatisfyMany isTSReturnValue+        _ <- trySatisfyMany $ not . isTSDoneProc+        _ <- trySatisfy isTSDoneProc -      let rvs' = (\(TSReturnValue rv) -> rv) <$>  rvs-      return $ RpcResponse (fromIntegral ret) (fromReturnValues rvs') rss+        let rvs' = (\(TSReturnValue rv) -> rv) <$>  rvs+        return $ RpcResponse (fromIntegral ret) (fromReturnValues rvs') rrs+  err <- rrParser+  case err of+    Left ei -> return $ RpcResponseError ei+    Right rr -> return rr +  where     isTSReturnStatus :: TokenStream -> Bool     isTSReturnStatus (TSReturnStatus{}) = True     isTSReturnStatus _ = False@@ -126,6 +173,8 @@     isTSDoneProc :: TokenStream -> Bool     isTSDoneProc (TSDoneProc{}) = True     isTSDoneProc _ = False++   
src/Database/MSSQLServer/Query/Template.hs view
@@ -92,7 +92,7 @@ #else                         [ClassP (mkName "Result") [VarT (mkName $ "a" <> show i)]] #endif-                        (AppT (ConT (mkName "Parser")) (VarT (mkName $ "a" <> show i)))+                        (AppT (ConT (mkName "Parser'")) (VarT (mkName $ "a" <> show i)))                       )                      )                  )@@ -212,7 +212,7 @@ #else                         [ClassP (mkName "RpcResult") [VarT (mkName $ "a" <> show i)]] #endif-                        (AppT (ConT (mkName "Parser")) (VarT (mkName $ "a" <> show i)))+                        (AppT (ConT (mkName "Parser'")) (VarT (mkName $ "a" <> show i)))                       )                      )                  )
src/Database/MSSQLServer/Query/TokenStreamParser.hs view
@@ -4,28 +4,30 @@                                                     , parse                                                     , item                                                     , satisfy-                                                    , many-                                                    , many1-                                                    , oneOf-                                                    , noneOf-                                                    , noResult-                                                    , listOfRow-                                                    , rowCount+                                                    , satisfyNotError+                                                    , Parser'(..)+                                                    , trySatisfy+                                                    , trySatisfyMany                                                     ) where  -import Control.Applicative((<$>))-import Control.Applicative(Applicative((<*>),pure),Alternative((<|>),empty))+import Control.Applicative(Applicative((<*>),pure),Alternative((<|>),empty),many,(<$>)) import Control.Monad(Monad(..),MonadPlus(..),ap)+import Data.Monoid ((<>),mconcat) #if MIN_VERSION_base(4,9,0) import Control.Monad.Fail(MonadFail(..)) #endif-import Data.Monoid (mconcat,(<>),All(..),Any(..))  import Database.Tds.Message import Database.MSSQLServer.Query.Row  +#if MIN_VERSION_mtl(2,2,1)+import Control.Monad.Except+#else+import Control.Monad.Error+import qualified Data.Text as T+#endif  data Parser a = Parser ([TokenStream] -> [(a,[TokenStream])]) @@ -69,90 +71,50 @@                  then return x                  else empty -many :: Parser a -> Parser [a]-many p = many1 p <|> return []+satisfyNotError :: (TokenStream -> Bool) -> Parser TokenStream+satisfyNotError f = satisfy (\x -> f x && (not . isTSError) x) -many1 :: Parser a -> Parser [a]-many1 p = do a <- p-             as <- many p-             return $ a:as -oneOf :: [TokenStream -> Bool] -> Parser TokenStream-oneOf xs = satisfy $ \x -> getAny $ mconcat $ (\f -> Any $ f x) <$> xs -noneOf :: [TokenStream -> Bool] -> Parser TokenStream-noneOf xs = satisfy $ \x -> getAll $ mconcat $ (\f -> All $ not $ f x) <$> xs+#if MIN_VERSION_mtl(2,2,1)+type Parser' = ExceptT Info Parser+#else+type Parser' = ErrorT Info Parser+instance Error Info where+  noMsg = Info 0 0 0 (T.pack "") (T.pack "") (T.pack "") 0+#endif  -noResult :: Parser ()-noResult = do-  _ <- many $ satisfy $ not . isTSDone-  _ <- satisfy isTSDone -- [MEMO] just parse here-  return ()-    where--      -- [TODO] check Status contains 0x10-      isTSDone :: TokenStream -> Bool-      isTSDone (TSDone{}) = True-      isTSDone (TSDoneInProc{}) = True-      isTSDone _ = False-  --listOfRow :: Row a => Parser ([a])-listOfRow = do-  _ <- many $ satisfy $ not . isTSColMetaData-  tsCmd <- satisfy isTSColMetaData-  _ <- many $ satisfy $ not . isTSRow-  tsRows <- many $ satisfy isTSRow-  _ <- many $ satisfy $ not . isTSDone-  _ <- satisfy isTSDone -- [MEMO] just parse here-  return $-    let-      (TSColMetaData (maybeCmd)) = tsCmd-      mcds = case (\(ColMetaData x) -> x) <$> maybeCmd of-               Nothing -> error "listOfRow: ColMetaData is necessary"-               Just mcds' -> mcds'-      rows = (\(TSRow row) -> getRawBytes <$> row) <$> tsRows-    in fromListOfRawBytes mcds <$> rows-    where--      isTSColMetaData :: TokenStream -> Bool-      isTSColMetaData (TSColMetaData{}) = True-      isTSColMetaData _ = False--      isTSRow :: TokenStream -> Bool-      isTSRow (TSRow{}) = True-      isTSRow _ = False--      -- [TODO] check Status contains 0x10-      isTSDone :: TokenStream -> Bool-      isTSDone (TSDone{}) = True-      isTSDone (TSDoneInProc{}) = True-      isTSDone _ = False+trySatisfy :: (TokenStream -> Bool) -> Parser' TokenStream+trySatisfy f = do+  ts <- lift $ (satisfyNotError f) <|> errorDone+  case ts of+    TSError ei -> throwError ei+    _ -> return ts -      getRawBytes :: RowColumnData -> RawBytes-      getRawBytes (RCDOrdinal dt) = dt-      getRawBytes (RCDLarge _ _ dt) = dt+trySatisfyMany :: (TokenStream -> Bool) -> Parser' [TokenStream]+trySatisfyMany f = do+  tss <- lift $ (many $ satisfyNotError f) <|> ((\x->[x]) <$> errorDone)+  case tss of+    (TSError ei):_ -> throwError ei+    _ -> return tss  -rowCount :: Parser Int-rowCount = do-  _ <- many $ satisfy $ not . isTSDone-  tsDone <- satisfy isTSDone-  return $-    let-      Done _ _ rc = getDone tsDone-    in fromIntegral rc-    where+errorDone :: Parser TokenStream+errorDone = do+  _  <- many $ satisfy $ not . isTSError+  ts <- satisfy isTSError+  _  <- many $ satisfy $ not . isTSDoneOrDoneProc+  _  <- satisfy isTSDoneOrDoneProc+  return ts+  where+    isTSDoneOrDoneProc :: TokenStream -> Bool+    isTSDoneOrDoneProc (TSDone{}) = True+    isTSDoneOrDoneProc (TSDoneProc{}) = True+    isTSDoneOrDoneProc _ = False -      -- [TODO] check Status contains 0x10-      isTSDone :: TokenStream -> Bool-      isTSDone (TSDone{}) = True-      isTSDone (TSDoneInProc{}) = True-      isTSDone _ = False+isTSError :: TokenStream -> Bool+isTSError (TSError{}) = True+isTSError _ = False -      getDone :: TokenStream -> Done-      getDone (TSDone x) = x-      getDone (TSDoneInProc x) = x-      getDone _ = error "rowCount: TSDone and TSDoneInProc are only possible here"