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