mirror of
https://github.com/fluencelabs/sqlite
synced 2025-07-03 01:31:37 +00:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
19d85ba7a5 | |||
e7c772cfb6 | |||
807d6ff47d | |||
5b9324916d | |||
71080d772d | |||
f3a435616a | |||
b07df8ab66 | |||
f23126d37e | |||
107372813c | |||
932bfb38a1 | |||
2150b81cf6 | |||
0820036f56 | |||
af0ac14818 | |||
38fb596f7c | |||
15384f3ab1 | |||
c6e4a30f40 | |||
5660a45c22 | |||
1765640d12 | |||
cb62ab800e | |||
4179ccd6f9 | |||
df5cbd0b0f |
@ -4,10 +4,13 @@ RUN apt-get update \
|
|||||||
&& apt-get install -y ca-certificates \
|
&& apt-get install -y ca-certificates \
|
||||||
curl \
|
curl \
|
||||||
git \
|
git \
|
||||||
make
|
make \
|
||||||
|
cargo
|
||||||
|
|
||||||
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 /
|
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 /
|
||||||
|
|
||||||
|
RUN cargo install fcli --version 0.1.12
|
||||||
|
|
||||||
VOLUME /code
|
VOLUME /code
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
CMD make
|
CMD make
|
||||||
|
18
Makefile
18
Makefile
@ -2,12 +2,12 @@ TARGET = sqlite3
|
|||||||
CC = /bin/clang
|
CC = /bin/clang
|
||||||
SYSROOT = /share/wasi-sysroot
|
SYSROOT = /share/wasi-sysroot
|
||||||
TARGET_TRIPLE = wasm32-wasi
|
TARGET_TRIPLE = wasm32-wasi
|
||||||
CFLAGS = -nostartfiles -fvisibility=hidden
|
CFLAGS = -fvisibility=hidden
|
||||||
SDK = sdk/logger.h
|
SDK = sdk/logger.h
|
||||||
LDFLAGS = -Wl,--no-entry,--demangle,--allow-undefined
|
LDFLAGS = -Wl,--demangle,--allow-undefined
|
||||||
EXPORT_FUNCS = \
|
EXPORT_FUNCS = \
|
||||||
--export=allocate,$\
|
--export=allocate,$\
|
||||||
--export=deallocate,$\
|
--export=release_objects,$\
|
||||||
--export=set_result_size,$\
|
--export=set_result_size,$\
|
||||||
--export=set_result_ptr,$\
|
--export=set_result_ptr,$\
|
||||||
--export=get_result_size,$\
|
--export=get_result_size,$\
|
||||||
@ -26,15 +26,14 @@ EXPORT_FUNCS = \
|
|||||||
--export=sqlite3_column_name_,$\
|
--export=sqlite3_column_name_,$\
|
||||||
--export=sqlite3_step,$\
|
--export=sqlite3_step,$\
|
||||||
--export=sqlite3_reset,$\
|
--export=sqlite3_reset,$\
|
||||||
--export=sqlite3_bind_blob_,$\
|
--export=sqlite3_bind_blob,$\
|
||||||
--export=sqlite3_bind_double,$\
|
--export=sqlite3_bind_double,$\
|
||||||
--export=sqlite3_bind_int64,$\
|
--export=sqlite3_bind_int64,$\
|
||||||
--export=sqlite3_bind_text_,$\
|
--export=sqlite3_bind_text,$\
|
||||||
--export=sqlite3_bind_null,$\
|
--export=sqlite3_bind_null,$\
|
||||||
--export=sqlite3_column_count,$\
|
--export=sqlite3_column_count,$\
|
||||||
--export=sqlite3_column_double,$\
|
--export=sqlite3_column_double,$\
|
||||||
--export=sqlite3_column_int64,$\
|
--export=sqlite3_column_int64,$\
|
||||||
--export=sqlite3_column_text_,$\
|
|
||||||
--export=sqlite3_column_blob_,$\
|
--export=sqlite3_column_blob_,$\
|
||||||
--export=sqlite3_column_bytes,$\
|
--export=sqlite3_column_bytes,$\
|
||||||
--export=sqlite3_finalize
|
--export=sqlite3_finalize
|
||||||
@ -52,6 +51,8 @@ SQLITE_SRC = \
|
|||||||
src/complete.c\
|
src/complete.c\
|
||||||
src/ctime.c\
|
src/ctime.c\
|
||||||
src/date.c\
|
src/date.c\
|
||||||
|
src/demo_os.c\
|
||||||
|
src/demo_vfs.c\
|
||||||
src/dbpage.c\
|
src/dbpage.c\
|
||||||
src/dbstat.c\
|
src/dbstat.c\
|
||||||
src/delete.c\
|
src/delete.c\
|
||||||
@ -136,6 +137,7 @@ SQLITE_FLAGS = \
|
|||||||
-DENABLE_LOG\
|
-DENABLE_LOG\
|
||||||
-DBUILD_sqlite\
|
-DBUILD_sqlite\
|
||||||
-DNDEBUG\
|
-DNDEBUG\
|
||||||
|
-DSQLITE_OS_UNIX\
|
||||||
-DSQLITE_THREADSAFE=0\
|
-DSQLITE_THREADSAFE=0\
|
||||||
-DHAVE_READLINE=0\
|
-DHAVE_READLINE=0\
|
||||||
-DHAVE_EDITLINE=0\
|
-DHAVE_EDITLINE=0\
|
||||||
@ -151,7 +153,8 @@ SQLITE_FLAGS = \
|
|||||||
-DSQLITE_ENABLE_OFFSET_SQL_FUNC\
|
-DSQLITE_ENABLE_OFFSET_SQL_FUNC\
|
||||||
-DSQLITE_ENABLE_DESERIALIZE\
|
-DSQLITE_ENABLE_DESERIALIZE\
|
||||||
-DSQLITE_INTROSPECTION_PRAGMAS\
|
-DSQLITE_INTROSPECTION_PRAGMAS\
|
||||||
-DSQLITE_OMIT_POPEN
|
-DSQLITE_OMIT_POPEN\
|
||||||
|
-DCVECTOR_LOGARITHMIC_GROWTH
|
||||||
|
|
||||||
.PHONY: default all clean
|
.PHONY: default all clean
|
||||||
|
|
||||||
@ -160,6 +163,7 @@ all: default
|
|||||||
|
|
||||||
$(TARGET): $(SQLITE_SRC) $(WRAPPER_SRC)
|
$(TARGET): $(SQLITE_SRC) $(WRAPPER_SRC)
|
||||||
$(CC) -O3 --sysroot=$(SYSROOT) --target=$(TARGET_TRIPLE) $(SQLITE_FLAGS) $(CFLAGS) $(LDFLAGS) -Wl,$(EXPORT_FUNCS) $^ -o $@.wasm
|
$(CC) -O3 --sysroot=$(SYSROOT) --target=$(TARGET_TRIPLE) $(SQLITE_FLAGS) $(CFLAGS) $(LDFLAGS) -Wl,$(EXPORT_FUNCS) $^ -o $@.wasm
|
||||||
|
# /root/.cargo/bin/fce embed_it -i sqlite3.wasm -w sqlite3.wit
|
||||||
|
|
||||||
.PRECIOUS: $(TARGET)
|
.PRECIOUS: $(TARGET)
|
||||||
|
|
||||||
|
197
cvector/cvector.h
Normal file
197
cvector/cvector.h
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
#ifndef CVECTOR_H_
|
||||||
|
#define CVECTOR_H_
|
||||||
|
|
||||||
|
#include <assert.h> /* for assert */
|
||||||
|
#include <stdlib.h> /* for malloc/realloc/free */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_vector_type - The vector type used in this library
|
||||||
|
*/
|
||||||
|
#define cvector_vector_type(type) type *
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_set_capacity - For internal use, sets the capacity variable of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param size - the new capacity to set
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_set_capacity(vec, size) \
|
||||||
|
do { \
|
||||||
|
if (vec) { \
|
||||||
|
((size_t *)(vec))[-1] = (size); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_set_size - For internal use, sets the size variable of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param size - the new capacity to set
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_set_size(vec, size) \
|
||||||
|
do { \
|
||||||
|
if (vec) { \
|
||||||
|
((size_t *)(vec))[-2] = (size); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_capacity - gets the current capacity of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return the capacity as a size_t
|
||||||
|
*/
|
||||||
|
#define cvector_capacity(vec) \
|
||||||
|
((vec) ? ((size_t *)(vec))[-1] : (size_t)0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_size - gets the current size of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return the size as a size_t
|
||||||
|
*/
|
||||||
|
#define cvector_size(vec) \
|
||||||
|
((vec) ? ((size_t *)(vec))[-2] : (size_t)0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_empty - returns non-zero if the vector is empty
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return non-zero if empty, zero if non-empty
|
||||||
|
*/
|
||||||
|
#define cvector_empty(vec) \
|
||||||
|
(cvector_size(vec) == 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_grow - For internal use, ensures that the vector is at least <count> elements big
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param count - the new capacity to set
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_grow(vec, count) \
|
||||||
|
do { \
|
||||||
|
const size_t cv_sz = (count) * sizeof(*(vec)) + (sizeof(size_t) * 2); \
|
||||||
|
if (!(vec)) { \
|
||||||
|
size_t *cv_p = malloc(cv_sz); \
|
||||||
|
assert(cv_p); \
|
||||||
|
(vec) = (void *)(&cv_p[2]); \
|
||||||
|
cvector_set_capacity((vec), (count)); \
|
||||||
|
cvector_set_size((vec), 0); \
|
||||||
|
} else { \
|
||||||
|
size_t *cv_p1 = &((size_t *)(vec))[-2]; \
|
||||||
|
size_t *cv_p2 = realloc(cv_p1, (cv_sz)); \
|
||||||
|
assert(cv_p2); \
|
||||||
|
(vec) = (void *)(&cv_p2[2]); \
|
||||||
|
cvector_set_capacity((vec), (count)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_pop_back - removes the last element from the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_pop_back(vec) \
|
||||||
|
do { \
|
||||||
|
cvector_set_size((vec), cvector_size(vec) - 1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_erase - removes the element at index i from the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param i - index of element to remove
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_erase(vec, i) \
|
||||||
|
do { \
|
||||||
|
if (vec) { \
|
||||||
|
const size_t cv_sz = cvector_size(vec); \
|
||||||
|
if ((i) < cv_sz) { \
|
||||||
|
cvector_set_size((vec), cv_sz - 1); \
|
||||||
|
size_t cv_x; \
|
||||||
|
for (cv_x = (i); cv_x < (cv_sz - 1); ++cv_x) { \
|
||||||
|
(vec)[cv_x] = (vec)[cv_x + 1]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_free - frees all memory associated with the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_free(vec) \
|
||||||
|
do { \
|
||||||
|
if (vec) { \
|
||||||
|
size_t *p1 = &((size_t *)(vec))[-2]; \
|
||||||
|
free(p1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_begin - returns an iterator to first element of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return a pointer to the first element (or NULL)
|
||||||
|
*/
|
||||||
|
#define cvector_begin(vec) \
|
||||||
|
(vec)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_end - returns an iterator to one past the last element of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @return a pointer to one past the last element (or NULL)
|
||||||
|
*/
|
||||||
|
#define cvector_end(vec) \
|
||||||
|
((vec) ? &((vec)[cvector_size(vec)]) : NULL)
|
||||||
|
|
||||||
|
/* user request to use logarithmic growth algorithm */
|
||||||
|
#ifdef CVECTOR_LOGARITHMIC_GROWTH
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_push_back - adds an element to the end of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param value - the value to add
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_push_back(vec, value) \
|
||||||
|
do { \
|
||||||
|
size_t cv_cap = cvector_capacity(vec); \
|
||||||
|
if (cv_cap <= cvector_size(vec)) { \
|
||||||
|
cvector_grow((vec), !cv_cap ? cv_cap + 1 : cv_cap * 2); \
|
||||||
|
} \
|
||||||
|
vec[cvector_size(vec)] = (value); \
|
||||||
|
cvector_set_size((vec), cvector_size(vec) + 1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_push_back - adds an element to the end of the vector
|
||||||
|
* @param vec - the vector
|
||||||
|
* @param value - the value to add
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_push_back(vec, value) \
|
||||||
|
do { \
|
||||||
|
size_t cv_cap = cvector_capacity(vec); \
|
||||||
|
if (cv_cap <= cvector_size(vec)) { \
|
||||||
|
cvector_grow((vec), cv_cap + 1); \
|
||||||
|
} \
|
||||||
|
vec[cvector_size(vec)] = (value); \
|
||||||
|
cvector_set_size((vec), cvector_size(vec) + 1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* CVECTOR_LOGARITHMIC_GROWTH */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cvector_copy - copy a vector
|
||||||
|
* @param from - the original vector
|
||||||
|
* @param to - destination to which the function copy to
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
#define cvector_copy(from, to) \
|
||||||
|
do { \
|
||||||
|
for(size_t i = 0; i < cvector_size(from); i++) { \
|
||||||
|
cvector_push_back(to, from[i]); \
|
||||||
|
} \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
|
#endif /* CVECTOR_H_ */
|
330
sqlite3.wit
330
sqlite3.wit
@ -1,11 +1,10 @@
|
|||||||
;; Fluence SQLite fork Wasm Interface Types
|
(@interface it_version "0.20.0")
|
||||||
|
|
||||||
;; Types
|
;; Types
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $size: i32)
|
(param $size: i32)
|
||||||
(result i32))) ;; 0
|
(result i32))) ;; 0
|
||||||
(@interface type (func
|
(@interface type (func )) ;; 1
|
||||||
(param $pointer: i32 $size: i32) )) ;; 1
|
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(result i32))) ;; 2
|
(result i32))) ;; 2
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
@ -27,165 +26,179 @@
|
|||||||
field $ret_code: s32
|
field $ret_code: s32
|
||||||
field $db_handle: u32
|
field $db_handle: u32
|
||||||
))) ;; 8
|
))) ;; 8
|
||||||
|
(@interface type (record $SecurityTetraplet (
|
||||||
|
field $peer_pk: string
|
||||||
|
field $service_id: string
|
||||||
|
field $function_name: string
|
||||||
|
field $json_path: string
|
||||||
|
))) ;; 9
|
||||||
|
(@interface type (record $CallParameters (
|
||||||
|
field $init_peer_id: string
|
||||||
|
field $service_id: string
|
||||||
|
field $service_creator_peer_id: string
|
||||||
|
field $host_id: string
|
||||||
|
field $particle_id: string
|
||||||
|
field $tetraplets: array (array (record 9))
|
||||||
|
))) ;; 10
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
(result string))) ;; 9
|
(result string))) ;; 11
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
(result string))) ;; 10
|
(result string))) ;; 12
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(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
|
(result s32))) ;; 13
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32)
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
(result s32))) ;; 14
|
(result s32))) ;; 14
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $value: f64)
|
(param $db_handle: u32)
|
||||||
(result s32))) ;; 15
|
(result s32))) ;; 15
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $value: f64)
|
(param $db_handle: u32)
|
||||||
(result s32))) ;; 16
|
(result s32))) ;; 16
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $filename: string $flags: s32 $vfs: string)
|
(param $stmt_handle: u32 $pos: s32 $value: f64)
|
||||||
)) ;; 17
|
(result s32))) ;; 17
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $pos: s32 $value: f64)
|
||||||
|
(result s32))) ;; 18
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $filename: string $flags: s32 $vfs: string)
|
(param $filename: string $flags: s32 $vfs: string)
|
||||||
)) ;; 18
|
(result record 8))) ;; 19
|
||||||
|
(@interface type (func
|
||||||
|
(param $filename: string $flags: s32 $vfs: string)
|
||||||
|
(result record 8))) ;; 20
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32)
|
(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
|
(result s32))) ;; 21
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $db_handle: u32)
|
||||||
(result s32))) ;; 22
|
(result s32))) ;; 22
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(param $stmt_handle: u32)
|
||||||
(result s64))) ;; 23
|
(result s32))) ;; 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
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32)
|
||||||
|
(result s32))) ;; 24
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
|
(result s64))) ;; 25
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
|
(result s64))) ;; 26
|
||||||
|
(@interface type (func
|
||||||
|
(param $db: u32)
|
||||||
|
(result s32))) ;; 27
|
||||||
|
(@interface type (func
|
||||||
|
(param $db: u32)
|
||||||
|
(result s32))) ;; 28
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $icol: s32)
|
||||||
|
(result f64))) ;; 29
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $icol: s32)
|
||||||
|
(result f64))) ;; 30
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32 $ms: u32)
|
||||||
|
(result s32))) ;; 31
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32 $ms: u32)
|
||||||
|
(result s32))) ;; 32
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32)
|
||||||
|
(result string))) ;; 33
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32)
|
||||||
|
(result string))) ;; 34
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $pos: s32 $value: s64)
|
||||||
(result s32))) ;; 35
|
(result s32))) ;; 35
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32 $pos: s32 $value: s64)
|
||||||
(result s32))) ;; 36
|
(result s32))) ;; 36
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32 $sql: string)
|
(param $stmt_handle: u32)
|
||||||
)) ;; 37
|
(result s32))) ;; 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
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32)
|
||||||
|
(result s32))) ;; 38
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32 $sql: string)
|
||||||
|
(result record 7))) ;; 39
|
||||||
|
(@interface type (func
|
||||||
|
(param $db_handle: u32 $sql: string)
|
||||||
|
(result record 7))) ;; 40
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32 $pos: s32)
|
||||||
(result s32))) ;; 41
|
(result s32))) ;; 41
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32 $pos: s32)
|
||||||
(result s32))) ;; 42
|
(result s32))) ;; 42
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $blob: byte_array $xDel: s32)
|
(param $stmt_handle: u32)
|
||||||
(result s32))) ;; 43
|
(result s32))) ;; 43
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $blob: byte_array $xDel: s32)
|
(param $stmt_handle: u32)
|
||||||
(result s32))) ;; 44
|
(result s32))) ;; 44
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32)
|
(param $stmt_handle: u32 $pos: s32 $blob: array (u8) $xDel: s32)
|
||||||
(result s32))) ;; 45
|
(result s32))) ;; 45
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32)
|
(param $stmt_handle: u32 $pos: s32 $blob: array (u8) $xDel: s32)
|
||||||
(result s32))) ;; 46
|
(result s32))) ;; 46
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32)
|
(param $db_handle: u32)
|
||||||
(result s32))) ;; 47
|
(result s32))) ;; 47
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32)
|
(param $db_handle: u32)
|
||||||
(result s32))) ;; 48
|
(result s32))) ;; 48
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32)
|
||||||
(result s32))) ;; 49
|
(result s32))) ;; 49
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32)
|
(param $stmt_handle: u32 $pos: s32 $text: string $xDel: s32)
|
||||||
(result s32))) ;; 50
|
(result s32))) ;; 50
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32)
|
(param $stmt_handle: u32)
|
||||||
)) ;; 51
|
(result s32))) ;; 51
|
||||||
|
(@interface type (func
|
||||||
|
(param $stmt_handle: u32)
|
||||||
|
(result s32))) ;; 52
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32)
|
(param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32)
|
||||||
)) ;; 52
|
(result record 6))) ;; 53
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(result s32))) ;; 53
|
(param $db_handle: u32 $sql: string $callback_id: s32 $callback_arg: s32)
|
||||||
|
(result record 6))) ;; 54
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(result s32))) ;; 54
|
(result s32))) ;; 55
|
||||||
|
(@interface type (func
|
||||||
|
(result s32))) ;; 56
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: s32)
|
(param $stmt_handle: u32 $icol: s32)
|
||||||
(result byte_array))) ;; 55
|
(result array (u8)))) ;; 57
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: s32)
|
(param $stmt_handle: u32 $icol: s32)
|
||||||
(result byte_array))) ;; 56
|
(result array (u8)))) ;; 58
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $N: u32)
|
(param $stmt_handle: u32 $N: u32)
|
||||||
(result string))) ;; 57
|
(result string))) ;; 59
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $N: u32)
|
(param $stmt_handle: u32 $N: u32)
|
||||||
(result string))) ;; 58
|
(result string))) ;; 60
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
(result s32))) ;; 59
|
(result s32))) ;; 61
|
||||||
(@interface type (func
|
(@interface type (func
|
||||||
(param $stmt_handle: u32 $icol: u32)
|
(param $stmt_handle: u32 $icol: u32)
|
||||||
(result s32))) ;; 60
|
(result s32))) ;; 62
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; Adapters
|
;; Adapters
|
||||||
(@interface func (type 9)
|
(@interface func (type 11)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -194,22 +207,20 @@
|
|||||||
call-core 3
|
call-core 3
|
||||||
call-core 2
|
call-core 2
|
||||||
string.lift_memory
|
string.lift_memory
|
||||||
call-core 3
|
|
||||||
call-core 2
|
|
||||||
call-core 1)
|
call-core 1)
|
||||||
(@interface func (type 11)
|
(@interface func (type 13)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 7
|
call-core 7
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 13)
|
(@interface func (type 15)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 8
|
call-core 8
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 15)
|
(@interface func (type 17)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -217,9 +228,10 @@
|
|||||||
arg.get 2
|
arg.get 2
|
||||||
call-core 9
|
call-core 9
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 17)
|
(@interface func (type 19)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
string.size
|
string.size
|
||||||
|
i32.push 1
|
||||||
call-core 0
|
call-core 0
|
||||||
arg.get 0
|
arg.get 0
|
||||||
string.lower_memory
|
string.lower_memory
|
||||||
@ -227,58 +239,58 @@
|
|||||||
i32.from_s32
|
i32.from_s32
|
||||||
arg.get 2
|
arg.get 2
|
||||||
string.size
|
string.size
|
||||||
|
i32.push 1
|
||||||
call-core 0
|
call-core 0
|
||||||
arg.get 2
|
arg.get 2
|
||||||
string.lower_memory
|
string.lower_memory
|
||||||
call-core 10
|
call-core 10
|
||||||
call-core 3
|
call-core 3
|
||||||
record.lift_memory 8)
|
record.lift_memory 8
|
||||||
(@interface func (type 19)
|
call-core 1)
|
||||||
|
(@interface func (type 21)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 11
|
call-core 11
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 21)
|
(@interface func (type 23)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 12
|
call-core 12
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 23)
|
(@interface func (type 25)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 13
|
call-core 13
|
||||||
s64.from_i64)
|
s64.from_i64)
|
||||||
(@interface func (type 25)
|
(@interface func (type 27)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 14
|
call-core 14
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 27)
|
(@interface func (type 29)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_s32
|
i32.from_s32
|
||||||
call-core 15)
|
call-core 15)
|
||||||
(@interface func (type 29)
|
(@interface func (type 31)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 16
|
call-core 16
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 31)
|
(@interface func (type 33)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 17
|
call-core 17
|
||||||
call-core 3
|
call-core 3
|
||||||
call-core 2
|
call-core 2
|
||||||
string.lift_memory
|
string.lift_memory
|
||||||
call-core 3
|
|
||||||
call-core 2
|
|
||||||
call-core 1)
|
call-core 1)
|
||||||
(@interface func (type 33)
|
(@interface func (type 35)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -287,60 +299,60 @@
|
|||||||
i64.from_s64
|
i64.from_s64
|
||||||
call-core 18
|
call-core 18
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 35)
|
(@interface func (type 37)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 19
|
call-core 19
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 37)
|
(@interface func (type 39)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
string.size
|
string.size
|
||||||
|
i32.push 1
|
||||||
call-core 0
|
call-core 0
|
||||||
arg.get 1
|
arg.get 1
|
||||||
string.lower_memory
|
string.lower_memory
|
||||||
call-core 20
|
call-core 20
|
||||||
call-core 3
|
call-core 3
|
||||||
record.lift_memory 7)
|
record.lift_memory 7
|
||||||
(@interface func (type 39)
|
call-core 1)
|
||||||
|
(@interface func (type 41)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_s32
|
i32.from_s32
|
||||||
call-core 21
|
call-core 21
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 41)
|
(@interface func (type 43)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 22
|
call-core 22
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 43)
|
(@interface func (type 45)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_s32
|
i32.from_s32
|
||||||
arg.get 2
|
arg.get 2
|
||||||
byte_array.size
|
array.lower_memory u8
|
||||||
call-core 0
|
|
||||||
arg.get 2
|
|
||||||
byte_array.lower_memory
|
|
||||||
arg.get 3
|
arg.get 3
|
||||||
i32.from_s32
|
i32.from_s32
|
||||||
call-core 23
|
call-core 23
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 45)
|
(@interface func (type 47)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 24
|
call-core 24
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 47)
|
(@interface func (type 49)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
i32.from_s32
|
i32.from_s32
|
||||||
arg.get 2
|
arg.get 2
|
||||||
string.size
|
string.size
|
||||||
|
i32.push 1
|
||||||
call-core 0
|
call-core 0
|
||||||
arg.get 2
|
arg.get 2
|
||||||
string.lower_memory
|
string.lower_memory
|
||||||
@ -348,16 +360,17 @@
|
|||||||
i32.from_s32
|
i32.from_s32
|
||||||
call-core 25
|
call-core 25
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 49)
|
(@interface func (type 51)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
call-core 26
|
call-core 26
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 51)
|
(@interface func (type 53)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
string.size
|
string.size
|
||||||
|
i32.push 1
|
||||||
call-core 0
|
call-core 0
|
||||||
arg.get 1
|
arg.get 1
|
||||||
string.lower_memory
|
string.lower_memory
|
||||||
@ -367,11 +380,12 @@
|
|||||||
i32.from_s32
|
i32.from_s32
|
||||||
call-core 27
|
call-core 27
|
||||||
call-core 3
|
call-core 3
|
||||||
record.lift_memory 6)
|
record.lift_memory 6
|
||||||
(@interface func (type 53)
|
call-core 1)
|
||||||
|
(@interface func (type 55)
|
||||||
call-core 28
|
call-core 28
|
||||||
s32.from_i32)
|
s32.from_i32)
|
||||||
(@interface func (type 55)
|
(@interface func (type 57)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -380,10 +394,8 @@
|
|||||||
call-core 3
|
call-core 3
|
||||||
call-core 2
|
call-core 2
|
||||||
byte_array.lift_memory
|
byte_array.lift_memory
|
||||||
call-core 3
|
|
||||||
call-core 2
|
|
||||||
call-core 1)
|
call-core 1)
|
||||||
(@interface func (type 57)
|
(@interface func (type 59)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -392,10 +404,8 @@
|
|||||||
call-core 3
|
call-core 3
|
||||||
call-core 2
|
call-core 2
|
||||||
string.lift_memory
|
string.lift_memory
|
||||||
call-core 3
|
|
||||||
call-core 2
|
|
||||||
call-core 1)
|
call-core 1)
|
||||||
(@interface func (type 59)
|
(@interface func (type 61)
|
||||||
arg.get 0
|
arg.get 0
|
||||||
i32.from_u32
|
i32.from_u32
|
||||||
arg.get 1
|
arg.get 1
|
||||||
@ -405,40 +415,39 @@
|
|||||||
|
|
||||||
;; Exports
|
;; Exports
|
||||||
(@interface export "allocate" (func 0))
|
(@interface export "allocate" (func 0))
|
||||||
(@interface export "deallocate" (func 1))
|
(@interface export "release_objects" (func 1))
|
||||||
(@interface export "get_result_size" (func 2))
|
(@interface export "get_result_size" (func 2))
|
||||||
(@interface export "get_result_ptr" (func 3))
|
(@interface export "get_result_ptr" (func 3))
|
||||||
(@interface export "set_result_size" (func 4))
|
(@interface export "set_result_size" (func 4))
|
||||||
(@interface export "set_result_ptr" (func 5))
|
(@interface export "set_result_ptr" (func 5))
|
||||||
(@interface export "sqlite3_column_text" (func 10))
|
(@interface export "sqlite3_column_text" (func 12))
|
||||||
(@interface export "sqlite3_column_bytes" (func 12))
|
(@interface export "sqlite3_column_bytes" (func 14))
|
||||||
(@interface export "sqlite3_close" (func 14))
|
(@interface export "sqlite3_close" (func 16))
|
||||||
(@interface export "sqlite3_bind_double" (func 16))
|
(@interface export "sqlite3_bind_double" (func 18))
|
||||||
(@interface export "sqlite3_open_v2" (func 18))
|
(@interface export "sqlite3_open_v2" (func 20))
|
||||||
(@interface export "sqlite3_changes" (func 20))
|
(@interface export "sqlite3_changes" (func 22))
|
||||||
(@interface export "sqlite3_step" (func 22))
|
(@interface export "sqlite3_step" (func 24))
|
||||||
(@interface export "sqlite3_column_int64" (func 24))
|
(@interface export "sqlite3_column_int64" (func 26))
|
||||||
(@interface export "sqlite3_errcode" (func 26))
|
(@interface export "sqlite3_errcode" (func 28))
|
||||||
(@interface export "sqlite3_column_double" (func 28))
|
(@interface export "sqlite3_column_double" (func 30))
|
||||||
(@interface export "sqlite3_busy_timeout" (func 30))
|
(@interface export "sqlite3_busy_timeout" (func 32))
|
||||||
(@interface export "sqlite3_errmsg" (func 32))
|
(@interface export "sqlite3_errmsg" (func 34))
|
||||||
(@interface export "sqlite3_bind_int64" (func 34))
|
(@interface export "sqlite3_bind_int64" (func 36))
|
||||||
(@interface export "sqlite3_finalize" (func 36))
|
(@interface export "sqlite3_finalize" (func 38))
|
||||||
(@interface export "sqlite3_prepare_v2" (func 38))
|
(@interface export "sqlite3_prepare_v2" (func 40))
|
||||||
(@interface export "sqlite3_bind_null" (func 40))
|
(@interface export "sqlite3_bind_null" (func 42))
|
||||||
(@interface export "sqlite3_column_count" (func 42))
|
(@interface export "sqlite3_column_count" (func 44))
|
||||||
(@interface export "sqlite3_bind_blob" (func 44))
|
(@interface export "sqlite3_bind_blob" (func 46))
|
||||||
(@interface export "sqlite3_total_changes" (func 46))
|
(@interface export "sqlite3_total_changes" (func 48))
|
||||||
(@interface export "sqlite3_bind_text" (func 48))
|
(@interface export "sqlite3_bind_text" (func 50))
|
||||||
(@interface export "sqlite3_reset" (func 50))
|
(@interface export "sqlite3_reset" (func 52))
|
||||||
(@interface export "sqlite3_exec" (func 52))
|
(@interface export "sqlite3_exec" (func 54))
|
||||||
(@interface export "sqlite3_libversion_number" (func 54))
|
(@interface export "sqlite3_libversion_number" (func 56))
|
||||||
(@interface export "sqlite3_column_blob" (func 56))
|
(@interface export "sqlite3_column_blob" (func 58))
|
||||||
(@interface export "sqlite3_column_name" (func 58))
|
(@interface export "sqlite3_column_name" (func 60))
|
||||||
(@interface export "sqlite3_column_type" (func 60))
|
(@interface export "sqlite3_column_type" (func 62))
|
||||||
|
|
||||||
;; Implementations
|
;; Implementations
|
||||||
(@interface implement (func 10) (func 9))
|
|
||||||
(@interface implement (func 12) (func 11))
|
(@interface implement (func 12) (func 11))
|
||||||
(@interface implement (func 14) (func 13))
|
(@interface implement (func 14) (func 13))
|
||||||
(@interface implement (func 16) (func 15))
|
(@interface implement (func 16) (func 15))
|
||||||
@ -464,3 +473,4 @@
|
|||||||
(@interface implement (func 56) (func 55))
|
(@interface implement (func 56) (func 55))
|
||||||
(@interface implement (func 58) (func 57))
|
(@interface implement (func 58) (func 57))
|
||||||
(@interface implement (func 60) (func 59))
|
(@interface implement (func 60) (func 59))
|
||||||
|
(@interface implement (func 62) (func 61))
|
||||||
|
12
src/demo_os.c
Normal file
12
src/demo_os.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
|
extern sqlite3_vfs *sqlite3_demovfs(void);
|
||||||
|
|
||||||
|
int sqlite3_os_init() {
|
||||||
|
sqlite3_vfs_register(sqlite3_demovfs(), 0);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sqlite3_os_end() {
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
679
src/demo_vfs.c
Normal file
679
src/demo_vfs.c
Normal file
@ -0,0 +1,679 @@
|
|||||||
|
/*
|
||||||
|
** 2010 April 7
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
** a legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** May you do good and not evil.
|
||||||
|
** May you find forgiveness for yourself and forgive others.
|
||||||
|
** May you share freely, never taking more than you give.
|
||||||
|
**
|
||||||
|
*************************************************************************
|
||||||
|
**
|
||||||
|
** This file implements an example of a simple VFS implementation that
|
||||||
|
** omits complex features often not required or not possible on embedded
|
||||||
|
** platforms. Code is included to buffer writes to the journal file,
|
||||||
|
** which can be a significant performance improvement on some embedded
|
||||||
|
** platforms.
|
||||||
|
**
|
||||||
|
** OVERVIEW
|
||||||
|
**
|
||||||
|
** The code in this file implements a minimal SQLite VFS that can be
|
||||||
|
** used on Linux and other posix-like operating systems. The following
|
||||||
|
** system calls are used:
|
||||||
|
**
|
||||||
|
** File-system: access(), unlink(), getcwd()
|
||||||
|
** File IO: open(), read(), write(), fsync(), close(), fstat()
|
||||||
|
** Other: sleep(), usleep(), time()
|
||||||
|
**
|
||||||
|
** The following VFS features are omitted:
|
||||||
|
**
|
||||||
|
** 1. File locking. The user must ensure that there is at most one
|
||||||
|
** connection to each database when using this VFS. Multiple
|
||||||
|
** connections to a single shared-cache count as a single connection
|
||||||
|
** for the purposes of the previous statement.
|
||||||
|
**
|
||||||
|
** 2. The loading of dynamic extensions (shared libraries).
|
||||||
|
**
|
||||||
|
** 3. Temporary files. The user must configure SQLite to use in-memory
|
||||||
|
** temp files when using this VFS. The easiest way to do this is to
|
||||||
|
** compile with:
|
||||||
|
**
|
||||||
|
** -DSQLITE_TEMP_STORE=3
|
||||||
|
**
|
||||||
|
** 4. File truncation. As of version 3.6.24, SQLite may run without
|
||||||
|
** a working xTruncate() call, providing the user does not configure
|
||||||
|
** SQLite to use "journal_mode=truncate", or use both
|
||||||
|
** "journal_mode=persist" and ATTACHed databases.
|
||||||
|
**
|
||||||
|
** It is assumed that the system uses UNIX-like path-names. Specifically,
|
||||||
|
** that '/' characters are used to separate path components and that
|
||||||
|
** a path-name is a relative path unless it begins with a '/'. And that
|
||||||
|
** no UTF-8 encoded paths are greater than 512 bytes in length.
|
||||||
|
**
|
||||||
|
** JOURNAL WRITE-BUFFERING
|
||||||
|
**
|
||||||
|
** To commit a transaction to the database, SQLite first writes rollback
|
||||||
|
** information into the journal file. This usually consists of 4 steps:
|
||||||
|
**
|
||||||
|
** 1. The rollback information is sequentially written into the journal
|
||||||
|
** file, starting at the start of the file.
|
||||||
|
** 2. The journal file is synced to disk.
|
||||||
|
** 3. A modification is made to the first few bytes of the journal file.
|
||||||
|
** 4. The journal file is synced to disk again.
|
||||||
|
**
|
||||||
|
** Most of the data is written in step 1 using a series of calls to the
|
||||||
|
** VFS xWrite() method. The buffers passed to the xWrite() calls are of
|
||||||
|
** various sizes. For example, as of version 3.6.24, when committing a
|
||||||
|
** transaction that modifies 3 pages of a database file that uses 4096
|
||||||
|
** byte pages residing on a media with 512 byte sectors, SQLite makes
|
||||||
|
** eleven calls to the xWrite() method to create the rollback journal,
|
||||||
|
** as follows:
|
||||||
|
**
|
||||||
|
** Write offset | Bytes written
|
||||||
|
** ----------------------------
|
||||||
|
** 0 512
|
||||||
|
** 512 4
|
||||||
|
** 516 4096
|
||||||
|
** 4612 4
|
||||||
|
** 4616 4
|
||||||
|
** 4620 4096
|
||||||
|
** 8716 4
|
||||||
|
** 8720 4
|
||||||
|
** 8724 4096
|
||||||
|
** 12820 4
|
||||||
|
** ++++++++++++SYNC+++++++++++
|
||||||
|
** 0 12
|
||||||
|
** ++++++++++++SYNC+++++++++++
|
||||||
|
**
|
||||||
|
** On many operating systems, this is an efficient way to write to a file.
|
||||||
|
** However, on some embedded systems that do not cache writes in OS
|
||||||
|
** buffers it is much more efficient to write data in blocks that are
|
||||||
|
** an integer multiple of the sector-size in size and aligned at the
|
||||||
|
** start of a sector.
|
||||||
|
**
|
||||||
|
** To work around this, the code in this file allocates a fixed size
|
||||||
|
** buffer of SQLITE_DEMOVFS_BUFFERSZ using sqlite3_malloc() whenever a
|
||||||
|
** journal file is opened. It uses the buffer to coalesce sequential
|
||||||
|
** writes into aligned SQLITE_DEMOVFS_BUFFERSZ blocks. When SQLite
|
||||||
|
** invokes the xSync() method to sync the contents of the file to disk,
|
||||||
|
** all accumulated data is written out, even if it does not constitute
|
||||||
|
** a complete block. This means the actual IO to create the rollback
|
||||||
|
** journal for the example transaction above is this:
|
||||||
|
**
|
||||||
|
** Write offset | Bytes written
|
||||||
|
** ----------------------------
|
||||||
|
** 0 8192
|
||||||
|
** 8192 4632
|
||||||
|
** ++++++++++++SYNC+++++++++++
|
||||||
|
** 0 12
|
||||||
|
** ++++++++++++SYNC+++++++++++
|
||||||
|
**
|
||||||
|
** Much more efficient if the underlying OS is not caching write
|
||||||
|
** operations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
|
||||||
|
|
||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Size of the write buffer used by journal files in bytes.
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_DEMOVFS_BUFFERSZ
|
||||||
|
# define SQLITE_DEMOVFS_BUFFERSZ 8192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The maximum pathname length supported by this VFS.
|
||||||
|
*/
|
||||||
|
#define MAXPATHNAME 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
** When using this VFS, the sqlite3_file* handles that SQLite uses are
|
||||||
|
** actually pointers to instances of type DemoFile.
|
||||||
|
*/
|
||||||
|
typedef struct DemoFile DemoFile;
|
||||||
|
struct DemoFile {
|
||||||
|
sqlite3_file base; /* Base class. Must be first. */
|
||||||
|
int fd; /* File descriptor */
|
||||||
|
|
||||||
|
char *aBuffer; /* Pointer to malloc'd buffer */
|
||||||
|
int nBuffer; /* Valid bytes of data in zBuffer */
|
||||||
|
sqlite3_int64 iBufferOfst; /* Offset in file of zBuffer[0] */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write directly to the file passed as the first argument. Even if the
|
||||||
|
** file has a write-buffer (DemoFile.aBuffer), ignore it.
|
||||||
|
*/
|
||||||
|
static int demoDirectWrite(
|
||||||
|
DemoFile *p, /* File handle */
|
||||||
|
const void *zBuf, /* Buffer containing data to write */
|
||||||
|
int iAmt, /* Size of data to write in bytes */
|
||||||
|
sqlite_int64 iOfst /* File offset to write to */
|
||||||
|
){
|
||||||
|
off_t ofst; /* Return value from lseek() */
|
||||||
|
size_t nWrite; /* Return value from write() */
|
||||||
|
|
||||||
|
ofst = lseek(p->fd, iOfst, SEEK_SET);
|
||||||
|
if( ofst!=iOfst ){
|
||||||
|
return SQLITE_IOERR_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nWrite = write(p->fd, zBuf, iAmt);
|
||||||
|
if( nWrite!=iAmt ){
|
||||||
|
return SQLITE_IOERR_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Flush the contents of the DemoFile.aBuffer buffer to disk. This is a
|
||||||
|
** no-op if this particular file does not have a buffer (i.e. it is not
|
||||||
|
** a journal file) or if the buffer is currently empty.
|
||||||
|
*/
|
||||||
|
static int demoFlushBuffer(DemoFile *p){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
if( p->nBuffer ){
|
||||||
|
rc = demoDirectWrite(p, p->aBuffer, p->nBuffer, p->iBufferOfst);
|
||||||
|
p->nBuffer = 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Close a file.
|
||||||
|
*/
|
||||||
|
static int demoClose(sqlite3_file *pFile){
|
||||||
|
int rc;
|
||||||
|
DemoFile *p = (DemoFile*)pFile;
|
||||||
|
rc = demoFlushBuffer(p);
|
||||||
|
sqlite3_free(p->aBuffer);
|
||||||
|
close(p->fd);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Read data from a file.
|
||||||
|
*/
|
||||||
|
static int demoRead(
|
||||||
|
sqlite3_file *pFile,
|
||||||
|
void *zBuf,
|
||||||
|
int iAmt,
|
||||||
|
sqlite_int64 iOfst
|
||||||
|
){
|
||||||
|
DemoFile *p = (DemoFile*)pFile;
|
||||||
|
off_t ofst; /* Return value from lseek() */
|
||||||
|
int nRead; /* Return value from read() */
|
||||||
|
int rc; /* Return code from demoFlushBuffer() */
|
||||||
|
|
||||||
|
/* Flush any data in the write buffer to disk in case this operation
|
||||||
|
** is trying to read data the file-region currently cached in the buffer.
|
||||||
|
** It would be possible to detect this case and possibly save an
|
||||||
|
** unnecessary write here, but in practice SQLite will rarely read from
|
||||||
|
** a journal file when there is data cached in the write-buffer.
|
||||||
|
*/
|
||||||
|
rc = demoFlushBuffer(p);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofst = lseek(p->fd, iOfst, SEEK_SET);
|
||||||
|
if( ofst!=iOfst ){
|
||||||
|
return SQLITE_IOERR_READ;
|
||||||
|
}
|
||||||
|
nRead = read(p->fd, zBuf, iAmt);
|
||||||
|
|
||||||
|
if( nRead==iAmt ){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}else if( nRead>=0 ){
|
||||||
|
return SQLITE_IOERR_SHORT_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQLITE_IOERR_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write data to a crash-file.
|
||||||
|
*/
|
||||||
|
static int demoWrite(
|
||||||
|
sqlite3_file *pFile,
|
||||||
|
const void *zBuf,
|
||||||
|
int iAmt,
|
||||||
|
sqlite_int64 iOfst
|
||||||
|
){
|
||||||
|
DemoFile *p = (DemoFile*)pFile;
|
||||||
|
|
||||||
|
if( p->aBuffer ){
|
||||||
|
char *z = (char *)zBuf; /* Pointer to remaining data to write */
|
||||||
|
int n = iAmt; /* Number of bytes at z */
|
||||||
|
sqlite3_int64 i = iOfst; /* File offset to write to */
|
||||||
|
|
||||||
|
while( n>0 ){
|
||||||
|
int nCopy; /* Number of bytes to copy into buffer */
|
||||||
|
|
||||||
|
/* If the buffer is full, or if this data is not being written directly
|
||||||
|
** following the data already buffered, flush the buffer. Flushing
|
||||||
|
** the buffer is a no-op if it is empty.
|
||||||
|
*/
|
||||||
|
if( p->nBuffer==SQLITE_DEMOVFS_BUFFERSZ || p->iBufferOfst+p->nBuffer!=i ){
|
||||||
|
int rc = demoFlushBuffer(p);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert( p->nBuffer==0 || p->iBufferOfst+p->nBuffer==i );
|
||||||
|
p->iBufferOfst = i - p->nBuffer;
|
||||||
|
|
||||||
|
/* Copy as much data as possible into the buffer. */
|
||||||
|
nCopy = SQLITE_DEMOVFS_BUFFERSZ - p->nBuffer;
|
||||||
|
if( nCopy>n ){
|
||||||
|
nCopy = n;
|
||||||
|
}
|
||||||
|
memcpy(&p->aBuffer[p->nBuffer], z, nCopy);
|
||||||
|
p->nBuffer += nCopy;
|
||||||
|
|
||||||
|
n -= nCopy;
|
||||||
|
i += nCopy;
|
||||||
|
z += nCopy;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return demoDirectWrite(p, zBuf, iAmt, iOfst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Truncate a file. This is a no-op for this VFS (see header comments at
|
||||||
|
** the top of the file).
|
||||||
|
*/
|
||||||
|
static int demoTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||||
|
#if 0
|
||||||
|
if( ftruncate(((DemoFile *)pFile)->fd, size) ) return SQLITE_IOERR_TRUNCATE;
|
||||||
|
#endif
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Sync the contents of the file to the persistent media.
|
||||||
|
*/
|
||||||
|
static int demoSync(sqlite3_file *pFile, int flags){
|
||||||
|
DemoFile *p = (DemoFile*)pFile;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = demoFlushBuffer(p);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = fsync(p->fd);
|
||||||
|
return (rc==0 ? SQLITE_OK : SQLITE_IOERR_FSYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write the size of the file in bytes to *pSize.
|
||||||
|
*/
|
||||||
|
static int demoFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||||
|
DemoFile *p = (DemoFile*)pFile;
|
||||||
|
int rc; /* Return code from fstat() call */
|
||||||
|
struct stat sStat; /* Output of fstat() call */
|
||||||
|
|
||||||
|
/* Flush the contents of the buffer to disk. As with the flush in the
|
||||||
|
** demoRead() method, it would be possible to avoid this and save a write
|
||||||
|
** here and there. But in practice this comes up so infrequently it is
|
||||||
|
** not worth the trouble.
|
||||||
|
*/
|
||||||
|
rc = demoFlushBuffer(p);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = fstat(p->fd, &sStat);
|
||||||
|
if( rc!=0 ) return SQLITE_IOERR_FSTAT;
|
||||||
|
*pSize = sStat.st_size;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Locking functions. The xLock() and xUnlock() methods are both no-ops.
|
||||||
|
** The xCheckReservedLock() always indicates that no other process holds
|
||||||
|
** a reserved lock on the database file. This ensures that if a hot-journal
|
||||||
|
** file is found in the file-system it is rolled back.
|
||||||
|
*/
|
||||||
|
static int demoLock(sqlite3_file *pFile, int eLock){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
static int demoUnlock(sqlite3_file *pFile, int eLock){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
static int demoCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||||
|
*pResOut = 0;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** No xFileControl() verbs are implemented by this VFS.
|
||||||
|
*/
|
||||||
|
static int demoFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The xSectorSize() and xDeviceCharacteristics() methods. These two
|
||||||
|
** may return special values allowing SQLite to optimize file-system
|
||||||
|
** access to some extent. But it is also safe to simply return 0.
|
||||||
|
*/
|
||||||
|
static int demoSectorSize(sqlite3_file *pFile){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int demoDeviceCharacteristics(sqlite3_file *pFile){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Open a file handle.
|
||||||
|
*/
|
||||||
|
static int demoOpen(
|
||||||
|
sqlite3_vfs *pVfs, /* VFS */
|
||||||
|
const char *zName, /* File to open, or 0 for a temp file */
|
||||||
|
sqlite3_file *pFile, /* Pointer to DemoFile struct to populate */
|
||||||
|
int flags, /* Input SQLITE_OPEN_XXX flags */
|
||||||
|
int *pOutFlags /* Output SQLITE_OPEN_XXX flags (or NULL) */
|
||||||
|
){
|
||||||
|
static const sqlite3_io_methods demoio = {
|
||||||
|
1, /* iVersion */
|
||||||
|
demoClose, /* xClose */
|
||||||
|
demoRead, /* xRead */
|
||||||
|
demoWrite, /* xWrite */
|
||||||
|
demoTruncate, /* xTruncate */
|
||||||
|
demoSync, /* xSync */
|
||||||
|
demoFileSize, /* xFileSize */
|
||||||
|
demoLock, /* xLock */
|
||||||
|
demoUnlock, /* xUnlock */
|
||||||
|
demoCheckReservedLock, /* xCheckReservedLock */
|
||||||
|
demoFileControl, /* xFileControl */
|
||||||
|
demoSectorSize, /* xSectorSize */
|
||||||
|
demoDeviceCharacteristics /* xDeviceCharacteristics */
|
||||||
|
};
|
||||||
|
|
||||||
|
DemoFile *p = (DemoFile*)pFile; /* Populate this structure */
|
||||||
|
int oflags = 0; /* flags to pass to open() call */
|
||||||
|
char *aBuf = 0;
|
||||||
|
|
||||||
|
if( zName==0 ){
|
||||||
|
return SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
||||||
|
aBuf = (char *)sqlite3_malloc(SQLITE_DEMOVFS_BUFFERSZ);
|
||||||
|
if( !aBuf ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( flags&SQLITE_OPEN_EXCLUSIVE ) oflags |= O_EXCL;
|
||||||
|
if( flags&SQLITE_OPEN_CREATE ) oflags |= O_CREAT;
|
||||||
|
if( flags&SQLITE_OPEN_READONLY ) oflags |= O_RDONLY;
|
||||||
|
if( flags&SQLITE_OPEN_READWRITE ) oflags |= O_RDWR;
|
||||||
|
|
||||||
|
memset(p, 0, sizeof(DemoFile));
|
||||||
|
p->fd = open(zName, oflags, 0600);
|
||||||
|
if( p->fd<0 ){
|
||||||
|
sqlite3_free(aBuf);
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
p->aBuffer = aBuf;
|
||||||
|
|
||||||
|
if( pOutFlags ){
|
||||||
|
*pOutFlags = flags;
|
||||||
|
}
|
||||||
|
p->base.pMethods = &demoio;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete the file identified by argument zPath. If the dirSync parameter
|
||||||
|
** is non-zero, then ensure the file-system modification to delete the
|
||||||
|
** file has been synced to disk before returning.
|
||||||
|
*/
|
||||||
|
static int demoDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||||
|
int rc; /* Return code */
|
||||||
|
|
||||||
|
rc = unlink(zPath);
|
||||||
|
if( rc!=0 && errno==ENOENT ) return SQLITE_OK;
|
||||||
|
|
||||||
|
if( rc==0 && dirSync ){
|
||||||
|
int dfd; /* File descriptor open on directory */
|
||||||
|
int i; /* Iterator variable */
|
||||||
|
char zDir[MAXPATHNAME+1]; /* Name of directory containing file zPath */
|
||||||
|
|
||||||
|
/* Figure out the directory name from the path of the file deleted. */
|
||||||
|
sqlite3_snprintf(MAXPATHNAME, zDir, "%s", zPath);
|
||||||
|
zDir[MAXPATHNAME] = '\0';
|
||||||
|
for(i=strlen(zDir); i>1 && zDir[i]!='/'; i++);
|
||||||
|
zDir[i] = '\0';
|
||||||
|
|
||||||
|
/* Open a file-descriptor on the directory. Sync. Close. */
|
||||||
|
dfd = open(zDir, O_RDONLY, 0);
|
||||||
|
if( dfd<0 ){
|
||||||
|
rc = -1;
|
||||||
|
}else{
|
||||||
|
rc = fsync(dfd);
|
||||||
|
close(dfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (rc==0 ? SQLITE_OK : SQLITE_IOERR_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef F_OK
|
||||||
|
# define F_OK 0
|
||||||
|
#endif
|
||||||
|
#ifndef R_OK
|
||||||
|
# define R_OK 4
|
||||||
|
#endif
|
||||||
|
#ifndef W_OK
|
||||||
|
# define W_OK 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Query the file-system to see if the named file exists, is readable or
|
||||||
|
** is both readable and writable.
|
||||||
|
*/
|
||||||
|
static int demoAccess(
|
||||||
|
sqlite3_vfs *pVfs,
|
||||||
|
const char *zPath,
|
||||||
|
int flags,
|
||||||
|
int *pResOut
|
||||||
|
){
|
||||||
|
int rc; /* access() return code */
|
||||||
|
int eAccess = F_OK; /* Second argument to access() */
|
||||||
|
|
||||||
|
assert( flags==SQLITE_ACCESS_EXISTS /* access(zPath, F_OK) */
|
||||||
|
|| flags==SQLITE_ACCESS_READ /* access(zPath, R_OK) */
|
||||||
|
|| flags==SQLITE_ACCESS_READWRITE /* access(zPath, R_OK|W_OK) */
|
||||||
|
);
|
||||||
|
|
||||||
|
if( flags==SQLITE_ACCESS_READWRITE ) eAccess = R_OK|W_OK;
|
||||||
|
if( flags==SQLITE_ACCESS_READ ) eAccess = R_OK;
|
||||||
|
|
||||||
|
rc = access(zPath, eAccess);
|
||||||
|
*pResOut = (rc==0);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Argument zPath points to a nul-terminated string containing a file path.
|
||||||
|
** If zPath is an absolute path, then it is copied as is into the output
|
||||||
|
** buffer. Otherwise, if it is a relative path, then the equivalent full
|
||||||
|
** path is written to the output buffer.
|
||||||
|
**
|
||||||
|
** This function assumes that paths are UNIX style. Specifically, that:
|
||||||
|
**
|
||||||
|
** 1. Path components are separated by a '/'. and
|
||||||
|
** 2. Full paths begin with a '/' character.
|
||||||
|
*/
|
||||||
|
static int demoFullPathname(
|
||||||
|
sqlite3_vfs *pVfs, /* VFS */
|
||||||
|
const char *zPath, /* Input path (possibly a relative path) */
|
||||||
|
int nPathOut, /* Size of output buffer in bytes */
|
||||||
|
char *zPathOut /* Pointer to output buffer */
|
||||||
|
){
|
||||||
|
sqlite3_snprintf(nPathOut, zPathOut, "%s", zPath);
|
||||||
|
zPathOut[nPathOut-1] = '\0';
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following four VFS methods:
|
||||||
|
**
|
||||||
|
** xDlOpen
|
||||||
|
** xDlError
|
||||||
|
** xDlSym
|
||||||
|
** xDlClose
|
||||||
|
**
|
||||||
|
** are supposed to implement the functionality needed by SQLite to load
|
||||||
|
** extensions compiled as shared objects. This simple VFS does not support
|
||||||
|
** this functionality, so the following functions are no-ops.
|
||||||
|
*/
|
||||||
|
static void *demoDlOpen(sqlite3_vfs *pVfs, const char *zPath){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void demoDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
|
||||||
|
sqlite3_snprintf(nByte, zErrMsg, "Loadable extensions are not supported");
|
||||||
|
zErrMsg[nByte-1] = '\0';
|
||||||
|
}
|
||||||
|
static void (*demoDlSym(sqlite3_vfs *pVfs, void *pH, const char *z))(void){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void demoDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Parameter zByte points to a buffer nByte bytes in size. Populate this
|
||||||
|
** buffer with pseudo-random data.
|
||||||
|
*/
|
||||||
|
static int demoRandomness(sqlite3_vfs *pVfs, int nByte, char *zByte){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Sleep for at least nMicro microseconds. Return the (approximate) number
|
||||||
|
** of microseconds slept for.
|
||||||
|
*/
|
||||||
|
static int demoSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||||
|
sleep(nMicro / 1000000);
|
||||||
|
usleep(nMicro % 1000000);
|
||||||
|
return nMicro;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set *pTime to the current UTC time expressed as a Julian day. Return
|
||||||
|
** SQLITE_OK if successful, or an error code otherwise.
|
||||||
|
**
|
||||||
|
** http://en.wikipedia.org/wiki/Julian_day
|
||||||
|
**
|
||||||
|
** This implementation is not very good. The current time is rounded to
|
||||||
|
** an integer number of seconds. Also, assuming time_t is a signed 32-bit
|
||||||
|
** value, it will stop working some time in the year 2038 AD (the so-called
|
||||||
|
** "year 2038" problem that afflicts systems that store time this way).
|
||||||
|
*/
|
||||||
|
static int demoCurrentTime(sqlite3_vfs *pVfs, double *pTime){
|
||||||
|
time_t t = time(0);
|
||||||
|
*pTime = t/86400.0 + 2440587.5;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function returns a pointer to the VFS implemented in this file.
|
||||||
|
** To make the VFS available to SQLite:
|
||||||
|
**
|
||||||
|
** sqlite3_vfs_register(sqlite3_demovfs(), 0);
|
||||||
|
*/
|
||||||
|
sqlite3_vfs *sqlite3_demovfs(void){
|
||||||
|
static sqlite3_vfs demovfs = {
|
||||||
|
1, /* iVersion */
|
||||||
|
sizeof(DemoFile), /* szOsFile */
|
||||||
|
MAXPATHNAME, /* mxPathname */
|
||||||
|
0, /* pNext */
|
||||||
|
"demo", /* zName */
|
||||||
|
0, /* pAppData */
|
||||||
|
demoOpen, /* xOpen */
|
||||||
|
demoDelete, /* xDelete */
|
||||||
|
demoAccess, /* xAccess */
|
||||||
|
demoFullPathname, /* xFullPathname */
|
||||||
|
demoDlOpen, /* xDlOpen */
|
||||||
|
demoDlError, /* xDlError */
|
||||||
|
demoDlSym, /* xDlSym */
|
||||||
|
demoDlClose, /* xDlClose */
|
||||||
|
demoRandomness, /* xRandomness */
|
||||||
|
demoSleep, /* xSleep */
|
||||||
|
demoCurrentTime, /* xCurrentTime */
|
||||||
|
};
|
||||||
|
return &demovfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SQLITE_TEST
|
||||||
|
|
||||||
|
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||||
|
# include "sqlite_tcl.h"
|
||||||
|
#else
|
||||||
|
# include "tcl.h"
|
||||||
|
# ifndef SQLITE_TCLAPI
|
||||||
|
# define SQLITE_TCLAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SQLITE_OS_UNIX
|
||||||
|
static int SQLITE_TCLAPI register_demovfs(
|
||||||
|
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||||
|
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||||
|
int objc, /* Number of arguments */
|
||||||
|
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||||
|
){
|
||||||
|
sqlite3_vfs_register(sqlite3_demovfs(), 1);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
static int SQLITE_TCLAPI unregister_demovfs(
|
||||||
|
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||||
|
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||||
|
int objc, /* Number of arguments */
|
||||||
|
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||||
|
){
|
||||||
|
sqlite3_vfs_unregister(sqlite3_demovfs());
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Register commands with the TCL interpreter.
|
||||||
|
*/
|
||||||
|
int Sqlitetest_demovfs_Init(Tcl_Interp *interp){
|
||||||
|
Tcl_CreateObjCommand(interp, "register_demovfs", register_demovfs, 0, 0);
|
||||||
|
Tcl_CreateObjCommand(interp, "unregister_demovfs", unregister_demovfs, 0, 0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int Sqlitetest_demovfs_Init(Tcl_Interp *interp){ return TCL_OK; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SQLITE_TEST */
|
||||||
|
|
31
src/legacy.c
31
src/legacy.c
@ -28,32 +28,33 @@
|
|||||||
** argument to xCallback(). If xCallback=NULL then no callback
|
** argument to xCallback(). If xCallback=NULL then no callback
|
||||||
** is invoked, even for queries.
|
** is invoked, even for queries.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __sqlite_unmodified_upstream
|
||||||
void sqlite3_exec_(
|
void sqlite3_exec_(
|
||||||
sqlite3 *db, /* The database on which the SQL executes */
|
sqlite3 *db, /* The database on which the SQL executes */
|
||||||
char *zSql, /* The SQL to be executed */
|
char *zSql, /* The SQL to be executed */
|
||||||
int zSql_len,
|
int zSql_len,
|
||||||
sqlite3_callback xCallback, /* Invoke this callback routine */
|
sqlite3_callback xCallback, /* Invoke this callback routine */
|
||||||
void *pArg /* First argument to xCallback() */
|
void *pArg /* First argument to xCallback() */
|
||||||
) __EXPORT_NAME(sqlite3_exec) {
|
) __EXPORT_NAME(sqlite3_exec) {
|
||||||
char *new_zSql = (char *) malloc(zSql_len + 1);
|
zSql = handle_input_string(zSql, zSql_len);
|
||||||
memcpy(new_zSql, zSql, zSql_len);
|
|
||||||
new_zSql[zSql_len] = 0;
|
|
||||||
free((void *)zSql);
|
|
||||||
|
|
||||||
char *pzErrMsg = 0;
|
char *pzErrMsg = 0;
|
||||||
const int ret_code = sqlite3_exec(db, new_zSql, xCallback, pArg, &pzErrMsg);
|
const int ret_code = sqlite3_exec(db, zSql, xCallback, pArg, &pzErrMsg);
|
||||||
|
|
||||||
free(new_zSql);
|
// free the string passed from the IT side
|
||||||
int *result = malloc(3*8);
|
free(zSql);
|
||||||
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);
|
unsigned char *result = (unsigned char*)malloc(3*4);
|
||||||
|
write_le_int(result, 0, (unsigned int)ret_code);
|
||||||
|
write_le_int(result, 4, (unsigned int)pzErrMsg);
|
||||||
|
write_le_int(result, 8, (unsigned int)strlen(pzErrMsg));
|
||||||
|
|
||||||
|
// errmsg should be managed by user
|
||||||
|
add_object_to_release((void *) pzErrMsg);
|
||||||
|
add_object_to_release((void *) result);
|
||||||
|
set_result_ptr((void *) result);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int sqlite3_exec(
|
int sqlite3_exec(
|
||||||
sqlite3 *db, /* The database on which the SQL executes */
|
sqlite3 *db, /* The database on which the SQL executes */
|
||||||
|
736
src/main.c
736
src/main.c
File diff suppressed because it is too large
Load Diff
20
src/memdb.c
20
src/memdb.c
@ -17,10 +17,7 @@
|
|||||||
** sqlite3_deserialize().
|
** sqlite3_deserialize().
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#if __sqlite_unmodified_upstream
|
|
||||||
#else
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
|
||||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -426,15 +423,7 @@ static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
|||||||
** random data.
|
** random data.
|
||||||
*/
|
*/
|
||||||
static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
||||||
#if __sqlite_unmodified_upstream
|
|
||||||
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
|
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
|
||||||
#else
|
|
||||||
zBufOut = malloc(nByte);
|
|
||||||
for(int i = 0; i < nByte; ++i) {
|
|
||||||
zBufOut[i] = rand() % 256;
|
|
||||||
}
|
|
||||||
return SQLITE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -622,23 +611,14 @@ end_deserialize:
|
|||||||
** Register the new VFS.
|
** Register the new VFS.
|
||||||
*/
|
*/
|
||||||
int sqlite3MemdbInit(void){
|
int sqlite3MemdbInit(void){
|
||||||
#if __sqlite_unmodified_upstream
|
|
||||||
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
|
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
|
||||||
int sz = pLower->szOsFile;
|
int sz = pLower->szOsFile;
|
||||||
memdb_vfs.pAppData = pLower;
|
memdb_vfs.pAppData = pLower;
|
||||||
#else
|
|
||||||
memdb_vfs.pAppData = (void *)0xFFFFFFFF;
|
|
||||||
int sz = sizeof(MemFile);
|
|
||||||
#endif
|
|
||||||
/* In all known configurations of SQLite, the size of a default
|
/* In all known configurations of SQLite, the size of a default
|
||||||
** sqlite3_file is greater than the size of a memdb sqlite3_file.
|
** sqlite3_file is greater than the size of a memdb sqlite3_file.
|
||||||
** Should that ever change, remove the following NEVER() */
|
** Should that ever change, remove the following NEVER() */
|
||||||
if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
|
if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
|
||||||
memdb_vfs.szOsFile = sz;
|
memdb_vfs.szOsFile = sz;
|
||||||
#if __sqlite_unmodified_upstream
|
|
||||||
return sqlite3_vfs_register(&memdb_vfs, 0);
|
return sqlite3_vfs_register(&memdb_vfs, 0);
|
||||||
#else
|
|
||||||
return sqlite3_vfs_register(&memdb_vfs, 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_ENABLE_DESERIALIZE */
|
#endif /* SQLITE_ENABLE_DESERIALIZE */
|
||||||
|
@ -783,25 +783,30 @@ int sqlite3_prepare(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __sqlite_unmodified_upstream
|
||||||
void sqlite3_prepare_v2_(
|
void sqlite3_prepare_v2_(
|
||||||
sqlite3 *db, /* Database handle. */
|
sqlite3 *db, /* Database handle. */
|
||||||
const char *zSql, /* UTF-8 encoded SQL statement. */
|
const char *zSql, /* UTF-8 encoded SQL statement. */
|
||||||
int nBytes /* Length of zSql in bytes. */
|
int nBytes /* Length of zSql in bytes. */
|
||||||
) __EXPORT_NAME(sqlite3_prepare_v2) {
|
) __EXPORT_NAME(sqlite3_prepare_v2) {
|
||||||
sqlite3_stmt *ppStmt;
|
sqlite3_stmt *ppStmt = NULL;
|
||||||
const char *pzTail;
|
const char *pzTail = NULL;
|
||||||
|
|
||||||
const int ret_code = sqlite3_prepare_v2(db, zSql, nBytes, &ppStmt, &pzTail);
|
const int ret_code = sqlite3_prepare_v2(db, zSql, nBytes, &ppStmt, &pzTail);
|
||||||
free(zSql);
|
|
||||||
|
|
||||||
int *result = (int *)malloc(3*8);
|
// free the string passed from the IT side
|
||||||
result[0] = ret_code;
|
free((void *) zSql);
|
||||||
result[2] = (int)ppStmt;
|
|
||||||
result[4] = (int)pzTail;
|
|
||||||
result[5] = strlen(pzTail);
|
|
||||||
|
|
||||||
set_result_ptr((char *)result);
|
unsigned char *result = (unsigned char*)malloc(4 * 4);
|
||||||
|
write_le_int(result, 0, (unsigned int)ret_code);
|
||||||
|
write_le_int(result, 4, (unsigned int)ppStmt);
|
||||||
|
write_le_int(result, 8, (unsigned int)pzTail);
|
||||||
|
write_le_int(result, 12, (unsigned int)strlen(pzTail));
|
||||||
|
|
||||||
|
add_object_to_release((void *) result);
|
||||||
|
set_result_ptr((void *) result);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int sqlite3_prepare_v2(
|
int sqlite3_prepare_v2(
|
||||||
sqlite3 *db, /* Database handle. */
|
sqlite3 *db, /* Database handle. */
|
||||||
|
@ -37,9 +37,6 @@
|
|||||||
#define __EXPORT_NAME(name) \
|
#define __EXPORT_NAME(name) \
|
||||||
__attribute__((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++.
|
** Make sure we can call this stuff from C++.
|
||||||
*/
|
*/
|
||||||
|
@ -4908,4 +4908,14 @@ void sqlite3VectorErrorMsg(Parse*, Expr*);
|
|||||||
const char **sqlite3CompileOptions(int *pnOpt);
|
const char **sqlite3CompileOptions(int *pnOpt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __sqlite_unmodified_upstream
|
||||||
|
void add_object_to_release(void *object);
|
||||||
|
|
||||||
|
void set_result_ptr(void *ptr);
|
||||||
|
void set_result_size(int size);
|
||||||
|
|
||||||
|
char *handle_input_string(char *str, int len);
|
||||||
|
void write_le_int(unsigned char *array, unsigned int offset, unsigned int value);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SQLITEINT_H */
|
#endif /* SQLITEINT_H */
|
||||||
|
@ -1110,10 +1110,11 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void sqlite3_column_blob_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_blob) {
|
void sqlite3_column_blob_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_blob) {
|
||||||
const char *result = sqlite3_column_blob(pStmt, i);
|
const char *blob = sqlite3_column_blob(pStmt, i);
|
||||||
int blob_len = sqlite3_column_bytes(pStmt, i);
|
int blob_len = sqlite3_column_bytes(pStmt, i);
|
||||||
|
|
||||||
set_result_ptr((char *)result);
|
// blob is managed by SQLite itself
|
||||||
|
set_result_ptr((void *)blob);
|
||||||
set_result_size(blob_len);
|
set_result_size(blob_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,10 +1155,12 @@ sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sqlite3_column_text_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_text) {
|
void sqlite3_column_text_(sqlite3_stmt *pStmt, int i) __EXPORT_NAME(sqlite3_column_text) {
|
||||||
const unsigned char *result = sqlite3_column_text(pStmt, i);
|
const unsigned char *text = sqlite3_column_text(pStmt, i);
|
||||||
|
const unsigned int text_len = sqlite3_column_bytes(pStmt, i);
|
||||||
|
|
||||||
set_result_ptr((char *)result);
|
// test is managed by SQLite itself
|
||||||
set_result_size(strlen(result));
|
set_result_ptr((void *) text);
|
||||||
|
set_result_size(text_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
|
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
|
||||||
@ -1252,12 +1255,15 @@ static const void *columnName(
|
|||||||
** Return the name of the Nth column of the result set returned by SQL
|
** Return the name of the Nth column of the result set returned by SQL
|
||||||
** statement pStmt.
|
** statement pStmt.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __sqlite_unmodified_upstream
|
||||||
void sqlite3_column_name_(sqlite3_stmt *pStmt, int N) __EXPORT_NAME(sqlite3_column_name) {
|
void sqlite3_column_name_(sqlite3_stmt *pStmt, int N) __EXPORT_NAME(sqlite3_column_name) {
|
||||||
const char *result = sqlite3_column_name(pStmt, N);
|
const char *result = sqlite3_column_name(pStmt, N);
|
||||||
|
|
||||||
set_result_ptr((char *)result);
|
// result is managed by SQLite itself
|
||||||
|
set_result_ptr((void *)result);
|
||||||
set_result_size(strlen(result));
|
set_result_size(strlen(result));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
|
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
|
||||||
return columnName(pStmt, N, 0, COLNAME_NAME);
|
return columnName(pStmt, N, 0, COLNAME_NAME);
|
||||||
@ -1431,21 +1437,6 @@ static int bindText(
|
|||||||
/*
|
/*
|
||||||
** Bind a blob value to an SQL statement variable.
|
** 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(
|
int sqlite3_bind_blob(
|
||||||
sqlite3_stmt *pStmt,
|
sqlite3_stmt *pStmt,
|
||||||
int i,
|
int i,
|
||||||
@ -1456,7 +1447,13 @@ int sqlite3_bind_blob(
|
|||||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||||
if( nData<0 ) return SQLITE_MISUSE_BKPT;
|
if( nData<0 ) return SQLITE_MISUSE_BKPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __sqlite_unmodified_upstream
|
||||||
return bindText(pStmt, i, zData, nData, xDel, 0);
|
return bindText(pStmt, i, zData, nData, xDel, 0);
|
||||||
|
#else
|
||||||
|
// xDel is a custom deallocator, due to our IT architecture it can't be provided from other modules.
|
||||||
|
return bindText(pStmt, i, zData, nData, free, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
int sqlite3_bind_blob64(
|
int sqlite3_bind_blob64(
|
||||||
sqlite3_stmt *pStmt,
|
sqlite3_stmt *pStmt,
|
||||||
@ -1523,19 +1520,6 @@ int sqlite3_bind_pointer(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
int sqlite3_bind_text(
|
||||||
sqlite3_stmt *pStmt,
|
sqlite3_stmt *pStmt,
|
||||||
int i,
|
int i,
|
||||||
@ -1543,7 +1527,12 @@ int sqlite3_bind_text(
|
|||||||
int nData,
|
int nData,
|
||||||
void (*xDel)(void*)
|
void (*xDel)(void*)
|
||||||
){
|
){
|
||||||
|
#ifdef __sqlite_unmodified_upstream
|
||||||
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
|
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
|
||||||
|
#else
|
||||||
|
// xDel is a custom deallocator, due to our IT architecture it can't be provided from other modules.
|
||||||
|
return bindText(pStmt, i, zData, nData, free, SQLITE_UTF8);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
int sqlite3_bind_text64(
|
int sqlite3_bind_text64(
|
||||||
sqlite3_stmt *pStmt,
|
sqlite3_stmt *pStmt,
|
||||||
|
@ -1,19 +1,37 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
#include "../cvector/cvector.h"
|
||||||
|
|
||||||
sqlite3 *state;
|
#include <stdlib.h>
|
||||||
const char *RESULT_PTR;
|
|
||||||
|
void *RESULT_PTR;
|
||||||
int RESULT_SIZE;
|
int RESULT_SIZE;
|
||||||
|
|
||||||
void* allocate(size_t size) {
|
cvector_vector_type(void *) OBJECTS_TO_RELEASE;
|
||||||
|
|
||||||
|
void* allocate(size_t size, size_t _type_tag) {
|
||||||
|
if (size == 0 || size + 1 == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this +1 is needed to append then zero byte to strings passing to this module.
|
||||||
return malloc(size + 1);
|
return malloc(size + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(void *ptr, int size) {
|
void release_objects() {
|
||||||
free(ptr);
|
const unsigned int objects_count = cvector_size(OBJECTS_TO_RELEASE);
|
||||||
|
for (unsigned int obj_id = objects_count; obj_id > 0; --obj_id) {
|
||||||
|
void *object = OBJECTS_TO_RELEASE[obj_id-1];
|
||||||
|
free(object);
|
||||||
|
|
||||||
|
cvector_pop_back(OBJECTS_TO_RELEASE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_result_ptr(const char *ptr) {
|
void add_object_to_release(void *object) {
|
||||||
|
cvector_push_back(OBJECTS_TO_RELEASE, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_result_ptr(void *ptr) {
|
||||||
RESULT_PTR = ptr;
|
RESULT_PTR = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +43,29 @@ int get_result_size(void) {
|
|||||||
return RESULT_SIZE;
|
return RESULT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_result_ptr() {
|
void *get_result_ptr() {
|
||||||
return RESULT_PTR;
|
return RESULT_PTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *handle_input_string(char *str, int len) {
|
||||||
|
if (len == 0) {
|
||||||
|
free(str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this strings are supposed to be allocated by the allocate function, which allocates 1 byte more for null character
|
||||||
|
str[len] = '\x00';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_le_int(unsigned char *array, unsigned int offset, unsigned int value) {
|
||||||
|
array[offset] = value & 0xff;
|
||||||
|
array[offset + 1] = (value >> 8) & 0xff;
|
||||||
|
array[offset + 2] = (value >> 16) & 0xff;
|
||||||
|
array[offset + 3] = (value >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// the main purpose of this empty main is to initialize WASI subsystem
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user