Changeset: 230778a77ea1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/230778a77ea1
Modified Files:
        clients/odbc/samples/odbcconnect.c
Branch: Aug2024
Log Message:

Add list drivers and list dns's to odbcconnect

Fix a small memory leak in the process


diffs (204 lines):

diff --git a/clients/odbc/samples/odbcconnect.c 
b/clients/odbc/samples/odbcconnect.c
--- a/clients/odbc/samples/odbcconnect.c
+++ b/clients/odbc/samples/odbcconnect.c
@@ -15,6 +15,8 @@
 
 #include <WTypes.h>
 #endif
+
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -29,14 +31,22 @@ static const char *USAGE =
        "        -d              Target is DSN, call SQLConnect()\n"
        "        -c              Target is connection string, call 
SQLDriverConnect()\n"
        "        -b              Target is connection string, call 
SQLBrowseConnect()\n"
+       "        -l              List registered drivers and data sources\n"
        "        -u USER\n"
        "        -p PASSWORD\n"
        "        -v              Be verbose\n"
        "        TARGET          Connection String or DSN\n";
 
-static int do_sqlconnect(SQLCHAR *target);
-static int do_sqldriverconnect(SQLCHAR *target);
-static int do_sqlbrowseconnect(SQLCHAR *target);
+typedef int (action_t)(SQLCHAR *);
+
+static int do_actions(action_t action, int ntargets, SQLCHAR **targets);
+
+static action_t do_sqlconnect;
+static action_t do_sqldriverconnect;
+static action_t do_sqlbrowseconnect;
+
+static int do_listdrivers(void);
+static int do_listdsns(const char *prefix, SQLSMALLINT dir);
 
 static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message, 
SQLRETURN ret);
 
@@ -49,6 +59,7 @@ SQLHANDLE env = NULL;
 SQLHANDLE conn = NULL;
 
 SQLCHAR outbuf[4096];
+SQLCHAR attrbuf[4096];
 
 static void
 cleanup(void)
@@ -68,7 +79,7 @@ main(int argc, char **argv)
        action = do_sqlconnect;
        SQLCHAR **targets = calloc(argc, sizeof(argv[0]));
        int ntargets = 0;
-       int ret = 0;
+       int ret;
 
        for (int i = 1; i < argc; i++) {
                char *arg = argv[i];
@@ -78,6 +89,8 @@ main(int argc, char **argv)
                        action = do_sqldriverconnect;
                else if (strcmp(arg, "-b") == 0)
                        action = do_sqlbrowseconnect;
+               else if (strcmp(arg, "-l") == 0)
+                       action = NULL;
                else if (strcmp(arg, "-u") == 0 && i + 1 < argc)
                        user = (SQLCHAR*)argv[++i];
                else if (strcmp(arg, "-p") == 0 && i + 1 < argc)
@@ -88,15 +101,11 @@ main(int argc, char **argv)
                        targets[ntargets++] = (SQLCHAR*)arg;
                else {
                        fprintf(stderr, "\nERROR: invalid argument: %s\n%s", 
arg, USAGE);
-                       return 1;
+                       ret = 1;
+                       goto end;
                }
        }
 
-       if (ntargets == 0) {
-               fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE);
-               return 1;
-       }
-
        ensure_ok(
                SQL_HANDLE_ENV, NULL, "allocate env handle",
                SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env));
@@ -105,20 +114,25 @@ main(int argc, char **argv)
                SQL_HANDLE_ENV, env, "set odbc version",
                SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, 
(SQLPOINTER)SQL_OV_ODBC3, 0));
 
-       ensure_ok(
-               SQL_HANDLE_ENV, env, "allocate conn handle",
-               SQLAllocHandle(SQL_HANDLE_DBC, env, &conn));
-
-       for (int i = 0; i < ntargets; i++) {
-               SQLCHAR *t = targets[i];
-               if (verbose)
-                       printf("\nTarget: %s\n", t);
-               outbuf[0] = '\0';
-               int ret = action(t);
-               if (ret)
-                       break;
+       if (action) {
+               if (ntargets == 0) {
+                       fprintf(stderr, "\nERROR: pass at least one 
target\n%s", USAGE);
+                       ret = 1;
+                       goto end;
+               }
+               ret = do_actions(action, ntargets, targets);
+       } else {
+               if (ntargets != 0) {
+                       fprintf(stderr, "\nERROR: -l does not take 
arguments\n%s", USAGE);
+                       ret = 1;
+                       goto end;
+               }
+               ret = do_listdrivers();
+               ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_SYSTEM);
+               ret |= do_listdsns("SYSTEM", SQL_FETCH_FIRST_USER);
        }
 
+end:
        free(targets);
        cleanup();
 
@@ -174,6 +188,26 @@ ensure_ok(SQLSMALLINT type, SQLHANDLE ha
 
 
 static int
+do_actions(action_t action, int ntargets, SQLCHAR **targets)
+{
+       ensure_ok(
+               SQL_HANDLE_ENV, env, "allocate conn handle",
+               SQLAllocHandle(SQL_HANDLE_DBC, env, &conn));
+
+       for (int i = 0; i < ntargets; i++) {
+               SQLCHAR *t = targets[i];
+               if (verbose)
+                       printf("\nTarget: %s\n", t);
+               outbuf[0] = '\0';
+               int ret = action(t);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int
 do_sqlconnect(SQLCHAR *target)
 {
        ensure_ok(
@@ -218,3 +252,56 @@ do_sqlbrowseconnect(SQLCHAR *target)
        return 0;
 }
 
+static int
+do_listdrivers(void)
+{
+       SQLSMALLINT dir = SQL_FETCH_FIRST;
+       SQLSMALLINT len1, len2;
+       int count = 0;
+
+       while (1) {
+               outbuf[0] = attrbuf[0] = '\0';
+               SQLRETURN ret = SQLDrivers(
+                       env, dir,
+                       outbuf, sizeof(outbuf), &len1,
+                       attrbuf, sizeof(attrbuf), &len2
+               );
+               if (ret == SQL_NO_DATA)
+                       break;
+               ensure_ok(SQL_HANDLE_ENV, env, "SQLDrivers", ret);
+               dir = SQL_FETCH_NEXT;
+               count += 1;
+               printf("DRIVER={%s}\n", outbuf);
+               for (char *p = (char*)attrbuf; *p; p += strlen(p) + 1) {
+                       printf("    %s\n", (char*)p);
+               }
+       }
+
+       if (count == 0)
+               printf("no drivers.\n");
+
+       return 0;
+}
+
+static int
+do_listdsns(const char *prefix, SQLSMALLINT dir)
+{
+       SQLSMALLINT len1, len2;
+
+       while (1) {
+               outbuf[0] = attrbuf[0] = '\0';
+               SQLRETURN ret = SQLDataSources(
+                       env, dir,
+                       outbuf, sizeof(outbuf), &len1,
+                       attrbuf, sizeof(attrbuf), &len2
+               );
+               if (ret == SQL_NO_DATA)
+                       break;
+               ensure_ok(SQL_HANDLE_ENV, env, "SQLDataSources", ret);
+               dir = SQL_FETCH_NEXT;
+               printf("%s DSN=%s\n    Driver=%s\n", prefix, outbuf, attrbuf);
+       }
+
+       return 0;
+}
+
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to