00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "postgres_fe.h"
00013 #include "common.h"
00014 #include "dumputils.h"
00015
00016
00017 static void reindex_one_database(const char *name, const char *dbname,
00018 const char *type, const char *host,
00019 const char *port, const char *username,
00020 enum trivalue prompt_password, const char *progname,
00021 bool echo);
00022 static void reindex_all_databases(const char *maintenance_db,
00023 const char *host, const char *port,
00024 const char *username, enum trivalue prompt_password,
00025 const char *progname, bool echo,
00026 bool quiet);
00027 static void reindex_system_catalogs(const char *dbname,
00028 const char *host, const char *port,
00029 const char *username, enum trivalue prompt_password,
00030 const char *progname, bool echo);
00031 static void help(const char *progname);
00032
00033 int
00034 main(int argc, char *argv[])
00035 {
00036 static struct option long_options[] = {
00037 {"host", required_argument, NULL, 'h'},
00038 {"port", required_argument, NULL, 'p'},
00039 {"username", required_argument, NULL, 'U'},
00040 {"no-password", no_argument, NULL, 'w'},
00041 {"password", no_argument, NULL, 'W'},
00042 {"echo", no_argument, NULL, 'e'},
00043 {"quiet", no_argument, NULL, 'q'},
00044 {"dbname", required_argument, NULL, 'd'},
00045 {"all", no_argument, NULL, 'a'},
00046 {"system", no_argument, NULL, 's'},
00047 {"table", required_argument, NULL, 't'},
00048 {"index", required_argument, NULL, 'i'},
00049 {"maintenance-db", required_argument, NULL, 2},
00050 {NULL, 0, NULL, 0}
00051 };
00052
00053 const char *progname;
00054 int optindex;
00055 int c;
00056
00057 const char *dbname = NULL;
00058 const char *maintenance_db = NULL;
00059 const char *host = NULL;
00060 const char *port = NULL;
00061 const char *username = NULL;
00062 enum trivalue prompt_password = TRI_DEFAULT;
00063 bool syscatalog = false;
00064 bool alldb = false;
00065 bool echo = false;
00066 bool quiet = false;
00067 SimpleStringList indexes = {NULL, NULL};
00068 SimpleStringList tables = {NULL, NULL};
00069
00070 progname = get_progname(argv[0]);
00071 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
00072
00073 handle_help_version_opts(argc, argv, "reindexdb", help);
00074
00075
00076 while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:ast:i:", long_options, &optindex)) != -1)
00077 {
00078 switch (c)
00079 {
00080 case 'h':
00081 host = pg_strdup(optarg);
00082 break;
00083 case 'p':
00084 port = pg_strdup(optarg);
00085 break;
00086 case 'U':
00087 username = pg_strdup(optarg);
00088 break;
00089 case 'w':
00090 prompt_password = TRI_NO;
00091 break;
00092 case 'W':
00093 prompt_password = TRI_YES;
00094 break;
00095 case 'e':
00096 echo = true;
00097 break;
00098 case 'q':
00099 quiet = true;
00100 break;
00101 case 'd':
00102 dbname = pg_strdup(optarg);
00103 break;
00104 case 'a':
00105 alldb = true;
00106 break;
00107 case 's':
00108 syscatalog = true;
00109 break;
00110 case 't':
00111 simple_string_list_append(&tables, optarg);
00112 break;
00113 case 'i':
00114 simple_string_list_append(&indexes, optarg);
00115 break;
00116 case 2:
00117 maintenance_db = pg_strdup(optarg);
00118 break;
00119 default:
00120 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00121 exit(1);
00122 }
00123 }
00124
00125
00126
00127
00128
00129 if (optind < argc && dbname == NULL)
00130 {
00131 dbname = argv[optind];
00132 optind++;
00133 }
00134
00135 if (optind < argc)
00136 {
00137 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
00138 progname, argv[optind]);
00139 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00140 exit(1);
00141 }
00142
00143 setup_cancel_handler();
00144
00145 if (alldb)
00146 {
00147 if (dbname)
00148 {
00149 fprintf(stderr, _("%s: cannot reindex all databases and a specific one at the same time\n"), progname);
00150 exit(1);
00151 }
00152 if (syscatalog)
00153 {
00154 fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
00155 exit(1);
00156 }
00157 if (tables.head != NULL)
00158 {
00159 fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
00160 exit(1);
00161 }
00162 if (indexes.head != NULL)
00163 {
00164 fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
00165 exit(1);
00166 }
00167
00168 reindex_all_databases(maintenance_db, host, port, username,
00169 prompt_password, progname, echo, quiet);
00170 }
00171 else if (syscatalog)
00172 {
00173 if (tables.head != NULL)
00174 {
00175 fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
00176 exit(1);
00177 }
00178 if (indexes.head != NULL)
00179 {
00180 fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
00181 exit(1);
00182 }
00183
00184 if (dbname == NULL)
00185 {
00186 if (getenv("PGDATABASE"))
00187 dbname = getenv("PGDATABASE");
00188 else if (getenv("PGUSER"))
00189 dbname = getenv("PGUSER");
00190 else
00191 dbname = get_user_name(progname);
00192 }
00193
00194 reindex_system_catalogs(dbname, host, port, username, prompt_password,
00195 progname, echo);
00196 }
00197 else
00198 {
00199 if (dbname == NULL)
00200 {
00201 if (getenv("PGDATABASE"))
00202 dbname = getenv("PGDATABASE");
00203 else if (getenv("PGUSER"))
00204 dbname = getenv("PGUSER");
00205 else
00206 dbname = get_user_name(progname);
00207 }
00208
00209 if (indexes.head != NULL)
00210 {
00211 SimpleStringListCell *cell;
00212
00213 for (cell = indexes.head; cell; cell = cell->next)
00214 {
00215 reindex_one_database(cell->val, dbname, "INDEX", host, port,
00216 username, prompt_password, progname, echo);
00217 }
00218 }
00219 if (tables.head != NULL)
00220 {
00221 SimpleStringListCell *cell;
00222
00223 for (cell = tables.head; cell; cell = cell->next)
00224 {
00225 reindex_one_database(cell->val, dbname, "TABLE", host, port,
00226 username, prompt_password, progname, echo);
00227 }
00228 }
00229
00230 if (indexes.head == NULL && tables.head == NULL)
00231 reindex_one_database(dbname, dbname, "DATABASE", host, port,
00232 username, prompt_password, progname, echo);
00233 }
00234
00235 exit(0);
00236 }
00237
00238 static void
00239 reindex_one_database(const char *name, const char *dbname, const char *type,
00240 const char *host, const char *port, const char *username,
00241 enum trivalue prompt_password, const char *progname, bool echo)
00242 {
00243 PQExpBufferData sql;
00244
00245 PGconn *conn;
00246
00247 initPQExpBuffer(&sql);
00248
00249 appendPQExpBuffer(&sql, "REINDEX");
00250 if (strcmp(type, "TABLE") == 0)
00251 appendPQExpBuffer(&sql, " TABLE %s", name);
00252 else if (strcmp(type, "INDEX") == 0)
00253 appendPQExpBuffer(&sql, " INDEX %s", name);
00254 else if (strcmp(type, "DATABASE") == 0)
00255 appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
00256 appendPQExpBuffer(&sql, ";\n");
00257
00258 conn = connectDatabase(dbname, host, port, username, prompt_password,
00259 progname, false);
00260
00261 if (!executeMaintenanceCommand(conn, sql.data, echo))
00262 {
00263 if (strcmp(type, "TABLE") == 0)
00264 fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
00265 progname, name, dbname, PQerrorMessage(conn));
00266 if (strcmp(type, "INDEX") == 0)
00267 fprintf(stderr, _("%s: reindexing of index \"%s\" in database \"%s\" failed: %s"),
00268 progname, name, dbname, PQerrorMessage(conn));
00269 else
00270 fprintf(stderr, _("%s: reindexing of database \"%s\" failed: %s"),
00271 progname, dbname, PQerrorMessage(conn));
00272 PQfinish(conn);
00273 exit(1);
00274 }
00275
00276 PQfinish(conn);
00277 termPQExpBuffer(&sql);
00278 }
00279
00280 static void
00281 reindex_all_databases(const char *maintenance_db,
00282 const char *host, const char *port,
00283 const char *username, enum trivalue prompt_password,
00284 const char *progname, bool echo, bool quiet)
00285 {
00286 PGconn *conn;
00287 PGresult *result;
00288 int i;
00289
00290 conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
00291 prompt_password, progname);
00292 result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
00293 PQfinish(conn);
00294
00295 for (i = 0; i < PQntuples(result); i++)
00296 {
00297 char *dbname = PQgetvalue(result, i, 0);
00298
00299 if (!quiet)
00300 {
00301 printf(_("%s: reindexing database \"%s\"\n"), progname, dbname);
00302 fflush(stdout);
00303 }
00304
00305 reindex_one_database(dbname, dbname, "DATABASE", host, port, username,
00306 prompt_password, progname, echo);
00307 }
00308
00309 PQclear(result);
00310 }
00311
00312 static void
00313 reindex_system_catalogs(const char *dbname, const char *host, const char *port,
00314 const char *username, enum trivalue prompt_password,
00315 const char *progname, bool echo)
00316 {
00317 PQExpBufferData sql;
00318
00319 PGconn *conn;
00320
00321 initPQExpBuffer(&sql);
00322
00323 appendPQExpBuffer(&sql, "REINDEX SYSTEM %s;\n", dbname);
00324
00325 conn = connectDatabase(dbname, host, port, username, prompt_password,
00326 progname, false);
00327 if (!executeMaintenanceCommand(conn, sql.data, echo))
00328 {
00329 fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
00330 progname, PQerrorMessage(conn));
00331 PQfinish(conn);
00332 exit(1);
00333 }
00334 PQfinish(conn);
00335 termPQExpBuffer(&sql);
00336 }
00337
00338 static void
00339 help(const char *progname)
00340 {
00341 printf(_("%s reindexes a PostgreSQL database.\n\n"), progname);
00342 printf(_("Usage:\n"));
00343 printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
00344 printf(_("\nOptions:\n"));
00345 printf(_(" -a, --all reindex all databases\n"));
00346 printf(_(" -d, --dbname=DBNAME database to reindex\n"));
00347 printf(_(" -e, --echo show the commands being sent to the server\n"));
00348 printf(_(" -i, --index=INDEX recreate specific index(es) only\n"));
00349 printf(_(" -q, --quiet don't write any messages\n"));
00350 printf(_(" -s, --system reindex system catalogs\n"));
00351 printf(_(" -t, --table=TABLE reindex specific table(s) only\n"));
00352 printf(_(" -V, --version output version information, then exit\n"));
00353 printf(_(" -?, --help show this help, then exit\n"));
00354 printf(_("\nConnection options:\n"));
00355 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
00356 printf(_(" -p, --port=PORT database server port\n"));
00357 printf(_(" -U, --username=USERNAME user name to connect as\n"));
00358 printf(_(" -w, --no-password never prompt for password\n"));
00359 printf(_(" -W, --password force password prompt\n"));
00360 printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
00361 printf(_("\nRead the description of the SQL command REINDEX for details.\n"));
00362 printf(_("\nReport bugs to <[email protected]>.\n"));
00363 }