1 /++ 2 Conversion utilities that help to work with Mir Series and ndslice. 3 4 To use this module `mir-algorithm` package should be included into users `dub.json` file. 5 6 Public_imports: 7 mir.timeserires 8 9 Authors: Ilya Yaroshenko 10 Copyright: Kaleidic Associates Advisory Limited 11 License: BSD 3-clause 12 +/ 13 module influxdb.mir; 14 15 version(Have_mir_algorithm): 16 17 static if (__VERSION__ >= 2073) 18 { 19 //////////////////////////////////// 20 import mir.series; 21 import influxdb.api; 22 import std.datetime: DateTime; 23 24 /++ 25 Converts MeasurementSeries.Rows to Mir Series. 26 27 Params: 28 T = Time type. Default time type is DateTime. Supported types are SysTime, DateTime, and Date. 29 D = Data type. Default data type is double. 30 rows = MeasurementSeries rows 31 columns = List of columns (optional). The "time" colummn is ignored. 32 Returns: 33 2D Mir $(LINK2 https://docs.algorithm.dlang.io/latest/mir_series.html, Series). 34 +/ 35 Series!(T*, D*, 2) 36 toMirSeries(T = DateTime, D = double)( 37 MeasurementSeries.Rows rows, 38 const(string)[] columns = null) 39 { 40 // if columns are not set use all columns 41 if (columns is null) 42 { 43 columns = rows.columns; 44 } 45 // always exclude "time" column 46 foreach (i, column; columns) 47 { 48 if (column == "time") 49 { 50 columns = columns[0 .. i] ~ columns[i + 1 .. $]; 51 break; 52 } 53 } 54 import mir.ndslice.allocation: slice, uninitSlice; 55 import mir.ndslice.topology: map, as; 56 import mir.array.allocation: array; 57 import std.conv: to; 58 auto time = rows["time"].array.map!influxSysTime.as!T.slice; 59 auto data = uninitSlice!D(time.length, columns.length); 60 foreach (i, column; columns) 61 { 62 auto from = rows[column]; 63 foreach (ref elem; data[0 .. $, i]) 64 { 65 elem = from.front.to!D; 66 from.popFront; 67 } 68 assert(from.empty); 69 } 70 return time.series(data); 71 } 72 73 /// 74 @("toMirSeries") 75 unittest 76 { 77 import mir.series; 78 import std.datetime: DateTime; 79 80 auto influxSeries = MeasurementSeries("coolness", 81 ["time", "foo", "bar"], 82 [ 83 ["2015-06-11T20:46:02Z", "1.0", "2.0"], 84 ["2013-02-09T12:34:56Z", "3.0", "4.0"], 85 ]); 86 87 auto series = influxSeries.rows.toMirSeries; 88 89 // sort data if required 90 { 91 import mir.algorithm.iteration: all; 92 import mir.ndslice.allocation: uninitSlice; 93 import mir.ndslice.topology: pairwise; 94 95 if (!series.time.pairwise!"a <= b".all) 96 { 97 series.sort( 98 uninitSlice!size_t(series.length), // index buffer 99 uninitSlice!double(series.length)); // data buffer 100 } 101 } 102 103 assert(series.time == [ 104 DateTime(2013, 2, 9, 12, 34, 56), 105 DateTime(2015, 6, 11, 20, 46, 2)]); 106 107 assert(series.data == [ 108 [3.0, 4.0], 109 [1.0, 2.0]]); 110 } 111 //////////////////////////////////// 112 } 113 else 114 pragma(msg, "Warning: influxdb.mir requires DMD Front End >= 2073");