C++ ODBC Wrapper Classes ( SQLHANDLES ) - part 1
-
Friday, August 03, 2012 1:43 AM
In order to further increase my knowledge of ODBC and C++ good design practices i have decided to try my go at creating wrapper classes of the current ODBC C Api located on MSDN. I'm mainly wanting criticism on design problems people might see. Any advice is greatly appreciated ;) cheers
In order to avoid VTABLE overhead i have tried my best to implement simulated dynamic binding/CRTP ( which i believe i have implemented correctly )template<class TDerived, SQLSMALLINT THandle = SQL_HANDLE_UNKNOWN> class __declspec(novtable) CHandle { public: SQLHANDLE m_h; SQLSMALLINT m_hType; enum { SQL_HANDLE_UNKNOWN = -1 }; public: CHandle() : m_h(NULL), m_hType(THandle) { _ASSERTE(m_hType != -1); } CHandle(SQLHANDLE h) : m_h(h), m_hType(THandle) { _ASSERTE(h != NULL); _ASSERTE(m_hType != -1); Attach(h); } void Attach(_In_ SQLHANDLE h) { _ASSERTE(h != NULL); _ASSERTE(m_h == NULL); _ASSERTE(m_hType != -1); m_h = h; } SQLHANDLE Detach() { _ASSERTE(m_h != NULL); _ASSERTE(m_hType != -1); SQLHANDLE hTemp = m_h; m_h = NULL; return hTemp; } bool Create() { _ASSERTE(m_h == NULL); _ASSERTE(m_hType != -1); g_rt = SQLAllocHandle(THandle, NULL, &m_h); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } void Destroy() { _ASSERTE(m_h != NULL); _ASSERTE(m_hType != -1); g_rt = SQLFreeHandle(THandle, m_h); _ASSERTE(SQL_SUCCEEDED(g_rt)); m_h = NULL; m_hType = -1; } // TODO : test setting multiple attributes bool SetAttribute(_In_ SQLINTEGER attribute, _In_ SQLPOINTER value) { _ASSERTE(m_h != NULL); return static_cast<TDerived*>(this)->_SetAttribute(attribute, value); } // TODO : test getting multiple attributes bool GetAttribute(_In_ SQLINTEGER attribute, _Inout_ SQLPOINTER pValue, _Inout_ SQLINTEGER* pcbWritten) { _ASSERTE(m_h != NULL); return static_cast<TDerived*>(this)->_GetAttribute(attribute, pValue, pcbWritten); } operator SQLHANDLE() { return m_h; } }; class __declspec(novtable) CEnviromentHandle : public CHandle< CEnviromentHandle, SQL_HANDLE_ENV> { public: bool _SetAttribute(_In_ SQLINTEGER attribute, _In_ SQLPOINTER value) { _ASSERTE(m_h != NULL); g_rt = SQLSetEnvAttr(m_h, attribute, value, SQL_NTS); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } // TODO : i might need last parameter. For now ignoreing bool _GetAttribute(_In_ SQLINTEGER attribute, _Inout_ SQLPOINTER pValue, _Inout_ SQLINTEGER* pcbWritten) { _ASSERTE(m_h != NULL); g_rt = SQLGetEnvAttr(m_h, attribute, pValue, SQL_IS_UINTEGER, pcbWritten); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } }; class __declspec(novtable) CConnectionHandle : public CHandle< CConnectionHandle, SQL_HANDLE_DBC> { public: bool _SetAttribute(_In_ SQLINTEGER attribute, _In_ SQLPOINTER value) { _ASSERTE(m_h != NULL); g_rt = SQLSetConnectAttr(m_h, attribute, value, SQL_NTS); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } // TODO : i might need last parameter. For now ignoreing bool _GetAttribute(_In_ SQLINTEGER attribute, _Inout_ SQLPOINTER pValue, _Inout_ SQLINTEGER* pcbWritten) { _ASSERTE(m_h != NULL); g_rt = SQLGetConnectAttr(m_h, attribute, pValue, SQL_IS_UINTEGER, pcbWritten); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } }; class __declspec(novtable) CStatementHandle : public CHandle< CStatementHandle, SQL_HANDLE_STMT> { public: bool _SetAttribute(_In_ SQLINTEGER attribute, _In_ SQLPOINTER value) { _ASSERTE(m_h != NULL); g_rt = SQLSetStmtAttr(m_h, attribute, value, SQL_NTS); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } // TODO : i might need last parameter. For now ignoreing bool _GetAttribute(_In_ SQLINTEGER attribute, _Inout_ SQLPOINTER pValue, _Inout_ SQLINTEGER* pcbWritten) { _ASSERTE(m_h != NULL); g_rt = SQLGetStmtAttr(m_h, attribute, pValue, SQL_IS_UINTEGER, pcbWritten); _ASSERTE(SQL_SUCCEEDED(g_rt)); if (SQL_SUCCEEDED(g_rt) == FALSE) return FALSE; return TRUE; } };
- Changed Type Elegentin XieMicrosoft Contingent Staff, Moderator Monday, August 06, 2012 6:29 AM
All Replies
-
Monday, August 06, 2012 6:00 AMModerator
Hi v3nOm,
Welcome here.
Based on your description, you want criticism on design problems people might see; there is not a solid answer of it, so I will change the thread type to general discussion.
Thanks for your understanding.
Regards,
Elegentin Xie [MSFT]
MSDN Community Support | Feedback to us

