NebulaGraph CPP Client  release-3.4
DataSet.h
1 /* Copyright (c) 2020 vesoft inc. All rights reserved.
2  *
3  * This source code is licensed under Apache 2.0 License.
4  */
5 
6 #pragma once
7 
8 #include <iostream>
9 #include <iterator>
10 #include <sstream>
11 #include <string>
12 
13 #include "common/datatypes/List.h"
14 #include "common/datatypes/Value.h"
15 
16 namespace nebula {
17 
18 using Row = List;
19 
20 struct DataSet {
21  std::vector<std::string> colNames;
22  std::vector<Row> rows;
23 
24  DataSet() = default;
25  explicit DataSet(std::vector<std::string> columns) : colNames(std::move(columns)) {}
26  DataSet(const DataSet& ds) noexcept {
27  colNames = ds.colNames;
28  rows = ds.rows;
29  }
30  DataSet(DataSet&& ds) noexcept {
31  colNames = std::move(ds.colNames);
32  rows = std::move(ds.rows);
33  }
34  DataSet& operator=(const DataSet& ds) noexcept {
35  if (&ds != this) {
36  colNames = ds.colNames;
37  rows = ds.rows;
38  }
39  return *this;
40  }
41  DataSet& operator=(DataSet&& ds) noexcept {
42  if (&ds != this) {
43  colNames = std::move(ds.colNames);
44  rows = std::move(ds.rows);
45  }
46  return *this;
47  }
48 
49  const std::vector<std::string>& keys() const {
50  return colNames;
51  }
52 
53  const std::vector<Value>& rowValues(std::size_t index) const {
54  return rows[index].values;
55  }
56 
57  std::vector<Value> colValues(const std::string& colName) const {
58  std::vector<Value> col;
59  const auto find = std::find(colNames.begin(), colNames.end(), colName);
60  if (find == colNames.end()) {
61  return col;
62  }
63  std::size_t index = std::distance(colNames.begin(), find);
64  col.reserve(rows.size());
65  for (const auto& row : rows) {
66  col.emplace_back(row.values[index]);
67  }
68  return col;
69  }
70 
71  using iterator = std::vector<Row>::iterator;
72  using const_iterator = std::vector<Row>::const_iterator;
73 
74  iterator begin() {
75  return rows.begin();
76  }
77 
78  const_iterator begin() const {
79  return rows.begin();
80  }
81 
82  iterator end() {
83  return rows.end();
84  }
85 
86  const_iterator end() const {
87  return rows.end();
88  }
89 
90  template <typename T,
91  typename = typename std::enable_if<std::is_convertible<T, Row>::value, T>::type>
92  bool emplace_back(T&& row) {
93  if (row.size() != colNames.size()) {
94  return false;
95  }
96  rows.emplace_back(std::forward<T>(row));
97  return true;
98  }
99 
100  // append the DataSet to one with same header
101  bool append(DataSet&& o) {
102  if (colNames.empty()) {
103  colNames = std::move(o.colNames);
104  } else {
105  if (colNames != o.colNames) {
106  return false;
107  }
108  }
109  rows.reserve(rowSize() + o.rowSize());
110  rows.insert(
111  rows.end(), std::make_move_iterator(o.rows.begin()), std::make_move_iterator(o.rows.end()));
112  return true;
113  }
114 
115  // merge two DataSet Horizontally with same row count
116  bool merge(DataSet&& o) {
117  if (rowSize() != o.rowSize()) {
118  return false;
119  }
120  auto newColSize = colSize() + o.colSize();
121  colNames.reserve(newColSize);
122  colNames.insert(colNames.end(),
123  std::make_move_iterator(o.colNames.begin()),
124  std::make_move_iterator(o.colNames.end()));
125  for (std::size_t i = 0; i < rowSize(); ++i) {
126  rows[i].values.reserve(newColSize);
127  rows[i].values.insert(rows[i].values.begin(),
128  std::make_move_iterator(o.rows[i].values.begin()),
129  std::make_move_iterator(o.rows[i].values.end()));
130  }
131  return true;
132  }
133 
134  void clear() {
135  colNames.clear();
136  rows.clear();
137  }
138 
139  void __clear() {
140  clear();
141  }
142 
143  std::size_t size() const {
144  return rowSize();
145  }
146 
147  std::size_t rowSize() const {
148  return rows.size();
149  }
150 
151  std::size_t colSize() const {
152  return colNames.size();
153  }
154 
155  std::string toString() const {
156  std::stringstream os;
157  // header
158  for (const auto& h : colNames) {
159  os << h << "|";
160  }
161  os << std::endl;
162 
163  // body
164  for (const auto& row : rows) {
165  for (const auto& col : row.values) {
166  os << col << "|";
167  }
168  os << std::endl;
169  }
170  os << std::endl;
171  return os.str();
172  }
173 
174  bool operator==(const DataSet& rhs) const {
175  return colNames == rhs.colNames && rows == rhs.rows;
176  }
177 };
178 
179 inline std::ostream& operator<<(std::ostream& os, const DataSet& d) {
180  return os << d.toString();
181 }
182 
183 } // namespace nebula