xref: /netbsd-src/lib/lua/sqlite/sqlite.c (revision 78f8cb2089e2f5c4acaa3d316a269ec37f2f242c)
1 /*	$NetBSD: sqlite.c,v 1.2 2011/10/15 10:35:06 mbalmer Exp $ */
2 
3 /*
4  * Copyright (c) 2011 Marc Balmer <marc@msys.ch>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /* SQLite interface for Lua */
29 
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <sqlite3.h>
35 
36 #include <lua.h>
37 #include <lauxlib.h>
38 #include <lualib.h>
39 
40 #define SQLITE_DB_METATABLE "SQLite database connection methods"
41 #define SQLITE_STMT_METATABLE "SQLite statement methods"
42 
43 int luaopen_sqlite(lua_State*);
44 
45 static void
46 sqlite_error(lua_State *L, const char *fmt, ...)
47 {
48 	va_list ap;
49 	int len;
50 	char *msg;
51 
52 	va_start(ap, fmt);
53 	len = vasprintf(&msg, fmt, ap);
54 	va_end(ap);
55 
56 	if (len != -1) {
57 		lua_pushstring(L, msg);
58 		free(msg);
59 	} else
60 		lua_pushstring(L, "vasprintf failed");
61 	lua_error(L);
62 }
63 
64 static int
65 sqlite_initialize(lua_State *L)
66 {
67 	lua_pushinteger(L, sqlite3_initialize());
68 	return 1;
69 }
70 
71 static int
72 sqlite_shutdown(lua_State *L)
73 {
74 	lua_pushinteger(L, sqlite3_shutdown());
75 	return 1;
76 }
77 
78 static int
79 sqlite_open(lua_State *L)
80 {
81 	sqlite3 **db;
82 
83 	db = lua_newuserdata(L, sizeof(sqlite3 *));
84 	lua_pushinteger(L, sqlite3_open_v2(luaL_checkstring(L, -3), db,
85 	    (int)luaL_checkinteger(L, -2), NULL));
86 
87 	luaL_getmetatable(L, SQLITE_DB_METATABLE);
88 	lua_setmetatable(L, -3);
89 	return 2;
90 
91 }
92 
93 static int
94 sqlite_libversion(lua_State *L)
95 {
96 	lua_pushstring(L, sqlite3_libversion());
97 	return 1;
98 }
99 
100 static int
101 sqlite_libversion_number(lua_State *L)
102 {
103 	lua_pushinteger(L, sqlite3_libversion_number());
104 	return 1;
105 }
106 
107 static int
108 sqlite_sourceid(lua_State *L)
109 {
110 	lua_pushstring(L, sqlite3_sourceid());
111 	return 1;
112 }
113 
114 static int
115 db_close(lua_State *L)
116 {
117 	sqlite3 **db;
118 
119 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
120 	lua_pushinteger(L, sqlite3_close(*db));
121 	return 1;
122 
123 }
124 
125 static int
126 db_prepare(lua_State *L)
127 {
128 	sqlite3 **db;
129 	sqlite3_stmt **stmt;
130 	const char *sql;
131 
132 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
133 	stmt = lua_newuserdata(L, sizeof(sqlite3_stmt *));
134 	sql = luaL_checkstring(L, 2);
135 	lua_pushinteger(L, sqlite3_prepare_v2(*db, sql,
136 	    (int)strlen(sql) + 1, stmt, NULL));
137 	luaL_getmetatable(L, SQLITE_STMT_METATABLE);
138 	lua_setmetatable(L, -3);
139 	return 2;
140 
141 }
142 
143 static int
144 db_exec(lua_State *L)
145 {
146 	sqlite3 **db;
147 
148 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
149 	lua_pushinteger(L, sqlite3_exec(*db, lua_tostring(L, 2), NULL,
150 	    NULL, NULL));
151 	return 1;
152 }
153 
154 static int
155 db_errcode(lua_State *L)
156 {
157 	sqlite3 **db;
158 
159 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
160 	lua_pushinteger(L, sqlite3_errcode(*db));
161 	return 1;
162 }
163 
164 static int
165 db_errmsg(lua_State *L)
166 {
167 	sqlite3 **db;
168 
169 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
170 	lua_pushstring(L, sqlite3_errmsg(*db));
171 	return 1;
172 }
173 
174 static int
175 db_get_autocommit(lua_State *L)
176 {
177 	sqlite3 **db;
178 
179 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
180 	lua_pushboolean(L, sqlite3_get_autocommit(*db));
181 	return 1;
182 }
183 
184 static int
185 stmt_bind(lua_State *L)
186 {
187 	sqlite3_stmt **stmt;
188 	int pidx;
189 
190 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
191 	pidx = (int)luaL_checkinteger(L, 2);
192 
193 	switch (lua_type(L, 3)) {
194 	case LUA_TNUMBER:
195 		lua_pushinteger(L, sqlite3_bind_double(*stmt, pidx,
196 		    lua_tonumber(L, 3)));
197 		break;
198 	case LUA_TSTRING:
199 		lua_pushinteger(L, sqlite3_bind_text(*stmt, pidx,
200 		    lua_tostring(L, 3), -1, NULL));
201 		break;
202 	case LUA_TNIL:
203 		lua_pushinteger(L, sqlite3_bind_null(*stmt, pidx));
204 		break;
205 	default:
206 		sqlite_error(L, "unsupported data type %s",
207 		    luaL_typename(L, 3));
208 	}
209 	return 1;
210 }
211 
212 static int
213 stmt_bind_parameter_count(lua_State *L)
214 {
215 	sqlite3_stmt **stmt;
216 
217 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
218 	lua_pushinteger(L, sqlite3_bind_parameter_count(*stmt));
219 	return 1;
220 }
221 
222 static int
223 stmt_bind_parameter_index(lua_State *L)
224 {
225 	sqlite3_stmt **stmt;
226 
227 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
228 	lua_pushinteger(L, sqlite3_bind_parameter_index(*stmt,
229 	    lua_tostring(L, 2)));
230 	return 1;
231 }
232 
233 static int
234 stmt_bind_parameter_name(lua_State *L)
235 {
236 	sqlite3_stmt **stmt;
237 	int pidx;
238 
239 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
240 	pidx = (int)luaL_checkinteger(L, 2);
241 	lua_pushstring(L, sqlite3_bind_parameter_name(*stmt, pidx));
242 	return 1;
243 }
244 
245 static int
246 stmt_step(lua_State *L)
247 {
248 	sqlite3_stmt **stmt;
249 
250 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
251 	lua_pushinteger(L, sqlite3_step(*stmt));
252 	return 1;
253 }
254 
255 static int
256 stmt_column_name(lua_State *L)
257 {
258 	sqlite3_stmt **stmt;
259 	int cidx;
260 
261 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
262 	cidx = (int)luaL_checkinteger(L, 2) - 1;
263 
264 	lua_pushstring(L, sqlite3_column_name(*stmt, cidx));
265 	return 1;
266 }
267 
268 static int
269 stmt_column_count(lua_State *L)
270 {
271 	sqlite3_stmt **stmt;
272 
273 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
274 	lua_pushinteger(L, sqlite3_column_count(*stmt));
275 	return 1;
276 }
277 
278 static int
279 stmt_column(lua_State *L)
280 {
281 	sqlite3_stmt **stmt;
282 	int cidx;
283 
284 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
285 	cidx = (int)luaL_checkinteger(L, 2) - 1;
286 
287 	switch (sqlite3_column_type(*stmt, cidx)) {
288 	case SQLITE_INTEGER:
289 		lua_pushinteger(L, sqlite3_column_int(*stmt, cidx));
290 		break;
291 	case SQLITE_FLOAT:
292 		lua_pushnumber(L, sqlite3_column_double(*stmt, cidx));
293 		break;
294 	case SQLITE_TEXT:
295 		lua_pushstring(L, (const char *)sqlite3_column_text(*stmt,
296 		    cidx));
297 		break;
298 	case SQLITE_BLOB:
299 	case SQLITE_NULL:
300 		lua_pushnil(L);
301 		break;
302 	}
303 	return 1;
304 }
305 
306 static int
307 stmt_reset(lua_State *L)
308 {
309 	sqlite3_stmt **stmt;
310 
311 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
312 	sqlite3_reset(*stmt);
313 	return 0;
314 }
315 
316 static int
317 stmt_clear_bindings(lua_State *L)
318 {
319 	sqlite3_stmt **stmt;
320 
321 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
322 	sqlite3_clear_bindings(*stmt);
323 	return 0;
324 }
325 
326 static int
327 stmt_finalize(lua_State *L)
328 {
329 	sqlite3_stmt **stmt;
330 
331 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
332 	sqlite3_finalize(*stmt);
333 	return 0;
334 }
335 
336 struct constant {
337 	const char *name;
338 	int value;
339 };
340 
341 static const struct constant sqlite_constant[] = {
342 	/* SQLite return codes */
343 	{ "OK",			SQLITE_OK },
344 	{ "ERROR",		SQLITE_ERROR },
345 	{ "INTERNAL",		SQLITE_INTERNAL },
346 	{ "PERM",		SQLITE_PERM },
347 	{ "ABORT",		SQLITE_ABORT },
348 	{ "BUSY",		SQLITE_BUSY },
349 	{ "LOCKED",		SQLITE_LOCKED },
350 	{ "NOMEM",		SQLITE_NOMEM },
351 	{ "READONLY",		SQLITE_READONLY },
352 	{ "INTERRUPT",		SQLITE_INTERRUPT },
353 	{ "IOERR",		SQLITE_IOERR },
354 	{ "CORRUPT",		SQLITE_CORRUPT },
355 	{ "FULL",		SQLITE_FULL },
356 	{ "CANTOPEN",		SQLITE_CANTOPEN },
357 	{ "EMPTY",		SQLITE_EMPTY },
358 	{ "SCHEMA",		SQLITE_SCHEMA },
359 	{ "TOOBIG",		SQLITE_TOOBIG },
360 	{ "CONSTRAINT",		SQLITE_CONSTRAINT },
361 	{ "MISMATCH",		SQLITE_MISMATCH },
362 	{ "MISUSE",		SQLITE_MISUSE },
363 	{ "NOLFS",		SQLITE_NOLFS },
364 	{ "AUTH",		SQLITE_AUTH },
365 	{ "FORMAT",		SQLITE_FORMAT },
366 	{ "RANGE",		SQLITE_RANGE },
367 	{ "NOTADB",		SQLITE_NOTADB },
368 
369 	{ "ROW",		SQLITE_ROW },
370 	{ "DONE",		SQLITE_DONE },
371 
372 	/* File modes */
373 	{ "OPEN_READONLY",	SQLITE_OPEN_READONLY },
374 	{ "OPEN_READWRITE",	SQLITE_OPEN_READWRITE },
375 	{ "OPEN_CREATE",	SQLITE_OPEN_CREATE },
376 
377 	{ NULL,			0 }
378 };
379 
380 static void
381 gpio_set_info(lua_State *L)
382 {
383 	lua_pushliteral(L, "_COPYRIGHT");
384 	lua_pushliteral(L, "Copyright (C) 2011 Marc Balmer <marc@msys.ch>");
385 	lua_settable(L, -3);
386 	lua_pushliteral(L, "_DESCRIPTION");
387 	lua_pushliteral(L, "SQLite interface for Lua");
388 	lua_settable(L, -3);
389 	lua_pushliteral(L, "_VERSION");
390 	lua_pushliteral(L, "sqlite 1.0.0");
391 	lua_settable(L, -3);
392 }
393 
394 int
395 luaopen_sqlite(lua_State* L)
396 {
397 	static const struct luaL_Reg sqlite_methods[] = {
398 		{ "initialize",		sqlite_initialize },
399 		{ "shutdown",		sqlite_shutdown },
400 		{ "open",		sqlite_open },
401 		{ "libversion",		sqlite_libversion },
402 		{ "libversion_number",	sqlite_libversion_number },
403 		{ "sourceid",		sqlite_sourceid },
404 		{ NULL,			NULL }
405 	};
406 	static const struct luaL_Reg db_methods[] = {
407 		{ "close",		db_close },
408 		{ "prepare",		db_prepare },
409 		{ "exec",		db_exec },
410 		{ "errcode",		db_errcode },
411 		{ "errmsg",		db_errmsg },
412 		{ "get_autocommit",	db_get_autocommit },
413 		{ NULL,			NULL }
414 	};
415 	static const struct luaL_Reg stmt_methods[] = {
416 		{ "bind",		stmt_bind },
417 		{ "bind_parameter_count",	stmt_bind_parameter_count },
418 		{ "bind_parameter_index",	stmt_bind_parameter_index },
419 		{ "bind_parameter_name",	stmt_bind_parameter_name },
420 		{ "step",		stmt_step },
421 		{ "column",		stmt_column },
422 		{ "reset",		stmt_reset },
423 		{ "clear_bindings",	stmt_clear_bindings },
424 		{ "finalize",		stmt_finalize },
425 		{ "column_name",	stmt_column_name },
426 		{ "column_count",	stmt_column_count },
427 		{ NULL,		NULL }
428 	};
429 	int n;
430 
431 	sqlite3_initialize();
432 
433 	luaL_register(L, "sqlite", sqlite_methods);
434 	gpio_set_info(L);
435 
436 	/* The database connection metatable */
437 	if (luaL_newmetatable(L, SQLITE_DB_METATABLE)) {
438 		luaL_register(L, NULL, db_methods);
439 
440 		lua_pushliteral(L, "__gc");
441 		lua_pushcfunction(L, db_close);
442 		lua_settable(L, -3);
443 
444 		lua_pushliteral(L, "__index");
445 		lua_pushvalue(L, -2);
446 		lua_settable(L, -3);
447 
448 		lua_pushliteral(L, "__metatable");
449 		lua_pushliteral(L, "must not access this metatable");
450 		lua_settable(L, -3);
451 	}
452 	lua_pop(L, 1);
453 
454 	/* The statement metatable */
455 	if (luaL_newmetatable(L, SQLITE_STMT_METATABLE)) {
456 		luaL_register(L, NULL, stmt_methods);
457 
458 		lua_pushliteral(L, "__gc");
459 		lua_pushcfunction(L, stmt_finalize);
460 		lua_settable(L, -3);
461 
462 		lua_pushliteral(L, "__index");
463 		lua_pushvalue(L, -2);
464 		lua_settable(L, -3);
465 
466 		lua_pushliteral(L, "__metatable");
467 		lua_pushliteral(L, "must not access this metatable");
468 		lua_settable(L, -3);
469 	}
470 	lua_pop(L, 1);
471 
472 	for (n = 0; sqlite_constant[n].name != NULL; n++) {
473 		lua_pushinteger(L, sqlite_constant[n].value);
474 		lua_setfield(L, -2, sqlite_constant[n].name);
475 	};
476 	return 1;
477 }
478