0
votes

I'm thinking of developing an app to query our influxdb servers, I've looked at the influxdb library doc (https://hackage.haskell.org/package/influxdb-1.2.2/docs/Database-InfluxDB.html) but as far as I understand it, you need to pre-define some data structure or you can't query anything. I just need to be able to let the user query whatever without having to define some data in the sources first.

I imagine I could define something with a time field and a value field, then use something like "SELECT active as value FROM mem" to force it to fit that. I think that would work, but it wouldn't be very practical if I need to query two fields later on. Any better solutions I'm not seeing ? I'm still very much a beginner in Haskell, I'd appreciate any tips.

EDIT:

Even that doesn't work, since apparently it's missing the "String" constructor in that bit :

:{
data Test = Test { time :: UTCTime, value :: T.Text }
instance QueryResults Test where
  parseResults prec = parseResultsWith $ \_ _ columns fields -> do
    time <- getField "time" columns fields >>= parseUTCTime prec
    String value <- getField "value" columns fields
    return Test {..}
:}

I copied that from the doc and just changed the fields, not sure where the "String" is supposed to be declared.

1
String comes from Data.AesonDaniel Martin
Ah indeed, thanks ! Now I get an empty result to my query .. but at least it compilesUlrar

1 Answers

0
votes

I don't know what an "InfluxDB" is, but I can read Haskell type signatures, so maybe we can start with something like this:

import Data.Aeson
import qualified Data.Aeson.Types as A
import qualified Data.Vector as V

newtype GenericRawQueryResults = GenericRawQueryResults Value
  deriving Show

instance FromJSON GenericRawQueryResults where
  parseJSON = pure . GenericRawQueryResults

instance ToJSON GenericRawQueryResults where
  toJSON (GenericRawQueryResults v) = v

instance QueryResults GenericRawQueryResults where
  parseResults _ val = pure (V.singleton (GenericRawQueryResults val))

Then try your queries.

From what I can guess by reading the library's code, results from an influx DB query arrive at parseResults inside a json object that has a key called "results" that points to an array of objects, each of which has a key called "series" or a key called "error", and the assumption is that you write a parser to turn each element that's pointed to by "series" into whatever type you want to read from the db.

Except that there's even more framework going on there that I'd probably understand if I knew more about what an InfluxDB is and what kind of data it returns.

In any case, this should get you as close to the raw results as the library will let you get. One additional thing you might do is install the aeson-pretty package, remove the deriving Show bit and do:

instance Show GenericRawQueryResults where
  show g = "decode " ++ show (encodePretty g)

(Or you can keep the derived Show instance and just apply encodePretty to your query results to display them)