On 01/26/2010 02:55 PM, Guillaume Lelarge wrote: > Le 26/01/2010 19:43, Joe Conway a écrit : >> On 01/25/2010 03:21 PM, Guillaume Lelarge wrote: >>> I didn't put any documentation before knowing which one will be choosen. >>> So we still need to work on the manual. >> >> Please send the documentation as a separate patch. Once I have that I >> will commit the posted patch, barring any objections in the meantime. > > You'll find it attached with this mail. Please read it carefully, my > written english is not that good.
Final committed patch attached. One last code correction -- in psql/startup.c the original patch defines the keywords array in the body of the code, rather than at the top of the block. Minor improvements ( hopefully ;-)) to the documentation as well. Joe
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.295
diff -c -r1.295 libpq.sgml
*** doc/src/sgml/libpq.sgml 21 Jan 2010 14:58:52 -0000 1.295
--- doc/src/sgml/libpq.sgml 28 Jan 2010 06:26:29 -0000
***************
*** 56,62 ****
one time. (One reason to do that is to access more than one
database.) Each connection is represented by a
<structname>PGconn</><indexterm><primary>PGconn</></> object, which
! is obtained from the function <function>PQconnectdb</> or
<function>PQsetdbLogin</>. Note that these functions will always
return a non-null object pointer, unless perhaps there is too
little memory even to allocate the <structname>PGconn</> object.
--- 56,63 ----
one time. (One reason to do that is to access more than one
database.) Each connection is represented by a
<structname>PGconn</><indexterm><primary>PGconn</></> object, which
! is obtained from the function <function>PQconnectdb</>,
! <function>PQconnectdbParams</>, or
<function>PQsetdbLogin</>. Note that these functions will always
return a non-null object pointer, unless perhaps there is too
little memory even to allocate the <structname>PGconn</> object.
***************
*** 91,125 ****
<variablelist>
<varlistentry>
! <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
<listitem>
<para>
Makes a new connection to the database server.
<synopsis>
! PGconn *PQconnectdb(const char *conninfo);
</synopsis>
</para>
<para>
This function opens a new database connection using the parameters taken
! from the string <literal>conninfo</literal>. Unlike <function>PQsetdbLogin</> below,
! the parameter set can be extended without changing the function signature,
! so use of this function (or its nonblocking analogues <function>PQconnectStart</>
! and <function>PQconnectPoll</function>) is preferred for new application programming.
</para>
<para>
! The passed string
! can be empty to use all default parameters, or it can contain one or more
! parameter settings separated by whitespace.
! Each parameter setting is in the form <literal>keyword = value</literal>.
! Spaces around the equal sign are optional.
! To write an empty value or a value containing
! spaces, surround it with single quotes, e.g.,
! <literal>keyword = 'a value'</literal>.
! Single quotes and backslashes within the value must be escaped with a
! backslash, i.e., <literal>\'</literal> and <literal>\\</literal>.
</para>
<para>
--- 92,124 ----
<variablelist>
<varlistentry>
! <term><function>PQconnectdbParams</function><indexterm><primary>PQconnectdbParams</></></term>
<listitem>
<para>
Makes a new connection to the database server.
<synopsis>
! PGconn *PQconnectdbParams(const char **keywords, const char **values);
</synopsis>
</para>
<para>
This function opens a new database connection using the parameters taken
! from two <symbol>NULL</symbol>-terminated arrays. The first,
! <literal>keywords</literal>, is defined as an array of strings, each one
! being a key word. The second, <literal>values</literal>, gives the value
! for each key word. Unlike <function>PQsetdbLogin</> below, the parameter
! set can be extended without changing the function signature, so use of
! this function (or its nonblocking analogs <function>PQconnectStartParams</>
! and <function>PQconnectPoll</function>) is preferred for new application
! programming.
</para>
<para>
! The passed arrays can be empty to use all default parameters, or can
! contain one or more parameter settings. They should be matched in length.
! Processing will stop with the last non-<symbol>NULL</symbol> element
! of the <literal>keywords</literal> array.
</para>
<para>
***************
*** 478,483 ****
--- 477,515 ----
</varlistentry>
<varlistentry>
+ <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
+ <listitem>
+ <para>
+ Makes a new connection to the database server.
+
+ <synopsis>
+ PGconn *PQconnectdb(const char *conninfo);
+ </synopsis>
+ </para>
+
+ <para>
+ This function opens a new database connection using the parameters taken
+ from the string <literal>conninfo</literal>.
+ </para>
+
+ <para>
+ The passed string can be empty to use all default parameters, or it can
+ contain one or more parameter settings separated by whitespace.
+ Each parameter setting is in the form <literal>keyword = value</literal>.
+ Spaces around the equal sign are optional. To write an empty value,
+ or a value containing spaces, surround it with single quotes, e.g.,
+ <literal>keyword = 'a value'</literal>. Single quotes and backslashes
+ within the value must be escaped with a backslash, i.e.,
+ <literal>\'</literal> and <literal>\\</literal>.
+ </para>
+
+ <para>
+ The currently recognized parameter key words are the same as above.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><function>PQsetdbLogin</function><indexterm><primary>PQsetdbLogin</></></term>
<listitem>
<para>
***************
*** 532,537 ****
--- 564,570 ----
</varlistentry>
<varlistentry>
+ <term><function>PQconnectStartParams</function><indexterm><primary>PQconnectStartParams</></></term>
<term><function>PQconnectStart</function><indexterm><primary>PQconnectStart</></></term>
<term><function>PQconnectPoll</function><indexterm><primary>PQconnectPoll</></></term>
<listitem>
***************
*** 540,545 ****
--- 573,582 ----
Make a connection to the database server in a nonblocking manner.
<synopsis>
+ PGconn *PQconnectStartParams(const char **keywords, const char **values);
+ </synopsis>
+
+ <synopsis>
PGconn *PQconnectStart(const char *conninfo);
</synopsis>
***************
*** 549,577 ****
</para>
<para>
! These two functions are used to open a connection to a database server such
that your application's thread of execution is not blocked on remote I/O
! whilst doing so.
! The point of this approach is that the waits for I/O to complete can occur
! in the application's main loop, rather than down inside
! <function>PQconnectdb</>, and so the application can manage this
! operation in parallel with other activities.
</para>
<para>
! The database connection is made using the parameters taken from the string
! <literal>conninfo</literal>, passed to <function>PQconnectStart</function>. This string is in
! the same format as described above for <function>PQconnectdb</function>.
</para>
<para>
! Neither <function>PQconnectStart</function> nor <function>PQconnectPoll</function> will block, so long as a number of
restrictions are met:
<itemizedlist>
<listitem>
<para>
The <literal>hostaddr</> and <literal>host</> parameters are used appropriately to ensure that
name and reverse name queries are not made. See the documentation of
! these parameters under <function>PQconnectdb</function> above for details.
</para>
</listitem>
--- 586,622 ----
</para>
<para>
! These three functions are used to open a connection to a database server such
that your application's thread of execution is not blocked on remote I/O
! whilst doing so. The point of this approach is that the waits for I/O to
! complete can occur in the application's main loop, rather than down inside
! <function>PQconnectdbParams</> or <function>PQconnectdb</>, and so the
! application can manage this operation in parallel with other activities.
</para>
<para>
! With <function>PQconnectStartParams</function>, the database connection is made
! using the parameters taken from the <literal>keywords</literal> and
! <literal>values</literal> arrays, as described above for
! <function>PQconnectdbParams</function>.
</para>
+
<para>
! With <function>PQconnectStart</function>, the database connection is made
! using the parameters taken from the string <literal>conninfo</literal> as
! described above for <function>PQconnectdb</function>.
! </para>
!
! <para>
! Neither <function>PQconnectStartParams</function> nor <function>PQconnectStart</function>
! nor <function>PQconnectPoll</function> will block, so long as a number of
restrictions are met:
<itemizedlist>
<listitem>
<para>
The <literal>hostaddr</> and <literal>host</> parameters are used appropriately to ensure that
name and reverse name queries are not made. See the documentation of
! these parameters under <function>PQconnectdbParams</function> above for details.
</para>
</listitem>
***************
*** 592,597 ****
--- 637,647 ----
</para>
<para>
+ Note: use of <function>PQconnectStartParams</> is analogous to
+ <function>PQconnectStart</> shown below.
+ </para>
+
+ <para>
To begin a nonblocking connection request, call <literal>conn = PQconnectStart("<replaceable>connection_info_string</>")</literal>.
If <varname>conn</varname> is null, then <application>libpq</> has been unable to allocate a new <structname>PGconn</>
structure. Otherwise, a valid <structname>PGconn</> pointer is returned (though not yet
***************
*** 883,889 ****
parameters previously used. This can be useful for error recovery if a
working connection is lost. They differ from <function>PQreset</function> (above) in that they
act in a nonblocking manner. These functions suffer from the same
! restrictions as <function>PQconnectStart</> and <function>PQconnectPoll</>.
</para>
<para>
--- 933,940 ----
parameters previously used. This can be useful for error recovery if a
working connection is lost. They differ from <function>PQreset</function> (above) in that they
act in a nonblocking manner. These functions suffer from the same
! restrictions as <function>PQconnectStartParams</>, <function>PQconnectStart</>
! and <function>PQconnectPoll</>.
</para>
<para>
***************
*** 1096,1104 ****
</para>
<para>
! See the entry for <function>PQconnectStart</> and <function>PQconnectPoll</> with regards
! to other status codes
! that might be seen.
</para>
</listitem>
</varlistentry>
--- 1147,1155 ----
</para>
<para>
! See the entry for <function>PQconnectStartParams</>, <function>PQconnectStart</>
! and <function>PQconnectPoll</> with regards to other status codes that
! might be seen.
</para>
</listitem>
</varlistentry>
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/startup.c,v
retrieving revision 1.158
diff -c -r1.158 startup.c
*** src/bin/psql/startup.c 2 Jan 2010 16:57:59 -0000 1.158
--- src/bin/psql/startup.c 28 Jan 2010 06:26:29 -0000
***************
*** 90,95 ****
--- 90,97 ----
char *password = NULL;
char *password_prompt = NULL;
bool new_pass;
+ const char *keywords[] = {"host","port","dbname","user",
+ "password","application_name",NULL};
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
***************
*** 171,181 ****
/* loop until we have a password if requested by backend */
do
{
! new_pass = false;
! pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL,
! options.action == ACT_LIST_DB && options.dbname == NULL ?
! "postgres" : options.dbname,
! options.username, password);
if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
--- 173,192 ----
/* loop until we have a password if requested by backend */
do
{
! const char *values[] = {
! options.host,
! options.port,
! (options.action == ACT_LIST_DB &&
! options.dbname == NULL) ? "postgres" : options.dbname,
! options.username,
! password,
! pset.progname,
! NULL
! };
!
! new_pass = false;
!
! pset.db = PQconnectdbParams(keywords, values);
if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
Index: src/interfaces/libpq/exports.txt
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/exports.txt,v
retrieving revision 1.24
diff -c -r1.24 exports.txt
*** src/interfaces/libpq/exports.txt 21 Jan 2010 14:58:53 -0000 1.24
--- src/interfaces/libpq/exports.txt 28 Jan 2010 06:26:29 -0000
***************
*** 155,157 ****
--- 155,159 ----
PQinitOpenSSL 153
PQescapeLiteral 154
PQescapeIdentifier 155
+ PQconnectdbParams 156
+ PQconnectStartParams 157
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.384
diff -c -r1.384 fe-connect.c
*** src/interfaces/libpq/fe-connect.c 20 Jan 2010 21:15:21 -0000 1.384
--- src/interfaces/libpq/fe-connect.c 28 Jan 2010 06:26:29 -0000
***************
*** 262,271 ****
--- 262,275 ----
static int connectDBStart(PGconn *conn);
static int connectDBComplete(PGconn *conn);
static PGconn *makeEmptyPGconn(void);
+ static void fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
static void freePGconn(PGconn *conn);
static void closePGconn(PGconn *conn);
static PQconninfoOption *conninfo_parse(const char *conninfo,
PQExpBuffer errorMessage, bool use_defaults);
+ static PQconninfoOption *conninfo_array_parse(const char **keywords,
+ const char **values, PQExpBuffer errorMessage,
+ bool use_defaults);
static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
static void defaultNoticeReceiver(void *arg, const PGresult *res);
***************
*** 290,312 ****
/*
* Connecting to a Database
*
! * There are now four different ways a user of this API can connect to the
* database. Two are not recommended for use in new code, because of their
* lack of extensibility with respect to the passing of options to the
* backend. These are PQsetdb and PQsetdbLogin (the former now being a macro
* to the latter).
*
* If it is desired to connect in a synchronous (blocking) manner, use the
! * function PQconnectdb.
*
* To connect in an asynchronous (non-blocking) manner, use the functions
! * PQconnectStart, and PQconnectPoll.
*
* Internally, the static functions connectDBStart, connectDBComplete
* are part of the connection procedure.
*/
/*
* PQconnectdb
*
* establishes a connection to a postgres backend through the postmaster
--- 294,353 ----
/*
* Connecting to a Database
*
! * There are now six different ways a user of this API can connect to the
* database. Two are not recommended for use in new code, because of their
* lack of extensibility with respect to the passing of options to the
* backend. These are PQsetdb and PQsetdbLogin (the former now being a macro
* to the latter).
*
* If it is desired to connect in a synchronous (blocking) manner, use the
! * function PQconnectdb or PQconnectdbParams. The former accepts a string
! * of option = value pairs which must be parsed; the latter takes two NULL
! * terminated arrays instead.
*
* To connect in an asynchronous (non-blocking) manner, use the functions
! * PQconnectStart or PQconnectStartParams (which differ in the same way as
! * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
*
* Internally, the static functions connectDBStart, connectDBComplete
* are part of the connection procedure.
*/
/*
+ * PQconnectdbParams
+ *
+ * establishes a connection to a postgres backend through the postmaster
+ * using connection information in two arrays.
+ *
+ * The keywords array is defined as
+ *
+ * const char *params[] = {"option1", "option2", NULL}
+ *
+ * The values array is defined as
+ *
+ * const char *values[] = {"value1", "value2", NULL}
+ *
+ * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
+ * if a memory allocation failed.
+ * If the status field of the connection returned is CONNECTION_BAD,
+ * then some fields may be null'ed out instead of having valid values.
+ *
+ * You should call PQfinish (if conn is not NULL) regardless of whether this
+ * call succeeded.
+ */
+ PGconn *
+ PQconnectdbParams(const char **keywords, const char **values)
+ {
+ PGconn *conn = PQconnectStartParams(keywords, values);
+
+ if (conn && conn->status != CONNECTION_BAD)
+ (void) connectDBComplete(conn);
+
+ return conn;
+
+ }
+
+ /*
* PQconnectdb
*
* establishes a connection to a postgres backend through the postmaster
***************
*** 340,351 ****
}
/*
! * PQconnectStart
*
* Begins the establishment of a connection to a postgres backend through the
! * postmaster using connection information in a string.
*
! * See comment for PQconnectdb for the definition of the string format.
*
* Returns a PGconn*. If NULL is returned, a malloc error has occurred, and
* you should not attempt to proceed with this connection. If the status
--- 381,392 ----
}
/*
! * PQconnectStartParams
*
* Begins the establishment of a connection to a postgres backend through the
! * postmaster using connection information in a struct.
*
! * See comment for PQconnectdbParams for the definition of the string format.
*
* Returns a PGconn*. If NULL is returned, a malloc error has occurred, and
* you should not attempt to proceed with this connection. If the status
***************
*** 359,367 ****
* See PQconnectPoll for more info.
*/
PGconn *
! PQconnectStart(const char *conninfo)
{
! PGconn *conn;
/*
* Allocate memory for the conn structure
--- 400,409 ----
* See PQconnectPoll for more info.
*/
PGconn *
! PQconnectStartParams(const char **keywords, const char **values)
{
! PGconn *conn;
! PQconninfoOption *connOptions;
/*
* Allocate memory for the conn structure
***************
*** 371,380 ****
return NULL;
/*
! * Parse the conninfo string
*/
! if (!connectOptions1(conn, conninfo))
! return conn;
/*
* Compute derived options
--- 413,438 ----
return NULL;
/*
! * Parse the conninfo arrays
*/
! connOptions = conninfo_array_parse(keywords, values,
! &conn->errorMessage, true);
! if (connOptions == NULL)
! {
! conn->status = CONNECTION_BAD;
! /* errorMessage is already set */
! return false;
! }
!
! /*
! * Move option values into conn structure
! */
! fillPGconn(conn, connOptions);
!
! /*
! * Free the option info - all is in conn now
! */
! PQconninfoFree(connOptions);
/*
* Compute derived options
***************
*** 395,427 ****
}
/*
! * connectOptions1
*
! * Internal subroutine to set up connection parameters given an already-
! * created PGconn and a conninfo string. Derived settings should be
! * processed by calling connectOptions2 next. (We split them because
! * PQsetdbLogin overrides defaults in between.)
*
! * Returns true if OK, false if trouble (in which case errorMessage is set
! * and so is conn->status).
*/
! static bool
! connectOptions1(PGconn *conn, const char *conninfo)
{
! PQconninfoOption *connOptions;
! char *tmp;
/*
* Parse the conninfo string
*/
! connOptions = conninfo_parse(conninfo, &conn->errorMessage, true);
! if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
- /* errorMessage is already set */
- return false;
}
/*
* Move option values into conn structure
*
--- 453,517 ----
}
/*
! * PQconnectStart
*
! * Begins the establishment of a connection to a postgres backend through the
! * postmaster using connection information in a string.
*
! * See comment for PQconnectdb for the definition of the string format.
! *
! * Returns a PGconn*. If NULL is returned, a malloc error has occurred, and
! * you should not attempt to proceed with this connection. If the status
! * field of the connection returned is CONNECTION_BAD, an error has
! * occurred. In this case you should call PQfinish on the result, (perhaps
! * inspecting the error message first). Other fields of the structure may not
! * be valid if that occurs. If the status field is not CONNECTION_BAD, then
! * this stage has succeeded - call PQconnectPoll, using select(2) to see when
! * this is necessary.
! *
! * See PQconnectPoll for more info.
*/
! PGconn *
! PQconnectStart(const char *conninfo)
{
! PGconn *conn;
!
! /*
! * Allocate memory for the conn structure
! */
! conn = makeEmptyPGconn();
! if (conn == NULL)
! return NULL;
/*
* Parse the conninfo string
*/
! if (!connectOptions1(conn, conninfo))
! return conn;
!
! /*
! * Compute derived options
! */
! if (!connectOptions2(conn))
! return conn;
!
! /*
! * Connect to the database
! */
! if (!connectDBStart(conn))
{
+ /* Just in case we failed to set it in connectDBStart */
conn->status = CONNECTION_BAD;
}
+ return conn;
+ }
+
+ static void
+ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
+ {
+ char *tmp;
+
/*
* Move option values into conn structure
*
***************
*** 482,487 ****
--- 572,610 ----
#endif
tmp = conninfo_getval(connOptions, "replication");
conn->replication = tmp ? strdup(tmp) : NULL;
+ }
+
+ /*
+ * connectOptions1
+ *
+ * Internal subroutine to set up connection parameters given an already-
+ * created PGconn and a conninfo string. Derived settings should be
+ * processed by calling connectOptions2 next. (We split them because
+ * PQsetdbLogin overrides defaults in between.)
+ *
+ * Returns true if OK, false if trouble (in which case errorMessage is set
+ * and so is conn->status).
+ */
+ static bool
+ connectOptions1(PGconn *conn, const char *conninfo)
+ {
+ PQconninfoOption *connOptions;
+
+ /*
+ * Parse the conninfo string
+ */
+ connOptions = conninfo_parse(conninfo, &conn->errorMessage, true);
+ if (connOptions == NULL)
+ {
+ conn->status = CONNECTION_BAD;
+ /* errorMessage is already set */
+ return false;
+ }
+
+ /*
+ * Move option values into conn structure
+ */
+ fillPGconn(conn, connOptions);
/*
* Free the option info - all is in conn now
***************
*** 3598,3603 ****
--- 3721,3869 ----
return options;
}
+ /*
+ * Conninfo array parser routine
+ *
+ * If successful, a malloc'd PQconninfoOption array is returned.
+ * If not successful, NULL is returned and an error message is
+ * left in errorMessage.
+ * Defaults are supplied (from a service file, environment variables, etc)
+ * for unspecified options, but only if use_defaults is TRUE.
+ */
+ static PQconninfoOption *
+ conninfo_array_parse(const char **keywords, const char **values,
+ PQExpBuffer errorMessage, bool use_defaults)
+ {
+ char *tmp;
+ PQconninfoOption *options;
+ PQconninfoOption *option;
+ int i = 0;
+
+ /* Make a working copy of PQconninfoOptions */
+ options = malloc(sizeof(PQconninfoOptions));
+ if (options == NULL)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("out of memory\n"));
+ return NULL;
+ }
+ memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+
+ /* Parse the keywords/values arrays */
+ while(keywords[i])
+ {
+ const char *pname = keywords[i];
+ const char *pvalue = values[i];
+
+ if (pvalue != NULL)
+ {
+ /* Search for the param record */
+ for (option = options; option->keyword != NULL; option++)
+ {
+ if (strcmp(option->keyword, pname) == 0)
+ break;
+ }
+
+ /* Check for invalid connection option */
+ if (option->keyword == NULL)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("invalid connection option \"%s\"\n"),
+ pname);
+ PQconninfoFree(options);
+ return NULL;
+ }
+
+ /*
+ * Store the value
+ */
+ if (option->val)
+ free(option->val);
+ option->val = strdup(pvalue);
+ if (!option->val)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("out of memory\n"));
+ PQconninfoFree(options);
+ return NULL;
+ }
+ }
+ ++i;
+ }
+
+ /*
+ * Stop here if caller doesn't want defaults filled in.
+ */
+ if (!use_defaults)
+ return options;
+
+ /*
+ * If there's a service spec, use it to obtain any not-explicitly-given
+ * parameters.
+ */
+ if (parseServiceInfo(options, errorMessage))
+ {
+ PQconninfoFree(options);
+ return NULL;
+ }
+
+ /*
+ * Get the fallback resources for parameters not specified in the conninfo
+ * string nor the service.
+ */
+ for (option = options; option->keyword != NULL; option++)
+ {
+ if (option->val != NULL)
+ continue; /* Value was in conninfo or service */
+
+ /*
+ * Try to get the environment variable fallback
+ */
+ if (option->envvar != NULL)
+ {
+ if ((tmp = getenv(option->envvar)) != NULL)
+ {
+ option->val = strdup(tmp);
+ if (!option->val)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("out of memory\n"));
+ PQconninfoFree(options);
+ return NULL;
+ }
+ continue;
+ }
+ }
+
+ /*
+ * No environment variable specified or this one isn't set - try
+ * compiled in
+ */
+ if (option->compiled != NULL)
+ {
+ option->val = strdup(option->compiled);
+ if (!option->val)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("out of memory\n"));
+ PQconninfoFree(options);
+ return NULL;
+ }
+ continue;
+ }
+
+ /*
+ * Special handling for user
+ */
+ if (strcmp(option->keyword, "user") == 0)
+ {
+ option->val = pg_fe_getauthname(errorMessage);
+ continue;
+ }
+ }
+
+ return options;
+ }
static char *
conninfo_getval(PQconninfoOption *connOptions,
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.149
diff -c -r1.149 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h 21 Jan 2010 14:58:53 -0000 1.149
--- src/interfaces/libpq/libpq-fe.h 28 Jan 2010 06:26:29 -0000
***************
*** 226,235 ****
--- 226,237 ----
/* make a new client connection to the backend */
/* Asynchronous (non-blocking) */
extern PGconn *PQconnectStart(const char *conninfo);
+ extern PGconn *PQconnectStartParams(const char **keywords, const char **values);
extern PostgresPollingStatusType PQconnectPoll(PGconn *conn);
/* Synchronous (blocking) */
extern PGconn *PQconnectdb(const char *conninfo);
+ extern PGconn *PQconnectdbParams(const char **keywords, const char **values);
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
const char *pgoptions, const char *pgtty,
const char *dbName,
signature.asc
Description: OpenPGP digital signature
