PageRenderTime 44ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/bin/scripts/clusterdb.c

https://github.com/matheusoliveira/postgres
C | 282 lines | 233 code | 35 blank | 14 comment | 25 complexity | efcabd6e585bbb10b355242510592c9c MD5 | raw file
Possible License(s): AGPL-3.0
  1. /*-------------------------------------------------------------------------
  2. *
  3. * clusterdb
  4. *
  5. * Portions Copyright (c) 2002-2014, PostgreSQL Global Development Group
  6. *
  7. * src/bin/scripts/clusterdb.c
  8. *
  9. *-------------------------------------------------------------------------
  10. */
  11. #include "postgres_fe.h"
  12. #include "common.h"
  13. #include "dumputils.h"
  14. static void cluster_one_database(const char *dbname, bool verbose, const char *table,
  15. const char *host, const char *port,
  16. const char *username, enum trivalue prompt_password,
  17. const char *progname, bool echo);
  18. static void cluster_all_databases(bool verbose, const char *maintenance_db,
  19. const char *host, const char *port,
  20. const char *username, enum trivalue prompt_password,
  21. const char *progname, bool echo, bool quiet);
  22. static void help(const char *progname);
  23. int
  24. 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. {"quiet", no_argument, NULL, 'q'},
  34. {"dbname", required_argument, NULL, 'd'},
  35. {"all", no_argument, NULL, 'a'},
  36. {"table", required_argument, NULL, 't'},
  37. {"verbose", no_argument, NULL, 'v'},
  38. {"maintenance-db", required_argument, NULL, 2},
  39. {NULL, 0, NULL, 0}
  40. };
  41. const char *progname;
  42. int optindex;
  43. int c;
  44. const char *dbname = NULL;
  45. const 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 quiet = false;
  52. bool alldb = false;
  53. bool verbose = false;
  54. SimpleStringList tables = {NULL, NULL};
  55. progname = get_progname(argv[0]);
  56. set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
  57. handle_help_version_opts(argc, argv, "clusterdb", help);
  58. while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:at:v", long_options, &optindex)) != -1)
  59. {
  60. switch (c)
  61. {
  62. case 'h':
  63. host = pg_strdup(optarg);
  64. break;
  65. case 'p':
  66. port = pg_strdup(optarg);
  67. break;
  68. case 'U':
  69. username = pg_strdup(optarg);
  70. break;
  71. case 'w':
  72. prompt_password = TRI_NO;
  73. break;
  74. case 'W':
  75. prompt_password = TRI_YES;
  76. break;
  77. case 'e':
  78. echo = true;
  79. break;
  80. case 'q':
  81. quiet = true;
  82. break;
  83. case 'd':
  84. dbname = pg_strdup(optarg);
  85. break;
  86. case 'a':
  87. alldb = true;
  88. break;
  89. case 't':
  90. simple_string_list_append(&tables, optarg);
  91. break;
  92. case 'v':
  93. verbose = true;
  94. break;
  95. case 2:
  96. maintenance_db = pg_strdup(optarg);
  97. break;
  98. default:
  99. fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  100. exit(1);
  101. }
  102. }
  103. /*
  104. * Non-option argument specifies database name as long as it wasn't
  105. * already specified with -d / --dbname
  106. */
  107. if (optind < argc && dbname == NULL)
  108. {
  109. dbname = argv[optind];
  110. optind++;
  111. }
  112. if (optind < argc)
  113. {
  114. fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
  115. progname, argv[optind]);
  116. fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  117. exit(1);
  118. }
  119. setup_cancel_handler();
  120. if (alldb)
  121. {
  122. if (dbname)
  123. {
  124. fprintf(stderr, _("%s: cannot cluster all databases and a specific one at the same time\n"),
  125. progname);
  126. exit(1);
  127. }
  128. if (tables.head != NULL)
  129. {
  130. fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
  131. progname);
  132. exit(1);
  133. }
  134. cluster_all_databases(verbose, maintenance_db, host, port, username, prompt_password,
  135. progname, echo, quiet);
  136. }
  137. else
  138. {
  139. if (dbname == NULL)
  140. {
  141. if (getenv("PGDATABASE"))
  142. dbname = getenv("PGDATABASE");
  143. else if (getenv("PGUSER"))
  144. dbname = getenv("PGUSER");
  145. else
  146. dbname = get_user_name_or_exit(progname);
  147. }
  148. if (tables.head != NULL)
  149. {
  150. SimpleStringListCell *cell;
  151. for (cell = tables.head; cell; cell = cell->next)
  152. {
  153. cluster_one_database(dbname, verbose, cell->val,
  154. host, port, username, prompt_password,
  155. progname, echo);
  156. }
  157. }
  158. else
  159. cluster_one_database(dbname, verbose, NULL,
  160. host, port, username, prompt_password,
  161. progname, echo);
  162. }
  163. exit(0);
  164. }
  165. static void
  166. cluster_one_database(const char *dbname, bool verbose, const char *table,
  167. const char *host, const char *port,
  168. const char *username, enum trivalue prompt_password,
  169. const char *progname, bool echo)
  170. {
  171. PQExpBufferData sql;
  172. PGconn *conn;
  173. initPQExpBuffer(&sql);
  174. appendPQExpBufferStr(&sql, "CLUSTER");
  175. if (verbose)
  176. appendPQExpBufferStr(&sql, " VERBOSE");
  177. if (table)
  178. appendPQExpBuffer(&sql, " %s", table);
  179. appendPQExpBufferStr(&sql, ";");
  180. conn = connectDatabase(dbname, host, port, username, prompt_password,
  181. progname, false);
  182. if (!executeMaintenanceCommand(conn, sql.data, echo))
  183. {
  184. if (table)
  185. fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"),
  186. progname, table, dbname, PQerrorMessage(conn));
  187. else
  188. fprintf(stderr, _("%s: clustering of database \"%s\" failed: %s"),
  189. progname, dbname, PQerrorMessage(conn));
  190. PQfinish(conn);
  191. exit(1);
  192. }
  193. PQfinish(conn);
  194. termPQExpBuffer(&sql);
  195. }
  196. static void
  197. cluster_all_databases(bool verbose, const char *maintenance_db,
  198. const char *host, const char *port,
  199. const char *username, enum trivalue prompt_password,
  200. const char *progname, bool echo, bool quiet)
  201. {
  202. PGconn *conn;
  203. PGresult *result;
  204. int i;
  205. conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
  206. prompt_password, progname);
  207. result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
  208. PQfinish(conn);
  209. for (i = 0; i < PQntuples(result); i++)
  210. {
  211. char *dbname = PQgetvalue(result, i, 0);
  212. if (!quiet)
  213. {
  214. printf(_("%s: clustering database \"%s\"\n"), progname, dbname);
  215. fflush(stdout);
  216. }
  217. cluster_one_database(dbname, verbose, NULL,
  218. host, port, username, prompt_password,
  219. progname, echo);
  220. }
  221. PQclear(result);
  222. }
  223. static void
  224. help(const char *progname)
  225. {
  226. printf(_("%s clusters all previously clustered tables in a database.\n\n"), progname);
  227. printf(_("Usage:\n"));
  228. printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
  229. printf(_("\nOptions:\n"));
  230. printf(_(" -a, --all cluster all databases\n"));
  231. printf(_(" -d, --dbname=DBNAME database to cluster\n"));
  232. printf(_(" -e, --echo show the commands being sent to the server\n"));
  233. printf(_(" -q, --quiet don't write any messages\n"));
  234. printf(_(" -t, --table=TABLE cluster specific table(s) only\n"));
  235. printf(_(" -v, --verbose write a lot of output\n"));
  236. printf(_(" -V, --version output version information, then exit\n"));
  237. printf(_(" -?, --help show this help, then exit\n"));
  238. printf(_("\nConnection options:\n"));
  239. printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
  240. printf(_(" -p, --port=PORT database server port\n"));
  241. printf(_(" -U, --username=USERNAME user name to connect as\n"));
  242. printf(_(" -w, --no-password never prompt for password\n"));
  243. printf(_(" -W, --password force password prompt\n"));
  244. printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
  245. printf(_("\nRead the description of the SQL command CLUSTER for details.\n"));
  246. printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
  247. }