]> jfr.im git - irc/quakenet/newserv.git/blob - lua/luadb.c
pgsql is now optional for lua.
[irc/quakenet/newserv.git] / lua / luadb.c
1 #include "lua.h"
2 #include "luabot.h"
3
4 #include "../config.h"
5
6 #ifdef HAVE_PGSQL
7 #include "../pqsql/pqsql.h"
8
9 static int lua_dbcreatequery(lua_State *ps) {
10 char *s = (char *)lua_tostring(ps, 1);
11
12 if(!s)
13 LUA_RETURN(ps, LUA_FAIL);
14
15 pqcreatequery(s);
16 LUA_RETURN(ps, LUA_OK);
17 }
18
19 /* TODO */
20 /*
21 static int lua_dbloadtable(lua_State *ps) {
22 lua_list *l = lua_listfromstate(ps);
23 if(!l)
24 LUA_RETURN(ps, LUA_FAIL);
25
26 }
27 */
28
29 typedef struct lua_callback {
30 lua_list *l;
31 long handler, args;
32 } lua_callback;
33
34 /* hack */
35 PGresult *pgres;
36
37 static int lua_dbnumfields(lua_State *ps) {
38 lua_pushint(ps, PQnfields(pgres));
39
40 return 1;
41 }
42
43 static int lua_dbnumrows(lua_State *ps) {
44 lua_pushint(ps, PQntuples(pgres));
45
46 return 1;
47 }
48
49 static int lua_dbgetvalue(lua_State *ps) {
50 char *r;
51 int tuple, field, len;
52
53 if(!lua_isint(ps, 1) || !lua_isint(ps, 2))
54 return 0;
55
56 tuple = lua_toint(ps, 1);
57 field = lua_toint(ps, 2);
58
59 r = PQgetvalue(pgres, lua_toint(ps, 1), lua_toint(ps, 2));
60 len = PQgetlength(pgres, tuple, field);
61
62 lua_pushlstring(ps, r, len); /* safe?! */
63
64 return 1;
65 }
66
67 void lua_dbcallback(PGconn *dbconn, void *arg) {
68 pgres = PQgetResult(dbconn);
69 lua_callback *c = (lua_callback *)arg;
70
71 if(!lua_listexists(c->l)) {
72 luafree(c);
73 return;
74 }
75
76 if(PQresultStatus(pgres) != PGRES_TUPLES_OK) {
77 _lua_vpcall(c->l->l, (void *)c->handler, LUA_POINTERMODE, "bR", 0, c->args);
78
79 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->handler);
80 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->args);
81 luafree(c);
82 return;
83 }
84
85 _lua_vpcall(c->l->l, (void *)c->handler, LUA_POINTERMODE, "bR", 1, c->args);
86
87 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->handler);
88 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->args);
89 luafree(c);
90 PQclear(pgres);
91 pgres = NULL;
92 }
93
94 static int lua_dbquery(lua_State *ps) {
95 lua_list *l = lua_listfromstate(ps);
96 char *q = (char *)lua_tostring(ps, 1);
97 lua_callback *cb;
98
99 /* what happens if 3 isn't there? */
100 if(!l || !q)
101 LUA_RETURN(ps, LUA_FAIL);
102
103 if(!lua_isfunction(ps, 2)) {
104 pqquery(q);
105 LUA_RETURN(ps, LUA_OK);
106 }
107
108 cb = (lua_callback *)luamalloc(sizeof(lua_callback));
109 if(!cb)
110 LUA_RETURN(ps, LUA_FAIL);
111
112 cb->l = l;
113 cb->args = luaL_ref(ps, LUA_REGISTRYINDEX);
114 cb->handler = luaL_ref(ps, LUA_REGISTRYINDEX);
115
116 pqasyncquery(lua_dbcallback, cb, q);
117
118 LUA_RETURN(ps, LUA_OK);
119 }
120
121 static int lua_dbescape(lua_State *ps) {
122 char ebuf[8192 * 2];
123 char *s = (char *)lua_tostring(ps, 1);
124 int len;
125 size_t elen;
126
127 if(!s)
128 return 0;
129
130 len = lua_strlen(ps, 1);
131 if(len > sizeof(ebuf) / 2 - 5)
132 return 0;
133
134 elen = PQescapeString(ebuf, s, len);
135 lua_pushlstring(ps, ebuf, elen);
136
137 return 1;
138 }
139
140 void lua_registerdbcommands(lua_State *l) {
141 lua_register(l, "db_createquery", lua_dbcreatequery);
142
143 /* lua_register(l, "db_loadtable", lua_dbloadtable); */
144
145 lua_register(l, "db_query", lua_dbquery);
146 lua_register(l, "db_escape", lua_dbescape);
147 lua_register(l, "db_numfields", lua_dbnumfields);
148 lua_register(l, "db_numrows", lua_dbnumrows);
149 lua_register(l, "db_getvalue", lua_dbgetvalue);
150 }
151
152 #else
153
154 void lua_registerdbcommands(lua_State *l) {
155 }
156
157 #endif