query.cpp 4.88 KB
Newer Older
Axel Auweter's avatar
Axel Auweter committed
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * query.cpp
 *
 *  Created on: Feb 19, 2015
 *      Author: Axel Auweter
 */

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

#include <cstdlib>

#include "query.h"
#include "casshelper.h"

/* Lovely spaghetti code coming up next. Be aware... */
void DCDBQuery::doQuery(const char* hostname, std::list<std::string> sensors, DCDBTimeStamp start, DCDBTimeStamp end)
{
  /* Connect to db */
  CassCluster *cluster = CassHelper::create_cluster(hostname);
  CassSession* session = cass_session_new();

  if (CassHelper::connect_session(session, cluster) != CASS_OK) {
     cass_session_free(session);
     cass_cluster_free(cluster);
     std::cout << "Cannot connect to Cassandra database." << std::endl;
     exit(EXIT_FAILURE);
  }

  /* Iterate over sensors */
  for (std::list<std::string>::iterator it = sensors.begin(); it != sensors.end(); it++) {
      /* Lookup the sensor in the alias table */
      std::string aliasPattern;
      lookupAlias(session, *it, aliasPattern);

      std::cout << "Found alias: " << aliasPattern << std::endl;

      std::list<SensorId> sidList;
      expandAlias(session, aliasPattern, sidList);

  }

  /* Clean up */
  cass_session_free(session);
  cass_cluster_free(cluster);

}

void DCDBQuery::lookupAlias(CassSession* session, std::string name, std::string& pattern)
{
  CassError rc = CASS_OK;
  CassStatement* statement = nullptr;
  CassFuture* future = nullptr;
  const CassPrepared* prepared = nullptr;

  CassString query = cass_string_init("SELECT pattern FROM dcdb_config.sensoralias WHERE name = ? ;");
  CassString pattern_cstr;

  future = cass_session_prepare(session, query);
  cass_future_wait(future);

  rc = cass_future_error_code(future);
  if (rc != CASS_OK) {
    CassHelper::print_error(future);
  } else {
    prepared = cass_future_get_prepared(future);
  }

  statement = cass_prepared_bind(prepared);
  cass_statement_bind_string_by_name(statement, "name", cass_string_init(name.c_str()));

  future = cass_session_execute(session, statement);
  cass_future_wait(future);

  rc = cass_future_error_code(future);
  if (rc != CASS_OK) {
      CassHelper::print_error(future);
  } else {
      const CassResult* result = cass_future_get_result(future);
      CassIterator* iterator = cass_iterator_from_result(result);

      if (cass_iterator_next(iterator)) {
          const CassRow* row = cass_iterator_get_row(iterator);
          cass_value_get_string(cass_row_get_column_by_name(row, "pattern"), &pattern_cstr);
          pattern = std::string(pattern_cstr.data, pattern_cstr.length);
      }
      else {
          std::cout << "Unknown sensor: " << name << std::endl;
          exit(EXIT_FAILURE);
      }

      cass_result_free(result);
      cass_iterator_free(iterator);
  }
}

void DCDBQuery::expandAlias(CassSession* session, std::string aliasName, std::list<SensorId>& sensorIds)
{
  /* Clear the list of sensorIds */
  sensorIds.clear();

  /* Strip all slashes from aliasName */
  aliasName.erase(std::remove(aliasName.begin(), aliasName.end(), '/'), aliasName.end());

  /* Calculate lower and upper boundaries for the expansion of the alias */
  std::string low  = aliasName;
  std::string high = aliasName;
  if (aliasName.find("*") != std::string::npos) {
      low.replace(aliasName.find("*"), 1, 33-aliasName.length(), '0');
      high.replace(aliasName.find("*"), 1, 33-aliasName.length(), 'F');
  }

  /* Query the database to see which raw sensors actually exist in the interval between low and high */
/*
  CassError rc = CASS_OK;
  CassStatement* statement = nullptr;
  CassFuture* future = nullptr;
  const CassPrepared* prepared = nullptr;

  CassString query = cass_string_init("SELECT DISTINCT sid FROM dcdb.sensordata WHERE key(sid) >= ? and key(sid) <= ?;");
  CassString pattern_cstr;

  future = cass_session_prepare(session, query);
  cass_future_wait(future);

  rc = cass_future_error_code(future);
  if (rc != CASS_OK) {
    CassHelper::print_error(future);
  } else {
    prepared = cass_future_get_prepared(future);
  }

  statement = cass_prepared_bind(prepared);
  cass_statement_bind_string_by_name(statement, "name", cass_string_init(name.c_str()));

  future = cass_session_execute(session, statement);
  cass_future_wait(future);

  rc = cass_future_error_code(future);
  if (rc != CASS_OK) {
      CassHelper::print_error(future);
  } else {
      const CassResult* result = cass_future_get_result(future);
      CassIterator* iterator = cass_iterator_from_result(result);

      if (cass_iterator_next(iterator)) {
          const CassRow* row = cass_iterator_get_row(iterator);
          cass_value_get_string(cass_row_get_column_by_name(row, "pattern"), &pattern_cstr);
          pattern = std::string(pattern_cstr.data, pattern_cstr.length);
      }
      else {
          std::cout << "Unknown sensor: " << name << std::endl;
          exit(EXIT_FAILURE);
      }

      cass_result_free(result);
      cass_iterator_free(iterator);
  }
  */
}