Changeset: bab82f70e0ca for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/bab82f70e0ca
Added Files:
        clients/odbc/driver/ODBCAttrs.h
Modified Files:
        clients/odbc/driver/CMakeLists.txt
        clients/odbc/driver/ODBCDbc.c
        clients/odbc/driver/ODBCDbc.h
        clients/odbc/driver/SQLConnect.c
Branch: odbc-tls
Log Message:

Move all odbc parameters into msettings

Currently, uid, password, database, host, port, etc., all get passed
around and processed separately.

Now that we have lots of extra TLS parameters, plus schema, time
zone, etc, this is no longer sustainable.

This is a huge delta but I couldn't find a way to split it.,


diffs (truncated from 661 to 300 lines):

diff --git a/clients/odbc/driver/CMakeLists.txt 
b/clients/odbc/driver/CMakeLists.txt
--- a/clients/odbc/driver/CMakeLists.txt
+++ b/clients/odbc/driver/CMakeLists.txt
@@ -19,6 +19,7 @@ add_library(MonetODBC
 
 target_sources(MonetODBC
   PRIVATE
+  ODBCAttrs.h
   ODBCConvert.c
   ODBCDbc.c
   ODBCDbc.h
diff --git a/clients/odbc/driver/ODBCAttrs.h b/clients/odbc/driver/ODBCAttrs.h
new file mode 100644
--- /dev/null
+++ b/clients/odbc/driver/ODBCAttrs.h
@@ -0,0 +1,39 @@
+/*
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 2024 MonetDB Foundation;
+ * Copyright August 2008 - 2023 MonetDB B.V.;
+ * Copyright 1997 - July 2008 CWI.
+ */
+
+/*
+ * Provide a mapping between attribute names as found in data sources and
+ * connection strings.
+*/
+
+#ifndef ODBCATTRS
+#define ODBCATTRS
+
+#include "msettings.h"
+
+struct attr_setting {
+       const char *name;        // canonical attribute name
+       const char *alt_name;    // user-facing attribute name
+       mparm parm;
+};
+
+// defined in SQLConnect.c, also used in SQLBrowseConnect.c
+extern const struct attr_setting attr_settings[];
+extern const int attr_setting_count;
+
+// look up attr_setting entry by name or alt_name, -1 if not found
+int attr_setting_lookup(const char *attr_name);
+
+
+
+
+#endif
diff --git a/clients/odbc/driver/ODBCDbc.c b/clients/odbc/driver/ODBCDbc.c
--- a/clients/odbc/driver/ODBCDbc.c
+++ b/clients/odbc/driver/ODBCDbc.c
@@ -48,11 +48,21 @@ ODBCDbc *
 newODBCDbc(ODBCEnv *env)
 {
        ODBCDbc *dbc;
+       msettings *settings;
 
        assert(env);
 
        dbc = (ODBCDbc *) malloc(sizeof(ODBCDbc));
-       if (dbc == NULL) {
+       settings = msettings_create();
+
+       if (
+               dbc == NULL
+               || settings == NULL
+               || msetting_set_string(settings, MP_USER, "monetdb") != NULL
+               || msetting_set_string(settings, MP_PASSWORD, "monetdb") != NULL
+       ) {
+               free(dbc);
+               msettings_destroy(settings);
                /* Memory allocation error */
                addEnvError(env, "HY001", NULL, 0);
                return NULL;
@@ -60,6 +70,7 @@ newODBCDbc(ODBCEnv *env)
 
        *dbc = (ODBCDbc) {
                .Env = env,
+               .settings = settings,
                .sql_attr_autocommit = SQL_AUTOCOMMIT_ON,       /* default is 
autocommit */
                .sql_attr_metadata_id = SQL_FALSE,
                /* add this dbc to start of the administrative linked dbc list 
*/
@@ -173,16 +184,12 @@ destroyODBCDbc(ODBCDbc *dbc)
 
        /* cleanup own managed data */
        deleteODBCErrorList(&dbc->Error);
-       if (dbc->dsn)
-               free(dbc->dsn);
-       if (dbc->uid)
-               free(dbc->uid);
-       if (dbc->pwd)
-               free(dbc->pwd);
-       if (dbc->host)
-               free(dbc->host);
-       if (dbc->dbname)
-               free(dbc->dbname);
+       msettings_destroy(dbc->settings);
+       free(dbc->dsn);
+       free(dbc->uid);
+       free(dbc->pwd);
+       free(dbc->host);
+       free(dbc->dbname);
 
        free(dbc);
 }
diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h
--- a/clients/odbc/driver/ODBCDbc.h
+++ b/clients/odbc/driver/ODBCDbc.h
@@ -39,6 +39,7 @@
 #include "ODBCEnv.h"
 #include "ODBCError.h"
 #include "mapi.h"
+#include "msettings.h"
 
 
 typedef struct tODBCDRIVERDBC {
@@ -51,6 +52,7 @@ typedef struct tODBCDRIVERDBC {
        int RetrievedErrors;    /* # of errors already retrieved by SQLError */
 
        /* connection information */
+       msettings *settings;    /* All connection parameters */
        char *dsn;              /* Data source name or NULL */
        char *uid;              /* User ID or NULL */
        char *pwd;              /* Password for User ID or NULL */
diff --git a/clients/odbc/driver/SQLConnect.c b/clients/odbc/driver/SQLConnect.c
--- a/clients/odbc/driver/SQLConnect.c
+++ b/clients/odbc/driver/SQLConnect.c
@@ -32,6 +32,7 @@
 #include "ODBCGlobal.h"
 #include "ODBCDbc.h"
 #include "ODBCUtil.h"
+#include "ODBCAttrs.h"
 #include <time.h>
 #include "msettings.h"
 #include "mstring.h"
@@ -44,6 +45,42 @@
 #define 
SQLGetPrivateProfileString(section,entry,default,buffer,bufferlen,filename)    
((int) strcpy_len(buffer,default,bufferlen))
 #endif
 
+
+const struct attr_setting attr_settings[] = {
+       { "uid", "User", MP_USER },
+       { "pwd", "Password", MP_PASSWORD },
+       { "database", "Database", MP_DATABASE },
+       { "port", "Port", MP_PORT },
+       { "host", "Host", MP_HOST },
+       { "sock", "Unix Socket", MP_SOCK },
+       { "tls", "Encrypt", MP_TLS },
+       { "cert", "Server Certificate", MP_CERT },
+       { "certhash", "Server Certificate Hash", MP_CERTHASH },
+       { "clientkey", "Client Key", MP_CLIENTKEY },
+       { "clientcert", "Client Certificate", MP_CLIENTCERT },
+       { "autocommit", "Autocommit", MP_AUTOCOMMIT },
+       { "schema", "Schema", MP_SCHEMA },
+       { "timezone", "Time Zone", MP_TIMEZONE },
+       { "replysize", "Reply Size", MP_REPLYSIZE },
+       { "logfile", "Log File", MP_LOGFILE },
+};
+
+const int attr_setting_count = sizeof(attr_settings) / 
sizeof(attr_settings[0]);
+
+int
+attr_setting_lookup(const char *attr_name)
+{
+       for (int i = 0; i < attr_setting_count; i++) {
+               const struct attr_setting *entry = &attr_settings[i];
+               if (strcasecmp(attr_name, entry->name) == 0)
+                       return i;
+               if (entry->alt_name && strcasecmp(attr_name, entry->alt_name) 
== 0)
+                       return i;
+       }
+       return -1;
+}
+
+
 static void
 get_serverinfo(ODBCDbc *dbc)
 {
@@ -84,84 +121,146 @@ get_serverinfo(ODBCDbc *dbc)
        mapi_close_handle(hdl);
 }
 
-// Return a newly allocated NUL-terminated config value from either the 
argument
-// or the data source. Return 'default_value' if no value can be found, NULL on
-// allocation error.
+
+// Ensure '*argument' is either NULL or a NUL-terminated string,
+// taking into account 'argument_len' being either a proper string length
+// or one of the special values SQL_NULL_DATA or SQL_NTS.
 //
-// If non-NULL, parameter 'argument' points to an argument that may or may not
-// be NUL-terminated. The length parameter 'argument_len' can either be the
-// length of the argument or one of the following special values:
+// Return 'true' on success and 'false' on allocation failure.
 //
-//    SQL_NULL_DATA: consider the argument NULL
-//    SQL_NTS:       the argument is actually NUL-terminated
+// If memory needs to be allocated and 'scratch' is not NULL,
+// a pointer to the allocated memory will be stored in '*scratch'
+// and the previous value of '*scratch' will be free'd.
 //
-// Parameters 'dsn' and 'entry', if not NULL and not empty, indicate which data
-// source field to look up in "odbc.ini".
+// '*argument' is never free'd.
+static bool
+make_nul_terminated(const SQLCHAR **argument, ssize_t argument_len, void 
**scratch)
+{
+       assert(argument != NULL);
+
+       if (*argument == NULL || argument_len == SQL_NTS)
+               return true;
+       if (argument_len == SQL_NULL_DATA) {
+               *argument = NULL;
+               return true;
+       }
+
+       SQLCHAR *value = malloc(argument_len + 1);
+       if (value == NULL)
+               return false;
+       memmove(value, argument, argument_len);
+       value[argument_len] = '\0';
+
+       *argument = value;
+       if (scratch) {
+               free(*scratch);
+               *scratch = value;
+       }
+
+       return value;
+}
+
+#ifdef ODBCDEBUG
 static char*
-getConfig(
-       const void *argument, ssize_t argument_len,
-       const char *dsn, const char *entry,
-       const char *default_value)
+display_connect_string(const char *dsn, const msettings *settings)
 {
-       if (argument != NULL && argument_len != SQL_NULL_DATA) {
-               // argument is present..
-               if (argument_len == SQL_NTS) {
-                       // .. and it's already NUL-terminated
-                       return strdup((const char*)argument);
+
+       size_t pos = 0;
+       size_t cap = 1024;
+       char *buf = malloc(cap);  // reallocprintf will deal with allocation 
failures
+       char *sep = "";
+       char *value = NULL;
+       char *default_value = NULL;
+       bool ok = false;
+
+       if (dsn) {
+               if (reallocprintf(&buf, &pos, &cap, "DSN=%s", dsn) < 0)
+                       goto end;
+               sep = "; ";
+       }
+
+       for (int i = 0; i < attr_setting_count; i++) {
+               const struct attr_setting *entry = &attr_settings[i];
+               mparm parm = entry->parm;
+
+               if (parm == MP_TABLE || parm == MP_TABLESCHEMA)
+                       continue;
+
+               free(value);
+               value = msetting_as_string(settings, parm);
+               if (!value)
+                       goto end;
+
+               bool show_this = true;
+               if (parm == MP_USER || parm == MP_PASSWORD) {
+                       show_this = true;
+               } else if (parm == MP_PORT && msetting_long(settings, MP_PORT) 
<= 0) {
+                       show_this = false;
+               } else if (parm == MP_TLS) {
+                       show_this = msetting_bool(settings, MP_TLS);
+               } else if (mparm_is_core(parm)) {
+                       show_this = true;
                } else {
-                       // .. but we need to create a NUL-terminated copy
-                       char *value = malloc(argument_len + 1);
-                       if (value == NULL)
-                               return NULL;
-                       memmove(value, argument, argument_len);
-                       value[argument_len] = '\0';
-                       return value;
+                       // skip if still default
+                       free(default_value);
+                       default_value = msetting_as_string(msettings_default, 
parm);
+                       if (!default_value)
+                               goto end;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to