PageRenderTime 47ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/bin/scripts/createlang.c

https://github.com/matheusoliveira/postgres
C | 251 lines | 189 code | 33 blank | 29 comment | 27 complexity | 7113afdb9caab2f717e9701e786eab93 MD5 | raw file
Possible License(s): AGPL-3.0
  1. /*-------------------------------------------------------------------------
  2. *
  3. * createlang
  4. *
  5. * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  6. * Portions Copyright (c) 1994, Regents of the University of California
  7. *
  8. * src/bin/scripts/createlang.c
  9. *
  10. *-------------------------------------------------------------------------
  11. */
  12. #include "postgres_fe.h"
  13. #include "common.h"
  14. #include "print.h"
  15. static void help(const char *progname);
  16. int
  17. main(int argc, char *argv[])
  18. {
  19. static struct option long_options[] = {
  20. {"list", no_argument, NULL, 'l'},
  21. {"host", required_argument, NULL, 'h'},
  22. {"port", required_argument, NULL, 'p'},
  23. {"username", required_argument, NULL, 'U'},
  24. {"no-password", no_argument, NULL, 'w'},
  25. {"password", no_argument, NULL, 'W'},
  26. {"dbname", required_argument, NULL, 'd'},
  27. {"echo", no_argument, NULL, 'e'},
  28. {NULL, 0, NULL, 0}
  29. };
  30. const char *progname;
  31. int optindex;
  32. int c;
  33. bool listlangs = false;
  34. const char *dbname = NULL;
  35. char *host = NULL;
  36. char *port = NULL;
  37. char *username = NULL;
  38. enum trivalue prompt_password = TRI_DEFAULT;
  39. bool echo = false;
  40. char *langname = NULL;
  41. char *p;
  42. PQExpBufferData sql;
  43. PGconn *conn;
  44. PGresult *result;
  45. progname = get_progname(argv[0]);
  46. set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
  47. handle_help_version_opts(argc, argv, "createlang", help);
  48. while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1)
  49. {
  50. switch (c)
  51. {
  52. case 'l':
  53. listlangs = true;
  54. break;
  55. case 'h':
  56. host = pg_strdup(optarg);
  57. break;
  58. case 'p':
  59. port = pg_strdup(optarg);
  60. break;
  61. case 'U':
  62. username = pg_strdup(optarg);
  63. break;
  64. case 'w':
  65. prompt_password = TRI_NO;
  66. break;
  67. case 'W':
  68. prompt_password = TRI_YES;
  69. break;
  70. case 'd':
  71. dbname = pg_strdup(optarg);
  72. break;
  73. case 'e':
  74. echo = true;
  75. break;
  76. default:
  77. fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  78. exit(1);
  79. }
  80. }
  81. /*
  82. * We set dbname from positional arguments if it is not already set by
  83. * option arguments -d. If not doing listlangs, positional dbname must
  84. * follow positional langname.
  85. */
  86. if (argc - optind > 0)
  87. {
  88. if (listlangs)
  89. {
  90. if (dbname == NULL)
  91. dbname = argv[optind++];
  92. }
  93. else
  94. {
  95. langname = argv[optind++];
  96. if (argc - optind > 0 && dbname == NULL)
  97. dbname = argv[optind++];
  98. }
  99. }
  100. if (argc - optind > 0)
  101. {
  102. fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
  103. progname, argv[optind]);
  104. fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  105. exit(1);
  106. }
  107. if (dbname == NULL)
  108. {
  109. if (getenv("PGDATABASE"))
  110. dbname = getenv("PGDATABASE");
  111. else if (getenv("PGUSER"))
  112. dbname = getenv("PGUSER");
  113. else
  114. dbname = get_user_name_or_exit(progname);
  115. }
  116. initPQExpBuffer(&sql);
  117. /*
  118. * List option
  119. */
  120. if (listlangs)
  121. {
  122. printQueryOpt popt;
  123. static const bool translate_columns[] = {false, true};
  124. conn = connectDatabase(dbname, host, port, username, prompt_password,
  125. progname, false);
  126. printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
  127. "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
  128. "FROM pg_catalog.pg_language WHERE lanispl;",
  129. gettext_noop("Name"),
  130. gettext_noop("yes"), gettext_noop("no"),
  131. gettext_noop("Trusted?"));
  132. result = executeQuery(conn, sql.data, progname, echo);
  133. memset(&popt, 0, sizeof(popt));
  134. popt.topt.format = PRINT_ALIGNED;
  135. popt.topt.border = 1;
  136. popt.topt.start_table = true;
  137. popt.topt.stop_table = true;
  138. popt.topt.encoding = PQclientEncoding(conn);
  139. popt.title = _("Procedural Languages");
  140. popt.translate_header = true;
  141. popt.translate_columns = translate_columns;
  142. popt.n_translate_columns = lengthof(translate_columns);
  143. printQuery(result, &popt, stdout, NULL);
  144. PQfinish(conn);
  145. exit(0);
  146. }
  147. if (langname == NULL)
  148. {
  149. fprintf(stderr, _("%s: missing required argument language name\n"), progname);
  150. fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  151. exit(1);
  152. }
  153. /* lower case language name */
  154. for (p = langname; *p; p++)
  155. if (*p >= 'A' && *p <= 'Z')
  156. *p += ('a' - 'A');
  157. conn = connectDatabase(dbname, host, port, username, prompt_password,
  158. progname, false);
  159. /*
  160. * Make sure the language isn't already installed
  161. */
  162. printfPQExpBuffer(&sql,
  163. "SELECT oid FROM pg_catalog.pg_language WHERE lanname = '%s';",
  164. langname);
  165. result = executeQuery(conn, sql.data, progname, echo);
  166. if (PQntuples(result) > 0)
  167. {
  168. PQfinish(conn);
  169. fprintf(stderr,
  170. _("%s: language \"%s\" is already installed in database \"%s\"\n"),
  171. progname, langname, dbname);
  172. /* separate exit status for "already installed" */
  173. exit(2);
  174. }
  175. PQclear(result);
  176. /*
  177. * In 9.1 and up, assume that languages should be installed using CREATE
  178. * EXTENSION. However, it's possible this tool could be used against an
  179. * older server, and it's easy enough to continue supporting the old way.
  180. */
  181. if (PQserverVersion(conn) >= 90100)
  182. printfPQExpBuffer(&sql, "CREATE EXTENSION \"%s\";", langname);
  183. else
  184. printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";", langname);
  185. if (echo)
  186. printf("%s\n", sql.data);
  187. result = PQexec(conn, sql.data);
  188. if (PQresultStatus(result) != PGRES_COMMAND_OK)
  189. {
  190. fprintf(stderr, _("%s: language installation failed: %s"),
  191. progname, PQerrorMessage(conn));
  192. PQfinish(conn);
  193. exit(1);
  194. }
  195. PQclear(result);
  196. PQfinish(conn);
  197. exit(0);
  198. }
  199. static void
  200. help(const char *progname)
  201. {
  202. printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
  203. printf(_("Usage:\n"));
  204. printf(_(" %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
  205. printf(_("\nOptions:\n"));
  206. printf(_(" -d, --dbname=DBNAME database to install language in\n"));
  207. printf(_(" -e, --echo show the commands being sent to the server\n"));
  208. printf(_(" -l, --list show a list of currently installed languages\n"));
  209. printf(_(" -V, --version output version information, then exit\n"));
  210. printf(_(" -?, --help show this help, then exit\n"));
  211. printf(_("\nConnection options:\n"));
  212. printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
  213. printf(_(" -p, --port=PORT database server port\n"));
  214. printf(_(" -U, --username=USERNAME user name to connect as\n"));
  215. printf(_(" -w, --no-password never prompt for password\n"));
  216. printf(_(" -W, --password force password prompt\n"));
  217. printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
  218. }