xref: /netbsd-src/lib/lua/sqlite/sqlite.c (revision a536ee5124e62c9a0051a252f7833dc8f50f44c9)
1 /*	$NetBSD: sqlite.c,v 1.5 2012/11/02 12:24:52 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 __printflike(2, 3) 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 db_changes(lua_State *L)
186 {
187 	sqlite3 **db;
188 
189 	db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE);
190 	lua_pushinteger(L, sqlite3_changes(*db));
191 	return 1;
192 }
193 
194 static int
195 stmt_bind(lua_State *L)
196 {
197 	sqlite3_stmt **stmt;
198 	int pidx;
199 
200 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
201 	pidx = (int)luaL_checkinteger(L, 2);
202 
203 	switch (lua_type(L, 3)) {
204 	case LUA_TNUMBER:
205 		lua_pushinteger(L, sqlite3_bind_double(*stmt, pidx,
206 		    lua_tonumber(L, 3)));
207 		break;
208 	case LUA_TSTRING:
209 		lua_pushinteger(L, sqlite3_bind_text(*stmt, pidx,
210 		    lua_tostring(L, 3), -1, SQLITE_TRANSIENT));
211 		break;
212 	case LUA_TNIL:
213 		lua_pushinteger(L, sqlite3_bind_null(*stmt, pidx));
214 		break;
215 	default:
216 		sqlite_error(L, "unsupported data type %s",
217 		    luaL_typename(L, 3));
218 	}
219 	return 1;
220 }
221 
222 static int
223 stmt_bind_parameter_count(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_count(*stmt));
229 	return 1;
230 }
231 
232 static int
233 stmt_bind_parameter_index(lua_State *L)
234 {
235 	sqlite3_stmt **stmt;
236 
237 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
238 	lua_pushinteger(L, sqlite3_bind_parameter_index(*stmt,
239 	    lua_tostring(L, 2)));
240 	return 1;
241 }
242 
243 static int
244 stmt_bind_parameter_name(lua_State *L)
245 {
246 	sqlite3_stmt **stmt;
247 	int pidx;
248 
249 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
250 	pidx = (int)luaL_checkinteger(L, 2);
251 	lua_pushstring(L, sqlite3_bind_parameter_name(*stmt, pidx));
252 	return 1;
253 }
254 
255 static int
256 stmt_step(lua_State *L)
257 {
258 	sqlite3_stmt **stmt;
259 
260 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
261 	lua_pushinteger(L, sqlite3_step(*stmt));
262 	return 1;
263 }
264 
265 static int
266 stmt_column_name(lua_State *L)
267 {
268 	sqlite3_stmt **stmt;
269 	int cidx;
270 
271 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
272 	cidx = (int)luaL_checkinteger(L, 2) - 1;
273 
274 	lua_pushstring(L, sqlite3_column_name(*stmt, cidx));
275 	return 1;
276 }
277 
278 static int
279 stmt_column_count(lua_State *L)
280 {
281 	sqlite3_stmt **stmt;
282 
283 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
284 	lua_pushinteger(L, sqlite3_column_count(*stmt));
285 	return 1;
286 }
287 
288 static int
289 stmt_column(lua_State *L)
290 {
291 	sqlite3_stmt **stmt;
292 	int cidx;
293 
294 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
295 	cidx = (int)luaL_checkinteger(L, 2) - 1;
296 
297 	switch (sqlite3_column_type(*stmt, cidx)) {
298 	case SQLITE_INTEGER:
299 		lua_pushinteger(L, sqlite3_column_int(*stmt, cidx));
300 		break;
301 	case SQLITE_FLOAT:
302 		lua_pushnumber(L, sqlite3_column_double(*stmt, cidx));
303 		break;
304 	case SQLITE_TEXT:
305 		lua_pushstring(L, (const char *)sqlite3_column_text(*stmt,
306 		    cidx));
307 		break;
308 	case SQLITE_BLOB:
309 	case SQLITE_NULL:
310 		lua_pushnil(L);
311 		break;
312 	}
313 	return 1;
314 }
315 
316 static int
317 stmt_reset(lua_State *L)
318 {
319 	sqlite3_stmt **stmt;
320 
321 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
322 	sqlite3_reset(*stmt);
323 	return 0;
324 }
325 
326 static int
327 stmt_clear_bindings(lua_State *L)
328 {
329 	sqlite3_stmt **stmt;
330 
331 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
332 	sqlite3_clear_bindings(*stmt);
333 	return 0;
334 }
335 
336 static int
337 stmt_finalize(lua_State *L)
338 {
339 	sqlite3_stmt **stmt;
340 
341 	stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE);
342 	sqlite3_finalize(*stmt);
343 	return 0;
344 }
345 
346 struct constant {
347 	const char *name;
348 	int value;
349 };
350 
351 static const struct constant sqlite_constant[] = {
352 	/* SQLite return codes */
353 	{ "OK",			SQLITE_OK },
354 	{ "ERROR",		SQLITE_ERROR },
355 	{ "INTERNAL",		SQLITE_INTERNAL },
356 	{ "PERM",		SQLITE_PERM },
357 	{ "ABORT",		SQLITE_ABORT },
358 	{ "BUSY",		SQLITE_BUSY },
359 	{ "LOCKED",		SQLITE_LOCKED },
360 	{ "NOMEM",		SQLITE_NOMEM },
361 	{ "READONLY",		SQLITE_READONLY },
362 	{ "INTERRUPT",		SQLITE_INTERRUPT },
363 	{ "IOERR",		SQLITE_IOERR },
364 	{ "CORRUPT",		SQLITE_CORRUPT },
365 	{ "FULL",		SQLITE_FULL },
366 	{ "CANTOPEN",		SQLITE_CANTOPEN },
367 	{ "EMPTY",		SQLITE_EMPTY },
368 	{ "SCHEMA",		SQLITE_SCHEMA },
369 	{ "TOOBIG",		SQLITE_TOOBIG },
370 	{ "CONSTRAINT",		SQLITE_CONSTRAINT },
371 	{ "MISMATCH",		SQLITE_MISMATCH },
372 	{ "MISUSE",		SQLITE_MISUSE },
373 	{ "NOLFS",		SQLITE_NOLFS },
374 	{ "AUTH",		SQLITE_AUTH },
375 	{ "FORMAT",		SQLITE_FORMAT },
376 	{ "RANGE",		SQLITE_RANGE },
377 	{ "NOTADB",		SQLITE_NOTADB },
378 
379 	{ "ROW",		SQLITE_ROW },
380 	{ "DONE",		SQLITE_DONE },
381 
382 	/* File modes */
383 	{ "OPEN_READONLY",	SQLITE_OPEN_READONLY },
384 	{ "OPEN_READWRITE",	SQLITE_OPEN_READWRITE },
385 	{ "OPEN_CREATE",	SQLITE_OPEN_CREATE },
386 
387 	{ NULL,			0 }
388 };
389 
390 static void
391 gpio_set_info(lua_State *L)
392 {
393 	lua_pushliteral(L, "_COPYRIGHT");
394 	lua_pushliteral(L, "Copyright (C) 2011, 2012 by "
395 	    "Marc Balmer <marc@msys.ch>");
396 	lua_settable(L, -3);
397 	lua_pushliteral(L, "_DESCRIPTION");
398 	lua_pushliteral(L, "SQLite interface for Lua");
399 	lua_settable(L, -3);
400 	lua_pushliteral(L, "_VERSION");
401 	lua_pushliteral(L, "sqlite 1.0.2");
402 	lua_settable(L, -3);
403 }
404 
405 int
406 luaopen_sqlite(lua_State* L)
407 {
408 	static const struct luaL_Reg sqlite_methods[] = {
409 		{ "initialize",			sqlite_initialize },
410 		{ "shutdown",			sqlite_shutdown },
411 		{ "open",			sqlite_open },
412 		{ "libversion",			sqlite_libversion },
413 		{ "libversion_number",		sqlite_libversion_number },
414 		{ "sourceid",			sqlite_sourceid },
415 		{ NULL,				NULL }
416 	};
417 	static const struct luaL_Reg db_methods[] = {
418 		{ "close",			db_close },
419 		{ "prepare",			db_prepare },
420 		{ "exec",			db_exec },
421 		{ "errcode",			db_errcode },
422 		{ "errmsg",			db_errmsg },
423 		{ "get_autocommit",		db_get_autocommit },
424 		{ "changes",			db_changes },
425 		{ NULL,				NULL }
426 	};
427 	static const struct luaL_Reg stmt_methods[] = {
428 		{ "bind",			stmt_bind },
429 		{ "bind_parameter_count",	stmt_bind_parameter_count },
430 		{ "bind_parameter_index",	stmt_bind_parameter_index },
431 		{ "bind_parameter_name",	stmt_bind_parameter_name },
432 		{ "step",			stmt_step },
433 		{ "column",			stmt_column },
434 		{ "reset",			stmt_reset },
435 		{ "clear_bindings",		stmt_clear_bindings },
436 		{ "finalize",			stmt_finalize },
437 		{ "column_name",		stmt_column_name },
438 		{ "column_count",		stmt_column_count },
439 		{ NULL,		NULL }
440 	};
441 	int n;
442 
443 	sqlite3_initialize();
444 
445 	luaL_register(L, "sqlite", sqlite_methods);
446 	gpio_set_info(L);
447 
448 	/* The database connection metatable */
449 	if (luaL_newmetatable(L, SQLITE_DB_METATABLE)) {
450 		luaL_register(L, NULL, db_methods);
451 
452 		lua_pushliteral(L, "__gc");
453 		lua_pushcfunction(L, db_close);
454 		lua_settable(L, -3);
455 
456 		lua_pushliteral(L, "__index");
457 		lua_pushvalue(L, -2);
458 		lua_settable(L, -3);
459 
460 		lua_pushliteral(L, "__metatable");
461 		lua_pushliteral(L, "must not access this metatable");
462 		lua_settable(L, -3);
463 	}
464 	lua_pop(L, 1);
465 
466 	/* The statement metatable */
467 	if (luaL_newmetatable(L, SQLITE_STMT_METATABLE)) {
468 		luaL_register(L, NULL, stmt_methods);
469 
470 		lua_pushliteral(L, "__gc");
471 		lua_pushcfunction(L, stmt_finalize);
472 		lua_settable(L, -3);
473 
474 		lua_pushliteral(L, "__index");
475 		lua_pushvalue(L, -2);
476 		lua_settable(L, -3);
477 
478 		lua_pushliteral(L, "__metatable");
479 		lua_pushliteral(L, "must not access this metatable");
480 		lua_settable(L, -3);
481 	}
482 	lua_pop(L, 1);
483 
484 	for (n = 0; sqlite_constant[n].name != NULL; n++) {
485 		lua_pushinteger(L, sqlite_constant[n].value);
486 		lua_setfield(L, -2, sqlite_constant[n].name);
487 	};
488 	return 1;
489 }
490