influxdb 1.4.0 → 1.5.0
raw patch · 8 files changed
+107/−37 lines, 8 filesdep ~doctestPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: doctest
API changes (from Hackage documentation)
- Database.InfluxDB: UnexpectedResponse :: String -> ByteString -> InfluxException
+ Database.InfluxDB: UnexpectedResponse :: String -> Request -> ByteString -> InfluxException
- Database.InfluxDB.Types: UnexpectedResponse :: String -> ByteString -> InfluxException
+ Database.InfluxDB.Types: UnexpectedResponse :: String -> Request -> ByteString -> InfluxException
Files
- CHANGELOG.md +8/−0
- influxdb.cabal +2/−2
- src/Database/InfluxDB/Line.hs +54/−1
- src/Database/InfluxDB/Manage.hs +21/−17
- src/Database/InfluxDB/Ping.hs +1/−0
- src/Database/InfluxDB/Query.hs +11/−10
- src/Database/InfluxDB/Types.hs +4/−3
- src/Database/InfluxDB/Write.hs +6/−4
CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for influxdb +## v1.5.0 - 2018-03-15++* Change UnexpectedResponse constructor to include the request and throw it in place of UserError in query/write/manage+* Relax upper version bound for doctest+* Extend Haddock comments in Database.InfluxDB.Line++The first item is a breaking change.+ ## v1.4.0 - 2018-03-13 * Implement proper escaping/quoting for queries ([#54](https://github.com/maoe/influxdb-haskell/pull/54))
influxdb.cabal view
@@ -1,5 +1,5 @@ name: influxdb-version: 1.4.0+version: 1.5.0 synopsis: Haskell client library for InfluxDB description: @influxdb@ is a Haskell client library for InfluxDB.@@ -116,7 +116,7 @@ main-is: doctests.hs build-depends: base- , doctest >= 0.11.3 && < 0.15+ , doctest >= 0.11.3 && < 0.16 , QuickCheck >= 2.10 && < 2.12 , influxdb , template-haskell
src/Database/InfluxDB/Line.hs view
@@ -5,17 +5,22 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} module Database.InfluxDB.Line- ( Line(Line)+ ( -- $setup++ -- * Types and accessors+ Line(Line) , measurement , tagSet , fieldSet , timestamp + -- * Serializers , buildLine , buildLines , encodeLine , encodeLines + -- * Other types , LineField , Field(..) , Precision(..)@@ -35,6 +40,28 @@ import Database.InfluxDB.Internal.Text import Database.InfluxDB.Types +{- $setup+The Line protocol implementation.++>>> :set -XOverloadedStrings+>>> import Database.InfluxDB+>>> import Data.Time+>>> import qualified Data.ByteString.Lazy.Char8 as BL8+>>> import System.IO (stdout)+>>> :{+let l1 = Line "cpu_usage"+ (Map.singleton "cpu" "cpu-total")+ (Map.fromList+ [ ("idle", FieldFloat 10.1)+ , ("system", FieldFloat 53.3)+ , ("user", FieldFloat 46.6)+ ])+ (Just $ parseTimeOrError False defaultTimeLocale+ "%F %T%Q %Z"+ "2017-06-17 15:41:40.42659044 UTC") :: Line UTCTime+:}+-}+ -- | Placeholder for the Line Protocol -- -- See https://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/ for the@@ -52,19 +79,39 @@ -- ^ Timestamp (optional) } +-- | Serialize a 'Line' to a lazy bytestring+--+-- >>> BL8.putStrLn $ encodeLine (scaleTo Second) l1+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100 encodeLine :: (time -> Int64)+ -- ^ Function to convert time to an InfluxDB timestamp+ --+ -- Use 'scaleTo' for HTTP writes and 'roundTo' for UDP writes. -> Line time -> L.ByteString encodeLine toTimestamp = B.toLazyByteString . buildLine toTimestamp +-- | Serialize 'Line's to a lazy bytestring+--+-- >>> BL8.putStr $ encodeLines (scaleTo Second) [l1, l1]+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100+-- encodeLines :: Foldable f => (time -> Int64)+ -- ^ Function to convert time to an InfluxDB timestamp+ --+ -- Use 'scaleTo' for HTTP writes and 'roundTo' for UDP writes. -> f (Line time) -> L.ByteString encodeLines toTimestamp = B.toLazyByteString . buildLines toTimestamp +-- | Serialize a 'Line' to a bytestring 'B.Buider'+--+-- >>> B.hPutBuilder stdout $ buildLine (scaleTo Second) l1+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100 buildLine :: (time -> Int64) -> Line time@@ -104,6 +151,12 @@ FieldString t -> "\"" <> TE.encodeUtf8Builder (escapeStringField t) <> "\"" FieldBool b -> if b then "true" else "false" +-- | Serialize 'Line's to a bytestring 'B.Builder'+--+-- >>> B.hPutBuilder stdout $ buildLines (scaleTo Second) [l1, l1]+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100+-- buildLines :: Foldable f => (time -> Int64)
src/Database/InfluxDB/Manage.hs view
@@ -73,7 +73,7 @@ let body = HC.responseBody response case eitherDecode' body of Left message ->- throwIO $ UnexpectedResponse message body+ throwIO $ UnexpectedResponse message request body Right val -> case A.parse (parseResults (params^.precision)) val of A.Success (_ :: V.Vector Void) -> return () A.Error message -> do@@ -82,7 +82,11 @@ throwIO $ ServerError message when (HT.statusIsClientError status) $ throwIO $ ClientError message request- fail $ "BUG: " ++ message ++ " in Database.InfluxDB.Manage.manage"+ throwIO $ UnexpectedResponse+ ("BUG: " ++ message ++ " in Database.InfluxDB.Manage.manage")+ request+ (encode val)+ where request = HC.setQueryString qs $ manageRequest params qs =@@ -160,37 +164,37 @@ -- | Query ID ----- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)--- >> v ^.. each.qid--- >[149250]+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)+-- >>> v ^.. each.qid+-- ... qid :: Lens' ShowQuery Int -- | Query text ----- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)--- >> v ^.. each.queryText--- >["SHOW QUERIES"]+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)+-- >>> v ^.. each.queryText+-- ... queryText :: Lens' ShowQuery Query -- |--- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)--- >> v ^.. each.database--- >["_internal"]+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)+-- >>> v ^.. each.database+-- ... instance HasDatabase ShowQuery where database = _database -- | Duration of the query ----- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)--- >> v ^.. each.duration--- >[0.06062s]+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)+-- >>> v ^.. each.duration+-- ... duration :: Lens' ShowQuery NominalDiffTime makeLensesWith (lensRules & generateSignatures .~ False) ''ShowSeries -- | Series name ----- >> v <- query (queryParams "_internal") "SHOW SERIES" :: IO (V.Vector ShowSeries)--- >> length $ v ^.. each.key--- >755+-- >>> v <- query (queryParams "_internal") "SHOW SERIES" :: IO (V.Vector ShowSeries)+-- >>> length $ v ^.. each.key+-- ... key :: Lens' ShowSeries Key
src/Database/InfluxDB/Ping.hs view
@@ -129,6 +129,7 @@ Nothing -> throwIO $ UnexpectedResponse "The X-Influxdb-Version header was missing in the response."+ request "" `catch` (throwIO . HTTPException) where
src/Database/InfluxDB/Query.hs view
@@ -217,11 +217,10 @@ chunks <- HC.brConsume $ HC.responseBody response let body = BL.fromChunks chunks case eitherDecode' body of- Left message -> throwIO $ UnexpectedResponse message body+ Left message -> throwIO $ UnexpectedResponse message request body Right val -> case A.parse (parseResults (queryPrecision params)) val of A.Success vec -> return vec- A.Error message ->- errorQuery request response message+ A.Error message -> errorQuery message request response val setPrecision :: Precision 'QueryRequest@@ -271,7 +270,8 @@ | B.null chunk = return x | otherwise = case k chunk of AB.Fail unconsumed _contexts message ->- throwIO $ UnexpectedResponse message $ BL.fromStrict unconsumed+ throwIO $ UnexpectedResponse message request $+ BL.fromStrict unconsumed AB.Partial k' -> do chunk' <- HC.responseBody response loop x k' chunk'@@ -280,8 +280,7 @@ A.Success vec -> do x' <- step x vec loop x' k0 leftover- A.Error message ->- errorQuery request response message+ A.Error message -> errorQuery message request response val withQueryResponse :: QueryParams@@ -329,15 +328,17 @@ where Server {..} = queryServer -errorQuery :: HC.Request -> HC.Response body -> String -> IO a-errorQuery request response message = do+errorQuery :: String -> HC.Request -> HC.Response body -> A.Value -> IO a+errorQuery message request response val = do let status = HC.responseStatus response when (HT.statusIsServerError status) $ throwIO $ ServerError message when (HT.statusIsClientError status) $ throwIO $ ClientError message request- fail $ "BUG: " ++ message ++ " in Database.InfluxDB.Query.query - "- ++ show request+ throwIO $ UnexpectedResponse+ ("BUG: " ++ message ++ " in Database.InfluxDB.Query.query")+ request+ (encode val) makeLensesWith ( lensRules
src/Database/InfluxDB/Types.hs view
@@ -267,12 +267,13 @@ -- ^ Client side error. -- -- You need to fix your query to get a successful response.- | UnexpectedResponse String BL.ByteString+ | UnexpectedResponse String Request BL.ByteString -- ^ Received an unexpected response. The 'String' field is a message and the- -- 'BL.ByteString' field is a possibly-empty relevant payload.+ -- 'BL.ByteString' field is a possibly-empty relevant payload of the response. -- -- This can happen e.g. when the response from InfluxDB is incompatible with- -- what this library expects due to an upstream format change etc.+ -- what this library expects due to an upstream format change or when the JSON+ -- response doesn't have expected fields etc. | HTTPException HC.HttpException -- ^ HTTP communication error. --
src/Database/InfluxDB/Write.hs view
@@ -143,7 +143,7 @@ throwIO $ ClientError message request else case A.eitherDecode' body of Left message ->- throwIO $ UnexpectedResponse message body+ throwIO $ UnexpectedResponse message request body Right val -> case A.parse parseErrorObject val of A.Success _ -> fail $ "BUG: impossible code path in "@@ -153,9 +153,11 @@ throwIO $ ServerError message when (HT.statusIsClientError status) $ throwIO $ ClientError message request- fail $ "BUG: " ++ message- ++ " in Database.InfluxDB.Write.writeByteString"-+ throwIO $ UnexpectedResponse+ ("BUG: " ++ message+ ++ " in Database.InfluxDB.Write.writeByteString")+ request+ (A.encode val) where request = (writeRequest params) { HC.requestBody = HC.RequestBodyLBS payload