Skip to content
This repository has been archived by the owner on Nov 15, 2022. It is now read-only.

Commit

Permalink
WriteMany implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
xkrt committed Aug 4, 2015
1 parent 668b664 commit acb8740
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 17 deletions.
52 changes: 50 additions & 2 deletions src/InfluxDB.FSharp.IntegrationTests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ let ``create database`` () =

[<Test>]
let ``try create database that already exist => error`` () =
let client = Client(machine, proxy = fiddler)
let client = Client(machine)
let db = integrationDbs.[0]
shouldNotFailA (client.CreateDatabase db)

Expand Down Expand Up @@ -136,7 +136,7 @@ let ``try drop not existing database => error`` () =
[<Test>]
let ``write point then query it back`` () =
let db = integrationDbs.[0]
let client = Client(machine, proxy = fiddler)
let client = Client(machine)
shouldNotFailA (client.CreateDatabase db)

let timestamp = DateTime.UtcNow
Expand Down Expand Up @@ -192,6 +192,54 @@ let ``write point then query it back [FsCheck]`` (data: PointData) =
| Fail msg -> failwithf "Query result error: %s" msg
| x -> failwithf "unexpected results: %A" x

[<Test>]
let ``write many points then query it back`` () =
let db = integrationDbs.[0]
let client = Client(machine)
shouldNotFailA (client.CreateDatabase db)

let timestamp = DateTime.UtcNow
let temperatureInternal = Int 1L
let temperatureExternal = Int 100L
let cpuLoad = Float 0.64

let temperatureData = { Measurement = "temperature"
Tags = Map [ "machine", "unit42"; "type", "assembly" ]
Fields = Map [ "internal", temperatureInternal; "external", temperatureExternal ]
Timestamp = Some timestamp }
let cpuData = { Measurement = "cpu_load_short"
Tags = Map [ "host", "server01"; "region", "us-west" ]
Fields = Map [ "value", cpuLoad ]
Timestamp = Some timestamp }
let points = createFromMany [| temperatureData; cpuData |]

shouldNotFailA (client.WriteMany(db, points, Precision.Seconds))

let querySingle query =
let results = run (client.Query(db, query))
match results with
| result :: [] ->
match result with
| Ok series -> Seq.single series
| Fail msg -> failwithf "Query result error: %s" msg
| x -> failwithf "unexpected results: %A" x

// check temperature
let temperatureSerie = querySingle "SELECT * FROM temperature"
temperatureSerie.Name =? temperatureData.Measurement
temperatureSerie.Tags =? temperatureData.Tags
temperatureSerie.Columns =? ["time"; "external"; "internal"]
let temperatureValues = Seq.single temperatureSerie.Values
temperatureValues =? [| String (fmtTimestamp timestamp); temperatureExternal; temperatureInternal |]

// check cpu_load_short
let cpuSerie = querySingle "SELECT * FROM cpu_load_short"
cpuSerie.Name =? cpuData.Measurement
cpuSerie.Tags =? cpuData.Tags
cpuSerie.Columns =? ["time"; "value"]
let cpuValues = Seq.single cpuSerie.Values
cpuValues =? [| String (fmtTimestamp timestamp); cpuLoad |]

[<Test>]
let ``query have wrong syntax => error in response`` () =
let client = Client(machine)
Expand Down
2 changes: 1 addition & 1 deletion src/InfluxDB.FSharp.UnitTests/Point.fs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ let ``timestamp validation`` () =
let ``escaping`` () =
let toLine data =
let point = createFrom data
Point.toLine point Precision.Seconds
Point.toLine Precision.Seconds point

// measurement
toLine { correct with Measurement = "cpu,01" } =? @"cpu\,01,host=server01,region=uwest value=3.0 1420070400"
Expand Down
1 change: 1 addition & 0 deletions src/InfluxDB.FSharp.UnitTests/TestUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ let tryCreateFrom (data: PointData) =
Point.create data.Measurement data.Tags data.Fields data.Timestamp

let createFrom = tryCreateFrom >> notFail
let createFromMany = Array.map createFrom
36 changes: 24 additions & 12 deletions src/InfluxDB.FSharp/Client.fs
Original file line number Diff line number Diff line change
Expand Up @@ -184,26 +184,36 @@ type Client (host: string, ?port: uint16, ?credentials: Credentials, ?proxy: Inf
let dropDb name =
query None (sprintf "DROP DATABASE %s" name) checkForError

let toStr =
// todo reorder for perfmance?
function
| Precision.Microseconds -> "u"
| Precision.Milliseconds -> "ms"
| Precision.Seconds -> "s"
| Precision.Minutes -> "m"
| Precision.Hours -> "h"
| x -> raise (NotImplementedException(sprintf "precision %A" x))

// todo validate db name
// todo sort tags by keys for perfomance (see docs)
// todo rewrite with stringBuffer{} and run under profiler
let doWrite db (point: Point.T) precision =
let line = Point.toLine point precision
let precision =
// todo reorder for perfmance?
match precision with
| Precision.Microseconds -> "u"
| Precision.Milliseconds -> "ms"
| Precision.Seconds -> "s"
| Precision.Minutes -> "m"
| Precision.Hours -> "h"
| x -> raise (NotImplementedException(sprintf "precision %A" x))

let line = Point.toLine precision point
let precision = toStr precision
let query = [ { name="db"; value=db }
{ name="precision"; value=precision } ]
write query line

let doWriteMany db (points: Point.T[]) precision =
let lines =
points
|> Array.map (Point.toLine precision)
|> String.concat "\n"
let precision = toStr precision
let query = [ { name="db"; value=db }
{ name="precision"; value=precision } ]
write query lines

let doQuery db querystr =
query (Some db) querystr <| fun (resp: Response) ->
choice {
Expand All @@ -230,9 +240,10 @@ type Client (host: string, ?port: uint16, ?credentials: Credentials, ?proxy: Inf
| :? int32 as v -> FieldValue.Int (int64 v)
| :? int64 as v -> FieldValue.Int v
| :? float as v -> FieldValue.Float v
| :? decimal as v -> FieldValue.Float (float v)
| :? string as v -> FieldValue.String v
| :? bool as v -> FieldValue.Bool v
| x -> failwithf "mappint for %O (%s) not implemented" x (x.GetType().FullName)))
| x -> failwithf "mapping for %O (%s) not implemented" x (x.GetType().FullName)))
})
|> Array.toList
|> Ok)
Expand All @@ -249,5 +260,6 @@ type Client (host: string, ?port: uint16, ?credentials: Credentials, ?proxy: Inf

// todo write warning in xml doc about better usage of WriteMany
member __.Write(db: Database, point: Point.T, precision: Precision) = doWrite db point precision
member __.WriteMany(db: Database, points: Point.T[], precision: Precision) = doWriteMany db points precision

member __.Query(db: Database, query: string) : Async<Choice<QueryResult list,Error>> = doQuery db query
2 changes: 1 addition & 1 deletion src/InfluxDB.FSharp/Point.fs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ module Point =
<*> validateFields fields
<*> validateTimestamp timestamp

let toLine point precision =
let toLine precision point =
let tags =
point.Tags
|> Map.toSeq
Expand Down
3 changes: 2 additions & 1 deletion src/InfluxDB.FSharp/Point.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

open System

// todo replace signature file with just private DU constructor?
module Point =

type T

val create : Measurement -> Map<string,string> -> Map<string,FieldValue> -> DateTime option -> Choice<T, string list>
val toLine : T -> Precision -> string
val toLine : Precision -> T -> string

0 comments on commit acb8740

Please sign in to comment.