Added in PQconnectdb() function
authorMarc G. Fournier
Sat, 9 Nov 1996 10:39:54 +0000 (10:39 +0000)
committerMarc G. Fournier
Sat, 9 Nov 1996 10:39:54 +0000 (10:39 +0000)
Submitted by: [email protected] (Jan Wieck)

src/Makefile.global
src/interfaces/libpgtcl/pgtcl.c
src/interfaces/libpgtcl/pgtclCmds.c
src/interfaces/libpgtcl/pgtclCmds.h
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-fe.h

index d0356683c96f8dfe143811793a76641e1883c081..c4eb88b1d65fe3a73acbd1cc28f5b45bc897879f 100644 (file)
@@ -7,7 +7,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.56 1996/11/08 07:47:52 scrappy Exp $
+#    $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.57 1996/11/09 10:39:02 scrappy Exp $
 #
 # NOTES
 #    This is seen by any Makefiles that include mk/postgres.mk. To
@@ -59,7 +59,7 @@
 #  to change it in Makefile.custom.
 #  make sure that you have no whitespaces after the PORTNAME setting
 #  or the makefiles can get confused
-PORTNAME=  UNDEFINED
+PORTNAME=  BSD44_derived
 
 # Ignore LINUX_ELF if you're not using Linux.  But if you are, and you're
 # compiling to a.out (which means you're using the dld dynamic loading 
@@ -860,7 +860,7 @@ includedir= $(HEADERDIR)
 # Flags for CC and LD. (depend on COPT and PROFILE)
 #
 # PostgreSQL should *always* compile with -Wall -Werror enabled
-CFLAGS+=   -Wall -Werror
+CFLAGS+=   -Wall #-Werror
 
 # Globally pass debugging/optimization/profiling flags based
 # on the options selected above.
index d4021894e44f9ce97f1b4fdfafbff94ca51d9c85..ad9b68b41d0956962c2b316dcd8191f7f106d942 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.3 1996/10/30 06:18:38 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.4 1996/11/09 10:39:40 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -75,6 +75,11 @@ Pgtcl_Init (Tcl_Interp *interp)
   Tcl_CreateExitHandler(Pgtcl_AtExit, (ClientData)cd);
 
   /* register all pgtcl commands */
+  Tcl_CreateCommand(interp,
+           "pg_conndefaults",
+           Pg_conndefaults,
+           (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
+
   Tcl_CreateCommand(interp,
            "pg_connect",
            Pg_connect,
index 91be2bd37f53ea40ac6db1ff004a3b381a76093c..397bcd15f7a7a12658cc298e38e866aa928d1d63 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.5 1996/10/30 06:18:39 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.6 1996/11/09 10:39:41 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -209,6 +209,44 @@ tcl_value (char *value)
 
 #endif
 
+/**********************************
+ * pg_conndefaults
+ syntax:
+ pg_conndefaults
+ the return result is a list describing the possible options and their
+ current default values for a call to pg_connect with the new -conninfo
+ syntax. Each entry in the list is a sublist of the format:
+
+     {optname label dispchar dispsize value}
+ **********************************/
+
+int
+Pg_conndefaults(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+{
+    PQconninfoOption *option;
+    char   buf[8192];
+
+    Tcl_ResetResult(interp);
+    for(option = PQconndefaults(); option->keyword != NULL; option++) {
+        if(option->val == NULL) {
+       option->val = "";
+   }
+   sprintf(buf, "{%s} {%s} {%s} %d {%s}",
+       option->keyword,
+       option->label,
+       option->dispchar,
+       option->dispsize,
+       option->val);
+        Tcl_AppendElement(interp, buf);
+    }
+
+    return TCL_OK;
+}
+
+
 /**********************************
  * pg_connect
  make a connection to a backend.  
@@ -235,55 +273,73 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
   
     if (argc == 1) {
    Tcl_AppendResult(interp, "pg_connect: database name missing\n", 0);
-   Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]", 0);
+   Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]\n", 0);
+   Tcl_AppendResult(interp, "pg_connect -conninfo ", 0);
    return TCL_ERROR;
     
     }
-    if (argc > 2) { 
-   /* parse for pg environment settings */
-   i = 2;
-   while (i+1 < argc) {
-       if (strcmp(argv[i], "-host") == 0) {
-       pghost = argv[i+1];
-       i += 2;
-       }
-       else
-       if (strcmp(argv[i], "-port") == 0) {
-           pgport = argv[i+1];
+
+    if (!strcmp("-conninfo", argv[1])) {
+   /*
+    * Establish a connection using the new PQconnectdb() interface
+    */
+        if (argc != 3) {
+       Tcl_AppendResult(interp, "pg_connect: syntax error\n", 0);
+       Tcl_AppendResult(interp, "pg_connect -conninfo ", 0);
+       return TCL_ERROR;
+   }
+   conn = PQconnectdb(argv[2]);
+    } else {
+   /*
+    * Establish a connection using the old PQsetdb() interface
+    */
+   if (argc > 2) { 
+       /* parse for pg environment settings */
+       i = 2;
+       while (i+1 < argc) {
+       if (strcmp(argv[i], "-host") == 0) {
+           pghost = argv[i+1];
            i += 2;
        }
        else
-           if (strcmp(argv[i], "-tty") == 0) {
-           pgtty = argv[i+1];
+           if (strcmp(argv[i], "-port") == 0) {
+           pgport = argv[i+1];
            i += 2;
            }
-               else if (strcmp(argv[i], "-options") == 0) {
-           pgoptions = argv[i+1];
-           i += 2;
-           }
-           else {
-           Tcl_AppendResult(interp, "Bad option to pg_connect : \n",
-                    argv[i], 0);
-           Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
-           return TCL_ERROR;
-           }
-   } /* while */
-   if ((i % 2 != 0) || i != argc) {
-       Tcl_AppendResult(interp, "wrong # of arguments to pg_connect\n", argv[i],0);
-       Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
-       return TCL_ERROR;
+           else
+           if (strcmp(argv[i], "-tty") == 0) {
+               pgtty = argv[i+1];
+               i += 2;
+           }
+           else if (strcmp(argv[i], "-options") == 0) {
+               pgoptions = argv[i+1];
+               i += 2;
+           }
+           else {
+               Tcl_AppendResult(interp, "Bad option to pg_connect : \n",
+                        argv[i], 0);
+               Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
+               return TCL_ERROR;
+           }
+       } /* while */
+       if ((i % 2 != 0) || i != argc) {
+       Tcl_AppendResult(interp, "wrong # of arguments to pg_connect\n", argv[i],0);
+       Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
+       return TCL_ERROR;
+       }
    }
+   dbName = argv[1];
+        conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
     }
-    dbName = argv[1];
 
-    conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
     if (conn->status == CONNECTION_OK) {
    PgSetConnectionId(cd, interp->result, conn);
    return TCL_OK;
     }
     else {
-   Tcl_AppendResult(interp, "Connection to ", dbName, " failed\n", 0);
+   Tcl_AppendResult(interp, "Connection to database failed\n", 0);
    Tcl_AppendResult(interp, conn->errorMessage, 0);
+   PQfinish(conn);
    return TCL_ERROR;
     }
 }
index ea3ea84225fb53af33beb010df47457fc3be52dd..4883b926eaaf448cf70318df4b8434bebd515108 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pgtclCmds.h,v 1.3 1996/10/30 06:18:40 scrappy Exp $
+ * $Id: pgtclCmds.h,v 1.4 1996/11/09 10:39:42 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,6 +43,8 @@ typedef struct Pg_ResultId_s {
 /* **************************/
 /* registered Tcl functions */
 /* **************************/
+extern int Pg_conndefaults(
+    ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
 extern int Pg_connect(
     ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
 extern int Pg_disconnect(
index 8e67399370a9a7a04803d4f0154a6ca8f1ea48dd..341f6728f637dec35164fdd9e9b396ebfef37c7a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.14 1996/11/04 04:00:54 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.15 1996/11/09 10:39:51 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,10 +52,197 @@ static int packetSend(Port *port, PacketBuf *buf, PacketLen len,
 static void startup2PacketBuf(StartupInfo* s, PacketBuf* res);
 static void freePGconn(PGconn *conn);
 static void closePGconn(PGconn *conn);
+static int conninfo_parse(const char *conninfo, char *errorMessage);
+static char *conninfo_getval(char *keyword);
+static void conninfo_free();
 
 #define NOTIFYLIST_INITIAL_SIZE 10
 #define NOTIFYLIST_GROWBY 10
 
+
+/* ----------
+ * Definition of the conninfo parametes and their fallback resources.
+ * If Environment-Var and Compiled-in are specified as NULL, no
+ * fallback is available. If after all no value can be determined
+ * for an option, an error is returned.
+ *
+ * The values for dbname and user are treated special in conninfo_parse.
+ * If the Compiled-in resource is specified as a NULL value, the
+ * user is determined by fe_getauthname() and for dbname the user
+ * name is copied.
+ *
+ * The Label and Disp-Char entries are provided for applications that
+ * want to use PQconndefaults() to create a generic database connection
+ * dialog. Disp-Char is defined as follows:
+ *     ""  Normal input field
+ * ----------
+ */
+static PQconninfoOption PQconninfoOptions[] = {
+/*    ----------------------------------------------------------------- */
+/*    Option-name  Environment-Var Compiled-in Current value   */
+/*         Label               Disp-Char   */
+/*    ----------------- --------------- --------------- --------------- */
+    { "user",      "PGUSER",   NULL,       NULL,
+               "Database-User",        "", 20  },
+
+    { "dbname",        "PGDATABASE",   NULL,       NULL,
+               "Database-Name",        "", 20  },
+
+    { "host",      "PGHOST",   DefaultHost,    NULL,
+               "Database-Host",        "", 40  },
+
+    { "port",      "PGPORT",   POSTPORT,   NULL,
+               "Database-Port",        "", 6   },
+
+    { "tty",       "PGTTY",    DefaultTty, NULL,
+               "Backend-Debug-TTY",        "D", 40 },
+
+    { "options",   "PGOPTIONS",    DefaultOption,  NULL,
+               "Backend-Debug-Options",    "D", 40 },
+/*    ----------------- --------------- --------------- --------------- */
+    { NULL,        NULL,       NULL,       NULL,
+               NULL,               NULL, 0 }
+};
+
+/* ----------------
+ * PQconnectdb
+ * 
+ * establishes a connectin to a postgres backend through the postmaster
+ * using connection information in a string.
+ *
+ * The conninfo string is a list of
+ *
+ *     option = value
+ *
+ * definitions. Value might be a single value containing no whitespaces
+ * or a single quoted string. If a single quote should appear everywhere
+ * in the value, it must be escaped with a backslash like \'
+ *
+ * Returns a PGconn* which is needed for all subsequent libpq calls
+ * if the status field of the connection returned is CONNECTION_BAD,
+ * then some fields may be null'ed out instead of having valid values 
+ * ----------------
+ */
+PGconn*
+PQconnectdb(const char *conninfo)
+{
+    PGconn *conn;
+    PQconninfoOption *option;
+    char errorMessage[ERROR_MSG_LENGTH];
+
+    /* ----------
+     * Allocate memory for the conn structure
+     * ----------
+     */
+    conn = (PGconn*)malloc(sizeof(PGconn));
+    if (conn == NULL) {
+        fprintf(stderr,
+            "FATAL: PQsetdb() -- unable to allocate memory for a PGconn");
+        return (PGconn*)NULL;
+    }
+    memset((char *)conn, 0, sizeof(PGconn));
+
+    /* ----------
+     * Parse the conninfo string and get the fallback resources
+     * ----------
+     */
+    if(conninfo_parse(conninfo, errorMessage) < 0) {
+   conn->status = CONNECTION_BAD;
+   strcpy(conn->errorMessage, errorMessage);
+   conninfo_free();
+   return conn;
+    }
+
+    /* ----------
+     * Check that we have all connection parameters
+     * ----------
+     */
+    for(option = PQconninfoOptions; option->keyword != NULL; option++) {
+   if(option->val != NULL)  continue;  /* Value was in conninfo */
+
+   /* ----------
+    * No value was found for this option. Return an error.
+    * ----------
+    */
+   conn->status = CONNECTION_BAD;
+   sprintf(conn->errorMessage,
+      "ERROR: PQconnectdb(): Cannot determine a value for option '%s'.\n",
+      option->keyword);
+   strcat(conn->errorMessage,
+       "Option not specified in conninfo string");
+   if(option->environ) {
+       strcat(conn->errorMessage,
+           ", environment variable ");
+       strcat(conn->errorMessage, option->environ);
+       strcat(conn->errorMessage, "\nnot set");
+   }
+   strcat(conn->errorMessage, " and no compiled in default value.\n");
+   conninfo_free();
+   return conn;
+    }
+
+    /* ----------
+     * Setup the conn structure
+     * ----------
+     */
+    conn->Pfout = NULL;
+    conn->Pfin = NULL;
+    conn->Pfdebug = NULL;
+    conn->port = NULL;
+    conn->notifyList = DLNewList();
+
+    conn->pghost    = strdup(conninfo_getval("host"));
+    conn->pgport    = strdup(conninfo_getval("port"));
+    conn->pgtty     = strdup(conninfo_getval("tty"));
+    conn->pgoptions = strdup(conninfo_getval("options"));
+    conn->pguser    = strdup(conninfo_getval("user"));
+    conn->dbName    = strdup(conninfo_getval("dbname"));
+
+    /* ----------
+     * Free the connection info - all is in conn now
+     * ----------
+     */
+    conninfo_free();
+
+    /* ----------
+     * Connect to the database
+     * ----------
+     */
+    conn->status = connectDB(conn);
+    if (conn->status == CONNECTION_OK) {
+      PGresult *res;
+      /* Send a blank query to make sure everything works; in particular, that
+         the database exists.
+         */ 
+      res = PQexec(conn," ");
+      if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY) {
+        /* PQexec has put error message in conn->errorMessage */
+        closePGconn(conn);
+      }
+      PQclear(res);
+    } 
+
+    return conn;
+}
+
+/* ----------------
+ * PQconndefaults
+ * 
+ * Parse an empty string like PQconnectdb() would do and return the
+ * address of the connection options structure. Using this function
+ * an application might determine all possible options and their
+ * current default values.
+ * ----------------
+ */
+PQconninfoOption*
+PQconndefaults()
+{
+    char errorMessage[ERROR_MSG_LENGTH];
+
+    conninfo_parse("", errorMessage);
+    return PQconninfoOptions;
+}
+
 /* ----------------
  * PQsetdb
  * 
@@ -162,7 +349,7 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha
       if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
           ((tmp = getenv("PGDATABASE")))) {
         conn->dbName = strdup(tmp);
-      } else conn->dbName = conn->pguser;
+      } else conn->dbName = strdup(conn->pguser);
     } else conn->dbName = NULL;
 
     if (error) conn->status = CONNECTION_BAD;
@@ -461,6 +648,230 @@ startup2PacketBuf(StartupInfo* s, PacketBuf* res)
   strncpy(tmp, s->tty, sizeof(s->execFile));
 }
 
+/* ----------------
+ * Conninfo parser routine
+ * ----------------
+ */
+static int conninfo_parse(const char *conninfo, char *errorMessage)
+{
+    char *pname;
+    char *pval;
+    char *buf;
+    char *tmp;
+    char *cp;
+    char *cp2;
+    PQconninfoOption *option;
+    char errortmp[ERROR_MSG_LENGTH];
+
+    conninfo_free();
+
+    if((buf = strdup(conninfo)) == NULL) {
+        strcpy(errorMessage, 
+       "FATAL: cannot allocate memory for copy of conninfo string\n");
+        return -1;
+    }
+    cp = buf;
+
+    while(*cp) {
+   /* Skip blanks before the parameter name */
+        if(isspace(*cp)) {
+       cp++;
+       continue;
+   }
+
+   /* Get the parameter name */
+   pname = cp;
+   while(*cp) {
+       if(*cp == '=') {
+           break;
+       }
+       if(isspace(*cp)) {
+           *cp++ = '\0';
+       while(*cp) {
+           if(!isspace(*cp)) {
+               break;
+           }
+           cp++;
+       }
+       break;
+       }
+       cp++;
+   }
+
+   /* Check that there is a following '=' */
+   if(*cp != '=') {
+       sprintf(errorMessage,
+           "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
+       pname);
+       free(buf);
+       return -1;
+   }
+   *cp++ = '\0';
+
+   /* Skip blanks after the '=' */
+   while(*cp) {
+       if(!isspace(*cp)) {
+           break;
+       }
+       cp++;
+   }
+
+   pval = cp;
+
+   if(*cp != '\'') {
+       cp2 = pval;
+       while(*cp) {
+           if(isspace(*cp)) {
+           *cp++ = '\0';
+           break;
+       }
+       if(*cp == '\\') {
+           cp++;
+           if(*cp != '\0') {
+               *cp2++ = *cp++;
+           }
+       } else {
+           *cp2++ = *cp++;
+       }
+       }
+       *cp2  = '\0';
+   } else {
+       cp2 = pval;
+       cp++;
+       for(;;) {
+           if(*cp == '\0') {
+           sprintf(errorMessage,
+             "ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
+           free(buf);
+           return -1;
+       }
+       if(*cp == '\\') {
+           cp++;
+           if(*cp != '\0') {
+               *cp2++ = *cp++;
+           }
+           continue;
+       }
+       if(*cp == '\'') {
+           *cp2 = '\0';
+           cp++;
+           break;
+       }
+       *cp2++ = *cp++;
+       }
+   }
+
+        /* ----------
+    * Now we have the name and the value. Search
+    * for the param record.
+    * ----------
+    */
+        for(option = PQconninfoOptions; option->keyword != NULL; option++) {
+       if(!strcmp(option->keyword, pname)) {
+           break;
+       }
+   }
+   if(option->keyword == NULL) {
+       sprintf(errorMessage,
+           "ERROR: PQconnectdb() - unknown option '%s'\n",
+       pname);
+       free(buf);
+       return -1;
+   }
+
+   /* ----------
+    * Store the value
+    * ----------
+    */
+   option->val = strdup(pval);
+    }
+
+    free(buf);
+
+    /* ----------
+     * Get the fallback resources for parameters not specified
+     * in the conninfo string.
+     * ----------
+     */
+    for(option = PQconninfoOptions; option->keyword != NULL; option++) {
+   if(option->val != NULL)  continue;  /* Value was in conninfo */
+
+   /* ----------
+    * Try to get the environment variable fallback
+    * ----------
+    */
+   if(option->environ != NULL) {
+       if((tmp = getenv(option->environ)) != NULL) {
+           option->val = strdup(tmp);
+       continue;
+       }
+   }
+
+   /* ----------
+    * No environment variable specified or this one isn't set -
+    * try compiled in
+    * ----------
+    */
+   if(option->compiled != NULL) {
+       option->val = strdup(option->compiled);
+       continue;
+   }
+
+   /* ----------
+    * Special handling for user
+    * ----------
+    */
+   if(!strcmp(option->keyword, "user")) {
+       tmp = fe_getauthname(errortmp);
+       if (tmp) {
+           option->val = strdup(tmp);
+       }
+   }
+
+   /* ----------
+    * Special handling for dbname
+    * ----------
+    */
+   if(!strcmp(option->keyword, "dbname")) {
+       tmp = conninfo_getval("user");
+       if (tmp) {
+           option->val = strdup(tmp);
+       }
+   }
+    }
+
+    return 0;
+}
+
+
+static char*
+conninfo_getval(char *keyword)
+{
+    PQconninfoOption *option;
+
+    for(option = PQconninfoOptions; option->keyword != NULL; option++) {
+        if (!strcmp(option->keyword, keyword)) {
+       return option->val;
+   }
+    }
+
+    return NULL;
+}
+
+
+static void
+conninfo_free()
+{
+    PQconninfoOption *option;
+
+    for(option = PQconninfoOptions; option->keyword != NULL; option++) {
+        if(option->val != NULL) {
+       free(option->val);
+       option->val = NULL;
+   }
+    }
+}
+
 /* =========== accessor functions for PGconn ========= */
 char* 
 PQdb(PGconn* conn)
@@ -472,6 +883,16 @@ PQdb(PGconn* conn)
   return conn->dbName;
 }
 
+char* 
+PQuser(PGconn* conn)
+{
+  if (!conn) {
+    fprintf(stderr,"PQuser() -- pointer to PGconn is null");
+    return (char *)NULL;
+  }
+  return conn->pguser;
+}
+
 char* 
 PQhost(PGconn* conn)
 {
index 073b2cf52f081fecf6c9d9287ee1b98e33ef6b6c..bbf8021c598923a5ea7e7c2a913c1a210a8d5d5b 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: libpq-fe.h,v 1.9 1996/11/04 04:00:56 momjian Exp $
+ * $Id: libpq-fe.h,v 1.10 1996/11/09 10:39:54 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -146,8 +146,31 @@ struct _PQprintOpt {
 
 typedef struct _PQprintOpt PQprintOpt;
 
+/* ----------------
+ * Structure for the conninfo parameter definitions of PQconnectdb()
+ * ----------------
+ */
+struct _PQconninfoOption {
+    char   *keyword;   /* The keyword of the option        */
+    char   *environ;   /* Fallback environment variable name   */
+    char   *compiled;  /* Fallback compiled in default value   */
+    char   *val;       /* Options value            */
+    char   *label;     /* Label for field in connect dialog    */
+    char   *dispchar;  /* Character to display for this field  */
+               /* in a connect dialog. Values are: */
+                   /*    ""   Display entered value as is  */
+               /*    "*"  Password field - hide value  */
+               /*    "D"  Debug options - don't    */
+               /*         create a field by default    */
+    int        dispsize;   /* Field size in characters for dialog  */
+};
+
+typedef struct _PQconninfoOption PQconninfoOption;
+
 /* ===  in fe-connect.c === */
   /* make a new client connection to the backend */
+extern PGconn* PQconnectdb(const char* conninfo);
+extern PQconninfoOption *PQconndefaults();
 extern PGconn* PQsetdb(const char* pghost, const char* pgport, const char* pgoptions, 
               const char* pgtty, const char* dbName);
   /* close the current connection and free the PGconn data structure */
@@ -157,6 +180,7 @@ extern void PQfinish(PGconn* conn);
 extern void PQreset(PGconn* conn);
 
 extern char* PQdb(PGconn* conn);
+extern char* PQuser(PGconn* conn);
 extern char* PQhost(PGconn* conn);
 extern char* PQoptions(PGconn* conn);
 extern char* PQport(PGconn* conn);