1/*-------------------------------------------------------------------------
2 *
3 * dropdb
4 *
5 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
7 *
8 * src/bin/scripts/dropdb.c
9 *
10 *-------------------------------------------------------------------------
11 */
12
13#include "postgres_fe.h"
14#include "common.h"
15#include "common/logging.h"
16#include "fe_utils/string_utils.h"
17
18
19static void help(const char *progname);
20
21
22int
23main(int argc, char *argv[])
24{
25 static int if_exists = 0;
26
27 static struct option long_options[] = {
28 {"host", required_argument, NULL, 'h'},
29 {"port", required_argument, NULL, 'p'},
30 {"username", required_argument, NULL, 'U'},
31 {"no-password", no_argument, NULL, 'w'},
32 {"password", no_argument, NULL, 'W'},
33 {"echo", no_argument, NULL, 'e'},
34 {"interactive", no_argument, NULL, 'i'},
35 {"if-exists", no_argument, &if_exists, 1},
36 {"maintenance-db", required_argument, NULL, 2},
37 {NULL, 0, NULL, 0}
38 };
39
40 const char *progname;
41 int optindex;
42 int c;
43
44 char *dbname = NULL;
45 char *maintenance_db = NULL;
46 char *host = NULL;
47 char *port = NULL;
48 char *username = NULL;
49 enum trivalue prompt_password = TRI_DEFAULT;
50 bool echo = false;
51 bool interactive = false;
52
53 PQExpBufferData sql;
54
55 PGconn *conn;
56 PGresult *result;
57
58 pg_logging_init(argv[0]);
59 progname = get_progname(argv[0]);
60 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
61
62 handle_help_version_opts(argc, argv, "dropdb", help);
63
64 while ((c = getopt_long(argc, argv, "h:p:U:wWei", long_options, &optindex)) != -1)
65 {
66 switch (c)
67 {
68 case 'h':
69 host = pg_strdup(optarg);
70 break;
71 case 'p':
72 port = pg_strdup(optarg);
73 break;
74 case 'U':
75 username = pg_strdup(optarg);
76 break;
77 case 'w':
78 prompt_password = TRI_NO;
79 break;
80 case 'W':
81 prompt_password = TRI_YES;
82 break;
83 case 'e':
84 echo = true;
85 break;
86 case 'i':
87 interactive = true;
88 break;
89 case 0:
90 /* this covers the long options */
91 break;
92 case 2:
93 maintenance_db = pg_strdup(optarg);
94 break;
95 default:
96 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
97 exit(1);
98 }
99 }
100
101 switch (argc - optind)
102 {
103 case 0:
104 pg_log_error("missing required argument database name");
105 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
106 exit(1);
107 case 1:
108 dbname = argv[optind];
109 break;
110 default:
111 pg_log_error("too many command-line arguments (first is \"%s\")",
112 argv[optind + 1]);
113 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
114 exit(1);
115 }
116
117 if (interactive)
118 {
119 printf(_("Database \"%s\" will be permanently removed.\n"), dbname);
120 if (!yesno_prompt("Are you sure?"))
121 exit(0);
122 }
123
124 initPQExpBuffer(&sql);
125
126 appendPQExpBuffer(&sql, "DROP DATABASE %s%s;",
127 (if_exists ? "IF EXISTS " : ""), fmtId(dbname));
128
129 /* Avoid trying to drop postgres db while we are connected to it. */
130 if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
131 maintenance_db = "template1";
132
133 conn = connectMaintenanceDatabase(maintenance_db,
134 host, port, username, prompt_password,
135 progname, echo);
136
137 if (echo)
138 printf("%s\n", sql.data);
139 result = PQexec(conn, sql.data);
140 if (PQresultStatus(result) != PGRES_COMMAND_OK)
141 {
142 pg_log_error("database removal failed: %s", PQerrorMessage(conn));
143 PQfinish(conn);
144 exit(1);
145 }
146
147 PQclear(result);
148 PQfinish(conn);
149 exit(0);
150}
151
152
153static void
154help(const char *progname)
155{
156 printf(_("%s removes a PostgreSQL database.\n\n"), progname);
157 printf(_("Usage:\n"));
158 printf(_(" %s [OPTION]... DBNAME\n"), progname);
159 printf(_("\nOptions:\n"));
160 printf(_(" -e, --echo show the commands being sent to the server\n"));
161 printf(_(" -i, --interactive prompt before deleting anything\n"));
162 printf(_(" -V, --version output version information, then exit\n"));
163 printf(_(" --if-exists don't report error if database doesn't exist\n"));
164 printf(_(" -?, --help show this help, then exit\n"));
165 printf(_("\nConnection options:\n"));
166 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
167 printf(_(" -p, --port=PORT database server port\n"));
168 printf(_(" -U, --username=USERNAME user name to connect as\n"));
169 printf(_(" -w, --no-password never prompt for password\n"));
170 printf(_(" -W, --password force password prompt\n"));
171 printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
172 printf(_("\nReport bugs to <pgsql-bugs@lists.postgresql.org>.\n"));
173}
174