LCOV - differential code coverage report
Current view: top level - src/bin/scripts - pg_isready.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 66.7 % 129 86 43 86
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 2 2 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * pg_isready --- checks the status of the PostgreSQL server
       4                 :  *
       5                 :  * Copyright (c) 2013-2023, PostgreSQL Global Development Group
       6                 :  *
       7                 :  * src/bin/scripts/pg_isready.c
       8                 :  *
       9                 :  *-------------------------------------------------------------------------
      10                 :  */
      11                 : 
      12                 : #include "postgres_fe.h"
      13                 : #include "common.h"
      14                 : #include "common/logging.h"
      15                 : #include "fe_utils/option_utils.h"
      16                 : 
      17                 : #define DEFAULT_CONNECT_TIMEOUT "3"
      18                 : 
      19                 : static void
      20                 :             help(const char *progname);
      21                 : 
      22                 : int
      23 CBC           5 : main(int argc, char **argv)
      24                 : {
      25                 :     int         c;
      26                 : 
      27                 :     const char *progname;
      28                 : 
      29               5 :     const char *pghost = NULL;
      30               5 :     const char *pgport = NULL;
      31               5 :     const char *pguser = NULL;
      32               5 :     const char *pgdbname = NULL;
      33               5 :     const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
      34                 : 
      35               5 :     const char *pghost_str = NULL;
      36               5 :     const char *pghostaddr_str = NULL;
      37               5 :     const char *pgport_str = NULL;
      38                 : 
      39                 : #define PARAMS_ARRAY_SIZE   7
      40                 : 
      41                 :     const char *keywords[PARAMS_ARRAY_SIZE];
      42                 :     const char *values[PARAMS_ARRAY_SIZE];
      43                 : 
      44               5 :     bool        quiet = false;
      45                 : 
      46                 :     PGPing      rv;
      47               5 :     PQconninfoOption *opts = NULL;
      48               5 :     PQconninfoOption *defs = NULL;
      49                 :     PQconninfoOption *opt;
      50                 :     PQconninfoOption *def;
      51               5 :     char       *errmsg = NULL;
      52                 : 
      53                 :     /*
      54                 :      * We accept user and database as options to avoid useless errors from
      55                 :      * connecting with invalid params
      56                 :      */
      57                 : 
      58                 :     static struct option long_options[] = {
      59                 :         {"dbname", required_argument, NULL, 'd'},
      60                 :         {"host", required_argument, NULL, 'h'},
      61                 :         {"port", required_argument, NULL, 'p'},
      62                 :         {"quiet", no_argument, NULL, 'q'},
      63                 :         {"timeout", required_argument, NULL, 't'},
      64                 :         {"username", required_argument, NULL, 'U'},
      65                 :         {NULL, 0, NULL, 0}
      66                 :     };
      67                 : 
      68               5 :     pg_logging_init(argv[0]);
      69               5 :     progname = get_progname(argv[0]);
      70               5 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
      71               5 :     handle_help_version_opts(argc, argv, progname, help);
      72                 : 
      73               4 :     while ((c = getopt_long(argc, argv, "d:h:p:qt:U:", long_options, NULL)) != -1)
      74                 :     {
      75               2 :         switch (c)
      76                 :         {
      77 UBC           0 :             case 'd':
      78               0 :                 pgdbname = pg_strdup(optarg);
      79               0 :                 break;
      80               0 :             case 'h':
      81               0 :                 pghost = pg_strdup(optarg);
      82               0 :                 break;
      83               0 :             case 'p':
      84               0 :                 pgport = pg_strdup(optarg);
      85               0 :                 break;
      86               0 :             case 'q':
      87               0 :                 quiet = true;
      88               0 :                 break;
      89 CBC           1 :             case 't':
      90               1 :                 connect_timeout = pg_strdup(optarg);
      91               1 :                 break;
      92 UBC           0 :             case 'U':
      93               0 :                 pguser = pg_strdup(optarg);
      94               0 :                 break;
      95 CBC           1 :             default:
      96                 :                 /* getopt_long already emitted a complaint */
      97               1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
      98                 : 
      99                 :                 /*
     100                 :                  * We need to make sure we don't return 1 here because someone
     101                 :                  * checking the return code might infer unintended meaning
     102                 :                  */
     103               1 :                 exit(PQPING_NO_ATTEMPT);
     104                 :         }
     105                 :     }
     106                 : 
     107               2 :     if (optind < argc)
     108                 :     {
     109 UBC           0 :         pg_log_error("too many command-line arguments (first is \"%s\")",
     110                 :                      argv[optind]);
     111               0 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     112                 : 
     113                 :         /*
     114                 :          * We need to make sure we don't return 1 here because someone
     115                 :          * checking the return code might infer unintended meaning
     116                 :          */
     117               0 :         exit(PQPING_NO_ATTEMPT);
     118                 :     }
     119                 : 
     120 CBC           2 :     keywords[0] = "host";
     121               2 :     values[0] = pghost;
     122               2 :     keywords[1] = "port";
     123               2 :     values[1] = pgport;
     124               2 :     keywords[2] = "user";
     125               2 :     values[2] = pguser;
     126               2 :     keywords[3] = "dbname";
     127               2 :     values[3] = pgdbname;
     128               2 :     keywords[4] = "connect_timeout";
     129               2 :     values[4] = connect_timeout;
     130               2 :     keywords[5] = "fallback_application_name";
     131               2 :     values[5] = progname;
     132               2 :     keywords[6] = NULL;
     133               2 :     values[6] = NULL;
     134                 : 
     135                 :     /*
     136                 :      * Get the host and port so we can display them in our output
     137                 :      */
     138               2 :     if (pgdbname &&
     139 UBC           0 :         (strncmp(pgdbname, "postgresql://", 13) == 0 ||
     140               0 :          strncmp(pgdbname, "postgres://", 11) == 0 ||
     141               0 :          strchr(pgdbname, '=') != NULL))
     142                 :     {
     143               0 :         opts = PQconninfoParse(pgdbname, &errmsg);
     144               0 :         if (opts == NULL)
     145                 :         {
     146               0 :             pg_log_error("%s", errmsg);
     147               0 :             exit(PQPING_NO_ATTEMPT);
     148                 :         }
     149                 :     }
     150                 : 
     151 CBC           2 :     defs = PQconndefaults();
     152               2 :     if (defs == NULL)
     153                 :     {
     154 UBC           0 :         pg_log_error("could not fetch default options");
     155               0 :         exit(PQPING_NO_ATTEMPT);
     156                 :     }
     157                 : 
     158 CBC          80 :     for (opt = opts, def = defs; def->keyword; def++)
     159                 :     {
     160              78 :         if (strcmp(def->keyword, "host") == 0)
     161                 :         {
     162               2 :             if (opt && opt->val)
     163 UBC           0 :                 pghost_str = opt->val;
     164 CBC           2 :             else if (pghost)
     165 UBC           0 :                 pghost_str = pghost;
     166 CBC           2 :             else if (def->val)
     167               2 :                 pghost_str = def->val;
     168                 :             else
     169 UBC           0 :                 pghost_str = DEFAULT_PGSOCKET_DIR;
     170                 :         }
     171 CBC          76 :         else if (strcmp(def->keyword, "hostaddr") == 0)
     172                 :         {
     173               2 :             if (opt && opt->val)
     174 UBC           0 :                 pghostaddr_str = opt->val;
     175 CBC           2 :             else if (def->val)
     176 UBC           0 :                 pghostaddr_str = def->val;
     177                 :         }
     178 CBC          74 :         else if (strcmp(def->keyword, "port") == 0)
     179                 :         {
     180               2 :             if (opt && opt->val)
     181 UBC           0 :                 pgport_str = opt->val;
     182 CBC           2 :             else if (pgport)
     183 UBC           0 :                 pgport_str = pgport;
     184 CBC           2 :             else if (def->val)
     185               2 :                 pgport_str = def->val;
     186                 :         }
     187                 : 
     188              78 :         if (opt)
     189 UBC           0 :             opt++;
     190                 :     }
     191                 : 
     192 CBC           2 :     rv = PQpingParams(keywords, values, 1);
     193                 : 
     194               2 :     if (!quiet)
     195                 :     {
     196               2 :         printf("%s:%s - ",
     197                 :                pghostaddr_str != NULL ? pghostaddr_str : pghost_str,
     198                 :                pgport_str);
     199                 : 
     200               2 :         switch (rv)
     201                 :         {
     202               1 :             case PQPING_OK:
     203               1 :                 printf(_("accepting connections\n"));
     204               1 :                 break;
     205 UBC           0 :             case PQPING_REJECT:
     206               0 :                 printf(_("rejecting connections\n"));
     207               0 :                 break;
     208 CBC           1 :             case PQPING_NO_RESPONSE:
     209               1 :                 printf(_("no response\n"));
     210               1 :                 break;
     211 UBC           0 :             case PQPING_NO_ATTEMPT:
     212               0 :                 printf(_("no attempt\n"));
     213               0 :                 break;
     214               0 :             default:
     215               0 :                 printf(_("unknown\n"));
     216                 :         }
     217                 :     }
     218                 : 
     219 CBC           2 :     exit(rv);
     220                 : }
     221                 : 
     222                 : static void
     223               1 : help(const char *progname)
     224                 : {
     225               1 :     printf(_("%s issues a connection check to a PostgreSQL database.\n\n"), progname);
     226               1 :     printf(_("Usage:\n"));
     227               1 :     printf(_("  %s [OPTION]...\n"), progname);
     228                 : 
     229               1 :     printf(_("\nOptions:\n"));
     230               1 :     printf(_("  -d, --dbname=DBNAME      database name\n"));
     231               1 :     printf(_("  -q, --quiet              run quietly\n"));
     232               1 :     printf(_("  -V, --version            output version information, then exit\n"));
     233               1 :     printf(_("  -?, --help               show this help, then exit\n"));
     234                 : 
     235               1 :     printf(_("\nConnection options:\n"));
     236               1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
     237               1 :     printf(_("  -p, --port=PORT          database server port\n"));
     238               1 :     printf(_("  -t, --timeout=SECS       seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT);
     239               1 :     printf(_("  -U, --username=USERNAME  user name to connect as\n"));
     240               1 :     printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     241               1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
     242               1 : }
        

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