diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/psql_lisp.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/modules/psql_lisp.c b/modules/psql_lisp.c new file mode 100644 index 0000000..87ea748 --- /dev/null +++ b/modules/psql_lisp.c @@ -0,0 +1,85 @@ +#include <stdio.h> +#include <stdlib.h> +#include <libpq-fe.h> +#include "../lisp_api.h" + +value *hello_fun(env *e, value *args) { + printf("Hello from dynamically loaded module!\n"); + return make_nil(); +} + +value *pg_execute(env *e, value *args) { + value *fst_arg = eval(e, car(args)); + value *snd_arg = eval(e, car(cdr(args))); + + if (fst_arg->type != VT_STRING) { + printf("not a string:"); + println_value(fst_arg); + return make_nil(); //TODO: make error + } + if (snd_arg->type != VT_STRING) { + printf("not a string:"); + println_value(snd_arg); + return make_nil(); //TODO: make error + } + + const char *conn_str = fst_arg->as.str; + const char *query_str = snd_arg->as.str; + + PGconn *conn = PQconnectdb(conn_str); + if (PQstatus(conn) != CONNECTION_OK) { + fprintf(stderr, "Connection failed: %s", PQerrorMessage(conn)); + PQfinish(conn); + return make_nil(); //TODO: make error + } + + PGresult *res = PQexec(conn, query_str); + if (PQresultStatus(res) != PGRES_TUPLES_OK) { + fprintf(stderr, "Query failed: %s", PQerrorMessage(conn)); + PQclear(res); + PQfinish(conn); + return make_nil(); //TODO: make error + } + + int rows = PQntuples(res); + int cols = PQnfields(res); + + value *table = make_nil(); + + for (int row = 0; row < rows; row++) { + value *row_val = make_nil(); + for (int col = 0; col < cols; col++) { + switch (PQftype(res, col)) { + case 23: + row_val=cons(make_int(atoi(PQgetvalue(res, row, col))), row_val); + break; + case 1700: + case 20: + row_val=cons(make_int(atof(PQgetvalue(res, row, col))), row_val); + break; + default: + const char *str; + row_val=cons(make_string(PQgetvalue(res, row, col)), row_val); + break; + } + } + table = cons(reverse(row_val), table); + } + PQclear(res); + PQfinish(conn); + + table = reverse(table); + return table; +} + +module_export *module_init() { + static module_export exports[2]; + + exports[0].name = "pg_execute"; + exports[0].v = make_procedure(&pg_execute); + + exports[1].name = NULL; + exports[1].v = NULL; + + return exports; +} |
