~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-updates

« back to all changes in this revision

Viewing changes to src/bin/psql/startup.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * psql - the PostgreSQL interactive terminal
 
3
 *
 
4
 * Copyright (c) 2000-2009, PostgreSQL Global Development Group
 
5
 *
 
6
 * $PostgreSQL$
 
7
 */
 
8
#include "postgres_fe.h"
 
9
 
 
10
#include <sys/types.h>
 
11
 
 
12
#ifndef WIN32
 
13
#include <unistd.h>
 
14
#else                                                   /* WIN32 */
 
15
#include <io.h>
 
16
#include <win32.h>
 
17
#endif   /* WIN32 */
 
18
 
 
19
#include "getopt_long.h"
 
20
 
 
21
#ifndef HAVE_INT_OPTRESET
 
22
int                     optreset;
 
23
#endif
 
24
 
 
25
#include <locale.h>
 
26
 
 
27
 
 
28
#include "command.h"
 
29
#include "common.h"
 
30
#include "describe.h"
 
31
#include "help.h"
 
32
#include "input.h"
 
33
#include "mainloop.h"
 
34
#include "settings.h"
 
35
 
 
36
 
 
37
 
 
38
/*
 
39
 * Global psql options
 
40
 */
 
41
PsqlSettings pset;
 
42
 
 
43
#ifndef WIN32
 
44
#define SYSPSQLRC       "psqlrc"
 
45
#define PSQLRC          ".psqlrc"
 
46
#else
 
47
#define SYSPSQLRC       "psqlrc"
 
48
#define PSQLRC          "psqlrc.conf"
 
49
#endif
 
50
 
 
51
/*
 
52
 * Structures to pass information between the option parsing routine
 
53
 * and the main function
 
54
 */
 
55
enum _actions
 
56
{
 
57
        ACT_NOTHING = 0,
 
58
        ACT_SINGLE_SLASH,
 
59
        ACT_LIST_DB,
 
60
        ACT_SINGLE_QUERY,
 
61
        ACT_FILE
 
62
};
 
63
 
 
64
struct adhoc_opts
 
65
{
 
66
        char       *dbname;
 
67
        char       *host;
 
68
        char       *port;
 
69
        char       *username;
 
70
        char       *logfilename;
 
71
        enum _actions action;
 
72
        char       *action_string;
 
73
        bool            no_readline;
 
74
        bool            no_psqlrc;
 
75
        bool            single_txn;
 
76
};
 
77
 
 
78
static void parse_psql_options(int argc, char *argv[],
 
79
                                   struct adhoc_opts * options);
 
80
static void process_psqlrc(char *argv0);
 
81
static void process_psqlrc_file(char *filename);
 
82
static void showVersion(void);
 
83
static void EstablishVariableSpace(void);
 
84
 
 
85
/*
 
86
 *
 
87
 * main
 
88
 *
 
89
 */
 
90
int
 
91
main(int argc, char *argv[])
 
92
{
 
93
        struct adhoc_opts options;
 
94
        int                     successResult;
 
95
        char       *password = NULL;
 
96
        char       *password_prompt = NULL;
 
97
        bool            new_pass;
 
98
 
 
99
        set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
 
100
 
 
101
        if (argc > 1)
 
102
        {
 
103
                if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
 
104
                {
 
105
                        usage();
 
106
                        exit(EXIT_SUCCESS);
 
107
                }
 
108
                if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
 
109
                {
 
110
                        showVersion();
 
111
                        exit(EXIT_SUCCESS);
 
112
                }
 
113
        }
 
114
 
 
115
#ifdef WIN32
 
116
        setvbuf(stderr, NULL, _IONBF, 0);
 
117
#endif
 
118
 
 
119
        setup_cancel_handler();
 
120
 
 
121
        pset.progname = get_progname(argv[0]);
 
122
 
 
123
        pset.db = NULL;
 
124
        setDecimalLocale();
 
125
        pset.encoding = PQenv2encoding();
 
126
        pset.queryFout = stdout;
 
127
        pset.queryFoutPipe = false;
 
128
        pset.cur_cmd_source = stdin;
 
129
        pset.cur_cmd_interactive = false;
 
130
 
 
131
        /* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */
 
132
        pset.popt.topt.format = PRINT_ALIGNED;
 
133
        pset.popt.topt.border = 1;
 
134
        pset.popt.topt.pager = 1;
 
135
        pset.popt.topt.start_table = true;
 
136
        pset.popt.topt.stop_table = true;
 
137
        pset.popt.default_footer = true;
 
138
        /* We must get COLUMNS here before readline() sets it */
 
139
        pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
 
140
 
 
141
        pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout)));
 
142
 
 
143
        pset.getPassword = TRI_DEFAULT;
 
144
 
 
145
        EstablishVariableSpace();
 
146
 
 
147
        SetVariable(pset.vars, "VERSION", PG_VERSION_STR);
 
148
 
 
149
        /* Default values for variables */
 
150
        SetVariableBool(pset.vars, "AUTOCOMMIT");
 
151
        SetVariable(pset.vars, "VERBOSITY", "default");
 
152
        SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
 
153
        SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
 
154
        SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
 
155
 
 
156
        parse_psql_options(argc, argv, &options);
 
157
 
 
158
        if (!pset.popt.topt.fieldSep)
 
159
                pset.popt.topt.fieldSep = pg_strdup(DEFAULT_FIELD_SEP);
 
160
        if (!pset.popt.topt.recordSep)
 
161
                pset.popt.topt.recordSep = pg_strdup(DEFAULT_RECORD_SEP);
 
162
 
 
163
        if (options.username == NULL)
 
164
                password_prompt = pg_strdup(_("Password: "));
 
165
        else
 
166
        {
 
167
                password_prompt = malloc(strlen(_("Password for user %s: ")) - 2 +
 
168
                                                                 strlen(options.username) + 1);
 
169
                sprintf(password_prompt, _("Password for user %s: "),
 
170
                                options.username);
 
171
        }
 
172
 
 
173
        if (pset.getPassword == TRI_YES)
 
174
                password = simple_prompt(password_prompt, 100, false);
 
175
 
 
176
        /* loop until we have a password if requested by backend */
 
177
        do
 
178
        {
 
179
                new_pass = false;
 
180
                pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL,
 
181
                                        options.action == ACT_LIST_DB && options.dbname == NULL ?
 
182
                                                           "postgres" : options.dbname,
 
183
                                                           options.username, password);
 
184
 
 
185
                if (PQstatus(pset.db) == CONNECTION_BAD &&
 
186
                        PQconnectionNeedsPassword(pset.db) &&
 
187
                        password == NULL &&
 
188
                        pset.getPassword != TRI_NO)
 
189
                {
 
190
                        PQfinish(pset.db);
 
191
                        password = simple_prompt(password_prompt, 100, false);
 
192
                        new_pass = true;
 
193
                }
 
194
        } while (new_pass);
 
195
 
 
196
        free(password);
 
197
        free(password_prompt);
 
198
 
 
199
        if (PQstatus(pset.db) == CONNECTION_BAD)
 
200
        {
 
201
                fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db));
 
202
                PQfinish(pset.db);
 
203
                exit(EXIT_BADCONN);
 
204
        }
 
205
 
 
206
        PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
 
207
 
 
208
        SyncVariables();
 
209
 
 
210
        if (options.action == ACT_LIST_DB)
 
211
        {
 
212
                int                     success = listAllDbs(false);
 
213
 
 
214
                PQfinish(pset.db);
 
215
                exit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 
216
        }
 
217
 
 
218
        if (options.logfilename)
 
219
        {
 
220
                pset.logfile = fopen(options.logfilename, "a");
 
221
                if (!pset.logfile)
 
222
                        fprintf(stderr, _("%s: could not open log file \"%s\": %s\n"),
 
223
                                        pset.progname, options.logfilename, strerror(errno));
 
224
        }
 
225
 
 
226
        /*
 
227
         * Now find something to do
 
228
         */
 
229
 
 
230
        /*
 
231
         * process file given by -f
 
232
         */
 
233
        if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
 
234
        {
 
235
                if (!options.no_psqlrc)
 
236
                        process_psqlrc(argv[0]);
 
237
 
 
238
                successResult = process_file(options.action_string, options.single_txn);
 
239
        }
 
240
 
 
241
        /*
 
242
         * process slash command if one was given to -c
 
243
         */
 
244
        else if (options.action == ACT_SINGLE_SLASH)
 
245
        {
 
246
                PsqlScanState scan_state;
 
247
 
 
248
                if (pset.echo == PSQL_ECHO_ALL)
 
249
                        puts(options.action_string);
 
250
 
 
251
                scan_state = psql_scan_create();
 
252
                psql_scan_setup(scan_state,
 
253
                                                options.action_string,
 
254
                                                strlen(options.action_string));
 
255
 
 
256
                successResult = HandleSlashCmds(scan_state, NULL) != PSQL_CMD_ERROR
 
257
                        ? EXIT_SUCCESS : EXIT_FAILURE;
 
258
 
 
259
                psql_scan_destroy(scan_state);
 
260
        }
 
261
 
 
262
        /*
 
263
         * If the query given to -c was a normal one, send it
 
264
         */
 
265
        else if (options.action == ACT_SINGLE_QUERY)
 
266
        {
 
267
                if (pset.echo == PSQL_ECHO_ALL)
 
268
                        puts(options.action_string);
 
269
 
 
270
                successResult = SendQuery(options.action_string)
 
271
                        ? EXIT_SUCCESS : EXIT_FAILURE;
 
272
        }
 
273
 
 
274
        /*
 
275
         * or otherwise enter interactive main loop
 
276
         */
 
277
        else
 
278
        {
 
279
                if (!options.no_psqlrc)
 
280
                        process_psqlrc(argv[0]);
 
281
 
 
282
                connection_warnings();
 
283
                if (!pset.quiet && !pset.notty)
 
284
                        printf(_("Type \"help\" for help.\n\n"));
 
285
                if (!pset.notty)
 
286
                        initializeInput(options.no_readline ? 0 : 1);
 
287
                if (options.action_string)              /* -f - was used */
 
288
                        pset.inputfile = "<stdin>";
 
289
 
 
290
                successResult = MainLoop(stdin);
 
291
        }
 
292
 
 
293
        /* clean up */
 
294
        if (pset.logfile)
 
295
                fclose(pset.logfile);
 
296
        PQfinish(pset.db);
 
297
        setQFout(NULL);
 
298
 
 
299
        return successResult;
 
300
}
 
301
 
 
302
 
 
303
/*
 
304
 * Parse command line options
 
305
 */
 
306
 
 
307
static void
 
308
parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 
309
{
 
310
        static struct option long_options[] =
 
311
        {
 
312
                {"echo-all", no_argument, NULL, 'a'},
 
313
                {"no-align", no_argument, NULL, 'A'},
 
314
                {"command", required_argument, NULL, 'c'},
 
315
                {"dbname", required_argument, NULL, 'd'},
 
316
                {"echo-queries", no_argument, NULL, 'e'},
 
317
                {"echo-hidden", no_argument, NULL, 'E'},
 
318
                {"file", required_argument, NULL, 'f'},
 
319
                {"field-separator", required_argument, NULL, 'F'},
 
320
                {"host", required_argument, NULL, 'h'},
 
321
                {"html", no_argument, NULL, 'H'},
 
322
                {"list", no_argument, NULL, 'l'},
 
323
                {"log-file", required_argument, NULL, 'L'},
 
324
                {"no-readline", no_argument, NULL, 'n'},
 
325
                {"single-transaction", no_argument, NULL, '1'},
 
326
                {"output", required_argument, NULL, 'o'},
 
327
                {"port", required_argument, NULL, 'p'},
 
328
                {"pset", required_argument, NULL, 'P'},
 
329
                {"quiet", no_argument, NULL, 'q'},
 
330
                {"record-separator", required_argument, NULL, 'R'},
 
331
                {"single-step", no_argument, NULL, 's'},
 
332
                {"single-line", no_argument, NULL, 'S'},
 
333
                {"tuples-only", no_argument, NULL, 't'},
 
334
                {"table-attr", required_argument, NULL, 'T'},
 
335
                {"username", required_argument, NULL, 'U'},
 
336
                {"set", required_argument, NULL, 'v'},
 
337
                {"variable", required_argument, NULL, 'v'},
 
338
                {"version", no_argument, NULL, 'V'},
 
339
                {"no-password", no_argument, NULL, 'w'},
 
340
                {"password", no_argument, NULL, 'W'},
 
341
                {"expanded", no_argument, NULL, 'x'},
 
342
                {"no-psqlrc", no_argument, NULL, 'X'},
 
343
                {"help", no_argument, NULL, '?'},
 
344
                {NULL, 0, NULL, 0}
 
345
        };
 
346
 
 
347
        int                     optindex;
 
348
        extern char *optarg;
 
349
        extern int      optind;
 
350
        int                     c;
 
351
 
 
352
        memset(options, 0, sizeof *options);
 
353
 
 
354
        while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxX?1",
 
355
                                                        long_options, &optindex)) != -1)
 
356
        {
 
357
                switch (c)
 
358
                {
 
359
                        case 'a':
 
360
                                SetVariable(pset.vars, "ECHO", "all");
 
361
                                break;
 
362
                        case 'A':
 
363
                                pset.popt.topt.format = PRINT_UNALIGNED;
 
364
                                break;
 
365
                        case 'c':
 
366
                                options->action_string = optarg;
 
367
                                if (optarg[0] == '\\')
 
368
                                {
 
369
                                        options->action = ACT_SINGLE_SLASH;
 
370
                                        options->action_string++;
 
371
                                }
 
372
                                else
 
373
                                        options->action = ACT_SINGLE_QUERY;
 
374
                                break;
 
375
                        case 'd':
 
376
                                options->dbname = optarg;
 
377
                                break;
 
378
                        case 'e':
 
379
                                SetVariable(pset.vars, "ECHO", "queries");
 
380
                                break;
 
381
                        case 'E':
 
382
                                SetVariableBool(pset.vars, "ECHO_HIDDEN");
 
383
                                break;
 
384
                        case 'f':
 
385
                                options->action = ACT_FILE;
 
386
                                options->action_string = optarg;
 
387
                                break;
 
388
                        case 'F':
 
389
                                pset.popt.topt.fieldSep = pg_strdup(optarg);
 
390
                                break;
 
391
                        case 'h':
 
392
                                options->host = optarg;
 
393
                                break;
 
394
                        case 'H':
 
395
                                pset.popt.topt.format = PRINT_HTML;
 
396
                                break;
 
397
                        case 'l':
 
398
                                options->action = ACT_LIST_DB;
 
399
                                break;
 
400
                        case 'L':
 
401
                                options->logfilename = optarg;
 
402
                                break;
 
403
                        case 'n':
 
404
                                options->no_readline = true;
 
405
                                break;
 
406
                        case 'o':
 
407
                                setQFout(optarg);
 
408
                                break;
 
409
                        case 'p':
 
410
                                options->port = optarg;
 
411
                                break;
 
412
                        case 'P':
 
413
                                {
 
414
                                        char       *value;
 
415
                                        char       *equal_loc;
 
416
                                        bool            result;
 
417
 
 
418
                                        value = pg_strdup(optarg);
 
419
                                        equal_loc = strchr(value, '=');
 
420
                                        if (!equal_loc)
 
421
                                                result = do_pset(value, NULL, &pset.popt, true);
 
422
                                        else
 
423
                                        {
 
424
                                                *equal_loc = '\0';
 
425
                                                result = do_pset(value, equal_loc + 1, &pset.popt, true);
 
426
                                        }
 
427
 
 
428
                                        if (!result)
 
429
                                        {
 
430
                                                fprintf(stderr, _("%s: could not set printing parameter \"%s\"\n"), pset.progname, value);
 
431
                                                exit(EXIT_FAILURE);
 
432
                                        }
 
433
 
 
434
                                        free(value);
 
435
                                        break;
 
436
                                }
 
437
                        case 'q':
 
438
                                SetVariableBool(pset.vars, "QUIET");
 
439
                                break;
 
440
                        case 'R':
 
441
                                pset.popt.topt.recordSep = pg_strdup(optarg);
 
442
                                break;
 
443
                        case 's':
 
444
                                SetVariableBool(pset.vars, "SINGLESTEP");
 
445
                                break;
 
446
                        case 'S':
 
447
                                SetVariableBool(pset.vars, "SINGLELINE");
 
448
                                break;
 
449
                        case 't':
 
450
                                pset.popt.topt.tuples_only = true;
 
451
                                break;
 
452
                        case 'T':
 
453
                                pset.popt.topt.tableAttr = pg_strdup(optarg);
 
454
                                break;
 
455
                        case 'U':
 
456
                                options->username = optarg;
 
457
                                break;
 
458
                        case 'v':
 
459
                                {
 
460
                                        char       *value;
 
461
                                        char       *equal_loc;
 
462
 
 
463
                                        value = pg_strdup(optarg);
 
464
                                        equal_loc = strchr(value, '=');
 
465
                                        if (!equal_loc)
 
466
                                        {
 
467
                                                if (!DeleteVariable(pset.vars, value))
 
468
                                                {
 
469
                                                        fprintf(stderr, _("%s: could not delete variable \"%s\"\n"),
 
470
                                                                        pset.progname, value);
 
471
                                                        exit(EXIT_FAILURE);
 
472
                                                }
 
473
                                        }
 
474
                                        else
 
475
                                        {
 
476
                                                *equal_loc = '\0';
 
477
                                                if (!SetVariable(pset.vars, value, equal_loc + 1))
 
478
                                                {
 
479
                                                        fprintf(stderr, _("%s: could not set variable \"%s\"\n"),
 
480
                                                                        pset.progname, value);
 
481
                                                        exit(EXIT_FAILURE);
 
482
                                                }
 
483
                                        }
 
484
 
 
485
                                        free(value);
 
486
                                        break;
 
487
                                }
 
488
                        case 'V':
 
489
                                showVersion();
 
490
                                exit(EXIT_SUCCESS);
 
491
                        case 'w':
 
492
                                pset.getPassword = TRI_NO;
 
493
                                break;
 
494
                        case 'W':
 
495
                                pset.getPassword = TRI_YES;
 
496
                                break;
 
497
                        case 'x':
 
498
                                pset.popt.topt.expanded = true;
 
499
                                break;
 
500
                        case 'X':
 
501
                                options->no_psqlrc = true;
 
502
                                break;
 
503
                        case '1':
 
504
                                options->single_txn = true;
 
505
                                break;
 
506
                        case '?':
 
507
                                /* Actual help option given */
 
508
                                if (strcmp(argv[optind - 1], "-?") == 0 || strcmp(argv[optind - 1], "--help") == 0)
 
509
                                {
 
510
                                        usage();
 
511
                                        exit(EXIT_SUCCESS);
 
512
                                }
 
513
                                /* unknown option reported by getopt */
 
514
                                else
 
515
                                {
 
516
                                        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
 
517
                                                        pset.progname);
 
518
                                        exit(EXIT_FAILURE);
 
519
                                }
 
520
                                break;
 
521
                        default:
 
522
                                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
 
523
                                                pset.progname);
 
524
                                exit(EXIT_FAILURE);
 
525
                                break;
 
526
                }
 
527
        }
 
528
 
 
529
        /*
 
530
         * if we still have arguments, use it as the database name and username
 
531
         */
 
532
        while (argc - optind >= 1)
 
533
        {
 
534
                if (!options->dbname)
 
535
                        options->dbname = argv[optind];
 
536
                else if (!options->username)
 
537
                        options->username = argv[optind];
 
538
                else if (!pset.quiet)
 
539
                        fprintf(stderr, _("%s: warning: extra command-line argument \"%s\" ignored\n"),
 
540
                                        pset.progname, argv[optind]);
 
541
 
 
542
                optind++;
 
543
        }
 
544
}
 
545
 
 
546
 
 
547
/*
 
548
 * Load .psqlrc file, if found.
 
549
 */
 
550
static void
 
551
process_psqlrc(char *argv0)
 
552
{
 
553
        char            home[MAXPGPATH];
 
554
        char            rc_file[MAXPGPATH];
 
555
        char            my_exec_path[MAXPGPATH];
 
556
        char            etc_path[MAXPGPATH];
 
557
 
 
558
        find_my_exec(argv0, my_exec_path);
 
559
        get_etc_path(my_exec_path, etc_path);
 
560
 
 
561
        snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
 
562
        process_psqlrc_file(rc_file);
 
563
 
 
564
        if (get_home_path(home))
 
565
        {
 
566
                snprintf(rc_file, MAXPGPATH, "%s/%s", home, PSQLRC);
 
567
                process_psqlrc_file(rc_file);
 
568
        }
 
569
}
 
570
 
 
571
 
 
572
 
 
573
static void
 
574
process_psqlrc_file(char *filename)
 
575
{
 
576
        char       *psqlrc;
 
577
 
 
578
#if defined(WIN32) && (!defined(__MINGW32__))
 
579
#define R_OK 4
 
580
#endif
 
581
 
 
582
        psqlrc = pg_malloc(strlen(filename) + 1 + strlen(PG_VERSION) + 1);
 
583
        sprintf(psqlrc, "%s-%s", filename, PG_VERSION);
 
584
 
 
585
        if (access(psqlrc, R_OK) == 0)
 
586
                (void) process_file(psqlrc, false);
 
587
        else if (access(filename, R_OK) == 0)
 
588
                (void) process_file(filename, false);
 
589
        free(psqlrc);
 
590
}
 
591
 
 
592
 
 
593
 
 
594
/* showVersion
 
595
 *
 
596
 * This output format is intended to match GNU standards.
 
597
 */
 
598
static void
 
599
showVersion(void)
 
600
{
 
601
        puts("psql (PostgreSQL) " PG_VERSION);
 
602
 
 
603
#if defined(USE_READLINE)
 
604
        puts(_("contains support for command-line editing"));
 
605
#endif
 
606
}
 
607
 
 
608
 
 
609
 
 
610
/*
 
611
 * Assign hooks for psql variables.
 
612
 *
 
613
 * This isn't an amazingly good place for them, but neither is anywhere else.
 
614
 */
 
615
 
 
616
static void
 
617
autocommit_hook(const char *newval)
 
618
{
 
619
        pset.autocommit = ParseVariableBool(newval);
 
620
}
 
621
 
 
622
static void
 
623
on_error_stop_hook(const char *newval)
 
624
{
 
625
        pset.on_error_stop = ParseVariableBool(newval);
 
626
}
 
627
 
 
628
static void
 
629
quiet_hook(const char *newval)
 
630
{
 
631
        pset.quiet = ParseVariableBool(newval);
 
632
}
 
633
 
 
634
static void
 
635
singleline_hook(const char *newval)
 
636
{
 
637
        pset.singleline = ParseVariableBool(newval);
 
638
}
 
639
 
 
640
static void
 
641
singlestep_hook(const char *newval)
 
642
{
 
643
        pset.singlestep = ParseVariableBool(newval);
 
644
}
 
645
 
 
646
static void
 
647
fetch_count_hook(const char *newval)
 
648
{
 
649
        pset.fetch_count = ParseVariableNum(newval, -1, -1, false);
 
650
}
 
651
 
 
652
static void
 
653
echo_hook(const char *newval)
 
654
{
 
655
        if (newval == NULL)
 
656
                pset.echo = PSQL_ECHO_NONE;
 
657
        else if (strcmp(newval, "queries") == 0)
 
658
                pset.echo = PSQL_ECHO_QUERIES;
 
659
        else if (strcmp(newval, "all") == 0)
 
660
                pset.echo = PSQL_ECHO_ALL;
 
661
        else
 
662
                pset.echo = PSQL_ECHO_NONE;
 
663
}
 
664
 
 
665
static void
 
666
echo_hidden_hook(const char *newval)
 
667
{
 
668
        if (newval == NULL)
 
669
                pset.echo_hidden = PSQL_ECHO_HIDDEN_OFF;
 
670
        else if (strcmp(newval, "noexec") == 0)
 
671
                pset.echo_hidden = PSQL_ECHO_HIDDEN_NOEXEC;
 
672
        else if (pg_strcasecmp(newval, "off") == 0)
 
673
                pset.echo_hidden = PSQL_ECHO_HIDDEN_OFF;
 
674
        else
 
675
                pset.echo_hidden = PSQL_ECHO_HIDDEN_ON;
 
676
}
 
677
 
 
678
static void
 
679
on_error_rollback_hook(const char *newval)
 
680
{
 
681
        if (newval == NULL)
 
682
                pset.on_error_rollback = PSQL_ERROR_ROLLBACK_OFF;
 
683
        else if (pg_strcasecmp(newval, "interactive") == 0)
 
684
                pset.on_error_rollback = PSQL_ERROR_ROLLBACK_INTERACTIVE;
 
685
        else if (pg_strcasecmp(newval, "off") == 0)
 
686
                pset.on_error_rollback = PSQL_ERROR_ROLLBACK_OFF;
 
687
        else
 
688
                pset.on_error_rollback = PSQL_ERROR_ROLLBACK_ON;
 
689
}
 
690
 
 
691
static void
 
692
histcontrol_hook(const char *newval)
 
693
{
 
694
        if (newval == NULL)
 
695
                pset.histcontrol = hctl_none;
 
696
        else if (strcmp(newval, "ignorespace") == 0)
 
697
                pset.histcontrol = hctl_ignorespace;
 
698
        else if (strcmp(newval, "ignoredups") == 0)
 
699
                pset.histcontrol = hctl_ignoredups;
 
700
        else if (strcmp(newval, "ignoreboth") == 0)
 
701
                pset.histcontrol = hctl_ignoreboth;
 
702
        else
 
703
                pset.histcontrol = hctl_none;
 
704
}
 
705
 
 
706
static void
 
707
prompt1_hook(const char *newval)
 
708
{
 
709
        pset.prompt1 = newval ? newval : "";
 
710
}
 
711
 
 
712
static void
 
713
prompt2_hook(const char *newval)
 
714
{
 
715
        pset.prompt2 = newval ? newval : "";
 
716
}
 
717
 
 
718
static void
 
719
prompt3_hook(const char *newval)
 
720
{
 
721
        pset.prompt3 = newval ? newval : "";
 
722
}
 
723
 
 
724
static void
 
725
verbosity_hook(const char *newval)
 
726
{
 
727
        if (newval == NULL)
 
728
                pset.verbosity = PQERRORS_DEFAULT;
 
729
        else if (strcmp(newval, "default") == 0)
 
730
                pset.verbosity = PQERRORS_DEFAULT;
 
731
        else if (strcmp(newval, "terse") == 0)
 
732
                pset.verbosity = PQERRORS_TERSE;
 
733
        else if (strcmp(newval, "verbose") == 0)
 
734
                pset.verbosity = PQERRORS_VERBOSE;
 
735
        else
 
736
                pset.verbosity = PQERRORS_DEFAULT;
 
737
 
 
738
        if (pset.db)
 
739
                PQsetErrorVerbosity(pset.db, pset.verbosity);
 
740
}
 
741
 
 
742
 
 
743
static void
 
744
EstablishVariableSpace(void)
 
745
{
 
746
        pset.vars = CreateVariableSpace();
 
747
 
 
748
        SetVariableAssignHook(pset.vars, "AUTOCOMMIT", autocommit_hook);
 
749
        SetVariableAssignHook(pset.vars, "ON_ERROR_STOP", on_error_stop_hook);
 
750
        SetVariableAssignHook(pset.vars, "QUIET", quiet_hook);
 
751
        SetVariableAssignHook(pset.vars, "SINGLELINE", singleline_hook);
 
752
        SetVariableAssignHook(pset.vars, "SINGLESTEP", singlestep_hook);
 
753
        SetVariableAssignHook(pset.vars, "FETCH_COUNT", fetch_count_hook);
 
754
        SetVariableAssignHook(pset.vars, "ECHO", echo_hook);
 
755
        SetVariableAssignHook(pset.vars, "ECHO_HIDDEN", echo_hidden_hook);
 
756
        SetVariableAssignHook(pset.vars, "ON_ERROR_ROLLBACK", on_error_rollback_hook);
 
757
        SetVariableAssignHook(pset.vars, "HISTCONTROL", histcontrol_hook);
 
758
        SetVariableAssignHook(pset.vars, "PROMPT1", prompt1_hook);
 
759
        SetVariableAssignHook(pset.vars, "PROMPT2", prompt2_hook);
 
760
        SetVariableAssignHook(pset.vars, "PROMPT3", prompt3_hook);
 
761
        SetVariableAssignHook(pset.vars, "VERBOSITY", verbosity_hook);
 
762
}