@@ -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
51140SQLRETURN 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
61216SQLRETURN SQLFreeStmt (SQLHSTMT handle, SQLUSMALLINT option) {
0 commit comments