LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLGetDiagRec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 51 63 81.0 %
Date: 2024-10-04 20:04:04 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      15             :  * This code is LGPL. Please ensure that this message remains in future
      16             :  * distributions and uses of this code (that's about all I get out of it).
      17             :  * - Peter Harvey pharvey@codebydesign.com
      18             :  *
      19             :  * This file has been modified for the MonetDB project.  See the file
      20             :  * Copyright in this directory for more information.
      21             :  */
      22             : 
      23             : /**********************************************************************
      24             :  * SQLGetDiagRec()
      25             :  * CLI Compliance: ISO 92
      26             :  *
      27             :  * Author: Martin van Dinther, Sjoerd Mullender
      28             :  * Date  : 30 aug 2002
      29             :  *
      30             :  **********************************************************************/
      31             : 
      32             : #include "ODBCGlobal.h"
      33             : #include "ODBCEnv.h"
      34             : #include "ODBCDbc.h"
      35             : #include "ODBCStmt.h"
      36             : #include "ODBCError.h"
      37             : #include "ODBCUtil.h"
      38             : 
      39             : SQLRETURN
      40          77 : MNDBGetDiagRec(SQLSMALLINT HandleType,
      41             :                SQLHANDLE Handle,
      42             :                SQLSMALLINT RecNumber,
      43             :                SQLCHAR *SQLState,
      44             :                SQLINTEGER *NativeErrorPtr,
      45             :                SQLCHAR *MessageText,
      46             :                SQLSMALLINT BufferLength,
      47             :                SQLSMALLINT *TextLengthPtr)
      48             : {
      49          77 :         ODBCError *err;
      50          77 :         ODBCDbc *dbc = NULL;
      51          77 :         char *msg;
      52          77 :         SQLSMALLINT msgLen;
      53             : 
      54          77 :         switch (HandleType) {
      55           0 :         case SQL_HANDLE_ENV:
      56             :                 /* Check if this struct is still valid/alive */
      57           0 :                 if (!isValidEnv((ODBCEnv *) Handle))
      58             :                         return SQL_INVALID_HANDLE;
      59           0 :                 err = getEnvError((ODBCEnv *) Handle);
      60           0 :                 break;
      61          22 :         case SQL_HANDLE_DBC:
      62             :                 /* Check if this struct is still valid/alive */
      63          22 :                 dbc = (ODBCDbc *) Handle;
      64          22 :                 if (!isValidDbc(dbc))
      65             :                         return SQL_INVALID_HANDLE;
      66          22 :                 err = getDbcError(dbc);
      67          22 :                 break;
      68          55 :         case SQL_HANDLE_STMT:
      69             :                 /* Check if this struct is still valid/alive */
      70          55 :                 if (!isValidStmt((ODBCStmt *) Handle))
      71             :                         return SQL_INVALID_HANDLE;
      72          55 :                 err = getStmtError((ODBCStmt *) Handle);
      73          55 :                 dbc = ((ODBCStmt *) Handle)->Dbc;
      74          55 :                 break;
      75           0 :         case SQL_HANDLE_DESC:
      76             :                 /* Check if this struct is still valid/alive */
      77           0 :                 if (!isValidDesc((ODBCDesc *) Handle))
      78             :                         return SQL_INVALID_HANDLE;
      79           0 :                 err = getDescError((ODBCDesc *) Handle);
      80           0 :                 dbc = ((ODBCDesc *) Handle)->Dbc;
      81           0 :                 break;
      82             :         default:
      83             :                 return SQL_INVALID_HANDLE;
      84             :         }
      85             : 
      86             :         /* Note: BufferLength may be 0 !! */
      87          77 :         if (BufferLength < 0)
      88             :                 return SQL_ERROR;
      89             : 
      90          77 :         if (RecNumber <= 0)
      91             :                 return SQL_ERROR;
      92             : 
      93          77 :         err = getErrorRec(err, RecNumber);
      94             :         /* Check the error object from the handle, it may be NULL when
      95             :          * no (more) errors are available
      96             :          */
      97          77 :         if (err == NULL)
      98             :                 return SQL_NO_DATA;
      99             : 
     100             :         /* Now fill the output parameters where possible */
     101          46 :         if (SQLState) {
     102          46 :                 char *state = getSqlState(err);
     103             : 
     104          46 :                 assert(state);
     105             :                 /* copy only the first SQL_SQLSTATE_SIZE (5) chars in
     106             :                  * the buffer and make it null terminated
     107             :                  */
     108          46 :                 strcpy_len((char *) SQLState, state, SQL_SQLSTATE_SIZE + 1);
     109             :         }
     110             : 
     111          46 :         if (NativeErrorPtr)
     112          46 :                 *NativeErrorPtr = getNativeErrorCode(err);
     113             : 
     114          46 :         msg = getMessage(err);
     115             : 
     116             :         /* first write the error message prefix text:
     117             :          * [MonetDB][ODBC driver VERSION][DSN]
     118             :          * this is required by the ODBC spec:
     119             :          * https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/diagnostic-messages
     120             :          * and used to determine where the error originated
     121             :          */
     122          46 :         if (dbc && dbc->dsn)
     123          36 :                 msgLen = (SQLSMALLINT) strconcat_len((char *) MessageText, BufferLength, ODBCErrorMsgPrefix, "[", dbc->dsn, "]", msg, NULL);
     124             :         else
     125          10 :                 msgLen = (SQLSMALLINT) strconcat_len((char *) MessageText, BufferLength, ODBCErrorMsgPrefix, msg, NULL);
     126             : 
     127          46 :         if (TextLengthPtr)
     128          46 :                 *TextLengthPtr = msgLen;
     129             : 
     130          46 :         if (MessageText == NULL || msgLen >= BufferLength) {
     131             :                 /* it didn't fit */
     132           0 :                 return SQL_SUCCESS_WITH_INFO;
     133             :         }
     134             :         return SQL_SUCCESS;
     135             : }
     136             : 
     137             : SQLRETURN SQL_API
     138             : SQLGetDiagRec(SQLSMALLINT HandleType,
     139             :               SQLHANDLE Handle,
     140             :               SQLSMALLINT RecNumber,
     141             :               SQLCHAR *SQLState,
     142             :               SQLINTEGER *NativeErrorPtr,
     143             :               SQLCHAR *MessageText,
     144             :               SQLSMALLINT BufferLength,
     145             :               SQLSMALLINT *TextLengthPtr)
     146             : {
     147             : #ifdef ODBCDEBUG
     148          50 :         ODBCLOG("SQLGetDiagRec %s %p %d %d\n",
     149             :                 HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc",
     150             :                 Handle, (int) RecNumber, (int) BufferLength);
     151             : #endif
     152             : 
     153          25 :         return MNDBGetDiagRec(HandleType,
     154             :                               Handle,
     155             :                               RecNumber,
     156             :                               SQLState,
     157             :                               NativeErrorPtr,
     158             :                               MessageText,
     159             :                               BufferLength,
     160             :                               TextLengthPtr);
     161             : }
     162             : 
     163             : SQLRETURN SQL_API
     164             : SQLGetDiagRecA(SQLSMALLINT HandleType,
     165             :                SQLHANDLE Handle,
     166             :                SQLSMALLINT RecNumber,
     167             :                SQLCHAR *SQLState,
     168             :                SQLINTEGER *NativeErrorPtr,
     169             :                SQLCHAR *MessageText,
     170             :                SQLSMALLINT BufferLength,
     171             :                SQLSMALLINT *TextLengthPtr)
     172             : {
     173           0 :         return SQLGetDiagRec(HandleType,
     174             :                              Handle,
     175             :                              RecNumber,
     176             :                              SQLState,
     177             :                              NativeErrorPtr,
     178             :                              MessageText,
     179             :                              BufferLength,
     180             :                              TextLengthPtr);
     181             : }
     182             : 
     183             : SQLRETURN SQL_API
     184             : SQLGetDiagRecW(SQLSMALLINT HandleType,
     185             :                SQLHANDLE Handle,
     186             :                SQLSMALLINT RecNumber,
     187             :                SQLWCHAR *SQLState,
     188             :                SQLINTEGER *NativeErrorPtr,
     189             :                SQLWCHAR *MessageText,
     190             :                SQLSMALLINT BufferLength,
     191             :                SQLSMALLINT *TextLengthPtr)
     192             : {
     193          36 :         SQLRETURN rc;
     194          36 :         SQLCHAR state[6];
     195          36 :         SQLCHAR msg[512];
     196          36 :         SQLSMALLINT n;
     197             : 
     198             : #ifdef ODBCDEBUG
     199          72 :         ODBCLOG("SQLGetDiagRecW %s %p %d %d\n",
     200             :                 HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc",
     201             :                 Handle, (int) RecNumber, (int) BufferLength);
     202             : #endif
     203             : 
     204             : 
     205          36 :         rc = MNDBGetDiagRec(HandleType, Handle, RecNumber, state,
     206             :                             NativeErrorPtr, msg, (SQLSMALLINT) sizeof(msg), &n);
     207             : #ifdef ODBCDEBUG
     208          36 :         ODBCLOG("SQLGetDiagRecW: %s\n", SQL_SUCCEEDED(rc) ? (char *) msg : rc == SQL_NO_DATA ? "no error" : "failed");
     209             : #endif
     210             : 
     211          36 :         if (SQL_SUCCEEDED(rc)) {
     212          18 :                 const char *e = ODBCutf82wchar(state, 5, SQLState, 6, NULL,
     213             :                                                NULL);
     214             : 
     215          18 :                 if (e)
     216             :                         rc = SQL_ERROR;
     217             :         }
     218             : 
     219          18 :         if (SQL_SUCCEEDED(rc)) {
     220          18 :                 const char *e = ODBCutf82wchar(msg, n, MessageText,
     221             :                                                BufferLength, &n, NULL);
     222             : 
     223          18 :                 if (e)
     224           0 :                         rc = SQL_ERROR;
     225          18 :                 if (TextLengthPtr)
     226          18 :                         *TextLengthPtr = n;
     227             :         }
     228             : 
     229          36 :         return rc;
     230             : }

Generated by: LCOV version 1.14