Header And Logo

PostgreSQL
| The world's most advanced open source database.

createlang.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * createlang
00004  *
00005  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00006  * Portions Copyright (c) 1994, Regents of the University of California
00007  *
00008  * src/bin/scripts/createlang.c
00009  *
00010  *-------------------------------------------------------------------------
00011  */
00012 #include "postgres_fe.h"
00013 
00014 #include "common.h"
00015 #include "print.h"
00016 
00017 static void help(const char *progname);
00018 
00019 
00020 int
00021 main(int argc, char *argv[])
00022 {
00023     static struct option long_options[] = {
00024         {"list", no_argument, NULL, 'l'},
00025         {"host", required_argument, NULL, 'h'},
00026         {"port", required_argument, NULL, 'p'},
00027         {"username", required_argument, NULL, 'U'},
00028         {"no-password", no_argument, NULL, 'w'},
00029         {"password", no_argument, NULL, 'W'},
00030         {"dbname", required_argument, NULL, 'd'},
00031         {"echo", no_argument, NULL, 'e'},
00032         {NULL, 0, NULL, 0}
00033     };
00034 
00035     const char *progname;
00036     int         optindex;
00037     int         c;
00038 
00039     bool        listlangs = false;
00040     const char *dbname = NULL;
00041     char       *host = NULL;
00042     char       *port = NULL;
00043     char       *username = NULL;
00044     enum trivalue prompt_password = TRI_DEFAULT;
00045     bool        echo = false;
00046     char       *langname = NULL;
00047 
00048     char       *p;
00049 
00050     PQExpBufferData sql;
00051 
00052     PGconn     *conn;
00053     PGresult   *result;
00054 
00055     progname = get_progname(argv[0]);
00056     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
00057 
00058     handle_help_version_opts(argc, argv, "createlang", help);
00059 
00060     while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1)
00061     {
00062         switch (c)
00063         {
00064             case 'l':
00065                 listlangs = true;
00066                 break;
00067             case 'h':
00068                 host = pg_strdup(optarg);
00069                 break;
00070             case 'p':
00071                 port = pg_strdup(optarg);
00072                 break;
00073             case 'U':
00074                 username = pg_strdup(optarg);
00075                 break;
00076             case 'w':
00077                 prompt_password = TRI_NO;
00078                 break;
00079             case 'W':
00080                 prompt_password = TRI_YES;
00081                 break;
00082             case 'd':
00083                 dbname = pg_strdup(optarg);
00084                 break;
00085             case 'e':
00086                 echo = true;
00087                 break;
00088             default:
00089                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00090                 exit(1);
00091         }
00092     }
00093 
00094     /*
00095      * We set dbname from positional arguments if it is not already set by
00096      * option arguments -d. If not doing listlangs, positional dbname must
00097      * follow positional langname.
00098      */
00099 
00100     if (argc - optind > 0)
00101     {
00102         if (listlangs)
00103         {
00104             if (dbname == NULL)
00105                 dbname = argv[optind++];
00106         }
00107         else
00108         {
00109             langname = argv[optind++];
00110             if (argc - optind > 0 && dbname == NULL)
00111                 dbname = argv[optind++];
00112         }
00113     }
00114 
00115     if (argc - optind > 0)
00116     {
00117         fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
00118                 progname, argv[optind]);
00119         fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00120         exit(1);
00121     }
00122 
00123     if (dbname == NULL)
00124     {
00125         if (getenv("PGDATABASE"))
00126             dbname = getenv("PGDATABASE");
00127         else if (getenv("PGUSER"))
00128             dbname = getenv("PGUSER");
00129         else
00130             dbname = get_user_name(progname);
00131     }
00132 
00133     initPQExpBuffer(&sql);
00134 
00135     /*
00136      * List option
00137      */
00138     if (listlangs)
00139     {
00140         printQueryOpt popt;
00141         static const bool translate_columns[] = {false, true};
00142 
00143         conn = connectDatabase(dbname, host, port, username, prompt_password,
00144                                progname, false);
00145 
00146         printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
00147                 "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
00148                           "FROM pg_catalog.pg_language WHERE lanispl;",
00149                           gettext_noop("Name"),
00150                           gettext_noop("yes"), gettext_noop("no"),
00151                           gettext_noop("Trusted?"));
00152         result = executeQuery(conn, sql.data, progname, echo);
00153 
00154         memset(&popt, 0, sizeof(popt));
00155         popt.topt.format = PRINT_ALIGNED;
00156         popt.topt.border = 1;
00157         popt.topt.start_table = true;
00158         popt.topt.stop_table = true;
00159         popt.topt.encoding = PQclientEncoding(conn);
00160         popt.title = _("Procedural Languages");
00161         popt.translate_header = true;
00162         popt.translate_columns = translate_columns;
00163         printQuery(result, &popt, stdout, NULL);
00164 
00165         PQfinish(conn);
00166         exit(0);
00167     }
00168 
00169     if (langname == NULL)
00170     {
00171         fprintf(stderr, _("%s: missing required argument language name\n"), progname);
00172         fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00173         exit(1);
00174     }
00175 
00176     /* lower case language name */
00177     for (p = langname; *p; p++)
00178         if (*p >= 'A' && *p <= 'Z')
00179             *p += ('a' - 'A');
00180 
00181     conn = connectDatabase(dbname, host, port, username, prompt_password,
00182                            progname, false);
00183 
00184     /*
00185      * Make sure the language isn't already installed
00186      */
00187     printfPQExpBuffer(&sql,
00188               "SELECT oid FROM pg_catalog.pg_language WHERE lanname = '%s';",
00189                       langname);
00190     result = executeQuery(conn, sql.data, progname, echo);
00191     if (PQntuples(result) > 0)
00192     {
00193         PQfinish(conn);
00194         fprintf(stderr,
00195           _("%s: language \"%s\" is already installed in database \"%s\"\n"),
00196                 progname, langname, dbname);
00197         /* separate exit status for "already installed" */
00198         exit(2);
00199     }
00200     PQclear(result);
00201 
00202     /*
00203      * In 9.1 and up, assume that languages should be installed using CREATE
00204      * EXTENSION.  However, it's possible this tool could be used against an
00205      * older server, and it's easy enough to continue supporting the old way.
00206      */
00207     if (PQserverVersion(conn) >= 90100)
00208         printfPQExpBuffer(&sql, "CREATE EXTENSION \"%s\";\n", langname);
00209     else
00210         printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";\n", langname);
00211 
00212     if (echo)
00213         printf("%s", sql.data);
00214     result = PQexec(conn, sql.data);
00215     if (PQresultStatus(result) != PGRES_COMMAND_OK)
00216     {
00217         fprintf(stderr, _("%s: language installation failed: %s"),
00218                 progname, PQerrorMessage(conn));
00219         PQfinish(conn);
00220         exit(1);
00221     }
00222 
00223     PQclear(result);
00224     PQfinish(conn);
00225     exit(0);
00226 }
00227 
00228 
00229 
00230 static void
00231 help(const char *progname)
00232 {
00233     printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
00234     printf(_("Usage:\n"));
00235     printf(_("  %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
00236     printf(_("\nOptions:\n"));
00237     printf(_("  -d, --dbname=DBNAME       database to install language in\n"));
00238     printf(_("  -e, --echo                show the commands being sent to the server\n"));
00239     printf(_("  -l, --list                show a list of currently installed languages\n"));
00240     printf(_("  -V, --version             output version information, then exit\n"));
00241     printf(_("  -?, --help                show this help, then exit\n"));
00242     printf(_("\nConnection options:\n"));
00243     printf(_("  -h, --host=HOSTNAME       database server host or socket directory\n"));
00244     printf(_("  -p, --port=PORT           database server port\n"));
00245     printf(_("  -U, --username=USERNAME   user name to connect as\n"));
00246     printf(_("  -w, --no-password         never prompt for password\n"));
00247     printf(_("  -W, --password            force password prompt\n"));
00248     printf(_("\nReport bugs to <[email protected]>.\n"));
00249 }