fix
[libpgclient.git] / util / pgsql.c
bloba973c8582c7c7ab03174f9a4e1ddb1a8d28ea4d2
1 /*Copyright (c) Brian B.
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 3 of the License, or (at your option) any later version.
7 See the file LICENSE included with this distribution for more
8 information.
9 */
10 #include <stdio.h>
11 #include <libex/str.h>
12 #include "../include/libpgcli/pgconn.h"
13 #include "linenoise.h"
14 #include "pgsql_cmd.h"
16 static void usage (const char *progname) {
17 dprintf(STDERR_FILENO, "usage: %s <connection_string> [start_sql]\n", progname);
18 exit(1);
21 static int print_error (pgconn_t *conn) {
22 int rc;
23 pgerror_t e;
24 if (-1 == (rc = pg_error(conn, &e)))
25 dprintf(STDERR_FILENO, "%s: %s; CODE: %s\n", e.text, e.msg, e.code);
26 return rc;
29 static int exec_sql (pgconn_t *conn, const char *sql, size_t sql_len) {
30 if (pg_execsql(conn, sql, sql_len)) {
31 print_error(conn);
32 pg_close(conn);
33 return -1;
35 if (pg_nflds(conn) > 0)
36 print_result(conn);
37 if (conn->complete)
38 printf("%s\n", conn->complete->tag);
39 pg_close(conn);
40 return 0;
43 static void intro (pgconn_t *conn) {
44 cstr_t *schema = get_current_schema(conn),
45 *dbsize = get_dbsize(conn, conn->dbname);
46 printf("Server version: %d.%d\n", conn->major_ver, conn->minor_ver);
47 printf("Server time zone: %s\n", conn->timezone);
48 printf("Database: %s (%s)\n", conn->dbname, dbsize->ptr);
49 printf("Current schema: %s\n", schema->ptr);
50 free(dbsize);
51 free(schema);
54 int main (int argc, const char *argv[]) {
55 if (argc < 2 || argc > 3) usage(argv[0]);
56 pgconn_t *conn = pg_connect(argv[1]);
57 if (0 == print_error(conn) && PG_IDLE == pg_ready(conn)) {
58 int is_quit = 0;
59 char *homedir = getenv("HOME");
60 str_t *hist = NULL;
61 if (3 == argc) {
62 printf("%s\n", argv[2]);
63 exec_sql(conn, argv[2], strlen(argv[2]));
64 pg_disconnect(conn);
65 return 0;
67 if (homedir) {
68 hist = strfmt("%s/.pgsql_history", homedir);
69 linenoiseHistoryLoadFile(hist->ptr);
71 intro(conn);
72 while (!is_quit) {
73 str_t *sql = NULL;
74 char *line;
75 while ((line = linenoise(sql ? "# " : "> ", NULL))) {
76 if (sql)
77 strnadd(&sql, line, strlen(line));
78 else {
79 if (!strcmp(line, "quit") || !strcmp(line, "exit")) {
80 is_quit = 1;
81 break;
82 } else if (!strncmp(line, "show", 4)) {
83 char **str = &line;
84 size_t str_len = strlen(line);
85 show(conn, str, &str_len);
86 continue;
87 } else
88 sql = mkstr(line, strlen(line), 0);
90 char *e = sql->ptr + sql->len - 1;
91 while (e > sql->ptr && isspace(*e)) --e;
92 if (';' == *e) {
93 *e = ' ';
94 break;
95 } else
96 strnadd(&sql, CONST_STR_LEN(" "));
98 if (!is_quit && sql) {
99 if (0 == exec_sql(conn, sql->ptr, sql->len)) {
100 sql->ptr[sql->len-1] = ';';
101 linenoiseHistoryAdd(sql->ptr);
104 if (sql) free(sql);
105 sql = NULL;
107 if (hist) {
108 linenoiseHistorySaveFile(hist->ptr);
109 free(hist);
112 pg_disconnect(conn);
113 return 0;