Skip to content

Commit e9ce658

Browse files
committed
Refactor to eliminate duplicate copies of conninfo default-finding code.
Alex Shulgin, lightly edited by me
1 parent 04dfc87 commit e9ce658

File tree

1 file changed

+84
-101
lines changed

1 file changed

+84
-101
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 84 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
121121
* fallback is available. If after all no value can be determined
122122
* for an option, an error is returned.
123123
*
124-
* The value for the username is treated specially in conninfo_parse.
125-
* If the Compiled-in resource is specified as a NULL value, the
126-
* user is determined by pg_fe_getauthname().
124+
* The value for the username is treated specially in conninfo_add_defaults.
125+
* If the value is not obtained any other way, the username is determined
126+
* by pg_fe_getauthname().
127127
*
128128
* The Label and Disp-Char entries are provided for applications that
129129
* want to use PQconndefaults() to create a generic database connection
@@ -292,11 +292,14 @@ static PGconn *makeEmptyPGconn(void);
292292
static void fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
293293
static void freePGconn(PGconn *conn);
294294
static void closePGconn(PGconn *conn);
295+
static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
295296
static PQconninfoOption *conninfo_parse(const char *conninfo,
296297
PQExpBuffer errorMessage, bool use_defaults);
297298
static PQconninfoOption *conninfo_array_parse(const char *const * keywords,
298299
const char *const * values, PQExpBuffer errorMessage,
299300
bool use_defaults, int expand_dbname);
301+
static bool conninfo_add_defaults(PQconninfoOption *options,
302+
PQExpBuffer errorMessage);
300303
static char *conninfo_getval(PQconninfoOption *connOptions,
301304
const char *keyword);
302305
static void defaultNoticeReceiver(void *arg, const PGresult *res);
@@ -813,10 +816,9 @@ connectOptions2(PGconn *conn)
813816
/*
814817
* PQconndefaults
815818
*
816-
* Parse an empty string like PQconnectdb() would do and return the
817-
* resulting connection options array, ie, all the default values that are
818-
* available from the environment etc. On error (eg out of memory),
819-
* NULL is returned.
819+
* Construct a default connection options array, which identifies all the
820+
* available options and shows any default values that are available from the
821+
* environment etc. On error (eg out of memory), NULL is returned.
820822
*
821823
* Using this function, an application may determine all possible options
822824
* and their current default values.
@@ -833,10 +835,21 @@ PQconndefaults(void)
833835
PQExpBufferData errorBuf;
834836
PQconninfoOption *connOptions;
835837

838+
/* We don't actually report any errors here, but callees want a buffer */
836839
initPQExpBuffer(&errorBuf);
837840
if (PQExpBufferDataBroken(errorBuf))
838841
return NULL; /* out of memory already :-( */
839-
connOptions = conninfo_parse("", &errorBuf, true);
842+
843+
connOptions = conninfo_init(&errorBuf);
844+
if (connOptions != NULL)
845+
{
846+
if (!conninfo_add_defaults(connOptions, &errorBuf))
847+
{
848+
PQconninfoFree(connOptions);
849+
connOptions = NULL;
850+
}
851+
}
852+
840853
termPQExpBuffer(&errorBuf);
841854
return connOptions;
842855
}
@@ -3986,6 +3999,25 @@ PQconninfoParse(const char *conninfo, char **errmsg)
39863999
return connOptions;
39874000
}
39884001

4002+
/*
4003+
* Build a working copy of the constant PQconninfoOptions array.
4004+
*/
4005+
static PQconninfoOption *
4006+
conninfo_init(PQExpBuffer errorMessage)
4007+
{
4008+
PQconninfoOption *options;
4009+
4010+
options = (PQconninfoOption *) malloc(sizeof(PQconninfoOptions));
4011+
if (options == NULL)
4012+
{
4013+
printfPQExpBuffer(errorMessage,
4014+
libpq_gettext("out of memory\n"));
4015+
return NULL;
4016+
}
4017+
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
4018+
return options;
4019+
}
4020+
39894021
/*
39904022
* Conninfo parser routine
39914023
*
@@ -4002,21 +4034,15 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
40024034
char *pname;
40034035
char *pval;
40044036
char *buf;
4005-
char *tmp;
40064037
char *cp;
40074038
char *cp2;
40084039
PQconninfoOption *options;
40094040
PQconninfoOption *option;
40104041

40114042
/* Make a working copy of PQconninfoOptions */
4012-
options = malloc(sizeof(PQconninfoOptions));
4043+
options = conninfo_init(errorMessage);
40134044
if (options == NULL)
4014-
{
4015-
printfPQExpBuffer(errorMessage,
4016-
libpq_gettext("out of memory\n"));
40174045
return NULL;
4018-
}
4019-
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
40204046

40214047
/* Need a modifiable copy of the input string */
40224048
if ((buf = strdup(conninfo)) == NULL)
@@ -4170,73 +4196,14 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
41704196
free(buf);
41714197

41724198
/*
4173-
* Stop here if caller doesn't want defaults filled in.
4174-
*/
4175-
if (!use_defaults)
4176-
return options;
4177-
4178-
/*
4179-
* If there's a service spec, use it to obtain any not-explicitly-given
4180-
* parameters.
4181-
*/
4182-
if (parseServiceInfo(options, errorMessage))
4183-
{
4184-
PQconninfoFree(options);
4185-
return NULL;
4186-
}
4187-
4188-
/*
4189-
* Get the fallback resources for parameters not specified in the conninfo
4190-
* string nor the service.
4199+
* Add in defaults if the caller wants that.
41914200
*/
4192-
for (option = options; option->keyword != NULL; option++)
4201+
if (use_defaults)
41934202
{
4194-
if (option->val != NULL)
4195-
continue; /* Value was in conninfo or service */
4196-
4197-
/*
4198-
* Try to get the environment variable fallback
4199-
*/
4200-
if (option->envvar != NULL)
4203+
if (!conninfo_add_defaults(options, errorMessage))
42014204
{
4202-
if ((tmp = getenv(option->envvar)) != NULL)
4203-
{
4204-
option->val = strdup(tmp);
4205-
if (!option->val)
4206-
{
4207-
printfPQExpBuffer(errorMessage,
4208-
libpq_gettext("out of memory\n"));
4209-
PQconninfoFree(options);
4210-
return NULL;
4211-
}
4212-
continue;
4213-
}
4214-
}
4215-
4216-
/*
4217-
* No environment variable specified or this one isn't set - try
4218-
* compiled in
4219-
*/
4220-
if (option->compiled != NULL)
4221-
{
4222-
option->val = strdup(option->compiled);
4223-
if (!option->val)
4224-
{
4225-
printfPQExpBuffer(errorMessage,
4226-
libpq_gettext("out of memory\n"));
4227-
PQconninfoFree(options);
4228-
return NULL;
4229-
}
4230-
continue;
4231-
}
4232-
4233-
/*
4234-
* Special handling for user
4235-
*/
4236-
if (strcmp(option->keyword, "user") == 0)
4237-
{
4238-
option->val = pg_fe_getauthname(errorMessage);
4239-
continue;
4205+
PQconninfoFree(options);
4206+
return NULL;
42404207
}
42414208
}
42424209

@@ -4262,7 +4229,6 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
42624229
PQExpBuffer errorMessage, bool use_defaults,
42634230
int expand_dbname)
42644231
{
4265-
char *tmp;
42664232
PQconninfoOption *options;
42674233
PQconninfoOption *str_options = NULL;
42684234
PQconninfoOption *option;
@@ -4298,18 +4264,15 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
42984264
}
42994265

43004266
/* Make a working copy of PQconninfoOptions */
4301-
options = malloc(sizeof(PQconninfoOptions));
4267+
options = conninfo_init(errorMessage);
43024268
if (options == NULL)
43034269
{
4304-
printfPQExpBuffer(errorMessage,
4305-
libpq_gettext("out of memory\n"));
43064270
PQconninfoFree(str_options);
43074271
return NULL;
43084272
}
4309-
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
43104273

4311-
i = 0;
43124274
/* Parse the keywords/values arrays */
4275+
i = 0;
43134276
while (keywords[i])
43144277
{
43154278
const char *pname = keywords[i];
@@ -4386,20 +4349,42 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
43864349
PQconninfoFree(str_options);
43874350

43884351
/*
4389-
* Stop here if caller doesn't want defaults filled in.
4352+
* Add in defaults if the caller wants that.
43904353
*/
4391-
if (!use_defaults)
4392-
return options;
4354+
if (use_defaults)
4355+
{
4356+
if (!conninfo_add_defaults(options, errorMessage))
4357+
{
4358+
PQconninfoFree(options);
4359+
return NULL;
4360+
}
4361+
}
4362+
4363+
return options;
4364+
}
4365+
4366+
/*
4367+
* Add the default values for any unspecified options to the connection
4368+
* options array.
4369+
*
4370+
* Defaults are obtained from a service file, environment variables, etc.
4371+
*
4372+
* Returns TRUE if successful, otherwise FALSE; errorMessage is filled in
4373+
* upon failure. Note that failure to locate a default value is not an
4374+
* error condition here --- we just leave the option's value as NULL.
4375+
*/
4376+
static bool
4377+
conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
4378+
{
4379+
PQconninfoOption *option;
4380+
char *tmp;
43934381

43944382
/*
43954383
* If there's a service spec, use it to obtain any not-explicitly-given
43964384
* parameters.
43974385
*/
4398-
if (parseServiceInfo(options, errorMessage))
4399-
{
4400-
PQconninfoFree(options);
4401-
return NULL;
4402-
}
4386+
if (parseServiceInfo(options, errorMessage) != 0)
4387+
return false;
44034388

44044389
/*
44054390
* Get the fallback resources for parameters not specified in the conninfo
@@ -4422,16 +4407,15 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44224407
{
44234408
printfPQExpBuffer(errorMessage,
44244409
libpq_gettext("out of memory\n"));
4425-
PQconninfoFree(options);
4426-
return NULL;
4410+
return false;
44274411
}
44284412
continue;
44294413
}
44304414
}
44314415

44324416
/*
4433-
* No environment variable specified or this one isn't set - try
4434-
* compiled in
4417+
* No environment variable specified or the variable isn't set - try
4418+
* compiled-in default
44354419
*/
44364420
if (option->compiled != NULL)
44374421
{
@@ -4440,14 +4424,13 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44404424
{
44414425
printfPQExpBuffer(errorMessage,
44424426
libpq_gettext("out of memory\n"));
4443-
PQconninfoFree(options);
4444-
return NULL;
4427+
return false;
44454428
}
44464429
continue;
44474430
}
44484431

44494432
/*
4450-
* Special handling for user
4433+
* Special handling for "user" option
44514434
*/
44524435
if (strcmp(option->keyword, "user") == 0)
44534436
{
@@ -4456,7 +4439,7 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44564439
}
44574440
}
44584441

4459-
return options;
4442+
return true;
44604443
}
44614444

44624445
static char *

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy