📄 common.c
字号:
} PQclear(res); } res = PQexec(pset.db, query); if (!AcceptResult(res) && res) { PQclear(res); res = NULL; } return res;}/* * PrintNotifications: check for asynchronous notifications, and print them out */static voidPrintNotifications(void){ PGnotify *notify; while ((notify = PQnotifies(pset.db))) { fprintf(pset.queryFout, gettext("Asynchronous notification \"%s\" received from server process with PID %d.\n"), notify->relname, notify->be_pid); fflush(pset.queryFout); PQfreemem(notify); }}/* * PrintQueryTuples: assuming query result is OK, print its tuples * * Returns true if successful, false otherwise. */static boolPrintQueryTuples(const PGresult *results){ /* write output to \g argument, if any */ if (pset.gfname) { FILE *queryFout_copy = pset.queryFout; bool queryFoutPipe_copy = pset.queryFoutPipe; pset.queryFout = stdout; /* so it doesn't get closed */ /* open file/pipe */ if (!setQFout(pset.gfname)) { pset.queryFout = queryFout_copy; pset.queryFoutPipe = queryFoutPipe_copy; return false; } printQuery(results, &pset.popt, pset.queryFout); /* close file/pipe, restore old setting */ setQFout(NULL); pset.queryFout = queryFout_copy; pset.queryFoutPipe = queryFoutPipe_copy; free(pset.gfname); pset.gfname = NULL; } else printQuery(results, &pset.popt, pset.queryFout); return true;}/* * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it * * Note: Utility function for use by SendQuery() only. * * Returns true if the query executed successfully, false otherwise. */static boolProcessCopyResult(PGresult *results){ bool success = false; if (!results) return false; switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: case PGRES_COMMAND_OK: case PGRES_EMPTY_QUERY: /* nothing to do here */ success = true; break; case PGRES_COPY_OUT: success = handleCopyOut(pset.db, pset.queryFout); break; case PGRES_COPY_IN: if (pset.cur_cmd_interactive && !QUIET()) puts(gettext("Enter data to be copied followed by a newline.\n" "End with a backslash and a period on a line by itself.")); success = handleCopyIn(pset.db, pset.cur_cmd_source, pset.cur_cmd_interactive ? get_prompt(PROMPT_COPY) : NULL); break; default: break; } /* may need this to recover from conn loss during COPY */ if (!CheckConnection()) return false; return success;}/* * PrintQueryResults: print out query results as required * * Note: Utility function for use by SendQuery() only. * * Returns true if the query executed successfully, false otherwise. */static boolPrintQueryResults(PGresult *results){ bool success = false; if (!results) return false; switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: success = PrintQueryTuples(results); break; case PGRES_COMMAND_OK: { char buf[10]; success = true; sprintf(buf, "%u", (unsigned int) PQoidValue(results)); if (!QUIET()) { if (pset.popt.topt.format == PRINT_HTML) { fputs("<p>", pset.queryFout); html_escaped_print(PQcmdStatus(results), pset.queryFout); fputs("</p>\n", pset.queryFout); } else fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); } SetVariable(pset.vars, "LASTOID", buf); break; } case PGRES_EMPTY_QUERY: success = true; break; case PGRES_COPY_OUT: case PGRES_COPY_IN: /* nothing to do here */ success = true; break; default: break; } fflush(pset.queryFout); return success;}/* * SendQuery: send the query string to the backend * (and print out results) * * Note: This is the "front door" way to send a query. That is, use it to * send queries actually entered by the user. These queries will be subject to * single step mode. * To send "back door" queries (generated by slash commands, etc.) in a * controlled way, use PSQLexec(). * * Returns true if the query executed successfully, false otherwise. */boolSendQuery(const char *query){ PGresult *results; TimevalStruct before, after; bool OK; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); return false; } if (GetVariableBool(pset.vars, "SINGLESTEP")) { char buf[3]; printf(gettext("***(Single step mode: verify command)*******************************************\n" "%s\n" "***(press return to proceed or enter x and return to cancel)********************\n"), query); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != NULL) if (buf[0] == 'x') return false; } else if (VariableEquals(pset.vars, "ECHO", "queries")) { puts(query); fflush(stdout); } SetCancelConn(); if (PQtransactionStatus(pset.db) == PQTRANS_IDLE && !GetVariableBool(pset.vars, "AUTOCOMMIT") && !is_transact_command(query)) { results = PQexec(pset.db, "BEGIN"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); return false; } PQclear(results); } if (pset.timing) GETTIMEOFDAY(&before); results = PQexec(pset.db, query); /* these operations are included in the timing result: */ OK = (AcceptResult(results) && ProcessCopyResult(results)); if (pset.timing) GETTIMEOFDAY(&after); /* but printing results isn't: */ if (OK) OK = PrintQueryResults(results); PQclear(results); /* Possible microtiming output */ if (OK && pset.timing) printf(gettext("Time: %.3f ms\n"), DIFF_MSEC(&after, &before)); /* check for events that may occur during query execution */ if (pset.encoding != PQclientEncoding(pset.db) && PQclientEncoding(pset.db) >= 0) { /* track effects of SET CLIENT_ENCODING */ pset.encoding = PQclientEncoding(pset.db); pset.popt.topt.encoding = pset.encoding; SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); } PrintNotifications(); return OK;}/* * check whether a query string begins with BEGIN/COMMIT/ROLLBACK/START XACT */static boolis_transact_command(const char *query){ int wordlen; /* * First we must advance over any whitespace and comments. */ while (*query) { if (isspace((unsigned char) *query)) query++; else if (query[0] == '-' && query[1] == '-') { query += 2; while (*query && *query != '\n') query++; } else if (query[0] == '/' && query[1] == '*') { query += 2; while (*query) { if (query[0] == '*' && query[1] == '/') { query += 2; break; } else query++; } } else break; /* found first token */ } /* * Check word length ("beginx" is not "begin"). */ wordlen = 0; while (isalpha((unsigned char) query[wordlen])) wordlen++; if (wordlen == 5 && strncasecmp(query, "begin", 5) == 0) return true; if (wordlen == 6 && strncasecmp(query, "commit", 6) == 0) return true; if (wordlen == 8 && strncasecmp(query, "rollback", 8) == 0) return true; if (wordlen == 5 && strncasecmp(query, "abort", 5) == 0) return true; if (wordlen == 3 && strncasecmp(query, "end", 3) == 0) return true; if (wordlen == 5 && strncasecmp(query, "start", 5) == 0) return true; return false;}charparse_char(char **buf){ long l; l = strtol(*buf, buf, 0); --*buf; return (char) l;}/* * Test if the current user is a database superuser. * * Note: this will correctly detect superuserness only with a protocol-3.0 * or newer backend; otherwise it will always say "false". */boolis_superuser(void){ const char *val; if (!pset.db) return false; val = PQparameterStatus(pset.db, "is_superuser"); if (val && strcmp(val, "on") == 0) return true; return false;}/* * Return the session user of the current connection. * * Note: this will correctly detect the session user only with a * protocol-3.0 or newer backend; otherwise it will return the * connection user. */const char *session_username(void){ const char *val; if (!pset.db) return NULL; val = PQparameterStatus(pset.db, "session_authorization"); if (val) return val; else return PQuser(pset.db);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -