cql_connection.h 6 KB
Newer Older
1
// Copyright (C) 2015-2017 Deutsche Telekom AG.
2
//
3
4
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
//          Andrei Pavel <andrei.pavel@qualitance.com>
5
6
7
8
9
10
11
12
13
14
15
16
17
//
// 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.

Tomek Mrugalski's avatar
Tomek Mrugalski committed
18
19
#ifndef CQL_CONNECTION_H
#define CQL_CONNECTION_H
20
21

#include <dhcpsrv/database_connection.h>
Andrei Pavel's avatar
Andrei Pavel committed
22

23
#include <cassandra.h>
Andrei Pavel's avatar
Andrei Pavel committed
24

25
#include <cstring>
Andrei Pavel's avatar
Andrei Pavel committed
26
#include <map>
27
#include <memory>
Andrei Pavel's avatar
Andrei Pavel committed
28
#include <string>
29
30
#include <unordered_map>
#include <utility>
31
32
33
34
35
#include <vector>

namespace isc {
namespace dhcp {

36
37
38
39
40
41
42
43
44
45
46
47
/// @brief Pair containing major and minor versions
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: 2.3
/// @{
constexpr uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR;
constexpr uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR;
/// @}

Razvan Becheriu's avatar
Razvan Becheriu committed
48
/// Define CQL schema version: 1.0
49
/// @{
Razvan Becheriu's avatar
Razvan Becheriu committed
50
constexpr uint32_t CQL_SCHEMA_VERSION_MAJOR = 1u;
51
52
53
54
constexpr uint32_t CQL_SCHEMA_VERSION_MINOR = 0u;
/// @}

/// @brief Defines a single statement or query
Tomek Mrugalski's avatar
Tomek Mrugalski committed
55
///
Andrei Pavel's avatar
Andrei Pavel committed
56
57
/// @param name_ short description of the query
/// @param text_ text representation of the actual query
58
59
60
61
/// @param prepared_statement_ internal Cassandra object representing the
///     prepared statement
/// @param is_raw_statement_ shows if statement should be executed rawly or with
///     binds
Tomek Mrugalski's avatar
Tomek Mrugalski committed
62
struct CqlTaggedStatement {
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    StatementTag name_;
    char const* const text_;
    const CassPrepared* prepared_statement_;
    bool is_raw_statement_;

    /// @brief Constructor
    CqlTaggedStatement(StatementTag name, char const* const text)
        : name_(name), text_(text), prepared_statement_(NULL),
          is_raw_statement_(false) {
    }

    /// @brief Constructor
    CqlTaggedStatement(StatementTag name,
                       char const* const text,
                       bool const& is_raw_statement)
        : name_(name), text_(text), prepared_statement_(NULL),
          is_raw_statement_(is_raw_statement) {
    }
81
82
};

83
84
85
86
87
88
89
90
/// @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));
    }
};
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/// @brief Equality function for StatementMap keys
struct StatementTagEqual {
    bool operator()(StatementTag const& lhs, StatementTag const& rhs) const {
        return std::strcmp(lhs, rhs) == 0;
    }
};

/// @brief Contains all statements.
typedef std::unordered_map<StatementTag,
                           CqlTaggedStatement,
                           StatementTagHash,
                           StatementTagEqual>
    StatementMap;

typedef std::pair<StatementTag, CqlTaggedStatement> StatementMapEntry;
107

Andrei Pavel's avatar
Andrei Pavel committed
108
109
110
/// @brief Common CQL connector pool
///
/// Provides common operations for the Cassandra database connection used by
111
112
113
114
115
116
/// 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
Andrei Pavel's avatar
Andrei Pavel committed
117
/// use instances of CqlConnection.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
118
class CqlConnection : public DatabaseConnection {
119
120
121
public:
    /// @brief Constructor
    ///
Tomek Mrugalski's avatar
Tomek Mrugalski committed
122
    /// Initialize CqlConnection object with parameters needed for connection.
Andrei Pavel's avatar
Andrei Pavel committed
123
    explicit CqlConnection(const ParameterMap& parameters);
124
125

    /// @brief Destructor
Tomek Mrugalski's avatar
Tomek Mrugalski committed
126
    virtual ~CqlConnection();
127
128
129

    /// @brief Prepare statements
    ///
Tomek Mrugalski's avatar
Tomek Mrugalski committed
130
    /// Creates the prepared statements for all of the CQL statements used
Tomek Mrugalski's avatar
Tomek Mrugalski committed
131
    /// by the CQL backend.
132
    ///
Andrei Pavel's avatar
Andrei Pavel committed
133
134
135
136
    /// @throw isc::dhcp::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.
137
    void prepareStatements(StatementMap& statements);
138

Andrei Pavel's avatar
Andrei Pavel committed
139
    /// @brief Open database
140
141
    ///
    /// Opens the database using the information supplied in the parameters
Tomek Mrugalski's avatar
Tomek Mrugalski committed
142
    /// passed to the constructor. If no parameters are supplied, the default
Andrei Pavel's avatar
Andrei Pavel committed
143
    /// values will be used (e.g. keyspace 'keatest', port 9042).
144
    ///
Andrei Pavel's avatar
Andrei Pavel committed
145
    /// @throw DbOpenError error opening the database
146
147
    void openDatabase();

Andrei Pavel's avatar
Andrei Pavel committed
148
149
150
151
152
153
    /// @brief Set consistency
    void setConsistency(bool force, CassConsistency consistency);

    /// @brief Start transaction
    void startTransaction();

154
155
156
157
158
159
    /// @brief Commit Transactions
    virtual void commit();

    /// @brief Rollback Transactions
    virtual void rollback();

Andrei Pavel's avatar
Andrei Pavel committed
160
    /// @brief Check for errors
161
    ///
Andrei Pavel's avatar
Andrei Pavel committed
162
    /// Check for errors on the current database operation.
163
164
165
166
    static const std::string
    checkFutureError(const std::string& what,
                     CassFuture* future,
                     StatementTag statement_tag = NULL);
167

168
169
170
    /// @brief Pointer to external array of tagged statements containing
    ///     statement name, array of names of bind parameters and text query
    StatementMap statements_;
171

Tomek Mrugalski's avatar
Tomek Mrugalski committed
172
    /// @brief CQL connection handle
173
    CassCluster* cluster_;
Tomek Mrugalski's avatar
Tomek Mrugalski committed
174
175

    /// @brief CQL session handle
176
    CassSession* session_;
Tomek Mrugalski's avatar
Tomek Mrugalski committed
177

Andrei Pavel's avatar
Andrei Pavel committed
178
179
180
    /// @brief CQL consistency
    CassConsistency consistency_;

181
182
    // @brief Schema meta information, used for UDTs
    const CassSchemaMeta* schema_meta_;
Andrei Pavel's avatar
Andrei Pavel committed
183

184
185
    /// @brief Keyspace meta information, used for UDTs
    const CassKeyspaceMeta* keyspace_meta_;
Andrei Pavel's avatar
Andrei Pavel committed
186

187
188
    /// @brief CQL consistency enabled
    bool force_consistency_;
Andrei Pavel's avatar
Andrei Pavel committed
189
190
};

191
192
typedef std::shared_ptr<CqlConnection> CqlConnectionPtr;

Andrei Pavel's avatar
Andrei Pavel committed
193
194
}  // namespace dhcp
}  // namespace isc
195

Andrei Pavel's avatar
Andrei Pavel committed
196
#endif  // CQL_CONNECTION_H