Skip to content

Commit ba5c8ec

Browse files
committed
Extract SQLAllocHandle Implementation
* Tests will be added in separate PRs
1 parent 2c63d48 commit ba5c8ec

File tree

1 file changed

+165
-10
lines changed

1 file changed

+165
-10
lines changed

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 165 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,181 @@ SQLRETURN SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, SQLHANDLE* result)
3636
ARROW_LOG(DEBUG) << "SQLAllocHandle called with type: " << type
3737
<< ", parent: " << parent
3838
<< ", result: " << static_cast<const void*>(result);
39-
// GH-46096 TODO: Implement SQLAllocEnv
40-
// GH-46097 TODO: Implement SQLAllocConnect, pre-requisite requires SQLAllocEnv
39+
// GH-46096 TODO: Implement SQLAllocEnv //-AL- todo remove
40+
// GH-46097 TODO: Add tests for SQLAllocConnect, pre-requisite requires SQLAllocEnv
4141
// implementation
4242

43-
// GH-47706 TODO: Implement SQLAllocStmt, pre-requisite requires
43+
// GH-47706 TODO: Add tests for SQLAllocStmt, pre-requisite requires
4444
// SQLDriverConnect implementation
4545

46-
// GH-47707 TODO: Implement SQL_HANDLE_DESC for
46+
// GH-47707 TODO: Add tests for SQL_HANDLE_DESC implementation for
4747
// descriptor handle, pre-requisite requires SQLAllocStmt
48-
return SQL_INVALID_HANDLE;
48+
49+
*result = nullptr;
50+
51+
switch (type) {
52+
case SQL_HANDLE_ENV: {
53+
using driver::flight_sql::FlightSqlDriver;
54+
using ODBC::ODBCEnvironment;
55+
56+
*result = SQL_NULL_HENV;
57+
58+
try {
59+
static std::shared_ptr<FlightSqlDriver> odbc_driver =
60+
std::make_shared<FlightSqlDriver>();
61+
*result = reinterpret_cast<SQLHENV>(new ODBCEnvironment(odbc_driver));
62+
63+
return SQL_SUCCESS;
64+
} catch (const std::bad_alloc&) {
65+
// allocating environment failed so cannot log diagnostic error here
66+
return SQL_ERROR;
67+
}
68+
}
69+
70+
case SQL_HANDLE_DBC: {
71+
using ODBC::ODBCConnection;
72+
using ODBC::ODBCEnvironment;
73+
74+
*result = SQL_NULL_HDBC;
75+
76+
ODBCEnvironment* environment = reinterpret_cast<ODBCEnvironment*>(parent);
77+
78+
return ODBCEnvironment::ExecuteWithDiagnostics(environment, SQL_ERROR, [=]() {
79+
std::shared_ptr<ODBCConnection> conn = environment->CreateConnection();
80+
81+
if (conn) {
82+
*result = reinterpret_cast<SQLHDBC>(conn.get());
83+
84+
return SQL_SUCCESS;
85+
}
86+
87+
return SQL_ERROR;
88+
});
89+
}
90+
91+
case SQL_HANDLE_STMT: {
92+
using ODBC::ODBCConnection;
93+
using ODBC::ODBCStatement;
94+
95+
*result = SQL_NULL_HSTMT;
96+
97+
ODBCConnection* connection = reinterpret_cast<ODBCConnection*>(parent);
98+
99+
return ODBCConnection::ExecuteWithDiagnostics(connection, SQL_ERROR, [=]() {
100+
std::shared_ptr<ODBCStatement> statement = connection->CreateStatement();
101+
102+
if (statement) {
103+
*result = reinterpret_cast<SQLHSTMT>(statement.get());
104+
105+
return SQL_SUCCESS;
106+
}
107+
108+
return SQL_ERROR;
109+
});
110+
}
111+
112+
case SQL_HANDLE_DESC: {
113+
using ODBC::ODBCConnection;
114+
using ODBC::ODBCDescriptor;
115+
116+
*result = SQL_NULL_HDESC;
117+
118+
ODBCConnection* connection = reinterpret_cast<ODBCConnection*>(parent);
119+
120+
return ODBCConnection::ExecuteWithDiagnostics(connection, SQL_ERROR, [=]() {
121+
std::shared_ptr<ODBCDescriptor> descriptor = connection->CreateDescriptor();
122+
123+
if (descriptor) {
124+
*result = reinterpret_cast<SQLHDESC>(descriptor.get());
125+
126+
return SQL_SUCCESS;
127+
}
128+
129+
return SQL_ERROR;
130+
});
131+
}
132+
133+
default:
134+
break;
135+
}
136+
137+
return SQL_ERROR;
49138
}
50139

51140
SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle) {
52141
ARROW_LOG(DEBUG) << "SQLFreeHandle called with type: " << type
53142
<< ", handle: " << handle;
54-
// GH-46096 TODO: Implement SQLFreeEnv
55-
// GH-46097 TODO: Implement SQLFreeConnect
56-
// GH-47706 TODO: Implement SQLFreeStmt
57-
// GH-47707 TODO: Implement SQL_HANDLE_DESC for descriptor handle
58-
return SQL_INVALID_HANDLE;
143+
// GH-46096 TODO: Implement SQLFreeEnv //-AL- todo remove
144+
// GH-46097 TODO: Add tests for SQLFreeConnect, pre-requisite requires SQLAllocConnect
145+
// implementation
146+
147+
// GH-47706 TODO: Add tests for SQLFreeStmt, pre-requisite requires
148+
// SQLAllocStmt tests
149+
150+
// GH-47707 TODO: Add tests for SQL_HANDLE_DESC implementation for
151+
// descriptor handle
152+
switch (type) {
153+
case SQL_HANDLE_ENV: {
154+
using ODBC::ODBCEnvironment;
155+
156+
ODBCEnvironment* environment = reinterpret_cast<ODBCEnvironment*>(handle);
157+
158+
if (!environment) {
159+
return SQL_INVALID_HANDLE;
160+
}
161+
162+
delete environment;
163+
164+
return SQL_SUCCESS;
165+
}
166+
167+
case SQL_HANDLE_DBC: {
168+
using ODBC::ODBCConnection;
169+
170+
ODBCConnection* conn = reinterpret_cast<ODBCConnection*>(handle);
171+
172+
if (!conn) {
173+
return SQL_INVALID_HANDLE;
174+
}
175+
176+
conn->ReleaseConnection();
177+
178+
return SQL_SUCCESS;
179+
}
180+
181+
case SQL_HANDLE_STMT: {
182+
using ODBC::ODBCStatement;
183+
184+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(handle);
185+
186+
if (!statement) {
187+
return SQL_INVALID_HANDLE;
188+
}
189+
190+
statement->ReleaseStatement();
191+
192+
return SQL_SUCCESS;
193+
}
194+
195+
case SQL_HANDLE_DESC: {
196+
using ODBC::ODBCDescriptor;
197+
198+
ODBCDescriptor* descriptor = reinterpret_cast<ODBCDescriptor*>(handle);
199+
200+
if (!descriptor) {
201+
return SQL_INVALID_HANDLE;
202+
}
203+
204+
descriptor->ReleaseDescriptor();
205+
206+
return SQL_SUCCESS;
207+
}
208+
209+
default:
210+
break;
211+
}
212+
213+
return SQL_ERROR;
59214
}
60215

61216
SQLRETURN SQLFreeStmt(SQLHSTMT handle, SQLUSMALLINT option) {

0 commit comments

Comments
 (0)