diff --git a/Config.toml b/Config.toml index 93f6737..4509d1a 100644 --- a/Config.toml +++ b/Config.toml @@ -2,5 +2,5 @@ modules_dir = "./" [[module]] name = "sqlite3" - mem_pages_count = 100 + mem_pages_count = 1000 logger_enabled = true diff --git a/Dockerfile b/Dockerfile index f77add1..b07f0a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ RUN apt-get update \ git \ make -RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-10/wasi-sdk-10.0-linux.tar.gz | tar xz --strip-components=1 -C / +RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-11/wasi-sdk-11.0-linux.tar.gz | tar xz --strip-components=1 -C / VOLUME /code WORKDIR /code diff --git a/Makefile b/Makefile index 4873073..c74b97c 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ CC = /bin/clang SYSROOT = /share/wasi-sysroot TARGET_TRIPLE = wasm32-wasi CFLAGS = -nostartfiles -fvisibility=hidden +SDK = sdk/logger.h LDFLAGS = -Wl,--no-entry,--demangle,--allow-undefined EXPORT_FUNCS = \ --export=allocate,$\ @@ -11,7 +12,32 @@ EXPORT_FUNCS = \ --export=set_result_ptr,$\ --export=get_result_size,$\ --export=get_result_ptr,$\ - --export=invoke + --export=sqlite3_open_v2_,$\ + --export=sqlite3_close,$\ + --export=sqlite3_prepare_v2_,$\ + --export=sqlite3_exec_,$\ + --export=sqlite3_libversion_number,$\ + --export=sqlite3_total_changes,$\ + --export=sqlite3_changes,$\ + --export=sqlite3_busy_timeout,$\ + --export=sqlite3_errmsg_,$\ + --export=sqlite3_errcode,$\ + --export=sqlite3_column_type,$\ + --export=sqlite3_column_name_,$\ + --export=sqlite3_step,$\ + --export=sqlite3_reset,$\ + --export=sqlite3_bind_blob_,$\ + --export=sqlite3_bind_double,$\ + --export=sqlite3_bind_int64,$\ + --export=sqlite3_bind_text_,$\ + --export=sqlite3_bind_null,$\ + --export=sqlite3_column_count,$\ + --export=sqlite3_column_double,$\ + --export=sqlite3_column_int64,$\ + --export=sqlite3_column_text_,$\ + --export=sqlite3_column_blob_,$\ + --export=sqlite3_column_bytes,$\ + --export=sqlite3_finalize SQLITE_SRC = \ src/alter.c\ src/analyze.c\ diff --git a/sqlite3.wit b/sqlite3.wit index a33884e..b67b983 100644 --- a/sqlite3.wit +++ b/sqlite3.wit @@ -1,43 +1,466 @@ ;; Fluence SQLite fork Wasm Interface Types -;; allocate -(@interface type (func (param $size: i32) (result i32))) ;; 0 +;; Types +(@interface type (func + (param $size: i32) + (result i32))) ;; 0 +(@interface type (func + (param $pointer: i32 $size: i32) )) ;; 1 +(@interface type (func + (result i32))) ;; 2 +(@interface type (func + (result i32))) ;; 3 +(@interface type (func + (param $result_size: i32) )) ;; 4 +(@interface type (func + (param $result_ptr: i32) )) ;; 5 +(@interface type (record $DBExecDescriptor ( + field $ret_code: s32 + field $err_msg: string +))) ;; 6 +(@interface type (record $DBPrepareDescriptor ( + field $ret_code: s32 + field $stmt_handle: u32 + field $tail: u32 +))) ;; 7 +(@interface type (record $DBOpenDescriptor ( + field $ret_code: s32 + field $db_handle: u32 +))) ;; 8 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result string))) ;; 9 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result string))) ;; 10 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s32))) ;; 11 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s32))) ;; 12 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 13 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 14 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $value: f64) + (result s32))) ;; 15 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $value: f64) + (result s32))) ;; 16 +(@interface type (func + (param $filename: string $flags: s32 $vfs: string) + )) ;; 17 +(@interface type (func + (param $filename: string $flags: s32 $vfs: string) + )) ;; 18 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 19 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 20 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 21 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 22 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s64))) ;; 23 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s64))) ;; 24 +(@interface type (func + (param $db: u32) + (result s32))) ;; 25 +(@interface type (func + (param $db: u32) + (result s32))) ;; 26 +(@interface type (func + (param $stmt_handle: u32 $icol: s32) + (result f64))) ;; 27 +(@interface type (func + (param $stmt_handle: u32 $icol: s32) + (result f64))) ;; 28 +(@interface type (func + (param $db_handle: u32 $ms: u32) + (result s32))) ;; 29 +(@interface type (func + (param $db_handle: u32 $ms: u32) + (result s32))) ;; 30 +(@interface type (func + (param $db_handle: u32) + (result string))) ;; 31 +(@interface type (func + (param $db_handle: u32) + (result string))) ;; 32 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $value: s64) + (result s32))) ;; 33 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $value: s64) + (result s32))) ;; 34 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 35 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 36 +(@interface type (func + (param $db_handle: u32 $sql: string) + )) ;; 37 +(@interface type (func + (param $db_handle: u32 $sql: string) + )) ;; 38 +(@interface type (func + (param $stmt_handle: u32 $pos: s32) + (result s32))) ;; 39 +(@interface type (func + (param $stmt_handle: u32 $pos: s32) + (result s32))) ;; 40 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 41 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 42 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $blob: byte_array $xDel: s32) + (result s32))) ;; 43 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $blob: byte_array $xDel: s32) + (result s32))) ;; 44 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 45 +(@interface type (func + (param $db_handle: u32) + (result s32))) ;; 46 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32) + (result s32))) ;; 47 +(@interface type (func + (param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32) + (result s32))) ;; 48 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 49 +(@interface type (func + (param $stmt_handle: u32) + (result s32))) ;; 50 +(@interface type (func + (param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32) + )) ;; 51 +(@interface type (func + (param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32) + )) ;; 52 +(@interface type (func + (result s32))) ;; 53 +(@interface type (func + (result s32))) ;; 54 +(@interface type (func + (param $stmt_handle: u32 $icol: s32) + (result byte_array))) ;; 55 +(@interface type (func + (param $stmt_handle: u32 $icol: s32) + (result byte_array))) ;; 56 +(@interface type (func + (param $stmt_handle: u32 $N: u32) + (result string))) ;; 57 +(@interface type (func + (param $stmt_handle: u32 $N: u32) + (result string))) ;; 58 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s32))) ;; 59 +(@interface type (func + (param $stmt_handle: u32 $icol: u32) + (result s32))) ;; 60 -;; deallocate -(@interface type (func (param $pointer: i32 $size: i32))) ;; 1 -;; invoke -(@interface type (func (param $request: string) (result string))) ;; 2 -;; get_result_ptr/get_result_size -(@interface type (func (result i32))) ;; 3 +;; Adapters +(@interface func (type 9) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 6 + call-core 3 + call-core 2 + string.lift_memory + call-core 3 + call-core 2 + call-core 1) +(@interface func (type 11) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 7 + s32.from_i32) +(@interface func (type 13) + arg.get 0 + i32.from_u32 + call-core 8 + s32.from_i32) +(@interface func (type 15) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + arg.get 2 + call-core 9 + s32.from_i32) +(@interface func (type 17) + arg.get 0 + string.size + call-core 0 + arg.get 0 + string.lower_memory + arg.get 1 + i32.from_s32 + arg.get 2 + string.size + call-core 0 + arg.get 2 + string.lower_memory + call-core 10 + call-core 3 + record.lift_memory 8) +(@interface func (type 19) + arg.get 0 + i32.from_u32 + call-core 11 + s32.from_i32) +(@interface func (type 21) + arg.get 0 + i32.from_u32 + call-core 12 + s32.from_i32) +(@interface func (type 23) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 13 + s64.from_i64) +(@interface func (type 25) + arg.get 0 + i32.from_u32 + call-core 14 + s32.from_i32) +(@interface func (type 27) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + call-core 15) +(@interface func (type 29) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 16 + s32.from_i32) +(@interface func (type 31) + arg.get 0 + i32.from_u32 + call-core 17 + call-core 3 + call-core 2 + string.lift_memory + call-core 3 + call-core 2 + call-core 1) +(@interface func (type 33) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + arg.get 2 + i64.from_s64 + call-core 18 + s32.from_i32) +(@interface func (type 35) + arg.get 0 + i32.from_u32 + call-core 19 + s32.from_i32) +(@interface func (type 37) + arg.get 0 + i32.from_u32 + arg.get 1 + string.size + call-core 0 + arg.get 1 + string.lower_memory + call-core 20 + call-core 3 + record.lift_memory 7) +(@interface func (type 39) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + call-core 21 + s32.from_i32) +(@interface func (type 41) + arg.get 0 + i32.from_u32 + call-core 22 + s32.from_i32) +(@interface func (type 43) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + arg.get 2 + byte_array.size + call-core 0 + arg.get 2 + byte_array.lower_memory + arg.get 3 + i32.from_s32 + call-core 23 + s32.from_i32) +(@interface func (type 45) + arg.get 0 + i32.from_u32 + call-core 24 + s32.from_i32) +(@interface func (type 47) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + arg.get 2 + string.size + call-core 0 + arg.get 2 + string.lower_memory + arg.get 3 + i32.from_s32 + call-core 25 + s32.from_i32) +(@interface func (type 49) + arg.get 0 + i32.from_u32 + call-core 26 + s32.from_i32) +(@interface func (type 51) + arg.get 0 + i32.from_u32 + arg.get 1 + string.size + call-core 0 + arg.get 1 + string.lower_memory + arg.get 2 + i32.from_s32 + arg.get 3 + i32.from_s32 + call-core 27 + call-core 3 + record.lift_memory 6) +(@interface func (type 53) + call-core 28 + s32.from_i32) +(@interface func (type 55) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_s32 + call-core 29 + call-core 3 + call-core 2 + byte_array.lift_memory + call-core 3 + call-core 2 + call-core 1) +(@interface func (type 57) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 30 + call-core 3 + call-core 2 + string.lift_memory + call-core 3 + call-core 2 + call-core 1) +(@interface func (type 59) + arg.get 0 + i32.from_u32 + arg.get 1 + i32.from_u32 + call-core 31 + s32.from_i32) -;; set_result_ptr/set_result_size -(@interface type (func (param $result: i32))) ;; 4 - -(@interface export "allocate" (func 0)) ;; 0 -(@interface export "deallocate" (func 1)) ;; 1 -(@interface export "invoke" (func 2)) ;; 2 -(@interface export "get_result_size" (func 3)) ;; 3 -(@interface export "get_result_ptr" (func 3)) ;; 4 -(@interface export "set_result_size" (func 4)) ;; 5 -(@interface export "set_result_ptr" (func 4)) ;; 6 - -;; adapter for export invoke function -(@interface func (type 2) - arg.get 0 - string.size - call-core 0 ;; call allocate - arg.get 0 - string.lower_memory - call-core 2 ;; call invoke - call-core 4 ;; call get_result_size - call-core 3 ;; call get_result_ptr - string.lift_memory - call-core 4 ;; call get_result_size - call-core 3 ;; call get_result_ptr - call-core 1 ;; call deallocate -) +;; Exports +(@interface export "allocate" (func 0)) +(@interface export "deallocate" (func 1)) +(@interface export "get_result_size" (func 2)) +(@interface export "get_result_ptr" (func 3)) +(@interface export "set_result_size" (func 4)) +(@interface export "set_result_ptr" (func 5)) +(@interface export "sqlite3_column_text" (func 10)) +(@interface export "sqlite3_column_bytes" (func 12)) +(@interface export "sqlite3_close" (func 14)) +(@interface export "sqlite3_bind_double" (func 16)) +(@interface export "sqlite3_open_v2" (func 18)) +(@interface export "sqlite3_changes" (func 20)) +(@interface export "sqlite3_step" (func 22)) +(@interface export "sqlite3_column_int64" (func 24)) +(@interface export "sqlite3_errcode" (func 26)) +(@interface export "sqlite3_column_double" (func 28)) +(@interface export "sqlite3_busy_timeout" (func 30)) +(@interface export "sqlite3_errmsg" (func 32)) +(@interface export "sqlite3_bind_int64" (func 34)) +(@interface export "sqlite3_finalize" (func 36)) +(@interface export "sqlite3_prepare_v2" (func 38)) +(@interface export "sqlite3_bind_null" (func 40)) +(@interface export "sqlite3_column_count" (func 42)) +(@interface export "sqlite3_bind_blob" (func 44)) +(@interface export "sqlite3_total_changes" (func 46)) +(@interface export "sqlite3_bind_text" (func 48)) +(@interface export "sqlite3_reset" (func 50)) +(@interface export "sqlite3_exec" (func 52)) +(@interface export "sqlite3_libversion_number" (func 54)) +(@interface export "sqlite3_column_blob" (func 56)) +(@interface export "sqlite3_column_name" (func 58)) +(@interface export "sqlite3_column_type" (func 60)) ;; Implementations -(@interface implement (func 2) (func 2)) +(@interface implement (func 10) (func 9)) +(@interface implement (func 12) (func 11)) +(@interface implement (func 14) (func 13)) +(@interface implement (func 16) (func 15)) +(@interface implement (func 18) (func 17)) +(@interface implement (func 20) (func 19)) +(@interface implement (func 22) (func 21)) +(@interface implement (func 24) (func 23)) +(@interface implement (func 26) (func 25)) +(@interface implement (func 28) (func 27)) +(@interface implement (func 30) (func 29)) +(@interface implement (func 32) (func 31)) +(@interface implement (func 34) (func 33)) +(@interface implement (func 36) (func 35)) +(@interface implement (func 38) (func 37)) +(@interface implement (func 40) (func 39)) +(@interface implement (func 42) (func 41)) +(@interface implement (func 44) (func 43)) +(@interface implement (func 46) (func 45)) +(@interface implement (func 48) (func 47)) +(@interface implement (func 50) (func 49)) +(@interface implement (func 52) (func 51)) +(@interface implement (func 54) (func 53)) +(@interface implement (func 56) (func 55)) +(@interface implement (func 58) (func 57)) +(@interface implement (func 60) (func 59)) diff --git a/src/legacy.c b/src/legacy.c index 867587e..790571d 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -16,6 +16,7 @@ */ #include "sqliteInt.h" +#include /* ** Execute SQL code. Return one of the SQLITE_ success/failure @@ -27,6 +28,33 @@ ** argument to xCallback(). If xCallback=NULL then no callback ** is invoked, even for queries. */ +void sqlite3_exec_( + sqlite3 *db, /* The database on which the SQL executes */ + char *zSql, /* The SQL to be executed */ + int zSql_len, + sqlite3_callback xCallback, /* Invoke this callback routine */ + void *pArg /* First argument to xCallback() */ +) __EXPORT_NAME(sqlite3_exec) { + char *new_zSql = (char *) malloc(zSql_len + 1); + memcpy(new_zSql, zSql, zSql_len); + new_zSql[zSql_len] = 0; + free((void *)zSql); + + char *pzErrMsg = 0; + const int ret_code = sqlite3_exec(db, new_zSql, xCallback, pArg, &pzErrMsg); + + free(new_zSql); + int *result = malloc(3*8); + result[0] = ret_code; + result[1] = 0; + result[2] = (int) pzErrMsg; + result[3] = 0; + result[4] = strlen(pzErrMsg); + result[5] = 0; + + set_result_ptr((char *)result); +} + int sqlite3_exec( sqlite3 *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ diff --git a/src/main.c b/src/main.c index f5c4e34..2e1b4f3 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,9 @@ */ #include "sqliteInt.h" +extern char *RESULT_PTR; +extern int RESULT_SIZE; + #ifdef SQLITE_ENABLE_FTS3 # include "fts3.h" #endif @@ -2450,6 +2453,13 @@ int sqlite3TempInMemory(const sqlite3 *db){ ** Return UTF-8 encoded English language explanation of the most recent ** error. */ +void sqlite3_errmsg_(sqlite3 *db) __EXPORT_NAME(sqlite3_errmsg) { + const char *result = sqlite3_errmsg(db); + + set_result_ptr((char *)result); + set_result_size(strlen(result)); +} + const char *sqlite3_errmsg(sqlite3 *db){ const char *z; if( !db ){ @@ -3428,15 +3438,50 @@ int sqlite3_open( return openDatabase(zFilename, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); } + +void sqlite3_open_v2_( + const char *filename, /* Database filename (UTF-8) */ + int filename_len, + int flags, /* Flags */ + const char *zVfs, /* Name of VFS module to use */ + int zVfs_len +) __EXPORT_NAME(sqlite3_open_v2) { + char *new_filename = (char *)malloc(filename_len + 1); + memcpy(new_filename, filename, filename_len); + new_filename[filename_len] = '\x00'; + free((void *)filename); + + char *new_zVfs = 0; + if (zVfs_len != 0) { + char *new_zVfs = (char *) malloc(zVfs_len + 1); + memcpy(new_zVfs, zVfs, zVfs_len); + new_zVfs[zVfs_len] = '\x00'; + free((void *) zVfs); + } + + sqlite3 *ppDb; + + const int ret_code = sqlite3_open_v2(new_filename, &ppDb, (unsigned int)flags, new_zVfs); + free(new_filename); + free(new_zVfs); + + int *result = (int *)malloc(16); + result[0] = ret_code; + result[2] = (int)ppDb; + + set_result_ptr((char *)result); +} + int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ -){ +) { return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); } + #ifndef SQLITE_OMIT_UTF16 /* ** Open a new database handle. diff --git a/src/prepare.c b/src/prepare.c index 2d928f1..74d915f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -782,6 +782,27 @@ int sqlite3_prepare( assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } + +void sqlite3_prepare_v2_( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes /* Length of zSql in bytes. */ +) __EXPORT_NAME(sqlite3_prepare_v2) { + sqlite3_stmt *ppStmt; + const char *pzTail; + + const int ret_code = sqlite3_prepare_v2(db, zSql, nBytes, &ppStmt, &pzTail); + free(zSql); + + int *result = (int *)malloc(3*8); + result[0] = ret_code; + result[2] = (int)ppStmt; + result[4] = (int)pzTail; + result[5] = strlen(pzTail); + + set_result_ptr((char *)result); +} + int sqlite3_prepare_v2( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ diff --git a/src/sqlite3.h b/src/sqlite3.h index cef6eea..80780cb 100644 --- a/src/sqlite3.h +++ b/src/sqlite3.h @@ -34,6 +34,12 @@ #define SQLITE3_H #include /* Needed for the definition of va_list */ +#define __EXPORT_NAME(name) \ + __attribute__((export_name(#name))) + +void set_result_ptr(const char *ptr); +void set_result_size(int size); + /* ** Make sure we can call this stuff from C++. */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 074d458..4509c8f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1108,6 +1108,15 @@ static void columnMallocFailure(sqlite3_stmt *pStmt) ** The following routines are used to access elements of the current row ** in the result set. */ + +void sqlite3_column_blob_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_blob) { + const char *result = sqlite3_column_blob(pStmt, i); + int blob_len = sqlite3_column_bytes(pStmt, i); + + set_result_ptr((char *)result); + set_result_size(blob_len); +} + const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ const void *val; val = sqlite3_value_blob( columnMem(pStmt,i) ); @@ -1143,6 +1152,14 @@ sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ columnMallocFailure(pStmt); return val; } + +void sqlite3_column_text_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_text) { + const unsigned char *result = sqlite3_column_text(pStmt, i); + + set_result_ptr((char *)result); + set_result_size(strlen(result)); +} + const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); @@ -1235,6 +1252,13 @@ static const void *columnName( ** Return the name of the Nth column of the result set returned by SQL ** statement pStmt. */ +void sqlite3_column_name_(sqlite3_stmt *pStmt, int N) __EXPORT_NAME(sqlite3_column_name) { + const char *result = sqlite3_column_name(pStmt, N); + + set_result_ptr((char *)result); + set_result_size(strlen(result)); +} + const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_NAME); } @@ -1407,6 +1431,21 @@ static int bindText( /* ** Bind a blob value to an SQL statement variable. */ + +int sqlite3_bind_blob_( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +) __EXPORT_NAME(sqlite3_bind_blob) { + + const int result = sqlite3_bind_blob(pStmt, i, zData, nData, xDel); + free((void *)zData); + + return result; +} + int sqlite3_bind_blob( sqlite3_stmt *pStmt, int i, @@ -1483,7 +1522,21 @@ int sqlite3_bind_pointer( } return rc; } -int sqlite3_bind_text( + +int sqlite3_bind_text_( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, + void (*xDel)(void*) +) __EXPORT_NAME(sqlite3_bind_text) { + const int result = sqlite3_bind_text(pStmt, i, zData, nData, xDel); + free((char *)zData); + + return result; +} + +int sqlite3_bind_text( sqlite3_stmt *pStmt, int i, const char *zData, diff --git a/src/wrapper.c b/src/wrapper.c index c2d9a26..cc38a47 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -1,22 +1,10 @@ #include -#include "../sdk/logger.h" #include "sqliteInt.h" sqlite3 *state; -char *RESULT_PTR; +const char *RESULT_PTR; int RESULT_SIZE; -int init() { - const int rc = sqlite3_initialize(); - if(rc != 0) { - return rc; - } - - return sqlite3_open(":memory:", &state); -} - -int g_isInited = 0; - void* allocate(size_t size) { return malloc(size + 1); } @@ -25,7 +13,7 @@ void deallocate(void *ptr, int size) { free(ptr); } -void set_result_ptr(char *ptr) { +void set_result_ptr(const char *ptr) { RESULT_PTR = ptr; } @@ -37,120 +25,7 @@ int get_result_size(void) { return RESULT_SIZE; } -char *get_result_ptr() { +const char *get_result_ptr() { return RESULT_PTR; } -typedef struct ShellText ShellText; -struct ShellText { - char *z; - int n; - int nAlloc; -}; - -static void initText(ShellText *p){ - memset(p, 0, sizeof(*p)); -} - -static void freeText(ShellText *p){ - free(p->z); - initText(p); -} - -static int strlen30(const char *z){ - const char *z2 = z; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - -static void appendText(ShellText *p, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen30(zAppend); - - len = nAppend+p->n+1; - if( quote ){ - len += 2; - for(i=0; in+len>=p->nAlloc ){ - p->nAlloc = p->nAlloc*2 + len + 20; - p->z = realloc(p->z, p->nAlloc); - // TODO: more solid work with OOM - if( p->z==0 ) __builtin_unreachable(); - } - - if( quote ){ - char *zCsr = p->z+p->n; - *zCsr++ = quote; - for(i=0; in = (int)(zCsr - p->z); - *zCsr = '\0'; - }else{ - memcpy(p->z+p->n, zAppend, nAppend); - p->n += nAppend; - p->z[p->n] = '\0'; - } -} - -static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ - ShellText *p = (ShellText*)pArg; - int i; - UNUSED_PARAMETER(az); - if( azArg==0 ) return 0; - if( p->n ) appendText(p, "|", 0); - for(i=0; i