static int c_psql_write (const data_set_t *ds, const value_list_t *vl, user_data_t *ud) { c_psql_database_t *db; char time_str[32]; char values_name_str[1024]; char values_type_str[1024]; char values_str[1024]; const char *params[9]; int success = 0; int i; if ((ud == NULL) || (ud->data == NULL)) { log_err ("c_psql_write: Invalid user data."); return -1; } db = ud->data; assert (db->database != NULL); assert (db->writers != NULL); if (cdtime_to_iso8601 (time_str, sizeof (time_str), vl->time) == 0) { log_err ("c_psql_write: Failed to convert time to ISO 8601 format"); return -1; } if (values_name_to_sqlarray (ds, values_name_str, sizeof (values_name_str)) == NULL) return -1; #define VALUE_OR_NULL(v) ((((v) == NULL) || (*(v) == '\0')) ? NULL : (v)) params[0] = time_str; params[1] = vl->host; params[2] = vl->plugin; params[3] = VALUE_OR_NULL(vl->plugin_instance); params[4] = vl->type; params[5] = VALUE_OR_NULL(vl->type_instance); params[6] = values_name_str; #undef VALUE_OR_NULL pthread_mutex_lock (&db->db_lock); if (0 != c_psql_check_connection (db)) { pthread_mutex_unlock (&db->db_lock); return -1; } if ((db->commit_interval > 0) && (db->next_commit == 0)) c_psql_begin (db); for (i = 0; i < db->writers_num; ++i) { c_psql_writer_t *writer; PGresult *res; writer = db->writers[i]; if (values_type_to_sqlarray (ds, values_type_str, sizeof (values_type_str), writer->store_rates) == NULL) { pthread_mutex_unlock (&db->db_lock); return -1; } if (values_to_sqlarray (ds, vl, values_str, sizeof (values_str), writer->store_rates) == NULL) { pthread_mutex_unlock (&db->db_lock); return -1; } params[7] = values_type_str; params[8] = values_str; res = PQexecParams (db->conn, writer->statement, STATIC_ARRAY_SIZE (params), NULL, (const char *const *)params, NULL, NULL, /* return text data */ 0); if ((PGRES_COMMAND_OK != PQresultStatus (res)) && (PGRES_TUPLES_OK != PQresultStatus (res))) { PQclear (res); if ((CONNECTION_OK != PQstatus (db->conn)) && (0 == c_psql_check_connection (db))) { /* try again */ res = PQexecParams (db->conn, writer->statement, STATIC_ARRAY_SIZE (params), NULL, (const char *const *)params, NULL, NULL, /* return text data */ 0); if ((PGRES_COMMAND_OK == PQresultStatus (res)) || (PGRES_TUPLES_OK == PQresultStatus (res))) { PQclear (res); success = 1; continue; } } log_err ("Failed to execute SQL query: %s", PQerrorMessage (db->conn)); log_info ("SQL query was: '%s', " "params: %s, %s, %s, %s, %s, %s, %s, %s", writer->statement, params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]); /* this will abort any current transaction -> restart */ if (db->next_commit > 0) c_psql_commit (db); pthread_mutex_unlock (&db->db_lock); return -1; } PQclear (res); success = 1; } if ((db->next_commit > 0) && (cdtime () > db->next_commit)) c_psql_commit (db); pthread_mutex_unlock (&db->db_lock); if (! success) return -1; return 0; } /* c_psql_write */
/* * helpSQL -- help with SQL commands * * Note: we assume caller removed any trailing spaces in "topic". */ void helpSQL(const char *topic, unsigned short int pager) { #define VALUE_OR_NULL(a) ((a) ? (a) : "") if (!topic || strlen(topic) == 0) { /* Print all the available command names */ int screen_width; int ncolumns; int nrows; FILE *output; int i; int j; #ifdef TIOCGWINSZ struct winsize screen_size; if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1) screen_width = 80; /* ioctl failed, assume 80 */ else screen_width = screen_size.ws_col; #else screen_width = 80; /* default assumption */ #endif ncolumns = (screen_width - 3) / (QL_MAX_CMD_LEN + 1); ncolumns = Max(ncolumns, 1); nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns; output = PageOutput(nrows + 1, pager); fputs(_("Available help:\n"), output); for (i = 0; i < nrows; i++) { fprintf(output, " "); for (j = 0; j < ncolumns - 1; j++) fprintf(output, "%-*s", QL_MAX_CMD_LEN + 1, VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd)); if (i + j * nrows < QL_HELP_COUNT) fprintf(output, "%s", VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd)); fputc('\n', output); } /* Only close if we used the pager */ if (output != stdout) { pclose(output); #ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL); #endif } } else { int i, j, x = 0; bool help_found = false; FILE *output; size_t len, wordlen; int nl_count = 0; /* * We first try exact match, then first + second words, then first * word only. */ len = strlen(topic); for (x = 1; x <= 3; x++) { if (x > 1) /* Nothing on first pass - try the opening * word(s) */ { wordlen = j = 1; while (topic[j] != ' ' && j++ < len) wordlen++; if (x == 2) { j++; while (topic[j] != ' ' && j++ <= len) wordlen++; } if (wordlen >= len) /* Don't try again if the same word */ { output = PageOutput(nl_count, pager); break; } len = wordlen; } /* Count newlines for pager */ for (i = 0; QL_HELP[i].cmd; i++) { if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 || strcmp(topic, "*") == 0) { nl_count += 5 + QL_HELP[i].nl_count; /* If we have an exact match, exit. Fixes \h SELECT */ if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } output = PageOutput(nl_count, pager); for (i = 0; QL_HELP[i].cmd; i++) { if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 || strcmp(topic, "*") == 0) { PQExpBufferData buffer; initPQExpBuffer(&buffer); QL_HELP[i].syntaxfunc(&buffer); help_found = true; fprintf(output, _("Command: %s\n" "Description: %s\n" "Syntax:\n%s\n\n"), QL_HELP[i].cmd, _(QL_HELP[i].help), buffer.data); /* If we have an exact match, exit. Fixes \h SELECT */ if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } if (help_found) /* Don't keep trying if we got a match */ break; } if (!help_found) fprintf(output, _("No help available for \"%s\".\nTry \\h with no arguments to see available help.\n"), topic); /* Only close if we used the pager */ if (output != stdout) { pclose(output); #ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL); #endif } } }
/* * helpSQL -- help with SQL commands * */ void helpSQL(const char *topic, unsigned short int pager) { #define VALUE_OR_NULL(a) ((a) ? (a) : "") if (!topic || strlen(topic) == 0) { int i; int items_per_column = (QL_HELP_COUNT + 2) / 3; FILE *output; output = PageOutput(items_per_column + 1, pager); fputs(_("Available help:\n"), output); for (i = 0; i < items_per_column; i++) { fprintf(output, " %-26s%-26s", VALUE_OR_NULL(QL_HELP[i].cmd), VALUE_OR_NULL(QL_HELP[i + items_per_column].cmd)); if (i + 2 * items_per_column < QL_HELP_COUNT) fprintf(output, "%-26s", VALUE_OR_NULL(QL_HELP[i + 2 * items_per_column].cmd)); fputc('\n', output); } /* Only close if we used the pager */ if (output != stdout) { pclose(output); #ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL); #endif } } else { int i; bool help_found = false; FILE *output; size_t len; int nl_count = 0; char *ch; /* don't care about trailing spaces */ len = strlen(topic); while (topic[len - 1] == ' ') len--; /* Count newlines for pager */ for (i = 0; QL_HELP[i].cmd; i++) { if (strncasecmp(topic, QL_HELP[i].cmd, len) == 0 || strcmp(topic, "*") == 0) { nl_count += 5; for (ch = QL_HELP[i].syntax; *ch != '\0'; ch++) if (*ch == '\n') nl_count++; /* If we have an exact match, exit. Fixes \h SELECT */ if (strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } output = PageOutput(nl_count, pager); for (i = 0; QL_HELP[i].cmd; i++) { if (strncasecmp(topic, QL_HELP[i].cmd, len) == 0 || strcmp(topic, "*") == 0) { help_found = true; fprintf(output, _("Command: %s\n" "Description: %s\n" "Syntax:\n%s\n\n"), QL_HELP[i].cmd, gettext(QL_HELP[i].help), gettext(QL_HELP[i].syntax)); /* If we have an exact match, exit. Fixes \h SELECT */ if (strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } if (!help_found) fprintf(output, _("No help available for \"%-.*s\".\nTry \\h with no arguments to see available help.\n"), (int) len, topic); /* Only close if we used the pager */ if (output != stdout) { pclose(output); #ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL); #endif } } }