Header And Logo

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

droplang.c

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