TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * createdb
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/bin/scripts/createdb.c
9 : *
10 : *-------------------------------------------------------------------------
11 : */
12 : #include "postgres_fe.h"
13 :
14 : #include "common.h"
15 : #include "common/logging.h"
16 : #include "fe_utils/option_utils.h"
17 : #include "fe_utils/string_utils.h"
18 :
19 :
20 : static void help(const char *progname);
21 :
22 :
23 : int
24 CBC 38 : main(int argc, char *argv[])
25 : {
26 : static struct option long_options[] = {
27 : {"host", required_argument, NULL, 'h'},
28 : {"port", required_argument, NULL, 'p'},
29 : {"username", required_argument, NULL, 'U'},
30 : {"no-password", no_argument, NULL, 'w'},
31 : {"password", no_argument, NULL, 'W'},
32 : {"echo", no_argument, NULL, 'e'},
33 : {"owner", required_argument, NULL, 'O'},
34 : {"tablespace", required_argument, NULL, 'D'},
35 : {"template", required_argument, NULL, 'T'},
36 : {"encoding", required_argument, NULL, 'E'},
37 : {"strategy", required_argument, NULL, 'S'},
38 : {"lc-collate", required_argument, NULL, 1},
39 : {"lc-ctype", required_argument, NULL, 2},
40 : {"locale", required_argument, NULL, 'l'},
41 : {"maintenance-db", required_argument, NULL, 3},
42 : {"locale-provider", required_argument, NULL, 4},
43 : {"icu-locale", required_argument, NULL, 5},
44 : {"icu-rules", required_argument, NULL, 6},
45 : {NULL, 0, NULL, 0}
46 : };
47 :
48 : const char *progname;
49 : int optindex;
50 : int c;
51 :
52 GIC 38 : const char *dbname = NULL;
53 CBC 38 : const char *maintenance_db = NULL;
54 38 : char *comment = NULL;
55 38 : char *host = NULL;
56 38 : char *port = NULL;
57 38 : char *username = NULL;
58 38 : enum trivalue prompt_password = TRI_DEFAULT;
59 ECB : ConnParams cparams;
60 GIC 38 : bool echo = false;
61 CBC 38 : char *owner = NULL;
62 38 : char *tablespace = NULL;
63 38 : char *template = NULL;
64 38 : char *encoding = NULL;
65 38 : char *strategy = NULL;
66 38 : char *lc_collate = NULL;
67 38 : char *lc_ctype = NULL;
68 38 : char *locale = NULL;
69 38 : char *locale_provider = NULL;
70 38 : char *icu_locale = NULL;
71 GNC 38 : char *icu_rules = NULL;
72 ECB :
73 : PQExpBufferData sql;
74 :
75 : PGconn *conn;
76 : PGresult *result;
77 :
78 GIC 38 : pg_logging_init(argv[0]);
79 38 : progname = get_progname(argv[0]);
80 CBC 38 : set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
81 ECB :
82 CBC 38 : handle_help_version_opts(argc, argv, "createdb", help);
83 :
84 GNC 78 : while ((c = getopt_long(argc, argv, "D:eE:h:l:O:p:S:T:U:wW", long_options, &optindex)) != -1)
85 : {
86 CBC 43 : switch (c)
87 : {
88 UNC 0 : case 'D':
89 0 : tablespace = pg_strdup(optarg);
90 0 : break;
91 0 : case 'e':
92 0 : echo = true;
93 0 : break;
94 GNC 6 : case 'E':
95 6 : encoding = pg_strdup(optarg);
96 6 : break;
97 LBC 0 : case 'h':
98 UIC 0 : host = pg_strdup(optarg);
99 UBC 0 : break;
100 GNC 3 : case 'l':
101 3 : locale = pg_strdup(optarg);
102 3 : break;
103 1 : case 'O':
104 1 : owner = pg_strdup(optarg);
105 1 : break;
106 UBC 0 : case 'p':
107 0 : port = pg_strdup(optarg);
108 0 : break;
109 GNC 3 : case 'S':
110 3 : strategy = pg_strdup(optarg);
111 3 : break;
112 12 : case 'T':
113 12 : template = pg_strdup(optarg);
114 12 : break;
115 GBC 6 : case 'U':
116 6 : username = pg_strdup(optarg);
117 CBC 6 : break;
118 LBC 0 : case 'w':
119 0 : prompt_password = TRI_NO;
120 UBC 0 : break;
121 0 : case 'W':
122 0 : prompt_password = TRI_YES;
123 LBC 0 : break;
124 GBC 1 : case 1:
125 1 : lc_collate = pg_strdup(optarg);
126 1 : break;
127 1 : case 2:
128 1 : lc_ctype = pg_strdup(optarg);
129 CBC 1 : break;
130 LBC 0 : case 3:
131 0 : maintenance_db = pg_strdup(optarg);
132 UBC 0 : break;
133 GBC 6 : case 4:
134 6 : locale_provider = pg_strdup(optarg);
135 CBC 6 : break;
136 3 : case 5:
137 3 : icu_locale = pg_strdup(optarg);
138 3 : break;
139 UNC 0 : case 6:
140 0 : icu_rules = pg_strdup(optarg);
141 0 : break;
142 CBC 1 : default:
143 ECB : /* getopt_long already emitted a complaint */
144 GBC 1 : pg_log_error_hint("Try \"%s --help\" for more information.", progname);
145 1 : exit(1);
146 EUB : }
147 ECB : }
148 :
149 CBC 35 : switch (argc - optind)
150 ECB : {
151 UIC 0 : case 0:
152 0 : break;
153 GIC 35 : case 1:
154 CBC 35 : dbname = argv[optind];
155 GIC 35 : break;
156 UBC 0 : case 2:
157 0 : dbname = argv[optind];
158 LBC 0 : comment = argv[optind + 1];
159 0 : break;
160 0 : default:
161 UBC 0 : pg_log_error("too many command-line arguments (first is \"%s\")",
162 EUB : argv[optind + 2]);
163 UBC 0 : pg_log_error_hint("Try \"%s --help\" for more information.", progname);
164 0 : exit(1);
165 EUB : }
166 :
167 GIC 35 : if (locale)
168 EUB : {
169 GBC 3 : if (!lc_ctype)
170 GIC 3 : lc_ctype = locale;
171 3 : if (!lc_collate)
172 CBC 3 : lc_collate = locale;
173 : }
174 ECB :
175 CBC 35 : if (encoding)
176 ECB : {
177 CBC 6 : if (pg_char_to_encoding(encoding) < 0)
178 GIC 1 : pg_fatal("\"%s\" is not a valid encoding name", encoding);
179 : }
180 ECB :
181 GIC 34 : if (dbname == NULL)
182 ECB : {
183 LBC 0 : if (getenv("PGDATABASE"))
184 UIC 0 : dbname = getenv("PGDATABASE");
185 0 : else if (getenv("PGUSER"))
186 LBC 0 : dbname = getenv("PGUSER");
187 : else
188 UBC 0 : dbname = get_user_name_or_exit(progname);
189 EUB : }
190 :
191 : /* No point in trying to use postgres db when creating postgres db. */
192 GIC 34 : if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
193 UBC 0 : maintenance_db = "template1";
194 :
195 GIC 34 : cparams.dbname = maintenance_db;
196 34 : cparams.pghost = host;
197 CBC 34 : cparams.pgport = port;
198 GBC 34 : cparams.pguser = username;
199 GIC 34 : cparams.prompt_password = prompt_password;
200 CBC 34 : cparams.override_dbname = NULL;
201 ECB :
202 CBC 34 : conn = connectMaintenanceDatabase(&cparams, progname, echo);
203 ECB :
204 CBC 34 : initPQExpBuffer(&sql);
205 ECB :
206 GIC 34 : appendPQExpBuffer(&sql, "CREATE DATABASE %s",
207 ECB : fmtId(dbname));
208 :
209 CBC 34 : if (owner)
210 GIC 1 : appendPQExpBuffer(&sql, " OWNER %s", fmtId(owner));
211 CBC 34 : if (tablespace)
212 UIC 0 : appendPQExpBuffer(&sql, " TABLESPACE %s", fmtId(tablespace));
213 GIC 34 : if (encoding)
214 ECB : {
215 CBC 5 : appendPQExpBufferStr(&sql, " ENCODING ");
216 5 : appendStringLiteralConn(&sql, encoding, conn);
217 EUB : }
218 CBC 34 : if (strategy)
219 GIC 3 : appendPQExpBuffer(&sql, " STRATEGY %s", fmtId(strategy));
220 CBC 34 : if (template)
221 12 : appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
222 GIC 34 : if (lc_collate)
223 ECB : {
224 CBC 4 : appendPQExpBufferStr(&sql, " LC_COLLATE ");
225 4 : appendStringLiteralConn(&sql, lc_collate, conn);
226 ECB : }
227 CBC 34 : if (lc_ctype)
228 : {
229 4 : appendPQExpBufferStr(&sql, " LC_CTYPE ");
230 4 : appendStringLiteralConn(&sql, lc_ctype, conn);
231 : }
232 34 : if (locale_provider)
233 GIC 6 : appendPQExpBuffer(&sql, " LOCALE_PROVIDER %s", locale_provider);
234 CBC 34 : if (icu_locale)
235 ECB : {
236 GIC 3 : appendPQExpBufferStr(&sql, " ICU_LOCALE ");
237 CBC 3 : appendStringLiteralConn(&sql, icu_locale, conn);
238 ECB : }
239 GNC 34 : if (icu_rules)
240 : {
241 UNC 0 : appendPQExpBufferStr(&sql, " ICU_RULES ");
242 0 : appendStringLiteralConn(&sql, icu_rules, conn);
243 : }
244 ECB :
245 GIC 34 : appendPQExpBufferChar(&sql, ';');
246 ECB :
247 CBC 34 : if (echo)
248 UIC 0 : printf("%s\n", sql.data);
249 CBC 34 : result = PQexec(conn, sql.data);
250 :
251 GBC 34 : if (PQresultStatus(result) != PGRES_COMMAND_OK)
252 EUB : {
253 GIC 8 : pg_log_error("database creation failed: %s", PQerrorMessage(conn));
254 8 : PQfinish(conn);
255 CBC 8 : exit(1);
256 : }
257 ECB :
258 GBC 26 : PQclear(result);
259 ECB :
260 GIC 26 : if (comment)
261 ECB : {
262 UIC 0 : printfPQExpBuffer(&sql, "COMMENT ON DATABASE %s IS ", fmtId(dbname));
263 LBC 0 : appendStringLiteralConn(&sql, comment, conn);
264 0 : appendPQExpBufferChar(&sql, ';');
265 ECB :
266 UIC 0 : if (echo)
267 0 : printf("%s\n", sql.data);
268 LBC 0 : result = PQexec(conn, sql.data);
269 :
270 0 : if (PQresultStatus(result) != PGRES_COMMAND_OK)
271 : {
272 UBC 0 : pg_log_error("comment creation failed (database was created): %s",
273 EUB : PQerrorMessage(conn));
274 UBC 0 : PQfinish(conn);
275 UIC 0 : exit(1);
276 EUB : }
277 :
278 UBC 0 : PQclear(result);
279 : }
280 EUB :
281 GIC 26 : PQfinish(conn);
282 EUB :
283 GIC 26 : exit(0);
284 EUB : }
285 :
286 :
287 : static void
288 GBC 1 : help(const char *progname)
289 : {
290 GIC 1 : printf(_("%s creates a PostgreSQL database.\n\n"), progname);
291 CBC 1 : printf(_("Usage:\n"));
292 GIC 1 : printf(_(" %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
293 CBC 1 : printf(_("\nOptions:\n"));
294 GIC 1 : printf(_(" -D, --tablespace=TABLESPACE default tablespace for the database\n"));
295 1 : printf(_(" -e, --echo show the commands being sent to the server\n"));
296 1 : printf(_(" -E, --encoding=ENCODING encoding for the database\n"));
297 1 : printf(_(" -l, --locale=LOCALE locale settings for the database\n"));
298 CBC 1 : printf(_(" --lc-collate=LOCALE LC_COLLATE setting for the database\n"));
299 GIC 1 : printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
300 CBC 1 : printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
301 GNC 1 : printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
302 CBC 1 : printf(_(" --locale-provider={libc|icu}\n"
303 ECB : " locale provider for the database's default collation\n"));
304 CBC 1 : printf(_(" -O, --owner=OWNER database user to own the new database\n"));
305 1 : printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
306 1 : printf(_(" -T, --template=TEMPLATE template database to copy\n"));
307 1 : printf(_(" -V, --version output version information, then exit\n"));
308 1 : printf(_(" -?, --help show this help, then exit\n"));
309 1 : printf(_("\nConnection options:\n"));
310 1 : printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
311 1 : printf(_(" -p, --port=PORT database server port\n"));
312 1 : printf(_(" -U, --username=USERNAME user name to connect as\n"));
313 1 : printf(_(" -w, --no-password never prompt for password\n"));
314 GIC 1 : printf(_(" -W, --password force password prompt\n"));
315 CBC 1 : printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
316 1 : printf(_("\nBy default, a database with the same name as the current user is created.\n"));
317 1 : printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
318 1 : printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
319 1 : }
|