1 /****************************************************************************** 2 * $Id: cpl_odbc.h 657d65d2f09c031221875536844191be01b4ea66 2020-08-31 18:09:29 +1000 Nyall Dawson $ 3 * 4 * Project: OGR ODBC Driver 5 * Purpose: Declarations for ODBC Access Cover API. 6 * Author: Frank Warmerdam, warmerdam@pobox.com 7 * 8 ****************************************************************************** 9 * Copyright (c) 2003, Frank Warmerdam 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included 19 * in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 * DEALINGS IN THE SOFTWARE. 28 ****************************************************************************/ 29 30 #ifndef CPL_ODBC_H_INCLUDED 31 #define CPL_ODBC_H_INCLUDED 32 33 #include "cpl_port.h" 34 35 #ifdef WIN32 36 # include <windows.h> 37 #endif 38 39 #include <sql.h> 40 #include <sqlext.h> 41 #include <odbcinst.h> 42 #include "cpl_string.h" 43 44 /*! @cond Doxygen_Suppress */ 45 #ifdef PATH_MAX 46 # define ODBC_FILENAME_MAX PATH_MAX 47 #else 48 # define ODBC_FILENAME_MAX (255 + 1) /* Max path length */ 49 #endif 50 /*! @endcond */ 51 52 /** 53 * \file cpl_odbc.h 54 * 55 * ODBC Abstraction Layer (C++). 56 */ 57 58 /** 59 * A class providing functions to install or remove ODBC driver. 60 */ 61 class CPL_DLL CPLODBCDriverInstaller 62 { 63 char m_szPathOut[ODBC_FILENAME_MAX]; 64 char m_szError[SQL_MAX_MESSAGE_LENGTH]; 65 DWORD m_nErrorCode; 66 DWORD m_nUsageCount; 67 68 public: 69 70 // Default constructor. 71 CPLODBCDriverInstaller(); 72 73 /** 74 * Installs ODBC driver or updates definition of already installed driver. 75 * Interanally, it calls ODBC's SQLInstallDriverEx function. 76 * 77 * @param pszDriver - The driver definition as a list of keyword-value 78 * pairs describing the driver (See ODBC API Reference). 79 * 80 * @param pszPathIn - Full path of the target directory of the installation, 81 * or a null pointer (for unixODBC, NULL is passed). 82 * 83 * @param fRequest - The fRequest argument must contain one of 84 * the following values: 85 * ODBC_INSTALL_COMPLETE - (default) complete the installation request 86 * ODBC_INSTALL_INQUIRY - inquire about where a driver can be installed 87 * 88 * @return TRUE indicates success, FALSE if it fails. 89 */ 90 int InstallDriver( const char* pszDriver, const char* pszPathIn, 91 WORD fRequest = ODBC_INSTALL_COMPLETE ); 92 93 /** 94 * Removes or changes information about the driver from 95 * the Odbcinst.ini entry in the system information. 96 * 97 * @param pszDriverName - The name of the driver as registered in 98 * the Odbcinst.ini key of the system information. 99 * 100 * @param fRemoveDSN - TRUE: Remove DSNs associated with the driver 101 * specified in lpszDriver. FALSE: Do not remove DSNs associated 102 * with the driver specified in lpszDriver. 103 * 104 * @return The function returns TRUE if it is successful, 105 * FALSE if it fails. If no entry exists in the system information 106 * when this function is called, the function returns FALSE. 107 * In order to obtain usage count value, call GetUsageCount(). 108 */ 109 int RemoveDriver( const char* pszDriverName, int fRemoveDSN = FALSE ); 110 111 /** The usage count of the driver after this function has been called */ GetUsageCount()112 int GetUsageCount() const { return m_nUsageCount; } 113 114 /** Path of the target directory where the driver should be installed. 115 * For details, see ODBC API Reference and lpszPathOut 116 * parameter of SQLInstallDriverEx 117 */ GetPathOut()118 const char* GetPathOut() const { return m_szPathOut; } 119 120 /** If InstallDriver returns FALSE, then GetLastError then 121 * error message can be obtained by calling this function. 122 * Internally, it calls ODBC's SQLInstallerError function. 123 */ GetLastError()124 const char* GetLastError() const { return m_szError; } 125 126 /** If InstallDriver returns FALSE, then GetLastErrorCode then 127 * error code can be obtained by calling this function. 128 * Internally, it calls ODBC's SQLInstallerError function. 129 * See ODBC API Reference for possible error flags. 130 */ GetLastErrorCode()131 DWORD GetLastErrorCode() const { return m_nErrorCode; } 132 }; 133 134 class CPLODBCStatement; 135 136 /* On MSVC SQLULEN is missing in some cases (i.e. VC6) 137 ** but it is always a #define so test this way. On Unix 138 ** it is a typedef so we can't always do this. 139 */ 140 #if defined(_MSC_VER) && !defined(SQLULEN) && !defined(_WIN64) 141 # define MISSING_SQLULEN 142 #endif 143 144 /*! @cond Doxygen_Suppress */ 145 #if !defined(MISSING_SQLULEN) 146 /* ODBC types to support 64 bit compilation */ 147 # define CPL_SQLULEN SQLULEN 148 # define CPL_SQLLEN SQLLEN 149 #else 150 # define CPL_SQLULEN SQLUINTEGER 151 # define CPL_SQLLEN SQLINTEGER 152 #endif /* ifdef SQLULEN */ 153 /*! @endcond */ 154 155 /** 156 * A class representing an ODBC database session. 157 * 158 * Includes error collection services. 159 */ 160 161 class CPL_DLL CPLODBCSession { 162 CPL_DISALLOW_COPY_ASSIGN(CPLODBCSession)163 CPL_DISALLOW_COPY_ASSIGN(CPLODBCSession) 164 165 CPLString m_osLastError{}; 166 HENV m_hEnv = nullptr; 167 HDBC m_hDBC = nullptr; 168 int m_bInTransaction = false; 169 int m_bAutoCommit = true; 170 171 public: 172 CPLODBCSession(); 173 ~CPLODBCSession(); 174 175 int EstablishSession( const char *pszDSN, 176 const char *pszUserid, 177 const char *pszPassword ); 178 const char *GetLastError(); 179 180 // Transaction handling 181 182 int ClearTransaction(); 183 int BeginTransaction(); 184 int CommitTransaction(); 185 int RollbackTransaction(); 186 /** Returns whether a transaction is active */ IsInTransaction()187 int IsInTransaction() { return m_bInTransaction; } 188 189 // Essentially internal. 190 191 int CloseSession(); 192 193 int Failed( int, HSTMT = nullptr ); 194 /** Return connection handle */ GetConnection()195 HDBC GetConnection() { return m_hDBC; } 196 /** Return GetEnvironment handle */ GetEnvironment()197 HENV GetEnvironment() { return m_hEnv; } 198 199 bool ConnectToMsAccess( const char * pszName, const char* pszDSNStringTemplate ); 200 201 }; 202 203 /** 204 * Abstraction for statement, and resultset. 205 * 206 * Includes methods for executing an SQL statement, and for accessing the 207 * resultset from that statement. Also provides for executing other ODBC 208 * requests that produce results sets such as SQLColumns() and SQLTables() 209 * requests. 210 */ 211 212 class CPL_DLL CPLODBCStatement { 213 214 CPL_DISALLOW_COPY_ASSIGN(CPLODBCStatement) 215 216 CPLODBCSession *m_poSession = nullptr; 217 HSTMT m_hStmt = nullptr; 218 219 SQLSMALLINT m_nColCount = 0; 220 char **m_papszColNames = nullptr; 221 SQLSMALLINT *m_panColType = nullptr; 222 char **m_papszColTypeNames = nullptr; 223 CPL_SQLULEN *m_panColSize = nullptr; 224 SQLSMALLINT *m_panColPrecision = nullptr; 225 SQLSMALLINT *m_panColNullable = nullptr; 226 char **m_papszColColumnDef = nullptr; 227 228 char **m_papszColValues = nullptr; 229 CPL_SQLLEN *m_panColValueLengths = nullptr; 230 231 int Failed( int ); 232 233 char *m_pszStatement = nullptr; 234 size_t m_nStatementMax = 0; 235 size_t m_nStatementLen = 0; 236 237 public: 238 explicit CPLODBCStatement( CPLODBCSession * ); 239 ~CPLODBCStatement(); 240 241 /** Return statement handle */ GetStatement()242 HSTMT GetStatement() { return m_hStmt; } 243 244 // Command buffer related. 245 void Clear(); 246 void AppendEscaped( const char * ); 247 void Append( const char * ); 248 void Append( int ); 249 void Append( double ); 250 int Appendf( CPL_FORMAT_STRING(const char *), ... ) CPL_PRINT_FUNC_FORMAT (2, 3); 251 /** Return statement string */ GetCommand()252 const char *GetCommand() { return m_pszStatement; } 253 254 int ExecuteSQL( const char * = nullptr ); 255 256 // Results fetching 257 int Fetch( int nOrientation = SQL_FETCH_NEXT, 258 int nOffset = 0 ); 259 void ClearColumnData(); 260 261 int GetColCount(); 262 const char *GetColName( int ); 263 short GetColType( int ); 264 const char *GetColTypeName( int ); 265 short GetColSize( int ); 266 short GetColPrecision( int ); 267 short GetColNullable( int ); 268 const char *GetColColumnDef( int ); 269 270 int GetColId( const char * ); 271 const char *GetColData( int, const char * = nullptr ); 272 const char *GetColData( const char *, const char * = nullptr ); 273 int GetColDataLength( int ); 274 int GetRowCountAffected(); 275 276 // Fetch special metadata. 277 int GetColumns( const char *pszTable, 278 const char *pszCatalog = nullptr, 279 const char *pszSchema = nullptr ); 280 int GetPrimaryKeys( const char *pszTable, 281 const char *pszCatalog = nullptr, 282 const char *pszSchema = nullptr ); 283 284 int GetTables( const char *pszCatalog = nullptr, 285 const char *pszSchema = nullptr ); 286 287 void DumpResult( FILE *fp, int bShowSchema = FALSE ); 288 289 static CPLString GetTypeName( int ); 290 static SQLSMALLINT GetTypeMapping( SQLSMALLINT ); 291 292 int CollectResultsInfo(); 293 }; 294 295 #endif 296