diff options
author | 2022-08-10 17:51:24 +0200 | |
---|---|---|
committer | 2022-08-10 17:51:24 +0200 | |
commit | 970c73444522a4b4988abaa1746b79df1bfa1137 (patch) | |
tree | 5aa64464faba010eb68f5561717774571391dc37 | |
parent | 69b1abc9fc40574a3756fee5b688b73fdf932e21 (diff) | |
download | qureje-970c73444522a4b4988abaa1746b79df1bfa1137.tar.gz qureje-970c73444522a4b4988abaa1746b79df1bfa1137.zip |
Add connection to PostgreSQL
By Makefile you can now decide what driver to include in this program
-rw-r--r-- | database.c | 136 | ||||
-rw-r--r-- | database.h | 17 | ||||
-rw-r--r-- | main.c | 117 | ||||
-rw-r--r-- | postgresql.c | 123 | ||||
-rw-r--r-- | postgresql.h | 24 | ||||
-rw-r--r-- | utils.c | 29 | ||||
-rw-r--r-- | utils.h | 24 |
7 files changed, 334 insertions, 136 deletions
@@ -14,49 +14,145 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ + */ -#include <libpq-fe.h> -#include "database.h" +#include <stdio.h> #include <stdlib.h> #include <string.h> -static int MAX_SIZE_DBMS_NAME = 7; /* including \0 */ -static int MAX_SIZE_CONN_FIELD = 129; /* including \0 */ - -static char * -str_create(int size) -{ - char *str = (char *) malloc(sizeof (char) * size); - memset(str, '\0', size); +#include "database.h" +#include "utils.h" +#ifdef PSQL +#include "postgresql.h" +#endif - return str; -} +static int MAX_SIZE_DBMS_NAME = 15; +static int MAX_SIZE_CONN_FIELD = 129; /* including \0 */ qureje_conn * qureje_conn_create() { qureje_conn *conn = (qureje_conn *) malloc (sizeof (qureje_conn)); - conn->type = str_create(MAX_SIZE_DBMS_NAME); - conn->host = str_create(MAX_SIZE_CONN_FIELD); - conn->user = str_create(MAX_SIZE_CONN_FIELD); - conn->password = str_create(MAX_SIZE_CONN_FIELD); - conn->dbname = str_create(MAX_SIZE_CONN_FIELD); + conn->type = NONE; + conn->host = strcrt(MAX_SIZE_CONN_FIELD); + conn->user = strcrt(MAX_SIZE_CONN_FIELD); + conn->password = strcrt(MAX_SIZE_CONN_FIELD); + conn->dbname = strcrt(MAX_SIZE_CONN_FIELD); return conn; } +static int +opt_get_type(qureje_conn *conn, char *opt, char *optv) +{ + if (strcmp("-t", opt) == 0 || strcmp("--type", opt) == 0) { + if (strcmp("psql", optv) == 0) { + conn->type = POSTGRESQL; + } else if (strcmp("mariadb", optv) == 0) { + conn->type = MARIADB; + } else { + conn->type = NONE; + } + + return 0; + } + + return 1; +} + +static int +opt_get_user(qureje_conn *conn, char *opt, char *optv) +{ + if (strcmp("-u", opt) == 0 || strcmp("--username", opt) == 0) { + strncpy(conn->user, optv, MAX_SIZE_CONN_FIELD); + return 0; + } + + return 1; +} + +static void +opt_get_dbname(qureje_conn *conn, char *opt) +{ + strncpy(conn->dbname, opt, MAX_SIZE_DBMS_NAME); +} + qureje_conn * qureje_conn_create_from_arguments(int argc, char **argv) { + int i, j; qureje_conn *conn = qureje_conn_create(); + /* + Parameters: + -t, --type + -u, --username + -p, --password + -P, --no-password + -h, --hostname + */ + for (i = 1, j = 2; i < argc; i++, j++) { + if (opt_get_type(conn, argv[i], argv[j]) == 0 + || opt_get_user(conn, argv[i], argv[j]) == 0) { + i = j++; + continue; + } + + /* this call must be the last one */ + opt_get_dbname(conn, argv[i]); + } return conn; } -void -qureje_connect() +int +qureje_connect(qureje_conn *conn) +{ + #ifdef PSQL + if (conn->type == POSTGRESQL) { + printf("Establishing a PostgreSQL connection.\n"); + return qureje_psql_connect(conn); + } + #endif + + return 0; +} + +char * +qureje_get_type(qureje_conn *conn) +{ + int max_length = 11; + char *str_type = strcrt(max_length); + + switch (conn->type) { + case POSTGRESQL: + #ifdef PSQL + strncpy(str_type, "PostgreSQL", max_length); + #else + printf("This program is not compiled with the support to PostgreSQL!\n"); + exit(1); + #endif + break; + case MARIADB: + strncpy(str_type, "MariaDB", max_length); + break; + default: + strncpy(str_type, "None", max_length); + break; + } + + return str_type; +} + +char * +qureje_get_user(qureje_conn *conn) +{ + return conn->user; +} + +char * +qureje_get_dbname(qureje_conn *conn) { + return conn->dbname; } @@ -14,21 +14,32 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ + */ #ifndef __DATABASE_H__ #define __DATABASE_H__ +typedef enum { + NONE, + POSTGRESQL, + MARIADB +} qureje_dbtype; + typedef struct { - char *type; + qureje_dbtype type; char *host; char *user; char *password; char *dbname; + void *conn; /* implementation based connection data */ } qureje_conn; -void qureje_connect(); +int qureje_connect(qureje_conn *); qureje_conn *qureje_conn_create(); qureje_conn *qureje_conn_create_from_arguments(int, char **); +char *qureje_get_type(qureje_conn *); +char *qureje_get_user(qureje_conn *); +char *qureje_get_dbname(qureje_conn *); +void qureje_free(qureje_conn *); #endif @@ -16,131 +16,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <libpq-fe.h> - #include <stdio.h> #include <stdlib.h> #include <string.h> #include "database.h" -char *qureje_parse_arguments(int, char **, qureje_conn *); -char *qureje_param(char *, char *); - int main(int argc, char** argv) { qureje_conn *conn = qureje_conn_create_from_arguments(argc, argv); - PGconn *conn1; - /*PGresult *res;*/ - /*int rowcount, colcount, i, j, firstcol;*/ - - char *conninfo = qureje_parse_arguments(argc, argv, conn); - printf("%s\n", conn->type); - - /* parameter type should be guessed by PostgreSQL */ - /*const Oid paramTypes[1] = { 0 };*/ - - /* parameter value */ - /*const char * const paramValues[1] = { "pg_database" };*/ - /* - * Using an empty connectstring will use default values for everything. - * If set, the environment variables PGHOST, PGDATABASE, PGPORT and - * PGUSER will be used. - */ - conn1 = PQconnectdb(conninfo); - - /* - * This can only happen if there is not enough memory - * to allocate the PGconn structure. - */ - if (conn1 == NULL) { - fprintf(stderr, "Out of memory connecting to PostgreSQL.\n"); - return 1; + if (qureje_connect(conn) != 0) { + fprintf(stderr, "Cannot establish connection with the database!\n"); + return 1; } - /* check if the connection attempt worked */ - if (PQstatus(conn1) != CONNECTION_OK) { - fprintf(stderr, "%s\n", PQerrorMessage(conn1)); - /* - * Even if the connection failed, the PGconn structure has been - * allocated and must be freed. - */ - PQfinish(conn1); - return 1; - } - printf("Hello, World!\n"); + printf("Connection established.\n"); return 0; } - -char * -qureje_parse_arguments(int argc, char **argv, qureje_conn *conn) -{ - int i = 1, totsize = 0, paramc = 0, verbose = 0; - char *conninfo; - char **paramv; - - if (argc <= 1) { - return ""; - } - - paramv = (char **) malloc(sizeof (char **) * argc); - - if (strcmp ("-t", argv[i]) == 0 && i < argc) { - conn->type = argv[++i]; - } - - if (conn->type == NULL) { - puts("You must specify the database driver."); - exit(1); - return NULL; - } - - while (i < argc) { - /* these are all options with a value */ - if (strcmp ("-h", argv[i]) == 0) { - paramv[paramc++] = qureje_param("host", argv[++i]); - } else if (strcmp ("-U", argv[i]) == 0) { - paramv[paramc++] = qureje_param("user", argv[++i]); - } else if (strcmp ("-v", argv[i]) == 0) { - verbose = 1; - } - - ++i; - } - - for (i = 0; i < paramc; i++) { - totsize += strlen(paramv[i]); - if (i < paramc) totsize ++; - } - - conninfo = (char *) malloc(sizeof (char *) * totsize); - memset (conninfo, '\0', totsize); - - for (i = 0; i < paramc; i++) { - strcat(conninfo, paramv[i]); - if (i < argc - 1) strcat(conninfo, " "); - } - - if (verbose == 1) { - printf("connection info:\n%s\n", conninfo); - } - - return conninfo; -} - -char * -qureje_param(char *parname, char *src) -{ - /* the src's legth + the paraname length + '=' + '\0' */ - int strc = strlen(src) + strlen(parname) + 2; - char *param = (char *) malloc(sizeof (char) * strc); - memset(param, '\0', strc); - - strcat(param, parname); - strcat(param, "="); - strcat(param, src); - - return param; -} diff --git a/postgresql.c b/postgresql.c new file mode 100644 index 0000000..5f799bf --- /dev/null +++ b/postgresql.c @@ -0,0 +1,123 @@ +/* + qureje is a database managment tool. + Copyright (C) 2022 Alessandro Iezzi <aiezzi AT alessandroiezzi PERIOD it> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <libpq-fe.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "database.h" +#include "utils.h" + +static char * +parameter(const char *key, char *value) +{ + int vsize = 0; + char *param = NULL; + + if (value == NULL || (vsize = strlen(value)) <= 0) return NULL; + + param = strcrt(strlen(key) + vsize + 2); + strcat(param, key); + strcat(param, "="); + strcat(param, value); + strcat(param, " "); + + return param; +} + +static void +prmcat(char *conninfo, char *prm) +{ + if (prm != NULL) { + strcat(conninfo, prm); + free(prm); + } +} + +static char * +create_connection_info(qureje_conn *conn) +{ + int strsize = 0; + char *conninfo, + *prmusr = NULL, + *prmdb = NULL; + + if ((prmusr = parameter("user", conn->user)) != NULL) { + strsize += strlen(prmusr); + } + + if ((prmdb = parameter("dbname", conn->dbname)) != NULL) { + strsize += strlen(prmdb); + } + + conninfo = strcrt(strsize + 1); + + prmcat(conninfo, prmusr); + prmcat(conninfo, prmdb ); + + return conninfo; +} + +int +qureje_psql_connect(qureje_conn *conn) +{ + char *conninfo = NULL; + PGconn *pgconn; + + if (conn == NULL) return 1; + + conninfo = create_connection_info(conn); + /* + * Using an empty connectstring will use default values for everything. + * If set, the environment variables PGHOST, PGDATABASE, PGPORT and + * PGUSER will be used. + */ + pgconn = PQconnectdb(conninfo); + + free(conninfo); + + /* + * This can only happen if there is not enough memory + * to allocate the PGconn structure. + */ + if (pgconn == NULL) { + fprintf(stderr, "Out of memory connecting to PostgreSQL.\n"); + + return 1; + } + + /* check if the connection attempt worked */ + if (PQstatus(pgconn) != CONNECTION_OK) { + fprintf(stderr, "%s\n", PQerrorMessage(pgconn)); + /* + * Even if the connection failed, the PGconn structure has been + * allocated and must be freed. + */ + PQfinish(pgconn); + + return 1; + } + + /* this program expects the database to return data in UTF-8 */ + PQsetClientEncoding(pgconn, "UTF8"); + + conn->conn = pgconn; + + return 0; +} diff --git a/postgresql.h b/postgresql.h new file mode 100644 index 0000000..1e4df10 --- /dev/null +++ b/postgresql.h @@ -0,0 +1,24 @@ +/* + qureje is a database managment tool. + Copyright (C) 2022 Alessandro Iezzi <aiezzi AT alessandroiezzi PERIOD it> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __POSTGRESQL_H__ +#define __POSTGRESQL_H__ + +int qureje_psql_connect(); + +#endif @@ -0,0 +1,29 @@ +/* + qureje is a database managment tool. + Copyright (C) 2022 Alessandro Iezzi <aiezzi AT alessandroiezzi PERIOD it> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> + +char * +strcrt(int size) +{ + char *str = (char *) malloc(sizeof (char) * size); + memset(str, '\0', size); + + return str; +} @@ -0,0 +1,24 @@ +/* + qureje is a database managment tool. + Copyright (C) 2022 Alessandro Iezzi <aiezzi AT alessandroiezzi PERIOD it> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +char *strcrt(int); + +#endif |