OSDN Git Service

3e3fa762f5083d07fed9f86b0482883d18372d89
[pg-rex/syncrep.git] / src / bin / scripts / createlang.c
1 /*-------------------------------------------------------------------------
2  *
3  * createlang
4  *
5  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.12 2004/06/03 00:07:38 momjian Exp $
9  *
10  *-------------------------------------------------------------------------
11  */
12
13 #include "postgres_fe.h"
14 #include "common.h"
15 #include "print.h"
16
17
18 static void help(const char *progname);
19
20
21 int
22 main(int argc, char *argv[])
23 {
24         static struct option long_options[] = {
25                 {"list", no_argument, NULL, 'l'},
26                 {"host", required_argument, NULL, 'h'},
27                 {"port", required_argument, NULL, 'p'},
28                 {"username", required_argument, NULL, 'U'},
29                 {"password", no_argument, NULL, 'W'},
30                 {"dbname", required_argument, NULL, 'd'},
31                 {"pglib", required_argument, NULL, 'L'},
32                 {"echo", no_argument, NULL, 'e'},
33                 {NULL, 0, NULL, 0}
34         };
35
36         const char *progname;
37         int                     optindex;
38         int                     c;
39
40         bool            listlangs = false;
41         const char *dbname = NULL;
42         char       *host = NULL;
43         char       *port = NULL;
44         char       *username = NULL;
45         bool            password = false;
46         bool            echo = false;
47         char       *pglib = NULL;
48         char       *langname = NULL;
49
50         char       *p;
51         bool            handlerexists;
52         bool            validatorexists;
53         bool            trusted;
54         char       *handler;
55         char       *validator = NULL;
56         char       *object;
57
58         PQExpBufferData sql;
59
60         PGconn     *conn;
61         PGresult   *result;
62
63         progname = get_progname(argv[0]);
64         set_pglocale_pgservice(argv[0], "pgscripts");
65
66         handle_help_version_opts(argc, argv, "createlang", help);
67
68         while ((c = getopt_long(argc, argv, "lh:p:U:Wd:L:e", long_options, &optindex)) != -1)
69         {
70                 switch (c)
71                 {
72                         case 'l':
73                                 listlangs = true;
74                                 break;
75                         case 'h':
76                                 host = optarg;
77                                 break;
78                         case 'p':
79                                 port = optarg;
80                                 break;
81                         case 'U':
82                                 username = optarg;
83                                 break;
84                         case 'W':
85                                 password = true;
86                                 break;
87                         case 'd':
88                                 dbname = optarg;
89                                 break;
90                         case 'L':
91                                 pglib = optarg;
92                                 break;
93                         case 'e':
94                                 echo = true;
95                                 break;
96                         default:
97                                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
98                                 exit(1);
99                 }
100         }
101
102         if (argc - optind > 0)
103         {
104                 if (listlangs)
105                         dbname = argv[optind++];
106                 else
107                 {
108                         langname = argv[optind++];
109                         if (argc - optind > 0)
110                                 dbname = argv[optind++];
111                 }
112         }
113
114         if (argc - optind > 0)
115         {
116                 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
117                                 progname, argv[optind]);
118                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
119                 exit(1);
120         }
121
122         if (dbname == NULL)
123         {
124                 if (getenv("PGDATABASE"))
125                         dbname = getenv("PGDATABASE");
126                 else if (getenv("PGUSER"))
127                         dbname = getenv("PGUSER");
128                 else
129                         dbname = get_user_name(progname);
130         }
131
132         initPQExpBuffer(&sql);
133
134         /*
135          * List option
136          */
137         if (listlangs)
138         {
139                 printQueryOpt popt;
140
141                 conn = connectDatabase(dbname, host, port, username, password, progname);
142
143                 printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?"));
144                 result = executeQuery(conn, sql.data, progname, echo);
145
146                 memset(&popt, 0, sizeof(popt));
147                 popt.topt.format = PRINT_ALIGNED;
148                 popt.topt.border = 1;
149                 popt.topt.encoding = PQclientEncoding(conn);
150                 popt.title = _("Procedural Languages");
151                 printQuery(result, &popt, stdout);
152
153                 PQfinish(conn);
154                 exit(0);
155         }
156
157         if (langname == NULL)
158         {
159                 fprintf(stderr, _("%s: missing required argument language name\n"), progname);
160                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
161                 exit(1);
162         }
163
164         if (!pglib)
165                 pglib = "$libdir";
166
167         for (p = langname; *p; p++)
168                 if (*p >= 'A' && *p <= 'Z')
169                         *p += ('a' - 'A');
170
171         if (strcmp(langname, "plpgsql") == 0)
172         {
173                 trusted = true;
174                 handler = "plpgsql_call_handler";
175                 validator = "plpgsql_validator";
176                 object = "plpgsql";
177         }
178         else if (strcmp(langname, "pltcl") == 0)
179         {
180                 trusted = true;
181                 handler = "pltcl_call_handler";
182                 object = "pltcl";
183         }
184         else if (strcmp(langname, "pltclu") == 0)
185         {
186                 trusted = false;
187                 handler = "pltclu_call_handler";
188                 object = "pltcl";
189         }
190         else if (strcmp(langname, "plperl") == 0)
191         {
192                 trusted = true;
193                 handler = "plperl_call_handler";
194                 object = "plperl";
195         }
196         else if (strcmp(langname, "plperlu") == 0)
197         {
198                 trusted = false;
199                 handler = "plperl_call_handler";
200                 object = "plperl";
201         }
202         else if (strcmp(langname, "plpythonu") == 0)
203         {
204                 trusted = false;
205                 handler = "plpython_call_handler";
206                 object = "plpython";
207         }
208         else
209         {
210                 fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
211                 fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpythonu.\n"));
212                 exit(1);
213         }
214
215         conn = connectDatabase(dbname, host, port, username, password, progname);
216
217         /*
218          * Make sure the language isn't already installed
219          */
220         printfPQExpBuffer(&sql, "SELECT oid FROM pg_language WHERE lanname = '%s';", langname);
221         result = executeQuery(conn, sql.data, progname, echo);
222         if (PQntuples(result) > 0)
223         {
224                 PQfinish(conn);
225                 fprintf(stderr,
226                                 _("%s: language \"%s\" is already installed in database \"%s\"\n"),
227                                 progname, langname, dbname);
228                 /* separate exit status for "already installed" */
229                 exit(2);
230         }
231         PQclear(result);
232
233         /*
234          * Check whether the call handler exists
235          */
236         printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND prorettype = 'pg_catalog.language_handler'::regtype AND pronargs = 0;", handler);
237         result = executeQuery(conn, sql.data, progname, echo);
238         handlerexists = (PQntuples(result) > 0);
239         PQclear(result);
240
241         /*
242          * Check whether the validator exists
243          */
244         if (validator)
245         {
246                 printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND proargtypes[0] = 'pg_catalog.oid'::regtype AND pronargs = 1;", validator);
247                 result = executeQuery(conn, sql.data, progname, echo);
248                 validatorexists = (PQntuples(result) > 0);
249                 PQclear(result);
250         }
251         else
252                 validatorexists = true;                 /* don't try to create it */
253
254         /*
255          * Create the function(s) and the language
256          */
257         resetPQExpBuffer(&sql);
258
259         if (!handlerexists)
260                 appendPQExpBuffer(&sql,
261                                                   "CREATE FUNCTION \"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
262                                                   handler, pglib, object);
263
264         if (!validatorexists)
265                 appendPQExpBuffer(&sql,
266                                                   "CREATE FUNCTION \"%s\" (oid) RETURNS void AS '%s/%s' LANGUAGE C;\n",
267                                                   validator, pglib, object);
268
269         appendPQExpBuffer(&sql,
270                                           "CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
271                                           (trusted ? "TRUSTED " : ""), langname, handler);
272
273         if (validator)
274                 appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
275
276         appendPQExpBuffer(&sql, ";\n");
277
278         if (echo)
279                 printf("%s", sql.data);
280         result = PQexec(conn, sql.data);
281         if (PQresultStatus(result) != PGRES_COMMAND_OK)
282         {
283                 fprintf(stderr, _("%s: language installation failed: %s"),
284                                 progname, PQerrorMessage(conn));
285                 PQfinish(conn);
286                 exit(1);
287         }
288
289         PQfinish(conn);
290         exit(0);
291 }
292
293
294
295 static void
296 help(const char *progname)
297 {
298         printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
299         printf(_("Usage:\n"));
300         printf(_("  %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
301         printf(_("\nOptions:\n"));
302         printf(_("  -d, --dbname=DBNAME       database to install language in\n"));
303         printf(_("  -e, --echo                show the commands being sent to the server\n"));
304         printf(_("  -l, --list                show a list of currently installed languages\n"));
305         printf(_("  -L, --pglib=DIRECTORY     find language interpreter file in DIRECTORY\n"));
306         printf(_("  -h, --host=HOSTNAME       database server host or socket directory\n"));
307         printf(_("  -p, --port=PORT           database server port\n"));
308         printf(_("  -U, --username=USERNAME   user name to connect as\n"));
309         printf(_("  -W, --password            prompt for password\n"));
310         printf(_("  --help                    show this help, then exit\n"));
311         printf(_("  --version                 output version information, then exit\n"));
312         printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
313 }