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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2017 Deutsche Telekom AG.
//
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
// Andrei Pavel <andrei.pavel@qualitance.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CQL_CONNECTION_H
#define CQL_CONNECTION_H
#include <database/database_connection.h>
#include <cassandra.h>
#include <cstring>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace isc {
namespace db {
/// @brief Pair containing major and minor versions
/// @todo: This is already defined in lease_mgr.h. Need to have one
/// definition. May need to move it if necessary.
typedef std::pair<uint32_t, uint32_t> VersionPair;
/// @brief Statement index representing the statement name
typedef char const* const StatementTag;
/// @brief Define CQL backend version. The CASS_VERSION_* constants
/// are defined in a header provided by cpp-driver.
/// @{
constexpr uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR;
constexpr uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR;
/// @}
/// Define CQL schema version: 5.0
/// @{
constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 5u;
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 0u;
/// @}
/// @brief Defines a single statement or query
struct CqlTaggedStatement {
/// Short description of the query
StatementTag name_;
/// Text representation of the actual query
char const* const text_;
/// Internal Cassandra object representing the prepared statement
const CassPrepared* prepared_statement_;
/// Should the statement be executed raw or with binds?
bool is_raw_;
/// @brief Constructor
/// @param name brief name of the query
/// @param text text (CQL) representation of the query
CqlTaggedStatement(StatementTag name, char const* const text)
: name_(name), text_(text), prepared_statement_(NULL), is_raw_(false) {
}
/// @brief Constructor
/// @param name brief name of the query
/// @param text text (CQL) representation of the query
/// @param is_raw should the statement be executed raw?
CqlTaggedStatement(StatementTag name, char const* const text, bool const& is_raw)
: name_(name), text_(text), prepared_statement_(NULL), is_raw_(is_raw) {
}
};
/// @brief Hash function for StatementMap keys
///
/// Delegates to std::hash<std::string>.
struct StatementTagHash {
size_t operator()(StatementTag const& key) const {
return std::hash<std::string>{}(std::string(key));
}
};
/// @brief Equality function for StatementMap keys
struct StatementTagEqual {
bool operator()(StatementTag const& lhs, StatementTag const& rhs) const {
return std::strcmp(lhs, rhs) == 0;
}
};
/// @brief A container for all statements.
typedef std::unordered_map<StatementTag, CqlTaggedStatement,
StatementTagHash, StatementTagEqual> StatementMap;
/// @brief A type for a single entry on the statements map
typedef std::pair<StatementTag, CqlTaggedStatement> StatementMapEntry;
/// @brief Common CQL connector pool
///
/// Provides common operations for the Cassandra database connection used by
/// CqlLeaseMgr, CqlHostDataSource and CqlSrvConfigMgr. Manages the connection
/// to the Cassandra database and preparing of compiled statements. Its fields
/// are public because they are used (both set and retrieved) in classes that
/// use instances of CqlConnection.
class CqlConnection : public db::DatabaseConnection {
public:
/// @brief Constructor
///
/// Initialize CqlConnection object with parameters needed for connection.
/// @param parameters specify the connection details (username, ip addresses etc.)
explicit CqlConnection(const ParameterMap& parameters);
/// @brief Destructor
virtual ~CqlConnection();
/// @brief Get the schema version.
///
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
///
/// @return Version number as a pair of unsigned integers. "first" is the
/// major version number, "second" the minor number.
///
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
static std::pair<uint32_t, uint32_t>
getVersion(const ParameterMap& parameters);
/// @brief Prepare statements
///
/// Creates the prepared statements for all of the CQL statements used
/// by the CQL backend.
/// @param statements statements to be prepared
///
/// @throw isc::db::DbOperationError if an operation on the open database
/// has failed
/// @throw isc::InvalidParameter if there is an invalid access in the
/// vector. This represents an internal error within the code.
void prepareStatements(StatementMap& statements);
/// @brief Open database
///
/// Opens the database using the information supplied in the parameters
/// passed to the constructor. If no parameters are supplied, the default
/// values will be used. The parameters supported as as follows (default
/// values specified in parentheses):
/// - keyspace: name of the database to which to connect (keatest)
/// - contact-points: IP addresses of the nodes to connect to (127.0.0.1)
/// - consistency: consistency level (quorum)
/// - serial-consistency: serial consistency level (serial)
/// - port: The TCP port to use (9042)
/// - user - credentials to use when connecting (no username)
/// - password - credentials to use when connecting (no password)
/// - reconnect-wait-time 2000
/// - connect-timeout 5000
/// - request-timeout 12000
/// - tcp-keepalive no
/// - tcp-nodelay no
///
/// @throw DbOpenError error opening the database
void openDatabase();
/// @brief Set consistency
void setConsistency(bool force,
CassConsistency consistency,
CassConsistency serial_consistency);
/// @brief Start transaction
void startTransaction();
/// @brief Commit Transactions
virtual void commit();
/// @brief Rollback Transactions
virtual void rollback();
/// @brief parse Consistency value
static CassConsistency parseConsistency(std::string value);
/// @brief Check for errors
///
/// Check for errors on the current database operation and returns text
/// description of what happened. In case of success, also returns
/// some logging friendly text.
///
/// @param what text description of the operation
/// @param future the structure that holds the status of operation
/// @param statement_tag statement that was used (optional)
/// @return text description of the error
static const std::string
checkFutureError(const std::string& what,
CassFuture* future,
StatementTag statement_tag = NULL);
/// @brief Pointer to external array of tagged statements containing
/// statement name, array of names of bind parameters and text query
StatementMap statements_;
/// @brief CQL connection handle
CassCluster* cluster_;
/// @brief CQL session handle
CassSession* session_;
/// @brief CQL consistency
CassConsistency consistency_;
/// @brief CQL serial consistency
CassConsistency serial_consistency_;
// @brief Schema meta information, used for UDTs
const CassSchemaMeta* schema_meta_;
/// @brief Keyspace meta information, used for UDTs
const CassKeyspaceMeta* keyspace_meta_;
/// @brief CQL consistency enabled
bool force_consistency_;
};
typedef std::shared_ptr<CqlConnection> CqlConnectionPtr;
} // namespace db
} // namespace isc
#endif // CQL_CONNECTION_H
|