]> jfr.im git - irc/quakenet/newserv.git/blame - lua/luadb.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / lua / luadb.c
CommitLineData
55cee062
CP
1#include "lua.h"
2#include "luabot.h"
d7839cef 3
dad344a7 4#include "../dbapi2/dbapi2.h"
d7839cef 5
dad344a7 6static DBAPIConn *luadb;
ee8cd7d0 7
dad344a7
CP
8typedef struct lua_callback {
9 lua_list *l;
10 long handler, args;
11} lua_callback;
55cee062
CP
12
13static int lua_dbcreatequery(lua_State *ps) {
14 char *s = (char *)lua_tostring(ps, 1);
15
dad344a7
CP
16 if(!luadb)
17 LUA_RETURN(ps, LUA_FAIL);
18
55cee062
CP
19 if(!s)
20 LUA_RETURN(ps, LUA_FAIL);
21
dad344a7 22 luadb->unsafecreatetable(luadb, NULL, NULL, "%s", s);
55cee062
CP
23 LUA_RETURN(ps, LUA_OK);
24}
25
dad344a7
CP
26static int lua_dbtablename(lua_State *ps) {
27 char *s = (char *)lua_tostring(ps, 1);
28
29 if(!luadb)
55cee062
CP
30 LUA_RETURN(ps, LUA_FAIL);
31
dad344a7
CP
32 if(!s)
33 LUA_RETURN(ps, LUA_FAIL);
34
35 char *tablename = luadb->tablename(luadb, s);
36 if(!tablename)
37 LUA_RETURN(ps, LUA_FAIL);
38
39 lua_pushstring(ps, tablename);
40 return 1;
55cee062 41}
55cee062 42
dad344a7
CP
43const static DBAPIResult *active_result;
44static void lua_dbcallback(const DBAPIResult *result, void *tag) {
45 lua_callback *c = (lua_callback *)tag;
46
47 if(!lua_listexists(c->l)) {
48 luafree(c);
49 return;
50 }
51
52 active_result = result;
53 _lua_vpcall(c->l->l, (void *)c->handler, LUA_POINTERMODE, "bR", result && result->success ? 1 : 0, c->args);
54 active_result = NULL;
55cee062 55
dad344a7
CP
56 if(result)
57 result->clear(result);
58
59 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->handler);
60 luaL_unref(c->l->l, LUA_REGISTRYINDEX, c->args);
61 luafree(c);
62}
55cee062
CP
63
64static int lua_dbnumfields(lua_State *ps) {
dad344a7
CP
65 if(!luadb)
66 return 0;
67
68 if(!active_result)
69 return 0;
55cee062 70
dad344a7 71 lua_pushint(ps, active_result->fields);
55cee062
CP
72 return 1;
73}
74
dad344a7
CP
75static int lua_dbgetvalue(lua_State *ps) {
76 if(!luadb)
77 return 0;
78
79 if(!active_result)
80 return 0;
55cee062 81
ee8cd7d0 82 if(!lua_isint(ps, 1))
55cee062
CP
83 return 0;
84
dad344a7
CP
85 int field = lua_toint(ps, 1);
86 if(field < 0 || field >= active_result->fields)
87 return 0;
88
89 char *value = active_result->get(active_result, field);
90 /* bit rubbish, no way to get the length... binary data is out then */
91 lua_pushstring(ps, value);
55cee062
CP
92
93 return 1;
94}
55cee062 95
dad344a7
CP
96static int lua_dbnextrow(lua_State *ps) {
97 if(!luadb)
98 return 0;
55cee062 99
dad344a7
CP
100 if(!active_result)
101 return 0;
55cee062 102
dad344a7
CP
103 int r = active_result->next(active_result);
104 lua_pushboolean(ps, r?1:0);
105 return 1;
55cee062
CP
106}
107
108static int lua_dbquery(lua_State *ps) {
109 lua_list *l = lua_listfromstate(ps);
110 char *q = (char *)lua_tostring(ps, 1);
111 lua_callback *cb;
112
dad344a7
CP
113 if(!luadb)
114 LUA_RETURN(ps, LUA_FAIL);
115
55cee062
CP
116 /* what happens if 3 isn't there? */
117 if(!l || !q)
118 LUA_RETURN(ps, LUA_FAIL);
119
120 if(!lua_isfunction(ps, 2)) {
dad344a7 121 luadb->unsafesquery(luadb, "%s", q);
55cee062
CP
122 LUA_RETURN(ps, LUA_OK);
123 }
124
d0e17ef9 125 cb = (lua_callback *)luamalloc(sizeof(lua_callback));
55cee062
CP
126 if(!cb)
127 LUA_RETURN(ps, LUA_FAIL);
128
129 cb->l = l;
130 cb->args = luaL_ref(ps, LUA_REGISTRYINDEX);
131 cb->handler = luaL_ref(ps, LUA_REGISTRYINDEX);
132
dad344a7 133 luadb->unsafequery(luadb, lua_dbcallback, cb, "%s", q);
55cee062
CP
134
135 LUA_RETURN(ps, LUA_OK);
136}
137
138static int lua_dbescape(lua_State *ps) {
ee8cd7d0 139 char ebuf[8192 * 2 + 1];
55cee062
CP
140 char *s = (char *)lua_tostring(ps, 1);
141 int len;
55cee062 142
dad344a7
CP
143 if(!luadb)
144 return 0;
145
55cee062
CP
146 if(!s)
147 return 0;
148
149 len = lua_strlen(ps, 1);
150 if(len > sizeof(ebuf) / 2 - 5)
151 return 0;
152
dad344a7 153 luadb->escapestring(luadb, ebuf, s, len);
ee8cd7d0 154 lua_pushstring(ps, ebuf);
55cee062
CP
155
156 return 1;
157}
158
159void lua_registerdbcommands(lua_State *l) {
dad344a7 160 lua_register(l, "db_tablename", lua_dbtablename);
55cee062 161
dad344a7 162 lua_register(l, "db_createquery", lua_dbcreatequery);
55cee062
CP
163 lua_register(l, "db_query", lua_dbquery);
164 lua_register(l, "db_escape", lua_dbescape);
dad344a7 165
55cee062 166 lua_register(l, "db_numfields", lua_dbnumfields);
dad344a7
CP
167 lua_register(l, "db_getvalue", lua_dbgetvalue);
168 lua_register(l, "db_nextrow", lua_dbnextrow);
d7839cef 169
dad344a7 170 luadb = dbapi2open(NULL, "lua");
d7839cef 171
dad344a7
CP
172 /* TODO */
173 /* open gets you a unique db */
174 /* parameterised queries (huge pain due to no va_args in dbapi2) */
175 /* loadtable */
176 /* getrow */
d7839cef
CP
177}
178
dad344a7
CP
179void lua_destroydb(void) {
180 if(luadb)
181 luadb->close(luadb);
182}