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