Fledge
An open source edge computing platform for industrial users
resultset.h
1 #ifndef _RESULTSET_H
2 #define _RESULTSET_H
3 /*
4  * Fledge storage client.
5  *
6  * Copyright (c) 2018 Dianomic Systems
7  *
8  * Released under the Apache 2.0 Licence
9  *
10  * Author: Mark Riddoch
11  */
12 #include <string>
13 #include <string.h>
14 #include <sstream>
15 #include <iostream>
16 #include <vector>
17 #include <rapidjson/document.h>
18 
19 typedef enum column_type {
20  INT_COLUMN = 1,
21  NUMBER_COLUMN,
22  STRING_COLUMN,
23  BOOL_COLUMN,
24  JSON_COLUMN,
25  NULL_COLUMN
26 } ColumnType;
27 
28 
32 class ResultSet {
33  public:
34  class ColumnValue {
35  public:
36  ColumnValue(const std::string& value)
37  {
38  m_value.str = (char *)malloc(value.length() + 1);
39  strncpy(m_value.str, value.c_str(), value.length() + 1);
40  m_type = STRING_COLUMN;
41  };
42  ColumnValue(const int value)
43  {
44  m_value.ival = value;
45  m_type = INT_COLUMN;
46  };
47  ColumnValue(const long value)
48  {
49  m_value.ival = value;
50  m_type = INT_COLUMN;
51  };
52  ColumnValue(const double value)
53  {
54  m_value.fval = value;
55  m_type = NUMBER_COLUMN;
56  };
57  ColumnValue(const rapidjson::Value& value)
58  {
59  m_doc = new rapidjson::Document();
60  rapidjson::Document::AllocatorType& a = m_doc->GetAllocator();
61  m_value.json = new rapidjson::Value(value, a);
62  m_type = JSON_COLUMN;
63  };
64  ~ColumnValue()
65  {
66  if (m_type == STRING_COLUMN)
67  free(m_value.str);
68  else if (m_type == JSON_COLUMN)
69  {
70  delete m_doc;
71  delete m_value.json;
72  }
73  };
74  ColumnType getType() { return m_type; };
75  long getInteger() const;
76  double getNumber() const;
77  char *getString() const;
78  const rapidjson::Value *getJSON() const { return m_value.json; };
79  private:
80  ColumnValue(const ColumnValue&);
81  ColumnValue& operator=(ColumnValue const&);
82  ColumnType m_type;
83  union {
84  char *str;
85  long ival;
86  double fval;
87  rapidjson::Value *json;
88  } m_value;
89  rapidjson::Document *m_doc;
90  };
91 
92  class Row {
93  public:
94  Row(ResultSet *resultSet) : m_resultSet(resultSet) {};
95  ~Row()
96  {
97  for (auto it = m_values.cbegin();
98  it != m_values.cend(); it++)
99  delete *it;
100  }
101  void append(ColumnValue *value)
102  {
103  m_values.push_back(value);
104  };
105  ColumnType getType(unsigned int column);
106  ColumnType getType(const std::string& name);
107  ColumnValue *getColumn(unsigned int column) const;
108  ColumnValue *getColumn(const std::string& name) const;
109  ColumnValue *operator[] (unsigned long colNo) const {
110  return m_values[colNo];
111  };
112  private:
113  Row(const Row&);
114  Row& operator=(Row const&);
115  std::vector<ResultSet::ColumnValue *> m_values;
116  const ResultSet *m_resultSet;
117  };
118 
119  typedef std::vector<Row *>::iterator RowIterator;
120 
121  ResultSet(const std::string& json);
122  ~ResultSet();
123  unsigned int rowCount() const { return m_rowCount; };
124  unsigned int columnCount() const { return m_columns.size(); };
125  const std::string& columnName(unsigned int column) const;
126  ColumnType columnType(unsigned int column) const;
127  ColumnType columnType(const std::string& name) const;
128  RowIterator firstRow();
129  RowIterator nextRow(RowIterator it);
130  bool isLastRow(RowIterator it) const;
131  bool hasNextRow(RowIterator it) const;
132  unsigned int findColumn(const std::string& name) const;
133  const Row * operator[] (unsigned long rowNo) {
134  return m_rows[rowNo];
135  };
136 
137  private:
138  ResultSet(const ResultSet &);
139  ResultSet& operator=(ResultSet const&);
140  class Column {
141  public:
142  Column(const std::string& name, ColumnType type) : m_name(name), m_type(type) {};
143  const std::string& getName() { return m_name; };
144  ColumnType getType() { return m_type; };
145  private:
146  const std::string m_name;
147  ColumnType m_type;
148  };
149 
150 
151  unsigned int m_rowCount;
152  std::vector<ResultSet::Column *> m_columns;
153  std::vector<ResultSet::Row *> m_rows;
154 
155 };
156 
157 class ResultException : public std::exception {
158 
159  public:
160  ResultException(const char *what)
161  {
162  m_what = strdup(what);
163  };
164  ~ResultException()
165  {
166  if (m_what)
167  free(m_what);
168  };
169  virtual const char *what() const throw()
170  {
171  return m_what;
172  };
173  private:
174  char *m_what;
175 };
176 
177 class ResultNoSuchColumnException : public std::exception {
178  public:
179  virtual const char *what() const throw()
180  {
181  return "Column does not exist";
182  }
183 };
184 
185 class ResultNoMoreRowsException : public std::exception {
186  public:
187  virtual const char *what() const throw()
188  {
189  return "No more rows in the result set";
190  }
191 };
192 
193 class ResultIncorrectTypeException : public std::exception {
194  public:
195  virtual const char *what() const throw()
196  {
197  return "No more rows in the result set";
198  }
199 };
200 
201 #endif
202 
ResultSet(const std::string &json)
Construct a result set from a JSON document returned from the Fledge storage service.
Definition: result_set.cpp:25
~ResultSet()
Destructor for a result set.
Definition: result_set.cpp:140
unsigned int findColumn(const std::string &name) const
Find the named column in the result set and return the column index.
Definition: result_set.cpp:312
const std::string & columnName(unsigned int column) const
Return the name of a specific column.
Definition: result_set.cpp:162
Definition: resultset.h:34
long getInteger() const
Retrieve a column value as an integer.
Definition: result_set.cpp:330
bool hasNextRow(RowIterator it) const
Given an iterator over the rows in a result set return if there are any more rows in the result set...
Definition: result_set.cpp:234
RowIterator nextRow(RowIterator it)
Given an iterator over the rows in a result set move to the next row in the result set...
Definition: result_set.cpp:219
Result set.
Definition: resultset.h:32
double getNumber() const
Retrieve a column value as a floating point number.
Definition: result_set.cpp:349
Definition: resultset.h:185
bool isLastRow(RowIterator it) const
Given an iterator over the rows in a result set return if there this is the last row in the result se...
Definition: result_set.cpp:246
Definition: resultset.h:177
ColumnType columnType(unsigned int column) const
Return the type of a specific column.
Definition: result_set.cpp:179
Definition: resultset.h:92
Definition: resultset.h:157
Definition: resultset.h:193
RowIterator firstRow()
Fetch an iterator for the rows in a result set.
Definition: result_set.cpp:206
char * getString() const
Retrieve a column value as a string.
Definition: result_set.cpp:368