mirror of
https://github.com/cuberite/sqlite.git
synced 2025-09-08 04:04:54 -04:00
Use C++ compiled Lua
This commit is contained in:
parent
4435d7e429
commit
9aeab26b00
@ -1,14 +1,5 @@
|
||||
cmake_minimum_required (VERSION 3.13)
|
||||
project (lsqlite C)
|
||||
|
||||
add_library(lsqlite lsqlite3.c)
|
||||
add_library(lsqlite lsqlite3.cpp)
|
||||
target_link_libraries(lsqlite PUBLIC sqlite3 lualib)
|
||||
|
||||
# FreeBSD requires us to define this to get POSIX 2001 standard
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
target_compile_definitions(lsqlite PRIVATE _XOPEN_SOURCE=600)
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(lsqlite PRIVATE ${DYNAMIC_LOADER})
|
||||
endif()
|
||||
|
@ -1,10 +1,10 @@
|
||||
/************************************************************************
|
||||
* lsqlite3 *
|
||||
* Copyright (C) 2002-2013 Tiago Dionizio, Doug Currie *
|
||||
* Copyright (C) 2002-2016 Tiago Dionizio, Doug Currie *
|
||||
* All rights reserved. *
|
||||
* Author : Tiago Dionizio <tiago.dionizio@ist.utl.pt> *
|
||||
* Author : Doug Currie <doug.currie@alum.mit.edu> *
|
||||
* Library : lsqlite3 - a SQLite 3 database binding for Lua 5 *
|
||||
* Library : lsqlite3 - an SQLite 3 database binding for Lua 5 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||
* a copy of this software and associated documentation files (the *
|
||||
@ -25,19 +25,6 @@
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE *
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
************************************************************************/
|
||||
// Slightly modified by _Xoft to compile in MSVC
|
||||
|
||||
|
||||
|
||||
|
||||
// 2013_04_07 _X: Added the following #define-s so that MSVC doesn't complain about non-secure stuff:
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -48,16 +35,25 @@ extern "C" {
|
||||
#include "lauxlib.h"
|
||||
|
||||
#if LUA_VERSION_NUM > 501
|
||||
//
|
||||
// Lua 5.2
|
||||
//
|
||||
/*
|
||||
** Lua 5.2
|
||||
*/
|
||||
#ifndef lua_strlen
|
||||
#define lua_strlen lua_rawlen
|
||||
// luaL_typerror always used with arg at ndx == NULL
|
||||
#endif
|
||||
/* luaL_typerror always used with arg at ndx == NULL */
|
||||
#define luaL_typerror(L,ndx,str) luaL_error(L,"bad argument %d (%s expected, got nil)",ndx,str)
|
||||
// luaL_register used once, so below expansion is OK for this case
|
||||
/* luaL_register used once, so below expansion is OK for this case */
|
||||
#define luaL_register(L,name,reg) lua_newtable(L);luaL_setfuncs(L,reg,0)
|
||||
// luaL_openlib always used with name == NULL
|
||||
/* luaL_openlib always used with name == NULL */
|
||||
#define luaL_openlib(L,name,reg,nup) luaL_setfuncs(L,reg,nup)
|
||||
|
||||
#if LUA_VERSION_NUM > 502
|
||||
/*
|
||||
** Lua 5.3
|
||||
*/
|
||||
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "sqlite3.h"
|
||||
@ -69,9 +65,15 @@ extern "C" {
|
||||
#if !defined(LSQLITE_OMIT_UPDATE_HOOK)
|
||||
#define LSQLITE_OMIT_UPDATE_HOOK 0
|
||||
#endif
|
||||
#if defined(LSQLITE_OMIT_OPEN_V2)
|
||||
#define SQLITE3_OPEN(L,filename,flags) sqlite3_open(L,filename)
|
||||
#else
|
||||
#define SQLITE3_OPEN(L,filename,flags) sqlite3_open_v2(L,filename,flags,NULL)
|
||||
#endif
|
||||
|
||||
typedef struct sdb sdb;
|
||||
typedef struct sdb_vm sdb_vm;
|
||||
typedef struct sdb_bu sdb_bu;
|
||||
typedef struct sdb_func sdb_func;
|
||||
|
||||
/* to use as C user data so i know what function sqlite is calling */
|
||||
@ -123,9 +125,36 @@ struct sdb {
|
||||
|
||||
static const char *sqlite_meta = ":sqlite3";
|
||||
static const char *sqlite_vm_meta = ":sqlite3:vm";
|
||||
static const char *sqlite_bu_meta = ":sqlite3:bu";
|
||||
static const char *sqlite_ctx_meta = ":sqlite3:ctx";
|
||||
static int sqlite_ctx_meta_ref;
|
||||
|
||||
/* Lua 5.3 introduced an integer type, but depending on the implementation, it could be 32
|
||||
** or 64 bits (or something else?). This helper macro tries to do "the right thing."
|
||||
*/
|
||||
|
||||
#if LUA_VERSION_NUM > 502
|
||||
#define PUSH_INT64(L,i64in,fallback) \
|
||||
do { \
|
||||
sqlite_int64 i64 = i64in; \
|
||||
lua_Integer i = (lua_Integer )i64; \
|
||||
if (i == i64) lua_pushinteger(L, i);\
|
||||
else { \
|
||||
lua_Number n = (lua_Number)i64; \
|
||||
if (n == i64) lua_pushnumber(L, n); \
|
||||
else fallback; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define PUSH_INT64(L,i64in,fallback) \
|
||||
do { \
|
||||
sqlite_int64 i64 = i64in; \
|
||||
lua_Number n = (lua_Number)i64; \
|
||||
if (n == i64) lua_pushnumber(L, n); \
|
||||
else fallback; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** Database Virtual Machine Operations
|
||||
@ -135,14 +164,9 @@ static int sqlite_ctx_meta_ref;
|
||||
static void vm_push_column(lua_State *L, sqlite3_stmt *vm, int idx) {
|
||||
switch (sqlite3_column_type(vm, idx)) {
|
||||
case SQLITE_INTEGER:
|
||||
{
|
||||
sqlite_int64 i64 = sqlite3_column_int64(vm, idx);
|
||||
lua_Number n = (lua_Number)i64;
|
||||
if (n == i64)
|
||||
lua_pushnumber(L, n);
|
||||
else
|
||||
lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx), sqlite3_column_bytes(vm, idx));
|
||||
}
|
||||
PUSH_INT64(L, sqlite3_column_int64(vm, idx)
|
||||
, lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx)
|
||||
, sqlite3_column_bytes(vm, idx)));
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
lua_pushnumber(L, sqlite3_column_double(vm, idx));
|
||||
@ -151,7 +175,7 @@ static void vm_push_column(lua_State *L, sqlite3_stmt *vm, int idx) {
|
||||
lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx), sqlite3_column_bytes(vm, idx));
|
||||
break;
|
||||
case SQLITE_BLOB:
|
||||
lua_pushlstring(L, sqlite3_column_blob(vm, idx), sqlite3_column_bytes(vm, idx));
|
||||
lua_pushlstring(L, (const char*)sqlite3_column_blob(vm, idx), sqlite3_column_bytes(vm, idx));
|
||||
break;
|
||||
case SQLITE_NULL:
|
||||
lua_pushnil(L);
|
||||
@ -174,9 +198,9 @@ struct sdb_vm {
|
||||
char temp; /* temporary vm used in db:rows */
|
||||
};
|
||||
|
||||
/* called with sql text on the lua stack */
|
||||
/* called with db,sql text on the lua stack */
|
||||
static sdb_vm *newvm(lua_State *L, sdb *db) {
|
||||
sdb_vm *svm = (sdb_vm*)lua_newuserdata(L, sizeof(sdb_vm));
|
||||
sdb_vm *svm = (sdb_vm*)lua_newuserdata(L, sizeof(sdb_vm)); /* db sql svm_ud -- */
|
||||
|
||||
luaL_getmetatable(L, sqlite_vm_meta);
|
||||
lua_setmetatable(L, -2); /* set metatable */
|
||||
@ -187,18 +211,19 @@ static sdb_vm *newvm(lua_State *L, sdb *db) {
|
||||
svm->vm = NULL;
|
||||
svm->temp = 0;
|
||||
|
||||
/* add an entry on the database table: svm -> sql text */
|
||||
lua_pushlightuserdata(L, db);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushlightuserdata(L, svm);
|
||||
lua_pushvalue(L, -4); /* the sql text */
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 1);
|
||||
/* add an entry on the database table: svm -> db to keep db live while svm is live */
|
||||
lua_pushlightuserdata(L, db); /* db sql svm_ud db_lud -- */
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* db sql svm_ud reg[db_lud] -- */
|
||||
lua_pushlightuserdata(L, svm); /* db sql svm_ud reg[db_lud] svm_lud -- */
|
||||
lua_pushvalue(L, -5); /* db sql svm_ud reg[db_lud] svm_lud db -- */
|
||||
lua_rawset(L, -3); /* (reg[db_lud])[svm_lud] = db ; set the db for this vm */
|
||||
lua_pop(L, 1); /* db sql svm_ud -- */
|
||||
|
||||
return svm;
|
||||
}
|
||||
|
||||
static int cleanupvm(lua_State *L, sdb_vm *svm) {
|
||||
|
||||
/* remove entry in database table - no harm if not present in the table */
|
||||
lua_pushlightuserdata(L, svm->db);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
@ -212,40 +237,13 @@ static int cleanupvm(lua_State *L, sdb_vm *svm) {
|
||||
|
||||
if (!svm->vm) return 0;
|
||||
|
||||
lua_pushnumber(L, sqlite3_finalize(svm->vm));
|
||||
lua_pushinteger(L, sqlite3_finalize(svm->vm));
|
||||
svm->vm = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int stepvm(lua_State *L, sdb_vm *svm) {
|
||||
int result;
|
||||
int loop_limit = 3;
|
||||
while ( loop_limit-- ) {
|
||||
result = sqlite3_step(svm->vm);
|
||||
if ( result==SQLITE_ERROR ) {
|
||||
result = sqlite3_reset (svm->vm);
|
||||
}
|
||||
if ( result==SQLITE_SCHEMA ) {
|
||||
sqlite3_stmt *vn;
|
||||
const char *sql;
|
||||
/* recover sql text */
|
||||
lua_pushlightuserdata(L, svm->db);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushlightuserdata(L, svm);
|
||||
lua_rawget(L, -2); /* sql text */
|
||||
sql = luaL_checkstring(L, -1);
|
||||
/* re-prepare */
|
||||
result = sqlite3_prepare(svm->db->db, sql, -1, &vn, NULL);
|
||||
if (result != SQLITE_OK) break;
|
||||
sqlite3_transfer_bindings(svm->vm, vn);
|
||||
sqlite3_finalize(svm->vm);
|
||||
svm->vm = vn;
|
||||
lua_pop(L,2);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return sqlite3_step(svm->vm);
|
||||
}
|
||||
|
||||
static sdb_vm *lsqlite_getvm(lua_State *L, int index) {
|
||||
@ -292,7 +290,7 @@ static int dbvm_step(lua_State *L) {
|
||||
svm->has_values = result == SQLITE_ROW ? 1 : 0;
|
||||
svm->columns = sqlite3_data_count(svm->vm);
|
||||
|
||||
lua_pushnumber(L, result);
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -304,7 +302,7 @@ static int dbvm_finalize(lua_State *L) {
|
||||
static int dbvm_reset(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
sqlite3_reset(svm->vm);
|
||||
lua_pushnumber(L, sqlite3_errcode(svm->db->db));
|
||||
lua_pushinteger(L, sqlite3_errcode(svm->db->db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -326,6 +324,14 @@ static void dbvm_check_bind_index(lua_State *L, sdb_vm *svm, int index) {
|
||||
}
|
||||
}
|
||||
|
||||
static int dbvm_last_insert_rowid(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
/* conversion warning: int64 -> luaNumber */
|
||||
sqlite_int64 rowid = sqlite3_last_insert_rowid(svm->db->db);
|
||||
PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** Virtual Machine - generic info
|
||||
@ -333,7 +339,7 @@ static void dbvm_check_bind_index(lua_State *L, sdb_vm *svm, int index) {
|
||||
*/
|
||||
static int dbvm_columns(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
lua_pushnumber(L, sqlite3_column_count(svm->vm));
|
||||
lua_pushinteger(L, sqlite3_column_count(svm->vm));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -354,7 +360,7 @@ static int dbvm_get_value(lua_State *L) {
|
||||
|
||||
static int dbvm_get_name(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
int index = (int)luaL_checknumber(L, 2);
|
||||
int index = luaL_checknumber(L, 2);
|
||||
dbvm_check_index(L, svm, index);
|
||||
lua_pushstring(L, sqlite3_column_name(svm->vm, index));
|
||||
return 1;
|
||||
@ -362,7 +368,7 @@ static int dbvm_get_name(lua_State *L) {
|
||||
|
||||
static int dbvm_get_type(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
int index = (int)luaL_checknumber(L, 2);
|
||||
int index = luaL_checknumber(L, 2);
|
||||
dbvm_check_index(L, svm, index);
|
||||
lua_pushstring(L, sqlite3_column_decltype(svm->vm, index));
|
||||
return 1;
|
||||
@ -375,7 +381,7 @@ static int dbvm_get_values(lua_State *L) {
|
||||
int n;
|
||||
dbvm_check_contents(L, svm);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, columns, 0);
|
||||
for (n = 0; n < columns;) {
|
||||
vm_push_column(L, vm, n++);
|
||||
lua_rawseti(L, -2, n);
|
||||
@ -389,7 +395,7 @@ static int dbvm_get_names(lua_State *L) {
|
||||
int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
|
||||
int n;
|
||||
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, columns, 0);
|
||||
for (n = 0; n < columns;) {
|
||||
lua_pushstring(L, sqlite3_column_name(vm, n++));
|
||||
lua_rawseti(L, -2, n);
|
||||
@ -403,7 +409,7 @@ static int dbvm_get_types(lua_State *L) {
|
||||
int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
|
||||
int n;
|
||||
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, columns, 0);
|
||||
for (n = 0; n < columns;) {
|
||||
lua_pushstring(L, sqlite3_column_decltype(vm, n++));
|
||||
lua_rawseti(L, -2, n);
|
||||
@ -455,7 +461,7 @@ static int dbvm_get_named_values(lua_State *L) {
|
||||
int n;
|
||||
dbvm_check_contents(L, svm);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, 0, columns);
|
||||
for (n = 0; n < columns; ++n) {
|
||||
lua_pushstring(L, sqlite3_column_name(vm, n));
|
||||
vm_push_column(L, vm, n);
|
||||
@ -470,7 +476,7 @@ static int dbvm_get_named_types(lua_State *L) {
|
||||
int columns = sqlite3_column_count(vm);
|
||||
int n;
|
||||
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, 0, columns);
|
||||
for (n = 0; n < columns; ++n) {
|
||||
lua_pushstring(L, sqlite3_column_name(vm, n));
|
||||
lua_pushstring(L, sqlite3_column_decltype(vm, n));
|
||||
@ -490,6 +496,10 @@ static int dbvm_bind_index(lua_State *L, sqlite3_stmt *vm, int index, int lindex
|
||||
case LUA_TSTRING:
|
||||
return sqlite3_bind_text(vm, index, lua_tostring(L, lindex), lua_strlen(L, lindex), SQLITE_TRANSIENT);
|
||||
case LUA_TNUMBER:
|
||||
#if LUA_VERSION_NUM > 502
|
||||
if (lua_isinteger(L, lindex))
|
||||
return sqlite3_bind_int64(vm, index, lua_tointeger(L, lindex));
|
||||
#endif
|
||||
return sqlite3_bind_double(vm, index, lua_tonumber(L, lindex));
|
||||
case LUA_TBOOLEAN:
|
||||
return sqlite3_bind_int(vm, index, lua_toboolean(L, lindex) ? 1 : 0);
|
||||
@ -505,13 +515,13 @@ static int dbvm_bind_index(lua_State *L, sqlite3_stmt *vm, int index, int lindex
|
||||
|
||||
static int dbvm_bind_parameter_count(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
lua_pushnumber(L, sqlite3_bind_parameter_count(svm->vm));
|
||||
lua_pushinteger(L, sqlite3_bind_parameter_count(svm->vm));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dbvm_bind_parameter_name(lua_State *L) {
|
||||
sdb_vm *svm = lsqlite_checkvm(L, 1);
|
||||
int index = (int)luaL_checknumber(L, 2);
|
||||
int index = luaL_checknumber(L, 2);
|
||||
dbvm_check_bind_index(L, svm, index);
|
||||
lua_pushstring(L, sqlite3_bind_parameter_name(svm->vm, index));
|
||||
return 1;
|
||||
@ -526,7 +536,7 @@ static int dbvm_bind(lua_State *L) {
|
||||
dbvm_check_bind_index(L, svm, index);
|
||||
result = dbvm_bind_index(L, vm, index, 3);
|
||||
|
||||
lua_pushnumber(L, result);
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -536,7 +546,7 @@ static int dbvm_bind_blob(lua_State *L) {
|
||||
const char *value = luaL_checkstring(L, 3);
|
||||
int len = lua_strlen(L, 3);
|
||||
|
||||
lua_pushnumber(L, sqlite3_bind_blob(svm->vm, index, value, len, SQLITE_TRANSIENT));
|
||||
lua_pushinteger(L, sqlite3_bind_blob(svm->vm, index, value, len, SQLITE_TRANSIENT));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -555,12 +565,12 @@ static int dbvm_bind_values(lua_State *L) {
|
||||
|
||||
for (n = 2; n <= top; ++n) {
|
||||
if ((result = dbvm_bind_index(L, vm, n - 1, n)) != SQLITE_OK) {
|
||||
lua_pushnumber(L, result);
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnumber(L, SQLITE_OK);
|
||||
lua_pushinteger(L, SQLITE_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -581,19 +591,19 @@ static int dbvm_bind_names(lua_State *L) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else {
|
||||
lua_pushnumber(L, n);
|
||||
lua_pushinteger(L, n);
|
||||
lua_gettable(L, 2);
|
||||
result = dbvm_bind_index(L, vm, n, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if (result != SQLITE_OK) {
|
||||
lua_pushnumber(L, result);
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnumber(L, SQLITE_OK);
|
||||
lua_pushinteger(L, SQLITE_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -657,7 +667,7 @@ static int cleanupdb(lua_State *L, sdb *db) {
|
||||
top = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */
|
||||
sdb_vm *svm = (sdb_vm*)lua_touserdata(L, -2); /* key: vm; val: sql text */
|
||||
cleanupvm(L, svm);
|
||||
|
||||
lua_settop(L, top);
|
||||
@ -793,7 +803,7 @@ static int lcontext_set_aggregate_context(lua_State *L) {
|
||||
static int lcontext_aggregate_count(lua_State *L) {
|
||||
lcontext *ctx = lsqlite_checkcontext(L, 1);
|
||||
lcontext_check_aggregate(L, ctx);
|
||||
lua_pushnumber(L, sqlite3_aggregate_count(ctx->ctx));
|
||||
lua_pushinteger(L, sqlite3_aggregate_count(ctx->ctx));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -806,6 +816,11 @@ static int lcontext_result(lua_State *L) {
|
||||
lcontext *ctx = lsqlite_checkcontext(L, 1);
|
||||
switch (lua_type(L, 2)) {
|
||||
case LUA_TNUMBER:
|
||||
#if LUA_VERSION_NUM > 502
|
||||
if (lua_isinteger(L, 2))
|
||||
sqlite3_result_int64(ctx->ctx, luaL_checkinteger(L, 2));
|
||||
else
|
||||
#endif
|
||||
sqlite3_result_double(ctx->ctx, luaL_checknumber(L, 2));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
@ -883,29 +898,25 @@ static int db_last_insert_rowid(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
/* conversion warning: int64 -> luaNumber */
|
||||
sqlite_int64 rowid = sqlite3_last_insert_rowid(db->db);
|
||||
lua_Number n = (lua_Number)rowid;
|
||||
if (n == rowid)
|
||||
lua_pushnumber(L, n);
|
||||
else
|
||||
lua_pushfstring(L, "%ll", rowid);
|
||||
PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int db_changes(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
lua_pushnumber(L, sqlite3_changes(db->db));
|
||||
lua_pushinteger(L, sqlite3_changes(db->db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int db_total_changes(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
lua_pushnumber(L, sqlite3_total_changes(db->db));
|
||||
lua_pushinteger(L, sqlite3_total_changes(db->db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int db_errcode(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
lua_pushnumber(L, sqlite3_errcode(db->db));
|
||||
lua_pushinteger(L, sqlite3_errcode(db->db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -921,6 +932,14 @@ static int db_interrupt(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int db_db_filename(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
const char *db_name = luaL_checkstring(L, 2);
|
||||
// sqlite3_db_filename may return NULL, in that case Lua pushes nil...
|
||||
lua_pushstring(L, sqlite3_db_filename(db->db, db_name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Registering SQL functions:
|
||||
*/
|
||||
@ -932,14 +951,9 @@ static void db_push_value(lua_State *L, sqlite3_value *value) {
|
||||
break;
|
||||
|
||||
case SQLITE_INTEGER:
|
||||
{
|
||||
sqlite_int64 i64 = sqlite3_value_int64(value);
|
||||
lua_Number n = (lua_Number)i64;
|
||||
if (n == i64)
|
||||
lua_pushnumber(L, n);
|
||||
else
|
||||
lua_pushlstring(L, (const char*)sqlite3_value_text(value), sqlite3_value_bytes(value));
|
||||
}
|
||||
PUSH_INT64(L, sqlite3_value_int64(value)
|
||||
, lua_pushlstring(L, (const char*)sqlite3_value_text(value)
|
||||
, sqlite3_value_bytes(value)));
|
||||
break;
|
||||
|
||||
case SQLITE_FLOAT:
|
||||
@ -947,7 +961,7 @@ static void db_push_value(lua_State *L, sqlite3_value *value) {
|
||||
break;
|
||||
|
||||
case SQLITE_BLOB:
|
||||
lua_pushlstring(L, sqlite3_value_blob(value), sqlite3_value_bytes(value));
|
||||
lua_pushlstring(L, (const char*)sqlite3_value_blob(value), sqlite3_value_bytes(value));
|
||||
break;
|
||||
|
||||
case SQLITE_NULL:
|
||||
@ -1165,8 +1179,8 @@ static int collwrapper(scc *co,int l1,const void *p1,
|
||||
int res=0;
|
||||
lua_State *L=co->L;
|
||||
lua_rawgeti(L,LUA_REGISTRYINDEX,co->ref);
|
||||
lua_pushlstring(L,p1,l1);
|
||||
lua_pushlstring(L,p2,l2);
|
||||
lua_pushlstring(L,(const char*)p1,l1);
|
||||
lua_pushlstring(L,(const char*)p2,l2);
|
||||
if (lua_pcall(L,2,1,0)==0) res=(int)lua_tonumber(L,-1);
|
||||
lua_pop(L,1);
|
||||
return res;
|
||||
@ -1205,6 +1219,34 @@ static int db_create_collation(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Thanks to Wolfgang Oertl...
|
||||
*/
|
||||
static int db_load_extension(lua_State *L) {
|
||||
sdb *db=lsqlite_checkdb(L,1);
|
||||
const char *extname=luaL_optstring(L,2,NULL);
|
||||
const char *entrypoint=luaL_optstring(L,3,NULL);
|
||||
int result;
|
||||
char *errmsg = NULL;
|
||||
|
||||
if (extname == NULL) {
|
||||
result = sqlite3_enable_load_extension(db->db,0); /* disable extension loading */
|
||||
}
|
||||
else {
|
||||
sqlite3_enable_load_extension(db->db,1); /* enable extension loading */
|
||||
result = sqlite3_load_extension(db->db,extname,entrypoint,&errmsg);
|
||||
}
|
||||
|
||||
if (result == SQLITE_OK) {
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushboolean(L,0); /* so, assert(load_extension(...)) works */
|
||||
lua_pushstring(L,errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
** trace callback:
|
||||
** Params: database, callback function, userdata
|
||||
@ -1275,18 +1317,16 @@ static void db_update_hook_callback(void *user, int op, char const *dbname, char
|
||||
sdb *db = (sdb*)user;
|
||||
lua_State *L = db->L;
|
||||
int top = lua_gettop(L);
|
||||
lua_Number n = (lua_Number)rowid;
|
||||
lua_Number n;
|
||||
|
||||
/* setup lua callback call */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, db->update_hook_cb); /* get callback */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, db->update_hook_udata); /* get callback user data */
|
||||
lua_pushnumber(L, (lua_Number )op);
|
||||
lua_pushinteger(L, op);
|
||||
lua_pushstring(L, dbname); /* update_hook database name */
|
||||
lua_pushstring(L, tblname); /* update_hook database name */
|
||||
if (n == rowid)
|
||||
lua_pushnumber(L, n);
|
||||
else
|
||||
lua_pushfstring(L, "%ll", rowid);
|
||||
|
||||
PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid));
|
||||
|
||||
/* call lua function */
|
||||
lua_pcall(L, 5, 0, 0);
|
||||
@ -1513,6 +1553,122 @@ static int db_progress_handler(lua_State *L) {
|
||||
|
||||
#endif /* #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK */
|
||||
|
||||
/* Online Backup API */
|
||||
#if 0
|
||||
sqlite3_backup *sqlite3_backup_init(
|
||||
sqlite3 *pDest, /* Destination database handle */
|
||||
const char *zDestName, /* Destination database name */
|
||||
sqlite3 *pSource, /* Source database handle */
|
||||
const char *zSourceName /* Source database name */
|
||||
);
|
||||
int sqlite3_backup_step(sqlite3_backup *p, int nPage);
|
||||
int sqlite3_backup_finish(sqlite3_backup *p);
|
||||
int sqlite3_backup_remaining(sqlite3_backup *p);
|
||||
int sqlite3_backup_pagecount(sqlite3_backup *p);
|
||||
#endif
|
||||
|
||||
struct sdb_bu {
|
||||
sqlite3_backup *bu; /* backup structure */
|
||||
};
|
||||
|
||||
static int cleanupbu(lua_State *L, sdb_bu *sbu) {
|
||||
|
||||
if (!sbu->bu) return 0; /* already finished */
|
||||
|
||||
/* remove table from registry */
|
||||
lua_pushlightuserdata(L, sbu->bu);
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
lua_pushinteger(L, sqlite3_backup_finish(sbu->bu));
|
||||
sbu->bu = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsqlite_backup_init(lua_State *L) {
|
||||
|
||||
sdb *target_db = lsqlite_checkdb(L, 1);
|
||||
const char *target_nm = luaL_checkstring(L, 2);
|
||||
sdb *source_db = lsqlite_checkdb(L, 3);
|
||||
const char *source_nm = luaL_checkstring(L, 4);
|
||||
|
||||
sqlite3_backup *bu = sqlite3_backup_init(target_db->db, target_nm, source_db->db, source_nm);
|
||||
|
||||
if (NULL != bu) {
|
||||
sdb_bu *sbu = (sdb_bu*)lua_newuserdata(L, sizeof(sdb_bu));
|
||||
|
||||
luaL_getmetatable(L, sqlite_bu_meta);
|
||||
lua_setmetatable(L, -2); /* set metatable */
|
||||
sbu->bu = bu;
|
||||
|
||||
/* create table from registry */
|
||||
/* to prevent referenced databases from being garbage collected while bu is live */
|
||||
lua_pushlightuserdata(L, bu);
|
||||
lua_createtable(L, 2, 0);
|
||||
/* add source and target dbs to table at indices 1 and 2 */
|
||||
lua_pushvalue(L, 1); /* target db */
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_pushvalue(L, 3); /* source db */
|
||||
lua_rawseti(L, -2, 2);
|
||||
/* put table in registry with key lightuserdata bu */
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static sdb_bu *lsqlite_getbu(lua_State *L, int index) {
|
||||
sdb_bu *sbu = (sdb_bu*)luaL_checkudata(L, index, sqlite_bu_meta);
|
||||
if (sbu == NULL) luaL_typerror(L, index, "sqlite database backup");
|
||||
return sbu;
|
||||
}
|
||||
|
||||
static sdb_bu *lsqlite_checkbu(lua_State *L, int index) {
|
||||
sdb_bu *sbu = lsqlite_getbu(L, index);
|
||||
if (sbu->bu == NULL) luaL_argerror(L, index, "attempt to use closed sqlite database backup");
|
||||
return sbu;
|
||||
}
|
||||
|
||||
static int dbbu_gc(lua_State *L) {
|
||||
sdb_bu *sbu = lsqlite_getbu(L, 1);
|
||||
if (sbu->bu != NULL) {
|
||||
cleanupbu(L, sbu);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
/* else ignore if already finished */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dbbu_step(lua_State *L) {
|
||||
sdb_bu *sbu = lsqlite_checkbu(L, 1);
|
||||
int nPage = luaL_checkint(L, 2);
|
||||
lua_pushinteger(L, sqlite3_backup_step(sbu->bu, nPage));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dbbu_remaining(lua_State *L) {
|
||||
sdb_bu *sbu = lsqlite_checkbu(L, 1);
|
||||
lua_pushinteger(L, sqlite3_backup_remaining(sbu->bu));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dbbu_pagecount(lua_State *L) {
|
||||
sdb_bu *sbu = lsqlite_checkbu(L, 1);
|
||||
lua_pushinteger(L, sqlite3_backup_pagecount(sbu->bu));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dbbu_finish(lua_State *L) {
|
||||
sdb_bu *sbu = lsqlite_checkbu(L, 1);
|
||||
return cleanupbu(L, sbu);
|
||||
}
|
||||
|
||||
/* end of Online Backup API */
|
||||
|
||||
/*
|
||||
** busy handler:
|
||||
** Params: database, callback function, userdata
|
||||
@ -1529,7 +1685,7 @@ static int db_busy_callback(void *user, int tries) {
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_cb);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_udata);
|
||||
lua_pushnumber(L, tries);
|
||||
lua_pushinteger(L, tries);
|
||||
|
||||
/* call lua function */
|
||||
if (!lua_pcall(L, 2, 1, 0))
|
||||
@ -1602,7 +1758,7 @@ static int db_exec_callback(void* user, int columns, char **data, char **names)
|
||||
|
||||
lua_pushvalue(L, 3); /* function to call */
|
||||
lua_pushvalue(L, 4); /* user data */
|
||||
lua_pushnumber(L, columns); /* total number of rows in result */
|
||||
lua_pushinteger(L, columns); /* total number of rows in result */
|
||||
|
||||
/* column values */
|
||||
lua_pushvalue(L, 6);
|
||||
@ -1615,7 +1771,7 @@ static int db_exec_callback(void* user, int columns, char **data, char **names)
|
||||
lua_pushvalue(L, 5);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, columns, 0);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_replace(L, 5);
|
||||
for (n = 0; n < columns;) {
|
||||
@ -1626,8 +1782,14 @@ static int db_exec_callback(void* user, int columns, char **data, char **names)
|
||||
|
||||
/* call lua function */
|
||||
if (!lua_pcall(L, 4, 1, 0)) {
|
||||
|
||||
#if LUA_VERSION_NUM > 502
|
||||
if (lua_isinteger(L, -1))
|
||||
result = lua_tointeger(L, -1);
|
||||
else
|
||||
#endif
|
||||
if (lua_isnumber(L, -1))
|
||||
result = (int)lua_tonumber(L, -1);
|
||||
result = lua_tonumber(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
@ -1658,7 +1820,7 @@ static int db_exec(lua_State *L) {
|
||||
result = sqlite3_exec(db->db, sql, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
lua_pushnumber(L, result);
|
||||
lua_pushinteger(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1672,14 +1834,14 @@ static int db_prepare(lua_State *L) {
|
||||
int sql_len = lua_strlen(L, 2);
|
||||
const char *sqltail;
|
||||
sdb_vm *svm;
|
||||
lua_settop(L,2); /* sql is on top of stack for call to newvm */
|
||||
lua_settop(L,2); /* db,sql is on top of stack for call to newvm */
|
||||
svm = newvm(L, db);
|
||||
|
||||
if (sqlite3_prepare(db->db, sql, sql_len, &svm->vm, &sqltail) != SQLITE_OK) {
|
||||
cleanupvm(L, svm);
|
||||
|
||||
if (sqlite3_prepare_v2(db->db, sql, sql_len, &svm->vm, &sqltail) != SQLITE_OK) {
|
||||
lua_pushnil(L);
|
||||
lua_pushnumber(L, sqlite3_errcode(db->db));
|
||||
lua_pushinteger(L, sqlite3_errcode(db->db));
|
||||
if (cleanupvm(L, svm) == 1)
|
||||
lua_pop(L, 1); /* this should not happen since sqlite3_prepare_v2 will not set ->vm on error */
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -1702,14 +1864,15 @@ static int db_do_next_row(lua_State *L, int packed) {
|
||||
|
||||
if (result == SQLITE_ROW) {
|
||||
if (packed) {
|
||||
lua_newtable(L);
|
||||
if (packed == 1) {
|
||||
lua_createtable(L, columns, 0);
|
||||
for (i = 0; i < columns;) {
|
||||
vm_push_column(L, vm, i);
|
||||
lua_rawseti(L, -2, ++i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lua_createtable(L, 0, columns);
|
||||
for (i = 0; i < columns; ++i) {
|
||||
lua_pushstring(L, sqlite3_column_name(vm, i));
|
||||
vm_push_column(L, vm, i);
|
||||
@ -1780,14 +1943,14 @@ static int db_do_rows(lua_State *L, int(*f)(lua_State *)) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
const char *sql = luaL_checkstring(L, 2);
|
||||
sdb_vm *svm;
|
||||
lua_settop(L,2); /* sql is on top of stack for call to newvm */
|
||||
lua_settop(L,2); /* db,sql is on top of stack for call to newvm */
|
||||
svm = newvm(L, db);
|
||||
svm->temp = 1;
|
||||
|
||||
if (sqlite3_prepare(db->db, sql, -1, &svm->vm, NULL) != SQLITE_OK) {
|
||||
cleanupvm(L, svm);
|
||||
|
||||
if (sqlite3_prepare_v2(db->db, sql, -1, &svm->vm, NULL) != SQLITE_OK) {
|
||||
lua_pushstring(L, sqlite3_errmsg(svm->db->db));
|
||||
if (cleanupvm(L, svm) == 1)
|
||||
lua_pop(L, 1); /* this should not happen since sqlite3_prepare_v2 will not set ->vm on error */
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
@ -1822,7 +1985,7 @@ static int db_tostring(lua_State *L) {
|
||||
|
||||
static int db_close(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
lua_pushnumber(L, cleanupdb(L, db));
|
||||
lua_pushinteger(L, cleanupdb(L, db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1838,7 +2001,7 @@ static int db_close_vm(lua_State *L) {
|
||||
/* close all used handles */
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */
|
||||
sdb_vm *svm = (sdb_vm*)lua_touserdata(L, -2); /* key: vm; val: sql text */
|
||||
|
||||
if ((!temp || svm->temp) && svm->vm)
|
||||
{
|
||||
@ -1852,6 +2015,17 @@ static int db_close_vm(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* From: Wolfgang Oertl
|
||||
When using lsqlite3 in a multithreaded environment, each thread has a separate Lua
|
||||
environment, but full userdata structures can't be passed from one thread to another.
|
||||
This is possible with lightuserdata, however. See: lsqlite_open_ptr().
|
||||
*/
|
||||
static int db_get_ptr(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
lua_pushlightuserdata(L, db->db);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int db_gc(lua_State *L) {
|
||||
sdb *db = lsqlite_getdb(L, 1);
|
||||
if (db->db != NULL) /* ignore closed databases */
|
||||
@ -1876,7 +2050,7 @@ static int lsqlite_complete(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
static int lsqlite_temp_directory(lua_State *L) {
|
||||
const char *oldtemp = sqlite3_temp_directory;
|
||||
|
||||
@ -1897,17 +2071,17 @@ static int lsqlite_temp_directory(lua_State *L) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lsqlite_do_open(lua_State *L, const char *filename) {
|
||||
static int lsqlite_do_open(lua_State *L, const char *filename, int flags) {
|
||||
sdb *db = newdb(L); /* create and leave in stack */
|
||||
|
||||
if (sqlite3_open(filename, &db->db) == SQLITE_OK) {
|
||||
if (SQLITE3_OPEN(filename, &db->db, flags) == SQLITE_OK) {
|
||||
/* database handle already in the stack - return it */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* failed to open database */
|
||||
lua_pushnil(L); /* push nil */
|
||||
lua_pushnumber(L, sqlite3_errcode(db->db));
|
||||
lua_pushinteger(L, sqlite3_errcode(db->db));
|
||||
lua_pushstring(L, sqlite3_errmsg(db->db)); /* push error message */
|
||||
|
||||
/* clean things up */
|
||||
@ -1919,11 +2093,36 @@ static int lsqlite_do_open(lua_State *L, const char *filename) {
|
||||
|
||||
static int lsqlite_open(lua_State *L) {
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
return lsqlite_do_open(L, filename);
|
||||
int flags = luaL_optinteger(L, 2, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
return lsqlite_do_open(L, filename, flags);
|
||||
}
|
||||
|
||||
static int lsqlite_open_memory(lua_State *L) {
|
||||
return lsqlite_do_open(L, ":memory:");
|
||||
return lsqlite_do_open(L, ":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
}
|
||||
|
||||
/* From: Wolfgang Oertl
|
||||
When using lsqlite3 in a multithreaded environment, each thread has a separate Lua
|
||||
environment, but full userdata structures can't be passed from one thread to another.
|
||||
This is possible with lightuserdata, however. See: db_get_ptr().
|
||||
*/
|
||||
static int lsqlite_open_ptr(lua_State *L) {
|
||||
sqlite3 *db_ptr;
|
||||
sdb *db;
|
||||
int rc;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
|
||||
db_ptr = (sqlite3*)lua_touserdata(L, 1);
|
||||
/* This is the only API function that runs sqlite3SafetyCheck regardless of
|
||||
* SQLITE_ENABLE_API_ARMOR and does almost nothing (without an SQL
|
||||
* statement) */
|
||||
rc = sqlite3_exec(db_ptr, NULL, NULL, NULL, NULL);
|
||||
if (rc != SQLITE_OK)
|
||||
luaL_argerror(L, 1, "not a valid SQLite3 pointer");
|
||||
|
||||
db = newdb(L); /* create and leave in stack */
|
||||
db->db = db_ptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsqlite_newindex(lua_State *L) {
|
||||
@ -1932,6 +2131,18 @@ static int lsqlite_newindex(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef LSQLITE_VERSION
|
||||
/* should be defined in rockspec, but just in case... */
|
||||
#define LSQLITE_VERSION "unknown"
|
||||
#endif
|
||||
|
||||
/* Version number of this library
|
||||
*/
|
||||
static int lsqlite_lversion(lua_State *L) {
|
||||
lua_pushstring(L, LSQLITE_VERSION);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** Register functions
|
||||
@ -1995,6 +2206,17 @@ static const struct {
|
||||
SC(FUNCTION )
|
||||
SC(SAVEPOINT )
|
||||
|
||||
/* file open flags */
|
||||
SC(OPEN_READONLY)
|
||||
SC(OPEN_READWRITE)
|
||||
SC(OPEN_CREATE)
|
||||
SC(OPEN_URI)
|
||||
SC(OPEN_MEMORY)
|
||||
SC(OPEN_NOMUTEX)
|
||||
SC(OPEN_FULLMUTEX)
|
||||
SC(OPEN_SHAREDCACHE)
|
||||
SC(OPEN_PRIVATECACHE)
|
||||
|
||||
/* terminator */
|
||||
{ NULL, 0 }
|
||||
};
|
||||
@ -2011,10 +2233,12 @@ static const luaL_Reg dblib[] = {
|
||||
{"errmsg", db_errmsg },
|
||||
{"error_message", db_errmsg },
|
||||
{"interrupt", db_interrupt },
|
||||
{"db_filename", db_db_filename },
|
||||
|
||||
{"create_function", db_create_function },
|
||||
{"create_aggregate", db_create_aggregate },
|
||||
{"create_collation", db_create_collation },
|
||||
{"load_extension", db_load_extension },
|
||||
|
||||
{"trace", db_trace },
|
||||
{"progress_handler", db_progress_handler },
|
||||
@ -2035,6 +2259,7 @@ static const luaL_Reg dblib[] = {
|
||||
{"execute", db_exec },
|
||||
{"close", db_close },
|
||||
{"close_vm", db_close_vm },
|
||||
{"get_ptr", db_get_ptr },
|
||||
|
||||
{"__tostring", db_tostring },
|
||||
{"__gc", db_gc },
|
||||
@ -2075,6 +2300,8 @@ static const luaL_Reg vmlib[] = {
|
||||
{"urows", dbvm_urows },
|
||||
{"nrows", dbvm_nrows },
|
||||
|
||||
{"last_insert_rowid", dbvm_last_insert_rowid },
|
||||
|
||||
/* compatibility names (added by request) */
|
||||
{"idata", dbvm_get_values },
|
||||
{"inames", dbvm_get_names },
|
||||
@ -2108,14 +2335,30 @@ static const luaL_Reg ctxlib[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_Reg dbbulib[] = {
|
||||
|
||||
{"step", dbbu_step },
|
||||
{"remaining", dbbu_remaining },
|
||||
{"pagecount", dbbu_pagecount },
|
||||
{"finish", dbbu_finish },
|
||||
|
||||
// {"__tostring", dbbu_tostring },
|
||||
{"__gc", dbbu_gc },
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_Reg sqlitelib[] = {
|
||||
{"lversion", lsqlite_lversion },
|
||||
{"version", lsqlite_version },
|
||||
{"complete", lsqlite_complete },
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
{"temp_directory", lsqlite_temp_directory },
|
||||
#endif
|
||||
{"open", lsqlite_open },
|
||||
{"open_memory", lsqlite_open_memory },
|
||||
{"open_ptr", lsqlite_open_ptr },
|
||||
|
||||
{"backup_init", lsqlite_backup_init },
|
||||
|
||||
{"__newindex", lsqlite_newindex },
|
||||
{NULL, NULL}
|
||||
@ -2137,6 +2380,7 @@ static void create_meta(lua_State *L, const char *name, const luaL_Reg *lib) {
|
||||
LUALIB_API int luaopen_lsqlite3(lua_State *L) {
|
||||
create_meta(L, sqlite_meta, dblib);
|
||||
create_meta(L, sqlite_vm_meta, vmlib);
|
||||
create_meta(L, sqlite_bu_meta, dbbulib);
|
||||
create_meta(L, sqlite_ctx_meta, ctxlib);
|
||||
|
||||
luaL_getmetatable(L, sqlite_ctx_meta);
|
||||
@ -2150,7 +2394,7 @@ LUALIB_API int luaopen_lsqlite3(lua_State *L) {
|
||||
/* add constants to global table */
|
||||
while (sqlite_constants[i].name) {
|
||||
lua_pushstring(L, sqlite_constants[i].name);
|
||||
lua_pushnumber(L, sqlite_constants[i].value);
|
||||
lua_pushinteger(L, sqlite_constants[i].value);
|
||||
lua_rawset(L, -3);
|
||||
++i;
|
||||
}
|
||||
@ -2162,14 +2406,3 @@ LUALIB_API int luaopen_lsqlite3(lua_State *L) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user