[External] Remove external from RT-Thread

This commit is contained in:
bernard
2017-11-02 13:50:42 +08:00
parent 23582c8129
commit b2057f506a
1366 changed files with 0 additions and 873570 deletions

View File

@@ -1,138 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The directory where to find the mingw32ce tools
MINGW32CE = /opt/mingw32ce/bin
#### The target prefix of the mingw32ce tools
TARGET = arm-wince-mingw32ce
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DTHREADSAFE=1
#THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
#OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .exe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
#AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
AR = $(MINGW32CE)/$(TARGET)-ar cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
SO = dll
SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
#USLEEP =
USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
#THREADSAFE = -DTHREADSAFE=1
THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1
OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
#EXE = .exe
EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
MKSHLIB = gcc -shared
SO = so
SHPREFIX = lib
# SO = dll
# SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
#TCLOBJ =
TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +0,0 @@
This directory contains source code to
SQLite: An Embeddable SQL Database Engine
To compile the project, first create a directory in which to place
the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
For example:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make ;# Run the makefile.
make install ;# (Optional) Install the build products
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
The linux binaries on the website are created using the generic makefile,
not the configure script. The windows binaries on the website are created
using MinGW32 configured as a cross-compiler running under Linux. For
details, see the ./publish.sh script at the top-level of the source tree.
The developers do not use teh configure script.
SQLite does not require TCL to run, but a TCL installation is required
by the makefiles. SQLite contains a lot of generated code and TCL is
used to do much of that code generation. The makefile also requires
AWK.
Contacts:
http://www.sqlite.org/

View File

@@ -1,14 +0,0 @@
Import('rtconfig')
import os
from building import *
cwd = GetCurrentDir() + str(r'/SQLiteLib/')
src = Split("""
SQLiteLib/sqlite3.c
SQLiteLib/test/test10.c
""")
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('sqlite', src, depend = ['RT_USING_SQLITE'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -1,33 +0,0 @@
# SQLite on RT-Thread
## 简介
初始版本基于SQLite 3.8.1版本,使用混合单文件结构源代码
测试方法:
1.
在rtconfig.h中定义一下宏,并打开newlib组件
/*
* SQLite compile macro
*/
#define RT_USING_SQLITE
2.
关注SQLite目录下的src/sqlite_config_rtthread.h
#define SQLITE_MINIMUM_FILE_DESCRIPTOR 0
#define SQLITE_OMIT_LOAD_EXTENSION 1
#define SQLITE_OMIT_WAL
#define SQLITE_RTTHREAD_NO_WIDE 1
#define SQLITE_ENABLE_LOCKING_STYLE 0
#define SQLITE_DISABLE_LOCKING_STYLE 1
#define SQLITE_TEMP_STORE 1
#define SQLITE_THREADSAFE 1
#define HAVE_READLINE 0
#define NDEBUG
#define _HAVE_SQLITE_CONFIG_H
#define BUILD_sqlite
#define SQLITE_OS_OTHER 1
#define SQLITE_OS_RTTHREAD 1
3.
用test目录下的test10.c来进行测试.
推荐用mini2440bsp因为板子的ram较大。
注意shell.c还没有移植的。请不要使用。

View File

@@ -1,114 +0,0 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the `fdatasync' function. */
/* #undef HAVE_FDATASYNC */
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if the system has the type `int16_t'. */
#define HAVE_INT16_T 1
/* Define to 1 if the system has the type `int32_t'. */
#define HAVE_INT32_T 1
/* Define to 1 if the system has the type `int64_t'. */
#define HAVE_INT64_T 1
/* Define to 1 if the system has the type `int8_t'. */
#define HAVE_INT8_T 1
/* Define to 1 if the system has the type `intptr_t'. */
#define HAVE_INTPTR_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `localtime_r' function. */
#define HAVE_LOCALTIME_R 1
/* Define to 1 if you have the `localtime_s' function. */
/* #undef HAVE_LOCALTIME_S */
/* Define to 1 if you have the <malloc.h> header file. */
/* #define HAVE_MALLOC_H 0 */
/* Define to 1 if you have the `malloc_usable_size' function. */
/* #define HAVE_MALLOC_USABLE_SIZE 0 */
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if the system has the type `uint16_t'. */
#define HAVE_UINT16_T 1
/* Define to 1 if the system has the type `uint32_t'. */
#define HAVE_UINT32_T 1
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if the system has the type `uint8_t'. */
#define HAVE_UINT8_T 1
/* Define to 1 if the system has the type `uintptr_t'. */
#define HAVE_UINTPTR_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `usleep' function. */
/* #undef HAVE_USLEEP */
/* Define to 1 if you have the utime() library function. */
/* #undef HAVE_UTIME */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "sqlite"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "sqlite 3.8.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "sqlite"
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.8.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,487 +0,0 @@
/*
** 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.
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
#include "sqlite3.h"
typedef struct sqlite3_api_routines sqlite3_api_routines;
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each others' shared
** libraries!
*/
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 (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
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);
sqlite3_value* (*column_value)(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 void*,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 (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
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)(void*);
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 (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
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*);
void *(*realloc)(void*,int);
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);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*vsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
};
/*
** 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
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#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_bind_value sqlite3_api->bind_value
#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_column_value sqlite3_api->column_value
#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_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#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
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#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
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#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_malloc sqlite3_api->malloc
#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_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#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
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#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
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
#endif /* SQLITE_CORE */
#ifndef SQLITE_CORE
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* _SQLITE3EXT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
#include <stdio.h>
#include <sqlite3.h>
#include "finsh.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
rt_kprintf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
rt_kprintf("\n");
return 0;
}
int test10_main(void){
static int step = 0;
int argc = 4;
char *argv[4] = {"test10_main", "test.db",
"create table mytable(entry1 int)",
"drop table mytable"};
sqlite3 *db;
char *zErrMsg = 0;
int rc;
if( argc<3 ){
rt_kprintf("Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
return(1);
}
rt_kprintf("ready open %s\n", argv[1]);
rc = sqlite3_open(argv[1], &db);
if( rc ){
rt_kprintf("Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return(1);
}
else{
rt_kprintf("open %s success\n", argv[1]);
}
if (step == 0) {
rt_kprintf("SQL exec: %s\n", argv[2]);
rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
rt_kprintf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else{
rt_kprintf("SQL exec: %s success\n", argv[2]);
}
}
else {
rt_kprintf("SQL exec: %s\n", argv[3]);
rc = sqlite3_exec(db, argv[3], callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
rt_kprintf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else{
rt_kprintf("SQL exec: %s success\n", argv[3]);
}
}
step = !step;
sqlite3_close(db);
return 0;
}
FINSH_FUNCTION_EXPORT(test10_main, sqlite test)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,217 +0,0 @@
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** Code for testing the utf.c module in SQLite. This code
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. Specifically, the code in this file
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
/*
** The first argument is a TCL UTF-8 string. Return the byte array
** object with the encoded representation of the string, including
** the NULL terminator.
*/
static int binarize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int len;
char *bytes;
Tcl_Obj *pRet;
assert(objc==2);
bytes = Tcl_GetStringFromObj(objv[1], &len);
pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1);
Tcl_SetObjResult(interp, pRet);
return TCL_OK;
}
/*
** Usage: test_value_overhead <repeat-count> <do-calls>.
**
** This routine is used to test the overhead of calls to
** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea
** is to figure out whether or not it is a problem to use sqlite3_value
** structures with collation sequence functions.
**
** If <do-calls> is 0, then the calls to sqlite3_value_text() are not
** actually made.
*/
static int test_value_overhead(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int do_calls;
int repeat_count;
int i;
Mem val;
if( objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " <repeat-count> <do-calls>", 0);
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR;
val.flags = MEM_Str|MEM_Term|MEM_Static;
val.z = "hello world";
val.type = SQLITE_TEXT;
val.enc = SQLITE_UTF8;
for(i=0; i<repeat_count; i++){
if( do_calls ){
sqlite3_value_text(&val);
}
}
return TCL_OK;
}
static u8 name_to_enc(Tcl_Interp *interp, Tcl_Obj *pObj){
struct EncName {
char *zName;
u8 enc;
} encnames[] = {
{ "UTF8", SQLITE_UTF8 },
{ "UTF16LE", SQLITE_UTF16LE },
{ "UTF16BE", SQLITE_UTF16BE },
{ "UTF16", SQLITE_UTF16 },
{ 0, 0 }
};
struct EncName *pEnc;
char *z = Tcl_GetString(pObj);
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( 0==sqlite3StrICmp(z, pEnc->zName) ){
break;
}
}
if( !pEnc->enc ){
Tcl_AppendResult(interp, "No such encoding: ", z, 0);
}
if( pEnc->enc==SQLITE_UTF16 ){
return SQLITE_UTF16NATIVE;
}
return pEnc->enc;
}
/*
** Usage: test_translate <string/blob> <from enc> <to enc> ?<transient>?
**
*/
static int test_translate(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
u8 enc_from;
u8 enc_to;
sqlite3_value *pVal;
char *z;
int len;
void (*xDel)(void *p) = SQLITE_STATIC;
if( objc!=4 && objc!=5 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0),
" <string/blob> <from enc> <to enc>", 0
);
return TCL_ERROR;
}
if( objc==5 ){
xDel = sqlite3_free;
}
enc_from = name_to_enc(interp, objv[2]);
if( !enc_from ) return TCL_ERROR;
enc_to = name_to_enc(interp, objv[3]);
if( !enc_to ) return TCL_ERROR;
pVal = sqlite3ValueNew(0);
if( enc_from==SQLITE_UTF8 ){
z = Tcl_GetString(objv[1]);
if( objc==5 ){
z = sqlite3_mprintf("%s", z);
}
sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
}else{
z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len);
if( objc==5 ){
char *zTmp = z;
z = sqlite3_malloc(len);
memcpy(z, zTmp, len);
}
sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
}
z = (char *)sqlite3ValueText(pVal, enc_to);
len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len));
sqlite3ValueFree(pVal);
return TCL_OK;
}
/*
** Usage: translate_selftest
**
** Call sqlite3UtfSelfTest() to run the internal tests for unicode
** translation. If there is a problem an assert() will fail.
**/
void sqlite3UtfSelfTest(void);
static int test_translate_selftest(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_OMIT_UTF16
sqlite3UtfSelfTest();
#endif
return SQLITE_OK;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest5_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aCmd[] = {
{ "binarize", (Tcl_ObjCmdProc*)binarize },
{ "test_value_overhead", (Tcl_ObjCmdProc*)test_value_overhead },
{ "test_translate", (Tcl_ObjCmdProc*)test_translate },
{ "translate_selftest", (Tcl_ObjCmdProc*)test_translate_selftest},
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
}
return SQLITE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,200 +0,0 @@
/*
** 2007 March 29
**
** 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 obscure tests of the C-interface required
** for completeness. Test code is written in C for these cases
** as there is not much point in binding to Tcl.
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
/*
** c_collation_test
*/
static int c_collation_test(
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 */
){
const char *zErrFunction = "N/A";
sqlite3 *db;
int rc;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
/* Open a database. */
rc = sqlite3_open(":memory:", &db);
if( rc!=SQLITE_OK ){
zErrFunction = "sqlite3_open";
goto error_out;
}
rc = sqlite3_create_collation(db, "collate", 456, 0, 0);
if( rc!=SQLITE_MISUSE ){
sqlite3_close(db);
zErrFunction = "sqlite3_create_collation";
goto error_out;
}
sqlite3_close(db);
return TCL_OK;
error_out:
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
return TCL_ERROR;
}
/*
** c_realloc_test
*/
static int c_realloc_test(
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 */
){
void *p;
const char *zErrFunction = "N/A";
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
p = sqlite3_malloc(5);
if( !p ){
zErrFunction = "sqlite3_malloc";
goto error_out;
}
/* Test that realloc()ing a block of memory to a negative size is
** the same as free()ing that memory.
*/
p = sqlite3_realloc(p, -1);
if( p ){
zErrFunction = "sqlite3_realloc";
goto error_out;
}
return TCL_OK;
error_out:
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
return TCL_ERROR;
}
/*
** c_misuse_test
*/
static int c_misuse_test(
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 */
){
const char *zErrFunction = "N/A";
sqlite3 *db = 0;
sqlite3_stmt *pStmt;
int rc;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
/* Open a database. Then close it again. We need to do this so that
** we have a "closed database handle" to pass to various API functions.
*/
rc = sqlite3_open(":memory:", &db);
if( rc!=SQLITE_OK ){
zErrFunction = "sqlite3_open";
goto error_out;
}
sqlite3_close(db);
rc = sqlite3_errcode(db);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_errcode";
goto error_out;
}
pStmt = (sqlite3_stmt*)1234;
rc = sqlite3_prepare(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare";
goto error_out;
}
assert( pStmt==0 ); /* Verify that pStmt is zeroed even on a MISUSE error */
pStmt = (sqlite3_stmt*)1234;
rc = sqlite3_prepare_v2(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare_v2";
goto error_out;
}
assert( pStmt==0 );
#ifndef SQLITE_OMIT_UTF16
pStmt = (sqlite3_stmt*)1234;
rc = sqlite3_prepare16(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare16";
goto error_out;
}
assert( pStmt==0 );
pStmt = (sqlite3_stmt*)1234;
rc = sqlite3_prepare16_v2(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare16_v2";
goto error_out;
}
assert( pStmt==0 );
#endif
return TCL_OK;
error_out:
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
return TCL_ERROR;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest9_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "c_misuse_test", c_misuse_test, 0 },
{ "c_realloc_test", c_realloc_test, 0 },
{ "c_collation_test", c_collation_test, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
return TCL_OK;
}

View File

@@ -1,241 +0,0 @@
/*
** 2005 December 14
**
** 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 a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
*/
#define TCL_THREADS
#include <tcl.h>
#ifdef SQLITE_ENABLE_ASYNCIO
#include "sqlite3async.h"
#include "sqlite3.h"
#include <assert.h>
/* From main.c */
extern const char *sqlite3ErrName(int);
struct TestAsyncGlobal {
int isInstalled; /* True when async VFS is installed */
} testasync_g = { 0 };
TCL_DECLARE_MUTEX(testasync_g_writerMutex);
/*
** sqlite3async_initialize PARENT-VFS ISDEFAULT
*/
static int testAsyncInit(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
const char *zParent;
int isDefault;
int rc;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
return TCL_ERROR;
}
zParent = Tcl_GetString(objv[1]);
if( !*zParent ) {
zParent = 0;
}
if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
return TCL_ERROR;
}
rc = sqlite3async_initialize(zParent, isDefault);
if( rc!=SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
return TCL_ERROR;
}
return TCL_OK;
}
/*
** sqlite3async_shutdown
*/
static int testAsyncShutdown(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3async_shutdown();
return TCL_OK;
}
static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
Tcl_MutexLock(&testasync_g_writerMutex);
*((int *)pIsStarted) = 1;
sqlite3async_run();
Tcl_MutexUnlock(&testasync_g_writerMutex);
Tcl_ExitThread(0);
TCL_THREAD_CREATE_RETURN;
}
/*
** sqlite3async_start
**
** Start a new writer thread.
*/
static int testAsyncStart(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
volatile int isStarted = 0;
ClientData threadData = (ClientData)&isStarted;
Tcl_ThreadId x;
const int nStack = TCL_THREAD_STACK_DEFAULT;
const int flags = TCL_THREAD_NOFLAGS;
int rc;
rc = Tcl_CreateThread(&x, tclWriterThread, threadData, nStack, flags);
if( rc!=TCL_OK ){
Tcl_AppendResult(interp, "Tcl_CreateThread() failed", 0);
return TCL_ERROR;
}
while( isStarted==0 ) { /* Busy loop */ }
return TCL_OK;
}
/*
** sqlite3async_wait
**
** Wait for the current writer thread to terminate.
**
** If the current writer thread is set to run forever then this
** command would block forever. To prevent that, an error is returned.
*/
static int testAsyncWait(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int eCond;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond);
if( eCond==SQLITEASYNC_HALT_NEVER ){
Tcl_AppendResult(interp, "would block forever", (char*)0);
return TCL_ERROR;
}
Tcl_MutexLock(&testasync_g_writerMutex);
Tcl_MutexUnlock(&testasync_g_writerMutex);
return TCL_OK;
}
/*
** sqlite3async_control OPTION ?VALUE?
*/
static int testAsyncControl(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = SQLITE_OK;
int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES };
const char *azOpt[] = { "halt", "delay", "lockfiles", 0 };
const char *az[] = { "never", "now", "idle", 0 };
int iVal;
int eOpt;
if( objc!=2 && objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?");
return TCL_ERROR;
}
if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){
return TCL_ERROR;
}
eOpt = aeOpt[eOpt];
if( objc==3 ){
switch( eOpt ){
case SQLITEASYNC_HALT: {
assert( SQLITEASYNC_HALT_NEVER==0 );
assert( SQLITEASYNC_HALT_NOW==1 );
assert( SQLITEASYNC_HALT_IDLE==2 );
if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){
return TCL_ERROR;
}
break;
}
case SQLITEASYNC_DELAY:
if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){
return TCL_ERROR;
}
break;
case SQLITEASYNC_LOCKFILES:
if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){
return TCL_ERROR;
}
break;
}
rc = sqlite3async_control(eOpt, iVal);
}
if( rc==SQLITE_OK ){
rc = sqlite3async_control(
eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT :
eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY :
SQLITEASYNC_GET_LOCKFILES, &iVal);
}
if( rc!=SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
return TCL_ERROR;
}
if( eOpt==SQLITEASYNC_HALT ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1));
}else{
Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
}
return TCL_OK;
}
#endif /* SQLITE_ENABLE_ASYNCIO */
/*
** This routine registers the custom TCL commands defined in this
** module. This should be the only procedure visible from outside
** of this module.
*/
int Sqlitetestasync_Init(Tcl_Interp *interp){
#ifdef SQLITE_ENABLE_ASYNCIO
Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0);
#endif /* SQLITE_ENABLE_ASYNCIO */
return TCL_OK;
}

View File

@@ -1,221 +0,0 @@
/*
** 2006 August 23
**
** 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.
**
*************************************************************************
** Test extension for testing the sqlite3_auto_extension() function.
*/
#include "tcl.h"
#include "sqlite3ext.h"
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_EXTENSION_INIT1
/*
** The sqr() SQL function returns the square of its input value.
*/
static void sqrFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
double r = sqlite3_value_double(argv[0]);
sqlite3_result_double(context, r*r);
}
/*
** This is the entry point to register the extension for the sqr() function.
*/
static int sqr_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
sqlite3_create_function(db, "sqr", 1, SQLITE_ANY, 0, sqrFunc, 0, 0);
return 0;
}
/*
** The cube() SQL function returns the cube of its input value.
*/
static void cubeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
double r = sqlite3_value_double(argv[0]);
sqlite3_result_double(context, r*r*r);
}
/*
** This is the entry point to register the extension for the cube() function.
*/
static int cube_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
sqlite3_create_function(db, "cube", 1, SQLITE_ANY, 0, cubeFunc, 0, 0);
return 0;
}
/*
** This is a broken extension entry point
*/
static int broken_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
char *zErr;
SQLITE_EXTENSION_INIT2(pApi);
zErr = sqlite3_mprintf("broken autoext!");
*pzErrMsg = zErr;
return 1;
}
/*
** tclcmd: sqlite3_auto_extension_sqr
**
** Register the "sqr" extension to be loaded automatically.
*/
static int autoExtSqrObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_auto_extension((void*)sqr_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
/*
** tclcmd: sqlite3_cancel_auto_extension_sqr
**
** Unregister the "sqr" extension.
*/
static int cancelAutoExtSqrObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_cancel_auto_extension((void*)sqr_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
/*
** tclcmd: sqlite3_auto_extension_cube
**
** Register the "cube" extension to be loaded automatically.
*/
static int autoExtCubeObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_auto_extension((void*)cube_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
/*
** tclcmd: sqlite3_cancel_auto_extension_cube
**
** Unregister the "cube" extension.
*/
static int cancelAutoExtCubeObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_cancel_auto_extension((void*)cube_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
/*
** tclcmd: sqlite3_auto_extension_broken
**
** Register the broken extension to be loaded automatically.
*/
static int autoExtBrokenObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_auto_extension((void*)broken_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
/*
** tclcmd: sqlite3_cancel_auto_extension_broken
**
** Unregister the broken extension.
*/
static int cancelAutoExtBrokenObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = sqlite3_cancel_auto_extension((void*)broken_init);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return SQLITE_OK;
}
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
/*
** tclcmd: sqlite3_reset_auto_extension
**
** Reset all auto-extensions
*/
static int resetAutoExtObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_reset_auto_extension();
return SQLITE_OK;
}
/*
** This procedure registers the TCL procs defined in this file.
*/
int Sqlitetest_autoext_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_LOAD_EXTENSION
Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_sqr",
autoExtSqrObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_cube",
autoExtCubeObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_broken",
autoExtBrokenObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_sqr",
cancelAutoExtSqrObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_cube",
cancelAutoExtCubeObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_cancel_auto_extension_broken",
cancelAutoExtBrokenObjCmd, 0, 0);
#endif
Tcl_CreateObjCommand(interp, "sqlite3_reset_auto_extension",
resetAutoExtObjCmd, 0, 0);
return TCL_OK;
}

View File

@@ -1,150 +0,0 @@
/*
** 2009 January 28
**
** 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 test logic for the sqlite3_backup() interface.
**
*/
#include "tcl.h"
#include <sqlite3.h>
#include <assert.h>
/* These functions are implemented in main.c. */
extern const char *sqlite3ErrName(int);
/* These functions are implemented in test1.c. */
extern int getDbPointer(Tcl_Interp *, const char *, sqlite3 **);
static int backupTestCmd(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const*objv
){
enum BackupSubCommandEnum {
BACKUP_STEP, BACKUP_FINISH, BACKUP_REMAINING, BACKUP_PAGECOUNT
};
struct BackupSubCommand {
const char *zCmd;
enum BackupSubCommandEnum eCmd;
int nArg;
const char *zArg;
} aSub[] = {
{"step", BACKUP_STEP , 1, "npage" },
{"finish", BACKUP_FINISH , 0, "" },
{"remaining", BACKUP_REMAINING , 0, "" },
{"pagecount", BACKUP_PAGECOUNT , 0, "" },
{0, 0, 0, 0}
};
sqlite3_backup *p = (sqlite3_backup *)clientData;
int iCmd;
int rc;
rc = Tcl_GetIndexFromObjStruct(
interp, objv[1], aSub, sizeof(aSub[0]), "option", 0, &iCmd
);
if( rc!=TCL_OK ){
return rc;
}
if( objc!=(2 + aSub[iCmd].nArg) ){
Tcl_WrongNumArgs(interp, 2, objv, aSub[iCmd].zArg);
return TCL_ERROR;
}
switch( aSub[iCmd].eCmd ){
case BACKUP_FINISH: {
const char *zCmdName;
Tcl_CmdInfo cmdInfo;
zCmdName = Tcl_GetString(objv[0]);
Tcl_GetCommandInfo(interp, zCmdName, &cmdInfo);
cmdInfo.deleteProc = 0;
Tcl_SetCommandInfo(interp, zCmdName, &cmdInfo);
Tcl_DeleteCommand(interp, zCmdName);
rc = sqlite3_backup_finish(p);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
break;
}
case BACKUP_STEP: {
int nPage;
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &nPage) ){
return TCL_ERROR;
}
rc = sqlite3_backup_step(p, nPage);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
break;
}
case BACKUP_REMAINING:
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_remaining(p)));
break;
case BACKUP_PAGECOUNT:
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_pagecount(p)));
break;
}
return TCL_OK;
}
static void backupTestFinish(ClientData clientData){
sqlite3_backup *pBackup = (sqlite3_backup *)clientData;
sqlite3_backup_finish(pBackup);
}
/*
** sqlite3_backup CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME
**
*/
static int backupTestInit(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const*objv
){
sqlite3_backup *pBackup;
sqlite3 *pDestDb;
sqlite3 *pSrcDb;
const char *zDestName;
const char *zSrcName;
const char *zCmd;
if( objc!=6 ){
Tcl_WrongNumArgs(
interp, 1, objv, "CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME"
);
return TCL_ERROR;
}
zCmd = Tcl_GetString(objv[1]);
getDbPointer(interp, Tcl_GetString(objv[2]), &pDestDb);
zDestName = Tcl_GetString(objv[3]);
getDbPointer(interp, Tcl_GetString(objv[4]), &pSrcDb);
zSrcName = Tcl_GetString(objv[5]);
pBackup = sqlite3_backup_init(pDestDb, zDestName, pSrcDb, zSrcName);
if( !pBackup ){
Tcl_AppendResult(interp, "sqlite3_backup_init() failed", 0);
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, zCmd, backupTestCmd, pBackup, backupTestFinish);
Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
int Sqlitetestbackup_Init(Tcl_Interp *interp){
Tcl_CreateObjCommand(interp, "sqlite3_backup", backupTestInit, 0, 0);
return TCL_OK;
}

View File

@@ -1,62 +0,0 @@
/*
** 2007 May 05
**
** 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.
**
*************************************************************************
** Code for testing the btree.c module in SQLite. This code
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
*/
#include "btreeInt.h"
#include <tcl.h>
/*
** Usage: sqlite3_shared_cache_report
**
** Return a list of file that are shared and the number of
** references to each file.
*/
int sqlite3BtreeSharedCacheReport(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_OMIT_SHARED_CACHE
extern BtShared *sqlite3SharedCacheList;
BtShared *pBt;
Tcl_Obj *pRet = Tcl_NewObj();
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
const char *zFile = sqlite3PagerFilename(pBt->pPager, 1);
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
}
Tcl_SetObjResult(interp, pRet);
#endif
return TCL_OK;
}
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *p){
#ifdef SQLITE_DEBUG
BtCursor *pCur;
BtShared *pBt = p->pBt;
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
MemPage *pPage = pCur->apPage[pCur->iPage];
char *zMode = pCur->wrFlag ? "rw" : "ro";
sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
pCur, pCur->pgnoRoot, zMode,
pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage],
(pCur->eState==CURSOR_VALID) ? "" : " eof"
);
}
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,398 +0,0 @@
/*
** 2008 Jan 22
**
** 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 that modified the OS layer in order to simulate
** different device types (by overriding the return values of the
** xDeviceCharacteristics() and xSectorSize() methods).
*/
#if SQLITE_TEST /* This file is used for testing only */
#include "sqlite3.h"
#include "sqliteInt.h"
/*
** Maximum pathname length supported by the devsym backend.
*/
#define DEVSYM_MAX_PATHNAME 512
/*
** Name used to identify this VFS.
*/
#define DEVSYM_VFS_NAME "devsym"
typedef struct devsym_file devsym_file;
struct devsym_file {
sqlite3_file base;
sqlite3_file *pReal;
};
/*
** Method declarations for devsym_file.
*/
static int devsymClose(sqlite3_file*);
static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
static int devsymSync(sqlite3_file*, int flags);
static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int devsymLock(sqlite3_file*, int);
static int devsymUnlock(sqlite3_file*, int);
static int devsymCheckReservedLock(sqlite3_file*, int *);
static int devsymFileControl(sqlite3_file*, int op, void *pArg);
static int devsymSectorSize(sqlite3_file*);
static int devsymDeviceCharacteristics(sqlite3_file*);
static int devsymShmLock(sqlite3_file*,int,int,int);
static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **);
static void devsymShmBarrier(sqlite3_file*);
static int devsymShmUnmap(sqlite3_file*,int);
/*
** Method declarations for devsym_vfs.
*/
static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
static void devsymDlClose(sqlite3_vfs*, void*);
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int devsymSleep(sqlite3_vfs*, int microseconds);
static int devsymCurrentTime(sqlite3_vfs*, double*);
static sqlite3_vfs devsym_vfs = {
2, /* iVersion */
sizeof(devsym_file), /* szOsFile */
DEVSYM_MAX_PATHNAME, /* mxPathname */
0, /* pNext */
DEVSYM_VFS_NAME, /* zName */
0, /* pAppData */
devsymOpen, /* xOpen */
devsymDelete, /* xDelete */
devsymAccess, /* xAccess */
devsymFullPathname, /* xFullPathname */
#ifndef SQLITE_OMIT_LOAD_EXTENSION
devsymDlOpen, /* xDlOpen */
devsymDlError, /* xDlError */
devsymDlSym, /* xDlSym */
devsymDlClose, /* xDlClose */
#else
0, /* xDlOpen */
0, /* xDlError */
0, /* xDlSym */
0, /* xDlClose */
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
devsymRandomness, /* xRandomness */
devsymSleep, /* xSleep */
devsymCurrentTime, /* xCurrentTime */
0, /* xGetLastError */
0 /* xCurrentTimeInt64 */
};
static sqlite3_io_methods devsym_io_methods = {
2, /* iVersion */
devsymClose, /* xClose */
devsymRead, /* xRead */
devsymWrite, /* xWrite */
devsymTruncate, /* xTruncate */
devsymSync, /* xSync */
devsymFileSize, /* xFileSize */
devsymLock, /* xLock */
devsymUnlock, /* xUnlock */
devsymCheckReservedLock, /* xCheckReservedLock */
devsymFileControl, /* xFileControl */
devsymSectorSize, /* xSectorSize */
devsymDeviceCharacteristics, /* xDeviceCharacteristics */
devsymShmMap, /* xShmMap */
devsymShmLock, /* xShmLock */
devsymShmBarrier, /* xShmBarrier */
devsymShmUnmap /* xShmUnmap */
};
struct DevsymGlobal {
sqlite3_vfs *pVfs;
int iDeviceChar;
int iSectorSize;
};
struct DevsymGlobal g = {0, 0, 512};
/*
** Close an devsym-file.
*/
static int devsymClose(sqlite3_file *pFile){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsClose(p->pReal);
}
/*
** Read data from an devsym-file.
*/
static int devsymRead(
sqlite3_file *pFile,
void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
}
/*
** Write data to an devsym-file.
*/
static int devsymWrite(
sqlite3_file *pFile,
const void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
}
/*
** Truncate an devsym-file.
*/
static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsTruncate(p->pReal, size);
}
/*
** Sync an devsym-file.
*/
static int devsymSync(sqlite3_file *pFile, int flags){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsSync(p->pReal, flags);
}
/*
** Return the current file-size of an devsym-file.
*/
static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsFileSize(p->pReal, pSize);
}
/*
** Lock an devsym-file.
*/
static int devsymLock(sqlite3_file *pFile, int eLock){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsLock(p->pReal, eLock);
}
/*
** Unlock an devsym-file.
*/
static int devsymUnlock(sqlite3_file *pFile, int eLock){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsUnlock(p->pReal, eLock);
}
/*
** Check if another file-handle holds a RESERVED lock on an devsym-file.
*/
static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsCheckReservedLock(p->pReal, pResOut);
}
/*
** File control method. For custom operations on an devsym-file.
*/
static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsFileControl(p->pReal, op, pArg);
}
/*
** Return the sector-size in bytes for an devsym-file.
*/
static int devsymSectorSize(sqlite3_file *pFile){
return g.iSectorSize;
}
/*
** Return the device characteristic flags supported by an devsym-file.
*/
static int devsymDeviceCharacteristics(sqlite3_file *pFile){
return g.iDeviceChar;
}
/*
** Shared-memory methods are all pass-thrus.
*/
static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmLock(p->pReal, ofst, n, flags);
}
static int devsymShmMap(
sqlite3_file *pFile,
int iRegion,
int szRegion,
int isWrite,
void volatile **pp
){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
}
static void devsymShmBarrier(sqlite3_file *pFile){
devsym_file *p = (devsym_file *)pFile;
sqlite3OsShmBarrier(p->pReal);
}
static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmUnmap(p->pReal, delFlag);
}
/*
** Open an devsym file handle.
*/
static int devsymOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
int rc;
devsym_file *p = (devsym_file *)pFile;
p->pReal = (sqlite3_file *)&p[1];
rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
if( p->pReal->pMethods ){
pFile->pMethods = &devsym_io_methods;
}
return rc;
}
/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return sqlite3OsDelete(g.pVfs, zPath, dirSync);
}
/*
** Test for access permissions. Return true if the requested permission
** is available, or false otherwise.
*/
static int devsymAccess(
sqlite3_vfs *pVfs,
const char *zPath,
int flags,
int *pResOut
){
return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
}
/*
** Populate buffer zOut with the full canonical pathname corresponding
** to the pathname in zPath. zOut is guaranteed to point to a buffer
** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
*/
static int devsymFullPathname(
sqlite3_vfs *pVfs,
const char *zPath,
int nOut,
char *zOut
){
return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Open the dynamic library located at zPath and return a handle.
*/
static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
return sqlite3OsDlOpen(g.pVfs, zPath);
}
/*
** Populate the buffer zErrMsg (size nByte bytes) with a human readable
** utf-8 string describing the most recent error encountered associated
** with dynamic libraries.
*/
static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
}
/*
** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
*/
static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
return sqlite3OsDlSym(g.pVfs, p, zSym);
}
/*
** Close the dynamic library handle pHandle.
*/
static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
sqlite3OsDlClose(g.pVfs, pHandle);
}
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
}
/*
** Sleep for nMicro microseconds. Return the number of microseconds
** actually slept.
*/
static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
return sqlite3OsSleep(g.pVfs, nMicro);
}
/*
** Return the current time as a Julian Day number in *pTimeOut.
*/
static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
}
/*
** This procedure registers the devsym vfs with SQLite. If the argument is
** true, the devsym vfs becomes the new default vfs. It is the only publicly
** available function in this file.
*/
void devsym_register(int iDeviceChar, int iSectorSize){
if( g.pVfs==0 ){
g.pVfs = sqlite3_vfs_find(0);
devsym_vfs.szOsFile += g.pVfs->szOsFile;
sqlite3_vfs_register(&devsym_vfs, 0);
}
if( iDeviceChar>=0 ){
g.iDeviceChar = iDeviceChar;
}else{
g.iDeviceChar = 0;
}
if( iSectorSize>=0 ){
g.iSectorSize = iSectorSize;
}else{
g.iSectorSize = 512;
}
}
#endif

View File

@@ -1,335 +0,0 @@
/*
** 2013 Jan 11
**
** 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.
**
*************************************************************************
** Code for testing the virtual table interfaces. This code
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** The FS virtual table is created as follows:
**
** CREATE VIRTUAL TABLE tbl USING fs(idx);
**
** where idx is the name of a table in the db with 2 columns. The virtual
** table also has two columns - file path and file contents.
**
** The first column of table idx must be an IPK, and the second contains file
** paths. For example:
**
** CREATE TABLE idx(id INTEGER PRIMARY KEY, path TEXT);
** INSERT INTO idx VALUES(4, '/etc/passwd');
**
** Adding the row to the idx table automatically creates a row in the
** virtual table with rowid=4, path=/etc/passwd and a text field that
** contains data read from file /etc/passwd on disk.
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <io.h>
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
typedef struct fs_vtab fs_vtab;
typedef struct fs_cursor fs_cursor;
/*
** A fs virtual-table object
*/
struct fs_vtab {
sqlite3_vtab base;
sqlite3 *db;
char *zDb; /* Name of db containing zTbl */
char *zTbl; /* Name of docid->file map table */
};
/* A fs cursor object */
struct fs_cursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt;
char *zBuf;
int nBuf;
int nAlloc;
};
/*
** This function is the implementation of both the xConnect and xCreate
** methods of the fs virtual table.
**
** The argv[] array contains the following:
**
** argv[0] -> module name ("fs")
** argv[1] -> database name
** argv[2] -> table name
** argv[...] -> other module argument fields.
*/
static int fsConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
fs_vtab *pVtab;
int nByte;
const char *zTbl;
const char *zDb = argv[1];
if( argc!=4 ){
*pzErr = sqlite3_mprintf("wrong number of arguments");
return SQLITE_ERROR;
}
zTbl = argv[3];
nByte = sizeof(fs_vtab) + (int)strlen(zTbl) + 1 + (int)strlen(zDb) + 1;
pVtab = (fs_vtab *)sqlite3MallocZero( nByte );
if( !pVtab ) return SQLITE_NOMEM;
pVtab->zTbl = (char *)&pVtab[1];
pVtab->zDb = &pVtab->zTbl[strlen(zTbl)+1];
pVtab->db = db;
memcpy(pVtab->zTbl, zTbl, strlen(zTbl));
memcpy(pVtab->zDb, zDb, strlen(zDb));
*ppVtab = &pVtab->base;
sqlite3_declare_vtab(db, "CREATE TABLE xyz(path TEXT, data TEXT)");
return SQLITE_OK;
}
/* Note that for this virtual table, the xCreate and xConnect
** methods are identical. */
static int fsDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/* The xDisconnect and xDestroy methods are also the same */
/*
** Open a new fs cursor.
*/
static int fsOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
fs_cursor *pCur;
pCur = sqlite3MallocZero(sizeof(fs_cursor));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Close a fs cursor.
*/
static int fsClose(sqlite3_vtab_cursor *cur){
fs_cursor *pCur = (fs_cursor *)cur;
sqlite3_finalize(pCur->pStmt);
sqlite3_free(pCur->zBuf);
sqlite3_free(pCur);
return SQLITE_OK;
}
static int fsNext(sqlite3_vtab_cursor *cur){
fs_cursor *pCur = (fs_cursor *)cur;
int rc;
rc = sqlite3_step(pCur->pStmt);
if( rc==SQLITE_ROW || rc==SQLITE_DONE ) rc = SQLITE_OK;
return rc;
}
static int fsFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
int rc;
fs_cursor *pCur = (fs_cursor *)pVtabCursor;
fs_vtab *p = (fs_vtab *)(pVtabCursor->pVtab);
assert( (idxNum==0 && argc==0) || (idxNum==1 && argc==1) );
if( idxNum==1 ){
char *zStmt = sqlite3_mprintf(
"SELECT * FROM %Q.%Q WHERE rowid=?", p->zDb, p->zTbl);
if( !zStmt ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(p->db, zStmt, -1, &pCur->pStmt, 0);
sqlite3_free(zStmt);
if( rc==SQLITE_OK ){
sqlite3_bind_value(pCur->pStmt, 1, argv[0]);
}
}else{
char *zStmt = sqlite3_mprintf("SELECT * FROM %Q.%Q", p->zDb, p->zTbl);
if( !zStmt ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(p->db, zStmt, -1, &pCur->pStmt, 0);
sqlite3_free(zStmt);
}
if( rc==SQLITE_OK ){
rc = fsNext(pVtabCursor);
}
return rc;
}
static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
fs_cursor *pCur = (fs_cursor*)cur;
assert( i==0 || i==1 );
if( i==0 ){
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pStmt, 0));
}else{
const char *zFile = (const char *)sqlite3_column_text(pCur->pStmt, 1);
struct stat sbuf;
int fd;
int n;
fd = open(zFile, O_RDONLY);
if( fd<0 ) return SQLITE_IOERR;
fstat(fd, &sbuf);
if( sbuf.st_size>=pCur->nAlloc ){
int nNew = sbuf.st_size*2;
char *zNew;
if( nNew<1024 ) nNew = 1024;
zNew = sqlite3Realloc(pCur->zBuf, nNew);
if( zNew==0 ){
close(fd);
return SQLITE_NOMEM;
}
pCur->zBuf = zNew;
pCur->nAlloc = nNew;
}
n = (int)read(fd, pCur->zBuf, sbuf.st_size);
close(fd);
if( n!=sbuf.st_size ) return SQLITE_ERROR;
pCur->nBuf = sbuf.st_size;
pCur->zBuf[pCur->nBuf] = '\0';
sqlite3_result_text(ctx, pCur->zBuf, -1, SQLITE_TRANSIENT);
}
return SQLITE_OK;
}
static int fsRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
fs_cursor *pCur = (fs_cursor*)cur;
*pRowid = sqlite3_column_int64(pCur->pStmt, 0);
return SQLITE_OK;
}
static int fsEof(sqlite3_vtab_cursor *cur){
fs_cursor *pCur = (fs_cursor*)cur;
return (sqlite3_data_count(pCur->pStmt)==0);
}
static int fsBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int ii;
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
if( pCons->iColumn<0 && pCons->usable
&& pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 0;
pUsage->argvIndex = 1;
pIdxInfo->idxNum = 1;
pIdxInfo->estimatedCost = 1.0;
break;
}
}
return SQLITE_OK;
}
/*
** A virtual table module that provides read-only access to a
** Tcl global variable namespace.
*/
static sqlite3_module fsModule = {
0, /* iVersion */
fsConnect,
fsConnect,
fsBestIndex,
fsDisconnect,
fsDisconnect,
fsOpen, /* xOpen - open a cursor */
fsClose, /* xClose - close a cursor */
fsFilter, /* xFilter - configure scan constraints */
fsNext, /* xNext - advance a cursor */
fsEof, /* xEof - check for end of scan */
fsColumn, /* xColumn - read data */
fsRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
/*
** Decode a pointer to an sqlite3 object.
*/
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
/*
** Register the echo virtual table module.
*/
static int register_fs_module(
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 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "fs", &fsModule, (void *)interp);
#endif
return TCL_OK;
}
#endif
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetestfs_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "register_fs_module", register_fs_module, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
#endif
return TCL_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,388 +0,0 @@
/*
** 2007 April 6
**
** 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.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces. This code
** implements TCL commands for reading and writing the binary
** database files and displaying the content of those files as
** hexadecimal. We could, in theory, use the built-in "binary"
** command of TCL to do a lot of this, but there are some issues
** with historical versions of the "binary" command. So it seems
** easier and safer to build our own mechanism.
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/*
** Convert binary to hex. The input zBuf[] contains N bytes of
** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[]
** with a hexadecimal representation of its original binary input.
*/
void sqlite3TestBinToHex(unsigned char *zBuf, int N){
const unsigned char zHex[] = "0123456789ABCDEF";
int i, j;
unsigned char c;
i = N*2;
zBuf[i--] = 0;
for(j=N-1; j>=0; j--){
c = zBuf[j];
zBuf[i--] = zHex[c&0xf];
zBuf[i--] = zHex[c>>4];
}
assert( i==-1 );
}
/*
** Convert hex to binary. The input zIn[] contains N bytes of
** hexadecimal. Convert this into binary and write aOut[] with
** the binary data. Spaces in the original input are ignored.
** Return the number of bytes of binary rendered.
*/
int sqlite3TestHexToBin(const unsigned char *zIn, int N, unsigned char *aOut){
const unsigned char aMap[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0,
0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int i, j;
int hi=1;
unsigned char c;
for(i=j=0; i<N; i++){
c = aMap[zIn[i]];
if( c==0 ) continue;
if( hi ){
aOut[j] = (c-1)<<4;
hi = 0;
}else{
aOut[j++] |= c-1;
hi = 1;
}
}
return j;
}
/*
** Usage: hexio_read FILENAME OFFSET AMT
**
** Read AMT bytes from file FILENAME beginning at OFFSET from the
** beginning of the file. Convert that information to hexadecimal
** and return the resulting HEX string.
*/
static int hexio_read(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int offset;
int amt, got;
const char *zFile;
unsigned char *zBuf;
FILE *in;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET AMT");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &amt) ) return TCL_ERROR;
zFile = Tcl_GetString(objv[1]);
zBuf = sqlite3_malloc( amt*2+1 );
if( zBuf==0 ){
return TCL_ERROR;
}
in = fopen(zFile, "rb");
if( in==0 ){
in = fopen(zFile, "r");
}
if( in==0 ){
Tcl_AppendResult(interp, "cannot open input file ", zFile, 0);
return TCL_ERROR;
}
fseek(in, offset, SEEK_SET);
got = (int)fread(zBuf, 1, amt, in);
fclose(in);
if( got<0 ){
got = 0;
}
sqlite3TestBinToHex(zBuf, got);
Tcl_AppendResult(interp, zBuf, 0);
sqlite3_free(zBuf);
return TCL_OK;
}
/*
** Usage: hexio_write FILENAME OFFSET DATA
**
** Write DATA into file FILENAME beginning at OFFSET from the
** beginning of the file. DATA is expressed in hexadecimal.
*/
static int hexio_write(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int offset;
int nIn, nOut, written;
const char *zFile;
const unsigned char *zIn;
unsigned char *aOut;
FILE *out;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
zFile = Tcl_GetString(objv[1]);
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn);
aOut = sqlite3_malloc( nIn/2 );
if( aOut==0 ){
return TCL_ERROR;
}
nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
out = fopen(zFile, "r+b");
if( out==0 ){
out = fopen(zFile, "r+");
}
if( out==0 ){
Tcl_AppendResult(interp, "cannot open output file ", zFile, 0);
return TCL_ERROR;
}
fseek(out, offset, SEEK_SET);
written = (int)fwrite(aOut, 1, nOut, out);
sqlite3_free(aOut);
fclose(out);
Tcl_SetObjResult(interp, Tcl_NewIntObj(written));
return TCL_OK;
}
/*
** USAGE: hexio_get_int HEXDATA
**
** Interpret the HEXDATA argument as a big-endian integer. Return
** the value of that integer. HEXDATA can contain between 2 and 8
** hexadecimal digits.
*/
static int hexio_get_int(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int val;
int nIn, nOut;
const unsigned char *zIn;
unsigned char *aOut;
unsigned char aNum[4];
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA");
return TCL_ERROR;
}
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
aOut = sqlite3_malloc( nIn/2 );
if( aOut==0 ){
return TCL_ERROR;
}
nOut = sqlite3TestHexToBin(zIn, nIn, aOut);
if( nOut>=4 ){
memcpy(aNum, aOut, 4);
}else{
memset(aNum, 0, sizeof(aNum));
memcpy(&aNum[4-nOut], aOut, nOut);
}
sqlite3_free(aOut);
val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3];
Tcl_SetObjResult(interp, Tcl_NewIntObj(val));
return TCL_OK;
}
/*
** USAGE: hexio_render_int16 INTEGER
**
** Render INTEGER has a 16-bit big-endian integer in hexadecimal.
*/
static int hexio_render_int16(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int val;
unsigned char aNum[10];
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "INTEGER");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR;
aNum[0] = val>>8;
aNum[1] = val;
sqlite3TestBinToHex(aNum, 2);
Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 4));
return TCL_OK;
}
/*
** USAGE: hexio_render_int32 INTEGER
**
** Render INTEGER has a 32-bit big-endian integer in hexadecimal.
*/
static int hexio_render_int32(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int val;
unsigned char aNum[10];
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "INTEGER");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR;
aNum[0] = val>>24;
aNum[1] = val>>16;
aNum[2] = val>>8;
aNum[3] = val;
sqlite3TestBinToHex(aNum, 4);
Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 8));
return TCL_OK;
}
/*
** USAGE: utf8_to_utf8 HEX
**
** The argument is a UTF8 string represented in hexadecimal.
** The UTF8 might not be well-formed. Run this string through
** sqlite3Utf8to8() convert it back to hex and return the result.
*/
static int utf8_to_utf8(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#ifdef SQLITE_DEBUG
int n;
int nOut;
const unsigned char *zOrig;
unsigned char *z;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HEX");
return TCL_ERROR;
}
zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
z = sqlite3_malloc( n+3 );
n = sqlite3TestHexToBin(zOrig, n, z);
z[n] = 0;
nOut = sqlite3Utf8To8(z);
sqlite3TestBinToHex(z,nOut);
Tcl_AppendResult(interp, (char*)z, 0);
sqlite3_free(z);
return TCL_OK;
#else
Tcl_AppendResult(interp,
"[utf8_to_utf8] unavailable - SQLITE_DEBUG not defined", 0
);
return TCL_ERROR;
#endif
}
static int getFts3Varint(const char *p, sqlite_int64 *v){
const unsigned char *q = (const unsigned char *) p;
sqlite_uint64 x = 0, y = 1;
while( (*q & 0x80) == 0x80 ){
x += y * (*q++ & 0x7f);
y <<= 7;
}
x += y * (*q++);
*v = (sqlite_int64) x;
return (int) (q - (unsigned char *)p);
}
/*
** USAGE: read_fts3varint BLOB VARNAME
**
** Read a varint from the start of BLOB. Set variable VARNAME to contain
** the interpreted value. Return the number of bytes of BLOB consumed.
*/
static int read_fts3varint(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int nBlob;
unsigned char *zBlob;
sqlite3_int64 iVal;
int nVal;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "BLOB VARNAME");
return TCL_ERROR;
}
zBlob = Tcl_GetByteArrayFromObj(objv[1], &nBlob);
nVal = getFts3Varint((char*)zBlob, (sqlite3_int64 *)(&iVal));
Tcl_ObjSetVar2(interp, objv[2], 0, Tcl_NewWideIntObj(iVal), 0);
Tcl_SetObjResult(interp, Tcl_NewIntObj(nVal));
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_hexio_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aObjCmd[] = {
{ "hexio_read", hexio_read },
{ "hexio_write", hexio_write },
{ "hexio_get_int", hexio_get_int },
{ "hexio_render_int16", hexio_render_int16 },
{ "hexio_render_int32", hexio_render_int32 },
{ "utf8_to_utf8", utf8_to_utf8 },
{ "read_fts3varint", read_fts3varint },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
}
return TCL_OK;
}

View File

@@ -1,291 +0,0 @@
/*
** 2009 August 17
**
** 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.
**
*************************************************************************
**
** The code in this file is used for testing SQLite. It is not part of
** the source code used in production systems.
**
** Specifically, this file tests the effect of errors while initializing
** the various pluggable sub-systems from within sqlite3_initialize().
** If an error occurs in sqlite3_initialize() the following should be
** true:
**
** 1) An error code is returned to the user, and
** 2) A subsequent call to sqlite3_shutdown() calls the shutdown method
** of those subsystems that were initialized, and
** 3) A subsequent call to sqlite3_initialize() attempts to initialize
** the remaining, uninitialized, subsystems.
*/
#include "sqliteInt.h"
#include <string.h>
#include <tcl.h>
static struct Wrapped {
sqlite3_pcache_methods2 pcache;
sqlite3_mem_methods mem;
sqlite3_mutex_methods mutex;
int mem_init; /* True if mem subsystem is initalized */
int mem_fail; /* True to fail mem subsystem inialization */
int mutex_init; /* True if mutex subsystem is initalized */
int mutex_fail; /* True to fail mutex subsystem inialization */
int pcache_init; /* True if pcache subsystem is initalized */
int pcache_fail; /* True to fail pcache subsystem inialization */
} wrapped;
static int wrMemInit(void *pAppData){
int rc;
if( wrapped.mem_fail ){
rc = SQLITE_ERROR;
}else{
rc = wrapped.mem.xInit(wrapped.mem.pAppData);
}
if( rc==SQLITE_OK ){
wrapped.mem_init = 1;
}
return rc;
}
static void wrMemShutdown(void *pAppData){
wrapped.mem.xShutdown(wrapped.mem.pAppData);
wrapped.mem_init = 0;
}
static void *wrMemMalloc(int n) {return wrapped.mem.xMalloc(n);}
static void wrMemFree(void *p) {wrapped.mem.xFree(p);}
static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
static int wrMemSize(void *p) {return wrapped.mem.xSize(p);}
static int wrMemRoundup(int n) {return wrapped.mem.xRoundup(n);}
static int wrMutexInit(void){
int rc;
if( wrapped.mutex_fail ){
rc = SQLITE_ERROR;
}else{
rc = wrapped.mutex.xMutexInit();
}
if( rc==SQLITE_OK ){
wrapped.mutex_init = 1;
}
return rc;
}
static int wrMutexEnd(void){
wrapped.mutex.xMutexEnd();
wrapped.mutex_init = 0;
return SQLITE_OK;
}
static sqlite3_mutex *wrMutexAlloc(int e){
return wrapped.mutex.xMutexAlloc(e);
}
static void wrMutexFree(sqlite3_mutex *p){
wrapped.mutex.xMutexFree(p);
}
static void wrMutexEnter(sqlite3_mutex *p){
wrapped.mutex.xMutexEnter(p);
}
static int wrMutexTry(sqlite3_mutex *p){
return wrapped.mutex.xMutexTry(p);
}
static void wrMutexLeave(sqlite3_mutex *p){
wrapped.mutex.xMutexLeave(p);
}
static int wrMutexHeld(sqlite3_mutex *p){
return wrapped.mutex.xMutexHeld(p);
}
static int wrMutexNotheld(sqlite3_mutex *p){
return wrapped.mutex.xMutexNotheld(p);
}
static int wrPCacheInit(void *pArg){
int rc;
if( wrapped.pcache_fail ){
rc = SQLITE_ERROR;
}else{
rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
}
if( rc==SQLITE_OK ){
wrapped.pcache_init = 1;
}
return rc;
}
static void wrPCacheShutdown(void *pArg){
wrapped.pcache.xShutdown(wrapped.pcache.pArg);
wrapped.pcache_init = 0;
}
static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
return wrapped.pcache.xCreate(a, b, c);
}
static void wrPCacheCachesize(sqlite3_pcache *p, int n){
wrapped.pcache.xCachesize(p, n);
}
static int wrPCachePagecount(sqlite3_pcache *p){
return wrapped.pcache.xPagecount(p);
}
static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
return wrapped.pcache.xFetch(p, a, b);
}
static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
wrapped.pcache.xUnpin(p, a, b);
}
static void wrPCacheRekey(
sqlite3_pcache *p,
sqlite3_pcache_page *a,
unsigned b,
unsigned c
){
wrapped.pcache.xRekey(p, a, b, c);
}
static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
wrapped.pcache.xTruncate(p, a);
}
static void wrPCacheDestroy(sqlite3_pcache *p){
wrapped.pcache.xDestroy(p);
}
static void installInitWrappers(void){
sqlite3_mutex_methods mutexmethods = {
wrMutexInit, wrMutexEnd, wrMutexAlloc,
wrMutexFree, wrMutexEnter, wrMutexTry,
wrMutexLeave, wrMutexHeld, wrMutexNotheld
};
sqlite3_pcache_methods2 pcachemethods = {
1, 0,
wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
wrPCacheDestroy
};
sqlite3_mem_methods memmethods = {
wrMemMalloc, wrMemFree, wrMemRealloc,
wrMemSize, wrMemRoundup, wrMemInit,
wrMemShutdown,
0
};
memset(&wrapped, 0, sizeof(wrapped));
sqlite3_shutdown();
sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
}
static int init_wrapper_install(
ClientData clientData, /* Unused */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int i;
installInitWrappers();
for(i=1; i<objc; i++){
char *z = Tcl_GetString(objv[i]);
if( strcmp(z, "mem")==0 ){
wrapped.mem_fail = 1;
}else if( strcmp(z, "mutex")==0 ){
wrapped.mutex_fail = 1;
}else if( strcmp(z, "pcache")==0 ){
wrapped.pcache_fail = 1;
}else{
Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
return TCL_ERROR;
}
}
return TCL_OK;
}
static int init_wrapper_uninstall(
ClientData clientData, /* Unused */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
sqlite3_shutdown();
sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
return TCL_OK;
}
static int init_wrapper_clear(
ClientData clientData, /* Unused */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
wrapped.mem_fail = 0;
wrapped.mutex_fail = 0;
wrapped.pcache_fail = 0;
return TCL_OK;
}
static int init_wrapper_query(
ClientData clientData, /* Unused */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
Tcl_Obj *pRet;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
pRet = Tcl_NewObj();
if( wrapped.mutex_init ){
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
}
if( wrapped.mem_init ){
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
}
if( wrapped.pcache_init ){
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
}
Tcl_SetObjResult(interp, pRet);
return TCL_OK;
}
int Sqlitetest_init_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aObjCmd[] = {
{"init_wrapper_install", init_wrapper_install},
{"init_wrapper_query", init_wrapper_query },
{"init_wrapper_uninstall", init_wrapper_uninstall},
{"init_wrapper_clear", init_wrapper_clear}
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
}
return TCL_OK;
}

View File

@@ -1,382 +0,0 @@
/*
** 2009 November 10
**
** 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 a read-only VIRTUAL TABLE that contains the
** content of a C-language array of integer values. See the corresponding
** header file for full details.
*/
#include "test_intarray.h"
#include <string.h>
#include <assert.h>
/*
** Definition of the sqlite3_intarray object.
**
** The internal representation of an intarray object is subject
** to change, is not externally visible, and should be used by
** the implementation of intarray only. This object is opaque
** to users.
*/
struct sqlite3_intarray {
int n; /* Number of elements in the array */
sqlite3_int64 *a; /* Contents of the array */
void (*xFree)(void*); /* Function used to free a[] */
};
/* Objects used internally by the virtual table implementation */
typedef struct intarray_vtab intarray_vtab;
typedef struct intarray_cursor intarray_cursor;
/* A intarray table object */
struct intarray_vtab {
sqlite3_vtab base; /* Base class */
sqlite3_intarray *pContent; /* Content of the integer array */
};
/* A intarray cursor object */
struct intarray_cursor {
sqlite3_vtab_cursor base; /* Base class */
int i; /* Current cursor position */
};
/*
** None of this works unless we have virtual tables.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Free an sqlite3_intarray object.
*/
static void intarrayFree(sqlite3_intarray *p){
if( p->xFree ){
p->xFree(p->a);
}
sqlite3_free(p);
}
/*
** Table destructor for the intarray module.
*/
static int intarrayDestroy(sqlite3_vtab *p){
intarray_vtab *pVtab = (intarray_vtab*)p;
sqlite3_free(pVtab);
return 0;
}
/*
** Table constructor for the intarray module.
*/
static int intarrayCreate(
sqlite3 *db, /* Database where module is created */
void *pAux, /* clientdata for the module */
int argc, /* Number of arguments */
const char *const*argv, /* Value for all arguments */
sqlite3_vtab **ppVtab, /* Write the new virtual table object here */
char **pzErr /* Put error message text here */
){
int rc = SQLITE_NOMEM;
intarray_vtab *pVtab = sqlite3_malloc(sizeof(intarray_vtab));
if( pVtab ){
memset(pVtab, 0, sizeof(intarray_vtab));
pVtab->pContent = (sqlite3_intarray*)pAux;
rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)");
}
*ppVtab = (sqlite3_vtab *)pVtab;
return rc;
}
/*
** Open a new cursor on the intarray table.
*/
static int intarrayOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_NOMEM;
intarray_cursor *pCur;
pCur = sqlite3_malloc(sizeof(intarray_cursor));
if( pCur ){
memset(pCur, 0, sizeof(intarray_cursor));
*ppCursor = (sqlite3_vtab_cursor *)pCur;
rc = SQLITE_OK;
}
return rc;
}
/*
** Close a intarray table cursor.
*/
static int intarrayClose(sqlite3_vtab_cursor *cur){
intarray_cursor *pCur = (intarray_cursor *)cur;
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Retrieve a column of data.
*/
static int intarrayColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
intarray_cursor *pCur = (intarray_cursor*)cur;
intarray_vtab *pVtab = (intarray_vtab*)cur->pVtab;
if( pCur->i>=0 && pCur->i<pVtab->pContent->n ){
sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);
}
return SQLITE_OK;
}
/*
** Retrieve the current rowid.
*/
static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
intarray_cursor *pCur = (intarray_cursor *)cur;
*pRowid = pCur->i;
return SQLITE_OK;
}
static int intarrayEof(sqlite3_vtab_cursor *cur){
intarray_cursor *pCur = (intarray_cursor *)cur;
intarray_vtab *pVtab = (intarray_vtab *)cur->pVtab;
return pCur->i>=pVtab->pContent->n;
}
/*
** Advance the cursor to the next row.
*/
static int intarrayNext(sqlite3_vtab_cursor *cur){
intarray_cursor *pCur = (intarray_cursor *)cur;
pCur->i++;
return SQLITE_OK;
}
/*
** Reset a intarray table cursor.
*/
static int intarrayFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
pCur->i = 0;
return SQLITE_OK;
}
/*
** Analyse the WHERE condition.
*/
static int intarrayBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_OK;
}
/*
** A virtual table module that merely echos method calls into TCL
** variables.
*/
static sqlite3_module intarrayModule = {
0, /* iVersion */
intarrayCreate, /* xCreate - create a new virtual table */
intarrayCreate, /* xConnect - connect to an existing vtab */
intarrayBestIndex, /* xBestIndex - find the best query index */
intarrayDestroy, /* xDisconnect - disconnect a vtab */
intarrayDestroy, /* xDestroy - destroy a vtab */
intarrayOpen, /* xOpen - open a cursor */
intarrayClose, /* xClose - close a cursor */
intarrayFilter, /* xFilter - configure scan constraints */
intarrayNext, /* xNext - advance a cursor */
intarrayEof, /* xEof */
intarrayColumn, /* xColumn - read data */
intarrayRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
/*
** Invoke this routine to create a specific instance of an intarray object.
** The new intarray object is returned by the 3rd parameter.
**
** Each intarray object corresponds to a virtual table in the TEMP table
** with a name of zName.
**
** Destroy the intarray object by dropping the virtual table. If not done
** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
sqlite3 *db,
const char *zName,
sqlite3_intarray **ppReturn
){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_intarray *p;
*ppReturn = p = sqlite3_malloc( sizeof(*p) );
if( p==0 ){
return SQLITE_NOMEM;
}
memset(p, 0, sizeof(*p));
rc = sqlite3_create_module_v2(db, zName, &intarrayModule, p,
(void(*)(void*))intarrayFree);
if( rc==SQLITE_OK ){
char *zSql;
zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE temp.%Q USING %Q",
zName, zName);
rc = sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
#endif
return rc;
}
/*
** Bind a new array array of integers to a specific intarray object.
**
** The array of integers bound must be unchanged for the duration of
** any query against the corresponding virtual table. If the integer
** array does change or is deallocated undefined behavior will result.
*/
int sqlite3_intarray_bind(
sqlite3_intarray *pIntArray, /* The intarray object to bind to */
int nElements, /* Number of elements in the intarray */
sqlite3_int64 *aElements, /* Content of the intarray */
void (*xFree)(void*) /* How to dispose of the intarray when done */
){
if( pIntArray->xFree ){
pIntArray->xFree(pIntArray->a);
}
pIntArray->n = nElements;
pIntArray->a = aElements;
pIntArray->xFree = xFree;
return SQLITE_OK;
}
/*****************************************************************************
** Everything below is interface for testing this module.
*/
#ifdef SQLITE_TEST
#include <tcl.h>
/*
** Routines to encode and decode pointers
*/
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern void *sqlite3TestTextToPtr(const char*);
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char *zPtr, void*);
extern const char *sqlite3ErrName(int);
/*
** sqlite3_intarray_create DB NAME
**
** Invoke the sqlite3_intarray_create interface. A string that becomes
** the first parameter to sqlite3_intarray_bind.
*/
static int test_intarray_create(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zName;
sqlite3_intarray *pArray;
int rc = SQLITE_OK;
char zPtr[100];
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zName = Tcl_GetString(objv[2]);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_intarray_create(db, zName, &pArray);
#endif
if( rc!=SQLITE_OK ){
assert( pArray==0 );
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
return TCL_ERROR;
}
sqlite3TestMakePointerStr(interp, zPtr, pArray);
Tcl_AppendResult(interp, zPtr, (char*)0);
return TCL_OK;
}
/*
** sqlite3_intarray_bind INTARRAY ?VALUE ...?
**
** Invoke the sqlite3_intarray_bind interface on the given array of integers.
*/
static int test_intarray_bind(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_intarray *pArray;
int rc = SQLITE_OK;
int i, n;
sqlite3_int64 *a;
if( objc<2 ){
Tcl_WrongNumArgs(interp, 1, objv, "INTARRAY");
return TCL_ERROR;
}
pArray = (sqlite3_intarray*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
n = objc - 2;
#ifndef SQLITE_OMIT_VIRTUALTABLE
a = sqlite3_malloc( sizeof(a[0])*n );
if( a==0 ){
Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);
return TCL_ERROR;
}
for(i=0; i<n; i++){
Tcl_WideInt x = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &x);
a[i] = x;
}
rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
return TCL_ERROR;
}
#endif
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetestintarray_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "sqlite3_intarray_create", test_intarray_create, 0 },
{ "sqlite3_intarray_bind", test_intarray_bind, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
return TCL_OK;
}
#endif /* SQLITE_TEST */

View File

@@ -1,128 +0,0 @@
/*
** 2009 November 10
**
** 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 is the C-language interface definition for the "intarray" or
** integer array virtual table for SQLite.
**
** The intarray virtual table is designed to facilitate using an
** array of integers as the right-hand side of an IN operator. So
** instead of doing a prepared statement like this:
**
** SELECT * FROM table WHERE x IN (?,?,?,...,?);
**
** And then binding indivdual integers to each of ? slots, a C-language
** application can create an intarray object (named "ex1" in the following
** example), prepare a statement like this:
**
** SELECT * FROM table WHERE x IN ex1;
**
** Then bind an ordinary C/C++ array of integer values to the ex1 object
** to run the statement.
**
** USAGE:
**
** One or more intarray objects can be created as follows:
**
** sqlite3_intarray *p1, *p2, *p3;
** sqlite3_intarray_create(db, "ex1", &p1);
** sqlite3_intarray_create(db, "ex2", &p2);
** sqlite3_intarray_create(db, "ex3", &p3);
**
** Each call to sqlite3_intarray_create() generates a new virtual table
** module and a singleton of that virtual table module in the TEMP
** database. Both the module and the virtual table instance use the
** name given by the second parameter. The virtual tables can then be
** used in prepared statements:
**
** SELECT * FROM t1, t2, t3
** WHERE t1.x IN ex1
** AND t2.y IN ex2
** AND t3.z IN ex3;
**
** Each integer array is initially empty. New arrays can be bound to
** an integer array as follows:
**
** sqlite3_int64 a1[] = { 1, 2, 3, 4 };
** sqlite3_int64 a2[] = { 5, 6, 7, 8, 9, 10, 11 };
** sqlite3_int64 *a3 = sqlite3_malloc( 100*sizeof(sqlite3_int64) );
** // Fill in content of a3[]
** sqlite3_intarray_bind(p1, 4, a1, 0);
** sqlite3_intarray_bind(p2, 7, a2, 0);
** sqlite3_intarray_bind(p3, 100, a3, sqlite3_free);
**
** A single intarray object can be rebound multiple times. But do not
** attempt to change the bindings of an intarray while it is in the middle
** of a query.
**
** The array that holds the integers is automatically freed by the function
** in the fourth parameter to sqlite3_intarray_bind() when the array is no
** longer needed. The application must not change the intarray values
** while an intarray is in the middle of a query.
**
** The intarray object is automatically destroyed when its corresponding
** virtual table is dropped. Since the virtual tables are created in the
** TEMP database, they are automatically dropped when the database connection
** closes so the application does not normally need to take any special
** action to free the intarray objects.
*/
#include "sqlite3.h"
#ifndef _INTARRAY_H_
#define _INTARRAY_H_
/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
** An sqlite3_intarray is an abstract type to stores an instance of
** an integer array.
*/
typedef struct sqlite3_intarray sqlite3_intarray;
/*
** Invoke this routine to create a specific instance of an intarray object.
** The new intarray object is returned by the 3rd parameter.
**
** Each intarray object corresponds to a virtual table in the TEMP table
** with a name of zName.
**
** Destroy the intarray object by dropping the virtual table. If not done
** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
sqlite3 *db,
const char *zName,
sqlite3_intarray **ppReturn
);
/*
** Bind a new array array of integers to a specific intarray object.
**
** The array of integers bound must be unchanged for the duration of
** any query against the corresponding virtual table. If the integer
** array does change or is deallocated undefined behavior will result.
*/
int sqlite3_intarray_bind(
sqlite3_intarray *pIntArray, /* The intarray object to bind to */
int nElements, /* Number of elements in the intarray */
sqlite3_int64 *aElements, /* Content of the intarray */
void (*xFree)(void*) /* How to dispose of the intarray when done */
);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
#endif /* _INTARRAY_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,122 +0,0 @@
/*
** 2006 June 14
**
** 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.
**
*************************************************************************
** Test extension for testing the sqlite3_load_extension() function.
*/
#include <string.h>
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
/*
** The half() SQL function returns half of its input value.
*/
static void halfFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0]));
}
/*
** SQL functions to call the sqlite3_status function and return results.
*/
static void statusFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int op, mx, cur, resetFlag, rc;
if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
op = sqlite3_value_int(argv[0]);
}else if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
int i;
const char *zName;
static const struct {
const char *zName;
int op;
} aOp[] = {
{ "MEMORY_USED", SQLITE_STATUS_MEMORY_USED },
{ "PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED },
{ "PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW },
{ "SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED },
{ "SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW },
{ "MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE },
};
int nOp = sizeof(aOp)/sizeof(aOp[0]);
zName = (const char*)sqlite3_value_text(argv[0]);
for(i=0; i<nOp; i++){
if( strcmp(aOp[i].zName, zName)==0 ){
op = aOp[i].op;
break;
}
}
if( i>=nOp ){
char *zMsg = sqlite3_mprintf("unknown status property: %s", zName);
sqlite3_result_error(context, zMsg, -1);
sqlite3_free(zMsg);
return;
}
}else{
sqlite3_result_error(context, "unknown status type", -1);
return;
}
if( argc==2 ){
resetFlag = sqlite3_value_int(argv[1]);
}else{
resetFlag = 0;
}
rc = sqlite3_status(op, &cur, &mx, resetFlag);
if( rc!=SQLITE_OK ){
char *zMsg = sqlite3_mprintf("sqlite3_status(%d,...) returns %d", op, rc);
sqlite3_result_error(context, zMsg, -1);
sqlite3_free(zMsg);
return;
}
if( argc==2 ){
sqlite3_result_int(context, mx);
}else{
sqlite3_result_int(context, cur);
}
}
/*
** Extension load function.
*/
int testloadext_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int nErr = 0;
SQLITE_EXTENSION_INIT2(pApi);
nErr |= sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0);
nErr |= sqlite3_create_function(db, "sqlite3_status", 1, SQLITE_ANY, 0,
statusFunc, 0, 0);
nErr |= sqlite3_create_function(db, "sqlite3_status", 2, SQLITE_ANY, 0,
statusFunc, 0, 0);
return nErr ? SQLITE_ERROR : SQLITE_OK;
}
/*
** Another extension entry point. This one always fails.
*/
int testbrokenext_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
char *zErr;
SQLITE_EXTENSION_INIT2(pApi);
zErr = sqlite3_mprintf("broken!");
*pzErrMsg = zErr;
return 1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,99 +0,0 @@
/*
** 2011 March 18
**
** 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 a VFS "shim" - a layer that sits in between the
** pager and the real VFS.
**
** This particular shim enforces a multiplex system on DB files.
** This shim shards/partitions a single DB file into smaller
** "chunks" such that the total DB file size may exceed the maximum
** file size of the underlying file system.
**
*/
#ifndef _TEST_MULTIPLEX_H
#define _TEST_MULTIPLEX_H
/*
** CAPI: File-control Operations Supported by Multiplex VFS
**
** Values interpreted by the xFileControl method of a Multiplex VFS db file-handle.
**
** MULTIPLEX_CTRL_ENABLE:
** This file control is used to enable or disable the multiplex
** shim.
**
** MULTIPLEX_CTRL_SET_CHUNK_SIZE:
** This file control is used to set the maximum allowed chunk
** size for a multiplex file set. The chunk size should be
** a multiple of SQLITE_MAX_PAGE_SIZE, and will be rounded up
** if not.
**
** MULTIPLEX_CTRL_SET_MAX_CHUNKS:
** This file control is used to set the maximum number of chunks
** allowed to be used for a mutliplex file set.
*/
#define MULTIPLEX_CTRL_ENABLE 214014
#define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015
#define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016
#ifdef __cplusplus
extern "C" {
#endif
/*
** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
**
** Use the VFS named zOrigVfsName as the VFS that does the actual work.
** Use the default if zOrigVfsName==NULL.
**
** The multiplex VFS shim is named "multiplex". It will become the default
** VFS if makeDefault is non-zero.
**
** An auto-extension is registered which will make the function
** multiplex_control() available to database connections. This
** function gives access to the xFileControl interface of the
** multiplex VFS shim.
**
** SELECT multiplex_control(<op>,<val>);
**
** <op>=1 MULTIPLEX_CTRL_ENABLE
** <val>=0 disable
** <val>=1 enable
**
** <op>=2 MULTIPLEX_CTRL_SET_CHUNK_SIZE
** <val> int, chunk size
**
** <op>=3 MULTIPLEX_CTRL_SET_MAX_CHUNKS
** <val> int, max chunks
**
** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
** during start-up.
*/
extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault);
/*
** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
**
** All SQLite database connections must be closed before calling this
** routine.
**
** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
** shutting down in order to free all remaining multiplex groups.
*/
extern int sqlite3_multiplex_shutdown(void);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
#endif /* _TEST_MULTIPLEX_H */

View File

@@ -1,439 +0,0 @@
/*
** 2008 June 18
**
** 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 test logic for the sqlite3_mutex interfaces.
*/
#include "tcl.h"
#include "sqlite3.h"
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/* defined in main.c */
extern const char *sqlite3ErrName(int);
/* A countable mutex */
struct sqlite3_mutex {
sqlite3_mutex *pReal;
int eType;
};
/* State variables */
static struct test_mutex_globals {
int isInstalled; /* True if installed */
int disableInit; /* True to cause sqlite3_initalize() to fail */
int disableTry; /* True to force sqlite3_mutex_try() to fail */
int isInit; /* True if initialized */
sqlite3_mutex_methods m; /* Interface to "real" mutex system */
int aCounter[8]; /* Number of grabs of each type of mutex */
sqlite3_mutex aStatic[6]; /* The six static mutexes */
} g = {0};
/* Return true if the countable mutex is currently held */
static int counterMutexHeld(sqlite3_mutex *p){
return g.m.xMutexHeld(p->pReal);
}
/* Return true if the countable mutex is not currently held */
static int counterMutexNotheld(sqlite3_mutex *p){
return g.m.xMutexNotheld(p->pReal);
}
/* Initialize the countable mutex interface
** Or, if g.disableInit is non-zero, then do not initialize but instead
** return the value of g.disableInit as the result code. This can be used
** to simulate an initialization failure.
*/
static int counterMutexInit(void){
int rc;
if( g.disableInit ) return g.disableInit;
rc = g.m.xMutexInit();
g.isInit = 1;
return rc;
}
/*
** Uninitialize the mutex subsystem
*/
static int counterMutexEnd(void){
g.isInit = 0;
return g.m.xMutexEnd();
}
/*
** Allocate a countable mutex
*/
static sqlite3_mutex *counterMutexAlloc(int eType){
sqlite3_mutex *pReal;
sqlite3_mutex *pRet = 0;
assert( g.isInit );
assert(eType<8 && eType>=0);
pReal = g.m.xMutexAlloc(eType);
if( !pReal ) return 0;
if( eType==SQLITE_MUTEX_FAST || eType==SQLITE_MUTEX_RECURSIVE ){
pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));
}else{
pRet = &g.aStatic[eType-2];
}
pRet->eType = eType;
pRet->pReal = pReal;
return pRet;
}
/*
** Free a countable mutex
*/
static void counterMutexFree(sqlite3_mutex *p){
assert( g.isInit );
g.m.xMutexFree(p->pReal);
if( p->eType==SQLITE_MUTEX_FAST || p->eType==SQLITE_MUTEX_RECURSIVE ){
free(p);
}
}
/*
** Enter a countable mutex. Block until entry is safe.
*/
static void counterMutexEnter(sqlite3_mutex *p){
assert( g.isInit );
g.aCounter[p->eType]++;
g.m.xMutexEnter(p->pReal);
}
/*
** Try to enter a mutex. Return true on success.
*/
static int counterMutexTry(sqlite3_mutex *p){
assert( g.isInit );
g.aCounter[p->eType]++;
if( g.disableTry ) return SQLITE_BUSY;
return g.m.xMutexTry(p->pReal);
}
/* Leave a mutex
*/
static void counterMutexLeave(sqlite3_mutex *p){
assert( g.isInit );
g.m.xMutexLeave(p->pReal);
}
/*
** sqlite3_shutdown
*/
static int test_shutdown(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
rc = sqlite3_shutdown();
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** sqlite3_initialize
*/
static int test_initialize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
rc = sqlite3_initialize();
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** install_mutex_counters BOOLEAN
*/
static int test_install_mutex_counters(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc = SQLITE_OK;
int isInstall;
sqlite3_mutex_methods counter_methods = {
counterMutexInit,
counterMutexEnd,
counterMutexAlloc,
counterMutexFree,
counterMutexEnter,
counterMutexTry,
counterMutexLeave,
counterMutexHeld,
counterMutexNotheld
};
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
return TCL_ERROR;
}
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
return TCL_ERROR;
}
assert(isInstall==0 || isInstall==1);
assert(g.isInstalled==0 || g.isInstalled==1);
if( isInstall==g.isInstalled ){
Tcl_AppendResult(interp, "mutex counters are ", 0);
Tcl_AppendResult(interp, isInstall?"already installed":"not installed", 0);
return TCL_ERROR;
}
if( isInstall ){
assert( g.m.xMutexAlloc==0 );
rc = sqlite3_config(SQLITE_CONFIG_GETMUTEX, &g.m);
if( rc==SQLITE_OK ){
sqlite3_config(SQLITE_CONFIG_MUTEX, &counter_methods);
}
g.disableTry = 0;
}else{
assert( g.m.xMutexAlloc );
rc = sqlite3_config(SQLITE_CONFIG_MUTEX, &g.m);
memset(&g.m, 0, sizeof(sqlite3_mutex_methods));
}
if( rc==SQLITE_OK ){
g.isInstalled = isInstall;
}
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** read_mutex_counters
*/
static int test_read_mutex_counters(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
Tcl_Obj *pRet;
int ii;
char *aName[8] = {
"fast", "recursive", "static_master", "static_mem",
"static_open", "static_prng", "static_lru", "static_pmem"
};
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
for(ii=0; ii<8; ii++){
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii]));
}
Tcl_SetObjResult(interp, pRet);
Tcl_DecrRefCount(pRet);
return TCL_OK;
}
/*
** clear_mutex_counters
*/
static int test_clear_mutex_counters(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int ii;
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
for(ii=0; ii<8; ii++){
g.aCounter[ii] = 0;
}
return TCL_OK;
}
/*
** Create and free a mutex. Return the mutex pointer. The pointer
** will be invalid since the mutex has already been freed. The
** return pointer just checks to see if the mutex really was allocated.
*/
static int test_alloc_mutex(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#if SQLITE_THREADSAFE
sqlite3_mutex *p = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
char zBuf[100];
sqlite3_mutex_free(p);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p);
Tcl_AppendResult(interp, zBuf, (char*)0);
#endif
return TCL_OK;
}
/*
** sqlite3_config OPTION
**
** OPTION can be either one of the keywords:
**
** SQLITE_CONFIG_SINGLETHREAD
** SQLITE_CONFIG_MULTITHREAD
** SQLITE_CONFIG_SERIALIZED
**
** Or OPTION can be an raw integer.
*/
static int test_config(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
struct ConfigOption {
const char *zName;
int iValue;
} aOpt[] = {
{"singlethread", SQLITE_CONFIG_SINGLETHREAD},
{"multithread", SQLITE_CONFIG_MULTITHREAD},
{"serialized", SQLITE_CONFIG_SERIALIZED},
{0, 0}
};
int s = sizeof(struct ConfigOption);
int i;
int rc;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
if( Tcl_GetIndexFromObjStruct(interp, objv[1], aOpt, s, "flag", 0, &i) ){
if( Tcl_GetIntFromObj(interp, objv[1], &i) ){
return TCL_ERROR;
}
}else{
i = aOpt[i].iValue;
}
rc = sqlite3_config(i);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
static sqlite3 *getDbPointer(Tcl_Interp *pInterp, Tcl_Obj *pObj){
sqlite3 *db;
Tcl_CmdInfo info;
char *zCmd = Tcl_GetString(pObj);
if( Tcl_GetCommandInfo(pInterp, zCmd, &info) ){
db = *((sqlite3 **)info.objClientData);
}else{
db = (sqlite3*)sqlite3TestTextToPtr(zCmd);
}
assert( db );
return db;
}
static int test_enter_db_mutex(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
db = getDbPointer(interp, objv[1]);
if( !db ){
return TCL_ERROR;
}
sqlite3_mutex_enter(sqlite3_db_mutex(db));
return TCL_OK;
}
static int test_leave_db_mutex(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
db = getDbPointer(interp, objv[1]);
if( !db ){
return TCL_ERROR;
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return TCL_OK;
}
int Sqlitetest_mutex_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aCmd[] = {
{ "sqlite3_shutdown", (Tcl_ObjCmdProc*)test_shutdown },
{ "sqlite3_initialize", (Tcl_ObjCmdProc*)test_initialize },
{ "sqlite3_config", (Tcl_ObjCmdProc*)test_config },
{ "enter_db_mutex", (Tcl_ObjCmdProc*)test_enter_db_mutex },
{ "leave_db_mutex", (Tcl_ObjCmdProc*)test_leave_db_mutex },
{ "alloc_dealloc_mutex", (Tcl_ObjCmdProc*)test_alloc_mutex },
{ "install_mutex_counters", (Tcl_ObjCmdProc*)test_install_mutex_counters },
{ "read_mutex_counters", (Tcl_ObjCmdProc*)test_read_mutex_counters },
{ "clear_mutex_counters", (Tcl_ObjCmdProc*)test_clear_mutex_counters },
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
}
Tcl_LinkVar(interp, "disable_mutex_init",
(char*)&g.disableInit, TCL_LINK_INT);
Tcl_LinkVar(interp, "disable_mutex_try",
(char*)&g.disableTry, TCL_LINK_INT);
return SQLITE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,467 +0,0 @@
/*
** 2008 November 18
**
** 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 for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
**
** This file contains an application-defined pager cache
** implementation that can be plugged in in place of the
** default pcache. This alternative pager cache will throw
** some errors that the default cache does not.
**
** This pagecache implementation is designed for simplicity
** not speed.
*/
#include "sqlite3.h"
#include <string.h>
#include <assert.h>
/*
** Global data used by this test implementation. There is no
** mutexing, which means this page cache will not work in a
** multi-threaded test.
*/
typedef struct testpcacheGlobalType testpcacheGlobalType;
struct testpcacheGlobalType {
void *pDummy; /* Dummy allocation to simulate failures */
int nInstance; /* Number of current instances */
unsigned discardChance; /* Chance of discarding on an unpin (0-100) */
unsigned prngSeed; /* Seed for the PRNG */
unsigned highStress; /* Call xStress agressively */
};
static testpcacheGlobalType testpcacheGlobal;
/*
** Initializer.
**
** Verify that the initializer is only called when the system is
** uninitialized. Allocate some memory and report SQLITE_NOMEM if
** the allocation fails. This provides a means to test the recovery
** from a failed initialization attempt. It also verifies that the
** the destructor always gets call - otherwise there would be a
** memory leak.
*/
static int testpcacheInit(void *pArg){
assert( pArg==(void*)&testpcacheGlobal );
assert( testpcacheGlobal.pDummy==0 );
assert( testpcacheGlobal.nInstance==0 );
testpcacheGlobal.pDummy = sqlite3_malloc(10);
return testpcacheGlobal.pDummy==0 ? SQLITE_NOMEM : SQLITE_OK;
}
/*
** Destructor
**
** Verify that this is only called after initialization.
** Free the memory allocated by the initializer.
*/
static void testpcacheShutdown(void *pArg){
assert( pArg==(void*)&testpcacheGlobal );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance==0 );
sqlite3_free( testpcacheGlobal.pDummy );
testpcacheGlobal.pDummy = 0;
}
/*
** Number of pages in a cache.
**
** The number of pages is a hard upper bound in this test module.
** If more pages are requested, sqlite3PcacheFetch() returns NULL.
**
** If testing with in-memory temp tables, provide a larger pcache.
** Some of the test cases need this.
*/
#if defined(SQLITE_TEMP_STORE) && SQLITE_TEMP_STORE>=2
# define TESTPCACHE_NPAGE 499
#else
# define TESTPCACHE_NPAGE 217
#endif
#define TESTPCACHE_RESERVE 17
/*
** Magic numbers used to determine validity of the page cache.
*/
#define TESTPCACHE_VALID 0x364585fd
#define TESTPCACHE_CLEAR 0xd42670d4
/*
** Private implementation of a page cache.
*/
typedef struct testpcache testpcache;
struct testpcache {
int szPage; /* Size of each page. Multiple of 8. */
int szExtra; /* Size of extra data that accompanies each page */
int bPurgeable; /* True if the page cache is purgeable */
int nFree; /* Number of unused slots in a[] */
int nPinned; /* Number of pinned slots in a[] */
unsigned iRand; /* State of the PRNG */
unsigned iMagic; /* Magic number for sanity checking */
struct testpcachePage {
sqlite3_pcache_page page; /* Base class */
unsigned key; /* The key for this page. 0 means unallocated */
int isPinned; /* True if the page is pinned */
} a[TESTPCACHE_NPAGE]; /* All pages in the cache */
};
/*
** Get a random number using the PRNG in the given page cache.
*/
static unsigned testpcacheRandom(testpcache *p){
unsigned x = 0;
int i;
for(i=0; i<4; i++){
p->iRand = (p->iRand*69069 + 5);
x = (x<<8) | ((p->iRand>>16)&0xff);
}
return x;
}
/*
** Allocate a new page cache instance.
*/
static sqlite3_pcache *testpcacheCreate(
int szPage,
int szExtra,
int bPurgeable
){
int nMem;
char *x;
testpcache *p;
int i;
assert( testpcacheGlobal.pDummy!=0 );
szPage = (szPage+7)&~7;
nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
p = sqlite3_malloc( nMem );
if( p==0 ) return 0;
x = (char*)&p[1];
p->szPage = szPage;
p->szExtra = szExtra;
p->nFree = TESTPCACHE_NPAGE;
p->nPinned = 0;
p->iRand = testpcacheGlobal.prngSeed;
p->bPurgeable = bPurgeable;
p->iMagic = TESTPCACHE_VALID;
for(i=0; i<TESTPCACHE_NPAGE; i++, x += (szPage+szExtra)){
p->a[i].key = 0;
p->a[i].isPinned = 0;
p->a[i].page.pBuf = (void*)x;
p->a[i].page.pExtra = (void*)&x[szPage];
}
testpcacheGlobal.nInstance++;
return (sqlite3_pcache*)p;
}
/*
** Set the cache size
*/
static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){
testpcache *p = (testpcache*)pCache;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
}
/*
** Return the number of pages in the cache that are being used.
** This includes both pinned and unpinned pages.
*/
static int testpcachePagecount(sqlite3_pcache *pCache){
testpcache *p = (testpcache*)pCache;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
return TESTPCACHE_NPAGE - p->nFree;
}
/*
** Fetch a page.
*/
static sqlite3_pcache_page *testpcacheFetch(
sqlite3_pcache *pCache,
unsigned key,
int createFlag
){
testpcache *p = (testpcache*)pCache;
int i, j;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
/* See if the page is already in cache. Return immediately if it is */
for(i=0; i<TESTPCACHE_NPAGE; i++){
if( p->a[i].key==key ){
if( !p->a[i].isPinned ){
p->nPinned++;
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
p->a[i].isPinned = 1;
}
return &p->a[i].page;
}
}
/* If createFlag is 0, never allocate a new page */
if( createFlag==0 ){
return 0;
}
/* If no pages are available, always fail */
if( p->nPinned==TESTPCACHE_NPAGE ){
return 0;
}
/* Do not allocate the last TESTPCACHE_RESERVE pages unless createFlag is 2 */
if( p->nPinned>=TESTPCACHE_NPAGE-TESTPCACHE_RESERVE && createFlag<2 ){
return 0;
}
/* Do not allocate if highStress is enabled and createFlag is not 2.
**
** The highStress setting causes pagerStress() to be called much more
** often, which exercises the pager logic more intensely.
*/
if( testpcacheGlobal.highStress && createFlag<2 ){
return 0;
}
/* Find a free page to allocate if there are any free pages.
** Withhold TESTPCACHE_RESERVE free pages until createFlag is 2.
*/
if( p->nFree>TESTPCACHE_RESERVE || (createFlag==2 && p->nFree>0) ){
j = testpcacheRandom(p) % TESTPCACHE_NPAGE;
for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){
if( p->a[j].key==0 ){
p->a[j].key = key;
p->a[j].isPinned = 1;
memset(p->a[j].page.pBuf, 0, p->szPage);
memset(p->a[j].page.pExtra, 0, p->szExtra);
p->nPinned++;
p->nFree--;
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
return &p->a[j].page;
}
}
/* The prior loop always finds a freepage to allocate */
assert( 0 );
}
/* If this cache is not purgeable then we have to fail.
*/
if( p->bPurgeable==0 ){
return 0;
}
/* If there are no free pages, recycle a page. The page to
** recycle is selected at random from all unpinned pages.
*/
j = testpcacheRandom(p) % TESTPCACHE_NPAGE;
for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){
if( p->a[j].key>0 && p->a[j].isPinned==0 ){
p->a[j].key = key;
p->a[j].isPinned = 1;
memset(p->a[j].page.pBuf, 0, p->szPage);
memset(p->a[j].page.pExtra, 0, p->szExtra);
p->nPinned++;
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
return &p->a[j].page;
}
}
/* The previous loop always finds a page to recycle. */
assert(0);
return 0;
}
/*
** Unpin a page.
*/
static void testpcacheUnpin(
sqlite3_pcache *pCache,
sqlite3_pcache_page *pOldPage,
int discard
){
testpcache *p = (testpcache*)pCache;
int i;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
/* Randomly discard pages as they are unpinned according to the
** discardChance setting. If discardChance is 0, the random discard
** never happens. If discardChance is 100, it always happens.
*/
if( p->bPurgeable
&& (100-testpcacheGlobal.discardChance) <= (testpcacheRandom(p)%100)
){
discard = 1;
}
for(i=0; i<TESTPCACHE_NPAGE; i++){
if( &p->a[i].page==pOldPage ){
/* The pOldPage pointer always points to a pinned page */
assert( p->a[i].isPinned );
p->a[i].isPinned = 0;
p->nPinned--;
assert( p->nPinned>=0 );
if( discard ){
p->a[i].key = 0;
p->nFree++;
assert( p->nFree<=TESTPCACHE_NPAGE );
}
return;
}
}
/* The pOldPage pointer always points to a valid page */
assert( 0 );
}
/*
** Rekey a single page.
*/
static void testpcacheRekey(
sqlite3_pcache *pCache,
sqlite3_pcache_page *pOldPage,
unsigned oldKey,
unsigned newKey
){
testpcache *p = (testpcache*)pCache;
int i;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
/* If there already exists another page at newKey, verify that
** the other page is unpinned and discard it.
*/
for(i=0; i<TESTPCACHE_NPAGE; i++){
if( p->a[i].key==newKey ){
/* The new key is never a page that is already pinned */
assert( p->a[i].isPinned==0 );
p->a[i].key = 0;
p->nFree++;
assert( p->nFree<=TESTPCACHE_NPAGE );
break;
}
}
/* Find the page to be rekeyed and rekey it.
*/
for(i=0; i<TESTPCACHE_NPAGE; i++){
if( p->a[i].key==oldKey ){
/* The oldKey and pOldPage parameters match */
assert( &p->a[i].page==pOldPage );
/* Page to be rekeyed must be pinned */
assert( p->a[i].isPinned );
p->a[i].key = newKey;
return;
}
}
/* Rekey is always given a valid page to work with */
assert( 0 );
}
/*
** Truncate the page cache. Every page with a key of iLimit or larger
** is discarded.
*/
static void testpcacheTruncate(sqlite3_pcache *pCache, unsigned iLimit){
testpcache *p = (testpcache*)pCache;
unsigned int i;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
for(i=0; i<TESTPCACHE_NPAGE; i++){
if( p->a[i].key>=iLimit ){
p->a[i].key = 0;
if( p->a[i].isPinned ){
p->nPinned--;
assert( p->nPinned>=0 );
}
p->nFree++;
assert( p->nFree<=TESTPCACHE_NPAGE );
}
}
}
/*
** Destroy a page cache.
*/
static void testpcacheDestroy(sqlite3_pcache *pCache){
testpcache *p = (testpcache*)pCache;
assert( p->iMagic==TESTPCACHE_VALID );
assert( testpcacheGlobal.pDummy!=0 );
assert( testpcacheGlobal.nInstance>0 );
p->iMagic = TESTPCACHE_CLEAR;
sqlite3_free(p);
testpcacheGlobal.nInstance--;
}
/*
** Invoke this routine to register or unregister the testing pager cache
** implemented by this file.
**
** Install the test pager cache if installFlag is 1 and uninstall it if
** installFlag is 0.
**
** When installing, discardChance is a number between 0 and 100 that
** indicates the probability of discarding a page when unpinning the
** page. 0 means never discard (unless the discard flag is set).
** 100 means always discard.
*/
void installTestPCache(
int installFlag, /* True to install. False to uninstall. */
unsigned discardChance, /* 0-100. Chance to discard on unpin */
unsigned prngSeed, /* Seed for the PRNG */
unsigned highStress /* Call xStress agressively */
){
static const sqlite3_pcache_methods2 testPcache = {
1,
(void*)&testpcacheGlobal,
testpcacheInit,
testpcacheShutdown,
testpcacheCreate,
testpcacheCachesize,
testpcachePagecount,
testpcacheFetch,
testpcacheUnpin,
testpcacheRekey,
testpcacheTruncate,
testpcacheDestroy,
};
static sqlite3_pcache_methods2 defaultPcache;
static int isInstalled = 0;
assert( testpcacheGlobal.nInstance==0 );
assert( testpcacheGlobal.pDummy==0 );
assert( discardChance<=100 );
testpcacheGlobal.discardChance = discardChance;
testpcacheGlobal.prngSeed = prngSeed ^ (prngSeed<<16);
testpcacheGlobal.highStress = highStress;
if( installFlag!=isInstalled ){
if( installFlag ){
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache);
assert( defaultPcache.xCreate!=testpcacheCreate );
sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache);
}else{
assert( defaultPcache.xCreate!=0 );
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache);
}
isInstalled = installFlag;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,274 +0,0 @@
/*
** 2011 December 1
**
** 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 the interface definition for the quota a VFS shim.
**
** This particular shim enforces a quota system on files. One or more
** database files are in a "quota group" that is defined by a GLOB
** pattern. A quota is set for the combined size of all files in the
** the group. A quota of zero means "no limit". If the total size
** of all files in the quota group is greater than the limit, then
** write requests that attempt to enlarge a file fail with SQLITE_FULL.
**
** However, before returning SQLITE_FULL, the write requests invoke
** a callback function that is configurable for each quota group.
** This callback has the opportunity to enlarge the quota. If the
** callback does enlarge the quota such that the total size of all
** files within the group is less than the new quota, then the write
** continues as if nothing had happened.
*/
#ifndef _QUOTA_H_
#include "sqlite3.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <windows.h>
#endif
/* Make this callable from C++ */
#ifdef __cplusplus
extern "C" {
#endif
/*
** Initialize the quota VFS shim. Use the VFS named zOrigVfsName
** as the VFS that does the actual work. Use the default if
** zOrigVfsName==NULL.
**
** The quota VFS shim is named "quota". It will become the default
** VFS if makeDefault is non-zero.
**
** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
** during start-up.
*/
int sqlite3_quota_initialize(const char *zOrigVfsName, int makeDefault);
/*
** Shutdown the quota system.
**
** All SQLite database connections must be closed before calling this
** routine.
**
** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
** shutting down in order to free all remaining quota groups.
*/
int sqlite3_quota_shutdown(void);
/*
** Create or destroy a quota group.
**
** The quota group is defined by the zPattern. When calling this routine
** with a zPattern for a quota group that already exists, this routine
** merely updates the iLimit, xCallback, and pArg values for that quota
** group. If zPattern is new, then a new quota group is created.
**
** The zPattern is always compared against the full pathname of the file.
** Even if APIs are called with relative pathnames, SQLite converts the
** name to a full pathname before comparing it against zPattern. zPattern
** is a glob pattern with the following matching rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters. "]" can be part of the list if it is
** the first character. Within the list "X-Y" matches
** characters X or Y or any character in between the
** two. Ex: "[0-9]" matches any digit.
**
** [^...] Matches one character not in the enclosed list.
**
** / Matches either / or \. This allows glob patterns
** containing / to work on both unix and windows.
**
** Note that, unlike unix shell globbing, the directory separator "/"
** can match a wildcard. So, for example, the pattern "/abc/xyz/" "*"
** matches any files anywhere in the directory hierarchy beneath
** /abc/xyz.
**
** The glob algorithm works on bytes. Multi-byte UTF8 characters are
** matched as if each byte were a separate character.
**
** If the iLimit for a quota group is set to zero, then the quota group
** is disabled and will be deleted when the last database connection using
** the quota group is closed.
**
** Calling this routine on a zPattern that does not exist and with a
** zero iLimit is a no-op.
**
** A quota group must exist with a non-zero iLimit prior to opening
** database connections if those connections are to participate in the
** quota group. Creating a quota group does not affect database connections
** that are already open.
**
** The patterns that define the various quota groups should be distinct.
** If the same filename matches more than one quota group pattern, then
** the behavior of this package is undefined.
*/
int sqlite3_quota_set(
const char *zPattern, /* The filename pattern */
sqlite3_int64 iLimit, /* New quota to set for this quota group */
void (*xCallback)( /* Callback invoked when going over quota */
const char *zFilename, /* Name of file whose size increases */
sqlite3_int64 *piLimit, /* IN/OUT: The current limit */
sqlite3_int64 iSize, /* Total size of all files in the group */
void *pArg /* Client data */
),
void *pArg, /* client data passed thru to callback */
void (*xDestroy)(void*) /* Optional destructor for pArg */
);
/*
** Bring the named file under quota management, assuming its name matches
** the glob pattern of some quota group. Or if it is already under
** management, update its size. If zFilename does not match the glob
** pattern of any quota group, this routine is a no-op.
*/
int sqlite3_quota_file(const char *zFilename);
/*
** The following object serves the same role as FILE in the standard C
** library. It represents an open connection to a file on disk for I/O.
**
** A single quota_FILE should not be used by two or more threads at the
** same time. Multiple threads can be using different quota_FILE objects
** simultaneously, but not the same quota_FILE object.
*/
typedef struct quota_FILE quota_FILE;
/*
** Create a new quota_FILE object used to read and/or write to the
** file zFilename. The zMode parameter is as with standard library zMode.
*/
quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode);
/*
** Perform I/O against a quota_FILE object. When doing writes, the
** quota mechanism may result in a short write, in order to prevent
** the sum of sizes of all files from going over quota.
*/
size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*);
size_t sqlite3_quota_fwrite(const void*, size_t, size_t, quota_FILE*);
/*
** Flush all written content held in memory buffers out to disk.
** This is the equivalent of fflush() in the standard library.
**
** If the hardSync parameter is true (non-zero) then this routine
** also forces OS buffers to disk - the equivalent of fsync().
**
** This routine return zero on success and non-zero if something goes
** wrong.
*/
int sqlite3_quota_fflush(quota_FILE*, int hardSync);
/*
** Close a quota_FILE object and free all associated resources. The
** file remains under quota management.
*/
int sqlite3_quota_fclose(quota_FILE*);
/*
** Move the read/write pointer for a quota_FILE object. Or tell the
** current location of the read/write pointer.
*/
int sqlite3_quota_fseek(quota_FILE*, long, int);
void sqlite3_quota_rewind(quota_FILE*);
long sqlite3_quota_ftell(quota_FILE*);
/*
** Test the error indicator for the given file.
**
** Return non-zero if the error indicator is set.
*/
int sqlite3_quota_ferror(quota_FILE*);
/*
** Truncate a file previously opened by sqlite3_quota_fopen(). Return
** zero on success and non-zero on any kind of failure.
**
** The newSize argument must be less than or equal to the current file size.
** Any attempt to "truncate" a file to a larger size results in
** undefined behavior.
*/
int sqlite3_quota_ftruncate(quota_FILE*, sqlite3_int64 newSize);
/*
** Return the last modification time of the opened file, in seconds
** since 1970.
*/
int sqlite3_quota_file_mtime(quota_FILE*, time_t *pTime);
/*
** Return the size of the file as it is known to the quota system.
**
** This size might be different from the true size of the file on
** disk if some outside process has modified the file without using the
** quota mechanism, or if calls to sqlite3_quota_fwrite() have occurred
** which have increased the file size, but those writes have not yet been
** forced to disk using sqlite3_quota_fflush().
**
** Return -1 if the file is not participating in quota management.
*/
sqlite3_int64 sqlite3_quota_file_size(quota_FILE*);
/*
** Return the true size of the file.
**
** The true size should be the same as the size of the file as known
** to the quota system, however the sizes might be different if the
** file has been extended or truncated via some outside process or if
** pending writes have not yet been flushed to disk.
**
** Return -1 if the file does not exist or if the size of the file
** cannot be determined for some reason.
*/
sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
/*
** Determine the amount of data in bytes available for reading
** in the given file.
**
** Return -1 if the amount cannot be determined for some reason.
*/
long sqlite3_quota_file_available(quota_FILE*);
/*
** Delete a file from the disk, if that file is under quota management.
** Adjust quotas accordingly.
**
** If zFilename is the name of a directory that matches one of the
** quota glob patterns, then all files under quota management that
** are contained within that directory are deleted.
**
** A standard SQLite result code is returned (SQLITE_OK, SQLITE_NOMEM, etc.)
** When deleting a directory of files, if the deletion of any one
** file fails (for example due to an I/O error), then this routine
** returns immediately, with the error code, and does not try to
** delete any of the other files in the specified directory.
**
** All files are removed from quota management and deleted from disk.
** However, no attempt is made to remove empty directories.
**
** This routine is a no-op for files that are not under quota management.
*/
int sqlite3_quota_remove(const char *zFilename);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* _QUOTA_H_ */

View File

@@ -1,305 +0,0 @@
/*
** 2010 August 28
**
** 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.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces. This code
** is not included in the SQLite library.
*/
#include <sqlite3.h>
#include <tcl.h>
/* Solely for the UNUSED_PARAMETER() macro. */
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_RTREE
/*
** Type used to cache parameter information for the "circle" r-tree geometry
** callback.
*/
typedef struct Circle Circle;
struct Circle {
struct Box {
double xmin;
double xmax;
double ymin;
double ymax;
} aBox[2];
double centerx;
double centery;
double radius;
};
/*
** Destructor function for Circle objects allocated by circle_geom().
*/
static void circle_del(void *p){
sqlite3_free(p);
}
/*
** Implementation of "circle" r-tree geometry callback.
*/
static int circle_geom(
sqlite3_rtree_geometry *p,
int nCoord,
#ifdef SQLITE_RTREE_INT_ONLY
sqlite3_int64 *aCoord,
#else
double *aCoord,
#endif
int *pRes
){
int i; /* Iterator variable */
Circle *pCircle; /* Structure defining circular region */
double xmin, xmax; /* X dimensions of box being tested */
double ymin, ymax; /* X dimensions of box being tested */
if( p->pUser==0 ){
/* If pUser is still 0, then the parameter values have not been tested
** for correctness or stored into a Circle structure yet. Do this now. */
/* This geometry callback is for use with a 2-dimensional r-tree table.
** Return an error if the table does not have exactly 2 dimensions. */
if( nCoord!=4 ) return SQLITE_ERROR;
/* Test that the correct number of parameters (3) have been supplied,
** and that the parameters are in range (that the radius of the circle
** radius is greater than zero). */
if( p->nParam!=3 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
/* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM
** if the allocation fails. */
pCircle = (Circle *)(p->pUser = sqlite3_malloc(sizeof(Circle)));
if( !pCircle ) return SQLITE_NOMEM;
p->xDelUser = circle_del;
/* Record the center and radius of the circular region. One way that
** tested bounding boxes that intersect the circular region are detected
** is by testing if each corner of the bounding box lies within radius
** units of the center of the circle. */
pCircle->centerx = p->aParam[0];
pCircle->centery = p->aParam[1];
pCircle->radius = p->aParam[2];
/* Define two bounding box regions. The first, aBox[0], extends to
** infinity in the X dimension. It covers the same range of the Y dimension
** as the circular region. The second, aBox[1], extends to infinity in
** the Y dimension and is constrained to the range of the circle in the
** X dimension.
**
** Then imagine each box is split in half along its short axis by a line
** that intersects the center of the circular region. A bounding box
** being tested can be said to intersect the circular region if it contains
** points from each half of either of the two infinite bounding boxes.
*/
pCircle->aBox[0].xmin = pCircle->centerx;
pCircle->aBox[0].xmax = pCircle->centerx;
pCircle->aBox[0].ymin = pCircle->centery + pCircle->radius;
pCircle->aBox[0].ymax = pCircle->centery - pCircle->radius;
pCircle->aBox[1].xmin = pCircle->centerx + pCircle->radius;
pCircle->aBox[1].xmax = pCircle->centerx - pCircle->radius;
pCircle->aBox[1].ymin = pCircle->centery;
pCircle->aBox[1].ymax = pCircle->centery;
}
pCircle = (Circle *)p->pUser;
xmin = aCoord[0];
xmax = aCoord[1];
ymin = aCoord[2];
ymax = aCoord[3];
/* Check if any of the 4 corners of the bounding-box being tested lie
** inside the circular region. If they do, then the bounding-box does
** intersect the region of interest. Set the output variable to true and
** return SQLITE_OK in this case. */
for(i=0; i<4; i++){
double x = (i&0x01) ? xmax : xmin;
double y = (i&0x02) ? ymax : ymin;
double d2;
d2 = (x-pCircle->centerx)*(x-pCircle->centerx);
d2 += (y-pCircle->centery)*(y-pCircle->centery);
if( d2<(pCircle->radius*pCircle->radius) ){
*pRes = 1;
return SQLITE_OK;
}
}
/* Check if the bounding box covers any other part of the circular region.
** See comments above for a description of how this test works. If it does
** cover part of the circular region, set the output variable to true
** and return SQLITE_OK. */
for(i=0; i<2; i++){
if( xmin<=pCircle->aBox[i].xmin
&& xmax>=pCircle->aBox[i].xmax
&& ymin<=pCircle->aBox[i].ymin
&& ymax>=pCircle->aBox[i].ymax
){
*pRes = 1;
return SQLITE_OK;
}
}
/* The specified bounding box does not intersect the circular region. Set
** the output variable to zero and return SQLITE_OK. */
*pRes = 0;
return SQLITE_OK;
}
/* END of implementation of "circle" geometry callback.
**************************************************************************
*************************************************************************/
#include <assert.h>
#include "tcl.h"
typedef struct Cube Cube;
struct Cube {
double x;
double y;
double z;
double width;
double height;
double depth;
};
static void cube_context_free(void *p){
sqlite3_free(p);
}
/*
** The context pointer registered along with the 'cube' callback is
** always ((void *)&gHere). This is just to facilitate testing, it is not
** actually used for anything.
*/
static int gHere = 42;
/*
** Implementation of a simple r-tree geom callback to test for intersection
** of r-tree rows with a "cube" shape. Cubes are defined by six scalar
** coordinates as follows:
**
** cube(x, y, z, width, height, depth)
**
** The width, height and depth parameters must all be greater than zero.
*/
static int cube_geom(
sqlite3_rtree_geometry *p,
int nCoord,
#ifdef SQLITE_RTREE_INT_ONLY
sqlite3_int64 *aCoord,
#else
double *aCoord,
#endif
int *piRes
){
Cube *pCube = (Cube *)p->pUser;
assert( p->pContext==(void *)&gHere );
if( pCube==0 ){
if( p->nParam!=6 || nCoord!=6
|| p->aParam[3]<=0.0 || p->aParam[4]<=0.0 || p->aParam[5]<=0.0
){
return SQLITE_ERROR;
}
pCube = (Cube *)sqlite3_malloc(sizeof(Cube));
if( !pCube ){
return SQLITE_NOMEM;
}
pCube->x = p->aParam[0];
pCube->y = p->aParam[1];
pCube->z = p->aParam[2];
pCube->width = p->aParam[3];
pCube->height = p->aParam[4];
pCube->depth = p->aParam[5];
p->pUser = (void *)pCube;
p->xDelUser = cube_context_free;
}
assert( nCoord==6 );
*piRes = 0;
if( aCoord[0]<=(pCube->x+pCube->width)
&& aCoord[1]>=pCube->x
&& aCoord[2]<=(pCube->y+pCube->height)
&& aCoord[3]>=pCube->y
&& aCoord[4]<=(pCube->z+pCube->depth)
&& aCoord[5]>=pCube->z
){
*piRes = 1;
}
return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_RTREE */
static int register_cube_geom(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_ENABLE_RTREE
UNUSED_PARAMETER(clientData);
UNUSED_PARAMETER(interp);
UNUSED_PARAMETER(objc);
UNUSED_PARAMETER(objv);
#else
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
extern const char *sqlite3ErrName(int);
sqlite3 *db;
int rc;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
rc = sqlite3_rtree_geometry_callback(db, "cube", cube_geom, (void *)&gHere);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
#endif
return TCL_OK;
}
static int register_circle_geom(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_ENABLE_RTREE
UNUSED_PARAMETER(clientData);
UNUSED_PARAMETER(interp);
UNUSED_PARAMETER(objc);
UNUSED_PARAMETER(objv);
#else
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
extern const char *sqlite3ErrName(int);
sqlite3 *db;
int rc;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
rc = sqlite3_rtree_geometry_callback(db, "circle", circle_geom, 0);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
#endif
return TCL_OK;
}
int Sqlitetestrtree_Init(Tcl_Interp *interp){
Tcl_CreateObjCommand(interp, "register_cube_geom", register_cube_geom, 0, 0);
Tcl_CreateObjCommand(interp, "register_circle_geom",register_circle_geom,0,0);
return TCL_OK;
}

View File

@@ -1,362 +0,0 @@
/*
** 2006 June 10
**
** 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.
**
*************************************************************************
** Code for testing the virtual table interfaces. This code
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
*/
/* The code in this file defines a sqlite3 virtual-table module that
** provides a read-only view of the current database schema. There is one
** row in the schema table for each column in the database schema.
*/
#define SCHEMA \
"CREATE TABLE x(" \
"database," /* Name of database (i.e. main, temp etc.) */ \
"tablename," /* Name of table */ \
"cid," /* Column number (from left-to-right, 0 upward) */ \
"name," /* Column name */ \
"type," /* Specified type (i.e. VARCHAR(32)) */ \
"not_null," /* Boolean. True if NOT NULL was specified */ \
"dflt_value," /* Default value for this column */ \
"pk" /* True if this column is part of the primary key */ \
")"
/* If SQLITE_TEST is defined this code is preprocessed for use as part
** of the sqlite test binary "testfixture". Otherwise it is preprocessed
** to be compiled into an sqlite dynamic extension.
*/
#ifdef SQLITE_TEST
#include "sqliteInt.h"
#include "tcl.h"
#else
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#endif
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct schema_vtab schema_vtab;
typedef struct schema_cursor schema_cursor;
/* A schema table object */
struct schema_vtab {
sqlite3_vtab base;
sqlite3 *db;
};
/* A schema table cursor object */
struct schema_cursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pDbList;
sqlite3_stmt *pTableList;
sqlite3_stmt *pColumnList;
int rowid;
};
/*
** None of this works unless we have virtual tables.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Table destructor for the schema module.
*/
static int schemaDestroy(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return 0;
}
/*
** Table constructor for the schema module.
*/
static int schemaCreate(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
int rc = SQLITE_NOMEM;
schema_vtab *pVtab = sqlite3_malloc(sizeof(schema_vtab));
if( pVtab ){
memset(pVtab, 0, sizeof(schema_vtab));
pVtab->db = db;
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_declare_vtab(db, SCHEMA);
#endif
}
*ppVtab = (sqlite3_vtab *)pVtab;
return rc;
}
/*
** Open a new cursor on the schema table.
*/
static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_NOMEM;
schema_cursor *pCur;
pCur = sqlite3_malloc(sizeof(schema_cursor));
if( pCur ){
memset(pCur, 0, sizeof(schema_cursor));
*ppCursor = (sqlite3_vtab_cursor *)pCur;
rc = SQLITE_OK;
}
return rc;
}
/*
** Close a schema table cursor.
*/
static int schemaClose(sqlite3_vtab_cursor *cur){
schema_cursor *pCur = (schema_cursor *)cur;
sqlite3_finalize(pCur->pDbList);
sqlite3_finalize(pCur->pTableList);
sqlite3_finalize(pCur->pColumnList);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Retrieve a column of data.
*/
static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
schema_cursor *pCur = (schema_cursor *)cur;
switch( i ){
case 0:
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pDbList, 1));
break;
case 1:
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pTableList, 0));
break;
default:
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pColumnList, i-2));
break;
}
return SQLITE_OK;
}
/*
** Retrieve the current rowid.
*/
static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
schema_cursor *pCur = (schema_cursor *)cur;
*pRowid = pCur->rowid;
return SQLITE_OK;
}
static int finalize(sqlite3_stmt **ppStmt){
int rc = sqlite3_finalize(*ppStmt);
*ppStmt = 0;
return rc;
}
static int schemaEof(sqlite3_vtab_cursor *cur){
schema_cursor *pCur = (schema_cursor *)cur;
return (pCur->pDbList ? 0 : 1);
}
/*
** Advance the cursor to the next row.
*/
static int schemaNext(sqlite3_vtab_cursor *cur){
int rc = SQLITE_OK;
schema_cursor *pCur = (schema_cursor *)cur;
schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
char *zSql = 0;
while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
assert(pCur->pDbList);
while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
rc = finalize(&pCur->pDbList);
goto next_exit;
}
/* Set zSql to the SQL to pull the list of tables from the
** sqlite_master (or sqlite_temp_master) table of the database
** identfied by the row pointed to by the SQL statement pCur->pDbList
** (iterating through a "PRAGMA database_list;" statement).
*/
if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
zSql = sqlite3_mprintf(
"SELECT name FROM sqlite_temp_master WHERE type='table'"
);
}else{
sqlite3_stmt *pDbList = pCur->pDbList;
zSql = sqlite3_mprintf(
"SELECT name FROM %Q.sqlite_master WHERE type='table'",
sqlite3_column_text(pDbList, 1)
);
}
if( !zSql ){
rc = SQLITE_NOMEM;
goto next_exit;
}
rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
sqlite3_free(zSql);
if( rc!=SQLITE_OK ) goto next_exit;
}
/* Set zSql to the SQL to the table_info pragma for the table currently
** identified by the rows pointed to by statements pCur->pDbList and
** pCur->pTableList.
*/
zSql = sqlite3_mprintf("PRAGMA %Q.table_info(%Q)",
sqlite3_column_text(pCur->pDbList, 1),
sqlite3_column_text(pCur->pTableList, 0)
);
if( !zSql ){
rc = SQLITE_NOMEM;
goto next_exit;
}
rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
sqlite3_free(zSql);
if( rc!=SQLITE_OK ) goto next_exit;
}
pCur->rowid++;
next_exit:
/* TODO: Handle rc */
return rc;
}
/*
** Reset a schema table cursor.
*/
static int schemaFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
int rc;
schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
schema_cursor *pCur = (schema_cursor *)pVtabCursor;
pCur->rowid = 0;
finalize(&pCur->pTableList);
finalize(&pCur->pColumnList);
finalize(&pCur->pDbList);
rc = sqlite3_prepare(pVtab->db,"PRAGMA database_list", -1, &pCur->pDbList, 0);
return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
}
/*
** Analyse the WHERE condition.
*/
static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_OK;
}
/*
** A virtual table module that merely echos method calls into TCL
** variables.
*/
static sqlite3_module schemaModule = {
0, /* iVersion */
schemaCreate,
schemaCreate,
schemaBestIndex,
schemaDestroy,
schemaDestroy,
schemaOpen, /* xOpen - open a cursor */
schemaClose, /* xClose - close a cursor */
schemaFilter, /* xFilter - configure scan constraints */
schemaNext, /* xNext - advance a cursor */
schemaEof, /* xEof */
schemaColumn, /* xColumn - read data */
schemaRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
#ifdef SQLITE_TEST
/*
** Decode a pointer to an sqlite3 object.
*/
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
/*
** Register the schema virtual table module.
*/
static int register_schema_module(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "schema", &schemaModule, 0);
#endif
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetestschema_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "register_schema_module", register_schema_module, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
return TCL_OK;
}
#else
/*
** Extension load function.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_schema_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "schema", &schemaModule, 0);
#endif
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More