LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLBrowseConnect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 63 68 92.6 %
Date: 2024-12-20 20:06:10 Functions: 2 2 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             :  * SQLBrowseConnect()
      25             :  * CLI Compliance: ODBC (Microsoft)
      26             :  *
      27             :  * Author: Martin van Dinther, Sjoerd Mullender
      28             :  * Date  : 30 Aug 2002
      29             :  *
      30             :  **********************************************************************/
      31             : 
      32             : #include "ODBCGlobal.h"
      33             : #include "ODBCDbc.h"
      34             : #include "ODBCUtil.h"
      35             : #include "ODBCAttrs.h"
      36             : #ifdef HAVE_STRINGS_H
      37             : #include <strings.h>              /* strcasecmp */
      38             : #endif
      39             : 
      40             : #ifdef HAVE_ODBCINST_H
      41             : #include <odbcinst.h>
      42             : #endif
      43             : 
      44             : #ifndef HAVE_SQLGETPRIVATEPROFILESTRING
      45             : #define SQLGetPrivateProfileString(section,entry,default,buffer,bufferlen,filename)     ((int) strcpy_len(buffer,default,bufferlen))
      46             : #endif
      47             : 
      48             : static void
      49           6 : suggest_settings(ODBCDbc *dbc, char **buf, size_t *pos, size_t *cap, char touched_as, const char *prefix)
      50             : {
      51         138 :         for (int i = 0; i < attr_setting_count; i++) {
      52         132 :                 const struct attr_setting *entry = &attr_settings[i];
      53         132 :                 mparm parm = entry->parm;
      54         132 :                 if (dbc->setting_touched[(int)parm] == touched_as) {
      55          66 :                         const char *sep = *pos > 0 ? ";" : "";
      56          66 :                         reallocprintf(
      57             :                                 buf, pos, cap,
      58             :                                 "%s%s%s%s%s=?",
      59          66 :                                 sep, prefix, entry->name,
      60             :                                 entry->alt_name ? ":" : "",
      61          66 :                                 entry->alt_name ? entry->alt_name : "");
      62          66 :                         if (entry->is_enum) {
      63           6 :                                 assert(entry->values != NULL);
      64           6 :                                 *pos -= 1;  // eat the '?'
      65           6 :                                 sep = "{";
      66          18 :                                 for (const char **p = entry->values; *p; p++) {
      67          12 :                                         const char *item = *p;
      68          12 :                                         reallocprintf(buf, pos, cap, "%s%s", sep, item);
      69          12 :                                         sep = ",";
      70             :                                 }
      71           6 :                                 reallocprintf(buf, pos, cap, "}");
      72             :                         }
      73             :                 }
      74             :         }
      75           6 : }
      76             : 
      77             : 
      78             : 
      79             : static SQLRETURN
      80          10 : MNDBBrowseConnect(ODBCDbc *dbc,
      81             :                   const SQLCHAR *InConnectionString,
      82             :                   SQLSMALLINT StringLength1,
      83             :                   SQLCHAR *OutConnectionString,
      84             :                   SQLSMALLINT BufferLength,
      85             :                   SQLSMALLINT *StringLength2Ptr)
      86             : {
      87          10 :         SQLRETURN rc;
      88             : 
      89          10 :         rc = MNDBDriverConnect(
      90             :                 dbc, NULL,
      91             :                 InConnectionString, StringLength1,
      92             :                 OutConnectionString, BufferLength, StringLength2Ptr,
      93             :                 SQL_DRIVER_NOPROMPT,
      94             :                 0
      95             :         );
      96             : 
      97          10 :         if (SQL_SUCCEEDED(rc)) {
      98             :                 return rc;
      99             :         }
     100             : 
     101             :         // 0 = never touched, show it
     102             :         // 1 = touched, do not show it
     103             :         // 2 = show as mandatory
     104             : 
     105           3 :         if (dbc->setting_touched[MP_USER] != 1)
     106           3 :                 dbc->setting_touched[MP_USER] = 2;
     107           3 :         if (dbc->setting_touched[MP_PASSWORD] != 1)
     108           3 :                 dbc->setting_touched[MP_PASSWORD] = 2;
     109             : 
     110             :         // Make MP_DATABASE mandatory if monetdbd asks for it.
     111           6 :         for (ODBCError *err = dbc->Error; err != NULL; err = getErrorRec(err, 2)) {
     112           3 :                 if (strcmp("08001", getSqlState(err)) != 0)
     113           0 :                         continue;
     114           3 :                 if (strstr(getMessage(err), "monetdbd: please specify a database") == NULL)
     115           3 :                         continue;
     116           0 :                 dbc->setting_touched[MP_DATABASE] = 2;
     117             :         }
     118             : 
     119           3 :         char *buf = NULL;
     120           3 :         size_t pos = 0;
     121           3 :         size_t cap = 0;
     122           3 :         suggest_settings(dbc, &buf, &pos, &cap, 2, "");    // mandatory first
     123           3 :         suggest_settings(dbc, &buf, &pos, &cap, 0, "*");   // then optional
     124             :         // note that we leave out level 1, they have already been provided
     125             : 
     126           3 :         if (buf && pos) {
     127           3 :                 size_t n = strcpy_len((char*)OutConnectionString, buf, BufferLength);
     128           3 :                 if (StringLength2Ptr)
     129           3 :                         *StringLength2Ptr = (SQLSMALLINT)n;
     130             :         }
     131             : 
     132           3 :         free(buf);
     133           3 :         return SQL_NEED_DATA;
     134             : }
     135             : 
     136             : SQLRETURN SQL_API
     137             : SQLBrowseConnect(SQLHDBC ConnectionHandle,
     138             :                  SQLCHAR *InConnectionString,
     139             :                  SQLSMALLINT StringLength1,
     140             :                  SQLCHAR *OutConnectionString,
     141             :                  SQLSMALLINT BufferLength,
     142             :                  SQLSMALLINT *StringLength2Ptr)
     143             : {
     144           5 :         ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
     145             : 
     146             : #ifdef ODBCDEBUG
     147           5 :         ODBCLOG("SQLBrowseConnect %p", ConnectionHandle);
     148             : #endif
     149             : 
     150           5 :         if (!isValidDbc(dbc))
     151             :                 return SQL_INVALID_HANDLE;
     152             : 
     153           5 :         clearDbcErrors(dbc);
     154             : 
     155           5 :         return MNDBBrowseConnect(dbc, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr);
     156             : }
     157             : 
     158             : SQLRETURN SQL_API
     159             : SQLBrowseConnectA(SQLHDBC ConnectionHandle,
     160             :                   SQLCHAR *InConnectionString,
     161             :                   SQLSMALLINT StringLength1,
     162             :                   SQLCHAR *OutConnectionString,
     163             :                   SQLSMALLINT BufferLength,
     164             :                   SQLSMALLINT *StringLength2Ptr)
     165             : {
     166           0 :         return SQLBrowseConnect(ConnectionHandle, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr);
     167             : }
     168             : 
     169             : SQLRETURN SQL_API
     170             : SQLBrowseConnectW(SQLHDBC ConnectionHandle,
     171             :                   SQLWCHAR *InConnectionString,
     172             :                   SQLSMALLINT StringLength1,
     173             :                   SQLWCHAR *OutConnectionString,
     174             :                   SQLSMALLINT BufferLength,
     175             :                   SQLSMALLINT *StringLength2Ptr)
     176             : {
     177           5 :         ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
     178           5 :         SQLCHAR *in = NULL, *out;
     179           5 :         SQLSMALLINT n;
     180           5 :         SQLRETURN rc;
     181             : 
     182             : #ifdef ODBCDEBUG
     183           5 :         ODBCLOG("SQLBrowseConnectW %p", ConnectionHandle);
     184             : #endif
     185             : 
     186           5 :         if (!isValidDbc(dbc))
     187             :                 return SQL_INVALID_HANDLE;
     188             : 
     189           5 :         clearDbcErrors(dbc);
     190             : 
     191           5 :         fixWcharIn(InConnectionString, StringLength1, SQLCHAR, in,
     192             :                    addDbcError, dbc, return SQL_ERROR);
     193           5 :         out = malloc(2048);
     194           5 :         if (out == NULL) {
     195             :                 /* Memory allocation error */
     196           0 :                 addDbcError(dbc, "HY001", NULL, 0);
     197           0 :                 return SQL_ERROR;
     198             :         }
     199           5 :         rc = MNDBBrowseConnect(dbc, in, SQL_NTS, out, 2048, &n);
     200           5 :         if (SQL_SUCCEEDED(rc) || rc == SQL_NEED_DATA) {
     201           5 :                 fixWcharOut(rc, out, n, OutConnectionString, BufferLength,
     202             :                             StringLength2Ptr, 1, addDbcError, dbc);
     203             :         }
     204           5 :         free(out);
     205           5 :         if (in)
     206           5 :                 free(in);
     207             :         return rc;
     208             : }

Generated by: LCOV version 1.14