1/* $NetBSD: sqlite.c,v 1.10 2019/05/16 12:42:35 tpaul Exp $ */ 2 3/* 4 * Copyright (c) 2011, 2013, 2016, 2017 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 43int luaopen_sqlite(lua_State*); 44 45static __printflike(2, 3) void 46sqlite_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 64static int 65sqlite_initialize(lua_State *L) 66{ 67 lua_pushinteger(L, sqlite3_initialize()); 68 return 1; 69} 70 71static int 72sqlite_shutdown(lua_State *L) 73{ 74 lua_pushinteger(L, sqlite3_shutdown()); 75 return 1; 76} 77 78static int 79sqlite_open(lua_State *L) 80{ 81 sqlite3 **db; 82 83 db = lua_newuserdata(L, sizeof(sqlite3 *)); 84 luaL_getmetatable(L, SQLITE_DB_METATABLE); 85 lua_setmetatable(L, -2); 86 87 if (lua_gettop(L) > 2) 88 lua_pushinteger(L, sqlite3_open_v2(luaL_checkstring(L, -3), db, 89 (int)luaL_checkinteger(L, -2), NULL)); 90 else 91 lua_pushinteger(L, sqlite3_open(luaL_checkstring(L, -2), db)); 92 return 2; 93 94} 95 96static int 97sqlite_libversion(lua_State *L) 98{ 99 lua_pushstring(L, sqlite3_libversion()); 100 return 1; 101} 102 103static int 104sqlite_libversion_number(lua_State *L) 105{ 106 lua_pushinteger(L, sqlite3_libversion_number()); 107 return 1; 108} 109 110static int 111sqlite_sourceid(lua_State *L) 112{ 113 lua_pushstring(L, sqlite3_sourceid()); 114 return 1; 115} 116 117static int 118db_close(lua_State *L) 119{ 120 sqlite3 **db; 121 122 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 123 if (*db) { 124 lua_pushinteger(L, sqlite3_close(*db)); 125 *db = NULL; 126 } else 127 lua_pushnil(L); 128 return 1; 129 130} 131 132static int 133db_prepare(lua_State *L) 134{ 135 sqlite3 **db; 136 sqlite3_stmt **stmt; 137 const char *sql; 138 139 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 140 stmt = lua_newuserdata(L, sizeof(sqlite3_stmt *)); 141 sql = luaL_checkstring(L, 2); 142 lua_pushinteger(L, sqlite3_prepare_v2(*db, sql, 143 (int)strlen(sql) + 1, stmt, NULL)); 144 luaL_getmetatable(L, SQLITE_STMT_METATABLE); 145 lua_setmetatable(L, -3); 146 return 2; 147 148} 149 150static int 151db_exec(lua_State *L) 152{ 153 sqlite3 **db; 154 155 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 156 lua_pushinteger(L, sqlite3_exec(*db, lua_tostring(L, 2), NULL, 157 NULL, NULL)); 158 return 1; 159} 160 161static int 162db_errcode(lua_State *L) 163{ 164 sqlite3 **db; 165 166 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 167 lua_pushinteger(L, sqlite3_errcode(*db)); 168 return 1; 169} 170 171static int 172db_errmsg(lua_State *L) 173{ 174 sqlite3 **db; 175 176 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 177 lua_pushstring(L, sqlite3_errmsg(*db)); 178 return 1; 179} 180 181static int 182db_get_autocommit(lua_State *L) 183{ 184 sqlite3 **db; 185 186 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 187 lua_pushboolean(L, sqlite3_get_autocommit(*db)); 188 return 1; 189} 190 191static int 192db_changes(lua_State *L) 193{ 194 sqlite3 **db; 195 196 db = luaL_checkudata(L, 1, SQLITE_DB_METATABLE); 197 lua_pushinteger(L, sqlite3_changes(*db)); 198 return 1; 199} 200 201static int 202stmt_bind(lua_State *L) 203{ 204 sqlite3_stmt **stmt; 205 int pidx; 206 207 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 208 pidx = (int)luaL_checkinteger(L, 2); 209 210 switch (lua_type(L, 3)) { 211 case LUA_TNUMBER: 212 lua_pushinteger(L, sqlite3_bind_double(*stmt, pidx, 213 lua_tonumber(L, 3))); 214 break; 215 case LUA_TSTRING: 216 lua_pushinteger(L, sqlite3_bind_text(*stmt, pidx, 217 lua_tostring(L, 3), -1, SQLITE_TRANSIENT)); 218 break; 219 case LUA_TNIL: 220 lua_pushinteger(L, sqlite3_bind_null(*stmt, pidx)); 221 break; 222 default: 223 sqlite_error(L, "unsupported data type %s", 224 luaL_typename(L, 3)); 225 } 226 return 1; 227} 228 229static int 230stmt_bind_parameter_count(lua_State *L) 231{ 232 sqlite3_stmt **stmt; 233 234 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 235 lua_pushinteger(L, sqlite3_bind_parameter_count(*stmt)); 236 return 1; 237} 238 239static int 240stmt_bind_parameter_index(lua_State *L) 241{ 242 sqlite3_stmt **stmt; 243 244 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 245 lua_pushinteger(L, sqlite3_bind_parameter_index(*stmt, 246 lua_tostring(L, 2))); 247 return 1; 248} 249 250static int 251stmt_bind_parameter_name(lua_State *L) 252{ 253 sqlite3_stmt **stmt; 254 int pidx; 255 256 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 257 pidx = (int)luaL_checkinteger(L, 2); 258 lua_pushstring(L, sqlite3_bind_parameter_name(*stmt, pidx)); 259 return 1; 260} 261 262static int 263stmt_step(lua_State *L) 264{ 265 sqlite3_stmt **stmt; 266 267 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 268 lua_pushinteger(L, sqlite3_step(*stmt)); 269 return 1; 270} 271 272static int 273stmt_column_name(lua_State *L) 274{ 275 sqlite3_stmt **stmt; 276 int cidx; 277 278 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 279 cidx = (int)luaL_checkinteger(L, 2) - 1; 280 281 lua_pushstring(L, sqlite3_column_name(*stmt, cidx)); 282 return 1; 283} 284 285static int 286stmt_column_count(lua_State *L) 287{ 288 sqlite3_stmt **stmt; 289 290 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 291 lua_pushinteger(L, sqlite3_column_count(*stmt)); 292 return 1; 293} 294 295static int 296stmt_column(lua_State *L) 297{ 298 sqlite3_stmt **stmt; 299 int cidx; 300 301 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 302 cidx = (int)luaL_checkinteger(L, 2) - 1; 303 304 switch (sqlite3_column_type(*stmt, cidx)) { 305 case SQLITE_INTEGER: 306 lua_pushinteger(L, sqlite3_column_int(*stmt, cidx)); 307 break; 308 case SQLITE_FLOAT: 309 lua_pushnumber(L, sqlite3_column_double(*stmt, cidx)); 310 break; 311 case SQLITE_TEXT: 312 lua_pushstring(L, (const char *)sqlite3_column_text(*stmt, 313 cidx)); 314 break; 315 case SQLITE_BLOB: 316 case SQLITE_NULL: 317 lua_pushnil(L); 318 break; 319 } 320 return 1; 321} 322 323static int 324stmt_reset(lua_State *L) 325{ 326 sqlite3_stmt **stmt; 327 328 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 329 sqlite3_reset(*stmt); 330 return 0; 331} 332 333static int 334stmt_clear_bindings(lua_State *L) 335{ 336 sqlite3_stmt **stmt; 337 338 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 339 if (*stmt) { 340 sqlite3_clear_bindings(*stmt); 341 *stmt = NULL; 342 } 343 return 0; 344} 345 346static int 347stmt_finalize(lua_State *L) 348{ 349 sqlite3_stmt **stmt; 350 351 stmt = luaL_checkudata(L, 1, SQLITE_STMT_METATABLE); 352 if (*stmt) { 353 sqlite3_finalize(*stmt); 354 *stmt = NULL; 355 } 356 return 0; 357} 358 359struct constant { 360 const char *name; 361 int value; 362}; 363 364static const struct constant sqlite_constant[] = { 365 /* SQLite return codes */ 366 { "OK", SQLITE_OK }, 367 { "ERROR", SQLITE_ERROR }, 368 { "INTERNAL", SQLITE_INTERNAL }, 369 { "PERM", SQLITE_PERM }, 370 { "ABORT", SQLITE_ABORT }, 371 { "BUSY", SQLITE_BUSY }, 372 { "LOCKED", SQLITE_LOCKED }, 373 { "NOMEM", SQLITE_NOMEM }, 374 { "READONLY", SQLITE_READONLY }, 375 { "INTERRUPT", SQLITE_INTERRUPT }, 376 { "IOERR", SQLITE_IOERR }, 377 { "CORRUPT", SQLITE_CORRUPT }, 378 { "NOTFOUND", SQLITE_NOTFOUND }, 379 { "FULL", SQLITE_FULL }, 380 { "CANTOPEN", SQLITE_CANTOPEN }, 381 { "PROTOCOL", SQLITE_PROTOCOL }, 382 { "EMPTY", SQLITE_EMPTY }, 383 { "SCHEMA", SQLITE_SCHEMA }, 384 { "TOOBIG", SQLITE_TOOBIG }, 385 { "CONSTRAINT", SQLITE_CONSTRAINT }, 386 { "MISMATCH", SQLITE_MISMATCH }, 387 { "MISUSE", SQLITE_MISUSE }, 388 { "NOLFS", SQLITE_NOLFS }, 389 { "AUTH", SQLITE_AUTH }, 390 { "FORMAT", SQLITE_FORMAT }, 391 { "RANGE", SQLITE_RANGE }, 392 { "NOTADB", SQLITE_NOTADB }, 393 { "ROW", SQLITE_ROW }, 394 { "DONE", SQLITE_DONE }, 395 396 /* File modes */ 397 { "OPEN_READONLY", SQLITE_OPEN_READONLY }, 398 { "OPEN_READWRITE", SQLITE_OPEN_READWRITE }, 399 { "OPEN_CREATE", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, 400 401 { NULL, 0 } 402}; 403 404static void 405sqlite_set_info(lua_State *L) 406{ 407 lua_pushliteral(L, "_COPYRIGHT"); 408 lua_pushliteral(L, "Copyright (C) 2011, 2012, 2013 by " 409 "Marc Balmer <marc@msys.ch>"); 410 lua_settable(L, -3); 411 lua_pushliteral(L, "_DESCRIPTION"); 412 lua_pushliteral(L, "SQLite interface for Lua"); 413 lua_settable(L, -3); 414 lua_pushliteral(L, "_VERSION"); 415 lua_pushliteral(L, "sqlite 1.0.3"); 416 lua_settable(L, -3); 417} 418 419int 420luaopen_sqlite(lua_State* L) 421{ 422 static const struct luaL_Reg sqlite_methods[] = { 423 { "initialize", sqlite_initialize }, 424 { "shutdown", sqlite_shutdown }, 425 { "open", sqlite_open }, 426 { "libversion", sqlite_libversion }, 427 { "libversion_number", sqlite_libversion_number }, 428 { "sourceid", sqlite_sourceid }, 429 { NULL, NULL } 430 }; 431 static const struct luaL_Reg db_methods[] = { 432 { "close", db_close }, 433 { "prepare", db_prepare }, 434 { "exec", db_exec }, 435 { "errcode", db_errcode }, 436 { "errmsg", db_errmsg }, 437 { "get_autocommit", db_get_autocommit }, 438 { "changes", db_changes }, 439 { NULL, NULL } 440 }; 441 static const struct luaL_Reg stmt_methods[] = { 442 { "bind", stmt_bind }, 443 { "bind_parameter_count", stmt_bind_parameter_count }, 444 { "bind_parameter_index", stmt_bind_parameter_index }, 445 { "bind_parameter_name", stmt_bind_parameter_name }, 446 { "step", stmt_step }, 447 { "column", stmt_column }, 448 { "reset", stmt_reset }, 449 { "clear_bindings", stmt_clear_bindings }, 450 { "finalize", stmt_finalize }, 451 { "column_name", stmt_column_name }, 452 { "column_count", stmt_column_count }, 453 { NULL, NULL } 454 }; 455 int n; 456 457 sqlite3_initialize(); 458 459 luaL_newlib(L, sqlite_methods); 460 luaL_setfuncs(L, db_methods, 0); 461 luaL_setfuncs(L, stmt_methods, 0); 462 sqlite_set_info(L); 463 464 /* The database connection metatable */ 465 if (luaL_newmetatable(L, SQLITE_DB_METATABLE)) { 466 luaL_setfuncs(L, db_methods, 0); 467 468 lua_pushliteral(L, "__gc"); 469 lua_pushcfunction(L, db_close); 470 lua_settable(L, -3); 471 472 lua_pushliteral(L, "__index"); 473 lua_pushvalue(L, -2); 474 lua_settable(L, -3); 475 476 lua_pushliteral(L, "__metatable"); 477 lua_pushliteral(L, "must not access this metatable"); 478 lua_settable(L, -3); 479 } 480 lua_pop(L, 1); 481 482 /* The statement metatable */ 483 if (luaL_newmetatable(L, SQLITE_STMT_METATABLE)) { 484 luaL_setfuncs(L, stmt_methods, 0); 485 486 lua_pushliteral(L, "__gc"); 487 lua_pushcfunction(L, stmt_finalize); 488 lua_settable(L, -3); 489 490 lua_pushliteral(L, "__index"); 491 lua_pushvalue(L, -2); 492 lua_settable(L, -3); 493 494 lua_pushliteral(L, "__metatable"); 495 lua_pushliteral(L, "must not access this metatable"); 496 lua_settable(L, -3); 497 } 498 lua_pop(L, 1); 499 500 for (n = 0; sqlite_constant[n].name != NULL; n++) { 501 lua_pushinteger(L, sqlite_constant[n].value); 502 lua_setfield(L, -2, sqlite_constant[n].name); 503 }; 504 return 1; 505} 506