Skip to content

Commit e2eec95

Browse files
committed
Error handlig
1 parent 661cb65 commit e2eec95

File tree

11 files changed

+431
-427
lines changed

11 files changed

+431
-427
lines changed

CMakePresets.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"cacheVariables": {
5656
"YDB_SDK_TESTS": "TRUE",
5757
"YDB_SDK_EXAMPLES": "TRUE",
58+
"YDB_SDK_ODBC": "TRUE",
5859
"ARCADIA_ROOT": "..",
5960
"ARCADIA_BUILD_ROOT": "."
6061
}

odbc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_library(ydb-odbc SHARED
33
src/utils/types.cpp
44
src/utils/util.cpp
55
src/utils/convert.cpp
6+
src/utils/error_manager.cpp
67
src/odbc_driver.cpp
78
src/connection.cpp
89
src/statement.cpp

odbc/src/connection.cpp

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "connection.h"
22
#include "statement.h"
3+
#include "utils/error_manager.h"
34

45
#include <cstring>
56
#include <string>
@@ -35,8 +36,7 @@ SQLRETURN TConnection::DriverConnect(const std::string& connectionString) {
3536
Database_ = params["Database"];
3637

3738
if (Endpoint_.empty() || Database_.empty()) {
38-
AddError("08001", 0, "Missing Endpoint or Database in connection string");
39-
return SQL_ERROR;
39+
throw TOdbcException("08001", 0, "Missing Endpoint or Database in connection string");
4040
}
4141

4242
YdbDriver_ = std::make_unique<NYdb::TDriver>(NYdb::TDriverConfig()
@@ -64,8 +64,7 @@ SQLRETURN TConnection::Connect(const std::string& serverName,
6464
Database_ = database;
6565

6666
if (Endpoint_.empty() || Database_.empty()) {
67-
AddError("08001", 0, "Missing Endpoint or Database in DSN");
68-
return SQL_ERROR;
67+
throw TOdbcException("08001", 0, "Missing Endpoint or Database in DSN");
6968
}
7069

7170
YdbDriver_ = std::make_unique<NYdb::TDriver>(NYdb::TDriverConfig()
@@ -85,30 +84,6 @@ SQLRETURN TConnection::Disconnect() {
8584
return SQL_SUCCESS;
8685
}
8786

88-
SQLRETURN TConnection::GetDiagRec(SQLSMALLINT recNumber, SQLCHAR* sqlState, SQLINTEGER* nativeError,
89-
SQLCHAR* messageText, SQLSMALLINT bufferLength, SQLSMALLINT* textLength) {
90-
if (recNumber < 1 || recNumber > (SQLSMALLINT)Errors_.size()) {
91-
return SQL_NO_DATA;
92-
}
93-
94-
const auto& err = Errors_[recNumber-1];
95-
if (sqlState) {
96-
strncpy((char*)sqlState, err.SqlState.c_str(), 6);
97-
}
98-
99-
if (nativeError) {
100-
*nativeError = err.NativeError;
101-
}
102-
103-
if (messageText && bufferLength > 0) {
104-
strncpy((char*)messageText, err.Message.c_str(), bufferLength);
105-
if (textLength) {
106-
*textLength = (SQLSMALLINT)std::min((int)err.Message.size(), (int)bufferLength);
107-
}
108-
}
109-
return SQL_SUCCESS;
110-
}
111-
11287
std::unique_ptr<TStatement> TConnection::CreateStatement() {
11388
return std::make_unique<TStatement>(this);
11489
}
@@ -118,22 +93,11 @@ void TConnection::RemoveStatement(TStatement* stmt) {
11893
[stmt](const std::unique_ptr<TStatement>& s) { return s.get() == stmt; }), Statements_.end());
11994
}
12095

121-
void TConnection::AddError(const std::string& sqlState, SQLINTEGER nativeError, const std::string& message) {
122-
Errors_.push_back({sqlState, nativeError, message});
123-
}
124-
125-
void TConnection::ClearErrors() {
126-
Errors_.clear();
127-
}
128-
12996
SQLRETURN TConnection::SetAutocommit(bool value) {
13097
Autocommit_ = value;
13198
if (Autocommit_ && Tx_) {
13299
auto status = Tx_->Commit().ExtractValueSync();
133-
if (!status.IsSuccess()) {
134-
AddError("08001", 0, "Failed to commit transaction");
135-
return SQL_ERROR;
136-
}
100+
NStatusHelpers::ThrowOnError(status);
137101
Tx_.reset();
138102
}
139103
return SQL_SUCCESS;
@@ -153,20 +117,14 @@ void TConnection::SetTx(const NQuery::TTransaction& tx) {
153117

154118
SQLRETURN TConnection::CommitTx() {
155119
auto status = Tx_->Commit().ExtractValueSync();
156-
if (!status.IsSuccess()) {
157-
AddError("08001", 0, "Failed to commit transaction");
158-
return SQL_ERROR;
159-
}
120+
NStatusHelpers::ThrowOnError(status);
160121
Tx_.reset();
161122
return SQL_SUCCESS;
162123
}
163124

164125
SQLRETURN TConnection::RollbackTx() {
165126
auto status = Tx_->Rollback().ExtractValueSync();
166-
if (!status.IsSuccess()) {
167-
AddError("08001", 0, "Failed to rollback transaction");
168-
return SQL_ERROR;
169-
}
127+
NStatusHelpers::ThrowOnError(status);
170128
Tx_.reset();
171129
return SQL_SUCCESS;
172130
}

odbc/src/connection.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "environment.h"
4+
#include "utils/error_manager.h"
45

56
#include <ydb-cpp-sdk/client/driver/driver.h>
67
#include <ydb-cpp-sdk/client/query/client.h>
@@ -19,15 +20,14 @@ namespace NOdbc {
1920

2021
class TStatement;
2122

22-
class TConnection {
23+
class TConnection : public TErrorManager {
2324
private:
2425
std::unique_ptr<TDriver> YdbDriver_;
2526
std::unique_ptr<NQuery::TQueryClient> YdbClient_;
2627
std::unique_ptr<NTable::TTableClient> YdbTableClient_;
2728
std::unique_ptr<NScheme::TSchemeClient> YdbSchemeClient_;
2829
std::optional<NQuery::TTransaction> Tx_;
2930

30-
TErrorList Errors_;
3131
std::vector<std::unique_ptr<TStatement>> Statements_;
3232
std::string Endpoint_;
3333
std::string Database_;
@@ -42,8 +42,6 @@ class TConnection {
4242

4343
SQLRETURN DriverConnect(const std::string& connectionString);
4444
SQLRETURN Disconnect();
45-
SQLRETURN GetDiagRec(SQLSMALLINT recNumber, SQLCHAR* sqlState, SQLINTEGER* nativeError,
46-
SQLCHAR* messageText, SQLSMALLINT bufferLength, SQLSMALLINT* textLength);
4745

4846
std::unique_ptr<TStatement> CreateStatement();
4947
void RemoveStatement(TStatement* stmt);
@@ -52,9 +50,6 @@ class TConnection {
5250
NYdb::NTable::TTableClient* GetTableClient() { return YdbTableClient_.get(); }
5351
NScheme::TSchemeClient* GetSchemeClient() { return YdbSchemeClient_.get(); }
5452

55-
void AddError(const std::string& sqlState, SQLINTEGER nativeError, const std::string& message);
56-
void ClearErrors();
57-
5853
SQLRETURN SetAutocommit(bool value);
5954
bool GetAutocommit() const;
6055

odbc/src/environment.cpp

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,5 @@ SQLRETURN TEnvironment::SetAttribute(SQLINTEGER attribute, SQLPOINTER value, SQL
1313
return SQL_SUCCESS;
1414
}
1515

16-
SQLRETURN TEnvironment::GetDiagRec(SQLSMALLINT recNumber,
17-
SQLCHAR* sqlState,
18-
SQLINTEGER* nativeError,
19-
SQLCHAR* messageText,
20-
SQLSMALLINT bufferLength,
21-
SQLSMALLINT* textLength) {
22-
23-
if (recNumber < 1 || recNumber > (SQLSMALLINT)Errors_.size()) {
24-
return SQL_NO_DATA;
25-
}
26-
27-
const auto& err = Errors_[recNumber-1];
28-
if (sqlState) {
29-
strncpy((char*)sqlState, err.SqlState.c_str(), 6);
30-
}
31-
32-
if (nativeError) {
33-
*nativeError = err.NativeError;
34-
}
35-
36-
if (messageText && bufferLength > 0) {
37-
strncpy((char*)messageText, err.Message.c_str(), bufferLength);
38-
if (textLength) {
39-
*textLength = (SQLSMALLINT)std::min((int)err.Message.size(), (int)bufferLength);
40-
}
41-
}
42-
return SQL_SUCCESS;
43-
}
44-
45-
void TEnvironment::AddError(const std::string& sqlState, SQLINTEGER nativeError, const std::string& message) {
46-
Errors_.push_back({sqlState, nativeError, message});
47-
}
48-
49-
void TEnvironment::ClearErrors() {
50-
Errors_.clear();
51-
}
52-
5316
} // namespace NOdbc
5417
} // namespace NYdb

odbc/src/environment.h

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,24 @@
11
#pragma once
22

3+
#include "utils/error_manager.h"
4+
35
#include <sql.h>
46
#include <sqlext.h>
57

6-
#include <vector>
7-
#include <string>
8-
98
namespace NYdb {
109
namespace NOdbc {
1110

1211
class TConnection;
1312

14-
struct TErrorInfo {
15-
std::string SqlState;
16-
SQLINTEGER NativeError;
17-
std::string Message;
18-
};
19-
20-
using TErrorList = std::vector<TErrorInfo>;
21-
22-
class TEnvironment {
13+
class TEnvironment : public TErrorManager {
2314
private:
2415
SQLINTEGER OdbcVersion_;
25-
TErrorList Errors_;
2616

2717
public:
2818
TEnvironment();
2919
~TEnvironment();
3020

3121
SQLRETURN SetAttribute(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER stringLength);
32-
SQLRETURN GetDiagRec(SQLSMALLINT recNumber, SQLCHAR* sqlState, SQLINTEGER* nativeError,
33-
SQLCHAR* messageText, SQLSMALLINT bufferLength, SQLSMALLINT* textLength);
34-
35-
void AddError(const std::string& sqlState, SQLINTEGER nativeError, const std::string& message);
36-
void ClearErrors();
3722
};
3823

3924
} // namespace NOdbc

0 commit comments

Comments
 (0)