Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #ifndef DATABASE_GENDB_IF_H_
7 : #define DATABASE_GENDB_IF_H_
8 :
9 : #include <string>
10 : #include <vector>
11 : #include <map>
12 : #include <boost/function.hpp>
13 : #include <boost/uuid/uuid.hpp>
14 : #include <boost/uuid/uuid_io.hpp>
15 : #include <boost/variant.hpp>
16 : #include <boost/ptr_container/ptr_vector.hpp>
17 : #include <boost/scoped_ptr.hpp>
18 : #include <boost/tuple/tuple.hpp>
19 : #include <boost/asio/ip/tcp.hpp>
20 :
21 : #include <base/address.h>
22 : #include <database/gendb_types.h>
23 :
24 : namespace GenDb {
25 :
26 : struct DbConsistency {
27 : enum type {
28 : UNKNOWN,
29 : ANY,
30 : ONE,
31 : TWO,
32 : THREE,
33 : QUORUM,
34 : ALL,
35 : LOCAL_QUORUM,
36 : EACH_QUORUM,
37 : SERIAL,
38 : LOCAL_SERIAL,
39 : LOCAL_ONE,
40 : };
41 : };
42 :
43 : struct Op {
44 : enum type {
45 : INVALID,
46 : GE,
47 : GT,
48 : LE,
49 : LT,
50 : EQ,
51 : LIKE,
52 : CONTAINS,
53 : };
54 : static std::string ToString(Op::type op);
55 : };
56 :
57 : struct Blob {
58 210450 : Blob(const uint8_t *data, size_t size) :
59 210450 : data_(reinterpret_cast<const char *>(data), size) {
60 210454 : }
61 189698 : const uint8_t* data() const {
62 189698 : return reinterpret_cast<const uint8_t *>(data_.c_str());
63 : }
64 189698 : size_t size() const {
65 189698 : return data_.length();
66 : }
67 : private:
68 : friend inline bool operator==(const Blob &lhs, const Blob &rhs);
69 : friend inline bool operator<(const Blob &lhs, const Blob &rhs);
70 : std::string data_;
71 : };
72 :
73 0 : inline bool operator==(const Blob &lhs, const Blob &rhs) {
74 0 : return lhs.data_ == rhs.data_;
75 : }
76 :
77 : inline bool operator<(const Blob &lhs, const Blob &rhs) {
78 : return lhs.data_ < rhs.data_;
79 : }
80 :
81 : std::ostream& operator<<(std::ostream &out, const Blob &value);
82 :
83 : /* New stuff */
84 : typedef boost::variant<boost::blank, std::string, uint64_t, uint32_t,
85 : boost::uuids::uuid, uint8_t, uint16_t, double, IpAddress, Blob>
86 : DbDataValue;
87 :
88 : enum DbDataValueType {
89 : DB_VALUE_BLANK = 0,
90 : DB_VALUE_STRING = 1,
91 : DB_VALUE_UINT64 = 2,
92 : DB_VALUE_UINT32 = 3,
93 : DB_VALUE_UUID = 4,
94 : DB_VALUE_UINT8 = 5,
95 : DB_VALUE_UINT16 = 6,
96 : DB_VALUE_DOUBLE = 7,
97 : DB_VALUE_INET = 8,
98 : DB_VALUE_BLOB = 9,
99 : };
100 :
101 : typedef std::vector<DbDataValue> DbDataValueVec;
102 : typedef std::vector<GenDb::DbDataType::type> DbDataTypeVec;
103 :
104 : std::string DbDataValueVecToString(const GenDb::DbDataValueVec &v_db_value);
105 : std::string DbDataValueToString(const GenDb::DbDataValue &db_value);
106 : std::string bytes_to_hex(const uint8_t *byte_array, size_t size);
107 :
108 : struct NewCf {
109 : enum ColumnFamilyType {
110 : COLUMN_FAMILY_INVALID = 0,
111 : COLUMN_FAMILY_SQL = 1,
112 : COLUMN_FAMILY_NOSQL = 2,
113 : };
114 : typedef std::map<std::string, GenDb::DbDataType::type> ColumnMap; /* columns meta-data */
115 :
116 3 : NewCf(const std::string& cfname, const DbDataTypeVec& keys,
117 3 : const ColumnMap& cfcolumns) :
118 3 : cfname_(cfname),
119 3 : cftype_(COLUMN_FAMILY_SQL),
120 3 : partition_keys_(keys),
121 3 : cfcolumns_(cfcolumns) {
122 3 : }
123 :
124 7 : NewCf(const std::string& cfname, const DbDataTypeVec& keys,
125 : const DbDataTypeVec& clustering_columns,
126 : const DbDataTypeVec& columns,
127 7 : const DbDataTypeVec& values) :
128 7 : cfname_(cfname),
129 7 : cftype_(COLUMN_FAMILY_NOSQL),
130 7 : partition_keys_(keys),
131 7 : clustering_columns_(clustering_columns),
132 7 : columns_(columns),
133 14 : value_(values) {
134 7 : }
135 :
136 10 : ~NewCf() {}
137 :
138 : std::string cfname_;
139 : ColumnFamilyType cftype_;
140 : DbDataTypeVec partition_keys_; /* for key-value comparison */
141 : ColumnMap cfcolumns_; /* column-name:datatype - static tables */
142 : DbDataTypeVec clustering_columns_; /* clustering column datatype - dynamic tables */
143 : DbDataTypeVec columns_; /* column datatype - dynamic tables */
144 : DbDataTypeVec value_; /* actual data - used for dynamic tables */
145 : };
146 :
147 : struct NewCol {
148 25826 : NewCol(DbDataValueVec* n, DbDataValueVec* v, int ttl) :
149 25826 : cftype_(NewCf::COLUMN_FAMILY_NOSQL), name(n), value(v), ttl(ttl),
150 25826 : timestamp(new DbDataValueVec()) {}
151 :
152 126480 : NewCol(DbDataValueVec* n, DbDataValueVec* v, int ttl,
153 126480 : DbDataValueVec* t) :
154 126480 : cftype_(NewCf::COLUMN_FAMILY_NOSQL), name(n), value(v), ttl(ttl),
155 126480 : timestamp(t) {}
156 :
157 259 : NewCol(const std::string& n, const DbDataValue& v, int ttl) :
158 259 : cftype_(NewCf::COLUMN_FAMILY_SQL), name(new DbDataValueVec(1, n)),
159 259 : value(new DbDataValueVec(1, v)), ttl(ttl),
160 259 : timestamp(new DbDataValueVec()) {}
161 :
162 : NewCol(const std::string& n, const DbDataValue& v, int ttl, DbDataValueVec *t) :
163 : cftype_(NewCf::COLUMN_FAMILY_SQL), name(new DbDataValueVec(1, n)),
164 : value(new DbDataValueVec(1, v)), ttl(ttl), timestamp(t) {}
165 :
166 88 : NewCol(const NewCol &rhs) :
167 88 : cftype_(rhs.cftype_), name(new DbDataValueVec(*rhs.name)),
168 88 : value(new DbDataValueVec(*rhs.value)), ttl(rhs.ttl),
169 88 : timestamp(new DbDataValueVec(*rhs.timestamp)) {}
170 :
171 16 : bool operator==(const NewCol &rhs) const {
172 16 : return (*rhs.name == *name &&
173 16 : *rhs.value == *value &&
174 48 : rhs.ttl == ttl &&
175 32 : *rhs.timestamp == *timestamp);
176 : }
177 :
178 : size_t GetSize() const;
179 :
180 : NewCf::ColumnFamilyType cftype_;
181 : boost::scoped_ptr<DbDataValueVec> name;
182 : boost::scoped_ptr<DbDataValueVec> value;
183 : int ttl;
184 : boost::scoped_ptr<DbDataValueVec> timestamp;
185 : };
186 :
187 : typedef boost::ptr_vector<NewCol> NewColVec;
188 :
189 : struct ColList {
190 37971 : ColList() {
191 37971 : }
192 :
193 37996 : ~ColList() {
194 37996 : }
195 :
196 : size_t GetSize() const;
197 :
198 : std::string cfname_; /* column family name */
199 : DbDataValueVec rowkey_; /* rowkey-value */
200 : NewColVec columns_;
201 : };
202 :
203 5 : inline bool operator==(const ColList &lhs, const ColList &rhs) {
204 5 : return (lhs.cfname_ == rhs.cfname_ &&
205 10 : lhs.rowkey_ == rhs.rowkey_ &&
206 10 : lhs.columns_ == rhs.columns_);
207 : }
208 :
209 : typedef boost::ptr_vector<ColList> ColListVec;
210 :
211 : struct ColumnNameRange {
212 27095 : ColumnNameRange() : count_(0), start_op_(Op::GE), finish_op_(Op::LE) {
213 27095 : }
214 :
215 27095 : ~ColumnNameRange() {
216 27095 : }
217 :
218 108338 : bool IsEmpty() const {
219 128146 : return start_.empty() &&
220 128377 : finish_.empty() &&
221 109102 : count_ == 0;
222 : }
223 :
224 : std::string ToString() const;
225 :
226 : DbDataValueVec start_;
227 : DbDataValueVec finish_;
228 : uint32_t count_;
229 : Op::type start_op_;
230 : Op::type finish_op_;
231 : };
232 :
233 : typedef boost::tuple<std::string, GenDb::Op::type, DbDataValue> WhereIndexInfo;
234 : typedef std::vector<WhereIndexInfo> WhereIndexInfoVec;
235 :
236 : // fields to read, whether the field is rowkey, whether the field is column,
237 : // whether to read writetime
238 : typedef boost::tuple<std::string, bool, bool, bool> FieldNamesToReadInfo;
239 : typedef std::vector<FieldNamesToReadInfo> FieldNamesToReadVec;
240 :
241 : typedef boost::asio::ip::tcp::endpoint Endpoint;
242 :
243 : struct DbOpResult {
244 : enum type {
245 : OK,
246 : BACK_PRESSURE,
247 : ERROR,
248 : };
249 : };
250 :
251 : class GenDbIf {
252 : public:
253 : typedef boost::function<void(void)> DbErrorHandler;
254 : typedef boost::function<void(size_t)> DbQueueWaterMarkCb;
255 : typedef boost::function<void(DbOpResult::type)> DbAddColumnCb;
256 : typedef boost::function<void(DbOpResult::type,
257 : std::auto_ptr<ColList>)> DbGetRowCb;
258 :
259 3729 : GenDbIf() {}
260 3729 : virtual ~GenDbIf() {}
261 :
262 : // Init/Uninit
263 : virtual bool Db_Init() = 0;
264 : virtual void Db_Uninit() = 0;
265 : virtual void Db_SetInitDone(bool init_done) = 0;
266 : // Tablespace
267 : virtual bool Db_SetTablespace(const std::string& tablespace) = 0;
268 : virtual bool Db_AddSetTablespace(const std::string& tablespace,
269 : const std::string& replication_factor="1") = 0;
270 : // Column family
271 : virtual bool Db_AddColumnfamily(const NewCf& cf,
272 : const std::string &compaction_strategy) = 0;
273 : virtual bool Db_UseColumnfamily(const NewCf& cf) = 0;
274 : virtual bool Db_UseColumnfamily(const std::string& cfname) = 0;
275 : // Index
276 : virtual bool Db_CreateIndex(const std::string &cfname,
277 : const std::string &column, const std::string &indexname,
278 : const GenDb::ColIndexMode::type index_mode = GenDb::ColIndexMode::NONE) = 0;
279 : // Column
280 : virtual bool Db_AddColumn(std::auto_ptr<ColList> cl,
281 : DbConsistency::type dconsistency, DbAddColumnCb cb) = 0;
282 : virtual bool Db_AddColumnSync(std::auto_ptr<ColList> cl,
283 : DbConsistency::type dconsistency) = 0;
284 : // Read/Get
285 : virtual bool Db_GetRow(ColList *ret, const std::string& cfname,
286 : const DbDataValueVec& rowkey, DbConsistency::type dconsistency) = 0;
287 : virtual bool Db_GetRow(ColList *ret, const std::string& cfname,
288 : const DbDataValueVec& rowkey, DbConsistency::type dconsistency,
289 : const ColumnNameRange& crange,
290 : const FieldNamesToReadVec &read_vec) = 0;
291 : virtual bool Db_GetMultiRow(ColListVec *ret,
292 : const std::string& cfname, const std::vector<DbDataValueVec>& key) = 0;
293 : virtual bool Db_GetMultiRow(ColListVec *ret,
294 : const std::string& cfname, const std::vector<DbDataValueVec>& key,
295 : const ColumnNameRange& crange) = 0;
296 : virtual bool Db_GetMultiRow(ColListVec *ret,
297 : const std::string& cfname, const std::vector<DbDataValueVec>& key,
298 : const ColumnNameRange& crange,
299 : const FieldNamesToReadVec &read_vec,
300 : DbConsistency::type dconsistency = DbConsistency::ONE) = 0;
301 : virtual bool Db_GetRowAsync(const std::string& cfname,
302 : const DbDataValueVec& rowkey, DbConsistency::type dconsistency,
303 : int task_id, int task_instance, DbGetRowCb cb) = 0;
304 : virtual bool Db_GetRowAsync(const std::string& cfname,
305 : const DbDataValueVec& rowkey, DbConsistency::type dconsistency,
306 : DbGetRowCb cb) = 0;
307 : virtual bool Db_GetRowAsync(const std::string& cfname,
308 : const DbDataValueVec& rowkey, const ColumnNameRange &crange,
309 : DbConsistency::type dconsistency, DbGetRowCb cb) = 0;
310 : virtual bool Db_GetRowAsync(const std::string& cfname,
311 : const DbDataValueVec& rowkey, const ColumnNameRange &crange,
312 : DbConsistency::type dconsistency, int task_id, int task_instance,
313 : DbGetRowCb cb) = 0;
314 : virtual bool Db_GetRowAsync(const std::string &cfname,
315 : const GenDb::DbDataValueVec &rowkey, const GenDb::ColumnNameRange &crange,
316 : const GenDb::WhereIndexInfoVec &where_vec,
317 : GenDb::DbConsistency::type dconsistency,
318 : GenDb::GenDbIf::DbGetRowCb cb) = 0;
319 : virtual bool Db_GetAllRows(ColListVec *ret,
320 : const std::string& cfname, DbConsistency::type dconsistency) = 0;
321 : // Queue
322 : virtual bool Db_GetQueueStats(uint64_t *queue_count,
323 : uint64_t *enqueues) const = 0;
324 : virtual void Db_SetQueueWaterMark(bool high, size_t queue_count,
325 : DbQueueWaterMarkCb cb) = 0;
326 : virtual void Db_ResetQueueWaterMarks() = 0;
327 : // Stats
328 : virtual bool Db_GetStats(std::vector<DbTableInfo> *vdbti,
329 : DbErrors *dbe) = 0;
330 : virtual bool Db_GetCumulativeStats(std::vector<DbTableInfo> *vdbti,
331 : DbErrors *dbe) const= 0;
332 : // Connection
333 : virtual std::vector<Endpoint> Db_GetEndpoints() const = 0;
334 : };
335 :
336 : } // namespace GenDb
337 :
338 : #endif // DATABASE_GENDB_IF_H_
|