summaryrefslogtreecommitdiff
path: root/src/Database/InfluxDB.hs
blob: 87f14b4a752572330dbdfd75361127b530be4793 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
{- |
stability: experimental
portability: GHC
-}
module Database.InfluxDB
  ( -- $intro

  -- * Writing data
  -- $write
    write
  , writeBatch
  , writeByteString

  -- ** Write parameters
  , WriteParams
  , writeParams
  , retentionPolicy

  -- ** The Line protocol
  , Line(Line)
  , measurement
  , tagSet
  , fieldSet
  , timestamp

  , Field(..)
  , LineField
  , QueryField
  , Timestamp(..)
  , precisionScale
  , precisionName

  -- * Querying data
  -- $query
  , Query
  , query
  , queryChunked

  -- ** Query construction
  -- $query-construction
  , F.formatQuery
  , (F.%)

  -- ** Query parameters
  , QueryParams
  , queryParams
  , authentication

  -- ** Parsing results
  -- $parsing-results
  , QueryResults(..)
  , parseResultsWith
  , getField
  , getTag
  , parseUTCTime
  , parsePOSIXTime
  , parseQueryField

  -- * Database management
  , manage

  -- * Common data types and classes
  , Precision(..)
  , Database
  , F.formatDatabase
  , Key
  , F.formatKey

  , Server
  , defaultServer
  , host
  , port
  , ssl

  , Credentials
  , credentials
  , user
  , password

  -- * Exception
  , InfluxException(..)

  , HasServer(..)
  , HasDatabase(..)
  , HasPrecision(..)
  , HasManager(..)
  ) where

import Database.InfluxDB.JSON
import Database.InfluxDB.Line
import Database.InfluxDB.Manage (manage)
import Database.InfluxDB.Query
import Database.InfluxDB.Types
import Database.InfluxDB.Write
import qualified Database.InfluxDB.Format as F

{- $intro
= Getting started

This tutorial assumes the following language extensions and imports.

>>> :set -XOverloadedStrings
>>> :set -XRecordWildCards
>>> import Database.InfluxDB
>>> import qualified Database.InfluxDB.Format as F
>>> import Control.Lens
>>> import qualified Data.Map as Map
>>> import Data.Time
>>> import qualified Data.Vector as V

The examples below roughly follows the
 [README](https://github.com/influxdata/influxdb/blob/0b4528b26de43d5504ec0623c184540f7c3e1a54/client/README.md)
in the official Go client library.

== Creating a database

This library assumes the [lens](https://hackage.haskell.org/package/lens)
package in some APIs. Here we use 'Control.Lens.?~' to set the authentication
parameters of type @Maybe 'Credentials'@.

Also note that in order to construct a 'Query', we use 'formatQuery' with the
'F.database' formatter. There are many other formatters defined in
"Database.InfluxDB.Format".

>>> let db = "square_holes"
>>> let bubba = credentials "bubba" "bumblebeetuna"
>>> let p = queryParams db & authentication ?~ bubba
>>> manage p $ formatQuery ("CREATE DATABASE "%F.database) db

== Writing data

'write' or 'writeBatch' can be used to write data. In general 'writeBatch'
should be used for efficiency when writing multiple data points.

>>> let wp = writeParams db & authentication ?~ bubba & precision .~ Second
>>> let cpuUsage = "cpu_usage"
>>> :{
writeBatch wp
  [ Line cpuUsage (Map.singleton "cpu" "cpu-total")
    (Map.fromList
      [ ("idle",   FieldFloat 10.1)
      , ("system", FieldFloat 53.3)
      , ("user",   FieldFloat 46.6)
      ])
    (Nothing :: Maybe UTCTime)
  ]
:}

Note that the type signature of the timestamp is necessary. Otherwise it doesn't
type check.

== Querying data

First we define a placeholder data type called 'CPUUsage' and a 'QueryResults'
instance. 'getField', 'parseUTCTime' and 'parseQueryField' etc are avilable to
make JSON decoding easier.

>>> :{
data CPUUsage = CPUUsage
  { time :: UTCTime
  , cpuIdle, cpuSystem, cpuUser :: Double
  } deriving Show
instance QueryResults CPUUsage where
  parseResults prec = parseResultsWithDecoder strictDecoder $ \_ _ columns fields -> do
    time <- getField "time" columns fields >>= parseUTCTime prec
    FieldFloat cpuIdle <- getField "idle" columns fields >>= parseQueryField
    FieldFloat cpuSystem <- getField "system" columns fields >>= parseQueryField
    FieldFloat cpuUser <- getField "user" columns fields >>= parseQueryField
    return CPUUsage {..}
:}
>>> query p $ formatQuery ("SELECT * FROM "%F.key) cpuUsage :: IO (V.Vector CPUUsage)
[CPUUsage {time = 2017-06-17 15:41:40.52659044 UTC, cpuIdle = 10.1, cpuSystem = 53.3, cpuUser = 46.6}]

Note that the type signature on query here is also necessary to type check.
-}

{- $write
InfluxDB has two ways to write data into it, via HTTP and UDP. This module
only exports functions for the HTTP API. For UDP, you can use a qualified
import:

@
import qualified "Database.InfluxDB.Write.UDP" as UDP
@
-}

{- $query
'query' and 'queryChunked' can be used to query data. If your dataset fits your
memory, 'query' is easier to use. If it doesn't, use 'queryChunked' to stream
data.
-}

{- $query-construction
There are various utility functions available in "Database.InfluxDB.Format".
This module is designed to be imported as qualified:

@
import "Database.InfluxDB"
import qualified "Database.InfluxDB.Format" as F
@
-}