From 1e397f8fb4f94de4c4ad0e47c43cb145c2d436a6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Jun 2006 15:28:43 +0000 Subject: [PATCH] New shell command ".load" and the sqlite3_load_extension() API allow new SQL functions and collating sequences to be loaded at run-time from a DLL or shared library. (CVS 3207) FossilOrigin-Name: 4ca932d3ae9bb97b819b5baf6fd3e1cebda9e0e2 --- Makefile.in | 7 +- main.mk | 7 +- manifest | 20 ++-- manifest.uuid | 2 +- src/loadext.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++ src/shell.c | 17 ++- src/sqlite.h.in | 42 +++++++- src/sqlite3ext.h | 268 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 616 insertions(+), 14 deletions(-) create mode 100644 src/loadext.c create mode 100644 src/sqlite3ext.h diff --git a/Makefile.in b/Makefile.in index 81ea22e95e..5c600c6c1e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -124,7 +124,7 @@ TCC += -DSQLITE_OMIT_CURSOR # LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \ callback.lo complete.lo date.lo \ - delete.lo expr.lo func.lo hash.lo insert.lo \ + delete.lo expr.lo func.lo hash.lo insert.lo loadext.lo \ main.lo opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \ pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \ select.lo table.lo tokenize.lo trigger.lo update.lo \ @@ -152,6 +152,7 @@ SRC = \ $(TOP)/src/hash.h \ $(TOP)/src/insert.c \ $(TOP)/src/legacy.c \ + $(TOP)/src/loadext.c \ $(TOP)/src/main.c \ $(TOP)/src/os.c \ $(TOP)/src/os_unix.c \ @@ -222,6 +223,7 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ + $(TOP)/src/sqlite3ext.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h @@ -330,6 +332,9 @@ insert.lo: $(TOP)/src/insert.c $(HDR) legacy.lo: $(TOP)/src/legacy.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/legacy.c +loadext.lo: $(TOP)/src/loadext.c $(HDR) + $(LTCOMPILE) -c $(TOP)/src/loadext.c + main.lo: $(TOP)/src/main.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c diff --git a/main.mk b/main.mk index 580835f289..c51b7aa1db 100644 --- a/main.mk +++ b/main.mk @@ -57,7 +57,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \ callback.o complete.o date.o delete.o \ - expr.o func.o hash.o insert.o \ + expr.o func.o hash.o insert.o loadext.o \ main.o opcodes.o os.o os_os2.o os_unix.o os_win.o \ pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ @@ -85,6 +85,7 @@ SRC = \ $(TOP)/src/hash.h \ $(TOP)/src/insert.c \ $(TOP)/src/legacy.c \ + $(TOP)/src/loadext.c \ $(TOP)/src/main.c \ $(TOP)/src/os.c \ $(TOP)/src/os_os2.c \ @@ -155,6 +156,7 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ + $(TOP)/src/sqlite3ext.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h @@ -254,6 +256,9 @@ insert.o: $(TOP)/src/insert.c $(HDR) legacy.o: $(TOP)/src/legacy.c $(HDR) $(TCCX) -c $(TOP)/src/legacy.c +loadext.o: $(TOP)/src/loadext.c $(HDR) + $(TCCX) -c $(TOP)/src/loadext.c + main.o: $(TOP)/src/main.c $(HDR) $(TCCX) -c $(TOP)/src/main.c diff --git a/manifest b/manifest index 2490037430..1d607c6481 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Version\s3.3.6\s(CVS\s3206) -D 2006-06-06T13:34:16 -F Makefile.in 87b6d483513ab8a4e763775bc5b434d6b5c34963 +C New\sshell\scommand\s".load"\sand\sthe\ssqlite3_load_extension()\sAPI\sallow\nnew\sSQL\sfunctions\sand\scollating\ssequences\sto\sbe\sloaded\sat\srun-time\sfrom\na\sDLL\sor\sshared\slibrary.\s(CVS\s3207) +D 2006-06-08T15:28:44 +F Makefile.in 50d948a8c4eda30ebb5799b661bd4c2de11824d0 F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F VERSION 301ed2b2c08f5cca242ea56e50a9ed0264a3eb76 @@ -19,7 +19,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk e3dd76266d1b62f1835b238bb0565900ab99fe14 +F main.mk 9a328281e0d992dcbbf502ec868793dca0a1d7b9 F mkdll.sh 919df5efde876194e3102c6ebc60657d38949909 F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5 @@ -48,6 +48,7 @@ F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/insert.c 1ae4b8ff5549497808e1b57b9243abcb599fd02f F src/legacy.c fa15d505dd4e45044177ee4d1c6aeaf8c836d390 +F src/loadext.c 71405a8f9fedc0c21b63bbe24a0fb52081caf4a5 F src/main.c 928d93cfd5d72be3a619ee908182c9432151a99e F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235 @@ -70,8 +71,9 @@ F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240 F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 F src/select.c 8daba07a04a6d41f5267ea8353324cbe5a210e14 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 -F src/shell.c 087d388b2517b410b11b25d7b91728d0859f866c -F src/sqlite.h.in e783b895fe2fcd68f6c04408a4efaef58cd1cdda +F src/shell.c 4f1e4a4d3e7aadd1369604a30293fc3e1726c78c +F src/sqlite.h.in d33c4688ba292af5f84fea49b2e3946b9129673a +F src/sqlite3ext.h 127bd394c8eea481f2ac9b754bf399dbfc818b75 F src/sqliteInt.h 98b3d7e9c4c48fd128d03d5788ca8fae0994280a F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e F src/tclsqlite.c 5ae9f08f7af7fe80d38fbccc4f5359f272643af1 @@ -358,7 +360,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P b2e11e02902d6fa8fc2fb95cda4810e837d6861e -R 505b982c1bdabcdfb694033eb3799e95 +P c11cb07e4b3f0b815a7099c8d201b3473869cba2 +R 46a5b7e0c262c56ce770de14a1643ea8 U drh -Z 520f79fd80b6c51afb7f59475232b5c8 +Z edb9ada8988bcadffc5de5550d7a256a diff --git a/manifest.uuid b/manifest.uuid index e42e8cc98d..e243a6b8dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c11cb07e4b3f0b815a7099c8d201b3473869cba2 \ No newline at end of file +4ca932d3ae9bb97b819b5baf6fd3e1cebda9e0e2 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c new file mode 100644 index 0000000000..799b878d3a --- /dev/null +++ b/src/loadext.c @@ -0,0 +1,267 @@ +/* +** 2006 June 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 contains code used to dynamically load extensions into +** the SQLite library. +*/ +#ifndef SQLITE_OMIT_LOAD_EXTENSION + +#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#include "sqlite3ext.h" +#include +#include + +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +# define sqlite3_table_column_metadata 0 +#endif + +const sqlite3_api_routines sqlite3_api = { + sqlite3_aggregate_context, + sqlite3_aggregate_count, + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, + sqlite3_expired, + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + sqlite3_global_recover, + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, + sqlite3_thread_cleanup, + sqlite3_total_changes, + sqlite3_trace, + sqlite3_transfer_bindings, + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, +}; + + + #if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) +# include +# define SQLITE_LIBRARY_TYPE HANDLE +# define SQLITE_OPEN_LIBRARY(A) LoadLibrary(A) +# define SQLITE_FIND_SYMBOL(A,B) GetProcAddress(A,B) +# define SQLITE_LIBRARY_ERROR(A) FreeLibrary(A) +# define SQLITE_CLOSE_LIBRARY(A) +#endif /* windows */ + +/* +** Non-windows implementation of shared-library loaders +*/ +#if defined(HAVE_DLOPEN) && !defined(SQLITE_LIBRARY_TYPE) +# include +# define SQLITE_LIBRARY_TYPE void* +# define SQLITE_OPEN_LIBRARY(A) dlopen(A, RTLD_NOW | RTLD_GLOBAL) +# define SQLITE_FIND_SYMBOL(A,B) dlsym(A,B) +# define SQLITE_LIBRARY_ERROR(A) dlclose(A) +# define SQLITE_CLOSE_LIBRARY(A) +#endif + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point is derived from the filename. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3_free(). +** +** The entry point name is derived from the filename according to the +** following steps: +** +** * Convert the name to lower case +** * Remove the path prefix from the name +** * Remove the first "." and all following characters from the name +** * If the name begins with "lib" remove the first 3 characters +** * Remove all characters that are not US-ASCII alphanumerics +** or underscores +** * Remove any leading digits and underscores from the name +** * Append "_init" to the name +** +** So, for example, if the input filename is "/home/drh/libtest1.52.so" +** then the entry point would be computed as "test1_init". +** +** The derived entry point name is limited to a reasonable number of +** characters (currently 200). +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ +#ifdef SQLITE_LIBRARY_TYPE + SQLITE_LIBRARY_TYPE handle; + int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + char *zErrmsg = 0; + + if( zProc==0 ){ + int i, j, n; + char *z; + char zBuf[200]; + n = strlen(zFile); + for(i=n-1; i>0 && zFile[i-1]!='/'; i--){} + for(j=i; zFile[j] && zFile[j]!='.'; j++){} + if( j-i > sizeof(zBuf)-10 ) j = i + sizeof(zBuf) - 10; + memcpy(zBuf, &zFile[i], j - i); + zBuf[j - i] = 0; + z = zBuf; + for(i=j=0; z[i]; i++){ + int c = z[i]; + if( (c & 0x80)!=0 || (!isalnum(c) && c!='_') ) continue; + z[j++] = tolower(c); + } + z[j] = 0; + if( strncmp(z, "lib", 3)==0 ){ + z += 3; + } + while( z[0] && !isalpha(z[0]) ){ + z++; + } + strcat(z, "_init"); + zProc = z; + } + + handle = SQLITE_OPEN_LIBRARY(zFile); + if( handle==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile); + } + return SQLITE_ERROR; + } + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + SQLITE_FIND_SYMBOL(handle, zProc); + if( xInit==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]", + zProc, zFile); + } + SQLITE_LIBRARY_ERROR(handle); + return SQLITE_ERROR; + }else if( xInit(db, &zErrmsg, &sqlite3_api) ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + SQLITE_LIBRARY_ERROR(handle); + return SQLITE_ERROR; + } + SQLITE_CLOSE_LIBRARY(handle); + return SQLITE_OK; +#else + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf( + "shared library loading not enabled for this build"); + } + return SQLITE_ERROR; +#endif +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ diff --git a/src/shell.c b/src/shell.c index 8f9c8a45f0..4392ec5d31 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.138 2006/06/06 12:32:21 drh Exp $ +** $Id: shell.c,v 1.139 2006/06/08 15:28:44 drh Exp $ */ #include #include @@ -759,6 +759,7 @@ static char zHelp[] = ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" ".indices TABLE Show names of all indices on TABLE\n" + ".load FILE ?ENTRY? Load an extension library\n" ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" @@ -1144,6 +1145,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else + if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ + const char *zFile, *zProc; + char *zErrMsg = 0; + int rc; + zFile = azArg[1]; + zProc = nArg>=3 ? azArg[2] : 0; + open_db(p); + rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "%s\n", zErrMsg); + sqlite3_free(zErrMsg); + } + }else + if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){ int n2 = strlen(azArg[1]); if( strncmp(azArg[1],"line",n2)==0 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f39d46bb48..375e694d12 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.165 2006/04/04 01:54:55 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.166 2006/06/08 15:28:44 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1468,6 +1468,46 @@ int sqlite3_table_column_metadata( int *pAutoinc /* OUTPUT: True if colums is auto-increment */ ); +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point is derived from the filename. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3_free(). +** +** The entry point name is derived from the filename according to the +** following steps: +** +** * Convert the name to lower case +** * Remove the path prefix from the name +** * Remove the first "." and all following characters from the name +** * If the name begins with "lib" remove the first 3 characters +** * Remove all characters that are not US-ASCII alphanumerics +** or underscores +** * Remove any leading digits and underscores from the name +** * Append "_init" to the name +** +** So, for example, if the input filename is "/home/drh/libtest1.52.so" +** then the entry point would be computed as "test1_init". +** +** The derived entry point name is limited to a reasonable number of +** characters (currently 200). +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h new file mode 100644 index 0000000000..59d410bf05 --- /dev/null +++ b/src/sqlite3ext.h @@ -0,0 +1,268 @@ +/* +** 2006 June 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 header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +** +** @(#) $Id: sqlite3ext.h,v 1.1 2006/06/08 15:28:44 drh Exp $ +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ +#include + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure hold pointers to all of the SQLite API +** routines. +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(char*z); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interrupt)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char * (*vmprintf)(const char*,va_list); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected throught the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#define sqlite3_expired sqlite3_api->expired +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#define sqlite3_global_recover sqlite3_api->global_recover +#define sqlite3_interrupt sqlite3_api->interrupt +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#endif /* SQLITE_CORE */ + +#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; +#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; + +#endif /* _SQLITE3EXT_H_ */ -- 2.47.2