LCOV - differential code coverage report
Current view: top level - src/fe_utils - connect_utils.c (source / functions) Coverage Total Hit UNC UIC UBC GBC GIC GNC CBC EUB ECB DUB
Current: Differential Code Coverage HEAD vs 15 Lines: 72.6 % 62 45 1 6 10 1 13 31 4 14 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 3 3 2 1 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * Facilities for frontend code to connect to and disconnect from databases.
       4                 :  *
       5                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       6                 :  * Portions Copyright (c) 1994, Regents of the University of California
       7                 :  *
       8                 :  * src/fe_utils/connect_utils.c
       9                 :  *
      10                 :  *-------------------------------------------------------------------------
      11                 :  */
      12                 : #include "postgres_fe.h"
      13                 : 
      14                 : #include "common/connect.h"
      15                 : #include "common/logging.h"
      16                 : #include "common/string.h"
      17                 : #include "fe_utils/connect_utils.h"
      18                 : #include "fe_utils/query_utils.h"
      19                 : 
      20                 : /*
      21                 :  * Make a database connection with the given parameters.
      22                 :  *
      23                 :  * An interactive password prompt is automatically issued if needed and
      24                 :  * allowed by cparams->prompt_password.
      25                 :  *
      26                 :  * If allow_password_reuse is true, we will try to re-use any password
      27                 :  * given during previous calls to this routine.  (Callers should not pass
      28                 :  * allow_password_reuse=true unless reconnecting to the same database+user
      29                 :  * as before, else we might create password exposure hazards.)
      30                 :  */
      31                 : PGconn *
      32 CBC         245 : connectDatabase(const ConnParams *cparams, const char *progname,
      33                 :                 bool echo, bool fail_ok, bool allow_password_reuse)
      34                 : {
      35                 :     PGconn     *conn;
      36                 :     bool        new_pass;
      37                 :     static char *password = NULL;
      38                 : 
      39                 :     /* Callers must supply at least dbname; other params can be NULL */
      40             245 :     Assert(cparams->dbname);
      41                 : 
      42             245 :     if (!allow_password_reuse && password)
      43                 :     {
      44 UBC           0 :         free(password);
      45               0 :         password = NULL;
      46                 :     }
      47                 : 
      48 CBC         245 :     if (cparams->prompt_password == TRI_YES && password == NULL)
      49 UBC           0 :         password = simple_prompt("Password: ", false);
      50                 : 
      51                 :     /*
      52                 :      * Start the connection.  Loop until we have a password if requested by
      53                 :      * backend.
      54                 :      */
      55                 :     do
      56                 :     {
      57                 :         const char *keywords[8];
      58                 :         const char *values[8];
      59 CBC         245 :         int         i = 0;
      60                 : 
      61                 :         /*
      62                 :          * If dbname is a connstring, its entries can override the other
      63                 :          * values obtained from cparams; but in turn, override_dbname can
      64                 :          * override the dbname component of it.
      65                 :          */
      66             245 :         keywords[i] = "host";
      67             245 :         values[i++] = cparams->pghost;
      68             245 :         keywords[i] = "port";
      69             245 :         values[i++] = cparams->pgport;
      70             245 :         keywords[i] = "user";
      71             245 :         values[i++] = cparams->pguser;
      72             245 :         keywords[i] = "password";
      73             245 :         values[i++] = password;
      74             245 :         keywords[i] = "dbname";
      75             245 :         values[i++] = cparams->dbname;
      76             245 :         if (cparams->override_dbname)
      77                 :         {
      78              77 :             keywords[i] = "dbname";
      79              77 :             values[i++] = cparams->override_dbname;
      80                 :         }
      81             245 :         keywords[i] = "fallback_application_name";
      82             245 :         values[i++] = progname;
      83             245 :         keywords[i] = NULL;
      84             245 :         values[i++] = NULL;
      85             245 :         Assert(i <= lengthof(keywords));
      86                 : 
      87             245 :         new_pass = false;
      88             245 :         conn = PQconnectdbParams(keywords, values, true);
      89                 : 
      90             245 :         if (!conn)
      91 UBC           0 :             pg_fatal("could not connect to database %s: out of memory",
      92                 :                      cparams->dbname);
      93                 : 
      94                 :         /*
      95                 :          * No luck?  Trying asking (again) for a password.
      96                 :          */
      97 CBC         247 :         if (PQstatus(conn) == CONNECTION_BAD &&
      98               2 :             PQconnectionNeedsPassword(conn) &&
      99 UBC           0 :             cparams->prompt_password != TRI_NO)
     100                 :         {
     101               0 :             PQfinish(conn);
     102 UNC           0 :             free(password);
     103 UBC           0 :             password = simple_prompt("Password: ", false);
     104 UIC           0 :             new_pass = true;
     105 ECB             :         }
     106 GIC         245 :     } while (new_pass);
     107                 : 
     108 ECB             :     /* check to see that the backend connection was successfully made */
     109 GIC         245 :     if (PQstatus(conn) == CONNECTION_BAD)
     110 ECB             :     {
     111 GIC           2 :         if (fail_ok)
     112 EUB             :         {
     113 UBC           0 :             PQfinish(conn);
     114 UIC           0 :             return NULL;
     115 ECB             :         }
     116 GIC           2 :         pg_fatal("%s", PQerrorMessage(conn));
     117                 :     }
     118                 : 
     119 ECB             :     /* Start strict; callers may override this. */
     120 GIC         243 :     PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo));
     121 ECB             : 
     122 GIC         243 :     return conn;
     123                 : }
     124                 : 
     125                 : /*
     126                 :  * Try to connect to the appropriate maintenance database.
     127                 :  *
     128                 :  * This differs from connectDatabase only in that it has a rule for
     129                 :  * inserting a default "dbname" if none was given (which is why cparams
     130                 :  * is not const).  Note that cparams->dbname should typically come from
     131                 :  * a --maintenance-db command line parameter.
     132                 :  */
     133 ECB             : PGconn *
     134 GIC          86 : connectMaintenanceDatabase(ConnParams *cparams,
     135                 :                            const char *progname, bool echo)
     136                 : {
     137                 :     PGconn     *conn;
     138                 : 
     139 ECB             :     /* If a maintenance database name was specified, just connect to it. */
     140 GBC          86 :     if (cparams->dbname)
     141 UIC           0 :         return connectDatabase(cparams, progname, echo, false, false);
     142                 : 
     143 ECB             :     /* Otherwise, try postgres first and then template1. */
     144 CBC          86 :     cparams->dbname = "postgres";
     145              86 :     conn = connectDatabase(cparams, progname, echo, true, false);
     146 GIC          86 :     if (!conn)
     147 EUB             :     {
     148 UBC           0 :         cparams->dbname = "template1";
     149 UIC           0 :         conn = connectDatabase(cparams, progname, echo, false, false);
     150 ECB             :     }
     151 GIC          86 :     return conn;
     152                 : }
     153                 : 
     154                 : /*
     155                 :  * Disconnect the given connection, canceling any statement if one is active.
     156                 :  */
     157 ECB             : void
     158 GIC         158 : disconnectDatabase(PGconn *conn)
     159                 : {
     160                 :     char        errbuf[256];
     161 ECB             : 
     162 GIC         158 :     Assert(conn != NULL);
     163 ECB             : 
     164 GIC         158 :     if (PQtransactionStatus(conn) == PQTRANS_ACTIVE)
     165                 :     {
     166                 :         PGcancel   *cancel;
     167 EUB             : 
     168 UIC           0 :         if ((cancel = PQgetCancel(conn)))
     169 EUB             :         {
     170 UBC           0 :             (void) PQcancel(cancel, errbuf, sizeof(errbuf));
     171 UIC           0 :             PQfreeCancel(cancel);
     172                 :         }
     173                 :     }
     174 ECB             : 
     175 CBC         158 :     PQfinish(conn);
     176 GIC         158 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a