forked from vmware-archive/gemfirexd-oss
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathClientService.h
More file actions
379 lines (288 loc) · 12.3 KB
/
Copy pathClientService.h
File metadata and controls
379 lines (288 loc) · 12.3 KB
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* 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. See accompanying
* LICENSE file.
*/
/*
* Changes for SnappyData data platform.
*
* Portions Copyright (c) 2018 SnappyData, Inc. All rights reserved.
*
* 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. See accompanying
* LICENSE file.
*/
#ifndef CLIENTSERVICE_H_
#define CLIENTSERVICE_H_
#include "ClientBase.h"
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include "../thrift/SnappyDataService.h"
using namespace apache::thrift;
namespace apache {
namespace thrift {
namespace transport {
class TSocket;
}
namespace protocol {
class TProtocol;
}
}
}
namespace io {
namespace snappydata {
namespace client {
namespace impl {
class ClientTransport;
class ControlConnection;
enum class FailoverStatus :unsigned char{
NONE, /** no failover to be done */
NEW_SERVER, /** failover to a new server */
RETRY /** retry to the same server */
};
class SnappyDataClient : public thrift::SnappyDataServiceClient {
public:
SnappyDataClient(protocol::TProtocol* prot) :
thrift::SnappyDataServiceClient(
boost::shared_ptr < protocol::TProtocol > (prot)) {
}
inline protocol::TProtocol* getProtocol() const noexcept {
return iprot_;
}
private:
void resetProtocols(
const boost::shared_ptr<protocol::TProtocol>& iprot,
const boost::shared_ptr<protocol::TProtocol>& oprot) {
piprot_ = iprot;
poprot_ = oprot;
iprot_ = iprot.get();
oprot_ = oprot.get();
}
friend class ClientService;
};
class ClientService {
private:
const thrift::OpenConnectionArgs m_connArgs;
bool m_loadBalance;
thrift::ServerType::type m_reqdServerType;
bool m_useFramedTransport;
//const SSLSocketParameters m_sslParams;
std::set<std::string> m_serverGroups;
boost::shared_ptr<ClientTransport> m_transport;
SnappyDataClient m_client;
thrift::HostAddress m_currentHostAddr;
std::vector<thrift::HostAddress> m_connHosts;
int64_t m_connId;
std::string m_token;
bool m_isOpen;
std::map<thrift::TransactionAttribute::type, bool> m_pendingTXAttrs;
bool m_hasPendingTXAttrs;
IsolationLevel m_isolationLevel;
std::map<thrift::TransactionAttribute::type, bool> m_currentTXAttrs;
// using boost::mutex and not std::mutex due to superior implementation on
// Windows compared to that provided by VS (which always does kernel call)
boost::mutex m_lock;
// no copy constructor or assignment operator due to obvious issues
// with usage of same connection by multiple threads concurrently
ClientService(const ClientService&) = delete;
ClientService& operator=(const ClientService&) = delete;
void clearPendingTransactionAttrs();
static thrift::OpenConnectionArgs& initConnectionArgs(
thrift::OpenConnectionArgs& connArgs);
static protocol::TProtocol* createDummyProtocol();
static protocol::TProtocol* createProtocol(
thrift::HostAddress& hostAddr,
const thrift::ServerType::type serverType,
const bool useFramedTransport,
//const SSLSocketParameters& sslParams,
boost::shared_ptr<ClientTransport>& returnTransport);
void updateFailedServersForCurrent(std::set<thrift::HostAddress>& failedServers,
bool checkAllFailed, std::exception* failure);
protected:
virtual void checkConnection(const char* op);
virtual void handleSnappyException(const thrift::SnappyException& se);
virtual void handleStdException(const char* op,
const std::exception& stde);
virtual void handleTTransportException(const char* op,
const transport::TTransportException& tte);
virtual void handleTProtocolException(const char* op,
const protocol::TProtocolException& tpe);
virtual void handleTException(const char* op, const TException& te);
virtual void handleUnknownException(const char* op);
BOOST_NORETURN void throwSQLExceptionForNodeFailure(const char* op,
const std::exception& se);
void openConnection(thrift::HostAddress& hostAddr,
std::set<thrift::HostAddress>& failedServers);
void flushPendingTransactionAttrs();
void setPendingTransactionAttrs(thrift::StatementAttrs& stmtAttrs);
void getTransactionAttributesNoLock(
std::map<thrift::TransactionAttribute::type, bool>& result);
void destroyTransport() noexcept;
// void handleException(const TException* te,
// const std::set<thrift::HostAddress>& failedServers, bool tryFailover, bool ignoreFailOver,
// bool createNewConnection, const std::string& op);
private:
// the static hostName and hostId used by all connections
static std::string s_hostName;
static std::string s_hostId;
static boost::mutex s_globalLock;
static bool s_initialized;
/**
* Global initialization that is done only once.
* The s_globalLock must be held in the invocation.
*/
static bool globalInitialize();
public:
ClientService(const std::string& host, const int port,
thrift::OpenConnectionArgs& arguments);
virtual ~ClientService();
static void staticInitialize();
static void staticInitialize(
std::map<std::string, std::string>& props);
static thrift::ServerType::type getServerType(bool isServer,
bool useBinaryProtocol, bool useSSL);
inline bool isOpen() const noexcept {
return m_isOpen;
}
inline const boost::shared_ptr<ClientTransport>& getTransport()
const noexcept {
return m_transport;
}
const char* getTokenStr() const noexcept {
return m_token.empty() ? NULL : m_token.c_str();
}
const thrift::HostAddress& getCurrentHostAddress() const noexcept {
return m_currentHostAddr;
}
const thrift::OpenConnectionArgs& getConnectionArgs() const noexcept {
return m_connArgs;
}
IsolationLevel getCurrentIsolationLevel() const noexcept {
return m_isolationLevel;
}
void execute(thrift::StatementResult& result,
const std::string& sql,
const std::map<int32_t, thrift::OutputParameter>& outputParams,
const thrift::StatementAttrs& attrs);
void executeUpdate(thrift::UpdateResult& result,
const std::vector<std::string>& sqls,
const thrift::StatementAttrs& attrs);
void executeQuery(thrift::RowSet& result, const std::string& sql,
const thrift::StatementAttrs& attrs);
void prepareStatement(thrift::PrepareResult& result,
const std::string& sql,
const std::map<int32_t, thrift::OutputParameter>& outputParams,
const thrift::StatementAttrs& attrs);
void executePrepared(thrift::StatementResult& result,
thrift::PrepareResult& prepResult, const thrift::Row& params,
const std::map<int32_t, thrift::OutputParameter>& outputParams,
const thrift::StatementAttrs& attrs);
void executePreparedUpdate(thrift::UpdateResult& result,
thrift::PrepareResult& prepResult, const thrift::Row& params,
const thrift::StatementAttrs& attrs);
void executePreparedQuery(thrift::RowSet& result,
thrift::PrepareResult& prepResult, const thrift::Row& params,
const thrift::StatementAttrs& attrs);
void executePreparedBatch(thrift::UpdateResult& result,
thrift::PrepareResult& prepResult,
const std::vector<thrift::Row>& paramsBatch,
const thrift::StatementAttrs& attrs);
void prepareAndExecute(thrift::StatementResult& result,
const std::string& sql,
const std::vector<thrift::Row>& paramsBatch,
const std::map<int32_t, thrift::OutputParameter>& outputParams,
const thrift::StatementAttrs& attrs);
void getNextResultSet(thrift::RowSet& result,
const int64_t cursorId, const int8_t otherResultSetBehaviour);
void getBlobChunk(thrift::BlobChunk& result, const int32_t lobId,
const int64_t offset, const int32_t size,
const bool freeLobAtEnd);
void getClobChunk(thrift::ClobChunk& result, const int32_t lobId,
const int64_t offset, const int32_t size,
const bool freeLobAtEnd);
int64_t sendBlobChunk(thrift::BlobChunk& chunk);
int64_t sendClobChunk(thrift::ClobChunk& chunk);
void freeLob(const int32_t lobId);
void scrollCursor(thrift::RowSet& result, const int64_t cursorId,
const int32_t offset, const bool offsetIsAbsolute,
const bool fetchReverse, const int32_t fetchSize);
void executeCursorUpdate(const int64_t cursorId,
const thrift::CursorUpdateOperation::type operation,
const thrift::Row& changedRow,
const std::vector<int32_t>& changedColumns,
const int32_t changedRowIndex);
void executeBatchCursorUpdate(const int64_t cursorId,
const std::vector<thrift::CursorUpdateOperation::type>& operations,
const std::vector<thrift::Row>& changedRows,
const std::vector<std::vector<int32_t> >& changedColumnsList,
const std::vector<int32_t>& changedRowIndexes);
void beginTransaction(const IsolationLevel isolationLevel);
void setTransactionAttribute(const TransactionAttribute flag, bool isTrue);
bool getTransactionAttribute(const TransactionAttribute flag);
void getTransactionAttributes(std::map<thrift::TransactionAttribute::type,
bool>& result);
void commitTransaction(const bool startNewTransaction);
void rollbackTransaction(const bool startNewTransaction);
void fetchActiveConnections(
std::vector<thrift::ConnectionProperties>& result);
void fetchActiveStatements(std::map<int64_t, std::string>& result);
void getServiceMetaData(thrift::ServiceMetaData& result);
void getSchemaMetaData(thrift::RowSet& result,
const thrift::ServiceMetaDataCall::type schemaCall,
thrift::ServiceMetaDataArgs& metadataArgs);
void getIndexInfo(thrift::RowSet& result,
thrift::ServiceMetaDataArgs& metadataArgs, const bool unique,
const bool approximate);
void getUDTs(thrift::RowSet& result,
thrift::ServiceMetaDataArgs& metadataArgs,
const std::vector<thrift::SnappyType::type>& types);
void getBestRowIdentifier(thrift::RowSet& result,
thrift::ServiceMetaDataArgs& metadataArgs, const int32_t scope,
const bool nullable);
void closeResultSet(const int64_t cursorId);
void cancelStatement(const int64_t stmtId);
void closeStatement(const int64_t stmtId);
void bulkClose(const std::vector<thrift::EntityId>& entities);
void close();
const std::vector<thrift::HostAddress>& getLocators() const noexcept{
return m_connHosts;
}
const std::set<std::string>& getServerGrps() const noexcept{
return m_serverGroups;
}
inline bool isFrameTransport() const noexcept {
return m_useFramedTransport;
}
};
class NetConnection{
private:
/** set of SQLState strings that denote failover should be done */
static std::set<std::string> failoverSQLStateSet;
public:
static FailoverStatus getFailoverStatus(const std::string& sqlState,const int32_t& errorCode, const TException& snappyEx);
};
} /* namespace impl */
} /* namespace client */
} /* namespace snappydata */
} /* namespace io */
#endif /* CLIENTSERVICE_H_ */