GDAL
cpl_odbc.h
Go to the documentation of this file.
1 /******************************************************************************
2  * $Id$
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 
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
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  static bool FindMdbToolsDriverLib(CPLString &osDriverFile);
69  static bool LibraryExists(const char *pszLibPath);
70 
71  public:
72  // Default constructor.
74 
92  int InstallDriver(const char *pszDriver, const char *pszPathIn,
93  WORD fRequest = ODBC_INSTALL_COMPLETE);
94 
102  static void InstallMdbToolsDriver();
103 
120  int RemoveDriver(const char *pszDriverName, int fRemoveDSN = FALSE);
121 
123  int GetUsageCount() const
124  {
125  return m_nUsageCount;
126  }
127 
132  const char *GetPathOut() const
133  {
134  return m_szPathOut;
135  }
136 
141  const char *GetLastError() const
142  {
143  return m_szError;
144  }
145 
151  DWORD GetLastErrorCode() const
152  {
153  return m_nErrorCode;
154  }
155 };
156 
157 class CPLODBCStatement;
158 
159 /* On MSVC SQLULEN is missing in some cases (i.e. VC6)
160 ** but it is always a #define so test this way. On Unix
161 ** it is a typedef so we can't always do this.
162 */
163 #if defined(_MSC_VER) && !defined(SQLULEN) && !defined(_WIN64)
164 #define MISSING_SQLULEN
165 #endif
166 
168 #if !defined(MISSING_SQLULEN)
169 /* ODBC types to support 64 bit compilation */
170 #define CPL_SQLULEN SQLULEN
171 #define CPL_SQLLEN SQLLEN
172 #else
173 #define CPL_SQLULEN SQLUINTEGER
174 #define CPL_SQLLEN SQLINTEGER
175 #endif /* ifdef SQLULEN */
184 class CPL_DLL CPLODBCSession
185 {
186 
188 
189 
190  protected:
191  CPLString m_osLastError{};
192  HENV m_hEnv = nullptr;
193  HDBC m_hDBC = nullptr;
194  int m_bInTransaction = false;
195  int m_bAutoCommit = true;
198  public:
199  CPLODBCSession();
200  ~CPLODBCSession();
201 
202  int EstablishSession(const char *pszDSN, const char *pszUserid,
203  const char *pszPassword);
204  const char *GetLastError();
205 
206  // Transaction handling
207 
208  int ClearTransaction();
209  int BeginTransaction();
210  int CommitTransaction();
211  int RollbackTransaction();
212 
215  {
216  return m_bInTransaction;
217  }
218 
219  // Essentially internal.
220 
221  int CloseSession();
222 
223  int Failed(int, HSTMT = nullptr);
224 
227  {
228  return m_hDBC;
229  }
230 
233  {
234  return m_hEnv;
235  }
236 
237  bool ConnectToMsAccess(const char *pszName,
238  const char *pszDSNStringTemplate);
239 };
240 
250 class CPL_DLL CPLODBCStatement
251 {
252 
254 
255 
256  protected:
257  int m_nFlags = 0;
258 
259  CPLODBCSession *m_poSession = nullptr;
260  HSTMT m_hStmt = nullptr;
261 
262  SQLSMALLINT m_nColCount = 0;
263  char **m_papszColNames = nullptr;
264  SQLSMALLINT *m_panColType = nullptr;
265  char **m_papszColTypeNames = nullptr;
266  CPL_SQLULEN *m_panColSize = nullptr;
267  SQLSMALLINT *m_panColPrecision = nullptr;
268  SQLSMALLINT *m_panColNullable = nullptr;
269  char **m_papszColColumnDef = nullptr;
270 
271  char **m_papszColValues = nullptr;
272  CPL_SQLLEN *m_panColValueLengths = nullptr;
273  double *m_padColValuesAsDouble = nullptr;
274 
275  int Failed(int);
276 
277  char *m_pszStatement = nullptr;
278  size_t m_nStatementMax = 0;
279  size_t m_nStatementLen = 0;
282  public:
286  enum Flag
287  {
302  RetrieveNumericColumnsAsDouble = 1 << 0,
303  };
304 
305  explicit CPLODBCStatement(CPLODBCSession *, int flags = 0);
306  ~CPLODBCStatement();
307 
309  HSTMT GetStatement()
310  {
311  return m_hStmt;
312  }
313 
317  int Flags() const
318  {
319  return m_nFlags;
320  }
321 
322  // Command buffer related.
323  void Clear();
324  void AppendEscaped(const char *);
325  void Append(const char *);
326  void Append(const std::string &);
327  // cppcheck-suppress functionStatic
328  void Append(int);
329  void Append(double);
330  int Appendf(CPL_FORMAT_STRING(const char *), ...)
331  CPL_PRINT_FUNC_FORMAT(2, 3);
332 
334  const char *GetCommand()
335  {
336  return m_pszStatement;
337  }
338 
339  int ExecuteSQL(const char * = nullptr);
340 
341  // Results fetching
342  int Fetch(int nOrientation = SQL_FETCH_NEXT, int nOffset = 0);
343  void ClearColumnData();
344 
345  int GetColCount();
346  const char *GetColName(int);
347  short GetColType(int);
348  const char *GetColTypeName(int);
349  short GetColSize(int);
350  short GetColPrecision(int);
351  short GetColNullable(int);
352  const char *GetColColumnDef(int);
353 
354  int GetColId(const char *) const;
355  const char *GetColData(int, const char * = nullptr);
356  const char *GetColData(const char *, const char * = nullptr);
357  int GetColDataLength(int);
358 
359  double GetColDataAsDouble(int) const;
360  double GetColDataAsDouble(const char *) const;
361 
362  int GetRowCountAffected();
363 
364  // Fetch special metadata.
365  int GetColumns(const char *pszTable, const char *pszCatalog = nullptr,
366  const char *pszSchema = nullptr);
367  int GetPrimaryKeys(const char *pszTable, const char *pszCatalog = nullptr,
368  const char *pszSchema = nullptr);
369 
370  int GetTables(const char *pszCatalog = nullptr,
371  const char *pszSchema = nullptr);
372 
373  void DumpResult(FILE *fp, int bShowSchema = FALSE);
374 
375  static CPLString GetTypeName(int);
376  static SQLSMALLINT GetTypeMapping(SQLSMALLINT);
377 
378  int CollectResultsInfo();
379 };
380 
381 #endif
A class providing functions to install or remove ODBC driver.
Definition: cpl_odbc.h:62
int GetUsageCount() const
The usage count of the driver after this function has been called.
Definition: cpl_odbc.h:123
const char * GetLastError() const
If InstallDriver returns FALSE, then GetLastError then error message can be obtained by calling this ...
Definition: cpl_odbc.h:141
const char * GetPathOut() const
Path of the target directory where the driver should be installed.
Definition: cpl_odbc.h:132
DWORD GetLastErrorCode() const
If InstallDriver returns FALSE, then GetLastErrorCode then error code can be obtained by calling this...
Definition: cpl_odbc.h:151
A class representing an ODBC database session.
Definition: cpl_odbc.h:185
int IsInTransaction()
Returns whether a transaction is active.
Definition: cpl_odbc.h:214
HDBC GetConnection()
Return connection handle.
Definition: cpl_odbc.h:226
HENV GetEnvironment()
Return GetEnvironment handle.
Definition: cpl_odbc.h:232
Abstraction for statement, and resultset.
Definition: cpl_odbc.h:251
int Flags() const
Returns statement flags.
Definition: cpl_odbc.h:317
HSTMT GetStatement()
Return statement handle.
Definition: cpl_odbc.h:309
Flag
Flags which control ODBC statement behavior.
Definition: cpl_odbc.h:287
Convenient string class based on std::string.
Definition: cpl_string.h:320
Core portability definitions for CPL.
#define CPL_FORMAT_STRING(arg)
Macro into which to wrap the format argument of a printf-like function.
Definition: cpl_port.h:966
#define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
Tag a function to have printf() formatting.
Definition: cpl_port.h:950
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:1042
Various convenience functions for working with strings and string lists.