]> jfr.im git - irc/quakenet/newserv.git/blame - lua/luadb.c
Fixed problem where you could set silly limits via CHANMODE which caused desync.
[irc/quakenet/newserv.git] / lua / luadb.c
CommitLineData
55cee062
CP
1#include "lua.h"
2#include "luabot.h"
669e39ad 3#include "../pqsql/pqsql.h"
55cee062
CP
4
5static 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/*
17static 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
25typedef struct lua_callback {
26 lua_list *l;
27 long handler, args;
28} lua_callback;
29
30/* hack */
31PGresult *pgres;
32
33static int lua_dbnumfields(lua_State *ps) {
34 lua_pushint(ps, PQnfields(pgres));
35
36 return 1;
37}
38
39static int lua_dbnumrows(lua_State *ps) {
40 lua_pushint(ps, PQntuples(pgres));
41
42 return 1;
43}
44
45static 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
63void lua_dbcallback(PGconn *dbconn, void *arg) {
64 pgres = PQgetResult(dbconn);
65 lua_callback *c = (lua_callback *)arg;
66
67 if(!lua_listexists(c->l)) {
d0e17ef9 68 luafree(c);
55cee062
CP
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);
d0e17ef9 77 luafree(c);
55cee062
CP
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);
d0e17ef9 85 luafree(c);
55cee062
CP
86 PQclear(pgres);
87 pgres = NULL;
88}
89
90static 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
d0e17ef9 104 cb = (lua_callback *)luamalloc(sizeof(lua_callback));
55cee062
CP
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
117static 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
136void 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}