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