#include #include #include #include #include "db.h" #define DB_MAX_FIELDS 64 #define DB_MAX_CHAR 256 static PGconn *g_pConnection = NULL; static PGresult *g_pResult = NULL; static char g_pError[DB_MAX_CHAR]; static int db_clear_error(void) { memset(&g_pError, 0, (size_t)(sizeof(char) * DB_MAX_CHAR)); return DB_OK; } // db_clear_error static int db_set_error(const char *f_pError) { db_clear_error(); strcpy(g_pError, f_pError); return DB_OK; } // db_set_error static void db_raise_warning(void) { // printf("Database exception!\n"); printf("%s", g_pError); } // db_raise_warning static void db_raise_error(void) { db_raise_warning(); db_close(); exit(1); } // db_raise_error static char *db_get_error(void) { return g_pError; } // db_get_error static int db_check_connection(void) { char l_pError[DB_MAX_CHAR]; if (g_pConnection == NULL) { sprintf(l_pError, "Database connection lost!"); db_set_error(l_pError); db_raise_error(); return DB_NO_CONNECTION; } return DB_OK; } // db_check_connection static int db_check_result(void) { char l_pError[DB_MAX_CHAR]; if (g_pResult == NULL) { sprintf(l_pError, "Incorrect PostgreSQL result."); db_set_error(l_pError); db_raise_warning(); return DB_INCORRECT_RESULT; } return DB_OK; } // db_check_result int db_init(void) { char l_pError[DB_MAX_CHAR]; g_pConnection = PQsetdbLogin(PGHOST, PGPORT, PGOPTIONS, PGTTY, DBNAME, LOGIN, PWD); if (PQstatus(g_pConnection) == CONNECTION_BAD) { sprintf(l_pError, "Connection to database '%s' failed.\n%s", DBNAME, PQerrorMessage(g_pConnection)); db_set_error(l_pError); db_raise_error(); return DB_NO_CONNECTION; } db_clear_error(); return DB_OK; } // db_init int db_close(void) { PQclear(g_pResult); PQfinish(g_pConnection); return DB_OK; } // db_close int db_output(void) { int l_iNTuples, l_iNFields; char l_pText[DB_MAX_CHAR]; int l_iColumnWidth[DB_MAX_FIELDS]; int l_iMaxColumnWidth[DB_MAX_FIELDS]; int i, j, k, l; // check the db connection if (db_check_connection() != DB_OK) { exit(1); return DB_COULD_NOT_OUTPUT; } // check the validity of the result if (db_check_result() != DB_OK) { return DB_COULD_NOT_OUTPUT; } l_iNTuples = PQntuples(g_pResult); l_iNFields = PQnfields(g_pResult); // copy all tuple names incl. field values for (i = 0; i < l_iNFields; i++) { k = 0; for (j = 0; j < l_iNTuples; j++) { strcpy(l_pText, PQgetvalue(g_pResult, j, i)); l_iColumnWidth[k] = (int)strlen(l_pText); k++; } strcpy(l_pText, PQfname(g_pResult, i)); l_iMaxColumnWidth[i] = (int)strlen(l_pText); for (j = 1; j < l_iNTuples; j++) { l_iMaxColumnWidth[i] = max(l_iMaxColumnWidth[i], l_iColumnWidth[j]); } } printf("\n"); // print column names for (i = 0; i < l_iNFields; i++) { int len; if (i) printf("| "); strcpy(l_pText, PQfname(g_pResult, i)); printf("%s", l_pText); len = (int)strlen(PQfname(g_pResult, i)) - 1; if (i < l_iNFields - 1) { for (k = 0; k < l_iMaxColumnWidth[i] - len; k++) { printf(" "); } } } printf("\n"); // print horizontal line l = 0; for (k = 0; k < l_iNFields; k++) l += l_iMaxColumnWidth[k]; l += (l_iNFields - 1) * 3; for (k = 0; k < l; k++) printf("-"); printf("\n"); // print row values for (i = 0; i < l_iNTuples; i++) { for (j = 0; j < l_iNFields; j++) { int len; if (j) printf("| "); strcpy(l_pText, PQgetvalue(g_pResult, i, j)); printf("%s ", l_pText); len = (int)strlen(l_pText) - 1; if (j < l_iNFields - 1) { for (k = 1; k < l_iMaxColumnWidth[j] - len; k++) { printf(" "); } } } printf("\n"); } printf("(%d rows)\n\n", l_iNTuples); return DB_OK; } // db_output int db_execute(const char* f_pQuery) { char l_pError[DB_MAX_CHAR]; char l_pCmdStatus[DB_MAX_CHAR]; // check the db connection if (db_check_connection() != DB_OK) { exit(1); return DB_COULD_NOT_EXECUTE; } g_pResult = PQexec(g_pConnection, f_pQuery); if (g_pResult == NULL || (PQresultStatus(g_pResult) != PGRES_COMMAND_OK && PQresultStatus(g_pResult) != PGRES_TUPLES_OK)) { sprintf(l_pError, "Unable to execute query: %s\n%s", f_pQuery, PQerrorMessage(g_pConnection)); db_set_error(l_pError); db_raise_warning(); return DB_COULD_NOT_EXECUTE; } sprintf(l_pCmdStatus, "%s", PQcmdStatus(g_pResult)); if (!strcmp(l_pCmdStatus, "SELECT")) { db_output(); } else { printf("\n%s\n\n", l_pCmdStatus); } return DB_OK; } // db_execute