Changeset: acc4ede18819 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/acc4ede18819
Modified Files:
        clients/odbc/driver/ODBCAttrs.h
        clients/odbc/driver/ODBCDbc.c
        clients/odbc/driver/ODBCDbc.h
        clients/odbc/driver/SQLBrowseConnect.c
        clients/odbc/driver/SQLConnect.c
        clients/odbc/driver/SQLDisconnect.c
        clients/odbc/driver/SQLDriverConnect.c
        clients/odbc/samples/odbcbrowse.c
        tools/merovingian/daemon/client.c
Branch: odbc-tls
Log Message:

Implement SQLBrowseConnect

It treats UID and PWD as mandatory,
DATABASE only if monetdbd asks for it.


diffs (truncated from 587 to 300 lines):

diff --git a/clients/odbc/driver/ODBCAttrs.h b/clients/odbc/driver/ODBCAttrs.h
--- a/clients/odbc/driver/ODBCAttrs.h
+++ b/clients/odbc/driver/ODBCAttrs.h
@@ -21,9 +21,11 @@
 #include "msettings.h"
 
 struct attr_setting {
-       const char *name;        // canonical attribute name
-       const char *alt_name;    // user-facing attribute name
+       const char *name;                // canonical attribute name
+       const char *alt_name;            // user-facing attribute name
        mparm parm;
+       // optional
+       const char *suggest_values;      // SQLBrowseConnect suggestion, or 
NULL for "?"
 };
 
 // defined in SQLConnect.c, also used in SQLBrowseConnect.c
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
@@ -76,6 +76,7 @@ newODBCDbc(ODBCEnv *env)
                /* add this dbc to start of the administrative linked dbc list 
*/
                .next = env->FirstDbc,
                .Type = ODBC_DBC_MAGIC_NR,      /* set it valid */
+               .setting_touched = { 0 },
        };
        env->FirstDbc = dbc;
        return 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
@@ -81,6 +81,7 @@ typedef struct tODBCDRIVERDBC {
        /* can't use ODBCStmt *FirstStmt here because of ordering of
           include files */
        struct tODBCDRIVERSTMT *FirstStmt;      /* first in list or NULL */
+       char setting_touched[MP__MAX];  /* for SQLBrowseConnect. set 0 on init, 
1 on touch, other is up to SQLBrowseConnect */
 } ODBCDbc;
 
 
@@ -170,9 +171,11 @@ SQLRETURN MNDBSetConnectAttr(ODBCDbc *db
 extern char *ODBCTranslateSQL(ODBCDbc *dbc, const SQLCHAR *query, size_t 
length, SQLULEN noscan);
 
 extern SQLRETURN MNDBConnectSettings(ODBCDbc *dbc, msettings *settings);
+extern SQLRETURN MNDBDriverConnect(ODBCDbc *dbc, SQLHWND WindowHandle, const 
SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLCHAR 
*OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2Ptr, 
SQLUSMALLINT DriverCompletion, int tryOnly);
 
 extern bool makeNulTerminated(const SQLCHAR **argument, ssize_t argument_len, 
void **scratch);
-extern const char* takeSettingsFromDS(msettings *settings, const char *dsn);
+extern const char* takeFromDataSource(ODBCDbc *dbc, msettings *settings, const 
char *dsn);
+extern SQLRETURN takeFromConnString(ODBCDbc *dbc, msettings *settings, const 
SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, char  **dsn_out);
 extern char* buildConnectionString(const char *dsn, const msettings *settings);
 
 
diff --git a/clients/odbc/driver/SQLBrowseConnect.c 
b/clients/odbc/driver/SQLBrowseConnect.c
--- a/clients/odbc/driver/SQLBrowseConnect.c
+++ b/clients/odbc/driver/SQLBrowseConnect.c
@@ -32,6 +32,7 @@
 #include "ODBCGlobal.h"
 #include "ODBCDbc.h"
 #include "ODBCUtil.h"
+#include "ODBCAttrs.h"
 #ifdef HAVE_STRINGS_H
 #include <strings.h>           /* strcasecmp */
 #endif
@@ -44,6 +45,24 @@
 #define 
SQLGetPrivateProfileString(section,entry,default,buffer,bufferlen,filename)    
((int) strcpy_len(buffer,default,bufferlen))
 #endif
 
+static void
+suggest_settings(ODBCDbc *dbc, char **buf, size_t *pos, size_t *cap, char 
touched_as, const char *prefix)
+{
+       for (int i = 0; i < attr_setting_count; i++) {
+               const struct attr_setting *entry = &attr_settings[i];
+               mparm parm = entry->parm;
+               if (dbc->setting_touched[(int)parm] == touched_as) {
+                       const char *sep = *pos > 0 ? ";" : "";
+                       const char *values = entry->suggest_values ? 
entry->suggest_values : "?";
+                       reallocprintf(
+                               buf, pos, cap,
+                               "%s%s%s:%s=%s",
+                               sep, prefix, entry->name, entry->alt_name, 
values);
+               }
+       }
+}
+
+
 
 static SQLRETURN
 MNDBBrowseConnect(ODBCDbc *dbc,
@@ -53,179 +72,53 @@ MNDBBrowseConnect(ODBCDbc *dbc,
                  SQLSMALLINT BufferLength,
                  SQLSMALLINT *StringLength2Ptr)
 {
-       char *key, *attr;
-       char *dsn, *uid, *pwd, *host, *dbname;
-       int port, mapToLongVarchar;
-       SQLSMALLINT len = 0;
-       char buf[1024];
-       int n;
        SQLRETURN rc;
-#ifdef ODBCDEBUG
-       bool odbcdebug_changed = false;
-#endif
 
-       fixODBCstring(InConnectionString, StringLength1, SQLSMALLINT, 
addDbcError, dbc, return SQL_ERROR);
-
-#ifdef ODBCDEBUG
-       ODBCLOG(" \"%.*s\"\n", (int) StringLength1, (char*) InConnectionString);
-#endif
+       rc = MNDBDriverConnect(
+               dbc, NULL,
+               InConnectionString, StringLength1,
+               OutConnectionString, BufferLength, StringLength2Ptr,
+               SQL_DRIVER_NOPROMPT,
+               0
+       );
 
-       /* check connection state, should not be connected */
-       if (dbc->Connected) {
-               /* Connection name in use */
-               addDbcError(dbc, "08002", NULL, 0);
-               return SQL_ERROR;
+       if (SQL_SUCCEEDED(rc)) {
+               return rc;
        }
 
-       dsn = dbc->dsn ? strdup(dbc->dsn) : NULL;
-       uid = dbc->uid ? strdup(dbc->uid) : NULL;
-       pwd = dbc->pwd ? strdup(dbc->pwd) : NULL;
-       host = dbc->host ? strdup(dbc->host) : NULL;
-       port = dbc->port;
-       dbname = dbc->dbname ? strdup(dbc->dbname) : NULL;
-       mapToLongVarchar = dbc->mapToLongVarchar;
-
-       while ((n = ODBCGetKeyAttr(&InConnectionString, &StringLength1, &key, 
&attr)) > 0) {
-               if (strcasecmp(key, "dsn") == 0 && dsn == NULL) {
-                       if (dsn)
-                               free(dsn);
-                       dsn = attr;
-               } else if (strcasecmp(key, "uid") == 0 && uid == NULL) {
-                       if (uid)
-                               free(uid);
-                       uid = attr;
-               } else if (strcasecmp(key, "pwd") == 0 && pwd == NULL) {
-                       if (pwd)
-                               free(pwd);
-                       pwd = attr;
-               } else if (strcasecmp(key, "host") == 0 && host == NULL) {
-                       if (host)
-                               free(host);
-                       host = attr;
-               } else if (strcasecmp(key, "port") == 0 && port == 0) {
-                       port = atoi(attr);
-                       free(attr);
-               } else if (strcasecmp(key, "database") == 0 && dbname == NULL) {
-                       if (dbname)
-                               free(dbname);
-                       dbname = attr;
-               } else if (strcasecmp(key, "mapToLongVarchar") == 0 && 
mapToLongVarchar == 0) {
-                       mapToLongVarchar = atoi(attr);
-                       free(attr);
-#ifdef ODBCDEBUG
-               } else if (strcasecmp(key, "logfile") == 0) {
-                       setODBCdebug(attr, false);
-                       free(attr);
-                       odbcdebug_changed = true;
-#endif
-               } else
-                       free(attr);
-               free(key);
-       }
-       if (n < 0)
-               goto nomem;
+       // 0 = never touched, show it
+       // 1 = touched, do not show it
+       // 2 = show as mandatory
 
-       if (dsn) {
-               if (uid == NULL) {
-                       n = SQLGetPrivateProfileString(dsn, "uid", "", buf, 
sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               uid = strdup(buf);
-                               if (uid == NULL)
-                                       goto nomem;
-                       }
-               }
-               if (pwd == NULL) {
-                       n = SQLGetPrivateProfileString(dsn, "pwd", "", buf, 
sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               pwd = strdup(buf);
-                               if (pwd == NULL)
-                                       goto nomem;
-                       }
-               }
-               if (host == NULL) {
-                       n = SQLGetPrivateProfileString(dsn, "host", "", buf, 
sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               host = strdup(buf);
-                               if (host == NULL)
-                                       goto nomem;
-                       }
-               }
-               if (port == 0) {
-                       n = SQLGetPrivateProfileString(dsn, "port", "", buf, 
sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               port = atoi(buf);
-                       }
-               }
-               if (dbname == NULL) {
-                       n = SQLGetPrivateProfileString(dsn, "database", "", 
buf, sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               dbname = strdup(buf);
-                               if (dbname == NULL)
-                                       goto nomem;
-                       }
-               }
-#ifdef ODBCDEBUG
-               if (!odbcdebug_changed) {
-                       /* if not set from InConnectionString argument
-                        * or environment, look in profile */
-                       n = SQLGetPrivateProfileString(dsn, "logfile", "", buf, 
sizeof(buf), "odbc.ini");
-                       if (n > 0 && buf[0]) {
-                               setODBCdebug(buf, false);
-                       }
-               }
-#endif
+       if (dbc->setting_touched[MP_USER] != 1)
+               dbc->setting_touched[MP_USER] = 2;
+       if (dbc->setting_touched[MP_PASSWORD] != 1)
+               dbc->setting_touched[MP_PASSWORD] = 2;
+
+       // Make MP_DATABASE mandatory if monetdbd asks for it.
+       for (ODBCError *err = dbc->Error; err != NULL; err = getErrorRec(err, 
2)) {
+               if (strcmp("08001", getSqlState(err)) != 0)
+                       continue;
+               if (strstr(getMessage(err), "monetdbd: please specify a 
database") == NULL)
+                       continue;
+               dbc->setting_touched[MP_DATABASE] = 2;
        }
 
-       if (uid != NULL && pwd != NULL) {
-               rc = MNDBConnect(dbc, (SQLCHAR *) dsn, SQL_NTS,
-                                (SQLCHAR *) uid, SQL_NTS,
-                                (SQLCHAR *) pwd, SQL_NTS,
-                                host, port, dbname,
-                                mapToLongVarchar);
-               if (SQL_SUCCEEDED(rc)) {
-                       rc = ODBCConnectionString(rc, dbc, OutConnectionString,
-                                                 BufferLength,
-                                                 StringLength2Ptr,
-                                                 dsn, uid, pwd, host, port,
-                                                 dbname, mapToLongVarchar);
-               }
-       } else {
-               len = (SQLSMALLINT) strconcat_len(
-                       (char *) OutConnectionString, BufferLength,
-                       uid ? "" : "UID:Login ID=?;",
-                       pwd ? "" : "PWD:Password=?;",
-                       host ? "" : "*HOST:Server=?;",
-                       port ? "" : "*PORT:Port=?;",
-                       dbname ? "" : "*DATABASE:Database=?;",
-#ifdef ODBCDEBUG
-                       ODBCdebug ? "" : "*LOGFILE:Logfile=?;",
-#endif
-                       NULL);
+       char *buf = NULL;
+       size_t pos = 0;
+       size_t cap = 0;
+       suggest_settings(dbc, &buf, &pos, &cap, 2, "");    // mandatory first
+       suggest_settings(dbc, &buf, &pos, &cap, 0, "*");   // then optional
 
+       if (buf && pos) {
+               size_t n = strcpy_len((char*)OutConnectionString, buf, 
BufferLength);
                if (StringLength2Ptr)
-                       *StringLength2Ptr = len;
-
-               rc = SQL_NEED_DATA;
+                       *StringLength2Ptr = n;
        }
 
-  bailout:
-       if (dsn)
-               free(dsn);
-       if (uid)
-               free(uid);
-       if (pwd)
-               free(pwd);
-       if (host)
-               free(host);
-       if (dbname)
-               free(dbname);
-       return rc;
-
-  nomem:
-       /* Memory allocation error */
-       addDbcError(dbc, "HY001", NULL, 0);
-       rc = SQL_ERROR;
-       goto bailout;
+       free(buf);
+       clearDbcErrors(dbc);
+       return SQL_NEED_DATA;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to