From 41714280760205215361ad268d712eccb542c46b Mon Sep 17 00:00:00 2001 From: iridiumR Date: Wed, 29 Mar 2023 23:01:10 +0800 Subject: [PATCH] feat(builtin): add support for pgsql --- Makefile | 4 +- builtin.c | 4 +- builtin.h | 5 +++ config.h | 7 ++++ postgres.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ postgres.h | 10 +++++ 6 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 postgres.c create mode 100644 postgres.h diff --git a/Makefile b/Makefile index 40b0890..1201a22 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SHELL := /bin/bash CC = gcc -SRC = main.c loop.c exec.c line.c builtin.c -LINK= -lreadline +SRC = main.c loop.c exec.c line.c builtin.c postgres.c +LINK= -lreadline -lpq OBJ = $(SRC:.c=.ro) DBGOBJ = $(SRC:.c=.do) EXE = dish diff --git a/builtin.c b/builtin.c index 2d57ea4..088ed59 100644 --- a/builtin.c +++ b/builtin.c @@ -22,11 +22,11 @@ int dish_echo(char **args); int dish_laststatus(char **args); char *builtin_cmd[] = {"cd", "help", "exit", "clear", "setenv", - "getenv", "unsetenv", "echo", "laststatus"}; + "getenv", "unsetenv", "echo", "laststatus", defined_builtin}; int (*builtin_func[])(char **) = { &dish_cd, &dish_help, &dish_exit, &dish_clear, &dish_setenv, - &dish_getenv, &dish_unsetenv, &dish_echo, &dish_laststatus}; + &dish_getenv, &dish_unsetenv, &dish_echo, &dish_laststatus, defined_builtin_func}; int getBuiltinNum() { return sizeof(builtin_cmd) / sizeof(char *); } diff --git a/builtin.h b/builtin.h index b67933f..3b5bd1a 100644 --- a/builtin.h +++ b/builtin.h @@ -8,6 +8,11 @@ #define _BUILTIN_H_ #include "config.h" + +#ifdef POSTGRES +#include "postgres.h" +#endif + int getBuiltinNum(); #endif \ No newline at end of file diff --git a/config.h b/config.h index e9b70f1..d192267 100644 --- a/config.h +++ b/config.h @@ -17,4 +17,11 @@ #define ANSI_COLOR_CYAN "\x1b[36m" #define ANSI_COLOR_RESET "\x1b[0m" +/* enable postgres support*/ +#define POSTGRES +#ifdef POSTGRES +#define defined_builtin "pg" +#define defined_builtin_func &dish_pg +#endif + #endif \ No newline at end of file diff --git a/postgres.c b/postgres.c new file mode 100644 index 0000000..11d7f11 --- /dev/null +++ b/postgres.c @@ -0,0 +1,114 @@ +#include "postgres.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef POSTGRES + +static PGconn *conn; + +int pg_connect(char *args) { + if (args == NULL) { + fprintf(stderr, "pg connect: need dbname\n"); + return 1; + } + conn = PQsetdbLogin("localhost", "5432", NULL, NULL, args, "postgres", NULL); + if (PQstatus(conn) == CONNECTION_BAD) { + fprintf(stderr, "pg connect: Connection to database failed: %s", + PQerrorMessage(conn)); + return 1; + } + return 0; +} +int pg_list() { + if (conn == NULL) { + fprintf(stderr, "pg list: not connected to database\n"); + return 1; + } + PGresult *res = + PQexec(conn, "SELECT table_name FROM information_schema.tables WHERE " + "table_schema = 'public'"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) { + fprintf(stderr, "pg list: No data retrieved\n"); + PQclear(res); + return 1; + } + int rows = PQntuples(res); + for (int i = 0; i < rows; i++) { + if (i != 0) + printf(", "); + printf("%s ", PQgetvalue(res, i, 0)); + } + printf("\n"); + return 0; +} + +int pg_show(char *args) { + if (conn == NULL) { + fprintf(stderr, "pg show: not connected to database\n"); + return 1; + } + if (args == NULL) { + fprintf(stderr, "pg show: need table name\n"); + return 1; + } + char *query = malloc(100); + sprintf(query, "SELECT * FROM %s", args); + PGresult *res = PQexec(conn, query); + if (PQresultStatus(res) != PGRES_TUPLES_OK) { + fprintf(stderr, "pg show: No data retrieved\n"); + PQclear(res); + return 1; + } + int rows = PQntuples(res); + int cols = PQnfields(res); + + //print header + for (int i = 0; i < cols; i++) { + if (i != 0) + printf(", "); + printf("%s ", PQfname(res, i)); + } + printf("\n"); + //print whole table + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (j != 0) + printf(", "); + printf("%s ", PQgetvalue(res, i, j)); + } + printf("\n"); + } + + + printf("\n"); + free(query); + return 0; +} + +int dish_pg(char **args) { + if (args[1] == NULL) { + fprintf(stderr, "pg: need arguments\n\ + possible arguments:\n\ + connect: connect to database\n\ + list: list all tables\n\ + show: show all contents of a table\n"); + return 1; + } + if (strcmp(args[1], "connect") == 0) { + pg_connect(args[2]); + } + if (strcmp(args[1], "list") == 0) { + pg_list(); + } + if (strcmp(args[1], "show") == 0) { + pg_show(args[2]); + } + + return 0; +} + +#endif \ No newline at end of file diff --git a/postgres.h b/postgres.h new file mode 100644 index 0000000..8f509f8 --- /dev/null +++ b/postgres.h @@ -0,0 +1,10 @@ +#include "config.h" + +#ifdef POSTGRES +#ifndef __POSTGRES_H__ +#define __POSTGRES_H__ + +int dish_pg(char **args); + +#endif +#endif \ No newline at end of file