You've already forked pg_probackup
mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-11-30 23:35:06 +02:00
Code cleanup. Parse subcmd before options
This commit is contained in:
127
pg_probackup.c
127
pg_probackup.c
@@ -84,6 +84,14 @@ static pgut_option options[] =
|
||||
{ 'u', 14, "window", &retention_window, SOURCE_CMDLINE },
|
||||
/* other */
|
||||
{ 'U', 15, "system-identifier", &system_identifier, SOURCE_FILE_STRICT },
|
||||
|
||||
{ 's', 'd', "dbname" , &pgut_dbname, SOURCE_CMDLINE },
|
||||
{ 's', 'h', "host" , &host, SOURCE_CMDLINE },
|
||||
{ 's', 'p', "port" , &port, SOURCE_CMDLINE },
|
||||
{ 'b', 'q', "quiet" , &quiet, SOURCE_CMDLINE },
|
||||
{ 's', 'U', "username" , &username, SOURCE_CMDLINE },
|
||||
{ 'b', 'v', "verbose" , &verbose, SOURCE_CMDLINE },
|
||||
{ 'B', 'w', "no-password" , &prompt_password, SOURCE_CMDLINE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -93,53 +101,50 @@ static pgut_option options[] =
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *cmd = NULL,
|
||||
*subcmd = NULL;
|
||||
const char *backup_id_string = NULL;
|
||||
ProbackupSubcmd backup_subcmd;
|
||||
time_t backup_id = 0;
|
||||
int i;
|
||||
|
||||
/* do not buffer progress messages */
|
||||
setvbuf(stdout, 0, _IONBF, 0); /* TODO: remove this */
|
||||
|
||||
/* initialize configuration */
|
||||
init_backup(¤t);
|
||||
|
||||
/* overwrite configuration with command line arguments */
|
||||
i = pgut_getopt(argc, argv, options);
|
||||
PROGRAM_NAME = get_progname(argv[0]);
|
||||
set_pglocale_pgservice(argv[0], "pgscripts");
|
||||
|
||||
for (; i < argc; i++)
|
||||
/* Parse subcommands and non-subcommand options */
|
||||
if (argc > 1)
|
||||
{
|
||||
if (cmd == NULL)
|
||||
cmd = argv[i];
|
||||
else if (strcmp(cmd, "retention") == 0)
|
||||
subcmd = argv[i];
|
||||
else if (backup_id_string == NULL &&
|
||||
(strcmp(cmd, "show") == 0 ||
|
||||
strcmp(cmd, "validate") == 0 ||
|
||||
strcmp(cmd, "delete") == 0 ||
|
||||
strcmp(cmd, "restore") == 0 ||
|
||||
strcmp(cmd, "delwal") == 0))
|
||||
backup_id_string = argv[i];
|
||||
else
|
||||
elog(ERROR, "too many arguments");
|
||||
}
|
||||
|
||||
/* command argument (backup/restore/show/...) is required. */
|
||||
if (cmd == NULL)
|
||||
{
|
||||
help(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (backup_id_string != NULL)
|
||||
{
|
||||
backup_id = base36dec(backup_id_string);
|
||||
if (backup_id == 0) {
|
||||
elog(ERROR, "wrong ID");
|
||||
if (strcmp(argv[1], "init") == 0)
|
||||
backup_subcmd = INIT;
|
||||
else if (strcmp(argv[1], "backup") == 0)
|
||||
backup_subcmd = BACKUP;
|
||||
else if (strcmp(argv[1], "restore") == 0)
|
||||
backup_subcmd = RESTORE;
|
||||
else if (strcmp(argv[1], "validate") == 0)
|
||||
backup_subcmd = VALIDATE;
|
||||
else if (strcmp(argv[1], "show") == 0)
|
||||
backup_subcmd = SHOW;
|
||||
else if (strcmp(argv[1], "delete") == 0)
|
||||
backup_subcmd = DELETE;
|
||||
else if (strcmp(argv[1], "configure") == 0)
|
||||
backup_subcmd = CONFIGURE;
|
||||
else if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
|
||||
{
|
||||
help(true);
|
||||
exit(0);
|
||||
}
|
||||
else if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
||||
{
|
||||
fprintf(stderr, "%s %s\n", PROGRAM_NAME, PROGRAM_VERSION);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
elog(ERROR, "Invalid subcommand");
|
||||
}
|
||||
|
||||
/* Parse command line arguments */
|
||||
i = pgut_getopt(argc, argv, options);
|
||||
|
||||
/* BACKUP_PATH is always required */
|
||||
if (backup_path == NULL)
|
||||
elog(ERROR, "required parameter not specified: BACKUP_PATH (-B, --backup-path)");
|
||||
@@ -189,39 +194,41 @@ main(int argc, char *argv[])
|
||||
num_threads = 1;
|
||||
|
||||
/* do actual operation */
|
||||
if (pg_strcasecmp(cmd, "init") == 0)
|
||||
return do_init();
|
||||
else if (pg_strcasecmp(cmd, "backup") == 0)
|
||||
return do_backup(smooth_checkpoint);
|
||||
else if (pg_strcasecmp(cmd, "restore") == 0)
|
||||
return do_restore(backup_id,
|
||||
switch (backup_subcmd)
|
||||
{
|
||||
case INIT:
|
||||
return do_init();
|
||||
case BACKUP:
|
||||
return do_backup(smooth_checkpoint);
|
||||
case RESTORE:
|
||||
return do_restore(backup_id,
|
||||
target_time,
|
||||
target_xid,
|
||||
target_inclusive,
|
||||
target_tli);
|
||||
else if (pg_strcasecmp(cmd, "show") == 0)
|
||||
return do_show(backup_id);
|
||||
else if (pg_strcasecmp(cmd, "validate") == 0)
|
||||
return do_validate(backup_id,
|
||||
case VALIDATE:
|
||||
return do_validate(backup_id,
|
||||
target_time,
|
||||
target_xid,
|
||||
target_inclusive,
|
||||
target_tli);
|
||||
else if (pg_strcasecmp(cmd, "delete") == 0)
|
||||
return do_delete(backup_id);
|
||||
else if (pg_strcasecmp(cmd, "delwal") == 0)
|
||||
return do_deletewal(backup_id, true, true);
|
||||
else if (pg_strcasecmp(cmd, "retention") == 0)
|
||||
{
|
||||
if (subcmd == NULL)
|
||||
elog(ERROR, "you must specify retention command");
|
||||
else if (pg_strcasecmp(subcmd, "show") == 0)
|
||||
return do_retention_show();
|
||||
else if (pg_strcasecmp(subcmd, "purge") == 0)
|
||||
return do_retention_purge();
|
||||
case SHOW:
|
||||
return do_show(backup_id);
|
||||
case DELETE:
|
||||
return do_delete(backup_id);
|
||||
case CONFIGURE:
|
||||
elog(ERROR, "not implemented yet");
|
||||
}
|
||||
else
|
||||
elog(ERROR, "invalid command \"%s\"", cmd);
|
||||
|
||||
// if (pg_strcasecmp(cmd, "retention") == 0)
|
||||
// {
|
||||
// if (subcmd == NULL)
|
||||
// elog(ERROR, "you must specify retention command");
|
||||
// else if (pg_strcasecmp(subcmd, "show") == 0)
|
||||
// return do_retention_show();
|
||||
// else if (pg_strcasecmp(subcmd, "purge") == 0)
|
||||
// return do_retention_purge();
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,17 @@ typedef enum BackupMode
|
||||
BACKUP_MODE_FULL /* full backup */
|
||||
} BackupMode;
|
||||
|
||||
typedef enum ProbackupSubcmd
|
||||
{
|
||||
INIT = 0,
|
||||
BACKUP,
|
||||
RESTORE,
|
||||
VALIDATE,
|
||||
SHOW,
|
||||
DELETE,
|
||||
CONFIGURE
|
||||
} ProbackupSubcmd;
|
||||
|
||||
|
||||
/* special values of pgBackup fields */
|
||||
#define KEEP_INFINITE (INT_MAX)
|
||||
|
||||
63
pgut/pgut.c
63
pgut/pgut.c
@@ -65,18 +65,6 @@ static void on_cleanup(void);
|
||||
static void exit_or_abort(int exitcode);
|
||||
static const char *get_username(void);
|
||||
|
||||
static pgut_option default_options[] =
|
||||
{
|
||||
{ 's', 'd', "dbname" , &pgut_dbname, SOURCE_CMDLINE },
|
||||
{ 's', 'h', "host" , &host, SOURCE_CMDLINE },
|
||||
{ 's', 'p', "port" , &port, SOURCE_CMDLINE },
|
||||
{ 'b', 'q', "quiet" , &quiet, SOURCE_CMDLINE },
|
||||
{ 's', 'U', "username" , &username, SOURCE_CMDLINE },
|
||||
{ 'b', 'v', "verbose" , &verbose, SOURCE_CMDLINE },
|
||||
{ 'B', 'w', "no-password" , &prompt_password, SOURCE_CMDLINE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static size_t
|
||||
option_length(const pgut_option opts[])
|
||||
{
|
||||
@@ -112,33 +100,14 @@ option_copy(struct option dst[], const pgut_option opts[], size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
static struct option *
|
||||
option_merge(const pgut_option opts1[], const pgut_option opts2[])
|
||||
{
|
||||
struct option *result;
|
||||
size_t len1 = option_length(opts1);
|
||||
size_t len2 = option_length(opts2);
|
||||
size_t n = len1 + len2;
|
||||
|
||||
result = pgut_newarray(struct option, n + 1);
|
||||
option_copy(result, opts1, len1);
|
||||
option_copy(result + len1, opts2, len2);
|
||||
memset(&result[n], 0, sizeof(pgut_option));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static pgut_option *
|
||||
option_find(int c, pgut_option opts1[], pgut_option opts2[])
|
||||
option_find(int c, pgut_option opts1[])
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; opts1 && opts1[i].type; i++)
|
||||
if (opts1[i].sname == c)
|
||||
return &opts1[i];
|
||||
for (i = 0; opts2 && opts2[i].type; i++)
|
||||
if (opts2[i].sname == c)
|
||||
return &opts2[i];
|
||||
|
||||
return NULL; /* not found */
|
||||
}
|
||||
@@ -572,38 +541,20 @@ pgut_getopt(int argc, char **argv, pgut_option options[])
|
||||
int c;
|
||||
int optindex = 0;
|
||||
char *optstring;
|
||||
struct option *longopts;
|
||||
pgut_option *opt;
|
||||
struct option *longopts;
|
||||
size_t len1;
|
||||
|
||||
if (PROGRAM_NAME == NULL)
|
||||
{
|
||||
PROGRAM_NAME = get_progname(argv[0]);
|
||||
set_pglocale_pgservice(argv[0], "pgscripts");
|
||||
}
|
||||
len1 = option_length(options);
|
||||
longopts = pgut_newarray(struct option, len1 + 1);
|
||||
option_copy(longopts, options, len1);
|
||||
|
||||
/* Help message and version are handled at first. */
|
||||
if (argc > 1)
|
||||
{
|
||||
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
|
||||
{
|
||||
help(true);
|
||||
exit_or_abort(0);
|
||||
}
|
||||
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
||||
{
|
||||
fprintf(stderr, "%s %s\n", PROGRAM_NAME, PROGRAM_VERSION);
|
||||
exit_or_abort(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge default and user options. */
|
||||
longopts = option_merge(default_options, options);
|
||||
optstring = longopts_to_optstring(longopts);
|
||||
|
||||
/* Assign named options */
|
||||
while ((c = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1)
|
||||
{
|
||||
opt = option_find(c, default_options, options);
|
||||
opt = option_find(c, options);
|
||||
if (opt && opt->allowed < SOURCE_CMDLINE)
|
||||
elog(ERROR, "option %s cannot be specified in command line",
|
||||
opt->lname);
|
||||
|
||||
@@ -85,6 +85,7 @@ extern const char *username;
|
||||
extern char *password;
|
||||
extern bool verbose;
|
||||
extern bool quiet;
|
||||
extern bool prompt_password;
|
||||
|
||||
extern bool interrupted;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user