query.cpp 6.41 KB
Newer Older
Axel Auweter's avatar
Axel Auweter committed
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * query.cpp
 *
 *  Created on: Feb 19, 2015
 *      Author: Axel Auweter
 */

#include <iostream>
#include <list>
#include <string>
#include <algorithm>

#include <cstdlib>
14
#include <cinttypes>
Axel Auweter's avatar
Axel Auweter committed
15

16
#include <boost/algorithm/string.hpp>
17
#include <boost/regex.hpp>
18
19

#include "dcdbendian.h"
Axel Auweter's avatar
Axel Auweter committed
20
21
#include "query.h"

Axel Auweter's avatar
Axel Auweter committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void DCDBQuery::setLocalTimeEnabled(bool enable) {
  useLocalTime = enable;
}

bool DCDBQuery::getLocalTimeEnabled() {
  return useLocalTime;
}

void DCDBQuery::setRawOutputEnabled(bool enable) {
  useRawOutput = enable;
}

bool DCDBQuery::getRawOutputEnabled() {
  return useRawOutput;
}

Axel Auweter's avatar
Axel Auweter committed
38
39
40
41
42
43
44
45
void DCDBQuery::setFloatOutputEnabled(bool enable) {
  useFloatOutput = enable;
}

bool DCDBQuery::getFloatOutputEnabled() {
  return useFloatOutput;
}

46
void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DCDB::TimeStamp start, DCDB::TimeStamp end)
Axel Auweter's avatar
Axel Auweter committed
47
48
{
  /* Create a new connection to the database */
49
  connection = new DCDB::Connection();
Axel Auweter's avatar
Axel Auweter committed
50
51
52
53
54
55
  connection->setHostname(hostname);
  if (!connection->connect()) {
      std::cout << "Cannot connect to database." << std::endl;
  }

  /* Initialize the SensorConfig interface */
56
57
  DCDB::SensorConfig sensorConfig(connection);
  DCDB::SensorDataStore sensorDataStore(connection);
Axel Auweter's avatar
Axel Auweter committed
58
59
60
61
62
63

  /* Print the CSV header */
  std::cout << "Sensor,Time,Value" << std::endl;

  /* Iterate over list of sensors requested by the user */
  for (std::list<std::string>::iterator it = sensors.begin(); it != sensors.end(); it++) {
Axel Auweter's avatar
Axel Auweter committed
64
      bool unitConvert = false;
65
66
      bool scale = false;
      double scalingFactor = 1;
root's avatar
root committed
67
      std::string modifierStr;
68
      DCDB::Unit baseUnit = DCDB::Unit_None, targetUnit = DCDB::Unit_None;
Axel Auweter's avatar
Axel Auweter committed
69

70
      /* Check if the sensor was requested in a different unit or with scaling factor */
Axel Auweter's avatar
Axel Auweter committed
71
      if (it->find('/') != std::string::npos) {
72
          modifierStr = it->substr(it->find('/')+1, it->length());
Axel Auweter's avatar
Axel Auweter committed
73

74
75
          /* Remove the modifier from the string */
          *it = it->substr(0, it->find('/'));
Axel Auweter's avatar
Axel Auweter committed
76

77
78
79
80
81
82
83
84
          /* Check what type of modificatino is requested */
          boost::regex e("\\.?[0-9]*", boost::regex::extended);
          if (boost::regex_match(modifierStr, e)) {
              scale = true;
              sscanf(modifierStr.c_str(), "%lf", &scalingFactor);
          }
          else {
              unitConvert = true;
85
              targetUnit = DCDB::UnitConv::fromString(modifierStr);
Axel Auweter's avatar
Axel Auweter committed
86

87
              DCDB::PublicSensor sen;
88
              sensorConfig.getPublicSensorByName(sen, it->c_str());
89
              baseUnit = DCDB::UnitConv::fromString(sen.unit);
90
          }
Axel Auweter's avatar
Axel Auweter committed
91
92
      }

Axel Auweter's avatar
Axel Auweter committed
93
94
95
      /* Lookup the sensor in the published sensors table */
      std::string pattern;
      switch (sensorConfig.getSensorPattern(pattern, *it)) {
96
      case DCDB::SC_OK:
Axel Auweter's avatar
Axel Auweter committed
97
        break;
98
      case DCDB::SC_INVALIDSESSION:
Axel Auweter's avatar
Axel Auweter committed
99
100
        std::cout << "Invalid session." << std::endl;
        return;
101
      case DCDB::SC_UNKNOWNSENSOR:
Axel Auweter's avatar
Axel Auweter committed
102
103
104
105
106
107
108
109
        std::cout << "Unknown sensor: " << *it << std::endl;
        return;
      default:
        std::cout << "Unknown error." << std::endl;
        return;
      }

      /* Expand the pattern into a list of existing sensors in the time range */
110
      std::list<DCDB::SensorId> sensorIds;
Axel Auweter's avatar
Axel Auweter committed
111
      switch (sensorConfig.getSensorListForPattern(sensorIds, pattern, start, end)) {
112
      case DCDB::SC_OK:
Axel Auweter's avatar
Axel Auweter committed
113
        break;
114
      case DCDB::SC_INVALIDPATTERN:
Axel Auweter's avatar
Axel Auweter committed
115
116
117
118
119
120
121
122
        std::cout << "Invalid pattern." << std::endl;
        return;
      default:
        std::cout << "Unknown error." << std::endl;
        return;
      }

      /* Iterate over the expanded list of sensorIds and output the results in CSV format */
123
124
      for (std::list<DCDB::SensorId>::iterator sit = sensorIds.begin(); sit != sensorIds.end(); sit++) {
          std::list <DCDB::SensorDataStoreReading> readings;
Axel Auweter's avatar
Axel Auweter committed
125
126
127
          sensorDataStore.query(readings, *sit, start, end);

          /* Iterate over the readings */
128
          for (std::list<DCDB::SensorDataStoreReading>::iterator rit = readings.begin(); rit != readings.end(); rit++) {
Axel Auweter's avatar
Axel Auweter committed
129
130
131
              double fvalue;
              int64_t ivalue;

132
              DCDB::SensorDataStoreReading reading = *rit;
Axel Auweter's avatar
Axel Auweter committed
133

Axel Auweter's avatar
Axel Auweter committed
134
135
136
137
138
139
140
141
              /* Assign the reading to local variable */
              if (useFloatOutput) {
                  fvalue = reading.value;
              }
              else {
                  ivalue = reading.value;
              }

Axel Auweter's avatar
Axel Auweter committed
142
143
              /* Convert the unit if requested */
              if (unitConvert) {
Axel Auweter's avatar
Axel Auweter committed
144
                  if (useFloatOutput) {
145
                      if (!DCDB::UnitConv::convert(fvalue, baseUnit, targetUnit)) {
Axel Auweter's avatar
Axel Auweter committed
146
                          std::cerr << "Warning, cannot convert units ("
147
148
                              << DCDB::UnitConv::toString(baseUnit) << " -> "
                              << DCDB::UnitConv::toString(targetUnit) << ")" << std::endl;
Axel Auweter's avatar
Axel Auweter committed
149
150
151
152
                          unitConvert = false;
                      }
                  }
                  else {
153
                      if (!DCDB::UnitConv::convert(ivalue, baseUnit, targetUnit)) {
Axel Auweter's avatar
Axel Auweter committed
154
                          std::cerr << "Warning, cannot convert units ("
155
156
                              << DCDB::UnitConv::toString(baseUnit) << " -> "
                              << DCDB::UnitConv::toString(targetUnit) << ")" << std::endl;
Axel Auweter's avatar
Axel Auweter committed
157
158
                          unitConvert = false;
                      }
Axel Auweter's avatar
Axel Auweter committed
159
160
161
                  }
              }

162
163
              /* Scale the value if requested */
              if (scale) {
Axel Auweter's avatar
Axel Auweter committed
164
165
166
167
168
169
                  if (useFloatOutput) {
                      fvalue *= scalingFactor;
                  }
                  else {
                      ivalue *= scalingFactor;
                  }
170
171
              }

Axel Auweter's avatar
Axel Auweter committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
              /* Print the sensor's public name */
              std::cout << *it << ",";

              /* Print the time stamp */
              if (useLocalTime) {
                  reading.timeStamp.convertToLocal();
              }
              if (useRawOutput) {
                  std::cout << reading.timeStamp.getRaw() << ",";
              }
              else {
                  std::cout << reading.timeStamp.getString() << ",";
              }

              /* Print the sensor value */
Axel Auweter's avatar
Axel Auweter committed
187
188
189
190
191
192
              if (useFloatOutput) {
                  std::cout << fvalue << std::endl;
              }
              else {
                  std::cout << ivalue << std::endl;
              }
Axel Auweter's avatar
Axel Auweter committed
193
194
195
196
197
198
199
200
201
202
203
204
          }
      }
  }

  /*
   * Clean up
   */
  connection->disconnect();
  delete connection;

}

Axel Auweter's avatar
Axel Auweter committed
205
DCDBQuery::DCDBQuery()
Axel Auweter's avatar
Axel Auweter committed
206
{
Axel Auweter's avatar
Axel Auweter committed
207
208
209
  connection = nullptr;
  useLocalTime = false;
  useRawOutput = false;
Axel Auweter's avatar
Axel Auweter committed
210
  useFloatOutput = false;
Axel Auweter's avatar
Axel Auweter committed
211
}