summaryrefslogtreecommitdiff
path: root/examples/random-points.hs
blob: f2287aad1bb7d28cc892b63375c74beb1738f367 (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
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE ViewPatterns #-}
import Data.Foldable
import Data.Traversable
import System.Environment
import System.IO
import Text.Printf (printf)

import Control.Lens
import Data.Aeson
import Data.Optional (Optional(Default))
import Data.Time.Clock.POSIX
import System.Random.MWC (Variate(..))
import qualified Control.Foldl as L
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Network.HTTP.Client as HC
import qualified System.Random.MWC as MWC

import Database.InfluxDB
import qualified Database.InfluxDB.Format as F
import qualified Database.InfluxDB.Manage as M

oneWeekInSeconds :: Int
oneWeekInSeconds = 7*24*60*60

main :: IO ()
main = do
  [read -> (numPoints :: Int), read -> (batches :: Int)] <- getArgs
  hSetBuffering stdout NoBuffering
  manager' <- HC.newManager managerSettings

  let
    ctx = "ctx"
    ct1 = "ct1"
    qparams = queryParams ctx
      & manager .~ Right manager'
      & precision .~ RFC3339

  M.manage qparams $ F.formatQuery ("DROP DATABASE "%F.database) ctx
  M.manage qparams $ F.formatQuery ("CREATE DATABASE "%F.database) ctx

  let wparams = writeParams ctx & manager .~ Right manager'

  gen <- MWC.create
  for_ [1..batches] $ \_ -> do
    batch <- for [1..numPoints] $ \_ -> do
      !time <- (-)
        <$> getPOSIXTime
        <*> (fromIntegral <$> uniformR (0, oneWeekInSeconds) gen)
      !value <- uniform gen
      return (time, value)
    writeBatch wparams $ flip map batch $ \(time, value) ->
      Line ct1
        (Map.fromList [])
        (Map.fromList [("value", nameToFVal value)])
        (Just time)

  queryChunked qparams Default (F.formatQuery ("SELECT * FROM "%F.measurement) ct1) $
    L.mapM_ $ traverse_ $ \Row {..} ->
      printf "%s:\t%s\n"
        (show $ posixSecondsToUTCTime rowTime)
        (show rowValue)

managerSettings :: HC.ManagerSettings
managerSettings = HC.defaultManagerSettings

data Row = Row
  { rowTime :: POSIXTime
  , rowValue :: Name
  } deriving Show

instance QueryResults Row where
  parseResults prec = parseResultsWith $ \_ _ columns fields -> do
    rowTime <- getField "time" columns fields >>= parsePOSIXTime prec
    String name <- getField "value" columns fields
    rowValue <- case name of
      "foo" -> return Foo
      "bar" -> return Bar
      "baz" -> return Baz
      "quu" -> return Quu
      "qux" -> return Qux
      _ -> fail $ "unknown name: " ++ show name
    return Row {..}

data Name
  = Foo
  | Bar
  | Baz
  | Quu
  | Qux
  deriving (Enum, Bounded, Show)

nameToFVal :: Name -> LineField
nameToFVal = FieldString . T.toLower . T.pack . show

instance Variate Name where
  uniform = uniformR (minBound, maxBound)
  uniformR (lower, upper) g = do
    name <- uniformR (fromEnum lower, fromEnum upper) g
    return $! toEnum name