├── LICENSE ├── example-keyvalue.lua ├── README.md └── sqlite3.lua /LICENSE: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | 3 | LJSQLite3: SQlite3 Interface. 4 | 5 | Copyright (C) 2014-2016 Stefano Peluchetti. All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | [ MIT license: http://opensource.org/licenses/MIT ] 26 | 27 | =============================================================================== -------------------------------------------------------------------------------- /example-keyvalue.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | This is a simple example of using SQLite for key-value storage. 3 | Make sure your require paths are correct and that you have an sqlite library. 4 | 5 | Usage: 6 | 7 | local Database = require('./example-keyvalue') -- path to this file 8 | 9 | local db = Database('test') -- open a database file by name (or create a new one) 10 | local tbl = db:getTable('table') -- get a table by name (or create a new one) 11 | 12 | tbl:set('foo', 'bar') -- set values 13 | local foo = tbl:get('foo') -- get values 14 | tbl:set('foo', nil) -- use nil to delete values 15 | tbl:set(42, '1234') -- numbers work, too 16 | ]] 17 | 18 | local sql = require('./sqlite3') 19 | 20 | local f = string.format 21 | 22 | local Database = {} 23 | Database.__index = Database 24 | 25 | local Table = {} 26 | Table.__index = Table 27 | 28 | setmetatable(Database, {__call = function(self, name) 29 | return setmetatable({ 30 | conn = sql.open(name .. '.db'), 31 | name = name, 32 | }, self) 33 | end}) 34 | 35 | function Database:getTable(name) 36 | self.conn:exec(f("CREATE TABLE IF NOT EXISTS %q (key PRIMARY KEY, value);", name)) 37 | return Table(name, self) 38 | end 39 | 40 | setmetatable(Table, {__call = function(self, name, database) 41 | local conn = database.conn 42 | return setmetatable({ 43 | stmts = { 44 | get = conn:prepare(f("SELECT value FROM %q WHERE key == ?;", name)), 45 | set = conn:prepare(f("INSERT OR REPLACE INTO %q VALUES (?, ?);", name)), 46 | delete = conn:prepare(f("DELETE FROM %q WHERE key == ?;", name)), 47 | }, 48 | name = name, 49 | database = database, 50 | }, self) 51 | end}) 52 | 53 | function Table:get(k) 54 | local stmt = self.stmts.get 55 | local res = stmt:reset():bind(k):step() 56 | return res and res[1] 57 | end 58 | 59 | function Table:set(k, v) 60 | if v == nil then 61 | local stmt = self.stmts.delete 62 | return stmt:reset():bind(k):step() 63 | else 64 | local stmt = self.stmts.set 65 | return stmt:reset():bind(k, v):step() 66 | end 67 | end 68 | 69 | return Database 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SQlite3 Interface for [Luvit](https://luvit.io/) 2 | ============================ 3 | 4 | Pure LuaJIT binding for [SQLite3](http://sqlite.org) databases. 5 | 6 | Forked from [stepelu/lua-ljsqlite3](https://github.com/stepelu/lua-ljsqlite3) by [Stefano Peluchetti](http://scilua.org/index.html). 7 | 8 | Repackaged for lit, Luvit's package manager. 9 | 10 | ## Features 11 | 12 | - all SQLite3 types are supported and mapped to LuaJIT types 13 | - efficient implementation via value-binding methods and prepared statements 14 | - ability to extend SQLite3 via scalar and aggregate (Lua) callback functions 15 | - command-line shell feature 16 | - results by row or by whole table 17 | 18 | ```lua 19 | local sql = require "sqlite3" 20 | local conn = sql.open("") -- Open a temporary in-memory database. 21 | 22 | -- Execute SQL commands separated by the ';' character: 23 | conn:exec[[ 24 | CREATE TABLE t(id TEXT, num REAL); 25 | INSERT INTO t VALUES('myid1', 200); 26 | ]] 27 | 28 | -- Prepared statements are supported: 29 | local stmt = conn:prepare("INSERT INTO t VALUES(?, ?)") 30 | for i=2,4 do 31 | stmt:reset():bind('myid'..i, 200*i):step() 32 | end 33 | 34 | -- Command-line shell feature which here prints all records: 35 | conn "SELECT * FROM t" 36 | --> id num 37 | --> myid1 200 38 | --> myid2 400 39 | --> myid3 600 40 | --> myid4 800 41 | 42 | local t = conn:exec("SELECT * FROM t") -- Records are by column. 43 | -- Access to columns via column numbers or names: 44 | assert(t[1] == t.id) 45 | -- Nested indexing corresponds to the record number: 46 | assert(t[1][3] == 'myid3') 47 | 48 | -- Convenience function returns multiple values for one record: 49 | local id, num = conn:rowexec("SELECT * FROM t WHERE id=='myid3'") 50 | print(id, num) --> myid3 600 51 | 52 | -- Custom scalar function definition, aggregates supported as well. 53 | conn:setscalar("MYFUN", function(x) return x/100 end) 54 | conn "SELECT MYFUN(num) FROM t" 55 | --> MYFUN(num) 56 | --> 2 57 | --> 4 58 | --> 6 59 | --> 8 60 | 61 | conn:close() -- Close stmt as well. 62 | ``` 63 | 64 | ## Install 65 | 66 | - Install the lit package: 67 | ``` 68 | lit install SinisterRectus/sqlite3 69 | ``` 70 | - Install [sqlite3](https://sqlite.org/download.html) as a dynamic library (sqlite3.dll, sqlite3.so) to your project directory. 71 | 72 | ## Documentation 73 | 74 | Refer to the [official documentation](http://scilua.org/ljsqlite3.html). 75 | -------------------------------------------------------------------------------- /sqlite3.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- A library for interfacing with SQLite3 databases. 3 | -- 4 | -- Copyright (C) 2011-2016 Stefano Peluchetti. All rights reserved. 5 | -- 6 | -- Features, documentation and more: http://www.scilua.org . 7 | -- 8 | -- This file is part of the LJSQLite3 library, which is released under the MIT 9 | -- license: full text in file LICENSE.TXT in the library's root folder. 10 | -------------------------------------------------------------------------------- 11 | --[[lit-meta 12 | name = "SinisterRectus/sqlite3" 13 | version = "1.0.1" 14 | homepage = "http://scilua.org/ljsqlite3.html" 15 | description = "SciLua's sqlite3 bindings repackaged for lit." 16 | tags = {"database", "sqlite3"} 17 | license = "MIT" 18 | author = "Stefano Peluchetti" 19 | contributors = { 20 | "Sinister Rectus" 21 | } 22 | ]] 23 | -------------------------------------------------------------------------------- 24 | 25 | -- TODO: Refactor according to latest style / coding guidelines. 26 | -- TODO: introduce functionality to get of a defined type to avoid if check? 27 | -- TODO: Add extended error codes from Sqlite? 28 | -- TODO: Consider type checks? 29 | -- TODO: Exposed cdef constants are ok? 30 | -- TODO: Resultset (and so exec) could be optimized by avoiding loads/stores 31 | -- TODO: of row table via _step? 32 | 33 | local ffi = require "ffi" 34 | local bit = require "bit" 35 | local jit = require "jit" 36 | 37 | ---- xsys replacement ---------------------------------------------------------- 38 | 39 | local insert = table.insert 40 | local match, gmatch = string.match, string.gmatch 41 | 42 | local function split(str, delim) 43 | local words = {} 44 | for word in gmatch(str .. delim, '(.-)' .. delim) do 45 | insert(words, word) 46 | end 47 | return words 48 | end 49 | 50 | local function trim(str) 51 | return match(str, '^%s*(.-)%s*$') 52 | end 53 | 54 | -------------------------------------------------------------------------------- 55 | 56 | local function err(code, msg) 57 | error("ljsqlite3["..code.."] "..msg) 58 | end 59 | 60 | -- Codes ----------------------------------------------------------------------- 61 | local sqlconstants = {} -- SQLITE_* and OPEN_* declarations. 62 | local codes = { 63 | [0] = "OK", "ERROR", "INTERNAL", "PERM", "ABORT", "BUSY", "LOCKED", "NOMEM", 64 | "READONLY", "INTERRUPT", "IOERR", "CORRUPT", "NOTFOUND", "FULL", "CANTOPEN", 65 | "PROTOCOL", "EMPTY", "SCHEMA", "TOOBIG", "CONSTRAINT", "MISMATCH", "MISUSE", 66 | "NOLFS", "AUTH", "FORMAT", "RANGE", "NOTADB", [100] = "ROW", [101] = "DONE" 67 | } -- From 0 to 26. 68 | 69 | do 70 | local types = { "INTEGER", "FLOAT", "TEXT", "BLOB", "NULL" } -- From 1 to 5. 71 | 72 | local opens = { 73 | READONLY = 0x00000001; 74 | READWRITE = 0x00000002; 75 | CREATE = 0x00000004; 76 | DELETEONCLOSE = 0x00000008; 77 | EXCLUSIVE = 0x00000010; 78 | AUTOPROXY = 0x00000020; 79 | URI = 0x00000040; 80 | MAIN_DB = 0x00000100; 81 | TEMP_DB = 0x00000200; 82 | TRANSIENT_DB = 0x00000400; 83 | MAIN_JOURNAL = 0x00000800; 84 | TEMP_JOURNAL = 0x00001000; 85 | SUBJOURNAL = 0x00002000; 86 | MASTER_JOURNAL = 0x00004000; 87 | NOMUTEX = 0x00008000; 88 | FULLMUTEX = 0x00010000; 89 | SHAREDCACHE = 0x00020000; 90 | PRIVATECACHE = 0x00040000; 91 | WAL = 0x00080000; 92 | } 93 | 94 | local t = sqlconstants 95 | local pre = "static const int32_t SQLITE_" 96 | for i=0,26 do t[#t+1] = pre..codes[i].."="..i..";\n" end 97 | for i=100,101 do t[#t+1] = pre..codes[i].."="..i..";\n" end 98 | for i=1,5 do t[#t+1] = pre..types[i].."="..i..";\n" end 99 | pre = pre.."OPEN_" 100 | for k,v in pairs(opens) do t[#t+1] = pre..k.."="..bit.tobit(v)..";\n" end 101 | end 102 | 103 | -- Cdef ------------------------------------------------------------------------ 104 | -- SQLITE_*, OPEN_* 105 | ffi.cdef(table.concat(sqlconstants)) 106 | 107 | -- sqlite3*, ljsqlite3_* 108 | ffi.cdef[[ 109 | // Typedefs. 110 | typedef struct sqlite3 sqlite3; 111 | typedef struct sqlite3_stmt sqlite3_stmt; 112 | typedef void (*sqlite3_destructor_type)(void*); 113 | typedef struct sqlite3_context sqlite3_context; 114 | typedef struct Mem sqlite3_value; 115 | 116 | // Get informative error message. 117 | const char *sqlite3_errmsg(sqlite3*); 118 | 119 | // Connection. 120 | int sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, 121 | const char *zVfs); 122 | int sqlite3_close(sqlite3*); 123 | int sqlite3_busy_timeout(sqlite3*, int ms); 124 | 125 | // Statement. 126 | int sqlite3_prepare_v2(sqlite3 *conn, const char *zSql, int nByte, 127 | sqlite3_stmt **ppStmt, const char **pzTail); 128 | int sqlite3_step(sqlite3_stmt*); 129 | int sqlite3_reset(sqlite3_stmt *pStmt); 130 | int sqlite3_finalize(sqlite3_stmt *pStmt); 131 | 132 | // Extra functions for SELECT. 133 | int sqlite3_column_count(sqlite3_stmt *pStmt); 134 | const char *sqlite3_column_name(sqlite3_stmt*, int N); 135 | int sqlite3_column_type(sqlite3_stmt*, int iCol); 136 | 137 | // Get value from SELECT. 138 | int64_t sqlite3_column_int64(sqlite3_stmt*, int iCol); 139 | double sqlite3_column_double(sqlite3_stmt*, int iCol); 140 | int sqlite3_column_bytes(sqlite3_stmt*, int iCol); 141 | const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); 142 | const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 143 | 144 | // Set value in bind. 145 | int sqlite3_bind_int64(sqlite3_stmt*, int, int64_t); 146 | int sqlite3_bind_double(sqlite3_stmt*, int, double); 147 | int sqlite3_bind_null(sqlite3_stmt*, int); 148 | int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); 149 | int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); 150 | 151 | // Clear bindings. 152 | int sqlite3_clear_bindings(sqlite3_stmt*); 153 | 154 | // Get value in callbacks. 155 | int sqlite3_value_type(sqlite3_value*); 156 | int64_t sqlite3_value_int64(sqlite3_value*); 157 | double sqlite3_value_double(sqlite3_value*); 158 | int sqlite3_value_bytes(sqlite3_value*); 159 | const unsigned char *sqlite3_value_text(sqlite3_value*); //Not used. 160 | const void *sqlite3_value_blob(sqlite3_value*); 161 | 162 | // Set value in callbacks. 163 | void sqlite3_result_error(sqlite3_context*, const char*, int); 164 | void sqlite3_result_int64(sqlite3_context*, int64_t); 165 | void sqlite3_result_double(sqlite3_context*, double); 166 | void sqlite3_result_null(sqlite3_context*); 167 | void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); 168 | void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); 169 | 170 | // Persistency of data in callbacks (here just a pointer for tagging). 171 | void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); 172 | 173 | // Typedefs for callbacks. 174 | typedef void (*ljsqlite3_cbstep)(sqlite3_context*,int,sqlite3_value**); 175 | typedef void (*ljsqlite3_cbfinal)(sqlite3_context*); 176 | 177 | // Register callbacks. 178 | int sqlite3_create_function( 179 | sqlite3 *conn, 180 | const char *zFunctionName, 181 | int nArg, 182 | int eTextRep, 183 | void *pApp, 184 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 185 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 186 | void (*xFinal)(sqlite3_context*) 187 | ); 188 | ]] 189 | 190 | -------------------------------------------------------------------------------- 191 | local sql = ffi.load("sqlite3") 192 | 193 | local transient = ffi.cast("sqlite3_destructor_type", -1) 194 | local int64_ct = ffi.typeof("int64_t") 195 | 196 | local blob_mt = {} -- For tagging only. 197 | 198 | local function blob(str) 199 | return setmetatable({ str }, blob_mt) 200 | end 201 | 202 | local connstmt = {} -- Statements for a conn. 203 | local conncb = {} -- Callbacks for a conn. 204 | local aggregatestate = {} -- Aggregate states. 205 | 206 | local stmt_step 207 | 208 | local stmt_mt, stmt_ct = {} 209 | stmt_mt.__index = stmt_mt 210 | 211 | local conn_mt, conn_ct = {} 212 | conn_mt.__index = conn_mt 213 | 214 | -- Checks ---------------------------------------------------------------------- 215 | 216 | -- Helper function to get error msg and code from sqlite. 217 | local function codemsg(pconn, code) 218 | return codes[code]:lower(), ffi.string(sql.sqlite3_errmsg(pconn)) 219 | end 220 | 221 | -- Throw error for a given connection. 222 | local function E_conn(pconn, code) 223 | local code, msg = codemsg(pconn, code) 224 | err(code, msg) 225 | end 226 | 227 | -- Test code is OK or throw error for a given connection. 228 | local function T_okcode(pconn, code) 229 | if code ~= sql.SQLITE_OK then 230 | E_conn(pconn, code) 231 | end 232 | end 233 | 234 | local function T_open(x) 235 | if x._closed then 236 | err("misuse", "object is closed") 237 | end 238 | end 239 | 240 | -- Getters / Setters to minimize code duplication ------------------------------ 241 | local sql_get_code = [=[ 242 | return function(stmt_or_value ) 243 | local t = sql.sqlite3__type(stmt_or_value ) 244 | if t == sql.SQLITE_INTEGER then 245 | return sql.sqlite3__int64(stmt_or_value ) 246 | elseif t == sql.SQLITE_FLOAT then 247 | return sql.sqlite3__double(stmt_or_value ) 248 | elseif t == sql.SQLITE_TEXT then 249 | local nb = sql.sqlite3__bytes(stmt_or_value ) 250 | return ffi.string(sql.sqlite3__text(stmt_or_value ), nb) 251 | elseif t == sql.SQLITE_BLOB then 252 | local nb = sql.sqlite3__bytes(stmt_or_value ) 253 | return ffi.string(sql.sqlite3__blob(stmt_or_value ), nb) 254 | elseif t == sql.SQLITE_NULL then 255 | return nil 256 | else 257 | err("constraint", "unexpected SQLite3 type") 258 | end 259 | end 260 | ]=] 261 | 262 | local sql_set_code = [=[ 263 | return function(stmt_or_value, v ) 264 | local t = type(v) 265 | if ffi.istype(int64_ct, v) then 266 | return sql.sqlite3__int64(stmt_or_value , v) 267 | elseif t == "number" then 268 | return sql.sqlite3__double(stmt_or_value , v) 269 | elseif t == "string" then 270 | return sql.sqlite3__text(stmt_or_value , v, #v, 271 | transient) 272 | elseif t == "table" and getmetatable(v) == blob_mt then 273 | v = v[1] 274 | return sql.sqlite3__blob(stmt_or_value , v, #v, 275 | transient) 276 | elseif t == "nil" then 277 | return sql.sqlite3__null(stmt_or_value ) 278 | else 279 | err("constraint", "unexpected Lua type") 280 | end 281 | end 282 | ]=] 283 | 284 | -- Environment for setters/getters. 285 | local sql_env = { 286 | sql = sql, 287 | transient = transient, 288 | ffi = ffi, 289 | int64_ct = int64_ct, 290 | blob_mt = blob_mt, 291 | getmetatable = getmetatable, 292 | err = err, 293 | type = type 294 | } 295 | 296 | local function sql_format(s, variant, index) 297 | return s:gsub("", variant):gsub("", index) 298 | end 299 | 300 | local function loadcode(s, env) 301 | local ret = assert(loadstring(s)) 302 | if env then setfenv(ret, env) end 303 | return ret() 304 | end 305 | 306 | -- Must always be called from *:_* function due to error level 4. 307 | local get_column = loadcode(sql_format(sql_get_code, "column", ",i"), sql_env) 308 | local get_value = loadcode(sql_format(sql_get_code, "value" , " "), sql_env) 309 | local set_column = loadcode(sql_format(sql_set_code, "bind" , ",i"), sql_env) 310 | local set_value = loadcode(sql_format(sql_set_code, "result", " "), sql_env) 311 | 312 | -- Connection ------------------------------------------------------------------ 313 | local open_modes = { 314 | ro = sql.SQLITE_OPEN_READONLY, 315 | rw = sql.SQLITE_OPEN_READWRITE, 316 | rwc = bit.bor(sql.SQLITE_OPEN_READWRITE, sql.SQLITE_OPEN_CREATE) 317 | } 318 | 319 | local function open(str, mode) 320 | mode = mode or "rwc" 321 | mode = open_modes[mode] 322 | if not mode then 323 | err("constraint", "argument #2 to open must be ro, rw, or rwc") 324 | end 325 | local aptr = ffi.new("sqlite3*[1]") 326 | -- Usually aptr is set even if error code, so conn always needs to be closed. 327 | local code = sql.sqlite3_open_v2(str, aptr, mode, nil) 328 | local conn = conn_ct(aptr[0], false) 329 | -- Must create this anyway due to conn:close() function. 330 | connstmt[conn] = setmetatable({}, { __mode = "k" }) 331 | conncb[conn] = { scalar = {}, step = {}, final = {} } 332 | if code ~= sql.SQLITE_OK then 333 | local code, msg = codemsg(conn._ptr, code) -- Before closing! 334 | conn:close() -- Free resources, should not fail here in this case! 335 | err(code, msg) 336 | end 337 | return conn 338 | end 339 | 340 | function conn_mt:close() T_open(self) 341 | -- Close all stmt linked to conn. 342 | for k,_ in pairs(connstmt[self]) do if not k._closed then k:close() end end 343 | -- Close all callbacks linked to conn. 344 | for _,v in pairs(conncb[self].scalar) do v:free() end 345 | for _,v in pairs(conncb[self].step) do v:free() end 346 | for _,v in pairs(conncb[self].final) do v:free() end 347 | local code = sql.sqlite3_close(self._ptr) 348 | T_okcode(self._ptr, code) 349 | connstmt[self] = nil -- Table connstmt is not weak, need to clear manually. 350 | conncb[self] = nil 351 | self._closed = true -- Set only if close succeded. 352 | end 353 | 354 | function conn_mt:__gc() 355 | if not self._closed then self:close() end 356 | end 357 | 358 | function conn_mt:prepare(stmtstr) T_open(self) 359 | local aptr = ffi.new("sqlite3_stmt*[1]") 360 | -- If error code aptr NULL, so no need to close anything. 361 | local code = sql.sqlite3_prepare_v2(self._ptr, stmtstr, #stmtstr, aptr, nil) 362 | T_okcode(self._ptr, code) 363 | local stmt = stmt_ct(aptr[0], false, self._ptr, code) 364 | connstmt[self][stmt] = true 365 | return stmt 366 | end 367 | 368 | -- Connection exec, __call, rowexec -------------------------------------------- 369 | function conn_mt:exec(commands, get) T_open(self) 370 | local cmd1 = split(commands, ";") 371 | local res, n 372 | for i=1,#cmd1 do 373 | local cmd = trim(cmd1[i]) 374 | if #cmd > 0 then 375 | local stmt = self:prepare(cmd) 376 | res, n = stmt:resultset(get) 377 | stmt:close() 378 | end 379 | end 380 | return res, n -- Only last record is returned. 381 | end 382 | 383 | function conn_mt:rowexec(command) T_open(self) 384 | local stmt = self:prepare(command) 385 | local res = stmt:_step() 386 | if stmt:_step() then 387 | err("misuse", "multiple records returned, 1 expected") 388 | end 389 | stmt:close() 390 | if res then 391 | return unpack(res) 392 | else 393 | return nil 394 | end 395 | end 396 | 397 | function conn_mt:__call(commands, out) T_open(self) 398 | out = out or print 399 | local cmd1 = split(commands, ";") 400 | for c=1,#cmd1 do 401 | local cmd = trim(cmd1[c]) 402 | if #cmd > 0 then 403 | local stmt = self:prepare(cmd) 404 | local ret, n = stmt:resultset() 405 | if ret then -- All the results get handled, not only last one. 406 | out(unpack(ret[0])) -- Headers are printed. 407 | for i=1,n do 408 | local o = {} 409 | for j=1,#ret[0] do 410 | local v = ret[j][i] 411 | if type(v) == "nil" then v = "" end -- Empty strings for NULLs. 412 | o[#o+1] = tostring(v) 413 | end 414 | out(unpack(o)) 415 | end 416 | end 417 | stmt:close() 418 | end 419 | end 420 | end 421 | 422 | -- Callbacks ------------------------------------------------------------------- 423 | -- Update (one of) callbacks registry for sqlite functions. 424 | local function updatecb(self, where, name, f) 425 | local cbs = conncb[self][where] 426 | if cbs[name] then -- Callback already present, free old one. 427 | cbs[name]:free() 428 | end 429 | cbs[name] = f -- Could be nil and that's fine. 430 | end 431 | 432 | -- Return manually casted callback that sqlite expects, scalar. 433 | local function scalarcb(name, f) 434 | local values = {} -- Conversion buffer. 435 | local function sqlf(context, nvalues, pvalues) 436 | -- Indexing 0,N-1. 437 | for i=1,nvalues do values[i] = get_value(pvalues[i - 1]) end 438 | -- Throw error via sqlite function if necessary. 439 | local ok, result = pcall(f, unpack(values, 1, nvalues)) 440 | if not ok then 441 | local msg = "Lua registered scalar function "..name.." error: "..result 442 | sql.sqlite3_result_error(context, msg, #msg) 443 | else 444 | set_value(context, result) 445 | end 446 | end 447 | return ffi.cast("ljsqlite3_cbstep", sqlf) 448 | end 449 | 450 | -- Return the state for aggregate case (created via initstate()). We use the ptr 451 | -- returned from aggregate_context() for tagging only, all the state data is 452 | -- handled from Lua side. 453 | local function getstate(context, initstate, size) 454 | -- Only pointer address relevant for indexing, size irrelevant. 455 | local ptr = sql.sqlite3_aggregate_context(context, size) 456 | local pid = tonumber(ffi.cast("intptr_t",ptr)) 457 | local state = aggregatestate[pid] 458 | if type(state) == "nil" then 459 | state = initstate() 460 | aggregatestate[pid] = state 461 | end 462 | return state, pid 463 | end 464 | 465 | -- Return manually casted callback that sqlite expects, stepper for aggregate. 466 | local function stepcb(name, f, initstate) 467 | local values = {} -- Conversion buffer. 468 | local function sqlf(context, nvalues, pvalues) 469 | -- Indexing 0,N-1. 470 | for i=1,nvalues do values[i] = get_value(pvalues[i - 1]) end 471 | local state = getstate(context, initstate, 1) 472 | -- Throw error via sqlite function if necessary. 473 | local ok, result = pcall(f, state, unpack(values, 1, nvalues)) 474 | if not ok then 475 | local msg = "Lua registered step function "..name.." error: "..result 476 | sql.sqlite3_result_error(context, msg, #msg) 477 | end 478 | end 479 | return ffi.cast("ljsqlite3_cbstep", sqlf) 480 | end 481 | 482 | -- Return manually casted callback that sqlite expects, finalizer for aggregate. 483 | local function finalcb(name, f, initstate) 484 | local function sqlf(context) 485 | local state, pid = getstate(context, initstate, 0) 486 | aggregatestate[pid] = nil -- Clear the state. 487 | local ok, result = pcall(f, state) 488 | -- Throw error via sqlite function if necessary. 489 | if not ok then 490 | local msg = "Lua registered final function "..name.." error: "..result 491 | sql.sqlite3_result_error(context, msg, #msg) 492 | else 493 | set_value(context, result) 494 | end 495 | end 496 | return ffi.cast("ljsqlite3_cbfinal", sqlf) 497 | end 498 | 499 | function conn_mt:setscalar(name, f) T_open(self) 500 | jit.off(stmt_step) -- Necessary to avoid bad calloc in some use cases. 501 | local cbf = f and scalarcb(name, f) or nil 502 | local code = sql.sqlite3_create_function(self._ptr, name, -1, 5, nil, 503 | cbf, nil, nil) -- If cbf nil this clears the function is sqlite. 504 | T_okcode(self._ptr, code) 505 | updatecb(self, "scalar", name, cbf) -- Update and clear old. 506 | end 507 | 508 | function conn_mt:setaggregate(name, initstate, step, final) T_open(self) 509 | jit.off(stmt_step) -- Necessary to avoid bad calloc in some use cases. 510 | local cbs = step and stepcb (name, step, initstate) or nil 511 | local cbf = final and finalcb(name, final, initstate) or nil 512 | local code = sql.sqlite3_create_function(self._ptr, name, -1, 5, nil, 513 | nil, cbs, cbf) -- If cbs, cbf nil this clears the function is sqlite. 514 | T_okcode(self._ptr, code) 515 | updatecb(self, "step", name, cbs) -- Update and clear old. 516 | updatecb(self, "final", name, cbf) -- Update and clear old. 517 | end 518 | 519 | conn_ct = ffi.metatype("struct { sqlite3* _ptr; bool _closed; }", conn_mt) 520 | 521 | -- Statement ------------------------------------------------------------------- 522 | function stmt_mt:reset() T_open(self) 523 | -- Ignore possible error code, it would be repetition of error raised during 524 | -- most recent evaluation of statement which would have been raised already. 525 | sql.sqlite3_reset(self._ptr) 526 | self._code = sql.SQLITE_OK -- Always succeds. 527 | return self 528 | end 529 | 530 | function stmt_mt:close() T_open(self) 531 | -- Ignore possible error code, it would be repetition of error raised during 532 | -- most recent evaluation of statement which would have been raised already. 533 | sql.sqlite3_finalize(self._ptr) 534 | self._code = sql.SQLITE_OK -- Always succeds. 535 | self._closed = true -- Must be called exaclty once. 536 | end 537 | 538 | function stmt_mt:__gc() 539 | if not self._closed then self:close() end 540 | end 541 | 542 | -- Statement step, resultset --------------------------------------------------- 543 | function stmt_mt:_ncol() 544 | return sql.sqlite3_column_count(self._ptr) 545 | end 546 | 547 | function stmt_mt:_header(h) 548 | for i=1,self:_ncol() do -- Here indexing 0,N-1. 549 | h[i] = ffi.string(sql.sqlite3_column_name(self._ptr, i - 1)) 550 | end 551 | end 552 | 553 | stmt_step = function(self, row, header) 554 | -- Must check code ~= SQL_DONE or sqlite3_step --> undefined result. 555 | if self._code == sql.SQLITE_DONE then return nil end -- Already finished. 556 | self._code = sql.sqlite3_step(self._ptr) 557 | if self._code == sql.SQLITE_ROW then 558 | -- All the sql.* functions called never errors here. 559 | row = row or {} 560 | for i=1,self:_ncol() do 561 | row[i] = get_column(self._ptr, i - 1) 562 | end 563 | if header then self:_header(header) end 564 | return row, header 565 | elseif self._code == sql.SQLITE_DONE then -- Have finished now. 566 | return nil 567 | else -- If code not DONE or ROW then it's error. 568 | E_conn(self._conn, self._code) 569 | end 570 | end 571 | stmt_mt._step = stmt_step 572 | 573 | function stmt_mt:step(row, header) T_open(self) 574 | return self:_step(row, header) 575 | end 576 | 577 | function stmt_mt:resultset(get, maxrecords) T_open(self) 578 | get = get or "hik" 579 | maxrecords = maxrecords or math.huge 580 | if maxrecords < 1 then 581 | err("constraint", "agument #1 to resultset must be >= 1") 582 | end 583 | local hash, hasi, hask = get:find("h"), get:find("i"), get:find("k") 584 | local r, h = self:_step({}, {}) 585 | if not r then return nil, 0 end -- No records case. 586 | -- First record, o is a temporary table used to get records. 587 | local o = hash and { [0] = h } or {} 588 | for i=1,#h do o[i] = { r[i] } end 589 | -- Other records. 590 | local n = 1 591 | while n < maxrecords and self:_step(r) do 592 | n = n + 1 593 | for i=1,#h do o[i][n] = r[i] end 594 | end 595 | 596 | local out = { [0] = o[0] } -- Eventually copy colnames. 597 | if hasi then -- Use numeric indexes. 598 | for i=1,#h do out[i] = o[i] end 599 | end 600 | if hask then -- Use colnames indexes. 601 | for i=1,#h do out[h[i]] = o[i] end 602 | end 603 | return out, n 604 | end 605 | 606 | -- Statement bind -------------------------------------------------------------- 607 | function stmt_mt:_bind1(i, v) 608 | local code = set_column(self._ptr, v, i) -- Here indexing 1,N. 609 | T_okcode(self._conn, code) 610 | return self 611 | end 612 | 613 | function stmt_mt:bind1(i, v) T_open(self) 614 | return self:_bind1(i, v) 615 | end 616 | 617 | function stmt_mt:bind(...) T_open(self) 618 | for i=1,select("#", ...) do self:_bind1(i, select(i, ...)) end 619 | return self 620 | end 621 | 622 | function stmt_mt:clearbind() T_open(self) 623 | local code = sql.sqlite3_clear_bindings(self._ptr) 624 | T_okcode(self._conn, code) 625 | return self 626 | end 627 | 628 | stmt_ct = ffi.metatype([[struct { 629 | sqlite3_stmt* _ptr; 630 | bool _closed; 631 | sqlite3* _conn; 632 | int32_t _code; 633 | }]], stmt_mt) 634 | 635 | return { 636 | open = open, 637 | blob = blob, 638 | } 639 | --------------------------------------------------------------------------------