summaryrefslogtreecommitdiffstats
path: root/db_demo/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'db_demo/db.c')
-rw-r--r--db_demo/db.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/db_demo/db.c b/db_demo/db.c
new file mode 100644
index 0000000..3a58c3f
--- /dev/null
+++ b/db_demo/db.c
@@ -0,0 +1,259 @@
+#include <libpq-fe.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#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]);
+ }
+ }
+
+ // 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");
+ }
+
+ 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("%s\n", l_pCmdStatus);
+ }
+
+ return DB_OK;
+
+} // db_execute