dbaction.cpp 3.49 KB
Newer Older
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * sensoraction.h
 *
 *  Created on: Jan 25, 2015
 *      Author: Axel Auweter
 */

#include <iostream>
#include <string>

#include <boost/lexical_cast.hpp>

#include "dbaction.h"

/*
 * Print the help for the SENSOR command
 */
void DBAction::printHelp(int argc, char* argv[])
{
  /*            01234567890123456789012345678901234567890123456789012345678901234567890123456789 */
  std::cout << "DB command help" << std::endl;
  std::cout << "The DB command has the following options:" << std::endl;
  std::cout << "   INSERT <sid> <time> <value> - Insert test data into the data store" << std::endl;
  std::cout << "   FUZZYTRUNC <time>           - Truncate data that is older than <time>" << std::endl;
}

/*
 * Execute any of the DB commands
 */
int DBAction::executeCommand(int argc, char* argv[], int argvidx, const char* hostname)
{
  /* Independent from the command, we need to connect to the server */
  connection = new DCDBConnection();
  connection->setHostname(hostname);
  if (!connection->connect()) {
      std::cerr << "Cannot connect to Cassandra database." << std::endl;
      return EXIT_FAILURE;
  }

  /* Check what we need to do (argv[argvidx] contains "DB") */
  argvidx++;
  if (argvidx >= argc) {
      std::cout << "The DB command needs at least two parameters." << std::endl;
      std::cout << "Run with 'HELP DB' to see the list of possible DB commands." << std::endl;
      goto executeCommandError;
  }

  if (strcasecmp(argv[argvidx], "INSERT") == 0) {
      /* INSERT needs two more parameters */
       if (argvidx+3 >= argc) {
           std::cout << "INSERT needs three more parameters!" << std::endl;
           goto executeCommandError;
       }
       doInsert(argv[argvidx+1], argv[argvidx+2], argv[argvidx+3]);
  }
  else if (strcasecmp(argv[argvidx], "FUZZYTRUNC") == 0) {
      /* FUZZYTRUNC needs one more parameter */
      if (argvidx+1 >= argc) {
          std::cout << "FUZZYTRUNC needs one more parameter!" << std::endl;
          goto executeCommandError;
      }
      doFuzzyTrunc(argv[argvidx+1]);
  }
  else {
      std::cout << "Invalid DB command: " << argv[argvidx] << std::endl;
      goto executeCommandError;
  }

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

executeCommandError:
  connection->disconnect();
  delete connection;
  return EXIT_FAILURE;
}

/*
 * Insert a single sensor reading into the database
 */
void DBAction::doInsert(std::string sidstr, std::string timestr, std::string valuestr)
{
  SensorDataStore ds(connection);
  SensorId sid;
  DCDBTimeStamp ts;
  int64_t value;

  if (!sid.mqttTopicConvert(sidstr)) {
      std::cout << "Invalid SID: " << sidstr << std::endl;
      return;
  }

  try {
      ts = DCDBTimeStamp(timestr);
  }
  catch (std::exception& e) {
      std::cout << "Wrong time format." << std::endl;
      return;
  }

  try {
      value = boost::lexical_cast<int64_t>(valuestr);
  }
  catch (std::exception& e) {
      std::cout << "Wrong value format." << std::endl;
      return;
  }

  ds.insert(&sid, ts.getRaw(), value);
}

/*
 * Fuzzy delete sensor data older than timestr
 * The goal of this is to kill entire cassandra rows, so we get the weekstamp of timestr,
 * subtract 1 and delete everything prior to that.
 */
void DBAction::doFuzzyTrunc(std::string timestr)
{
  SensorDataStore ds(connection);
  DCDBTimeStamp ts;

  try {
      ts = DCDBTimeStamp(timestr);
  }
  catch (std::exception& e) {
      std::cout << "Wrong time format." << std::endl;
      return;
  }

  ds.truncBeforeWeek(ts.getWeekstamp());
}