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