📄 mapiclient.c
字号:
#line 87 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapiclient/MapiClient.mx"#include "clients_config.h"#include <monet_options.h>#include "Mapi.h"#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <sys/stat.h>#include <errno.h>#include <string.h>#ifdef HAVE_LIBREADLINE#include <readline/readline.h>#include <readline/history.h>#include "ReadlineTools.h"#endif#include "msqldump.h"#include "mprompt.h"#ifndef S_ISCHR#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)#endif#ifdef NATIVE_WIN32/* Windows doesn't declare chdir, even though it does provide the function */extern int chdir(const char *);#define strdup _strdup#endif#ifndef HAVE_GETLOGIN#define getlogin() "win32"#endifstatic FILE *toConsole;static char *language = "mil";char *command = NULL;static long t0, t1; /* used for timing */static char *mark, *mark2;/* stolen piece */#ifdef HAVE_FTIME#include <sys/timeb.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endifstatic longgettime(void){#ifdef HAVE_GETTIMEOFDAY struct timeval tp; gettimeofday(&tp, NULL); return (long) tp.tv_sec * 1000000 + (long) tp.tv_usec;#else#ifdef HAVE_FTIME struct timeb tb; ftime(&tb); return (long) tb.time * 1000000 + (long) tb.millitm * 1000;#endif#endif}static voidtimerStart(void){ t0 = gettime();}static voidtimerEnd(void){ t1 = gettime(); if (mark) { fprintf(toConsole, "%s % 7ld.%03ld msec %s\n", mark, (t1 - t0) / 1000, (t1 - t0) % 1000, mark2 ? mark2 : ""); fflush(toConsole); }}static intdoRequest(Mapi mid, const char *buf, int interactive){ MapiHdl hdl; if ((hdl = mapi_quick_query(mid, buf, toConsole)) == NULL) { mapi_explain(mid, stderr); return 1; } if (mapi_result_error(hdl)) { mapi_explain_result(hdl, stderr); mapi_close_handle(hdl); return 1; } if (mapi_error(mid)) { mapi_explain_query(hdl, stderr); mapi_close_handle(hdl); return 1; } if (! (mapi_get_active(mid) && interactive )) mapi_close_handle(hdl); return 0;}#define CHECK_RESULT(mid, hdl, buf, break_or_continue) \ switch (mapi_error(mid)) { \ case MOK: \ /* everything A OK */ \ break; \ case MERROR: \ /* some error, but try to continue */ \ if (hdl) { \ mapi_explain_query(hdl, stderr); \ mapi_close_handle(hdl); \ hdl = NULL; \ } else \ mapi_explain(mid, stderr); \ break_or_continue; \ case MTIMEOUT: \ /* lost contact with the server */ \ if (hdl) { \ mapi_explain_query(hdl, stderr); \ mapi_close_handle(hdl); \ hdl = NULL; \ } else \ mapi_explain(mid, stderr); \ timerEnd(); \ free(buf); \ return 1; \ }static intdoFile(Mapi mid, const char *file, int xquery){ FILE *fp; char *buf = NULL; size_t length; MapiHdl hdl = NULL; MapiMsg rc = MOK; int bufsize = 0; if (file == NULL) fp = stdin; else if ((fp = fopen(file, "r")) == NULL) { fprintf(stderr, "%s: cannot open\n", file); return 1; } bufsize = BUFSIZ; buf = malloc(bufsize); if (!buf) { fprintf(stderr, "cannot allocate memory for send buffer\n"); if (file != NULL) fclose(fp); return 1; } timerStart(); do { if ((length = fread(buf, 1, bufsize, fp)) == 0) { /* end of file */ if (file != NULL) { fclose(fp); file = NULL; } if (hdl == NULL) { /* nothing more to do */ timerEnd(); free(buf); return 0; } /* hdl != NULL, we should finish the current query */ } if (hdl == NULL) { hdl = mapi_query_prep(mid); CHECK_RESULT(mid, hdl, buf, continue); } if (length > 0) { assert(hdl != NULL); mapi_query_part(hdl, buf, length); CHECK_RESULT(mid, hdl, buf, continue); /* in case of xquery; do the whole file in one go */ if (xquery && !feof(fp)) continue; } assert(hdl != NULL); /* If the server wants more but we're at the end of file (length == 0), notify the server that we don't have anything more. If the server still wants more (shouldn't happen according to the protocol) we break out of the loop (via the continue). The assertion at the end will then go off. */ if (mapi_query_done(hdl) == MMORE && (length > 0 || mapi_query_done(hdl) == MMORE)) continue; /* get more data */ CHECK_RESULT(mid, hdl, buf, continue); do { char *reply; if ((reply = mapi_result_error(hdl)) != NULL) mapi_explain_result(hdl, stderr); if (mapi_get_querytype(hdl) == Q_UPDATE) { fprintf(toConsole, "[ %d\t]\n", mapi_rows_affected(hdl)); } else { while ((reply = mapi_fetch_line(hdl)) != NULL) { if (xquery && *reply == '=') reply++; fprintf(toConsole, "%s\n", reply); } } } while ((rc = mapi_needmore(hdl)) == MOK && (rc = mapi_next_result(hdl)) == 1); if (rc == MMORE && (length > 0 || mapi_query_done(hdl) != MOK)) continue; /* get more data */ CHECK_RESULT(mid, hdl, buf, continue); mapi_close_handle(hdl); hdl = NULL; } while (length > 0); /* reached on end of file */ assert(hdl == NULL); timerEnd(); free(buf); if (file != NULL) fclose(fp); fflush(stdout); return 0;}static voidshowCommands(void){ fprintf(toConsole, "?\t - show this message\n"); fprintf(toConsole, "?text\t - send help message\n"); fprintf(toConsole, "!\t - shell escape\n"); fprintf(toConsole, "<file\t - read input from file\n"); fprintf(toConsole, ">file\t - save response in file\n"); fprintf(toConsole, ">\t - response to terminal\n"); fprintf(toConsole, "cd\t - change directory\n"); fprintf(toConsole, "\\l\t- line is sent immediately\n"); fprintf(toConsole, "\\q\t- terminate session\n"); fprintf(toConsole, "\\T\t- toggle timer\n"); fprintf(toConsole, "\\D\t- dump database\n"); fprintf(toConsole, "\\Dtable\t- dump table\n"); fprintf(toConsole, "\\A\t- enable auto commit\n"); fprintf(toConsole, "\\a\t- disable auto commit\n"); fprintf(toConsole, "\\t\t- toggle interaction trace\n");}static intdoFileByLines(Mapi mid, FILE *fp, const char *prompt, int linemode, int exit_on_error, int xquery){ char *line = NULL; char *buf = NULL; size_t length; MapiHdl hdl = mapi_get_active(mid); MapiMsg rc = MOK; int sent = 0; /* whether we sent any data to the server */#ifdef HAVE_LIBREADLINE if (prompt == NULL)#endif buf = malloc(BUFSIZ); do {#ifdef HAVE_LIBREADLINE if (prompt) { rl_completion_func_t *func = NULL; if (buf) free(buf); if (hdl) func = suspend_completion(); buf = readline(hdl ? "more>" : prompt); if (hdl) continue_completion(func); /* add a newline to the end since that makes further processing easier */ if (buf) { add_history(buf); length = strlen(buf); buf = realloc(buf, length + 2); buf[length++] = '\n'; buf[length] = 0; } line = buf; } else#endif {#ifndef HAVE_LIBREADLINE if (prompt) { fputs(hdl ? "more>" : prompt, stdout); fflush(stdout); }#endif line = fgets(buf, BUFSIZ, fp); } if (line == NULL) { /* end of file */ if (hdl == NULL) { /* nothing more to do */ return 0; } /* hdl != NULL, we should finish the current query */ line = NULL; length = 0; } else length = strlen(line); if (length > 0 && (!linemode || (hdl == NULL && length > 0 && line[length - 1] == '\n'))) { /* test for special commands */ while (length > 0 && (*line & ~0x7F) == 0 && isspace((int) *line)) { line++; length--; } /* in the switch, use continue if the line was processed, use break to send to server */ switch (*line) { case '\0': /* empty line */ break; case '\\': switch (line[1]) { case 'q': free(buf); return 0; case 'T': mark = mark ? NULL : "Timer"; if (mark2) free(mark2); mark2 = strdup(line + 2); continue; case 't': /* toggle interaction trace */ mapi_trace(mid, !mapi_get_trace(mid)); continue; case 'l': linemode = 1; line = ""; length = 0; continue; case 'b': linemode = 0; continue; case 'A': mapi_setAutocommit(mid, 1); continue; case 'a': mapi_setAutocommit(mid, 0); continue; case 'D': if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; if (line[2]) { fprintf(toConsole, "START TRANSACTION;\n"); dump_table(mid, line + 2, toConsole); fprintf(toConsole, "COMMIT;\n"); } else { dump_tables(mid, toConsole); } continue; default: break; } break; case '<': /* read commands from file */ if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; doFile(mid, line + 1, 0); continue; case '>': /* redirect output to file */ line++; length--; if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; if (toConsole != stdout && toConsole != stderr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -