diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-12 20:13:06 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-12 20:13:06 +0000 |
commit | 67361b3fcbd13d0ca74f4439e5a474a3867847b6 (patch) | |
tree | 10db345ad0f3a67e75c7ff9dbd3f30528fcc966b /third_party | |
parent | ce9eea60c922efff7c680a7a127480a799e06e94 (diff) | |
download | chromium_src-67361b3fcbd13d0ca74f4439e5a474a3867847b6.zip chromium_src-67361b3fcbd13d0ca74f4439e5a474a3867847b6.tar.gz chromium_src-67361b3fcbd13d0ca74f4439e5a474a3867847b6.tar.bz2 |
Cleanup SQLite 3.6.18 import.
Get things spic-n-span for converting to the amalgamation, then SQLite
3.7.x.
sqlite3Preload -> sqlite3_preload because in the amalgamation, sqlite3_ is the key bit to make sure things aren't marked static.
AFAICT, SQLite 3.6.18 was not imported correctly last time, throwing
up spurious deltas. Re-import and re-apply patches.
Remove a bunch of Gears-related stuff. Quite some time ago the
Chromium and Gears SQLite imports were brought into line, but they
were never fully shared. Nowadays these are completely useless:
- remove fts1 patches.
- add a Chromium test to make sure fts1 doesn't sneak in.
- drop the Symbian stuff.
- drop database poisoning.
Pull out the WebDatabase patch into a patch file. Move ICU shell
changes into a distinct patch file. Pull out testing patches into a
separate test.patch.
BUG=71731
TEST=automated testing and watching closely.
Review URL: http://codereview.chromium.org/6823057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81296 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
57 files changed, 1579 insertions, 6791 deletions
diff --git a/third_party/sqlite/README.chromium b/third_party/sqlite/README.chromium index c40754f..a65640e 100644 --- a/third_party/sqlite/README.chromium +++ b/third_party/sqlite/README.chromium @@ -2,6 +2,7 @@ Name: sqlite License File: src/LICENSE URL: http://sqlite.org/ Version: 3.6.18 +Included In Release: Yes Instructions for importing a new release of SQLite from sqlite.org. @@ -57,11 +58,12 @@ principle, exactly what is checked in: misc.patch preload-cache.patch safe-tolower.patch -sqlite-poison.patch fts2.patch fts3.patch icu-regexp.patch +icu-shell.patch attach-integer.patch +webdb.patch So, e.g. you could do this to apply all our patches to vanilla SQLite: @@ -69,11 +71,12 @@ cd sqlite-$LATEST patch -p0 < ../sqlite/misc.patch patch -p0 < ../sqlite/preload-cache.patch patch -p0 < ../sqlite/safe-tolower.patch -patch -p0 < ../sqlite/sqlite-poison.patch patch -p0 < ../sqlite/fts2.patch patch -p0 < ../sqlite/fts3.patch patch -p0 < ../sqlite/icu-regexp.patch +patch -p0 < ../sqlite/icu-shell.patch patch -p0 < ../sqlite/attach-integer.patch +patch -p0 < ../sqlite/webdb.patch This will only be the case if all changes we make also update the corresponding patch files. Therefore please remember to do that whenever you make a change! @@ -116,11 +119,9 @@ As of May 07, 2010, these are our changes from sqlite_vendor: tables. - fts2.c disables fts2_tokenizer(). - fts3.c disables fts3_tokenizer(). - - sqlite3Poison() in src/btree.c. - Tweak to SQLITE_EXTENSION_INIT* in sqlite3ext.h. - That implied a change in src/test_autoext.c for testing. - - Added fts.test and fts1.test in tests, modified quick.test. - - src/os_symbian.cc. + - Added fts.test in tests, modified quick.test. - Modifications to Makefile.linux-gcc and main.mk for compiling SQLite tests. - Compile warning (cast to void* for sqlite3_free) fixed in func.c. @@ -148,7 +149,7 @@ Changes from Chrome: our ICU data. shell.c has been modifed to call into these files. - fts2_icu.c and fts3_icu.c have a critical bug. U8_NEXT is used over a UTF-16 string. It's rep$ by U16_NEXT (jungshik) - - Added a new function sqlite3Preload we use to prime the database cache. It + - Added a new function sqlite3_preload we use to prime the database cache. It allows much faster performance by reading the file in one contiguous operation rather than bringing it in organically, which involves a lot of seeking. This change also required sqlite3PcacheGetCachesize to be compiled diff --git a/third_party/sqlite/icu-shell.patch b/third_party/sqlite/icu-shell.patch new file mode 100644 index 0000000..04a6329 --- /dev/null +++ b/third_party/sqlite/icu-shell.patch @@ -0,0 +1,90 @@ +History uses fts3 with an icu-based segmenter. These changes allow +building a sqlite3 binary which can read those files. + +Index: src/shell.c +=================================================================== +--- src/shell.c 2009-09-04 13:37:43.000000000 -0700 ++++ src/shell.c 2009-09-15 11:32:08.000000000 -0700 +@@ -3007,6 +3007,14 @@ + int i; + int rc = 0; + ++ /* Begin evanm patch. */ ++ extern int sqlite_shell_init_icu(); ++ if( !sqlite_shell_init_icu() ){ ++ fprintf(stderr, "%s: warning: couldn't find icudt38.dll; " ++ "queries against ICU FTS tables will fail.\n", argv[0]); ++ } ++ /* End evanm patch. */ ++ + Argv0 = argv[0]; + main_init(&data); + stdin_is_interactive = isatty(0); +Index: src/shell_icu_linux.c +=================================================================== +--- src/shell_icu_linux.c 1969-12-31 16:00:00.000000000 -0800 ++++ src/shell_icu_linux.c 2009-09-17 13:48:49.000000000 -0700 +@@ -0,0 +1,26 @@ ++/* Copyright 2007 Google Inc. All Rights Reserved. ++**/ ++ ++#include <limits.h> ++#include <unistd.h> ++#include "unicode/udata.h" ++ ++/* ++** This function attempts to load the ICU data tables from a data file. ++** Returns 0 on failure, nonzero on success. ++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. ++*/ ++int sqlite_shell_init_icu() { ++ char bin_dir[PATH_MAX + 1]; ++ int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX); ++ if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) ++ return 0; ++ bin_dir[bin_dir_size] = 0;; ++ ++ u_setDataDirectory(bin_dir); ++ // Only look for the packaged data file; ++ // the default behavior is to look for individual files. ++ UErrorCode err = U_ZERO_ERROR; ++ udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); ++ return err == U_ZERO_ERROR; ++} +Index: src/shell_icu_win.c +=================================================================== +--- src/shell_icu_win.c 1969-12-31 16:00:00.000000000 -0800 ++++ src/shell_icu_win.c 2011-03-03 14:29:11.000000000 -0700 +@@ -0,0 +1,32 @@ ++/* Copyright 2011 Google Inc. All Rights Reserved. ++**/ ++ ++#include <windows.h> ++#include "unicode/udata.h" ++ ++/* ++** This function attempts to load the ICU data tables from a DLL. ++** Returns 0 on failure, nonzero on success. ++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. ++*/ ++ ++#define ICU_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" ++int sqlite_shell_init_icu() { ++ HMODULE module; ++ FARPROC addr; ++ UErrorCode err; ++ ++ // Chrome dropped U_ICU_VERSION_SHORT from the icu data dll name. ++ module = LoadLibrary(L"icudt.dll"); ++ if (!module) ++ return 0; ++ ++ addr = GetProcAddress(module, ICU_DATA_SYMBOL); ++ if (!addr) ++ return 0; ++ ++ err = U_ZERO_ERROR; ++ udata_setCommonData(addr, &err); ++ ++ return 1; ++} diff --git a/third_party/sqlite/misc.patch b/third_party/sqlite/misc.patch index b90eba5..10fe084 100644 --- a/third_party/sqlite/misc.patch +++ b/third_party/sqlite/misc.patch @@ -1,100 +1,3 @@ -Index: Makefile.linux-gcc -=================================================================== ---- Makefile.linux-gcc 2009-09-03 13:32:06.000000000 -0700 -+++ Makefile.linux-gcc 2009-07-01 12:08:39.000000000 -0700 -@@ -14,7 +14,7 @@ - #### The toplevel directory of the source tree. This is the directory - # that contains this "Makefile.in" and the "configure.in" script. - # --TOP = ../sqlite -+TOP = .. - - #### C Compiler and options for use in building executables that - # will run on the platform that is doing the build. -@@ -33,13 +33,13 @@ - # appropriately: - # - #THREADSAFE = -DTHREADSAFE=1 --THREADSAFE = -DTHREADSAFE=0 -+THREADSAFE = -DTHREADSAFE=1 - - #### Specify any extra linker options needed to make the library - # thread safe - # - #THREADLIB = -lpthread --THREADLIB = -+THREADLIB = -lpthread - - #### Specify any extra libraries needed to access required functions. - # -@@ -57,8 +57,29 @@ - #OPTS = -DSQLITE_DEBUG=2 - #OPTS = -DSQLITE_DEBUG=1 - #OPTS = --OPTS = -DNDEBUG=1 --OPTS += -DHAVE_FDATASYNC=1 -+ -+# These flags match those for SQLITE_CFLAGS in config.mk. -+ -+OPTS += -DNDEBUG -+OPTS += -DSQLITE_CORE -+OPTS += -DSQLITE_ENABLE_FTS1 -DSQLITE_ENABLE_BROKEN_FTS1 -+OPTS += -DSQLITE_ENABLE_FTS2 -DSQLITE_ENABLE_BROKEN_FTS2 -+OPTS += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 -+OPTS += -DHAVE_USLEEP=1 -+ -+# Additional SQLite tests. -+OPTS += -DSQLITE_MEMDEBUG=1 -+ -+# Don't include these ones, they break the SQLite tests. -+# -DSQLITE_OMIT_ATTACH=1 \ -+# -DSQLITE_OMIT_LOAD_EXTENSION=1 \ -+# -DSQLITE_OMIT_VACUUM=1 \ -+# -DSQLITE_TRANSACTION_DEFAULT_IMMEDIATE=1 \ -+ -+SHELL_ICU = $(TOP)/src/shell_icu_linux.c -licuuc -+ -+# TODO(shess) I can't see why I need this setting. -+OPTS += -DOS_UNIX=1 - - #### The suffix to add to executable files. ".exe" for windows. - # Nothing for unix. -@@ -91,16 +112,16 @@ - - #### Extra compiler options needed for programs that use the TCL library. - # --#TCL_FLAGS = -+TCL_FLAGS = -I/usr/include/tcl8.4 - #TCL_FLAGS = -DSTATIC_BUILD=1 --TCL_FLAGS = -I/home/drh/tcltk/8.4linux -+#TCL_FLAGS = -I/home/drh/tcltk/8.4linux - #TCL_FLAGS = -I/home/drh/tcltk/8.4win -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.4linux/libtcl8.4g.a -lm -ldl -+LIBTCL = -ltcl8.4 -lm -ldl -+#LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl - #LIBTCL = /home/drh/tcltk/8.4win/libtcl84s.a -lmsvcrt - #LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc - -Index: ext/fts1/fts1.c -=================================================================== ---- ext/fts1/fts1.c 2009-09-04 13:37:41.000000000 -0700 -+++ ext/fts1/fts1.c 2009-09-14 18:16:55.000000000 -0700 -@@ -1225,10 +1225,6 @@ - break; - } - return rc; -- -- err: -- sqlite3_finalize(s); -- return rc; - } - - /* Like sql_step_statement(), but convert SQLITE_DONE to SQLITE_OK. Index: ext/icu/icu.c =================================================================== --- ext/icu/icu.c 2009-09-03 13:32:06.000000000 -0700 @@ -111,101 +14,6 @@ Index: ext/icu/icu.c #ifndef SQLITE_CORE #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 -Index: main.mk -=================================================================== ---- main.mk 2009-09-10 12:18:17.000000000 -0700 -+++ main.mk 2009-09-15 11:45:21.000000000 -0700 -@@ -69,6 +69,16 @@ - walker.o where.o utf.o vtab.o - - -+LIBOBJ += fts1.o \ -+ fts1_hash.o \ -+ fts1_tokenizer1.o \ -+ fts1_porter.o -+LIBOBJ += fts2.o \ -+ fts2_hash.o \ -+ fts2_icu.o \ -+ fts2_porter.o \ -+ fts2_tokenizer.o \ -+ fts2_tokenizer1.o - - # All of the source code files. - # -@@ -243,6 +253,25 @@ - $(TOP)/src/test_thread.c \ - $(TOP)/src/test_wsd.c - -+TESTSRC += \ -+ $(TOP)/ext/fts1/fts1.c \ -+ $(TOP)/ext/fts1/fts1.h \ -+ $(TOP)/ext/fts1/fts1_hash.c \ -+ $(TOP)/ext/fts1/fts1_hash.h \ -+ $(TOP)/ext/fts1/fts1_porter.c \ -+ $(TOP)/ext/fts1/fts1_tokenizer.h \ -+ $(TOP)/ext/fts1/fts1_tokenizer1.c -+TESTSRC += \ -+ $(TOP)/ext/fts2/fts2.c \ -+ $(TOP)/ext/fts2/fts2.h \ -+ $(TOP)/ext/fts2/fts2_hash.c \ -+ $(TOP)/ext/fts2/fts2_hash.h \ -+ $(TOP)/ext/fts2/fts2_icu.c \ -+ $(TOP)/ext/fts2/fts2_porter.c \ -+ $(TOP)/ext/fts2/fts2_tokenizer.h \ -+ $(TOP)/ext/fts2/fts2_tokenizer.c \ -+ $(TOP)/ext/fts2/fts2_tokenizer1.c -+ - #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c - #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c - -@@ -314,8 +343,8 @@ - - sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h - $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \ -- $(TOP)/src/shell.c \ -- libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) -+ $(TOP)/src/shell.c $(SHELL_ICU) \ -+ libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) -ldl - - objects: $(LIBOBJ_ORIG) - -@@ -447,6 +476,20 @@ - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c - - -+ -+ -+fts1.o: $(TOP)/ext/fts1/fts1.c $(HDR) $(EXTHDR) -+ $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1.c -+ -+fts1_hash.o: $(TOP)/ext/fts1/fts1_hash.c $(HDR) $(EXTHDR) -+ $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_hash.c -+ -+fts1_tokenizer1.o: $(TOP)/ext/fts1/fts1_tokenizer1.c $(HDR) $(EXTHDR) -+ $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_tokenizer1.c -+ -+fts1_porter.o: $(TOP)/ext/fts1/fts1_porter.c $(HDR) $(EXTHDR) -+ $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_porter.c -+ - # Rules for building test programs and for running tests - # - tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a -@@ -484,6 +527,15 @@ - test: testfixture$(EXE) sqlite3$(EXE) - ./testfixture$(EXE) $(TOP)/test/veryquick.test - -+ftstest: testfixture$(EXE) sqlite3$(EXE) -+ ./testfixture$(EXE) $(TOP)/test/fts.test -+ -+fts1test: testfixture$(EXE) sqlite3$(EXE) -+ ./testfixture$(EXE) $(TOP)/test/fts1.test -+ -+fts2test: testfixture$(EXE) sqlite3$(EXE) -+ ./testfixture$(EXE) $(TOP)/test/fts2.test -+ - sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \ - $(TOP)/tool/spaceanal.tcl - sed \ Index: src/expr.c =================================================================== --- src/expr.c 2009-09-08 12:16:11.000000000 -0700 @@ -234,953 +42,3 @@ Index: src/func.c } } sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); -Index: src/os.h -=================================================================== ---- src/os.h 2009-09-04 13:37:42.000000000 -0700 -+++ src/os.h 2009-09-14 18:18:24.000000000 -0700 -@@ -29,6 +29,10 @@ - ** will defined to either 1 or 0. One of the four will be 1. The other - ** three will be 0. - */ -+#ifdef OS_SYMBIAN -+# define SQLITE_OS_SYMBIAN 1 -+# define SQLITE_OS_OTHER 1 -+#endif - #if defined(SQLITE_OS_OTHER) - # if SQLITE_OS_OTHER==1 - # undef SQLITE_OS_UNIX -Index: src/os_unix.c -=================================================================== ---- src/os_unix.c 2009-09-10 12:14:55.000000000 -0700 -+++ src/os_unix.c 2009-09-15 16:50:43.000000000 -0700 -@@ -3215,6 +3215,7 @@ - ********************** End sqlite3_file Methods ******************************* - ******************************************************************************/ - -+ - /* - ** This division contains definitions of sqlite3_io_methods objects that - ** implement various file locking strategies. It also contains definitions -@@ -3496,9 +3497,16 @@ - */ - - /* -+** Initializes a unixFile structure with zeros. -+*/ -+void initUnixFile(sqlite3_file* file) { -+ memset(file, 0, sizeof(unixFile)); -+} -+ -+/* - ** Initialize the contents of the unixFile structure pointed to by pId. - */ --static int fillInUnixFile( -+int fillInUnixFile( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - int h, /* Open file descriptor of file being opened */ - int dirfd, /* Directory file descriptor */ -Index: src/os_win.c -=================================================================== ---- src/os_win.c 2009-09-10 15:08:39.000000000 -0700 -+++ src/os_win.c 2009-09-14 18:26:16.000000000 -0700 -@@ -1890,4 +1890,11 @@ - return SQLITE_OK; - } - -+void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { -+ winFile* winSQLite3File = (winFile*)file; -+ memset(file, 0, sizeof(*file)); -+ winSQLite3File->pMethod = &winIoMethod; -+ winSQLite3File->h = handle; -+} -+ - #endif /* SQLITE_OS_WIN */ -Index: src/pcache.c -=================================================================== ---- src/pcache.c 2009-09-04 13:37:42.000000000 -0700 -+++ src/pcache.c 2009-09-15 16:41:55.000000000 -0700 -@@ -542,14 +542,12 @@ - return nPage; - } - --#ifdef SQLITE_TEST - /* - ** Get the suggested cache-size value. - */ - int sqlite3PcacheGetCachesize(PCache *pCache){ - return pCache->nMax; - } --#endif - - /* - ** Set the suggested cache-size value. -Index: src/pcache.h -=================================================================== ---- src/pcache.h 2009-09-04 13:37:42.000000000 -0700 -+++ src/pcache.h 2009-09-15 16:41:52.000000000 -0700 -@@ -139,9 +139,7 @@ - ** of the suggested cache-sizes. - */ - void sqlite3PcacheSetCachesize(PCache *, int); --#ifdef SQLITE_TEST - int sqlite3PcacheGetCachesize(PCache *); --#endif - - #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - /* Try to return memory used by the pcache module to the main memory heap */ -Index: src/shell.c -=================================================================== ---- src/shell.c 2009-09-04 13:37:43.000000000 -0700 -+++ src/shell.c 2009-09-15 11:32:08.000000000 -0700 -@@ -3007,6 +3007,18 @@ - int i; - int rc = 0; - -+ /* Begin evanm patch. */ -+#ifdef SQLITE_GEARS_DISABLE_SHELL_ICU -+ /* Gears doesn't use this. */ -+#else -+ extern int sqlite_shell_init_icu(); -+ if( !sqlite_shell_init_icu() ){ -+ fprintf(stderr, "%s: warning: couldn't find icudt38.dll; " -+ "queries against ICU FTS tables will fail.\n", argv[0]); -+ } -+#endif -+ /* End evanm patch. */ -+ - Argv0 = argv[0]; - main_init(&data); - stdin_is_interactive = isatty(0); -Index: src/sqlite3ext.h -=================================================================== ---- src/sqlite3ext.h 2009-09-03 13:32:06.000000000 -0700 -+++ src/sqlite3ext.h 2009-09-15 11:34:43.000000000 -0700 -@@ -372,9 +372,15 @@ - #define sqlite3_next_stmt sqlite3_api->next_stmt - #define sqlite3_sql sqlite3_api->sql - #define sqlite3_status sqlite3_api->status --#endif /* SQLITE_CORE */ - - #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0; - #define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; - -+#else -+ -+#define SQLITE_EXTENSION_INIT1 -+#define SQLITE_EXTENSION_INIT2(v) -+ -+#endif /* SQLITE_CORE */ -+ - #endif /* _SQLITE3EXT_H_ */ -Index: src/test_autoext.c -=================================================================== ---- src/test_autoext.c 2009-09-03 13:32:06.000000000 -0700 -+++ src/test_autoext.c 2009-09-15 18:14:35.000000000 -0700 -@@ -17,7 +17,9 @@ - #include "sqlite3ext.h" - - #ifndef SQLITE_OMIT_LOAD_EXTENSION -+#ifndef SQLITE_CORE - static SQLITE_EXTENSION_INIT1 -+#endif - - /* - ** The sqr() SQL function returns the square of its input value. -Index: src/quick.test -=================================================================== ---- test/quick.test 2009-09-04 13:37:44.000000000 -0700 -+++ test/quick.test 2009-09-15 11:34:54.000000000 -0700 -@@ -58,6 +58,9 @@ - crash7.test - delete3.test - fts3.test -+ fts.test -+ fts1.test -+ fts2.test - fuzz.test - fuzz3.test - fuzz_malloc.test -Index: src/os_symbian.cc -=================================================================== ---- src/os_symbian.cc 1969-12-31 16:00:00.000000000 -0800 -+++ src/os_symbian.cc 2009-07-01 12:08:37.000000000 -0700 -@@ -0,0 +1,579 @@ -+// Copyright 2008, Google Inc. -+// -+// Redistribution and use in source and binary forms, with or without -+// modification, are permitted provided that the following conditions are met: -+// -+// 1. Redistributions of source code must retain the above copyright notice, -+// this list of conditions and the following disclaimer. -+// 2. Redistributions in binary form must reproduce the above copyright notice, -+// this list of conditions and the following disclaimer in the documentation -+// and/or other materials provided with the distribution. -+// 3. Neither the name of Google Inc. nor the names of its contributors may be -+// used to endorse or promote products derived from this software without -+// specific prior written permission. -+// -+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ -+// This file contains code that is specific to Symbian. -+// Differently from the rest of SQLite, it is implemented in C++ as this is -+// the native language of the OS and all interfaces we need to use are C++. -+// -+// This file follows the Gears code style guidelines. -+ -+#ifdef OS_SYMBIAN -+#include <coemain.h> -+#include <e32math.h> -+#include <f32file.h> -+#include <utf.h> -+ -+extern "C" { -+#include "sqliteInt.h" -+#include "os_common.h" -+} -+ -+const TInt kFileLockAttempts = 3; -+ -+// The global file system session. -+RFs g_fs_session; -+ -+static TInt UTF8ToUTF16(const char *in, TDes *out16) { -+ assert(in); -+ TPtrC8 in_des(reinterpret_cast<const unsigned char*>(in)); -+ return CnvUtfConverter::ConvertToUnicodeFromUtf8(*out16, in_des); -+} -+ -+static TInt UTF16ToUTF8(const TDesC16& in16, TDes8 *out8) { -+ return CnvUtfConverter::ConvertFromUnicodeToUtf8(*out8, in16); -+} -+ -+// The SymbianFile structure is a subclass of sqlite3_file* specific to the -+// Symbian portability layer. -+struct SymbianFile { -+ const sqlite3_io_methods *methods; -+ RFile handle; // The file handle -+ TUint8 lock_type; // Type of lock currently held on this file -+ TUint16 shared_lock_byte; // Randomly chosen byte used as a shared lock -+}; -+ -+static SymbianFile* ConvertToSymbianFile(sqlite3_file* const id) { -+ assert(id); -+ return reinterpret_cast<SymbianFile*>(id); -+} -+ -+static int SymbianClose(sqlite3_file *id) { -+ SymbianFile *file_id = ConvertToSymbianFile(id); -+ file_id->handle.Close(); -+ OpenCounter(-1); -+ return SQLITE_OK; -+} -+ -+static int SymbianRead(sqlite3_file *id, -+ void *buffer, -+ int amount, -+ sqlite3_int64 offset) { -+ assert(buffer); -+ assert(amount >=0); -+ assert(offset >=0); -+ -+ SymbianFile* file_id = ConvertToSymbianFile(id); -+ TPtr8 dest(static_cast<unsigned char*>(buffer), amount); -+ -+ if (KErrNone == file_id->handle.Read(offset, dest, amount)) { -+ if (dest.Length() == amount) { -+ return SQLITE_OK; -+ } else { -+ return SQLITE_IOERR_SHORT_READ; -+ } -+ } else { -+ return SQLITE_IOERR; -+ } -+} -+ -+static int SymbianWrite(sqlite3_file *id, -+ const void *buffer, -+ int amount, -+ sqlite3_int64 offset) { -+ assert(buffer); -+ assert(amount >=0); -+ assert(offset >=0); -+ -+ SymbianFile *file_id = ConvertToSymbianFile(id); -+ TPtrC8 src(static_cast<const unsigned char*>(buffer), amount); -+ if (file_id->handle.Write(offset, src) != KErrNone) { -+ return SQLITE_IOERR_WRITE; -+ } -+ -+ return SQLITE_OK; -+} -+ -+static int SymbianTruncate(sqlite3_file *id, sqlite3_int64 bytes) { -+ assert(bytes >=0); -+ -+ SymbianFile *file_id = ConvertToSymbianFile(id); -+ if (file_id->handle.SetSize(bytes) != KErrNone) { -+ return SQLITE_IOERR; -+ } -+ return SQLITE_OK; -+} -+ -+static int SymbianSync(sqlite3_file *id, int /*flags*/) { -+ SymbianFile *file_id = ConvertToSymbianFile(id); -+ if (file_id->handle.Flush() != KErrNone) { -+ return SQLITE_IOERR; -+ } else { -+ return SQLITE_OK; -+ } -+} -+ -+static int SymbianFileSize(sqlite3_file *id, sqlite3_int64 *size) { -+ assert(size); -+ -+ SymbianFile *file_id = ConvertToSymbianFile(id); -+ TInt size_tmp; -+ if (file_id->handle.Size(size_tmp) != KErrNone) { -+ return SQLITE_IOERR; -+ } -+ *size = size_tmp; -+ return SQLITE_OK; -+} -+ -+// File lock/unlock functions; see os_win.c for a description -+// of the algorithm used. -+static int GetReadLock(SymbianFile *file) { -+ file->shared_lock_byte = Math::Random() % (SHARED_SIZE - 1); -+ return file->handle.Lock(SHARED_FIRST + file->shared_lock_byte, 1); -+} -+ -+static int UnlockReadLock(SymbianFile *file) { -+ return file->handle.UnLock(SHARED_FIRST + file->shared_lock_byte, 1); -+} -+ -+static int SymbianLock(sqlite3_file *id, int lock_type) { -+ SymbianFile *file = ConvertToSymbianFile(id); -+ if (file->lock_type >= lock_type) { -+ return SQLITE_OK; -+ } -+ -+ // Make sure the locking sequence is correct -+ assert(file->lock_type != NO_LOCK || lock_type == SHARED_LOCK); -+ assert(lock_type != PENDING_LOCK); -+ assert(lock_type != RESERVED_LOCK || file->lock_type == SHARED_LOCK); -+ -+ // Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or -+ // a SHARED lock. If we are acquiring a SHARED lock, the acquisition of -+ // the PENDING_LOCK byte is temporary. -+ int new_lock_type = file->lock_type; -+ int got_pending_lock = 0; -+ int res = KErrNone; -+ if (file->lock_type == NO_LOCK || -+ (lock_type == EXCLUSIVE_LOCK && file->lock_type == RESERVED_LOCK)) { -+ int count = kFileLockAttempts; -+ while (count-- > 0 && -+ (res = file->handle.Lock(PENDING_BYTE, 1)) != KErrNone ) { -+ // Try 3 times to get the pending lock. The pending lock might be -+ // held by another reader process who will release it momentarily. -+ OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); -+ User::After(1000); -+ } -+ got_pending_lock = (res == KErrNone? 1 : 0); -+ } -+ -+ // Acquire a shared lock -+ if (lock_type == SHARED_LOCK && res == KErrNone) { -+ assert(file->lock_type == NO_LOCK); -+ res = GetReadLock(file); -+ if (res == KErrNone) { -+ new_lock_type = SHARED_LOCK; -+ } -+ } -+ -+ // Acquire a RESERVED lock -+ if (lock_type == RESERVED_LOCK && res == KErrNone) { -+ assert(file->lock_type == SHARED_LOCK); -+ res = file->handle.Lock(RESERVED_BYTE, 1); -+ if (res == KErrNone) { -+ new_lock_type = RESERVED_LOCK; -+ } -+ } -+ -+ // Acquire a PENDING lock -+ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { -+ new_lock_type = PENDING_LOCK; -+ got_pending_lock = 0; -+ } -+ -+ // Acquire an EXCLUSIVE lock -+ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { -+ assert(file->lock_type >= SHARED_LOCK); -+ res = UnlockReadLock(file); -+ OSTRACE2("unreadlock = %d\n", res); -+ res = file->handle.Lock(SHARED_FIRST, SHARED_SIZE); -+ if (res == KErrNone) { -+ new_lock_type = EXCLUSIVE_LOCK; -+ } else { -+ OSTRACE2("error-code = %d\n", GetLastError()); -+ GetReadLock(file); -+ } -+ } -+ -+ // If we are holding a PENDING lock that ought to be released, then -+ // release it now. -+ if (got_pending_lock && lock_type == SHARED_LOCK) { -+ file->handle.UnLock(PENDING_BYTE, 1); -+ } -+ -+ // Update the state of the lock held in the file descriptor, then -+ // return the appropriate result code. -+ file->lock_type = new_lock_type; -+ if (res == KErrNone) { -+ return SQLITE_OK; -+ } else { -+ OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", file->handle, -+ lock_type, new_lock_type); -+ return SQLITE_BUSY; -+ } -+} -+ -+static int SymbianUnlock(sqlite3_file *id, int lock_type) { -+ int type; -+ int rc = SQLITE_OK; -+ SymbianFile *file = ConvertToSymbianFile(id); -+ assert(lock_type <= SHARED_LOCK); -+ OSTRACE5("UNLOCK %d to %d was %d(%d)\n", file->handle, lock_type, -+ file->lock_type, file->shared_lock_byte); -+ type = file->lock_type; -+ if (type >= EXCLUSIVE_LOCK) { -+ file->handle.UnLock(SHARED_FIRST, SHARED_SIZE); -+ if (lock_type == SHARED_LOCK && GetReadLock(file) != KErrNone) { -+ // This should never happen. We should always be able to -+ // reacquire the read lock -+ rc = SQLITE_IOERR_UNLOCK; -+ } -+ } -+ if (type >= RESERVED_LOCK) { -+ file->handle.UnLock(RESERVED_BYTE, 1); -+ } -+ if (lock_type == NO_LOCK && type >= SHARED_LOCK) { -+ UnlockReadLock(file); -+ } -+ if (type >= PENDING_LOCK) { -+ file->handle.UnLock(PENDING_BYTE, 1); -+ } -+ file->lock_type = lock_type; -+ return rc; -+} -+ -+static int SymbianCheckReservedLock(sqlite3_file *id, int *result) { -+ int rc; -+ SymbianFile *file = ConvertToSymbianFile(id); -+ if (file->lock_type >= RESERVED_LOCK) { -+ rc = 1; -+ OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); -+ } else { -+ rc = file->handle.Lock(RESERVED_BYTE, 1); -+ if (rc == KErrNone) { -+ file->handle.UnLock(RESERVED_BYTE, 1); -+ } -+ rc = !rc; -+ OSTRACE3("TEST WR-LOCK %d %d (remote)\n", file->handle, rc); -+ } -+ *result = rc; -+ return SQLITE_OK; -+} -+ -+static int SymbianFileControl(sqlite3_file */*id*/, -+ int /*op*/, -+ void */*arg*/) { -+ return SQLITE_OK; -+} -+ -+static int SymbianSectorSize(sqlite3_file */*id*/) { -+ return SQLITE_DEFAULT_SECTOR_SIZE; -+} -+ -+static int SymbianDeviceCharacteristics(sqlite3_file */*id*/) { -+ return 0; -+} -+ -+/* -+** This vector defines all the methods that can operate on a -+** sqlite3_file for Symbian. -+*/ -+static const sqlite3_io_methods SymbianIoMethod = { -+ 1, // iVersion -+ SymbianClose, -+ SymbianRead, -+ SymbianWrite, -+ SymbianTruncate, -+ SymbianSync, -+ SymbianFileSize, -+ SymbianLock, -+ SymbianUnlock, -+ SymbianCheckReservedLock, -+ SymbianFileControl, -+ SymbianSectorSize, -+ SymbianDeviceCharacteristics -+}; -+ -+// ============================================================================ -+// vfs methods begin here -+// ============================================================================ -+static int SymbianOpen(sqlite3_vfs */*vfs*/, -+ const char *name, -+ sqlite3_file *id, -+ int flags, -+ int *out_flags) { -+ TUint desired_access; -+ TUint share_mode; -+ TInt err = KErrNone; -+ TFileName name_utf16; -+ SymbianFile *file = ConvertToSymbianFile(id); -+ -+ if (out_flags) { -+ *out_flags = flags; -+ } -+ -+ // if the name is NULL we have to open a temporary file. -+ if (!name) { -+ TPath private_path; -+ TFileName file_name; -+ if (g_fs_session.PrivatePath(private_path) != KErrNone) { -+ return SQLITE_CANTOPEN; -+ } -+ if (file->handle.Temp(g_fs_session, -+ private_path, -+ file_name, -+ EFileWrite) != -+ KErrNone) { -+ return SQLITE_CANTOPEN; -+ } -+ file->methods = &SymbianIoMethod; -+ file->lock_type = NO_LOCK; -+ file->shared_lock_byte = 0; -+ OpenCounter(+1); -+ return SQLITE_OK; -+ } -+ -+ if (UTF8ToUTF16(name, &name_utf16) != KErrNone) -+ return SQLITE_CANTOPEN; -+ -+ if (flags & SQLITE_OPEN_READWRITE) { -+ desired_access = EFileWrite; -+ } else { -+ desired_access = EFileRead; -+ } -+ if (flags & SQLITE_OPEN_MAIN_DB) { -+ share_mode = EFileShareReadersOrWriters; -+ } else { -+ share_mode = 0; -+ } -+ -+ if (flags & SQLITE_OPEN_CREATE) { -+ err = file->handle.Create(g_fs_session, -+ name_utf16, -+ desired_access | share_mode); -+ if (err != KErrNone && err != KErrAlreadyExists) { -+ return SQLITE_CANTOPEN; -+ } -+ } -+ -+ if (err != KErrNone) { -+ err = file->handle.Open(g_fs_session, -+ name_utf16, -+ desired_access | share_mode); -+ if (err != KErrNone && flags & SQLITE_OPEN_READWRITE) { -+ if (out_flags) { -+ *out_flags = (flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE; -+ } -+ desired_access = EFileRead; -+ err = file->handle.Open(g_fs_session, -+ name_utf16, -+ desired_access | share_mode); -+ } -+ if (err != KErrNone) { -+ return SQLITE_CANTOPEN; -+ } -+ } -+ file->methods = &SymbianIoMethod; -+ file->lock_type = NO_LOCK; -+ file->shared_lock_byte = 0; -+ OpenCounter(+1); -+ return SQLITE_OK; -+} -+ -+static int SymbianDelete(sqlite3_vfs */*vfs*/, -+ const char *file_name, -+ int /*sync_dir*/) { -+ assert(file_name); -+ TFileName file_name_utf16; -+ -+ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ TInt result = g_fs_session.Delete(file_name_utf16); -+ return (result == KErrNone || result == KErrPathNotFound)? -+ SQLITE_OK : SQLITE_IOERR_DELETE; -+} -+ -+static int SymbianAccess(sqlite3_vfs */*vfs*/, -+ const char *file_name, -+ int flags, -+ int *result) { -+ assert(file_name); -+ TEntry entry; -+ TFileName file_name_utf16; -+ -+ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ if (g_fs_session.Entry(file_name_utf16, entry) != KErrNone) { -+ *result = 0; -+ return SQLITE_OK; -+ } -+ -+ switch (flags) { -+ case SQLITE_ACCESS_READ: -+ case SQLITE_ACCESS_EXISTS: -+ *result = !entry.IsDir(); -+ break; -+ case SQLITE_ACCESS_READWRITE: -+ *result = !entry.IsDir() && !entry.IsReadOnly(); -+ break; -+ default: -+ return SQLITE_ERROR; -+ } -+ -+ return SQLITE_OK; -+} -+ -+static int SymbianFullPathname(sqlite3_vfs */*vfs*/, -+ const char *relative, -+ int full_len, -+ char *full) { -+ assert(relative); -+ assert(full); -+ -+ TParse parse; -+ TPath relative_utf16; -+ TPath base_path; -+ TPtr8 full_utf8(reinterpret_cast<unsigned char*>(full), full_len); -+ -+ g_fs_session.PrivatePath(base_path); -+ -+ if (UTF8ToUTF16(relative, &relative_utf16) != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ if (parse.Set(relative_utf16, &base_path, NULL) != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ TDesC full_utf16(parse.FullName()); -+ if (UTF16ToUTF8(relative_utf16, &full_utf8) != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ full_utf8.PtrZ(); -+ return SQLITE_OK; -+} -+ -+static int SymbianRandomness(sqlite3_vfs */*vfs*/, int buf_len, char *buffer) { -+ assert(buffer); -+ TInt64 seed = User::TickCount(); -+ for (TInt i = 0; i < buf_len; i++) { -+ buffer[i] = Math::Rand(seed) % 255; -+ } -+ return SQLITE_OK; -+} -+ -+static int SymbianSleep(sqlite3_vfs */*vfs*/, int microsec) { -+ User::After(microsec); -+ return SQLITE_OK; -+} -+ -+int SymbianCurrentTime(sqlite3_vfs */*vfs*/, double *now) { -+ _LIT(kEpoch, "19700101:000000.000000"); -+ assert(now); -+ TTime time; -+ TTime epoch_time(kEpoch); -+ TTimeIntervalSeconds interval; -+ -+ time.HomeTime(); -+ // calculate seconds elapsed since 1-1-1970 -+ time.SecondsFrom(epoch_time, interval); -+ -+ // Julian date @ 1-1-1970 = 2440587.5 -+ // seconds per day = 86400.0 -+ *now = interval.Int()/86400.0 + 2440587.5; -+ return SQLITE_OK; -+} -+ -+static int SymbianGetLastError(sqlite3_vfs */*vfs*/, -+ int /*buf_len*/, -+ char */*buf*/) { -+ assert(buf[0] == '\0'); -+ return 0; -+} -+ -+// Interfaces for opening a shared library, finding entry points -+// within the shared library, and closing the shared library. -+// TODO(marcogelmi): implement. -+#define SymbianDlOpen 0 -+#define SymbianDlError 0 -+#define SymbianDlSym 0 -+#define SymbianDlClose 0 -+ -+// Initialize and deinitialize the operating system interface. -+int sqlite3_os_init(void) { -+ static sqlite3_vfs symbian_vfs = { -+ 1, // iVersion -+ sizeof(SymbianFile), // szOsFile -+ KMaxPath, // mxPathname -+ 0, // pNext -+ "symbian", // name -+ 0, // pAppData -+ -+ SymbianOpen, // xOpen -+ SymbianDelete, // xDelete -+ SymbianAccess, // xAccess -+ SymbianFullPathname, // xFullPathname -+ SymbianDlOpen, // xDlOpen -+ SymbianDlError, // xDlError -+ SymbianDlSym, // xDlSym -+ SymbianDlClose, // xDlClose -+ SymbianRandomness, // xRandomness -+ SymbianSleep, // xSleep -+ SymbianCurrentTime, // xCurrentTime -+ SymbianGetLastError // xGetLastError -+ }; -+ -+ if (g_fs_session.Connect() != KErrNone) { -+ return SQLITE_ERROR; -+ } -+ -+ if (g_fs_session.ShareAuto() != KErrNone) { -+ g_fs_session.Close(); -+ return SQLITE_ERROR; -+ } -+ -+ sqlite3_vfs_register(&symbian_vfs, 1); -+ return SQLITE_OK; -+} -+ -+int sqlite3_os_end(void) { -+ g_fs_session.Close(); -+ return SQLITE_OK; -+} -+ -+#endif /* OS_SYMBIAN*/ -Index: src/shell_icu_linux.c -=================================================================== ---- src/shell_icu_linux.c 1969-12-31 16:00:00.000000000 -0800 -+++ src/shell_icu_linux.c 2009-09-17 13:48:49.000000000 -0700 -@@ -0,0 +1,26 @@ -+/* Copyright 2007 Google Inc. All Rights Reserved. -+**/ -+ -+#include <limits.h> -+#include <unistd.h> -+#include "unicode/udata.h" -+ -+/* -+** This function attempts to load the ICU data tables from a data file. -+** Returns 0 on failure, nonzero on success. -+** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. -+*/ -+int sqlite_shell_init_icu() { -+ char bin_dir[PATH_MAX + 1]; -+ int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX); -+ if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) -+ return 0; -+ bin_dir[bin_dir_size] = 0;; -+ -+ u_setDataDirectory(bin_dir); -+ // Only look for the packaged data file; -+ // the default behavior is to look for individual files. -+ UErrorCode err = U_ZERO_ERROR; -+ udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); -+ return err == U_ZERO_ERROR; -+} -Index: src/shell_icu_win.c -=================================================================== ---- src/shell_icu_win.c 1969-12-31 16:00:00.000000000 -0800 -+++ src/shell_icu_win.c 2011-03-03 14:29:11.000000000 -0700 -@@ -0,0 +1,32 @@ -+/* Copyright 2011 Google Inc. All Rights Reserved. -+**/ -+ -+#include <windows.h> -+#include "unicode/udata.h" -+ -+/* -+** This function attempts to load the ICU data tables from a DLL. -+** Returns 0 on failure, nonzero on success. -+** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. -+*/ -+ -+#define ICU_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" -+int sqlite_shell_init_icu() { -+ HMODULE module; -+ FARPROC addr; -+ UErrorCode err; -+ -+ // Chrome dropped U_ICU_VERSION_SHORT from the icu data dll name. -+ module = LoadLibrary(L"icudt.dll"); -+ if (!module) -+ return 0; -+ -+ addr = GetProcAddress(module, ICU_DATA_SYMBOL); -+ if (!addr) -+ return 0; -+ -+ err = U_ZERO_ERROR; -+ udata_setCommonData(addr, &err); -+ -+ return 1; -+} -Index: test/fts.test -=================================================================== ---- test/fts.test 1969-12-31 16:00:00.000000000 -0800 -+++ test/fts.test 2009-07-01 12:08:39.000000000 -0700 -@@ -0,0 +1,61 @@ -+# -+# 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 runs the fts tests. -+# -+# $Id$ -+ -+proc lshift {lvar} { -+ upvar $lvar l -+ set ret [lindex $l 0] -+ set l [lrange $l 1 end] -+ return $ret -+} -+while {[set arg [lshift argv]] != ""} { -+ switch -- $arg { -+ -sharedpagercache { -+ sqlite3_enable_shared_cache 1 -+ } -+ default { -+ set argv [linsert $argv 0 $arg] -+ break -+ } -+ } -+} -+ -+set testdir [file dirname $argv0] -+source $testdir/tester.tcl -+rename finish_test really_finish_test -+proc finish_test {} {} -+set ISQUICK 1 -+ -+set EXCLUDE { -+ fts.test -+ fts1.test -+ fts2.test -+} -+ -+if {[sqlite3 -has-codec]} { -+ # lappend EXCLUDE \ -+ # conflict.test -+} -+ -+foreach testfile [lsort -dictionary [glob $testdir/fts*.test]] { -+ set tail [file tail $testfile] -+ puts "test: $tail" -+ if {[lsearch -exact $EXCLUDE $tail]>=0} continue -+ source $testfile -+ catch {db close} -+ if {$sqlite_open_file_count>0} { -+ puts "$tail did not close all files: $sqlite_open_file_count" -+ incr nErr -+ lappend ::failList $tail -+ } -+} -+source $testdir/misuse.test -+ -+set sqlite_open_file_count 0 -+really_finish_test -Index: test/fts1.test -=================================================================== ---- test/fts1.test 1969-12-31 16:00:00.000000000 -0800 -+++ test/fts1.test 2009-07-01 12:08:39.000000000 -0700 -@@ -0,0 +1,61 @@ -+# -+# 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 runs the fts tests. -+# -+# $Id$ -+ -+proc lshift {lvar} { -+ upvar $lvar l -+ set ret [lindex $l 0] -+ set l [lrange $l 1 end] -+ return $ret -+} -+while {[set arg [lshift argv]] != ""} { -+ switch -- $arg { -+ -sharedpagercache { -+ sqlite3_enable_shared_cache 1 -+ } -+ default { -+ set argv [linsert $argv 0 $arg] -+ break -+ } -+ } -+} -+ -+set testdir [file dirname $argv0] -+source $testdir/tester.tcl -+rename finish_test really_finish_test -+proc finish_test {} {} -+set ISQUICK 1 -+ -+set EXCLUDE { -+ fts.test -+ fts1.test -+ fts2.test -+} -+ -+if {[sqlite3 -has-codec]} { -+ # lappend EXCLUDE \ -+ # conflict.test -+} -+ -+foreach testfile [lsort -dictionary [glob $testdir/fts1*.test]] { -+ set tail [file tail $testfile] -+ puts "test: $tail" -+ if {[lsearch -exact $EXCLUDE $tail]>=0} continue -+ source $testfile -+ catch {db close} -+ if {$sqlite_open_file_count>0} { -+ puts "$tail did not close all files: $sqlite_open_file_count" -+ incr nErr -+ lappend ::failList $tail -+ } -+} -+source $testdir/misuse.test -+ -+set sqlite_open_file_count 0 -+really_finish_test diff --git a/third_party/sqlite/preload-cache.patch b/third_party/sqlite/preload-cache.patch index 8dc5778..7a361d1 100644 --- a/third_party/sqlite/preload-cache.patch +++ b/third_party/sqlite/preload-cache.patch @@ -1,3 +1,6 @@ +Adds a new API function sqlite3_preload(). This fills the page cache +with the first pages of the database. + Index: src/build.c =================================================================== --- src/build.c 2009-09-11 07:02:46.000000000 -0700 @@ -19,7 +22,7 @@ Index: src/build.c + +/* Begin preload-cache.patch for Chromium */ +/* See declaration in sqlite3.h for information */ -+int sqlite3Preload(sqlite3 *db) ++int sqlite3_preload(sqlite3 *db) +{ + Pager *pPager; + Btree *pBt; @@ -63,7 +66,7 @@ Index: src/sqlite3.h.in +** them all and try to load them. If none are loadable successfully, we return +** an error. Otherwise, we return OK. +*/ -+int sqlite3Preload(sqlite3 *db); ++int sqlite3_preload(sqlite3 *db); +/* End preload-cache.patch for Chromium */ + /* @@ -242,3 +245,36 @@ Index: src/pager.h void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerIsMemdb(Pager*); +Index: src/pcache.c +=================================================================== +--- src/pcache.c 2009-09-04 13:37:42.000000000 -0700 ++++ src/pcache.c 2009-09-15 16:41:55.000000000 -0700 +@@ -542,14 +542,12 @@ + return nPage; + } + +-#ifdef SQLITE_TEST + /* + ** Get the suggested cache-size value. + */ + int sqlite3PcacheGetCachesize(PCache *pCache){ + return pCache->nMax; + } +-#endif + + /* + ** Set the suggested cache-size value. +Index: src/pcache.h +=================================================================== +--- src/pcache.h 2009-09-04 13:37:42.000000000 -0700 ++++ src/pcache.h 2009-09-15 16:41:52.000000000 -0700 +@@ -139,9 +139,7 @@ + ** of the suggested cache-sizes. + */ + void sqlite3PcacheSetCachesize(PCache *, int); +-#ifdef SQLITE_TEST + int sqlite3PcacheGetCachesize(PCache *); +-#endif + + #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + /* Try to return memory used by the pcache module to the main memory heap */ diff --git a/third_party/sqlite/preprocessed/sqlite3.h b/third_party/sqlite/preprocessed/sqlite3.h index b9452de..c487f95 100644 --- a/third_party/sqlite/preprocessed/sqlite3.h +++ b/third_party/sqlite/preprocessed/sqlite3.h @@ -4694,7 +4694,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff ** them all and try to load them. If none are loadable successfully, we return ** an error. Otherwise, we return OK. */ -int sqlite3Preload(sqlite3 *db); +SQLITE_API int sqlite3_preload(sqlite3 *db); /* End preload-cache.patch for Chromium */ /* diff --git a/third_party/sqlite/safe-tolower.patch b/third_party/sqlite/safe-tolower.patch index a2ea8af..f754d3a 100644 --- a/third_party/sqlite/safe-tolower.patch +++ b/third_party/sqlite/safe-tolower.patch @@ -92,45 +92,6 @@ Index: ext/fts3/fts3_tokenizer1.c } *ppToken = c->pToken; *pnBytes = n; -Index: ext/fts1/simple_tokenizer.c -=================================================================== ---- ext/fts1/simple_tokenizer.c 2009-09-03 13:32:06.000000000 -0700 -+++ ext/fts1/simple_tokenizer.c 2009-09-02 11:40:21.000000000 -0700 -@@ -138,7 +138,7 @@ - ** case-insensitivity. - */ - char ch = c->pCurrent[ii]; -- c->zToken[ii] = (unsigned char)ch<0x80 ? tolower(ch) : ch; -+ c->zToken[ii] = ((ch>='A' && ch<='Z') ? (ch-'A'+'a') : ch); - } - c->zToken[n] = '\0'; - *ppToken = c->zToken; -Index: ext/fts1/fts1_tokenizer1.c -=================================================================== ---- ext/fts1/fts1_tokenizer1.c 2009-09-03 13:32:06.000000000 -0700 -+++ ext/fts1/fts1_tokenizer1.c 2009-09-02 11:40:21.000000000 -0700 -@@ -182,7 +182,7 @@ - ** case-insensitivity. - */ - unsigned char ch = p[iStartOffset+i]; -- c->pToken[i] = ch<0x80 ? tolower(ch) : ch; -+ c->pToken[i] = (ch>='A' && ch<='Z') ? (ch-'A'+'a') : ch; - } - *ppToken = c->pToken; - *pnBytes = n; -Index: ext/fts1/fts1.c -=================================================================== ---- ext/fts1/fts1.c 2009-09-04 13:37:41.000000000 -0700 -+++ ext/fts1/fts1.c 2009-09-14 18:16:55.000000000 -0700 -@@ -208,7 +208,7 @@ - return (c&0x80)==0 ? isspace(c) : 0; - } - static int safe_tolower(char c){ -- return (c&0x80)==0 ? tolower(c) : c; -+ return (c>='A' && c<='Z') ? (c-'A'+'a') : c; - } - static int safe_isalnum(char c){ - return (c&0x80)==0 ? isalnum(c) : 0; Index: ext/fts2/fts2.c =================================================================== --- ext/fts2/fts2.c 2009-09-04 13:37:41.000000000 -0700 diff --git a/third_party/sqlite/sqlite-poison.patch b/third_party/sqlite/sqlite-poison.patch deleted file mode 100644 index 38f81a0..0000000 --- a/third_party/sqlite/sqlite-poison.patch +++ /dev/null @@ -1,98 +0,0 @@ -Index: src/btree.c -=================================================================== ---- src/btree.c 2009-09-09 06:45:19.000000000 -0700 -+++ src/btree.c 2009-09-14 18:17:53.000000000 -0700 -@@ -24,6 +24,12 @@ - static const char zMagicHeader[] = SQLITE_FILE_HEADER; - - /* -+** The header string that appears at the beginning of a SQLite -+** database which has been poisoned. -+*/ -+static const char zPoisonHeader[] = "SQLite poison 3"; -+ -+/* - ** Set this global variable to 1 to enable tracing using the TRACE - ** macro. - */ -@@ -2337,6 +2343,7 @@ - if( rc ) return rc; - memcpy(data, zMagicHeader, sizeof(zMagicHeader)); - assert( sizeof(zMagicHeader)==16 ); -+ assert( sizeof(zMagicHeader)==sizeof(zPoisonHeader) ); - put2byte(&data[16], pBt->pageSize); - data[18] = 1; - data[19] = 1; -@@ -7804,4 +7811,72 @@ - assert(!pCur->aOverflow); - pCur->isIncrblobHandle = 1; - } -+ -+/* Poison the db so that other clients error out as quickly as -+** possible. -+*/ -+int sqlite3Poison(sqlite3 *db){ -+ int rc; -+ Btree *p; -+ BtShared *pBt; -+ unsigned char *pP1; -+ -+ if( db == NULL) return SQLITE_OK; -+ -+ /* Database 0 corrosponds to the main database. */ -+ if( db->nDb<1 ) return SQLITE_OK; -+ p = db->aDb[0].pBt; -+ pBt = p->pBt; -+ -+ /* If in a transaction, roll it back. Committing any changes to a -+ ** corrupt database may mess up evidence, we definitely don't want -+ ** to allow poisoning to be rolled back, and the database is anyhow -+ ** going bye-bye RSN. -+ */ -+ /* TODO(shess): Figure out if this might release the lock and let -+ ** someone else get in there, which might deny us the lock a couple -+ ** lines down. -+ */ -+ if( sqlite3BtreeIsInTrans(p) ) sqlite3BtreeRollback(p); -+ -+ /* Start an exclusive transaction. This will check the headers, so -+ ** if someone else poisoned the database we should get an error. -+ */ -+ rc = sqlite3BtreeBeginTrans(p, 2); -+ /* TODO(shess): Handle SQLITE_BUSY? */ -+ if( rc!=SQLITE_OK ) return rc; -+ -+ /* Copied from sqlite3BtreeUpdateMeta(). Writing the old version of -+ ** the page to the journal may be overkill, but it probably won't -+ ** hurt. -+ */ -+ assert( pBt->inTrans==TRANS_WRITE ); -+ assert( pBt->pPage1!=0 ); -+ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); -+ if( rc ) goto err; -+ -+ /* "SQLite format 3" changes to -+ ** "SQLite poison 3". Be extra paranoid about making this change. -+ */ -+ if( sizeof(zMagicHeader)!=16 || -+ sizeof(zPoisonHeader)!=sizeof(zMagicHeader) ){ -+ rc = SQLITE_ERROR; -+ goto err; -+ } -+ pP1 = pBt->pPage1->aData; -+ if( memcmp(pP1, zMagicHeader, 16)!=0 ){ -+ rc = SQLITE_CORRUPT; -+ goto err; -+ } -+ memcpy(pP1, zPoisonHeader, 16); -+ -+ /* Push it to the database file. */ -+ return sqlite3BtreeCommit(p); -+ -+ err: -+ /* TODO(shess): What about errors, here? */ -+ sqlite3BtreeRollback(p); -+ return rc; -+} -+ - #endif diff --git a/third_party/sqlite/src/LICENSE b/third_party/sqlite/src/LICENSE deleted file mode 100644 index cb0841c..0000000 --- a/third_party/sqlite/src/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -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. diff --git a/third_party/sqlite/src/Makefile.arm-wince-mingw32ce-gcc b/third_party/sqlite/src/Makefile.arm-wince-mingw32ce-gcc index d1ca389..d1ca389 100755..100644 --- a/third_party/sqlite/src/Makefile.arm-wince-mingw32ce-gcc +++ b/third_party/sqlite/src/Makefile.arm-wince-mingw32ce-gcc diff --git a/third_party/sqlite/src/Makefile.in b/third_party/sqlite/src/Makefile.in index 3bd69b7..3bd69b7 100755..100644 --- a/third_party/sqlite/src/Makefile.in +++ b/third_party/sqlite/src/Makefile.in diff --git a/third_party/sqlite/src/Makefile.linux-gcc b/third_party/sqlite/src/Makefile.linux-gcc index 4d96398..4343077 100755..100644 --- a/third_party/sqlite/src/Makefile.linux-gcc +++ b/third_party/sqlite/src/Makefile.linux-gcc @@ -62,7 +62,6 @@ TLIBS = OPTS += -DNDEBUG OPTS += -DSQLITE_CORE -OPTS += -DSQLITE_ENABLE_FTS1 -DSQLITE_ENABLE_BROKEN_FTS1 OPTS += -DSQLITE_ENABLE_FTS2 -DSQLITE_ENABLE_BROKEN_FTS2 OPTS += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 OPTS += -DHAVE_USLEEP=1 diff --git a/third_party/sqlite/src/addopcodes.awk b/third_party/sqlite/src/addopcodes.awk index 9c21417..9c21417 100755..100644 --- a/third_party/sqlite/src/addopcodes.awk +++ b/third_party/sqlite/src/addopcodes.awk diff --git a/third_party/sqlite/src/art/2005osaward.gif b/third_party/sqlite/src/art/2005osaward.gif Binary files differdeleted file mode 100644 index fa6d7d7..0000000 --- a/third_party/sqlite/src/art/2005osaward.gif +++ /dev/null diff --git a/third_party/sqlite/src/art/SQLite.eps b/third_party/sqlite/src/art/SQLite.eps Binary files differdeleted file mode 100644 index 1f334ec..0000000 --- a/third_party/sqlite/src/art/SQLite.eps +++ /dev/null diff --git a/third_party/sqlite/src/art/SQLite.gif b/third_party/sqlite/src/art/SQLite.gif Binary files differdeleted file mode 100644 index 5ec05b0..0000000 --- a/third_party/sqlite/src/art/SQLite.gif +++ /dev/null diff --git a/third_party/sqlite/src/art/SQLiteLogo3.tiff b/third_party/sqlite/src/art/SQLiteLogo3.tiff Binary files differdeleted file mode 100644 index 70b88e7..0000000 --- a/third_party/sqlite/src/art/SQLiteLogo3.tiff +++ /dev/null diff --git a/third_party/sqlite/src/art/SQLite_big.gif b/third_party/sqlite/src/art/SQLite_big.gif Binary files differdeleted file mode 100644 index dc9e6a0..0000000 --- a/third_party/sqlite/src/art/SQLite_big.gif +++ /dev/null diff --git a/third_party/sqlite/src/art/nocopy.gif b/third_party/sqlite/src/art/nocopy.gif Binary files differdeleted file mode 100644 index cc4a59c..0000000 --- a/third_party/sqlite/src/art/nocopy.gif +++ /dev/null diff --git a/third_party/sqlite/src/art/powered_by_sqlite.gif b/third_party/sqlite/src/art/powered_by_sqlite.gif Binary files differdeleted file mode 100644 index 5bfed02..0000000 --- a/third_party/sqlite/src/art/powered_by_sqlite.gif +++ /dev/null diff --git a/third_party/sqlite/src/contrib/sqlitecon.tcl b/third_party/sqlite/src/contrib/sqlitecon.tcl deleted file mode 100755 index b5dbcaf..0000000 --- a/third_party/sqlite/src/contrib/sqlitecon.tcl +++ /dev/null @@ -1,679 +0,0 @@ -# A Tk console widget for SQLite. Invoke sqlitecon::create with a window name, -# a prompt string, a title to set a new top-level window, and the SQLite -# database handle. For example: -# -# sqlitecon::create .sqlcon {sql:- } {SQL Console} db -# -# A toplevel window is created that allows you to type in SQL commands to -# be processed on the spot. -# -# A limited set of dot-commands are supported: -# -# .table -# .schema ?TABLE? -# .mode list|column|multicolumn|line -# .exit -# -# In addition, a new SQL function named "edit()" is created. This function -# takes a single text argument and returns a text result. Whenever the -# the function is called, it pops up a new toplevel window containing a -# text editor screen initialized to the argument. When the "OK" button -# is pressed, whatever revised text is in the text editor is returned as -# the result of the edit() function. This allows text fields of SQL tables -# to be edited quickly and easily as follows: -# -# UPDATE table1 SET dscr = edit(dscr) WHERE rowid=15; -# - - -# Create a namespace to work in -# -namespace eval ::sqlitecon { - # do nothing -} - -# Create a console widget named $w. The prompt string is $prompt. -# The title at the top of the window is $title. The database connection -# object is $db -# -proc sqlitecon::create {w prompt title db} { - upvar #0 $w.t v - if {[winfo exists $w]} {destroy $w} - if {[info exists v]} {unset v} - toplevel $w - wm title $w $title - wm iconname $w $title - frame $w.mb -bd 2 -relief raised - pack $w.mb -side top -fill x - menubutton $w.mb.file -text File -menu $w.mb.file.m - menubutton $w.mb.edit -text Edit -menu $w.mb.edit.m - pack $w.mb.file $w.mb.edit -side left -padx 8 -pady 1 - set m [menu $w.mb.file.m -tearoff 0] - $m add command -label {Close} -command "destroy $w" - sqlitecon::create_child $w $prompt $w.mb.edit.m - set v(db) $db - $db function edit ::sqlitecon::_edit -} - -# This routine creates a console as a child window within a larger -# window. It also creates an edit menu named "$editmenu" if $editmenu!="". -# The calling function is responsible for posting the edit menu. -# -proc sqlitecon::create_child {w prompt editmenu} { - upvar #0 $w.t v - if {$editmenu!=""} { - set m [menu $editmenu -tearoff 0] - $m add command -label Cut -command "sqlitecon::Cut $w.t" - $m add command -label Copy -command "sqlitecon::Copy $w.t" - $m add command -label Paste -command "sqlitecon::Paste $w.t" - $m add command -label {Clear Screen} -command "sqlitecon::Clear $w.t" - $m add separator - $m add command -label {Save As...} -command "sqlitecon::SaveFile $w.t" - catch {$editmenu config -postcommand "sqlitecon::EnableEditMenu $w"} - } - scrollbar $w.sb -orient vertical -command "$w.t yview" - pack $w.sb -side right -fill y - text $w.t -font fixed -yscrollcommand "$w.sb set" - pack $w.t -side right -fill both -expand 1 - bindtags $w.t Sqlitecon - set v(editmenu) $editmenu - set v(history) 0 - set v(historycnt) 0 - set v(current) -1 - set v(prompt) $prompt - set v(prior) {} - set v(plength) [string length $v(prompt)] - set v(x) 0 - set v(y) 0 - set v(mode) column - set v(header) on - $w.t mark set insert end - $w.t tag config ok -foreground blue - $w.t tag config err -foreground red - $w.t insert end $v(prompt) - $w.t mark set out 1.0 - after idle "focus $w.t" -} - -bind Sqlitecon <1> {sqlitecon::Button1 %W %x %y} -bind Sqlitecon <B1-Motion> {sqlitecon::B1Motion %W %x %y} -bind Sqlitecon <B1-Leave> {sqlitecon::B1Leave %W %x %y} -bind Sqlitecon <B1-Enter> {sqlitecon::cancelMotor %W} -bind Sqlitecon <ButtonRelease-1> {sqlitecon::cancelMotor %W} -bind Sqlitecon <KeyPress> {sqlitecon::Insert %W %A} -bind Sqlitecon <Left> {sqlitecon::Left %W} -bind Sqlitecon <Control-b> {sqlitecon::Left %W} -bind Sqlitecon <Right> {sqlitecon::Right %W} -bind Sqlitecon <Control-f> {sqlitecon::Right %W} -bind Sqlitecon <BackSpace> {sqlitecon::Backspace %W} -bind Sqlitecon <Control-h> {sqlitecon::Backspace %W} -bind Sqlitecon <Delete> {sqlitecon::Delete %W} -bind Sqlitecon <Control-d> {sqlitecon::Delete %W} -bind Sqlitecon <Home> {sqlitecon::Home %W} -bind Sqlitecon <Control-a> {sqlitecon::Home %W} -bind Sqlitecon <End> {sqlitecon::End %W} -bind Sqlitecon <Control-e> {sqlitecon::End %W} -bind Sqlitecon <Return> {sqlitecon::Enter %W} -bind Sqlitecon <KP_Enter> {sqlitecon::Enter %W} -bind Sqlitecon <Up> {sqlitecon::Prior %W} -bind Sqlitecon <Control-p> {sqlitecon::Prior %W} -bind Sqlitecon <Down> {sqlitecon::Next %W} -bind Sqlitecon <Control-n> {sqlitecon::Next %W} -bind Sqlitecon <Control-k> {sqlitecon::EraseEOL %W} -bind Sqlitecon <<Cut>> {sqlitecon::Cut %W} -bind Sqlitecon <<Copy>> {sqlitecon::Copy %W} -bind Sqlitecon <<Paste>> {sqlitecon::Paste %W} -bind Sqlitecon <<Clear>> {sqlitecon::Clear %W} - -# Insert a single character at the insertion cursor -# -proc sqlitecon::Insert {w a} { - $w insert insert $a - $w yview insert -} - -# Move the cursor one character to the left -# -proc sqlitecon::Left {w} { - upvar #0 $w v - scan [$w index insert] %d.%d row col - if {$col>$v(plength)} { - $w mark set insert "insert -1c" - } -} - -# Erase the character to the left of the cursor -# -proc sqlitecon::Backspace {w} { - upvar #0 $w v - scan [$w index insert] %d.%d row col - if {$col>$v(plength)} { - $w delete {insert -1c} - } -} - -# Erase to the end of the line -# -proc sqlitecon::EraseEOL {w} { - upvar #0 $w v - scan [$w index insert] %d.%d row col - if {$col>=$v(plength)} { - $w delete insert {insert lineend} - } -} - -# Move the cursor one character to the right -# -proc sqlitecon::Right {w} { - $w mark set insert "insert +1c" -} - -# Erase the character to the right of the cursor -# -proc sqlitecon::Delete w { - $w delete insert -} - -# Move the cursor to the beginning of the current line -# -proc sqlitecon::Home w { - upvar #0 $w v - scan [$w index insert] %d.%d row col - $w mark set insert $row.$v(plength) -} - -# Move the cursor to the end of the current line -# -proc sqlitecon::End w { - $w mark set insert {insert lineend} -} - -# Add a line to the history -# -proc sqlitecon::addHistory {w line} { - upvar #0 $w v - if {$v(historycnt)>0} { - set last [lindex $v(history) [expr $v(historycnt)-1]] - if {[string compare $last $line]} { - lappend v(history) $line - incr v(historycnt) - } - } else { - set v(history) [list $line] - set v(historycnt) 1 - } - set v(current) $v(historycnt) -} - -# Called when "Enter" is pressed. Do something with the line -# of text that was entered. -# -proc sqlitecon::Enter w { - upvar #0 $w v - scan [$w index insert] %d.%d row col - set start $row.$v(plength) - set line [$w get $start "$start lineend"] - $w insert end \n - $w mark set out end - if {$v(prior)==""} { - set cmd $line - } else { - set cmd $v(prior)\n$line - } - if {[string index $cmd 0]=="." || [$v(db) complete $cmd]} { - regsub -all {\n} [string trim $cmd] { } cmd2 - addHistory $w $cmd2 - set rc [catch {DoCommand $w $cmd} res] - if {![winfo exists $w]} return - if {$rc} { - $w insert end $res\n err - } elseif {[string length $res]>0} { - $w insert end $res\n ok - } - set v(prior) {} - $w insert end $v(prompt) - } else { - set v(prior) $cmd - regsub -all {[^ ]} $v(prompt) . x - $w insert end $x - } - $w mark set insert end - $w mark set out {insert linestart} - $w yview insert -} - -# Execute a single SQL command. Pay special attention to control -# directives that begin with "." -# -# The return value is the text output from the command, properly -# formatted. -# -proc sqlitecon::DoCommand {w cmd} { - upvar #0 $w v - set mode $v(mode) - set header $v(header) - if {[regexp {^(\.[a-z]+)} $cmd all word]} { - if {$word==".mode"} { - regexp {^.[a-z]+ +([a-z]+)} $cmd all v(mode) - return {} - } elseif {$word==".exit"} { - destroy [winfo toplevel $w] - return {} - } elseif {$word==".header"} { - regexp {^.[a-z]+ +([a-z]+)} $cmd all v(header) - return {} - } elseif {$word==".tables"} { - set mode multicolumn - set cmd {SELECT name FROM sqlite_master WHERE type='table' - UNION ALL - SELECT name FROM sqlite_temp_master WHERE type='table'} - $v(db) eval {PRAGMA database_list} { - if {$name!="temp" && $name!="main"} { - append cmd "UNION ALL SELECT name FROM $name.sqlite_master\ - WHERE type='table'" - } - } - append cmd { ORDER BY 1} - } elseif {$word==".fullschema"} { - set pattern % - regexp {^.[a-z]+ +([^ ]+)} $cmd all pattern - set mode list - set header 0 - set cmd "SELECT sql FROM sqlite_master WHERE tbl_name LIKE '$pattern' - AND sql NOT NULL UNION ALL SELECT sql FROM sqlite_temp_master - WHERE tbl_name LIKE '$pattern' AND sql NOT NULL" - $v(db) eval {PRAGMA database_list} { - if {$name!="temp" && $name!="main"} { - append cmd " UNION ALL SELECT sql FROM $name.sqlite_master\ - WHERE tbl_name LIKE '$pattern' AND sql NOT NULL" - } - } - } elseif {$word==".schema"} { - set pattern % - regexp {^.[a-z]+ +([^ ]+)} $cmd all pattern - set mode list - set header 0 - set cmd "SELECT sql FROM sqlite_master WHERE name LIKE '$pattern' - AND sql NOT NULL UNION ALL SELECT sql FROM sqlite_temp_master - WHERE name LIKE '$pattern' AND sql NOT NULL" - $v(db) eval {PRAGMA database_list} { - if {$name!="temp" && $name!="main"} { - append cmd " UNION ALL SELECT sql FROM $name.sqlite_master\ - WHERE name LIKE '$pattern' AND sql NOT NULL" - } - } - } else { - return \ - ".exit\n.mode line|list|column\n.schema ?TABLENAME?\n.tables" - } - } - set res {} - if {$mode=="list"} { - $v(db) eval $cmd x { - set sep {} - foreach col $x(*) { - append res $sep$x($col) - set sep | - } - append res \n - } - if {[info exists x(*)] && $header} { - set sep {} - set hdr {} - foreach col $x(*) { - append hdr $sep$col - set sep | - } - set res $hdr\n$res - } - } elseif {[string range $mode 0 2]=="col"} { - set y {} - $v(db) eval $cmd x { - foreach col $x(*) { - if {![info exists cw($col)] || $cw($col)<[string length $x($col)]} { - set cw($col) [string length $x($col)] - } - lappend y $x($col) - } - } - if {[info exists x(*)] && $header} { - set hdr {} - set ln {} - set dash --------------------------------------------------------------- - append dash ------------------------------------------------------------ - foreach col $x(*) { - if {![info exists cw($col)] || $cw($col)<[string length $col]} { - set cw($col) [string length $col] - } - lappend hdr $col - lappend ln [string range $dash 1 $cw($col)] - } - set y [concat $hdr $ln $y] - } - if {[info exists x(*)]} { - set format {} - set arglist {} - set arglist2 {} - set i 0 - foreach col $x(*) { - lappend arglist x$i - append arglist2 " \$x$i" - incr i - append format " %-$cw($col)s" - } - set format [string trimleft $format]\n - if {[llength $arglist]>0} { - foreach $arglist $y "append res \[format [list $format] $arglist2\]" - } - } - } elseif {$mode=="multicolumn"} { - set y [$v(db) eval $cmd] - set max 0 - foreach e $y { - if {$max<[string length $e]} {set max [string length $e]} - } - set ncol [expr {int(80/($max+2))}] - if {$ncol<1} {set ncol 1} - set nelem [llength $y] - set nrow [expr {($nelem+$ncol-1)/$ncol}] - set format "%-${max}s" - for {set i 0} {$i<$nrow} {incr i} { - set j $i - while 1 { - append res [format $format [lindex $y $j]] - incr j $nrow - if {$j>=$nelem} break - append res { } - } - append res \n - } - } else { - $v(db) eval $cmd x { - foreach col $x(*) {append res "$col = $x($col)\n"} - append res \n - } - } - return [string trimright $res] -} - -# Change the line to the previous line -# -proc sqlitecon::Prior w { - upvar #0 $w v - if {$v(current)<=0} return - incr v(current) -1 - set line [lindex $v(history) $v(current)] - sqlitecon::SetLine $w $line -} - -# Change the line to the next line -# -proc sqlitecon::Next w { - upvar #0 $w v - if {$v(current)>=$v(historycnt)} return - incr v(current) 1 - set line [lindex $v(history) $v(current)] - sqlitecon::SetLine $w $line -} - -# Change the contents of the entry line -# -proc sqlitecon::SetLine {w line} { - upvar #0 $w v - scan [$w index insert] %d.%d row col - set start $row.$v(plength) - $w delete $start end - $w insert end $line - $w mark set insert end - $w yview insert -} - -# Called when the mouse button is pressed at position $x,$y on -# the console widget. -# -proc sqlitecon::Button1 {w x y} { - global tkPriv - upvar #0 $w v - set v(mouseMoved) 0 - set v(pressX) $x - set p [sqlitecon::nearestBoundry $w $x $y] - scan [$w index insert] %d.%d ix iy - scan $p %d.%d px py - if {$px==$ix} { - $w mark set insert $p - } - $w mark set anchor $p - focus $w -} - -# Find the boundry between characters that is nearest -# to $x,$y -# -proc sqlitecon::nearestBoundry {w x y} { - set p [$w index @$x,$y] - set bb [$w bbox $p] - if {![string compare $bb ""]} {return $p} - if {($x-[lindex $bb 0])<([lindex $bb 2]/2)} {return $p} - $w index "$p + 1 char" -} - -# This routine extends the selection to the point specified by $x,$y -# -proc sqlitecon::SelectTo {w x y} { - upvar #0 $w v - set cur [sqlitecon::nearestBoundry $w $x $y] - if {[catch {$w index anchor}]} { - $w mark set anchor $cur - } - set anchor [$w index anchor] - if {[$w compare $cur != $anchor] || (abs($v(pressX) - $x) >= 3)} { - if {$v(mouseMoved)==0} { - $w tag remove sel 0.0 end - } - set v(mouseMoved) 1 - } - if {[$w compare $cur < anchor]} { - set first $cur - set last anchor - } else { - set first anchor - set last $cur - } - if {$v(mouseMoved)} { - $w tag remove sel 0.0 $first - $w tag add sel $first $last - $w tag remove sel $last end - update idletasks - } -} - -# Called whenever the mouse moves while button-1 is held down. -# -proc sqlitecon::B1Motion {w x y} { - upvar #0 $w v - set v(y) $y - set v(x) $x - sqlitecon::SelectTo $w $x $y -} - -# Called whenever the mouse leaves the boundries of the widget -# while button 1 is held down. -# -proc sqlitecon::B1Leave {w x y} { - upvar #0 $w v - set v(y) $y - set v(x) $x - sqlitecon::motor $w -} - -# This routine is called to automatically scroll the window when -# the mouse drags offscreen. -# -proc sqlitecon::motor w { - upvar #0 $w v - if {![winfo exists $w]} return - if {$v(y)>=[winfo height $w]} { - $w yview scroll 1 units - } elseif {$v(y)<0} { - $w yview scroll -1 units - } else { - return - } - sqlitecon::SelectTo $w $v(x) $v(y) - set v(timer) [after 50 sqlitecon::motor $w] -} - -# This routine cancels the scrolling motor if it is active -# -proc sqlitecon::cancelMotor w { - upvar #0 $w v - catch {after cancel $v(timer)} - catch {unset v(timer)} -} - -# Do a Copy operation on the stuff currently selected. -# -proc sqlitecon::Copy w { - if {![catch {set text [$w get sel.first sel.last]}]} { - clipboard clear -displayof $w - clipboard append -displayof $w $text - } -} - -# Return 1 if the selection exists and is contained -# entirely on the input line. Return 2 if the selection -# exists but is not entirely on the input line. Return 0 -# if the selection does not exist. -# -proc sqlitecon::canCut w { - set r [catch { - scan [$w index sel.first] %d.%d s1x s1y - scan [$w index sel.last] %d.%d s2x s2y - scan [$w index insert] %d.%d ix iy - }] - if {$r==1} {return 0} - if {$s1x==$ix && $s2x==$ix} {return 1} - return 2 -} - -# Do a Cut operation if possible. Cuts are only allowed -# if the current selection is entirely contained on the -# current input line. -# -proc sqlitecon::Cut w { - if {[sqlitecon::canCut $w]==1} { - sqlitecon::Copy $w - $w delete sel.first sel.last - } -} - -# Do a paste opeation. -# -proc sqlitecon::Paste w { - if {[sqlitecon::canCut $w]==1} { - $w delete sel.first sel.last - } - if {[catch {selection get -displayof $w -selection CLIPBOARD} topaste] - && [catch {selection get -displayof $w -selection PRIMARY} topaste]} { - return - } - if {[info exists ::$w]} { - set prior 0 - foreach line [split $topaste \n] { - if {$prior} { - sqlitecon::Enter $w - update - } - set prior 1 - $w insert insert $line - } - } else { - $w insert insert $topaste - } -} - -# Enable or disable entries in the Edit menu -# -proc sqlitecon::EnableEditMenu w { - upvar #0 $w.t v - set m $v(editmenu) - if {$m=="" || ![winfo exists $m]} return - switch [sqlitecon::canCut $w.t] { - 0 { - $m entryconf Copy -state disabled - $m entryconf Cut -state disabled - } - 1 { - $m entryconf Copy -state normal - $m entryconf Cut -state normal - } - 2 { - $m entryconf Copy -state normal - $m entryconf Cut -state disabled - } - } -} - -# Prompt the user for the name of a writable file. Then write the -# entire contents of the console screen to that file. -# -proc sqlitecon::SaveFile w { - set types { - {{Text Files} {.txt}} - {{All Files} *} - } - set f [tk_getSaveFile -filetypes $types -title "Write Screen To..."] - if {$f!=""} { - if {[catch {open $f w} fd]} { - tk_messageBox -type ok -icon error -message $fd - } else { - puts $fd [string trimright [$w get 1.0 end] \n] - close $fd - } - } -} - -# Erase everything from the console above the insertion line. -# -proc sqlitecon::Clear w { - $w delete 1.0 {insert linestart} -} - -# An in-line editor for SQL -# -proc sqlitecon::_edit {origtxt {title {}}} { - for {set i 0} {[winfo exists .ed$i]} {incr i} continue - set w .ed$i - toplevel $w - wm protocol $w WM_DELETE_WINDOW "$w.b.can invoke" - wm title $w {Inline SQL Editor} - frame $w.b - pack $w.b -side bottom -fill x - button $w.b.can -text Cancel -width 6 -command [list set ::$w 0] - button $w.b.ok -text OK -width 6 -command [list set ::$w 1] - button $w.b.cut -text Cut -width 6 -command [list ::sqlitecon::Cut $w.t] - button $w.b.copy -text Copy -width 6 -command [list ::sqlitecon::Copy $w.t] - button $w.b.paste -text Paste -width 6 -command [list ::sqlitecon::Paste $w.t] - set ::$w {} - pack $w.b.cut $w.b.copy $w.b.paste $w.b.can $w.b.ok\ - -side left -padx 5 -pady 5 -expand 1 - if {$title!=""} { - label $w.title -text $title - pack $w.title -side top -padx 5 -pady 5 - } - text $w.t -bg white -fg black -yscrollcommand [list $w.sb set] - pack $w.t -side left -fill both -expand 1 - scrollbar $w.sb -orient vertical -command [list $w.t yview] - pack $w.sb -side left -fill y - $w.t insert end $origtxt - - vwait ::$w - - if {[set ::$w]} { - set txt [string trimright [$w.t get 1.0 end]] - } else { - set txt $origtxt - } - destroy $w - return $txt -} diff --git a/third_party/sqlite/src/doc/lemon.html b/third_party/sqlite/src/doc/lemon.html deleted file mode 100644 index 6a4d6db..0000000 --- a/third_party/sqlite/src/doc/lemon.html +++ /dev/null @@ -1,892 +0,0 @@ -<html> -<head> -<title>The Lemon Parser Generator</title> -</head> -<body bgcolor=white> -<h1 align=center>The Lemon Parser Generator</h1> - -<p>Lemon is an LALR(1) parser generator for C or C++. -It does the same job as ``bison'' and ``yacc''. -But lemon is not another bison or yacc clone. It -uses a different grammar syntax which is designed to -reduce the number of coding errors. Lemon also uses a more -sophisticated parsing engine that is faster than yacc and -bison and which is both reentrant and thread-safe. -Furthermore, Lemon implements features that can be used -to eliminate resource leaks, making is suitable for use -in long-running programs such as graphical user interfaces -or embedded controllers.</p> - -<p>This document is an introduction to the Lemon -parser generator.</p> - -<h2>Theory of Operation</h2> - -<p>The main goal of Lemon is to translate a context free grammar (CFG) -for a particular language into C code that implements a parser for -that language. -The program has two inputs: -<ul> -<li>The grammar specification. -<li>A parser template file. -</ul> -Typically, only the grammar specification is supplied by the programmer. -Lemon comes with a default parser template which works fine for most -applications. But the user is free to substitute a different parser -template if desired.</p> - -<p>Depending on command-line options, Lemon will generate between -one and three files of outputs. -<ul> -<li>C code to implement the parser. -<li>A header file defining an integer ID for each terminal symbol. -<li>An information file that describes the states of the generated parser - automaton. -</ul> -By default, all three of these output files are generated. -The header file is suppressed if the ``-m'' command-line option is -used and the report file is omitted when ``-q'' is selected.</p> - -<p>The grammar specification file uses a ``.y'' suffix, by convention. -In the examples used in this document, we'll assume the name of the -grammar file is ``gram.y''. A typical use of Lemon would be the -following command: -<pre> - lemon gram.y -</pre> -This command will generate three output files named ``gram.c'', -``gram.h'' and ``gram.out''. -The first is C code to implement the parser. The second -is the header file that defines numerical values for all -terminal symbols, and the last is the report that explains -the states used by the parser automaton.</p> - -<h3>Command Line Options</h3> - -<p>The behavior of Lemon can be modified using command-line options. -You can obtain a list of the available command-line options together -with a brief explanation of what each does by typing -<pre> - lemon -? -</pre> -As of this writing, the following command-line options are supported: -<ul> -<li><tt>-b</tt> -<li><tt>-c</tt> -<li><tt>-g</tt> -<li><tt>-m</tt> -<li><tt>-q</tt> -<li><tt>-s</tt> -<li><tt>-x</tt> -</ul> -The ``-b'' option reduces the amount of text in the report file by -printing only the basis of each parser state, rather than the full -configuration. -The ``-c'' option suppresses action table compression. Using -c -will make the parser a little larger and slower but it will detect -syntax errors sooner. -The ``-g'' option causes no output files to be generated at all. -Instead, the input grammar file is printed on standard output but -with all comments, actions and other extraneous text deleted. This -is a useful way to get a quick summary of a grammar. -The ``-m'' option causes the output C source file to be compatible -with the ``makeheaders'' program. -Makeheaders is a program that automatically generates header files -from C source code. When the ``-m'' option is used, the header -file is not output since the makeheaders program will take care -of generated all header files automatically. -The ``-q'' option suppresses the report file. -Using ``-s'' causes a brief summary of parser statistics to be -printed. Like this: -<pre> - Parser statistics: 74 terminals, 70 nonterminals, 179 rules - 340 states, 2026 parser table entries, 0 conflicts -</pre> -Finally, the ``-x'' option causes Lemon to print its version number -and then stops without attempting to read the grammar or generate a parser.</p> - -<h3>The Parser Interface</h3> - -<p>Lemon doesn't generate a complete, working program. It only generates -a few subroutines that implement a parser. This section describes -the interface to those subroutines. It is up to the programmer to -call these subroutines in an appropriate way in order to produce a -complete system.</p> - -<p>Before a program begins using a Lemon-generated parser, the program -must first create the parser. -A new parser is created as follows: -<pre> - void *pParser = ParseAlloc( malloc ); -</pre> -The ParseAlloc() routine allocates and initializes a new parser and -returns a pointer to it. -The actual data structure used to represent a parser is opaque -- -its internal structure is not visible or usable by the calling routine. -For this reason, the ParseAlloc() routine returns a pointer to void -rather than a pointer to some particular structure. -The sole argument to the ParseAlloc() routine is a pointer to the -subroutine used to allocate memory. Typically this means ``malloc()''.</p> - -<p>After a program is finished using a parser, it can reclaim all -memory allocated by that parser by calling -<pre> - ParseFree(pParser, free); -</pre> -The first argument is the same pointer returned by ParseAlloc(). The -second argument is a pointer to the function used to release bulk -memory back to the system.</p> - -<p>After a parser has been allocated using ParseAlloc(), the programmer -must supply the parser with a sequence of tokens (terminal symbols) to -be parsed. This is accomplished by calling the following function -once for each token: -<pre> - Parse(pParser, hTokenID, sTokenData, pArg); -</pre> -The first argument to the Parse() routine is the pointer returned by -ParseAlloc(). -The second argument is a small positive integer that tells the parse the -type of the next token in the data stream. -There is one token type for each terminal symbol in the grammar. -The gram.h file generated by Lemon contains #define statements that -map symbolic terminal symbol names into appropriate integer values. -(A value of 0 for the second argument is a special flag to the -parser to indicate that the end of input has been reached.) -The third argument is the value of the given token. By default, -the type of the third argument is integer, but the grammar will -usually redefine this type to be some kind of structure. -Typically the second argument will be a broad category of tokens -such as ``identifier'' or ``number'' and the third argument will -be the name of the identifier or the value of the number.</p> - -<p>The Parse() function may have either three or four arguments, -depending on the grammar. If the grammar specification file request -it, the Parse() function will have a fourth parameter that can be -of any type chosen by the programmer. The parser doesn't do anything -with this argument except to pass it through to action routines. -This is a convenient mechanism for passing state information down -to the action routines without having to use global variables.</p> - -<p>A typical use of a Lemon parser might look something like the -following: -<pre> - 01 ParseTree *ParseFile(const char *zFilename){ - 02 Tokenizer *pTokenizer; - 03 void *pParser; - 04 Token sToken; - 05 int hTokenId; - 06 ParserState sState; - 07 - 08 pTokenizer = TokenizerCreate(zFilename); - 09 pParser = ParseAlloc( malloc ); - 10 InitParserState(&sState); - 11 while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){ - 12 Parse(pParser, hTokenId, sToken, &sState); - 13 } - 14 Parse(pParser, 0, sToken, &sState); - 15 ParseFree(pParser, free ); - 16 TokenizerFree(pTokenizer); - 17 return sState.treeRoot; - 18 } -</pre> -This example shows a user-written routine that parses a file of -text and returns a pointer to the parse tree. -(We've omitted all error-handling from this example to keep it -simple.) -We assume the existence of some kind of tokenizer which is created -using TokenizerCreate() on line 8 and deleted by TokenizerFree() -on line 16. The GetNextToken() function on line 11 retrieves the -next token from the input file and puts its type in the -integer variable hTokenId. The sToken variable is assumed to be -some kind of structure that contains details about each token, -such as its complete text, what line it occurs on, etc. </p> - -<p>This example also assumes the existence of structure of type -ParserState that holds state information about a particular parse. -An instance of such a structure is created on line 6 and initialized -on line 10. A pointer to this structure is passed into the Parse() -routine as the optional 4th argument. -The action routine specified by the grammar for the parser can use -the ParserState structure to hold whatever information is useful and -appropriate. In the example, we note that the treeRoot field of -the ParserState structure is left pointing to the root of the parse -tree.</p> - -<p>The core of this example as it relates to Lemon is as follows: -<pre> - ParseFile(){ - pParser = ParseAlloc( malloc ); - while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){ - Parse(pParser, hTokenId, sToken); - } - Parse(pParser, 0, sToken); - ParseFree(pParser, free ); - } -</pre> -Basically, what a program has to do to use a Lemon-generated parser -is first create the parser, then send it lots of tokens obtained by -tokenizing an input source. When the end of input is reached, the -Parse() routine should be called one last time with a token type -of 0. This step is necessary to inform the parser that the end of -input has been reached. Finally, we reclaim memory used by the -parser by calling ParseFree().</p> - -<p>There is one other interface routine that should be mentioned -before we move on. -The ParseTrace() function can be used to generate debugging output -from the parser. A prototype for this routine is as follows: -<pre> - ParseTrace(FILE *stream, char *zPrefix); -</pre> -After this routine is called, a short (one-line) message is written -to the designated output stream every time the parser changes states -or calls an action routine. Each such message is prefaced using -the text given by zPrefix. This debugging output can be turned off -by calling ParseTrace() again with a first argument of NULL (0).</p> - -<h3>Differences With YACC and BISON</h3> - -<p>Programmers who have previously used the yacc or bison parser -generator will notice several important differences between yacc and/or -bison and Lemon. -<ul> -<li>In yacc and bison, the parser calls the tokenizer. In Lemon, - the tokenizer calls the parser. -<li>Lemon uses no global variables. Yacc and bison use global variables - to pass information between the tokenizer and parser. -<li>Lemon allows multiple parsers to be running simultaneously. Yacc - and bison do not. -</ul> -These differences may cause some initial confusion for programmers -with prior yacc and bison experience. -But after years of experience using Lemon, I firmly -believe that the Lemon way of doing things is better.</p> - -<h2>Input File Syntax</h2> - -<p>The main purpose of the grammar specification file for Lemon is -to define the grammar for the parser. But the input file also -specifies additional information Lemon requires to do its job. -Most of the work in using Lemon is in writing an appropriate -grammar file.</p> - -<p>The grammar file for lemon is, for the most part, free format. -It does not have sections or divisions like yacc or bison. Any -declaration can occur at any point in the file. -Lemon ignores whitespace (except where it is needed to separate -tokens) and it honors the same commenting conventions as C and C++.</p> - -<h3>Terminals and Nonterminals</h3> - -<p>A terminal symbol (token) is any string of alphanumeric -and underscore characters -that begins with an upper case letter. -A terminal can contain lower class letters after the first character, -but the usual convention is to make terminals all upper case. -A nonterminal, on the other hand, is any string of alphanumeric -and underscore characters than begins with a lower case letter. -Again, the usual convention is to make nonterminals use all lower -case letters.</p> - -<p>In Lemon, terminal and nonterminal symbols do not need to -be declared or identified in a separate section of the grammar file. -Lemon is able to generate a list of all terminals and nonterminals -by examining the grammar rules, and it can always distinguish a -terminal from a nonterminal by checking the case of the first -character of the name.</p> - -<p>Yacc and bison allow terminal symbols to have either alphanumeric -names or to be individual characters included in single quotes, like -this: ')' or '$'. Lemon does not allow this alternative form for -terminal symbols. With Lemon, all symbols, terminals and nonterminals, -must have alphanumeric names.</p> - -<h3>Grammar Rules</h3> - -<p>The main component of a Lemon grammar file is a sequence of grammar -rules. -Each grammar rule consists of a nonterminal symbol followed by -the special symbol ``::='' and then a list of terminals and/or nonterminals. -The rule is terminated by a period. -The list of terminals and nonterminals on the right-hand side of the -rule can be empty. -Rules can occur in any order, except that the left-hand side of the -first rule is assumed to be the start symbol for the grammar (unless -specified otherwise using the <tt>%start</tt> directive described below.) -A typical sequence of grammar rules might look something like this: -<pre> - expr ::= expr PLUS expr. - expr ::= expr TIMES expr. - expr ::= LPAREN expr RPAREN. - expr ::= VALUE. -</pre> -</p> - -<p>There is one non-terminal in this example, ``expr'', and five -terminal symbols or tokens: ``PLUS'', ``TIMES'', ``LPAREN'', -``RPAREN'' and ``VALUE''.</p> - -<p>Like yacc and bison, Lemon allows the grammar to specify a block -of C code that will be executed whenever a grammar rule is reduced -by the parser. -In Lemon, this action is specified by putting the C code (contained -within curly braces <tt>{...}</tt>) immediately after the -period that closes the rule. -For example: -<pre> - expr ::= expr PLUS expr. { printf("Doing an addition...\n"); } -</pre> -</p> - -<p>In order to be useful, grammar actions must normally be linked to -their associated grammar rules. -In yacc and bison, this is accomplished by embedding a ``$$'' in the -action to stand for the value of the left-hand side of the rule and -symbols ``$1'', ``$2'', and so forth to stand for the value of -the terminal or nonterminal at position 1, 2 and so forth on the -right-hand side of the rule. -This idea is very powerful, but it is also very error-prone. The -single most common source of errors in a yacc or bison grammar is -to miscount the number of symbols on the right-hand side of a grammar -rule and say ``$7'' when you really mean ``$8''.</p> - -<p>Lemon avoids the need to count grammar symbols by assigning symbolic -names to each symbol in a grammar rule and then using those symbolic -names in the action. -In yacc or bison, one would write this: -<pre> - expr -> expr PLUS expr { $$ = $1 + $3; }; -</pre> -But in Lemon, the same rule becomes the following: -<pre> - expr(A) ::= expr(B) PLUS expr(C). { A = B+C; } -</pre> -In the Lemon rule, any symbol in parentheses after a grammar rule -symbol becomes a place holder for that symbol in the grammar rule. -This place holder can then be used in the associated C action to -stand for the value of that symbol.<p> - -<p>The Lemon notation for linking a grammar rule with its reduce -action is superior to yacc/bison on several counts. -First, as mentioned above, the Lemon method avoids the need to -count grammar symbols. -Secondly, if a terminal or nonterminal in a Lemon grammar rule -includes a linking symbol in parentheses but that linking symbol -is not actually used in the reduce action, then an error message -is generated. -For example, the rule -<pre> - expr(A) ::= expr(B) PLUS expr(C). { A = B; } -</pre> -will generate an error because the linking symbol ``C'' is used -in the grammar rule but not in the reduce action.</p> - -<p>The Lemon notation for linking grammar rules to reduce actions -also facilitates the use of destructors for reclaiming memory -allocated by the values of terminals and nonterminals on the -right-hand side of a rule.</p> - -<h3>Precedence Rules</h3> - -<p>Lemon resolves parsing ambiguities in exactly the same way as -yacc and bison. A shift-reduce conflict is resolved in favor -of the shift, and a reduce-reduce conflict is resolved by reducing -whichever rule comes first in the grammar file.</p> - -<p>Just like in -yacc and bison, Lemon allows a measure of control -over the resolution of paring conflicts using precedence rules. -A precedence value can be assigned to any terminal symbol -using the %left, %right or %nonassoc directives. Terminal symbols -mentioned in earlier directives have a lower precedence that -terminal symbols mentioned in later directives. For example:</p> - -<p><pre> - %left AND. - %left OR. - %nonassoc EQ NE GT GE LT LE. - %left PLUS MINUS. - %left TIMES DIVIDE MOD. - %right EXP NOT. -</pre></p> - -<p>In the preceding sequence of directives, the AND operator is -defined to have the lowest precedence. The OR operator is one -precedence level higher. And so forth. Hence, the grammar would -attempt to group the ambiguous expression -<pre> - a AND b OR c -</pre> -like this -<pre> - a AND (b OR c). -</pre> -The associativity (left, right or nonassoc) is used to determine -the grouping when the precedence is the same. AND is left-associative -in our example, so -<pre> - a AND b AND c -</pre> -is parsed like this -<pre> - (a AND b) AND c. -</pre> -The EXP operator is right-associative, though, so -<pre> - a EXP b EXP c -</pre> -is parsed like this -<pre> - a EXP (b EXP c). -</pre> -The nonassoc precedence is used for non-associative operators. -So -<pre> - a EQ b EQ c -</pre> -is an error.</p> - -<p>The precedence of non-terminals is transferred to rules as follows: -The precedence of a grammar rule is equal to the precedence of the -left-most terminal symbol in the rule for which a precedence is -defined. This is normally what you want, but in those cases where -you want to precedence of a grammar rule to be something different, -you can specify an alternative precedence symbol by putting the -symbol in square braces after the period at the end of the rule and -before any C-code. For example:</p> - -<p><pre> - expr = MINUS expr. [NOT] -</pre></p> - -<p>This rule has a precedence equal to that of the NOT symbol, not the -MINUS symbol as would have been the case by default.</p> - -<p>With the knowledge of how precedence is assigned to terminal -symbols and individual -grammar rules, we can now explain precisely how parsing conflicts -are resolved in Lemon. Shift-reduce conflicts are resolved -as follows: -<ul> -<li> If either the token to be shifted or the rule to be reduced - lacks precedence information, then resolve in favor of the - shift, but report a parsing conflict. -<li> If the precedence of the token to be shifted is greater than - the precedence of the rule to reduce, then resolve in favor - of the shift. No parsing conflict is reported. -<li> If the precedence of the token it be shifted is less than the - precedence of the rule to reduce, then resolve in favor of the - reduce action. No parsing conflict is reported. -<li> If the precedences are the same and the shift token is - right-associative, then resolve in favor of the shift. - No parsing conflict is reported. -<li> If the precedences are the same the the shift token is - left-associative, then resolve in favor of the reduce. - No parsing conflict is reported. -<li> Otherwise, resolve the conflict by doing the shift and - report the parsing conflict. -</ul> -Reduce-reduce conflicts are resolved this way: -<ul> -<li> If either reduce rule - lacks precedence information, then resolve in favor of the - rule that appears first in the grammar and report a parsing - conflict. -<li> If both rules have precedence and the precedence is different - then resolve the dispute in favor of the rule with the highest - precedence and do not report a conflict. -<li> Otherwise, resolve the conflict by reducing by the rule that - appears first in the grammar and report a parsing conflict. -</ul> - -<h3>Special Directives</h3> - -<p>The input grammar to Lemon consists of grammar rules and special -directives. We've described all the grammar rules, so now we'll -talk about the special directives.</p> - -<p>Directives in lemon can occur in any order. You can put them before -the grammar rules, or after the grammar rules, or in the mist of the -grammar rules. It doesn't matter. The relative order of -directives used to assign precedence to terminals is important, but -other than that, the order of directives in Lemon is arbitrary.</p> - -<p>Lemon supports the following special directives: -<ul> -<li><tt>%code</tt> -<li><tt>%default_destructor</tt> -<li><tt>%default_type</tt> -<li><tt>%destructor</tt> -<li><tt>%extra_argument</tt> -<li><tt>%include</tt> -<li><tt>%left</tt> -<li><tt>%name</tt> -<li><tt>%nonassoc</tt> -<li><tt>%parse_accept</tt> -<li><tt>%parse_failure </tt> -<li><tt>%right</tt> -<li><tt>%stack_overflow</tt> -<li><tt>%stack_size</tt> -<li><tt>%start_symbol</tt> -<li><tt>%syntax_error</tt> -<li><tt>%token_destructor</tt> -<li><tt>%token_prefix</tt> -<li><tt>%token_type</tt> -<li><tt>%type</tt> -</ul> -Each of these directives will be described separately in the -following sections:</p> - -<h4>The <tt>%code</tt> directive</h4> - -<p>The %code directive is used to specify addition C/C++ code that -is added to the end of the main output file. This is similar to -the %include directive except that %include is inserted at the -beginning of the main output file.</p> - -<p>%code is typically used to include some action routines or perhaps -a tokenizer as part of the output file.</p> - -<h4>The <tt>%default_destructor</tt> directive</h4> - -<p>The %default_destructor directive specifies a destructor to -use for non-terminals that do not have their own destructor -specified by a separate %destructor directive. See the documentation -on the %destructor directive below for additional information.</p> - -<p>In some grammers, many different non-terminal symbols have the -same datatype and hence the same destructor. This directive is -a convenience way to specify the same destructor for all those -non-terminals using a single statement.</p> - -<h4>The <tt>%default_type</tt> directive</h4> - -<p>The %default_type directive specifies the datatype of non-terminal -symbols that do no have their own datatype defined using a separate -%type directive. See the documentation on %type below for addition -information.</p> - -<h4>The <tt>%destructor</tt> directive</h4> - -<p>The %destructor directive is used to specify a destructor for -a non-terminal symbol. -(See also the %token_destructor directive which is used to -specify a destructor for terminal symbols.)</p> - -<p>A non-terminal's destructor is called to dispose of the -non-terminal's value whenever the non-terminal is popped from -the stack. This includes all of the following circumstances: -<ul> -<li> When a rule reduces and the value of a non-terminal on - the right-hand side is not linked to C code. -<li> When the stack is popped during error processing. -<li> When the ParseFree() function runs. -</ul> -The destructor can do whatever it wants with the value of -the non-terminal, but its design is to deallocate memory -or other resources held by that non-terminal.</p> - -<p>Consider an example: -<pre> - %type nt {void*} - %destructor nt { free($$); } - nt(A) ::= ID NUM. { A = malloc( 100 ); } -</pre> -This example is a bit contrived but it serves to illustrate how -destructors work. The example shows a non-terminal named -``nt'' that holds values of type ``void*''. When the rule for -an ``nt'' reduces, it sets the value of the non-terminal to -space obtained from malloc(). Later, when the nt non-terminal -is popped from the stack, the destructor will fire and call -free() on this malloced space, thus avoiding a memory leak. -(Note that the symbol ``$$'' in the destructor code is replaced -by the value of the non-terminal.)</p> - -<p>It is important to note that the value of a non-terminal is passed -to the destructor whenever the non-terminal is removed from the -stack, unless the non-terminal is used in a C-code action. If -the non-terminal is used by C-code, then it is assumed that the -C-code will take care of destroying it if it should really -be destroyed. More commonly, the value is used to build some -larger structure and we don't want to destroy it, which is why -the destructor is not called in this circumstance.</p> - -<p>By appropriate use of destructors, it is possible to -build a parser using Lemon that can be used within a long-running -program, such as a GUI, that will not leak memory or other resources. -To do the same using yacc or bison is much more difficult.</p> - -<h4>The <tt>%extra_argument</tt> directive</h4> - -The %extra_argument directive instructs Lemon to add a 4th parameter -to the parameter list of the Parse() function it generates. Lemon -doesn't do anything itself with this extra argument, but it does -make the argument available to C-code action routines, destructors, -and so forth. For example, if the grammar file contains:</p> - -<p><pre> - %extra_argument { MyStruct *pAbc } -</pre></p> - -<p>Then the Parse() function generated will have an 4th parameter -of type ``MyStruct*'' and all action routines will have access to -a variable named ``pAbc'' that is the value of the 4th parameter -in the most recent call to Parse().</p> - -<h4>The <tt>%include</tt> directive</h4> - -<p>The %include directive specifies C code that is included at the -top of the generated parser. You can include any text you want -- -the Lemon parser generator copies it blindly. If you have multiple -%include directives in your grammar file the value of the last -%include directive overwrites all the others.</p. - -<p>The %include directive is very handy for getting some extra #include -preprocessor statements at the beginning of the generated parser. -For example:</p> - -<p><pre> - %include {#include <unistd.h>} -</pre></p> - -<p>This might be needed, for example, if some of the C actions in the -grammar call functions that are prototyed in unistd.h.</p> - -<h4>The <tt>%left</tt> directive</h4> - -The %left directive is used (along with the %right and -%nonassoc directives) to declare precedences of terminal -symbols. Every terminal symbol whose name appears after -a %left directive but before the next period (``.'') is -given the same left-associative precedence value. Subsequent -%left directives have higher precedence. For example:</p> - -<p><pre> - %left AND. - %left OR. - %nonassoc EQ NE GT GE LT LE. - %left PLUS MINUS. - %left TIMES DIVIDE MOD. - %right EXP NOT. -</pre></p> - -<p>Note the period that terminates each %left, %right or %nonassoc -directive.</p> - -<p>LALR(1) grammars can get into a situation where they require -a large amount of stack space if you make heavy use or right-associative -operators. For this reason, it is recommended that you use %left -rather than %right whenever possible.</p> - -<h4>The <tt>%name</tt> directive</h4> - -<p>By default, the functions generated by Lemon all begin with the -five-character string ``Parse''. You can change this string to something -different using the %name directive. For instance:</p> - -<p><pre> - %name Abcde -</pre></p> - -<p>Putting this directive in the grammar file will cause Lemon to generate -functions named -<ul> -<li> AbcdeAlloc(), -<li> AbcdeFree(), -<li> AbcdeTrace(), and -<li> Abcde(). -</ul> -The %name directive allows you to generator two or more different -parsers and link them all into the same executable. -</p> - -<h4>The <tt>%nonassoc</tt> directive</h4> - -<p>This directive is used to assign non-associative precedence to -one or more terminal symbols. See the section on precedence rules -or on the %left directive for additional information.</p> - -<h4>The <tt>%parse_accept</tt> directive</h4> - -<p>The %parse_accept directive specifies a block of C code that is -executed whenever the parser accepts its input string. To ``accept'' -an input string means that the parser was able to process all tokens -without error.</p> - -<p>For example:</p> - -<p><pre> - %parse_accept { - printf("parsing complete!\n"); - } -</pre></p> - - -<h4>The <tt>%parse_failure</tt> directive</h4> - -<p>The %parse_failure directive specifies a block of C code that -is executed whenever the parser fails complete. This code is not -executed until the parser has tried and failed to resolve an input -error using is usual error recovery strategy. The routine is -only invoked when parsing is unable to continue.</p> - -<p><pre> - %parse_failure { - fprintf(stderr,"Giving up. Parser is hopelessly lost...\n"); - } -</pre></p> - -<h4>The <tt>%right</tt> directive</h4> - -<p>This directive is used to assign right-associative precedence to -one or more terminal symbols. See the section on precedence rules -or on the %left directive for additional information.</p> - -<h4>The <tt>%stack_overflow</tt> directive</h4> - -<p>The %stack_overflow directive specifies a block of C code that -is executed if the parser's internal stack ever overflows. Typically -this just prints an error message. After a stack overflow, the parser -will be unable to continue and must be reset.</p> - -<p><pre> - %stack_overflow { - fprintf(stderr,"Giving up. Parser stack overflow\n"); - } -</pre></p> - -<p>You can help prevent parser stack overflows by avoiding the use -of right recursion and right-precedence operators in your grammar. -Use left recursion and and left-precedence operators instead, to -encourage rules to reduce sooner and keep the stack size down. -For example, do rules like this: -<pre> - list ::= list element. // left-recursion. Good! - list ::= . -</pre> -Not like this: -<pre> - list ::= element list. // right-recursion. Bad! - list ::= . -</pre> - -<h4>The <tt>%stack_size</tt> directive</h4> - -<p>If stack overflow is a problem and you can't resolve the trouble -by using left-recursion, then you might want to increase the size -of the parser's stack using this directive. Put an positive integer -after the %stack_size directive and Lemon will generate a parse -with a stack of the requested size. The default value is 100.</p> - -<p><pre> - %stack_size 2000 -</pre></p> - -<h4>The <tt>%start_symbol</tt> directive</h4> - -<p>By default, the start-symbol for the grammar that Lemon generates -is the first non-terminal that appears in the grammar file. But you -can choose a different start-symbol using the %start_symbol directive.</p> - -<p><pre> - %start_symbol prog -</pre></p> - -<h4>The <tt>%token_destructor</tt> directive</h4> - -<p>The %destructor directive assigns a destructor to a non-terminal -symbol. (See the description of the %destructor directive above.) -This directive does the same thing for all terminal symbols.</p> - -<p>Unlike non-terminal symbols which may each have a different data type -for their values, terminals all use the same data type (defined by -the %token_type directive) and so they use a common destructor. Other -than that, the token destructor works just like the non-terminal -destructors.</p> - -<h4>The <tt>%token_prefix</tt> directive</h4> - -<p>Lemon generates #defines that assign small integer constants -to each terminal symbol in the grammar. If desired, Lemon will -add a prefix specified by this directive -to each of the #defines it generates. -So if the default output of Lemon looked like this: -<pre> - #define AND 1 - #define MINUS 2 - #define OR 3 - #define PLUS 4 -</pre> -You can insert a statement into the grammar like this: -<pre> - %token_prefix TOKEN_ -</pre> -to cause Lemon to produce these symbols instead: -<pre> - #define TOKEN_AND 1 - #define TOKEN_MINUS 2 - #define TOKEN_OR 3 - #define TOKEN_PLUS 4 -</pre> - -<h4>The <tt>%token_type</tt> and <tt>%type</tt> directives</h4> - -<p>These directives are used to specify the data types for values -on the parser's stack associated with terminal and non-terminal -symbols. The values of all terminal symbols must be of the same -type. This turns out to be the same data type as the 3rd parameter -to the Parse() function generated by Lemon. Typically, you will -make the value of a terminal symbol by a pointer to some kind of -token structure. Like this:</p> - -<p><pre> - %token_type {Token*} -</pre></p> - -<p>If the data type of terminals is not specified, the default value -is ``int''.</p> - -<p>Non-terminal symbols can each have their own data types. Typically -the data type of a non-terminal is a pointer to the root of a parse-tree -structure that contains all information about that non-terminal. -For example:</p> - -<p><pre> - %type expr {Expr*} -</pre></p> - -<p>Each entry on the parser's stack is actually a union containing -instances of all data types for every non-terminal and terminal symbol. -Lemon will automatically use the correct element of this union depending -on what the corresponding non-terminal or terminal symbol is. But -the grammar designer should keep in mind that the size of the union -will be the size of its largest element. So if you have a single -non-terminal whose data type requires 1K of storage, then your 100 -entry parser stack will require 100K of heap space. If you are willing -and able to pay that price, fine. You just need to know.</p> - -<h3>Error Processing</h3> - -<p>After extensive experimentation over several years, it has been -discovered that the error recovery strategy used by yacc is about -as good as it gets. And so that is what Lemon uses.</p> - -<p>When a Lemon-generated parser encounters a syntax error, it -first invokes the code specified by the %syntax_error directive, if -any. It then enters its error recovery strategy. The error recovery -strategy is to begin popping the parsers stack until it enters a -state where it is permitted to shift a special non-terminal symbol -named ``error''. It then shifts this non-terminal and continues -parsing. But the %syntax_error routine will not be called again -until at least three new tokens have been successfully shifted.</p> - -<p>If the parser pops its stack until the stack is empty, and it still -is unable to shift the error symbol, then the %parse_failed routine -is invoked and the parser resets itself to its start state, ready -to begin parsing a new file. This is what will happen at the very -first syntax error, of course, if there are no instances of the -``error'' non-terminal in your grammar.</p> - -</body> -</html> diff --git a/third_party/sqlite/src/doc/report1.txt b/third_party/sqlite/src/doc/report1.txt deleted file mode 100644 index a236e7c..0000000 --- a/third_party/sqlite/src/doc/report1.txt +++ /dev/null @@ -1,121 +0,0 @@ -An SQLite (version 1.0) database was used in a large military application -where the database contained 105 tables and indices. The following is -a breakdown on the sizes of keys and data within these tables and indices: - -Entries: 967089 -Size: 45896104 -Avg Size: 48 -Key Size: 11112265 -Avg Key Size: 12 -Max Key Size: 99 - - 0..8 263 0% - 9..12 5560 0% - 13..16 71394 7% - 17..24 180717 26% - 25..32 215442 48% - 33..40 151118 64% - 41..48 77479 72% - 49..56 13983 74% - 57..64 14481 75% - 65..80 41342 79% - 81..96 127098 92% - 97..112 38054 96% - 113..128 14197 98% - 129..144 8208 99% - 145..160 3326 99% - 161..176 1242 99% - 177..192 604 99% - 193..208 222 99% - 209..224 213 99% - 225..240 132 99% - 241..256 58 99% - 257..288 515 99% - 289..320 64 99% - 321..352 39 99% - 353..384 44 99% - 385..416 25 99% - 417..448 24 99% - 449..480 26 99% - 481..512 27 99% - 513..1024 470 99% - 1025..2048 396 99% - 2049..4096 187 99% - 4097..8192 78 99% - 8193..16384 35 99% -16385..32768 17 99% -32769..65536 6 99% -65537..65541 3 100% - -If the indices are omitted, the statistics for the 49 tables -become the following: - -Entries: 451103 -Size: 30930282 -Avg Size: 69 -Key Size: 1804412 -Avg Key Size: 4 -Max Key Size: 4 - - 0..24 89 0% - 25..32 9417 2% - 33..40 119162 28% - 41..48 68710 43% - 49..56 9539 45% - 57..64 12435 48% - 65..80 38650 57% - 81..96 126877 85% - 97..112 38030 93% - 113..128 14183 96% - 129..144 7668 98% - 145..160 3302 99% - 161..176 1238 99% - 177..192 597 99% - 193..208 217 99% - 209..224 211 99% - 225..240 130 99% - 241..256 57 99% - 257..288 100 99% - 289..320 62 99% - 321..352 34 99% - 353..384 43 99% - 385..416 24 99% - 417..448 24 99% - 449..480 25 99% - 481..512 27 99% - 513..1024 153 99% - 1025..2048 92 99% - 2049..4096 7 100% - -The 56 indices have these statistics: - -Entries: 512422 -Size: 14879828 -Avg Size: 30 -Key Size: 9253204 -Avg Key Size: 19 -Max Key Size: 99 - - 0..8 246 0% - 9..12 5486 1% - 13..16 70717 14% - 17..24 178246 49% - 25..32 205722 89% - 33..40 31951 96% - 41..48 8768 97% - 49..56 4444 98% - 57..64 2046 99% - 65..80 2691 99% - 81..96 202 99% - 97..112 11 99% - 113..144 527 99% - 145..160 20 99% - 161..288 406 99% - 289..1024 316 99% - 1025..2048 304 99% - 2049..4096 180 99% - 4097..8192 78 99% - 8193..16384 35 99% -16385..32768 17 99% -32769..65536 6 99% -65537..65541 3 100% diff --git a/third_party/sqlite/src/ext/fts1/fts1.c b/third_party/sqlite/src/ext/fts1/fts1.c index d5d00b94..d5429ff 100644 --- a/third_party/sqlite/src/ext/fts1/fts1.c +++ b/third_party/sqlite/src/ext/fts1/fts1.c @@ -208,7 +208,7 @@ static int safe_isspace(char c){ return (c&0x80)==0 ? isspace(c) : 0; } static int safe_tolower(char c){ - return (c>='A' && c<='Z') ? (c-'A'+'a') : c; + return (c&0x80)==0 ? tolower(c) : c; } static int safe_isalnum(char c){ return (c&0x80)==0 ? isalnum(c) : 0; @@ -1225,6 +1225,10 @@ static int sql_step_statement(fulltext_vtab *v, fulltext_statement iStmt, break; } return rc; + + err: + sqlite3_finalize(s); + return rc; } /* Like sql_step_statement(), but convert SQLITE_DONE to SQLITE_OK. diff --git a/third_party/sqlite/src/ext/fts1/fts1_tokenizer1.c b/third_party/sqlite/src/ext/fts1/fts1_tokenizer1.c index 90774da..f58fba8 100644 --- a/third_party/sqlite/src/ext/fts1/fts1_tokenizer1.c +++ b/third_party/sqlite/src/ext/fts1/fts1_tokenizer1.c @@ -182,7 +182,7 @@ static int simpleNext( ** case-insensitivity. */ unsigned char ch = p[iStartOffset+i]; - c->pToken[i] = (ch>='A' && ch<='Z') ? (ch-'A'+'a') : ch; + c->pToken[i] = ch<0x80 ? tolower(ch) : ch; } *ppToken = c->pToken; *pnBytes = n; diff --git a/third_party/sqlite/src/ext/fts1/simple_tokenizer.c b/third_party/sqlite/src/ext/fts1/simple_tokenizer.c index 9a52bd1..d00a770 100644 --- a/third_party/sqlite/src/ext/fts1/simple_tokenizer.c +++ b/third_party/sqlite/src/ext/fts1/simple_tokenizer.c @@ -138,7 +138,7 @@ static int simpleNext( ** case-insensitivity. */ char ch = c->pCurrent[ii]; - c->zToken[ii] = ((ch>='A' && ch<='Z') ? (ch-'A'+'a') : ch); + c->zToken[ii] = (unsigned char)ch<0x80 ? tolower(ch) : ch; } c->zToken[n] = '\0'; *ppToken = c->zToken; diff --git a/third_party/sqlite/src/ext/icu/icu.c b/third_party/sqlite/src/ext/icu/icu.c index 2e2251c..e99f142 100644 --- a/third_party/sqlite/src/ext/icu/icu.c +++ b/third_party/sqlite/src/ext/icu/icu.c @@ -38,11 +38,6 @@ #include <assert.h> -// TODO(evanm): this is cut'n'pasted from fts2.c. Why is it necessary? -#if !defined(SQLITE_CORE) -# define SQLITE_CORE 1 -#endif - #ifndef SQLITE_CORE #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/third_party/sqlite/src/ext/rtree/rtree1.test b/third_party/sqlite/src/ext/rtree/rtree1.test index 8c1675b..8c1675b 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree1.test +++ b/third_party/sqlite/src/ext/rtree/rtree1.test diff --git a/third_party/sqlite/src/ext/rtree/rtree2.test b/third_party/sqlite/src/ext/rtree/rtree2.test index 7e38c8f..7e38c8f 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree2.test +++ b/third_party/sqlite/src/ext/rtree/rtree2.test diff --git a/third_party/sqlite/src/ext/rtree/rtree3.test b/third_party/sqlite/src/ext/rtree/rtree3.test index b83ceeb4..b83ceeb4 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree3.test +++ b/third_party/sqlite/src/ext/rtree/rtree3.test diff --git a/third_party/sqlite/src/ext/rtree/rtree4.test b/third_party/sqlite/src/ext/rtree/rtree4.test index d73e7a6..d73e7a6 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree4.test +++ b/third_party/sqlite/src/ext/rtree/rtree4.test diff --git a/third_party/sqlite/src/ext/rtree/rtree5.test b/third_party/sqlite/src/ext/rtree/rtree5.test index 4fa007f..4fa007f 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree5.test +++ b/third_party/sqlite/src/ext/rtree/rtree5.test diff --git a/third_party/sqlite/src/ext/rtree/rtree_perf.tcl b/third_party/sqlite/src/ext/rtree/rtree_perf.tcl index fa3a4d3..fa3a4d3 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree_perf.tcl +++ b/third_party/sqlite/src/ext/rtree/rtree_perf.tcl diff --git a/third_party/sqlite/src/ext/rtree/rtree_util.tcl b/third_party/sqlite/src/ext/rtree/rtree_util.tcl index 55482e4..55482e4 100755..100644 --- a/third_party/sqlite/src/ext/rtree/rtree_util.tcl +++ b/third_party/sqlite/src/ext/rtree/rtree_util.tcl diff --git a/third_party/sqlite/src/ext/rtree/viewrtree.tcl b/third_party/sqlite/src/ext/rtree/viewrtree.tcl index 2b4dd1b..2b4dd1b 100755..100644 --- a/third_party/sqlite/src/ext/rtree/viewrtree.tcl +++ b/third_party/sqlite/src/ext/rtree/viewrtree.tcl diff --git a/third_party/sqlite/src/main.mk b/third_party/sqlite/src/main.mk index bb49b31..382e7ca 100644 --- a/third_party/sqlite/src/main.mk +++ b/third_party/sqlite/src/main.mk @@ -69,10 +69,6 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \ walker.o where.o utf.o vtab.o -LIBOBJ += fts1.o \ - fts1_hash.o \ - fts1_tokenizer1.o \ - fts1_porter.o LIBOBJ += fts2.o \ fts2_hash.o \ fts2_icu.o \ @@ -254,14 +250,6 @@ TESTSRC = \ $(TOP)/src/test_wsd.c TESTSRC += \ - $(TOP)/ext/fts1/fts1.c \ - $(TOP)/ext/fts1/fts1.h \ - $(TOP)/ext/fts1/fts1_hash.c \ - $(TOP)/ext/fts1/fts1_hash.h \ - $(TOP)/ext/fts1/fts1_porter.c \ - $(TOP)/ext/fts1/fts1_tokenizer.h \ - $(TOP)/ext/fts1/fts1_tokenizer1.c -TESTSRC += \ $(TOP)/ext/fts2/fts2.c \ $(TOP)/ext/fts2/fts2.h \ $(TOP)/ext/fts2/fts2_hash.c \ @@ -476,20 +464,6 @@ rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c - - -fts1.o: $(TOP)/ext/fts1/fts1.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1.c - -fts1_hash.o: $(TOP)/ext/fts1/fts1_hash.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_hash.c - -fts1_tokenizer1.o: $(TOP)/ext/fts1/fts1_tokenizer1.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_tokenizer1.c - -fts1_porter.o: $(TOP)/ext/fts1/fts1_porter.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_porter.c - # Rules for building test programs and for running tests # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a @@ -530,9 +504,6 @@ test: testfixture$(EXE) sqlite3$(EXE) ftstest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/fts.test -fts1test: testfixture$(EXE) sqlite3$(EXE) - ./testfixture$(EXE) $(TOP)/test/fts1.test - fts2test: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/fts2.test diff --git a/third_party/sqlite/src/mkopcodeh.awk b/third_party/sqlite/src/mkopcodeh.awk index 796a7af..796a7af 100755..100644 --- a/third_party/sqlite/src/mkopcodeh.awk +++ b/third_party/sqlite/src/mkopcodeh.awk diff --git a/third_party/sqlite/src/publish.sh b/third_party/sqlite/src/publish.sh index 87b8346..87b8346 100755..100644 --- a/third_party/sqlite/src/publish.sh +++ b/third_party/sqlite/src/publish.sh diff --git a/third_party/sqlite/src/src/btree.c b/third_party/sqlite/src/src/btree.c index 2db3c90..a9ab445 100644 --- a/third_party/sqlite/src/src/btree.c +++ b/third_party/sqlite/src/src/btree.c @@ -24,12 +24,6 @@ static const char zMagicHeader[] = SQLITE_FILE_HEADER; /* -** The header string that appears at the beginning of a SQLite -** database which has been poisoned. -*/ -static const char zPoisonHeader[] = "SQLite poison 3"; - -/* ** Set this global variable to 1 to enable tracing using the TRACE ** macro. */ @@ -2343,7 +2337,6 @@ static int newDatabase(BtShared *pBt){ if( rc ) return rc; memcpy(data, zMagicHeader, sizeof(zMagicHeader)); assert( sizeof(zMagicHeader)==16 ); - assert( sizeof(zMagicHeader)==sizeof(zPoisonHeader) ); put2byte(&data[16], pBt->pageSize); data[18] = 1; data[19] = 1; @@ -7811,72 +7804,4 @@ void sqlite3BtreeCacheOverflow(BtCursor *pCur){ assert(!pCur->aOverflow); pCur->isIncrblobHandle = 1; } - -/* Poison the db so that other clients error out as quickly as -** possible. -*/ -int sqlite3Poison(sqlite3 *db){ - int rc; - Btree *p; - BtShared *pBt; - unsigned char *pP1; - - if( db == NULL) return SQLITE_OK; - - /* Database 0 corrosponds to the main database. */ - if( db->nDb<1 ) return SQLITE_OK; - p = db->aDb[0].pBt; - pBt = p->pBt; - - /* If in a transaction, roll it back. Committing any changes to a - ** corrupt database may mess up evidence, we definitely don't want - ** to allow poisoning to be rolled back, and the database is anyhow - ** going bye-bye RSN. - */ - /* TODO(shess): Figure out if this might release the lock and let - ** someone else get in there, which might deny us the lock a couple - ** lines down. - */ - if( sqlite3BtreeIsInTrans(p) ) sqlite3BtreeRollback(p); - - /* Start an exclusive transaction. This will check the headers, so - ** if someone else poisoned the database we should get an error. - */ - rc = sqlite3BtreeBeginTrans(p, 2); - /* TODO(shess): Handle SQLITE_BUSY? */ - if( rc!=SQLITE_OK ) return rc; - - /* Copied from sqlite3BtreeUpdateMeta(). Writing the old version of - ** the page to the journal may be overkill, but it probably won't - ** hurt. - */ - assert( pBt->inTrans==TRANS_WRITE ); - assert( pBt->pPage1!=0 ); - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc ) goto err; - - /* "SQLite format 3" changes to - ** "SQLite poison 3". Be extra paranoid about making this change. - */ - if( sizeof(zMagicHeader)!=16 || - sizeof(zPoisonHeader)!=sizeof(zMagicHeader) ){ - rc = SQLITE_ERROR; - goto err; - } - pP1 = pBt->pPage1->aData; - if( memcmp(pP1, zMagicHeader, 16)!=0 ){ - rc = SQLITE_CORRUPT; - goto err; - } - memcpy(pP1, zPoisonHeader, 16); - - /* Push it to the database file. */ - return sqlite3BtreeCommit(p); - - err: - /* TODO(shess): What about errors, here? */ - sqlite3BtreeRollback(p); - return rc; -} - #endif diff --git a/third_party/sqlite/src/src/build.c b/third_party/sqlite/src/src/build.c index 90bfef4..d5846da 100644 --- a/third_party/sqlite/src/src/build.c +++ b/third_party/sqlite/src/src/build.c @@ -3665,7 +3665,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ /* Begin preload-cache.patch for Chromium */ /* See declaration in sqlite3.h for information */ -int sqlite3Preload(sqlite3 *db) +int sqlite3_preload(sqlite3 *db) { Pager *pPager; Btree *pBt; diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/src/src/main.c index 3704628..3a6fccf 100644 --- a/third_party/sqlite/src/src/main.c +++ b/third_party/sqlite/src/src/main.c @@ -17,7 +17,7 @@ #include "sqliteInt.h" #ifdef SQLITE_ENABLE_FTS3 -# include "../../ext/fts3/fts3.h" +# include "../ext/fts3/fts3.h" #endif #ifdef SQLITE_ENABLE_RTREE # include "rtree.h" diff --git a/third_party/sqlite/src/src/os.h b/third_party/sqlite/src/src/os.h index 58941ce..7bc848f 100644 --- a/third_party/sqlite/src/src/os.h +++ b/third_party/sqlite/src/src/os.h @@ -29,10 +29,6 @@ ** will defined to either 1 or 0. One of the four will be 1. The other ** three will be 0. */ -#ifdef OS_SYMBIAN -# define SQLITE_OS_SYMBIAN 1 -# define SQLITE_OS_OTHER 1 -#endif #if defined(SQLITE_OS_OTHER) # if SQLITE_OS_OTHER==1 # undef SQLITE_OS_UNIX diff --git a/third_party/sqlite/src/src/os_symbian.cc b/third_party/sqlite/src/src/os_symbian.cc deleted file mode 100644 index 5b86338..0000000 --- a/third_party/sqlite/src/src/os_symbian.cc +++ /dev/null @@ -1,579 +0,0 @@ -// Copyright 2008, Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This file contains code that is specific to Symbian. -// Differently from the rest of SQLite, it is implemented in C++ as this is -// the native language of the OS and all interfaces we need to use are C++. -// -// This file follows the Gears code style guidelines. - -#ifdef OS_SYMBIAN -#include <coemain.h> -#include <e32math.h> -#include <f32file.h> -#include <utf.h> - -extern "C" { -#include "sqliteInt.h" -#include "os_common.h" -} - -const TInt kFileLockAttempts = 3; - -// The global file system session. -RFs g_fs_session; - -static TInt UTF8ToUTF16(const char *in, TDes *out16) { - assert(in); - TPtrC8 in_des(reinterpret_cast<const unsigned char*>(in)); - return CnvUtfConverter::ConvertToUnicodeFromUtf8(*out16, in_des); -} - -static TInt UTF16ToUTF8(const TDesC16& in16, TDes8 *out8) { - return CnvUtfConverter::ConvertFromUnicodeToUtf8(*out8, in16); -} - -// The SymbianFile structure is a subclass of sqlite3_file* specific to the -// Symbian portability layer. -struct SymbianFile { - const sqlite3_io_methods *methods; - RFile handle; // The file handle - TUint8 lock_type; // Type of lock currently held on this file - TUint16 shared_lock_byte; // Randomly chosen byte used as a shared lock -}; - -static SymbianFile* ConvertToSymbianFile(sqlite3_file* const id) { - assert(id); - return reinterpret_cast<SymbianFile*>(id); -} - -static int SymbianClose(sqlite3_file *id) { - SymbianFile *file_id = ConvertToSymbianFile(id); - file_id->handle.Close(); - OpenCounter(-1); - return SQLITE_OK; -} - -static int SymbianRead(sqlite3_file *id, - void *buffer, - int amount, - sqlite3_int64 offset) { - assert(buffer); - assert(amount >=0); - assert(offset >=0); - - SymbianFile* file_id = ConvertToSymbianFile(id); - TPtr8 dest(static_cast<unsigned char*>(buffer), amount); - - if (KErrNone == file_id->handle.Read(offset, dest, amount)) { - if (dest.Length() == amount) { - return SQLITE_OK; - } else { - return SQLITE_IOERR_SHORT_READ; - } - } else { - return SQLITE_IOERR; - } -} - -static int SymbianWrite(sqlite3_file *id, - const void *buffer, - int amount, - sqlite3_int64 offset) { - assert(buffer); - assert(amount >=0); - assert(offset >=0); - - SymbianFile *file_id = ConvertToSymbianFile(id); - TPtrC8 src(static_cast<const unsigned char*>(buffer), amount); - if (file_id->handle.Write(offset, src) != KErrNone) { - return SQLITE_IOERR_WRITE; - } - - return SQLITE_OK; -} - -static int SymbianTruncate(sqlite3_file *id, sqlite3_int64 bytes) { - assert(bytes >=0); - - SymbianFile *file_id = ConvertToSymbianFile(id); - if (file_id->handle.SetSize(bytes) != KErrNone) { - return SQLITE_IOERR; - } - return SQLITE_OK; -} - -static int SymbianSync(sqlite3_file *id, int /*flags*/) { - SymbianFile *file_id = ConvertToSymbianFile(id); - if (file_id->handle.Flush() != KErrNone) { - return SQLITE_IOERR; - } else { - return SQLITE_OK; - } -} - -static int SymbianFileSize(sqlite3_file *id, sqlite3_int64 *size) { - assert(size); - - SymbianFile *file_id = ConvertToSymbianFile(id); - TInt size_tmp; - if (file_id->handle.Size(size_tmp) != KErrNone) { - return SQLITE_IOERR; - } - *size = size_tmp; - return SQLITE_OK; -} - -// File lock/unlock functions; see os_win.c for a description -// of the algorithm used. -static int GetReadLock(SymbianFile *file) { - file->shared_lock_byte = Math::Random() % (SHARED_SIZE - 1); - return file->handle.Lock(SHARED_FIRST + file->shared_lock_byte, 1); -} - -static int UnlockReadLock(SymbianFile *file) { - return file->handle.UnLock(SHARED_FIRST + file->shared_lock_byte, 1); -} - -static int SymbianLock(sqlite3_file *id, int lock_type) { - SymbianFile *file = ConvertToSymbianFile(id); - if (file->lock_type >= lock_type) { - return SQLITE_OK; - } - - // Make sure the locking sequence is correct - assert(file->lock_type != NO_LOCK || lock_type == SHARED_LOCK); - assert(lock_type != PENDING_LOCK); - assert(lock_type != RESERVED_LOCK || file->lock_type == SHARED_LOCK); - - // Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or - // a SHARED lock. If we are acquiring a SHARED lock, the acquisition of - // the PENDING_LOCK byte is temporary. - int new_lock_type = file->lock_type; - int got_pending_lock = 0; - int res = KErrNone; - if (file->lock_type == NO_LOCK || - (lock_type == EXCLUSIVE_LOCK && file->lock_type == RESERVED_LOCK)) { - int count = kFileLockAttempts; - while (count-- > 0 && - (res = file->handle.Lock(PENDING_BYTE, 1)) != KErrNone ) { - // Try 3 times to get the pending lock. The pending lock might be - // held by another reader process who will release it momentarily. - OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); - User::After(1000); - } - got_pending_lock = (res == KErrNone? 1 : 0); - } - - // Acquire a shared lock - if (lock_type == SHARED_LOCK && res == KErrNone) { - assert(file->lock_type == NO_LOCK); - res = GetReadLock(file); - if (res == KErrNone) { - new_lock_type = SHARED_LOCK; - } - } - - // Acquire a RESERVED lock - if (lock_type == RESERVED_LOCK && res == KErrNone) { - assert(file->lock_type == SHARED_LOCK); - res = file->handle.Lock(RESERVED_BYTE, 1); - if (res == KErrNone) { - new_lock_type = RESERVED_LOCK; - } - } - - // Acquire a PENDING lock - if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { - new_lock_type = PENDING_LOCK; - got_pending_lock = 0; - } - - // Acquire an EXCLUSIVE lock - if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { - assert(file->lock_type >= SHARED_LOCK); - res = UnlockReadLock(file); - OSTRACE2("unreadlock = %d\n", res); - res = file->handle.Lock(SHARED_FIRST, SHARED_SIZE); - if (res == KErrNone) { - new_lock_type = EXCLUSIVE_LOCK; - } else { - OSTRACE2("error-code = %d\n", GetLastError()); - GetReadLock(file); - } - } - - // If we are holding a PENDING lock that ought to be released, then - // release it now. - if (got_pending_lock && lock_type == SHARED_LOCK) { - file->handle.UnLock(PENDING_BYTE, 1); - } - - // Update the state of the lock held in the file descriptor, then - // return the appropriate result code. - file->lock_type = new_lock_type; - if (res == KErrNone) { - return SQLITE_OK; - } else { - OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", file->handle, - lock_type, new_lock_type); - return SQLITE_BUSY; - } -} - -static int SymbianUnlock(sqlite3_file *id, int lock_type) { - int type; - int rc = SQLITE_OK; - SymbianFile *file = ConvertToSymbianFile(id); - assert(lock_type <= SHARED_LOCK); - OSTRACE5("UNLOCK %d to %d was %d(%d)\n", file->handle, lock_type, - file->lock_type, file->shared_lock_byte); - type = file->lock_type; - if (type >= EXCLUSIVE_LOCK) { - file->handle.UnLock(SHARED_FIRST, SHARED_SIZE); - if (lock_type == SHARED_LOCK && GetReadLock(file) != KErrNone) { - // This should never happen. We should always be able to - // reacquire the read lock - rc = SQLITE_IOERR_UNLOCK; - } - } - if (type >= RESERVED_LOCK) { - file->handle.UnLock(RESERVED_BYTE, 1); - } - if (lock_type == NO_LOCK && type >= SHARED_LOCK) { - UnlockReadLock(file); - } - if (type >= PENDING_LOCK) { - file->handle.UnLock(PENDING_BYTE, 1); - } - file->lock_type = lock_type; - return rc; -} - -static int SymbianCheckReservedLock(sqlite3_file *id, int *result) { - int rc; - SymbianFile *file = ConvertToSymbianFile(id); - if (file->lock_type >= RESERVED_LOCK) { - rc = 1; - OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); - } else { - rc = file->handle.Lock(RESERVED_BYTE, 1); - if (rc == KErrNone) { - file->handle.UnLock(RESERVED_BYTE, 1); - } - rc = !rc; - OSTRACE3("TEST WR-LOCK %d %d (remote)\n", file->handle, rc); - } - *result = rc; - return SQLITE_OK; -} - -static int SymbianFileControl(sqlite3_file */*id*/, - int /*op*/, - void */*arg*/) { - return SQLITE_OK; -} - -static int SymbianSectorSize(sqlite3_file */*id*/) { - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -static int SymbianDeviceCharacteristics(sqlite3_file */*id*/) { - return 0; -} - -/* -** This vector defines all the methods that can operate on a -** sqlite3_file for Symbian. -*/ -static const sqlite3_io_methods SymbianIoMethod = { - 1, // iVersion - SymbianClose, - SymbianRead, - SymbianWrite, - SymbianTruncate, - SymbianSync, - SymbianFileSize, - SymbianLock, - SymbianUnlock, - SymbianCheckReservedLock, - SymbianFileControl, - SymbianSectorSize, - SymbianDeviceCharacteristics -}; - -// ============================================================================ -// vfs methods begin here -// ============================================================================ -static int SymbianOpen(sqlite3_vfs */*vfs*/, - const char *name, - sqlite3_file *id, - int flags, - int *out_flags) { - TUint desired_access; - TUint share_mode; - TInt err = KErrNone; - TFileName name_utf16; - SymbianFile *file = ConvertToSymbianFile(id); - - if (out_flags) { - *out_flags = flags; - } - - // if the name is NULL we have to open a temporary file. - if (!name) { - TPath private_path; - TFileName file_name; - if (g_fs_session.PrivatePath(private_path) != KErrNone) { - return SQLITE_CANTOPEN; - } - if (file->handle.Temp(g_fs_session, - private_path, - file_name, - EFileWrite) != - KErrNone) { - return SQLITE_CANTOPEN; - } - file->methods = &SymbianIoMethod; - file->lock_type = NO_LOCK; - file->shared_lock_byte = 0; - OpenCounter(+1); - return SQLITE_OK; - } - - if (UTF8ToUTF16(name, &name_utf16) != KErrNone) - return SQLITE_CANTOPEN; - - if (flags & SQLITE_OPEN_READWRITE) { - desired_access = EFileWrite; - } else { - desired_access = EFileRead; - } - if (flags & SQLITE_OPEN_MAIN_DB) { - share_mode = EFileShareReadersOrWriters; - } else { - share_mode = 0; - } - - if (flags & SQLITE_OPEN_CREATE) { - err = file->handle.Create(g_fs_session, - name_utf16, - desired_access | share_mode); - if (err != KErrNone && err != KErrAlreadyExists) { - return SQLITE_CANTOPEN; - } - } - - if (err != KErrNone) { - err = file->handle.Open(g_fs_session, - name_utf16, - desired_access | share_mode); - if (err != KErrNone && flags & SQLITE_OPEN_READWRITE) { - if (out_flags) { - *out_flags = (flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE; - } - desired_access = EFileRead; - err = file->handle.Open(g_fs_session, - name_utf16, - desired_access | share_mode); - } - if (err != KErrNone) { - return SQLITE_CANTOPEN; - } - } - file->methods = &SymbianIoMethod; - file->lock_type = NO_LOCK; - file->shared_lock_byte = 0; - OpenCounter(+1); - return SQLITE_OK; -} - -static int SymbianDelete(sqlite3_vfs */*vfs*/, - const char *file_name, - int /*sync_dir*/) { - assert(file_name); - TFileName file_name_utf16; - - if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { - return SQLITE_ERROR; - } - - TInt result = g_fs_session.Delete(file_name_utf16); - return (result == KErrNone || result == KErrPathNotFound)? - SQLITE_OK : SQLITE_IOERR_DELETE; -} - -static int SymbianAccess(sqlite3_vfs */*vfs*/, - const char *file_name, - int flags, - int *result) { - assert(file_name); - TEntry entry; - TFileName file_name_utf16; - - if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { - return SQLITE_ERROR; - } - - if (g_fs_session.Entry(file_name_utf16, entry) != KErrNone) { - *result = 0; - return SQLITE_OK; - } - - switch (flags) { - case SQLITE_ACCESS_READ: - case SQLITE_ACCESS_EXISTS: - *result = !entry.IsDir(); - break; - case SQLITE_ACCESS_READWRITE: - *result = !entry.IsDir() && !entry.IsReadOnly(); - break; - default: - return SQLITE_ERROR; - } - - return SQLITE_OK; -} - -static int SymbianFullPathname(sqlite3_vfs */*vfs*/, - const char *relative, - int full_len, - char *full) { - assert(relative); - assert(full); - - TParse parse; - TPath relative_utf16; - TPath base_path; - TPtr8 full_utf8(reinterpret_cast<unsigned char*>(full), full_len); - - g_fs_session.PrivatePath(base_path); - - if (UTF8ToUTF16(relative, &relative_utf16) != KErrNone) { - return SQLITE_ERROR; - } - - if (parse.Set(relative_utf16, &base_path, NULL) != KErrNone) { - return SQLITE_ERROR; - } - - TDesC full_utf16(parse.FullName()); - if (UTF16ToUTF8(relative_utf16, &full_utf8) != KErrNone) { - return SQLITE_ERROR; - } - - full_utf8.PtrZ(); - return SQLITE_OK; -} - -static int SymbianRandomness(sqlite3_vfs */*vfs*/, int buf_len, char *buffer) { - assert(buffer); - TInt64 seed = User::TickCount(); - for (TInt i = 0; i < buf_len; i++) { - buffer[i] = Math::Rand(seed) % 255; - } - return SQLITE_OK; -} - -static int SymbianSleep(sqlite3_vfs */*vfs*/, int microsec) { - User::After(microsec); - return SQLITE_OK; -} - -int SymbianCurrentTime(sqlite3_vfs */*vfs*/, double *now) { - _LIT(kEpoch, "19700101:000000.000000"); - assert(now); - TTime time; - TTime epoch_time(kEpoch); - TTimeIntervalSeconds interval; - - time.HomeTime(); - // calculate seconds elapsed since 1-1-1970 - time.SecondsFrom(epoch_time, interval); - - // Julian date @ 1-1-1970 = 2440587.5 - // seconds per day = 86400.0 - *now = interval.Int()/86400.0 + 2440587.5; - return SQLITE_OK; -} - -static int SymbianGetLastError(sqlite3_vfs */*vfs*/, - int /*buf_len*/, - char */*buf*/) { - assert(buf[0] == '\0'); - return 0; -} - -// Interfaces for opening a shared library, finding entry points -// within the shared library, and closing the shared library. -// TODO(marcogelmi): implement. -#define SymbianDlOpen 0 -#define SymbianDlError 0 -#define SymbianDlSym 0 -#define SymbianDlClose 0 - -// Initialize and deinitialize the operating system interface. -int sqlite3_os_init(void) { - static sqlite3_vfs symbian_vfs = { - 1, // iVersion - sizeof(SymbianFile), // szOsFile - KMaxPath, // mxPathname - 0, // pNext - "symbian", // name - 0, // pAppData - - SymbianOpen, // xOpen - SymbianDelete, // xDelete - SymbianAccess, // xAccess - SymbianFullPathname, // xFullPathname - SymbianDlOpen, // xDlOpen - SymbianDlError, // xDlError - SymbianDlSym, // xDlSym - SymbianDlClose, // xDlClose - SymbianRandomness, // xRandomness - SymbianSleep, // xSleep - SymbianCurrentTime, // xCurrentTime - SymbianGetLastError // xGetLastError - }; - - if (g_fs_session.Connect() != KErrNone) { - return SQLITE_ERROR; - } - - if (g_fs_session.ShareAuto() != KErrNone) { - g_fs_session.Close(); - return SQLITE_ERROR; - } - - sqlite3_vfs_register(&symbian_vfs, 1); - return SQLITE_OK; -} - -int sqlite3_os_end(void) { - g_fs_session.Close(); - return SQLITE_OK; -} - -#endif /* OS_SYMBIAN*/ diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/src/src/os_unix.c index 3ebfa04..e5e1509 100644 --- a/third_party/sqlite/src/src/os_unix.c +++ b/third_party/sqlite/src/src/os_unix.c @@ -3215,7 +3215,6 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ ********************** End sqlite3_file Methods ******************************* ******************************************************************************/ - /* ** This division contains definitions of sqlite3_io_methods objects that ** implement various file locking strategies. It also contains definitions @@ -3497,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); */ /* +** Initializes a unixFile structure with zeros. +*/ +void initUnixFile(sqlite3_file* file) { + memset(file, 0, sizeof(unixFile)); +} + +/* ** Initialize the contents of the unixFile structure pointed to by pId. */ -static int fillInUnixFile( +int fillInUnixFile( sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ int dirfd, /* Directory file descriptor */ @@ -4082,7 +4088,7 @@ static int unixOpen( } } #endif - + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); open_finished: if( rc!=SQLITE_OK ){ diff --git a/third_party/sqlite/src/src/shell.c b/third_party/sqlite/src/src/shell.c index 22420b8..84d0744 100644 --- a/third_party/sqlite/src/src/shell.c +++ b/third_party/sqlite/src/src/shell.c @@ -3008,15 +3008,11 @@ int main(int argc, char **argv){ int rc = 0; /* Begin evanm patch. */ -#ifdef SQLITE_GEARS_DISABLE_SHELL_ICU - /* Gears doesn't use this. */ -#else extern int sqlite_shell_init_icu(); if( !sqlite_shell_init_icu() ){ fprintf(stderr, "%s: warning: couldn't find icudt38.dll; " "queries against ICU FTS tables will fail.\n", argv[0]); } -#endif /* End evanm patch. */ Argv0 = argv[0]; diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in index 305ef78..3643b26 100644 --- a/third_party/sqlite/src/src/sqlite.h.in +++ b/third_party/sqlite/src/src/sqlite.h.in @@ -4689,7 +4689,7 @@ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); ** them all and try to load them. If none are loadable successfully, we return ** an error. Otherwise, we return OK. */ -int sqlite3Preload(sqlite3 *db); +int sqlite3_preload(sqlite3 *db); /* End preload-cache.patch for Chromium */ /* diff --git a/third_party/sqlite/src/src/util.c b/third_party/sqlite/src/src/util.c index 81e42b4..d12bcd5 100644 --- a/third_party/sqlite/src/src/util.c +++ b/third_party/sqlite/src/src/util.c @@ -1,1094 +1,1094 @@ -/* -** 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. -** -************************************************************************* -** Utility functions used throughout sqlite. -** -** This file contains functions for allocating memory, comparing -** strings, and stuff like that. -** -*/ -#include "sqliteInt.h" -#include <stdarg.h> -#ifdef SQLITE_HAVE_ISNAN -# include <math.h> -#endif - -/* -** Routine needed to support the testcase() macro. -*/ -#ifdef SQLITE_COVERAGE_TEST -void sqlite3Coverage(int x){ - static int dummy = 0; - dummy += x; -} -#endif - -/* -** Return true if the floating point value is Not a Number (NaN). -** -** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. -** Otherwise, we have our own implementation that works on most systems. -*/ -int sqlite3IsNaN(double x){ - int rc; /* The value return */ -#if !defined(SQLITE_HAVE_ISNAN) - /* - ** Systems that support the isnan() library function should probably - ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have - ** found that many systems do not have a working isnan() function so - ** this implementation is provided as an alternative. - ** - ** This NaN test sometimes fails if compiled on GCC with -ffast-math. - ** On the other hand, the use of -ffast-math comes with the following - ** warning: - ** - ** This option [-ffast-math] should never be turned on by any - ** -O option since it can result in incorrect output for programs - ** which depend on an exact implementation of IEEE or ISO - ** rules/specifications for math functions. - ** - ** Under MSVC, this NaN test may fail if compiled with a floating- - ** point precision mode other than /fp:precise. From the MSDN - ** documentation: - ** - ** The compiler [with /fp:precise] will properly handle comparisons - ** involving NaN. For example, x != x evaluates to true if x is NaN - ** ... - */ -#ifdef __FAST_MATH__ -# error SQLite will not work correctly with the -ffast-math option of GCC. -#endif - volatile double y = x; - volatile double z = y; - rc = (y!=z); -#else /* if defined(SQLITE_HAVE_ISNAN) */ - rc = isnan(x); -#endif /* SQLITE_HAVE_ISNAN */ - testcase( rc ); - return rc; -} - -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -** -** The value returned will never be negative. Nor will it ever be greater -** than the actual length of the string. For very long strings (greater -** than 1GiB) the value returned might be less than the true string length. -*/ -int sqlite3Strlen30(const char *z){ - const char *z2 = z; - if( z==0 ) return 0; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - -/* -** Set the most recent error code and error string for the sqlite -** handle "db". The error code is set to "err_code". -** -** If it is not NULL, string zFormat specifies the format of the -** error string in the style of the printf functions: The following -** format characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** zFormat and any string tokens that follow it are assumed to be -** encoded in UTF-8. -** -** To clear the most recent error for sqlite handle "db", sqlite3Error -** should be called with err_code set to SQLITE_OK and zFormat set -** to NULL. -*/ -void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){ - if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ - db->errCode = err_code; - if( zFormat ){ - char *z; - va_list ap; - va_start(ap, zFormat); - z = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); - }else{ - sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC); - } - } -} - -/* -** Add an error message to pParse->zErrMsg and increment pParse->nErr. -** The following formatting characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** This function should be used to report any error that occurs whilst -** compiling an SQL statement (i.e. within sqlite3_prepare()). The -** last thing the sqlite3_prepare() function does is copy the error -** stored by this function into the database handle using sqlite3Error(). -** Function sqlite3Error() should be used during statement execution -** (sqlite3_step() etc.). -*/ -void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ - va_list ap; - sqlite3 *db = pParse->db; - pParse->nErr++; - sqlite3DbFree(db, pParse->zErrMsg); - va_start(ap, zFormat); - pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - pParse->rc = SQLITE_ERROR; -} - -/* -** Clear the error message in pParse, if any -*/ -void sqlite3ErrorClear(Parse *pParse){ - sqlite3DbFree(pParse->db, pParse->zErrMsg); - pParse->zErrMsg = 0; - pParse->nErr = 0; -} - -/* -** Convert an SQL-style quoted string into a normal string by removing -** the quote characters. The conversion is done in-place. If the -** input does not begin with a quote character, then this routine -** is a no-op. -** -** The input string must be zero-terminated. A new zero-terminator -** is added to the dequoted string. -** -** The return value is -1 if no dequoting occurs or the length of the -** dequoted string, exclusive of the zero terminator, if dequoting does -** occur. -** -** 2002-Feb-14: This routine is extended to remove MS-Access style -** brackets from around identifers. For example: "[a-b-c]" becomes -** "a-b-c". -*/ -int sqlite3Dequote(char *z){ - char quote; - int i, j; - if( z==0 ) return -1; - quote = z[0]; - switch( quote ){ - case '\'': break; - case '"': break; - case '`': break; /* For MySQL compatibility */ - case '[': quote = ']'; break; /* For MS SqlServer compatibility */ - default: return -1; - } - for(i=1, j=0; ALWAYS(z[i]); i++){ - if( z[i]==quote ){ - if( z[i+1]==quote ){ - z[j++] = quote; - i++; - }else{ - break; - } - }else{ - z[j++] = z[i]; - } - } - z[j] = 0; - return j; -} - -/* Convenient short-hand */ -#define UpperToLower sqlite3UpperToLower - -/* -** Some systems have stricmp(). Others have strcasecmp(). Because -** there is no consistency, we will define our own. -*/ -int sqlite3StrICmp(const char *zLeft, const char *zRight){ - register unsigned char *a, *b; - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } - return UpperToLower[*a] - UpperToLower[*b]; -} -int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ - register unsigned char *a, *b; - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } - return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; -} - -/* -** Return TRUE if z is a pure numeric string. Return FALSE and leave -** *realnum unchanged if the string contains any character which is not -** part of a number. -** -** If the string is pure numeric, set *realnum to TRUE if the string -** contains the '.' character or an "E+000" style exponentiation suffix. -** Otherwise set *realnum to FALSE. Note that just becaue *realnum is -** false does not mean that the number can be successfully converted into -** an integer - it might be too big. -** -** An empty string is considered non-numeric. -*/ -int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ - int incr = (enc==SQLITE_UTF8?1:2); - if( enc==SQLITE_UTF16BE ) z++; - if( *z=='-' || *z=='+' ) z += incr; - if( !sqlite3Isdigit(*z) ){ - return 0; - } - z += incr; - *realnum = 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - if( *z=='.' ){ - z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z += incr; - if( *z=='+' || *z=='-' ) z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - return *z==0; -} - -/* -** The string z[] is an ASCII representation of a real number. -** Convert this string to a double. -** -** This routine assumes that z[] really is a valid number. If it -** is not, the result is undefined. -** -** This routine is used instead of the library atof() function because -** the library atof() might want to use "," as the decimal point instead -** of "." depending on how locale is set. But that would cause problems -** for SQL. So this routine always uses "." regardless of locale. -*/ -int sqlite3AtoF(const char *z, double *pResult){ -#ifndef SQLITE_OMIT_FLOATING_POINT - const char *zBegin = z; - /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ - double result; - int nDigits = 0; - - /* skip leading spaces */ - while( sqlite3Isspace(*z) ) z++; - /* get sign of significand */ - if( *z=='-' ){ - sign = -1; - z++; - }else if( *z=='+' ){ - z++; - } - /* skip leading zeroes */ - while( z[0]=='0' ) z++, nDigits++; - - /* copy max significant digits to significand */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ - s = s*10 + (*z - '0'); - z++, nDigits++; - } - /* skip non-significant significand digits - ** (increase exponent by d to shift decimal left) */ - while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; - - /* if decimal point is present */ - if( *z=='.' ){ - z++; - /* copy digits from after decimal to significand - ** (decrease exponent by d to shift decimal right) */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ - s = s*10 + (*z - '0'); - z++, nDigits++, d--; - } - /* skip non-significant digits */ - while( sqlite3Isdigit(*z) ) z++, nDigits++; - } - - /* if exponent is present */ - if( *z=='e' || *z=='E' ){ - z++; - /* get sign of exponent */ - if( *z=='-' ){ - esign = -1; - z++; - }else if( *z=='+' ){ - z++; - } - /* copy digits to exponent */ - while( sqlite3Isdigit(*z) ){ - e = e*10 + (*z - '0'); - z++; - } - } - - /* adjust exponent by d, and update sign */ - e = (e*esign) + d; - if( e<0 ) { - esign = -1; - e *= -1; - } else { - esign = 1; - } - - /* if 0 significand */ - if( !s ) { - /* In the IEEE 754 standard, zero is signed. - ** Add the sign if we've seen at least one digit */ - result = (sign<0 && nDigits) ? -(double)0 : (double)0; - } else { - /* attempt to reduce exponent */ - if( esign>0 ){ - while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; - }else{ - while( !(s%10) && e>0 ) e--,s/=10; - } - - /* adjust the sign of significand */ - s = sign<0 ? -s : s; - - /* if exponent, scale significand as appropriate - ** and store in result. */ - if( e ){ - double scale = 1.0; - /* attempt to handle extremely small/large numbers better */ - if( e>307 && e<342 ){ - while( e%308 ) { scale *= 1.0e+1; e -= 1; } - if( esign<0 ){ - result = s / scale; - result /= 1.0e+308; - }else{ - result = s * scale; - result *= 1.0e+308; - } - }else{ - /* 1.0e+22 is the largest power of 10 than can be - ** represented exactly. */ - while( e%22 ) { scale *= 1.0e+1; e -= 1; } - while( e>0 ) { scale *= 1.0e+22; e -= 22; } - if( esign<0 ){ - result = s / scale; - }else{ - result = s * scale; - } - } - } else { - result = (double)s; - } - } - - /* store the result */ - *pResult = result; - - /* return number of characters used */ - return (int)(z - zBegin); -#else - return sqlite3Atoi64(z, pResult); -#endif /* SQLITE_OMIT_FLOATING_POINT */ -} - -/* -** Compare the 19-character string zNum against the text representation -** value 2^63: 9223372036854775808. Return negative, zero, or positive -** if zNum is less than, equal to, or greater than the string. -** -** Unlike memcmp() this routine is guaranteed to return the difference -** in the values of the last digit if the only difference is in the -** last digit. So, for example, -** -** compare2pow63("9223372036854775800") -** -** will return -8. -*/ -static int compare2pow63(const char *zNum){ - int c; - c = memcmp(zNum,"922337203685477580",18)*10; - if( c==0 ){ - c = zNum[18] - '8'; - } - return c; -} - - -/* -** Return TRUE if zNum is a 64-bit signed integer and write -** the value of the integer into *pNum. If zNum is not an integer -** or is an integer that is too large to be expressed with 64 bits, -** then return false. -** -** When this routine was originally written it dealt with only -** 32-bit numbers. At that time, it was much faster than the -** atoi() library routine in RedHat 7.2. -*/ -int sqlite3Atoi64(const char *zNum, i64 *pNum){ - i64 v = 0; - int neg; - int i, c; - const char *zStart; - while( sqlite3Isspace(*zNum) ) zNum++; - if( *zNum=='-' ){ - neg = 1; - zNum++; - }else if( *zNum=='+' ){ - neg = 0; - zNum++; - }else{ - neg = 0; - } - zStart = zNum; - while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */ - for(i=0; (c=zNum[i])>='0' && c<='9'; i++){ - v = v*10 + c - '0'; - } - *pNum = neg ? -v : v; - if( c!=0 || (i==0 && zStart==zNum) || i>19 ){ - /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranting that it is too large) */ - return 0; - }else if( i<19 ){ - /* Less than 19 digits, so we know that it fits in 64 bits */ - return 1; - }else{ - /* 19-digit numbers must be no larger than 9223372036854775807 if positive - ** or 9223372036854775808 if negative. Note that 9223372036854665808 - ** is 2^63. */ - return compare2pow63(zNum)<neg; - } -} - -/* -** The string zNum represents an unsigned integer. The zNum string -** consists of one or more digit characters and is terminated by -** a zero character. Any stray characters in zNum result in undefined -** behavior. -** -** If the unsigned integer that zNum represents will fit in a -** 64-bit signed integer, return TRUE. Otherwise return FALSE. -** -** If the negFlag parameter is true, that means that zNum really represents -** a negative number. (The leading "-" is omitted from zNum.) This -** parameter is needed to determine a boundary case. A string -** of "9223373036854775808" returns false if negFlag is false or true -** if negFlag is true. -** -** Leading zeros are ignored. -*/ -int sqlite3FitsIn64Bits(const char *zNum, int negFlag){ - int i; - int neg = 0; - - assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */ - - if( negFlag ) neg = 1-neg; - while( *zNum=='0' ){ - zNum++; /* Skip leading zeros. Ticket #2454 */ - } - for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); } - if( i<19 ){ - /* Guaranteed to fit if less than 19 digits */ - return 1; - }else if( i>19 ){ - /* Guaranteed to be too big if greater than 19 digits */ - return 0; - }else{ - /* Compare against 2^63. */ - return compare2pow63(zNum)<neg; - } -} - -/* -** If zNum represents an integer that will fit in 32-bits, then set -** *pValue to that integer and return true. Otherwise return false. -** -** Any non-numeric characters that following zNum are ignored. -** This is different from sqlite3Atoi64() which requires the -** input number to be zero-terminated. -*/ -int sqlite3GetInt32(const char *zNum, int *pValue){ - sqlite_int64 v = 0; - int i, c; - int neg = 0; - if( zNum[0]=='-' ){ - neg = 1; - zNum++; - }else if( zNum[0]=='+' ){ - zNum++; - } - while( zNum[0]=='0' ) zNum++; - for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ - v = v*10 + c; - } - - /* The longest decimal representation of a 32 bit integer is 10 digits: - ** - ** 1234567890 - ** 2^31 -> 2147483648 - */ - if( i>10 ){ - return 0; - } - if( v-neg>2147483647 ){ - return 0; - } - if( neg ){ - v = -v; - } - *pValue = (int)v; - return 1; -} - -/* -** The variable-length integer encoding is as follows: -** -** KEY: -** A = 0xxxxxxx 7 bits of data and one flag bit -** B = 1xxxxxxx 7 bits of data and one flag bit -** C = xxxxxxxx 8 bits of data -** -** 7 bits - A -** 14 bits - BA -** 21 bits - BBA -** 28 bits - BBBA -** 35 bits - BBBBA -** 42 bits - BBBBBA -** 49 bits - BBBBBBA -** 56 bits - BBBBBBBA -** 64 bits - BBBBBBBBC -*/ - -/* -** Write a 64-bit variable-length integer to memory starting at p[0]. -** The length of data write will be between 1 and 9 bytes. The number -** of bytes written is returned. -** -** A variable-length integer consists of the lower 7 bits of each byte -** for all bytes that have the 8th bit set and one byte with the 8th -** bit clear. Except, if we get to the 9th byte, it stores the full -** 8 bits and is the last byte. -*/ -int sqlite3PutVarint(unsigned char *p, u64 v){ - int i, j, n; - u8 buf[10]; - if( v & (((u64)0xff000000)<<32) ){ - p[8] = (u8)v; - v >>= 8; - for(i=7; i>=0; i--){ - p[i] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - } - return 9; - } - n = 0; - do{ - buf[n++] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - }while( v!=0 ); - buf[0] &= 0x7f; - assert( n<=9 ); - for(i=0, j=n-1; j>=0; j--, i++){ - p[i] = buf[j]; - } - return n; -} - -/* -** This routine is a faster version of sqlite3PutVarint() that only -** works for 32-bit positive integers and which is optimized for -** the common case of small integers. A MACRO version, putVarint32, -** is provided which inlines the single-byte case. All code should use -** the MACRO version as this function assumes the single-byte case has -** already been handled. -*/ -int sqlite3PutVarint32(unsigned char *p, u32 v){ -#ifndef putVarint32 - if( (v & ~0x7f)==0 ){ - p[0] = v; - return 1; - } -#endif - if( (v & ~0x3fff)==0 ){ - p[0] = (u8)((v>>7) | 0x80); - p[1] = (u8)(v & 0x7f); - return 2; - } - return sqlite3PutVarint(p, v); -} - -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -*/ -u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ - u32 a,b,s; - - a = *p; - /* a: p0 (unmasked) */ - if (!(a&0x80)) - { - *v = a; - return 1; - } - - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - a &= 0x7f; - a = a<<7; - a |= b; - *v = a; - return 2; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - a |= b; - *v = a; - return 3; - } - - /* CSE1 from below */ - a &= (0x7f<<14)|(0x7f); - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - b &= (0x7f<<14)|(0x7f); - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - *v = a; - return 4; - } - - /* a: p0<<14 | p2 (masked) */ - /* b: p1<<14 | p3 (unmasked) */ - /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - b &= (0x7f<<14)|(0x7f); - s = a; - /* s: p0<<14 | p2 (masked) */ - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* we can skip these cause they were (effectively) done above in calc'ing s */ - /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - /* b &= (0x7f<<14)|(0x7f); */ - b = b<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 5; - } - - /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - s = s<<7; - s |= b; - /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - - p++; - b = b<<14; - b |= *p; - /* b: p1<<28 | p3<<14 | p5 (unmasked) */ - if (!(b&0x80)) - { - /* we can skip this cause it was (effectively) done above in calc'ing s */ - /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - a &= (0x7f<<14)|(0x7f); - a = a<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 6; - } - - p++; - a = a<<14; - a |= *p; - /* a: p2<<28 | p4<<14 | p6 (unmasked) */ - if (!(a&0x80)) - { - a &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b &= (0x7f<<14)|(0x7f); - b = b<<7; - a |= b; - s = s>>11; - *v = ((u64)s)<<32 | a; - return 7; - } - - /* CSE2 from below */ - a &= (0x7f<<14)|(0x7f); - p++; - b = b<<14; - b |= *p; - /* b: p3<<28 | p5<<14 | p7 (unmasked) */ - if (!(b&0x80)) - { - b &= (0x1f<<28)|(0x7f<<14)|(0x7f); - /* moved CSE2 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - s = s>>4; - *v = ((u64)s)<<32 | a; - return 8; - } - - p++; - a = a<<15; - a |= *p; - /* a: p4<<29 | p6<<15 | p8 (unmasked) */ - - /* moved CSE2 up */ - /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ - b &= (0x7f<<14)|(0x7f); - b = b<<8; - a |= b; - - s = s<<4; - b = p[-4]; - b &= 0x7f; - b = b>>3; - s |= b; - - *v = ((u64)s)<<32 | a; - - return 9; -} - -/* -** Read a 32-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -** -** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned -** integer, then set *v to 0xffffffff. -** -** A MACRO version, getVarint32, is provided which inlines the -** single-byte case. All code should use the MACRO version as -** this function assumes the single-byte case has already been handled. -*/ -u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; - - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif - - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; - return 2; - } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; - return 3; - } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - p -= 2; - n = sqlite3GetVarint(p, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Walues between 268435456 and 34359738367 */ - a &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b &= (0x1f<<28)|(0x7f<<14)|(0x7f); - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); - *v = (u32)v64; - return n; - } -#endif -} - -/* -** Return the number of bytes that will be needed to store the given -** 64-bit integer. -*/ -int sqlite3VarintLen(u64 v){ - int i = 0; - do{ - i++; - v >>= 7; - }while( v!=0 && ALWAYS(i<9) ); - return i; -} - - -/* -** Read or write a four-byte big-endian integer value. -*/ -u32 sqlite3Get4byte(const u8 *p){ - return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; -} -void sqlite3Put4byte(unsigned char *p, u32 v){ - p[0] = (u8)(v>>24); - p[1] = (u8)(v>>16); - p[2] = (u8)(v>>8); - p[3] = (u8)v; -} - - - -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) -/* -** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F -*/ -static u8 hexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); -#ifdef SQLITE_ASCII - h += 9*(1&(h>>6)); -#endif -#ifdef SQLITE_EBCDIC - h += 9*(1&~(h>>4)); -#endif - return (u8)(h & 0xf); -} -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ - -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) -/* -** Convert a BLOB literal of the form "x'hhhhhh'" into its binary -** value. Return a pointer to its binary value. Space to hold the -** binary value has been obtained from malloc and must be freed by -** the calling routine. -*/ -void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ - char *zBlob; - int i; - - zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); - n--; - if( zBlob ){ - for(i=0; i<n; i+=2){ - zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]); - } - zBlob[i/2] = 0; - } - return zBlob; -} -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ - - -/* -** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY. -** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN -** when this routine is called. -** -** This routine is called when entering an SQLite API. The SQLITE_MAGIC_OPEN -** value indicates that the database connection passed into the API is -** open and is not being used by another thread. By changing the value -** to SQLITE_MAGIC_BUSY we indicate that the connection is in use. -** sqlite3SafetyOff() below will change the value back to SQLITE_MAGIC_OPEN -** when the API exits. -** -** This routine is a attempt to detect if two threads use the -** same sqlite* pointer at the same time. There is a race -** condition so it is possible that the error is not detected. -** But usually the problem will be seen. The result will be an -** error which can be used to debug the application that is -** using SQLite incorrectly. -** -** Ticket #202: If db->magic is not a valid open value, take care not -** to modify the db structure at all. It could be that db is a stale -** pointer. In other words, it could be that there has been a prior -** call to sqlite3_close(db) and db has been deallocated. And we do -** not want to write into deallocated memory. -*/ -#ifdef SQLITE_DEBUG -int sqlite3SafetyOn(sqlite3 *db){ - if( db->magic==SQLITE_MAGIC_OPEN ){ - db->magic = SQLITE_MAGIC_BUSY; - assert( sqlite3_mutex_held(db->mutex) ); - return 0; - }else if( db->magic==SQLITE_MAGIC_BUSY ){ - db->magic = SQLITE_MAGIC_ERROR; - db->u1.isInterrupted = 1; - } - return 1; -} -#endif - -/* -** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN. -** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY -** when this routine is called. -*/ -#ifdef SQLITE_DEBUG -int sqlite3SafetyOff(sqlite3 *db){ - if( db->magic==SQLITE_MAGIC_BUSY ){ - db->magic = SQLITE_MAGIC_OPEN; - assert( sqlite3_mutex_held(db->mutex) ); - return 0; - }else{ - db->magic = SQLITE_MAGIC_ERROR; - db->u1.isInterrupted = 1; - return 1; - } -} -#endif - -/* -** Check to make sure we have a valid db pointer. This test is not -** foolproof but it does provide some measure of protection against -** misuse of the interface such as passing in db pointers that are -** NULL or which have been previously closed. If this routine returns -** 1 it means that the db pointer is valid and 0 if it should not be -** dereferenced for any reason. The calling function should invoke -** SQLITE_MISUSE immediately. -** -** sqlite3SafetyCheckOk() requires that the db pointer be valid for -** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to -** open properly and is not fit for general use but which can be -** used as an argument to sqlite3_errmsg() or sqlite3_close(). -*/ -int sqlite3SafetyCheckOk(sqlite3 *db){ - u32 magic; - if( db==0 ) return 0; - magic = db->magic; - if( magic!=SQLITE_MAGIC_OPEN -#ifdef SQLITE_DEBUG - && magic!=SQLITE_MAGIC_BUSY -#endif - ){ - return 0; - }else{ - return 1; - } -} -int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ - u32 magic; - magic = db->magic; - if( magic!=SQLITE_MAGIC_SICK && - magic!=SQLITE_MAGIC_OPEN && - magic!=SQLITE_MAGIC_BUSY ) return 0; - return 1; -} +/*
+** 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.
+**
+*************************************************************************
+** Utility functions used throughout sqlite.
+**
+** This file contains functions for allocating memory, comparing
+** strings, and stuff like that.
+**
+*/
+#include "sqliteInt.h"
+#include <stdarg.h>
+#ifdef SQLITE_HAVE_ISNAN
+# include <math.h>
+#endif
+
+/*
+** Routine needed to support the testcase() macro.
+*/
+#ifdef SQLITE_COVERAGE_TEST
+void sqlite3Coverage(int x){
+ static int dummy = 0;
+ dummy += x;
+}
+#endif
+
+/*
+** Return true if the floating point value is Not a Number (NaN).
+**
+** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
+** Otherwise, we have our own implementation that works on most systems.
+*/
+int sqlite3IsNaN(double x){
+ int rc; /* The value return */
+#if !defined(SQLITE_HAVE_ISNAN)
+ /*
+ ** Systems that support the isnan() library function should probably
+ ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
+ ** found that many systems do not have a working isnan() function so
+ ** this implementation is provided as an alternative.
+ **
+ ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
+ ** On the other hand, the use of -ffast-math comes with the following
+ ** warning:
+ **
+ ** This option [-ffast-math] should never be turned on by any
+ ** -O option since it can result in incorrect output for programs
+ ** which depend on an exact implementation of IEEE or ISO
+ ** rules/specifications for math functions.
+ **
+ ** Under MSVC, this NaN test may fail if compiled with a floating-
+ ** point precision mode other than /fp:precise. From the MSDN
+ ** documentation:
+ **
+ ** The compiler [with /fp:precise] will properly handle comparisons
+ ** involving NaN. For example, x != x evaluates to true if x is NaN
+ ** ...
+ */
+#ifdef __FAST_MATH__
+# error SQLite will not work correctly with the -ffast-math option of GCC.
+#endif
+ volatile double y = x;
+ volatile double z = y;
+ rc = (y!=z);
+#else /* if defined(SQLITE_HAVE_ISNAN) */
+ rc = isnan(x);
+#endif /* SQLITE_HAVE_ISNAN */
+ testcase( rc );
+ return rc;
+}
+
+/*
+** Compute a string length that is limited to what can be stored in
+** lower 30 bits of a 32-bit signed integer.
+**
+** The value returned will never be negative. Nor will it ever be greater
+** than the actual length of the string. For very long strings (greater
+** than 1GiB) the value returned might be less than the true string length.
+*/
+int sqlite3Strlen30(const char *z){
+ const char *z2 = z;
+ if( z==0 ) return 0;
+ while( *z2 ){ z2++; }
+ return 0x3fffffff & (int)(z2 - z);
+}
+
+/*
+** Set the most recent error code and error string for the sqlite
+** handle "db". The error code is set to "err_code".
+**
+** If it is not NULL, string zFormat specifies the format of the
+** error string in the style of the printf functions: The following
+** format characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+**
+** zFormat and any string tokens that follow it are assumed to be
+** encoded in UTF-8.
+**
+** To clear the most recent error for sqlite handle "db", sqlite3Error
+** should be called with err_code set to SQLITE_OK and zFormat set
+** to NULL.
+*/
+void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
+ if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
+ db->errCode = err_code;
+ if( zFormat ){
+ char *z;
+ va_list ap;
+ va_start(ap, zFormat);
+ z = sqlite3VMPrintf(db, zFormat, ap);
+ va_end(ap);
+ sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
+ }else{
+ sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
+ }
+ }
+}
+
+/*
+** Add an error message to pParse->zErrMsg and increment pParse->nErr.
+** The following formatting characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+**
+** This function should be used to report any error that occurs whilst
+** compiling an SQL statement (i.e. within sqlite3_prepare()). The
+** last thing the sqlite3_prepare() function does is copy the error
+** stored by this function into the database handle using sqlite3Error().
+** Function sqlite3Error() should be used during statement execution
+** (sqlite3_step() etc.).
+*/
+void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
+ va_list ap;
+ sqlite3 *db = pParse->db;
+ pParse->nErr++;
+ sqlite3DbFree(db, pParse->zErrMsg);
+ va_start(ap, zFormat);
+ pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
+ va_end(ap);
+ pParse->rc = SQLITE_ERROR;
+}
+
+/*
+** Clear the error message in pParse, if any
+*/
+void sqlite3ErrorClear(Parse *pParse){
+ sqlite3DbFree(pParse->db, pParse->zErrMsg);
+ pParse->zErrMsg = 0;
+ pParse->nErr = 0;
+}
+
+/*
+** Convert an SQL-style quoted string into a normal string by removing
+** the quote characters. The conversion is done in-place. If the
+** input does not begin with a quote character, then this routine
+** is a no-op.
+**
+** The input string must be zero-terminated. A new zero-terminator
+** is added to the dequoted string.
+**
+** The return value is -1 if no dequoting occurs or the length of the
+** dequoted string, exclusive of the zero terminator, if dequoting does
+** occur.
+**
+** 2002-Feb-14: This routine is extended to remove MS-Access style
+** brackets from around identifers. For example: "[a-b-c]" becomes
+** "a-b-c".
+*/
+int sqlite3Dequote(char *z){
+ char quote;
+ int i, j;
+ if( z==0 ) return -1;
+ quote = z[0];
+ switch( quote ){
+ case '\'': break;
+ case '"': break;
+ case '`': break; /* For MySQL compatibility */
+ case '[': quote = ']'; break; /* For MS SqlServer compatibility */
+ default: return -1;
+ }
+ for(i=1, j=0; ALWAYS(z[i]); i++){
+ if( z[i]==quote ){
+ if( z[i+1]==quote ){
+ z[j++] = quote;
+ i++;
+ }else{
+ break;
+ }
+ }else{
+ z[j++] = z[i];
+ }
+ }
+ z[j] = 0;
+ return j;
+}
+
+/* Convenient short-hand */
+#define UpperToLower sqlite3UpperToLower
+
+/*
+** Some systems have stricmp(). Others have strcasecmp(). Because
+** there is no consistency, we will define our own.
+*/
+int sqlite3StrICmp(const char *zLeft, const char *zRight){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return UpperToLower[*a] - UpperToLower[*b];
+}
+int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
+}
+
+/*
+** Return TRUE if z is a pure numeric string. Return FALSE and leave
+** *realnum unchanged if the string contains any character which is not
+** part of a number.
+**
+** If the string is pure numeric, set *realnum to TRUE if the string
+** contains the '.' character or an "E+000" style exponentiation suffix.
+** Otherwise set *realnum to FALSE. Note that just becaue *realnum is
+** false does not mean that the number can be successfully converted into
+** an integer - it might be too big.
+**
+** An empty string is considered non-numeric.
+*/
+int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
+ int incr = (enc==SQLITE_UTF8?1:2);
+ if( enc==SQLITE_UTF16BE ) z++;
+ if( *z=='-' || *z=='+' ) z += incr;
+ if( !sqlite3Isdigit(*z) ){
+ return 0;
+ }
+ z += incr;
+ *realnum = 0;
+ while( sqlite3Isdigit(*z) ){ z += incr; }
+ if( *z=='.' ){
+ z += incr;
+ if( !sqlite3Isdigit(*z) ) return 0;
+ while( sqlite3Isdigit(*z) ){ z += incr; }
+ *realnum = 1;
+ }
+ if( *z=='e' || *z=='E' ){
+ z += incr;
+ if( *z=='+' || *z=='-' ) z += incr;
+ if( !sqlite3Isdigit(*z) ) return 0;
+ while( sqlite3Isdigit(*z) ){ z += incr; }
+ *realnum = 1;
+ }
+ return *z==0;
+}
+
+/*
+** The string z[] is an ASCII representation of a real number.
+** Convert this string to a double.
+**
+** This routine assumes that z[] really is a valid number. If it
+** is not, the result is undefined.
+**
+** This routine is used instead of the library atof() function because
+** the library atof() might want to use "," as the decimal point instead
+** of "." depending on how locale is set. But that would cause problems
+** for SQL. So this routine always uses "." regardless of locale.
+*/
+int sqlite3AtoF(const char *z, double *pResult){
+#ifndef SQLITE_OMIT_FLOATING_POINT
+ const char *zBegin = z;
+ /* sign * significand * (10 ^ (esign * exponent)) */
+ int sign = 1; /* sign of significand */
+ i64 s = 0; /* significand */
+ int d = 0; /* adjust exponent for shifting decimal point */
+ int esign = 1; /* sign of exponent */
+ int e = 0; /* exponent */
+ double result;
+ int nDigits = 0;
+
+ /* skip leading spaces */
+ while( sqlite3Isspace(*z) ) z++;
+ /* get sign of significand */
+ if( *z=='-' ){
+ sign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ /* skip leading zeroes */
+ while( z[0]=='0' ) z++, nDigits++;
+
+ /* copy max significant digits to significand */
+ while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+ s = s*10 + (*z - '0');
+ z++, nDigits++;
+ }
+ /* skip non-significant significand digits
+ ** (increase exponent by d to shift decimal left) */
+ while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;
+
+ /* if decimal point is present */
+ if( *z=='.' ){
+ z++;
+ /* copy digits from after decimal to significand
+ ** (decrease exponent by d to shift decimal right) */
+ while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+ s = s*10 + (*z - '0');
+ z++, nDigits++, d--;
+ }
+ /* skip non-significant digits */
+ while( sqlite3Isdigit(*z) ) z++, nDigits++;
+ }
+
+ /* if exponent is present */
+ if( *z=='e' || *z=='E' ){
+ z++;
+ /* get sign of exponent */
+ if( *z=='-' ){
+ esign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ /* copy digits to exponent */
+ while( sqlite3Isdigit(*z) ){
+ e = e*10 + (*z - '0');
+ z++;
+ }
+ }
+
+ /* adjust exponent by d, and update sign */
+ e = (e*esign) + d;
+ if( e<0 ) {
+ esign = -1;
+ e *= -1;
+ } else {
+ esign = 1;
+ }
+
+ /* if 0 significand */
+ if( !s ) {
+ /* In the IEEE 754 standard, zero is signed.
+ ** Add the sign if we've seen at least one digit */
+ result = (sign<0 && nDigits) ? -(double)0 : (double)0;
+ } else {
+ /* attempt to reduce exponent */
+ if( esign>0 ){
+ while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
+ }else{
+ while( !(s%10) && e>0 ) e--,s/=10;
+ }
+
+ /* adjust the sign of significand */
+ s = sign<0 ? -s : s;
+
+ /* if exponent, scale significand as appropriate
+ ** and store in result. */
+ if( e ){
+ double scale = 1.0;
+ /* attempt to handle extremely small/large numbers better */
+ if( e>307 && e<342 ){
+ while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+ if( esign<0 ){
+ result = s / scale;
+ result /= 1.0e+308;
+ }else{
+ result = s * scale;
+ result *= 1.0e+308;
+ }
+ }else{
+ /* 1.0e+22 is the largest power of 10 than can be
+ ** represented exactly. */
+ while( e%22 ) { scale *= 1.0e+1; e -= 1; }
+ while( e>0 ) { scale *= 1.0e+22; e -= 22; }
+ if( esign<0 ){
+ result = s / scale;
+ }else{
+ result = s * scale;
+ }
+ }
+ } else {
+ result = (double)s;
+ }
+ }
+
+ /* store the result */
+ *pResult = result;
+
+ /* return number of characters used */
+ return (int)(z - zBegin);
+#else
+ return sqlite3Atoi64(z, pResult);
+#endif /* SQLITE_OMIT_FLOATING_POINT */
+}
+
+/*
+** Compare the 19-character string zNum against the text representation
+** value 2^63: 9223372036854775808. Return negative, zero, or positive
+** if zNum is less than, equal to, or greater than the string.
+**
+** Unlike memcmp() this routine is guaranteed to return the difference
+** in the values of the last digit if the only difference is in the
+** last digit. So, for example,
+**
+** compare2pow63("9223372036854775800")
+**
+** will return -8.
+*/
+static int compare2pow63(const char *zNum){
+ int c;
+ c = memcmp(zNum,"922337203685477580",18)*10;
+ if( c==0 ){
+ c = zNum[18] - '8';
+ }
+ return c;
+}
+
+
+/*
+** Return TRUE if zNum is a 64-bit signed integer and write
+** the value of the integer into *pNum. If zNum is not an integer
+** or is an integer that is too large to be expressed with 64 bits,
+** then return false.
+**
+** When this routine was originally written it dealt with only
+** 32-bit numbers. At that time, it was much faster than the
+** atoi() library routine in RedHat 7.2.
+*/
+int sqlite3Atoi64(const char *zNum, i64 *pNum){
+ i64 v = 0;
+ int neg;
+ int i, c;
+ const char *zStart;
+ while( sqlite3Isspace(*zNum) ) zNum++;
+ if( *zNum=='-' ){
+ neg = 1;
+ zNum++;
+ }else if( *zNum=='+' ){
+ neg = 0;
+ zNum++;
+ }else{
+ neg = 0;
+ }
+ zStart = zNum;
+ while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
+ v = v*10 + c - '0';
+ }
+ *pNum = neg ? -v : v;
+ if( c!=0 || (i==0 && zStart==zNum) || i>19 ){
+ /* zNum is empty or contains non-numeric text or is longer
+ ** than 19 digits (thus guaranting that it is too large) */
+ return 0;
+ }else if( i<19 ){
+ /* Less than 19 digits, so we know that it fits in 64 bits */
+ return 1;
+ }else{
+ /* 19-digit numbers must be no larger than 9223372036854775807 if positive
+ ** or 9223372036854775808 if negative. Note that 9223372036854665808
+ ** is 2^63. */
+ return compare2pow63(zNum)<neg;
+ }
+}
+
+/*
+** The string zNum represents an unsigned integer. The zNum string
+** consists of one or more digit characters and is terminated by
+** a zero character. Any stray characters in zNum result in undefined
+** behavior.
+**
+** If the unsigned integer that zNum represents will fit in a
+** 64-bit signed integer, return TRUE. Otherwise return FALSE.
+**
+** If the negFlag parameter is true, that means that zNum really represents
+** a negative number. (The leading "-" is omitted from zNum.) This
+** parameter is needed to determine a boundary case. A string
+** of "9223373036854775808" returns false if negFlag is false or true
+** if negFlag is true.
+**
+** Leading zeros are ignored.
+*/
+int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
+ int i;
+ int neg = 0;
+
+ assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */
+
+ if( negFlag ) neg = 1-neg;
+ while( *zNum=='0' ){
+ zNum++; /* Skip leading zeros. Ticket #2454 */
+ }
+ for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
+ if( i<19 ){
+ /* Guaranteed to fit if less than 19 digits */
+ return 1;
+ }else if( i>19 ){
+ /* Guaranteed to be too big if greater than 19 digits */
+ return 0;
+ }else{
+ /* Compare against 2^63. */
+ return compare2pow63(zNum)<neg;
+ }
+}
+
+/*
+** If zNum represents an integer that will fit in 32-bits, then set
+** *pValue to that integer and return true. Otherwise return false.
+**
+** Any non-numeric characters that following zNum are ignored.
+** This is different from sqlite3Atoi64() which requires the
+** input number to be zero-terminated.
+*/
+int sqlite3GetInt32(const char *zNum, int *pValue){
+ sqlite_int64 v = 0;
+ int i, c;
+ int neg = 0;
+ if( zNum[0]=='-' ){
+ neg = 1;
+ zNum++;
+ }else if( zNum[0]=='+' ){
+ zNum++;
+ }
+ while( zNum[0]=='0' ) zNum++;
+ for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
+ v = v*10 + c;
+ }
+
+ /* The longest decimal representation of a 32 bit integer is 10 digits:
+ **
+ ** 1234567890
+ ** 2^31 -> 2147483648
+ */
+ if( i>10 ){
+ return 0;
+ }
+ if( v-neg>2147483647 ){
+ return 0;
+ }
+ if( neg ){
+ v = -v;
+ }
+ *pValue = (int)v;
+ return 1;
+}
+
+/*
+** The variable-length integer encoding is as follows:
+**
+** KEY:
+** A = 0xxxxxxx 7 bits of data and one flag bit
+** B = 1xxxxxxx 7 bits of data and one flag bit
+** C = xxxxxxxx 8 bits of data
+**
+** 7 bits - A
+** 14 bits - BA
+** 21 bits - BBA
+** 28 bits - BBBA
+** 35 bits - BBBBA
+** 42 bits - BBBBBA
+** 49 bits - BBBBBBA
+** 56 bits - BBBBBBBA
+** 64 bits - BBBBBBBBC
+*/
+
+/*
+** Write a 64-bit variable-length integer to memory starting at p[0].
+** The length of data write will be between 1 and 9 bytes. The number
+** of bytes written is returned.
+**
+** A variable-length integer consists of the lower 7 bits of each byte
+** for all bytes that have the 8th bit set and one byte with the 8th
+** bit clear. Except, if we get to the 9th byte, it stores the full
+** 8 bits and is the last byte.
+*/
+int sqlite3PutVarint(unsigned char *p, u64 v){
+ int i, j, n;
+ u8 buf[10];
+ if( v & (((u64)0xff000000)<<32) ){
+ p[8] = (u8)v;
+ v >>= 8;
+ for(i=7; i>=0; i--){
+ p[i] = (u8)((v & 0x7f) | 0x80);
+ v >>= 7;
+ }
+ return 9;
+ }
+ n = 0;
+ do{
+ buf[n++] = (u8)((v & 0x7f) | 0x80);
+ v >>= 7;
+ }while( v!=0 );
+ buf[0] &= 0x7f;
+ assert( n<=9 );
+ for(i=0, j=n-1; j>=0; j--, i++){
+ p[i] = buf[j];
+ }
+ return n;
+}
+
+/*
+** This routine is a faster version of sqlite3PutVarint() that only
+** works for 32-bit positive integers and which is optimized for
+** the common case of small integers. A MACRO version, putVarint32,
+** is provided which inlines the single-byte case. All code should use
+** the MACRO version as this function assumes the single-byte case has
+** already been handled.
+*/
+int sqlite3PutVarint32(unsigned char *p, u32 v){
+#ifndef putVarint32
+ if( (v & ~0x7f)==0 ){
+ p[0] = v;
+ return 1;
+ }
+#endif
+ if( (v & ~0x3fff)==0 ){
+ p[0] = (u8)((v>>7) | 0x80);
+ p[1] = (u8)(v & 0x7f);
+ return 2;
+ }
+ return sqlite3PutVarint(p, v);
+}
+
+/*
+** Read a 64-bit variable-length integer from memory starting at p[0].
+** Return the number of bytes read. The value is stored in *v.
+*/
+u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
+ u32 a,b,s;
+
+ a = *p;
+ /* a: p0 (unmasked) */
+ if (!(a&0x80))
+ {
+ *v = a;
+ return 1;
+ }
+
+ p++;
+ b = *p;
+ /* b: p1 (unmasked) */
+ if (!(b&0x80))
+ {
+ a &= 0x7f;
+ a = a<<7;
+ a |= b;
+ *v = a;
+ return 2;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<14 | p2 (unmasked) */
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<14)|(0x7f);
+ b &= 0x7f;
+ b = b<<7;
+ a |= b;
+ *v = a;
+ return 3;
+ }
+
+ /* CSE1 from below */
+ a &= (0x7f<<14)|(0x7f);
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p1<<14 | p3 (unmasked) */
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<14)|(0x7f);
+ /* moved CSE1 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ a = a<<7;
+ a |= b;
+ *v = a;
+ return 4;
+ }
+
+ /* a: p0<<14 | p2 (masked) */
+ /* b: p1<<14 | p3 (unmasked) */
+ /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+ /* moved CSE1 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ b &= (0x7f<<14)|(0x7f);
+ s = a;
+ /* s: p0<<14 | p2 (masked) */
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<28 | p2<<14 | p4 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* we can skip these cause they were (effectively) done above in calc'ing s */
+ /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+ /* b &= (0x7f<<14)|(0x7f); */
+ b = b<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 5;
+ }
+
+ /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+ s = s<<7;
+ s |= b;
+ /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p1<<28 | p3<<14 | p5 (unmasked) */
+ if (!(b&0x80))
+ {
+ /* we can skip this cause it was (effectively) done above in calc'ing s */
+ /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+ a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 6;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p2<<28 | p4<<14 | p6 (unmasked) */
+ if (!(a&0x80))
+ {
+ a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x7f<<14)|(0x7f);
+ b = b<<7;
+ a |= b;
+ s = s>>11;
+ *v = ((u64)s)<<32 | a;
+ return 7;
+ }
+
+ /* CSE2 from below */
+ a &= (0x7f<<14)|(0x7f);
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p3<<28 | p5<<14 | p7 (unmasked) */
+ if (!(b&0x80))
+ {
+ b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
+ /* moved CSE2 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ a = a<<7;
+ a |= b;
+ s = s>>4;
+ *v = ((u64)s)<<32 | a;
+ return 8;
+ }
+
+ p++;
+ a = a<<15;
+ a |= *p;
+ /* a: p4<<29 | p6<<15 | p8 (unmasked) */
+
+ /* moved CSE2 up */
+ /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
+ b &= (0x7f<<14)|(0x7f);
+ b = b<<8;
+ a |= b;
+
+ s = s<<4;
+ b = p[-4];
+ b &= 0x7f;
+ b = b>>3;
+ s |= b;
+
+ *v = ((u64)s)<<32 | a;
+
+ return 9;
+}
+
+/*
+** Read a 32-bit variable-length integer from memory starting at p[0].
+** Return the number of bytes read. The value is stored in *v.
+**
+** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
+** integer, then set *v to 0xffffffff.
+**
+** A MACRO version, getVarint32, is provided which inlines the
+** single-byte case. All code should use the MACRO version as
+** this function assumes the single-byte case has already been handled.
+*/
+u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
+ u32 a,b;
+
+ /* The 1-byte case. Overwhelmingly the most common. Handled inline
+ ** by the getVarin32() macro */
+ a = *p;
+ /* a: p0 (unmasked) */
+#ifndef getVarint32
+ if (!(a&0x80))
+ {
+ /* Values between 0 and 127 */
+ *v = a;
+ return 1;
+ }
+#endif
+
+ /* The 2-byte case */
+ p++;
+ b = *p;
+ /* b: p1 (unmasked) */
+ if (!(b&0x80))
+ {
+ /* Values between 128 and 16383 */
+ a &= 0x7f;
+ a = a<<7;
+ *v = a | b;
+ return 2;
+ }
+
+ /* The 3-byte case */
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<14 | p2 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* Values between 16384 and 2097151 */
+ a &= (0x7f<<14)|(0x7f);
+ b &= 0x7f;
+ b = b<<7;
+ *v = a | b;
+ return 3;
+ }
+
+ /* A 32-bit varint is used to store size information in btrees.
+ ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
+ ** A 3-byte varint is sufficient, for example, to record the size
+ ** of a 1048569-byte BLOB or string.
+ **
+ ** We only unroll the first 1-, 2-, and 3- byte cases. The very
+ ** rare larger cases can be handled by the slower 64-bit varint
+ ** routine.
+ */
+#if 1
+ {
+ u64 v64;
+ u8 n;
+
+ p -= 2;
+ n = sqlite3GetVarint(p, &v64);
+ assert( n>3 && n<=9 );
+ if( (v64 & SQLITE_MAX_U32)!=v64 ){
+ *v = 0xffffffff;
+ }else{
+ *v = (u32)v64;
+ }
+ return n;
+ }
+
+#else
+ /* For following code (kept for historical record only) shows an
+ ** unrolling for the 3- and 4-byte varint cases. This code is
+ ** slightly faster, but it is also larger and much harder to test.
+ */
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p1<<14 | p3 (unmasked) */
+ if (!(b&0x80))
+ {
+ /* Values between 2097152 and 268435455 */
+ b &= (0x7f<<14)|(0x7f);
+ a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ *v = a | b;
+ return 4;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<28 | p2<<14 | p4 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* Walues between 268435456 and 34359738367 */
+ a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
+ b = b<<7;
+ *v = a | b;
+ return 5;
+ }
+
+ /* We can only reach this point when reading a corrupt database
+ ** file. In that case we are not in any hurry. Use the (relatively
+ ** slow) general-purpose sqlite3GetVarint() routine to extract the
+ ** value. */
+ {
+ u64 v64;
+ u8 n;
+
+ p -= 4;
+ n = sqlite3GetVarint(p, &v64);
+ assert( n>5 && n<=9 );
+ *v = (u32)v64;
+ return n;
+ }
+#endif
+}
+
+/*
+** Return the number of bytes that will be needed to store the given
+** 64-bit integer.
+*/
+int sqlite3VarintLen(u64 v){
+ int i = 0;
+ do{
+ i++;
+ v >>= 7;
+ }while( v!=0 && ALWAYS(i<9) );
+ return i;
+}
+
+
+/*
+** Read or write a four-byte big-endian integer value.
+*/
+u32 sqlite3Get4byte(const u8 *p){
+ return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+}
+void sqlite3Put4byte(unsigned char *p, u32 v){
+ p[0] = (u8)(v>>24);
+ p[1] = (u8)(v>>16);
+ p[2] = (u8)(v>>8);
+ p[3] = (u8)v;
+}
+
+
+
+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
+/*
+** Translate a single byte of Hex into an integer.
+** This routine only works if h really is a valid hexadecimal
+** character: 0..9a..fA..F
+*/
+static u8 hexToInt(int h){
+ assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
+#ifdef SQLITE_ASCII
+ h += 9*(1&(h>>6));
+#endif
+#ifdef SQLITE_EBCDIC
+ h += 9*(1&~(h>>4));
+#endif
+ return (u8)(h & 0xf);
+}
+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
+
+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
+/*
+** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
+** value. Return a pointer to its binary value. Space to hold the
+** binary value has been obtained from malloc and must be freed by
+** the calling routine.
+*/
+void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
+ char *zBlob;
+ int i;
+
+ zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
+ n--;
+ if( zBlob ){
+ for(i=0; i<n; i+=2){
+ zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
+ }
+ zBlob[i/2] = 0;
+ }
+ return zBlob;
+}
+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
+
+
+/*
+** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
+** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
+** when this routine is called.
+**
+** This routine is called when entering an SQLite API. The SQLITE_MAGIC_OPEN
+** value indicates that the database connection passed into the API is
+** open and is not being used by another thread. By changing the value
+** to SQLITE_MAGIC_BUSY we indicate that the connection is in use.
+** sqlite3SafetyOff() below will change the value back to SQLITE_MAGIC_OPEN
+** when the API exits.
+**
+** This routine is a attempt to detect if two threads use the
+** same sqlite* pointer at the same time. There is a race
+** condition so it is possible that the error is not detected.
+** But usually the problem will be seen. The result will be an
+** error which can be used to debug the application that is
+** using SQLite incorrectly.
+**
+** Ticket #202: If db->magic is not a valid open value, take care not
+** to modify the db structure at all. It could be that db is a stale
+** pointer. In other words, it could be that there has been a prior
+** call to sqlite3_close(db) and db has been deallocated. And we do
+** not want to write into deallocated memory.
+*/
+#ifdef SQLITE_DEBUG
+int sqlite3SafetyOn(sqlite3 *db){
+ if( db->magic==SQLITE_MAGIC_OPEN ){
+ db->magic = SQLITE_MAGIC_BUSY;
+ assert( sqlite3_mutex_held(db->mutex) );
+ return 0;
+ }else if( db->magic==SQLITE_MAGIC_BUSY ){
+ db->magic = SQLITE_MAGIC_ERROR;
+ db->u1.isInterrupted = 1;
+ }
+ return 1;
+}
+#endif
+
+/*
+** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
+** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
+** when this routine is called.
+*/
+#ifdef SQLITE_DEBUG
+int sqlite3SafetyOff(sqlite3 *db){
+ if( db->magic==SQLITE_MAGIC_BUSY ){
+ db->magic = SQLITE_MAGIC_OPEN;
+ assert( sqlite3_mutex_held(db->mutex) );
+ return 0;
+ }else{
+ db->magic = SQLITE_MAGIC_ERROR;
+ db->u1.isInterrupted = 1;
+ return 1;
+ }
+}
+#endif
+
+/*
+** Check to make sure we have a valid db pointer. This test is not
+** foolproof but it does provide some measure of protection against
+** misuse of the interface such as passing in db pointers that are
+** NULL or which have been previously closed. If this routine returns
+** 1 it means that the db pointer is valid and 0 if it should not be
+** dereferenced for any reason. The calling function should invoke
+** SQLITE_MISUSE immediately.
+**
+** sqlite3SafetyCheckOk() requires that the db pointer be valid for
+** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to
+** open properly and is not fit for general use but which can be
+** used as an argument to sqlite3_errmsg() or sqlite3_close().
+*/
+int sqlite3SafetyCheckOk(sqlite3 *db){
+ u32 magic;
+ if( db==0 ) return 0;
+ magic = db->magic;
+ if( magic!=SQLITE_MAGIC_OPEN
+#ifdef SQLITE_DEBUG
+ && magic!=SQLITE_MAGIC_BUSY
+#endif
+ ){
+ return 0;
+ }else{
+ return 1;
+ }
+}
+int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
+ u32 magic;
+ magic = db->magic;
+ if( magic!=SQLITE_MAGIC_SICK &&
+ magic!=SQLITE_MAGIC_OPEN &&
+ magic!=SQLITE_MAGIC_BUSY ) return 0;
+ return 1;
+}
diff --git a/third_party/sqlite/src/test/fts.test b/third_party/sqlite/src/test/fts.test deleted file mode 100644 index 031f547..0000000 --- a/third_party/sqlite/src/test/fts.test +++ /dev/null @@ -1,61 +0,0 @@ -# -# 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 runs the fts tests. -# -# $Id$ - -proc lshift {lvar} { - upvar $lvar l - set ret [lindex $l 0] - set l [lrange $l 1 end] - return $ret -} -while {[set arg [lshift argv]] != ""} { - switch -- $arg { - -sharedpagercache { - sqlite3_enable_shared_cache 1 - } - default { - set argv [linsert $argv 0 $arg] - break - } - } -} - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -rename finish_test really_finish_test -proc finish_test {} {} -set ISQUICK 1 - -set EXCLUDE { - fts.test - fts1.test - fts2.test -} - -if {[sqlite3 -has-codec]} { - # lappend EXCLUDE \ - # conflict.test -} - -foreach testfile [lsort -dictionary [glob $testdir/fts*.test]] { - set tail [file tail $testfile] - puts "test: $tail" - if {[lsearch -exact $EXCLUDE $tail]>=0} continue - source $testfile - catch {db close} - if {$sqlite_open_file_count>0} { - puts "$tail did not close all files: $sqlite_open_file_count" - incr nErr - lappend ::failList $tail - } -} -source $testdir/misuse.test - -set sqlite_open_file_count 0 -really_finish_test diff --git a/third_party/sqlite/src/test/fts1.test b/third_party/sqlite/src/test/fts1.test deleted file mode 100644 index 1ddb19f..0000000 --- a/third_party/sqlite/src/test/fts1.test +++ /dev/null @@ -1,61 +0,0 @@ -# -# 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 runs the fts tests. -# -# $Id$ - -proc lshift {lvar} { - upvar $lvar l - set ret [lindex $l 0] - set l [lrange $l 1 end] - return $ret -} -while {[set arg [lshift argv]] != ""} { - switch -- $arg { - -sharedpagercache { - sqlite3_enable_shared_cache 1 - } - default { - set argv [linsert $argv 0 $arg] - break - } - } -} - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -rename finish_test really_finish_test -proc finish_test {} {} -set ISQUICK 1 - -set EXCLUDE { - fts.test - fts1.test - fts2.test -} - -if {[sqlite3 -has-codec]} { - # lappend EXCLUDE \ - # conflict.test -} - -foreach testfile [lsort -dictionary [glob $testdir/fts1*.test]] { - set tail [file tail $testfile] - puts "test: $tail" - if {[lsearch -exact $EXCLUDE $tail]>=0} continue - source $testfile - catch {db close} - if {$sqlite_open_file_count>0} { - puts "$tail did not close all files: $sqlite_open_file_count" - incr nErr - lappend ::failList $tail - } -} -source $testdir/misuse.test - -set sqlite_open_file_count 0 -really_finish_test diff --git a/third_party/sqlite/src/test/malloc_common.tcl b/third_party/sqlite/src/test/malloc_common.tcl index 90f6b06..90f6b06 100755..100644 --- a/third_party/sqlite/src/test/malloc_common.tcl +++ b/third_party/sqlite/src/test/malloc_common.tcl diff --git a/third_party/sqlite/src/test/quick.test b/third_party/sqlite/src/test/quick.test index 70b0eeb..def0d0e 100644 --- a/third_party/sqlite/src/test/quick.test +++ b/third_party/sqlite/src/test/quick.test @@ -59,7 +59,6 @@ set EXCLUDE { delete3.test fts3.test fts.test - fts1.test fts2.test fuzz.test fuzz3.test diff --git a/third_party/sqlite/src/test/tester.tcl b/third_party/sqlite/src/test/tester.tcl index d8047a5..d8047a5 100755..100644 --- a/third_party/sqlite/src/test/tester.tcl +++ b/third_party/sqlite/src/test/tester.tcl diff --git a/third_party/sqlite/src/test/thread_common.tcl b/third_party/sqlite/src/test/thread_common.tcl index bbd9389..bbd9389 100755..100644 --- a/third_party/sqlite/src/test/thread_common.tcl +++ b/third_party/sqlite/src/test/thread_common.tcl diff --git a/third_party/sqlite/src/tool/mksqlite3c.tcl b/third_party/sqlite/src/tool/mksqlite3c.tcl index 5a66e04..5a66e04 100755..100644 --- a/third_party/sqlite/src/tool/mksqlite3c.tcl +++ b/third_party/sqlite/src/tool/mksqlite3c.tcl diff --git a/third_party/sqlite/src/tool/spaceanal.tcl b/third_party/sqlite/src/tool/spaceanal.tcl index 3718357..3718357 100755..100644 --- a/third_party/sqlite/src/tool/spaceanal.tcl +++ b/third_party/sqlite/src/tool/spaceanal.tcl diff --git a/third_party/sqlite/src/www/capi3ref.tcl b/third_party/sqlite/src/www/capi3ref.tcl deleted file mode 100755 index 631acef..0000000 --- a/third_party/sqlite/src/www/capi3ref.tcl +++ /dev/null @@ -1,1882 +0,0 @@ -set rcsid {$Id: capi3ref.tcl,v 1.60 2007/05/19 06:48:43 danielk1977 Exp $} -source common.tcl -header {C/C++ Interface For SQLite Version 3} -puts { -<h2 class=pdf_section>C/C++ Interface For SQLite Version 3</h2> -} - -proc api {name prototype desc {notused x}} { - global apilist specialname - if {$name==""} { - regsub -all {sqlite3_[a-z0-9_]+\(} $prototype \ - {[lappend name [string trimright & (]]} x1 - subst $x1 - } else { - lappend specialname $name - } - lappend apilist [list $name $prototype $desc] -} - -api {extended-result-codes} { -#define SQLITE_IOERR_READ -#define SQLITE_IOERR_SHORT_READ -#define SQLITE_IOERR_WRITE -#define SQLITE_IOERR_FSYNC -#define SQLITE_IOERR_DIR_FSYNC -#define SQLITE_IOERR_TRUNCATE -#define SQLITE_IOERR_FSTAT -#define SQLITE_IOERR_UNLOCK -#define SQLITE_IOERR_RDLOCK -... -} { -In its default configuration, SQLite API routines return one of 26 integer -result codes described at result-codes. However, experience has shown that -many of these result codes are too course-grained. They do not provide as -much information about problems as users might like. In an effort to -address this, newer versions of SQLite (version 3.3.8 and later) include -support for additional result codes that provide more detailed information -about errors. The extended result codes are enabled (or disabled) for -each database -connection using the sqlite3_extended_result_codes() API. - -Some of the available extended result codes are listed above. -We expect the number of extended result codes will be expand -over time. Software that uses extended result codes should expect -to see new result codes in future releases of SQLite. - -The symbolic name for an extended result code always contains a related -primary result code as a prefix. Primary result codes contain a single -"_" character. Extended result codes contain two or more "_" characters. -The numeric value of an extended result code can be converted to its -corresponding primary result code by masking off the lower 8 bytes. - -A complete list of available extended result codes and -details about the meaning of the various extended result codes can be -found by consulting the C code, especially the sqlite3.h header -file and its antecedent sqlite.h.in. Additional information -is also available at the SQLite wiki: -http://www.sqlite.org/cvstrac/wiki?p=ExtendedResultCodes -} - - -api {result-codes} { -#define SQLITE_OK 0 /* Successful result */ -#define SQLITE_ERROR 1 /* SQL error or missing database */ -#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ -#define SQLITE_PERM 3 /* Access permission denied */ -#define SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define SQLITE_BUSY 5 /* The database file is locked */ -#define SQLITE_LOCKED 6 /* A table in the database is locked */ -#define SQLITE_NOMEM 7 /* A malloc() failed */ -#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */ -#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ -#define SQLITE_FULL 13 /* Insertion failed because database is full */ -#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */ -#define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ -#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -#define SQLITE_MISMATCH 20 /* Data type mismatch */ -#define SQLITE_MISUSE 21 /* Library used incorrectly */ -#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_ROW 100 /* sqlite_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite_step() has finished executing */ -} { -Many SQLite functions return an integer result code from the set shown -above in order to indicates success or failure. - -The result codes above are the only ones returned by SQLite in its -default configuration. However, the sqlite3_extended_result_codes() -API can be used to set a database connectoin to return more detailed -result codes. See the documentation on sqlite3_extended_result_codes() -or extended-result-codes for additional information. -} - -api {} { - int sqlite3_extended_result_codes(sqlite3*, int onoff); -} { -This routine enables or disabled extended-result-codes feature. -By default, SQLite API routines return one of only 26 integer -result codes described at result-codes. When extended result codes -are enabled by this routine, the repetoire of result codes can be -much larger and can (hopefully) provide more detailed information -about the cause of an error. - -The second argument is a boolean value that turns extended result -codes on and off. Extended result codes are off by default for -backwards compatibility with older versions of SQLite. -} - -api {} { - const char *sqlite3_libversion(void); -} { - Return a pointer to a string which contains the version number of - the library. The same string is available in the global - variable named "sqlite3_version". This interface is provided since - windows is unable to access global variables in DLLs. -} - -api {} { - void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); -} { - Aggregate functions use this routine to allocate - a structure for storing their state. The first time this routine - is called for a particular aggregate, a new structure of size nBytes - is allocated, zeroed, and returned. On subsequent calls (for the - same aggregate instance) the same buffer is returned. The implementation - of the aggregate can use the returned buffer to accumulate data. - - The buffer is freed automatically by SQLite when the query that - invoked the aggregate function terminates. -} - -api {} { - int sqlite3_aggregate_count(sqlite3_context*); -} { - This function is deprecated. It continues to exist so as not to - break any legacy code that might happen to use it. But it should not - be used in any new code. - - In order to encourage people to not use this function, we are not going - to tell you what it does. -} - -api {} { - int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); - int sqlite3_bind_double(sqlite3_stmt*, int, double); - int sqlite3_bind_int(sqlite3_stmt*, int, int); - int sqlite3_bind_int64(sqlite3_stmt*, int, long long int); - int sqlite3_bind_null(sqlite3_stmt*, int); - int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); - int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); - #define SQLITE_STATIC ((void(*)(void *))0) - #define SQLITE_TRANSIENT ((void(*)(void *))-1) -} { - In the SQL strings input to sqlite3_prepare_v2() and sqlite3_prepare16_v2(), - one or more literals can be replace by a parameter "?" or "?NNN" - or ":AAA" or "@AAA" or "\$VVV" where NNN is an integer literal, - AAA is an alphanumeric identifier and VVV is a variable name according - to the syntax rules of the TCL programming language. - The values of these parameters (also called "host parameter names") - can be set using the sqlite3_bind_*() routines. - - The first argument to the sqlite3_bind_*() routines always is a pointer - to the sqlite3_stmt structure returned from sqlite3_prepare_v2(). The second - argument is the index of the parameter to be set. The first parameter has - an index of 1. When the same named parameter is used more than once, second - and subsequent - occurrences have the same index as the first occurrence. The index for - named parameters can be looked up using the - sqlite3_bind_parameter_name() API if desired. The index for "?NNN" - parametes is the value of NNN. The NNN value must be between 1 and 999. - - - The third argument is the value to bind to the parameter. - - In those - routines that have a fourth argument, its value is the number of bytes - in the parameter. To be clear: the value is the number of bytes in the - string, not the number of characters. The number - of bytes does not include the zero-terminator at the end of strings. - If the fourth parameter is negative, the length of the string is - number of bytes up to the first zero terminator. - - The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and - sqlite3_bind_text16() is a destructor used to dispose of the BLOB or - text after SQLite has finished with it. If the fifth argument is the - special value SQLITE_STATIC, then the library assumes that the information - is in static, unmanaged space and does not need to be freed. If the - fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its - own private copy of the data immediately, before the sqlite3_bind_*() - routine returns. - - The sqlite3_bind_*() routines must be called after - sqlite3_prepare_v2() or sqlite3_reset() and before sqlite3_step(). - Bindings are not cleared by the sqlite3_reset() routine. - Unbound parameters are interpreted as NULL. - - These routines return SQLITE_OK on success or an error code if - anything goes wrong. SQLITE_RANGE is returned if the parameter - index is out of range. SQLITE_NOMEM is returned if malloc fails. - SQLITE_MISUSE is returned if these routines are called on a virtual - machine that is the wrong state or which has already been finalized. -} - -api {} { - int sqlite3_bind_parameter_count(sqlite3_stmt*); -} { - Return the number of parameters in the precompiled statement given as - the argument. -} - -api {} { - const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int n); -} { - Return the name of the n-th parameter in the precompiled statement. - Parameters of the form ":AAA" or "@AAA" or "\$VVV" have a name which is the - string ":AAA" or "@AAA" or "\$VVV". - In other words, the initial ":" or "$" or "@" - is included as part of the name. - Parameters of the form "?" or "?NNN" have no name. - - The first bound parameter has an index of 1, not 0. - - If the value n is out of range or if the n-th parameter is nameless, - then NULL is returned. The returned string is always in the - UTF-8 encoding even if the named parameter was originally specified - as UTF-16 in sqlite3_prepare16_v2(). -} - -api {} { - int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); -} { - Return the index of the parameter with the given name. - The name must match exactly. - If there is no parameter with the given name, return 0. - The string zName is always in the UTF-8 encoding. -} - -api {} { - int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); -} { - This routine identifies a callback function that might be invoked - whenever an attempt is made to open a database table - that another thread or process has locked. - If the busy callback is NULL, then SQLITE_BUSY is returned immediately - upon encountering the lock. - If the busy callback is not NULL, then the - callback will be invoked with two arguments. The - first argument to the handler is a copy of the void* pointer which - is the third argument to this routine. The second argument to - the handler is the number of times that the busy handler has - been invoked for this locking event. If the - busy callback returns 0, then no additional attempts are made to - access the database and SQLITE_BUSY is returned. - If the callback returns non-zero, then another attempt is made to open the - database for reading and the cycle repeats. - - The presence of a busy handler does not guarantee that - it will be invoked when there is lock contention. - If SQLite determines that invoking the busy handler could result in - a deadlock, it will return SQLITE_BUSY instead. - Consider a scenario where one process is holding a read lock that - it is trying to promote to a reserved lock and - a second process is holding a reserved lock that it is trying - to promote to an exclusive lock. The first process cannot proceed - because it is blocked by the second and the second process cannot - proceed because it is blocked by the first. If both processes - invoke the busy handlers, neither will make any progress. Therefore, - SQLite returns SQLITE_BUSY for the first process, hoping that this - will induce the first process to release its read lock and allow - the second process to proceed. - - The default busy callback is NULL. - - Sqlite is re-entrant, so the busy handler may start a new query. - (It is not clear why anyone would every want to do this, but it - is allowed, in theory.) But the busy handler may not close the - database. Closing the database from a busy handler will delete - data structures out from under the executing query and will - probably result in a coredump. - - There can only be a single busy handler defined for each database - connection. Setting a new busy handler clears any previous one. - Note that calling sqlite3_busy_timeout() will also set or clear - the busy handler. -} - -api {} { - int sqlite3_busy_timeout(sqlite3*, int ms); -} { - This routine sets a busy handler that sleeps for a while when a - table is locked. The handler will sleep multiple times until - at least "ms" milliseconds of sleeping have been done. After - "ms" milliseconds of sleeping, the handler returns 0 which - causes sqlite3_exec() to return SQLITE_BUSY. - - Calling this routine with an argument less than or equal to zero - turns off all busy handlers. - - There can only be a single busy handler for a particular database - connection. If another busy handler was defined - (using sqlite3_busy_handler()) prior to calling - this routine, that other busy handler is cleared. -} - -api {} { - int sqlite3_changes(sqlite3*); -} { - This function returns the number of database rows that were changed - (or inserted or deleted) by the most recently completed - INSERT, UPDATE, or DELETE - statement. Only changes that are directly specified by the INSERT, - UPDATE, or DELETE statement are counted. Auxiliary changes caused by - triggers are not counted. Use the sqlite3_total_changes() function - to find the total number of changes including changes caused by triggers. - - Within the body of a trigger, the sqlite3_changes() function does work - to report the number of rows that were changed for the most recently - completed INSERT, UPDATE, or DELETE statement within the trigger body. - - SQLite implements the command "DELETE FROM table" without a WHERE clause - by dropping and recreating the table. (This is much faster than going - through and deleting individual elements from the table.) Because of - this optimization, the change count for "DELETE FROM table" will be - zero regardless of the number of elements that were originally in the - table. To get an accurate count of the number of rows deleted, use - "DELETE FROM table WHERE 1" instead. -} - -api {} { - int sqlite3_total_changes(sqlite3*); -} { - This function returns the total number of database rows that have - be modified, inserted, or deleted since the database connection was - created using sqlite3_open(). All changes are counted, including - changes by triggers and changes to TEMP and auxiliary databases. - Except, changes to the SQLITE_MASTER table (caused by statements - such as CREATE TABLE) are not counted. Nor are changes counted when - an entire table is deleted using DROP TABLE. - - See also the sqlite3_changes() API. - - SQLite implements the command "DELETE FROM table" without a WHERE clause - by dropping and recreating the table. (This is much faster than going - through and deleting individual elements form the table.) Because of - this optimization, the change count for "DELETE FROM table" will be - zero regardless of the number of elements that were originally in the - table. To get an accurate count of the number of rows deleted, use - "DELETE FROM table WHERE 1" instead. -} - -api {} { - int sqlite3_close(sqlite3*); -} { - Call this function with a pointer to a structure that was previously - returned from sqlite3_open() or sqlite3_open16() - and the corresponding database will by closed. - - SQLITE_OK is returned if the close is successful. If there are - prepared statements that have not been finalized, then SQLITE_BUSY - is returned. SQLITE_ERROR might be returned if the argument is not - a valid connection pointer returned by sqlite3_open() or if the connection - pointer has been closed previously. -} - -api {} { -const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -double sqlite3_column_double(sqlite3_stmt*, int iCol); -int sqlite3_column_int(sqlite3_stmt*, int iCol); -long long int sqlite3_column_int64(sqlite3_stmt*, int iCol); -const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -int sqlite3_column_type(sqlite3_stmt*, int iCol); -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_TEXT 3 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 -} { - These routines return information about the information - in a single column of the current result row of a query. In every - case the first argument is a pointer to the SQL statement that is being - executed (the sqlite_stmt* that was returned from sqlite3_prepare_v2()) and - the second argument is the index of the column for which information - should be returned. iCol is zero-indexed. The left-most column has an - index of 0. - - If the SQL statement is not currently point to a valid row, or if the - the column index is out of range, the result is undefined. - - The sqlite3_column_type() routine returns the initial data type - of the result column. The returned value is one of SQLITE_INTEGER, - SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. The value - returned by sqlite3_column_type() is only meaningful if no type - conversions have occurred as described below. After a type conversion, - the value returned by sqlite3_column_type() is undefined. Future - versions of SQLite may change the behavior of sqlite3_column_type() - following a type conversion. - - If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() - routine returns the number of bytes in that BLOB or string. - If the result is a UTF-16 string, then sqlite3_column_bytes() converts - the string to UTF-8 and then returns the number of bytes. - If the result is a numeric value then sqlite3_column_bytes() uses - sqlite3_snprintf() to convert that value to a UTF-8 string and returns - the number of bytes in that string. - The value returned does - not include the \\000 terminator at the end of the string. - - The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() - but leaves the result in UTF-16 instead of UTF-8. - The \\u0000 terminator is not included in this count. - - These routines attempt to convert the value where appropriate. For - example, if the internal representation is FLOAT and a text result - is requested, sqlite3_snprintf() is used internally to do the conversion - automatically. The following table details the conversions that - are applied: - -<blockquote> -<table border="1"> -<tr><th>Internal Type</th><th>Requested Type</th><th>Conversion</th></tr> -<tr><td> NULL </td><td> INTEGER</td><td>Result is 0</td></tr> -<tr><td> NULL </td><td> FLOAT </td><td> Result is 0.0</td></tr> -<tr><td> NULL </td><td> TEXT </td><td> Result is NULL pointer</td></tr> -<tr><td> NULL </td><td> BLOB </td><td> Result is NULL pointer</td></tr> -<tr><td> INTEGER </td><td> FLOAT </td><td> Convert from integer to float</td></tr> -<tr><td> INTEGER </td><td> TEXT </td><td> ASCII rendering of the integer</td></tr> -<tr><td> INTEGER </td><td> BLOB </td><td> Same as for INTEGER->TEXT</td></tr> -<tr><td> FLOAT </td><td> INTEGER</td><td>Convert from float to integer</td></tr> -<tr><td> FLOAT </td><td> TEXT </td><td> ASCII rendering of the float</td></tr> -<tr><td> FLOAT </td><td> BLOB </td><td> Same as FLOAT->TEXT</td></tr> -<tr><td> TEXT </td><td> INTEGER</td><td>Use atoi()</td></tr> -<tr><td> TEXT </td><td> FLOAT </td><td> Use atof()</td></tr> -<tr><td> TEXT </td><td> BLOB </td><td> No change</td></tr> -<tr><td> BLOB </td><td> INTEGER</td><td>Convert to TEXT then use atoi()</td></tr> -<tr><td> BLOB </td><td> FLOAT </td><td> Convert to TEXT then use atof()</td></tr> -<tr><td> BLOB </td><td> TEXT </td><td> Add a \\000 terminator if needed</td></tr> -</table> -</blockquote> - - Note that when type conversions occur, pointers returned by prior - calls to sqlite3_column_blob(), sqlite3_column_text(), and/or - sqlite3_column_text16() may be invalidated. - Type conversions and pointer invalidations might occur - in the following cases: - - <ul> - <li><p> - The initial content is a BLOB and sqlite3_column_text() - or sqlite3_column_text16() - is called. A zero-terminator might need to be added to the string. - </p></li> - <li><p> - The initial content is UTF-8 text and sqlite3_column_bytes16() or - sqlite3_column_text16() is called. The content must be converted to UTF-16. - </p></li> - <li><p> - The initial content is UTF-16 text and sqlite3_column_bytes() or - sqlite3_column_text() is called. The content must be converted to UTF-8. - </p></li> - </ul> - - Conversions between UTF-16be and UTF-16le - are always done in place and do - not invalidate a prior pointer, though of course the content of the buffer - that the prior pointer points to will have been modified. Other kinds - of conversion are done in place when it is possible, but sometime it is - not possible and in those cases prior pointers are invalidated. - - The safest and easiest to remember policy is to invoke these routines - in one of the following ways: - - <ul> - <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> - <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> - <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> - </ul> - - In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), - or sqlite3_column_text16() first to force the result into the desired - format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to - find the size of the result. Do not mix call to sqlite3_column_text() or - sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not - mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). -} - -api {} { -int sqlite3_column_count(sqlite3_stmt *pStmt); -} { - Return the number of columns in the result set returned by the prepared - SQL statement. This routine returns 0 if pStmt is an SQL statement - that does not return data (for example an UPDATE). - - See also sqlite3_data_count(). -} - -api {} { -const char *sqlite3_column_decltype(sqlite3_stmt *, int i); -const void *sqlite3_column_decltype16(sqlite3_stmt*,int); -} { - The first argument is a prepared SQL statement. If this statement - is a SELECT statement, the Nth column of the returned result set - of the SELECT is a table column then the declared type of the table - column is returned. If the Nth column of the result set is not a table - column, then a NULL pointer is returned. The returned string is - UTF-8 encoded for sqlite3_column_decltype() and UTF-16 encoded - for sqlite3_column_decltype16(). For example, in the database schema: - - <blockquote><pre> - CREATE TABLE t1(c1 INTEGER); - </pre></blockquote> - - And the following statement compiled: - - <blockquote><pre> - SELECT c1 + 1, c1 FROM t1; - </pre></blockquote> - - Then this routine would return the string "INTEGER" for the second - result column (i==1), and a NULL pointer for the first result column - (i==0). - - If the following statements were compiled then this routine would - return "INTEGER" for the first (only) result column. - - <blockquote><pre> - SELECT (SELECT c1) FROM t1; - SELECT (SELECT c1 FROM t1); - SELECT c1 FROM (SELECT c1 FROM t1); - SELECT * FROM (SELECT c1 FROM t1); - SELECT * FROM (SELECT * FROM t1); - </pre></blockquote> -} - -api {} { - int sqlite3_table_column_metadata( - sqlite3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if colums is auto-increment */ - ); -} { - This routine is used to obtain meta information about a specific column of a - specific database table accessible using the connection handle passed as the - first function argument. - - The column is identified by the second, third and fourth parameters to - this function. The second parameter is either the name of the database - (i.e. "main", "temp" or an attached database) containing the specified - table or NULL. If it is NULL, then all attached databases are searched - for the table using the same algorithm as the database engine uses to - resolve unqualified table references. - - The third and fourth parameters to this function are the table and column - name of the desired column, respectively. Neither of these parameters - may be NULL. - - Meta information is returned by writing to the memory locations passed as - the 5th and subsequent parameters to this function. Any of these - arguments may be NULL, in which case the corresponding element of meta - information is ommitted. - -<pre> - Parameter Output Type Description - ----------------------------------- - 5th const char* Declared data type - 6th const char* Name of the columns default collation sequence - 7th int True if the column has a NOT NULL constraint - 8th int True if the column is part of the PRIMARY KEY - 9th int True if the column is AUTOINCREMENT -</pre> - - The memory pointed to by the character pointers returned for the - declaration type and collation sequence is valid only until the next - call to any sqlite API function. - - This function may load one or more schemas from database files. If an - error occurs during this process, or if the requested table or column - cannot be found, an SQLITE error code is returned and an error message - left in the database handle (to be retrieved using sqlite3_errmsg()). - Specifying an SQL view instead of a table as the third argument is also - considered an error. - - If the specified column is "rowid", "oid" or "_rowid_" and an - INTEGER PRIMARY KEY column has been explicitly declared, then the output - parameters are set for the explicitly declared column. If there is no - explicitly declared IPK column, then the data-type is "INTEGER", the - collation sequence "BINARY" and the primary-key flag is set. Both - the not-null and auto-increment flags are clear. - - This API is only available if the library was compiled with the - SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. -} - -api {} { -const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N); -const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N); -} { -If the Nth column returned by statement pStmt is a column reference, -these functions may be used to access the name of the database (either -"main", "temp" or the name of an attached database) that contains -the column. If the Nth column is not a column reference, NULL is -returned. - -See the description of function sqlite3_column_decltype() for a -description of exactly which expressions are considered column references. - -Function sqlite3_column_database_name() returns a pointer to a UTF-8 -encoded string. sqlite3_column_database_name16() returns a pointer -to a UTF-16 encoded string. -} - -api {} { -const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N); -const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N); -} { -If the Nth column returned by statement pStmt is a column reference, -these functions may be used to access the schema name of the referenced -column in the database schema. If the Nth column is not a column -reference, NULL is returned. - -See the description of function sqlite3_column_decltype() for a -description of exactly which expressions are considered column references. - -Function sqlite3_column_origin_name() returns a pointer to a UTF-8 -encoded string. sqlite3_column_origin_name16() returns a pointer -to a UTF-16 encoded string. -} - -api {} { -const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N); -const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N); -} { -If the Nth column returned by statement pStmt is a column reference, -these functions may be used to access the name of the table that -contains the column. If the Nth column is not a column reference, -NULL is returned. - -See the description of function sqlite3_column_decltype() for a -description of exactly which expressions are considered column references. - -Function sqlite3_column_table_name() returns a pointer to a UTF-8 -encoded string. sqlite3_column_table_name16() returns a pointer -to a UTF-16 encoded string. -} - -api {} { -const char *sqlite3_column_name(sqlite3_stmt*,int); -const void *sqlite3_column_name16(sqlite3_stmt*,int); -} { - The first argument is a prepared SQL statement. This function returns - the column heading for the Nth column of that statement, where N is the - second function argument. The string returned is UTF-8 for - sqlite3_column_name() and UTF-16 for sqlite3_column_name16(). -} - -api {} { -void *sqlite3_commit_hook(sqlite3*, int(*xCallback)(void*), void *pArg); -} { - <i>Experimental</i> - - Register a callback function to be invoked whenever a new transaction - is committed. The pArg argument is passed through to the callback. - callback. If the callback function returns non-zero, then the commit - is converted into a rollback. - - If another function was previously registered, its pArg value is returned. - Otherwise NULL is returned. - - Registering a NULL function disables the callback. Only a single commit - hook callback can be registered at a time. -} - -api {} { -int sqlite3_complete(const char *sql); -int sqlite3_complete16(const void *sql); -} { - These functions return true if the given input string comprises - one or more complete SQL statements. - The argument must be a nul-terminated UTF-8 string for sqlite3_complete() - and a nul-terminated UTF-16 string for sqlite3_complete16(). - - These routines do not check to see if the SQL statement is well-formed. - They only check to see that the statement is terminated by a semicolon - that is not part of a string literal and is not inside - the body of a trigger. -} {} - -api {} { -int sqlite3_create_collation( - sqlite3*, - const char *zName, - int pref16, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); -int sqlite3_create_collation16( - sqlite3*, - const char *zName, - int pref16, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); -#define SQLITE_UTF8 1 -#define SQLITE_UTF16BE 2 -#define SQLITE_UTF16LE 3 -#define SQLITE_UTF16 4 -} { - These two functions are used to add new collation sequences to the - sqlite3 handle specified as the first argument. - - The name of the new collation sequence is specified as a UTF-8 string - for sqlite3_create_collation() and a UTF-16 string for - sqlite3_create_collation16(). In both cases the name is passed as the - second function argument. - - The third argument must be one of the constants SQLITE_UTF8, - SQLITE_UTF16LE or SQLITE_UTF16BE, indicating that the user-supplied - routine expects to be passed pointers to strings encoded using UTF-8, - UTF-16 little-endian or UTF-16 big-endian respectively. The - SQLITE_UTF16 constant indicates that text strings are expected in - UTF-16 in the native byte order of the host machine. - - A pointer to the user supplied routine must be passed as the fifth - argument. If it is NULL, this is the same as deleting the collation - sequence (so that SQLite cannot call it anymore). Each time the user - supplied function is invoked, it is passed a copy of the void* passed as - the fourth argument to sqlite3_create_collation() or - sqlite3_create_collation16() as its first argument. - - The remaining arguments to the user-supplied routine are two strings, - each represented by a [length, data] pair and encoded in the encoding - that was passed as the third argument when the collation sequence was - registered. The user routine should return negative, zero or positive if - the first string is less than, equal to, or greater than the second - string. i.e. (STRING1 - STRING2). -} - -api {} { -int sqlite3_collation_needed( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const char*) -); -int sqlite3_collation_needed16( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const void*) -); -} { - To avoid having to register all collation sequences before a database - can be used, a single callback function may be registered with the - database handle to be called whenever an undefined collation sequence is - required. - - If the function is registered using the sqlite3_collation_needed() API, - then it is passed the names of undefined collation sequences as strings - encoded in UTF-8. If sqlite3_collation_needed16() is used, the names - are passed as UTF-16 in machine native byte order. A call to either - function replaces any existing callback. - - When the user-function is invoked, the first argument passed is a copy - of the second argument to sqlite3_collation_needed() or - sqlite3_collation_needed16(). The second argument is the database - handle. The third argument is one of SQLITE_UTF8, SQLITE_UTF16BE or - SQLITE_UTF16LE, indicating the most desirable form of the collation - sequence function required. The fourth argument is the name of the - required collation sequence. - - The collation sequence is returned to SQLite by a collation-needed - callback using the sqlite3_create_collation() or - sqlite3_create_collation16() APIs, described above. -} - -api {} { -int sqlite3_create_function( - sqlite3 *, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pUserData, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); -int sqlite3_create_function16( - sqlite3*, - const void *zFunctionName, - int nArg, - int eTextRep, - void *pUserData, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); -#define SQLITE_UTF8 1 -#define SQLITE_UTF16 2 -#define SQLITE_UTF16BE 3 -#define SQLITE_UTF16LE 4 -#define SQLITE_ANY 5 -} { - These two functions are used to add SQL functions or aggregates - implemented in C. The - only difference between these two routines is that the second argument, the - name of the (scalar) function or aggregate, is encoded in UTF-8 for - sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). - The length of the name is limited to 255 bytes, exclusive of the - zero-terminator. Note that the name length limit is in bytes, not - characters. Any attempt to create a function with a longer name - will result in an SQLITE_ERROR error. - - The first argument is the database handle that the new function or - aggregate is to be added to. If a single program uses more than one - database handle internally, then user functions or aggregates must - be added individually to each database handle with which they will be - used. - - The third argument is the number of arguments that the function or - aggregate takes. If this argument is -1 then the function or - aggregate may take any number of arguments. The maximum number - of arguments to a new SQL function is 127. A number larger than - 127 for the third argument results in an SQLITE_ERROR error. - - The fourth argument, eTextRep, specifies what type of text arguments - this function prefers to receive. Any function should be able to work - work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be - more efficient with one representation than another. Users are allowed - to specify separate implementations for the same function which are called - depending on the text representation of the arguments. The the implementation - which provides the best match is used. If there is only a single - implementation which does not care what text representation is used, - then the fourth argument should be SQLITE_ANY. - - The fifth argument is an arbitrary pointer. The function implementations - can gain access to this pointer using the sqlite_user_data() API. - - The sixth, seventh and eighth argumens, xFunc, xStep and xFinal, are - pointers to user implemented C functions that implement the user - function or aggregate. A scalar function requires an implementation of - the xFunc callback only, NULL pointers should be passed as the xStep - and xFinal arguments. An aggregate function requires an implementation - of xStep and xFinal, and NULL should be passed for xFunc. To delete an - existing user function or aggregate, pass NULL for all three function - callbacks. Specifying an inconstant set of callback values, such as an - xFunc and an xFinal, or an xStep but no xFinal, results in an SQLITE_ERROR - return. -} - -api {} { -int sqlite3_data_count(sqlite3_stmt *pStmt); -} { - Return the number of values in the current row of the result set. - - After a call to sqlite3_step() that returns SQLITE_ROW, this routine - will return the same value as the sqlite3_column_count() function. - After sqlite3_step() has returned an SQLITE_DONE, SQLITE_BUSY or - error code, or before sqlite3_step() has been called on a - prepared SQL statement, this routine returns zero. -} - -api {} { -int sqlite3_errcode(sqlite3 *db); -} { - Return the error code for the most recent failed sqlite3_* API call associated - with sqlite3 handle 'db'. If a prior API call failed but the most recent - API call succeeded, the return value from this routine is undefined. - - Calls to many sqlite3_* functions set the error code and string returned - by sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16() - (overwriting the previous values). Note that calls to sqlite3_errcode(), - sqlite3_errmsg() and sqlite3_errmsg16() themselves do not affect the - results of future invocations. Calls to API routines that do not return - an error code (examples: sqlite3_data_count() or sqlite3_mprintf()) do - not change the error code returned by this routine. - - Assuming no other intervening sqlite3_* API calls are made, the error - code returned by this function is associated with the same error as - the strings returned by sqlite3_errmsg() and sqlite3_errmsg16(). -} {} - -api {} { -const char *sqlite3_errmsg(sqlite3*); -const void *sqlite3_errmsg16(sqlite3*); -} { - Return a pointer to a UTF-8 encoded string (sqlite3_errmsg) - or a UTF-16 encoded string (sqlite3_errmsg16) describing in English the - error condition for the most recent sqlite3_* API call. The returned - string is always terminated by an 0x00 byte. - - The string "not an error" is returned when the most recent API call was - successful. -} - -api {} { -int sqlite3_exec( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be executed */ - sqlite_callback, /* Callback function */ - void *, /* 1st argument to callback function */ - char **errmsg /* Error msg written here */ -); -} { - A function to executes one or more statements of SQL. - - If one or more of the SQL statements are queries, then - the callback function specified by the 3rd argument is - invoked once for each row of the query result. This callback - should normally return 0. If the callback returns a non-zero - value then the query is aborted, all subsequent SQL statements - are skipped and the sqlite3_exec() function returns the SQLITE_ABORT. - - The 1st argument is an arbitrary pointer that is passed - to the callback function as its first argument. - - The 2nd argument to the callback function is the number of - columns in the query result. The 3rd argument to the callback - is an array of strings holding the values for each column. - The 4th argument to the callback is an array of strings holding - the names of each column. - - The callback function may be NULL, even for queries. A NULL - callback is not an error. It just means that no callback - will be invoked. - - If an error occurs while parsing or evaluating the SQL (but - not while executing the callback) then an appropriate error - message is written into memory obtained from malloc() and - *errmsg is made to point to that message. The calling function - is responsible for freeing the memory that holds the error - message. Use sqlite3_free() for this. If errmsg==NULL, - then no error message is ever written. - - The return value is is SQLITE_OK if there are no errors and - some other return code if there is an error. The particular - return value depends on the type of error. - - If the query could not be executed because a database file is - locked or busy, then this function returns SQLITE_BUSY. (This - behavior can be modified somewhat using the sqlite3_busy_handler() - and sqlite3_busy_timeout() functions.) -} {} - -api {} { -int sqlite3_finalize(sqlite3_stmt *pStmt); -} { - The sqlite3_finalize() function is called to delete a prepared - SQL statement obtained by a previous call to sqlite3_prepare(), - sqlite3_prepare_v2(), sqlite3_prepare16(), or sqlite3_prepare16_v2(). - If the statement was executed successfully, or - not executed at all, then SQLITE_OK is returned. If execution of the - statement failed then an error code is returned. - - After sqlite_finalize() has been called, the statement handle is - invalidated. Passing it to any other SQLite function may cause a - crash. - - All prepared statements must finalized before sqlite3_close() is - called or else the close will fail with a return code of SQLITE_BUSY. - - This routine can be called at any point during the execution of the - virtual machine. If the virtual machine has not completed execution - when this routine is called, that is like encountering an error or - an interrupt. (See sqlite3_interrupt().) Incomplete updates may be - rolled back and transactions canceled, depending on the circumstances, - and the result code returned will be SQLITE_ABORT. -} - -api {} { -void *sqlite3_malloc(int); -void *sqlite3_realloc(void*, int); -void sqlite3_free(void*); -} { - These routines provide access to the memory allocator used by SQLite. - Depending on how SQLite has been compiled and the OS-layer backend, - the memory allocator used by SQLite might be the standard system - malloc()/realloc()/free(), or it might be something different. With - certain compile-time flags, SQLite will add wrapper logic around the - memory allocator to add memory leak and buffer overrun detection. The - OS layer might substitute a completely different memory allocator. - Use these APIs to be sure you are always using the correct memory - allocator. - - The sqlite3_free() API, not the standard free() from the system library, - should always be used to free the memory buffer returned by - sqlite3_mprintf() or sqlite3_vmprintf() and to free the error message - string returned by sqlite3_exec(). Using free() instead of sqlite3_free() - might accidentally work on some systems and build configurations but - will fail on others. - - Compatibility Note: Prior to version 3.4.0, the sqlite3_free API - was prototyped to take a <tt>char*</tt> parameter rather than - <tt>void*</tt>. Like this: -<blockquote><pre> -void sqlite3_free(char*); -</pre></blockquote> - The change to using <tt>void*</tt> might cause warnings when - compiling older code against - newer libraries, but everything should still work correctly. -} - -api {} { -int sqlite3_get_table( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be executed */ - char ***resultp, /* Result written to a char *[] that this points to */ - int *nrow, /* Number of result rows written here */ - int *ncolumn, /* Number of result columns written here */ - char **errmsg /* Error msg written here */ -); -void sqlite3_free_table(char **result); -} { - This next routine is really just a wrapper around sqlite3_exec(). - Instead of invoking a user-supplied callback for each row of the - result, this routine remembers each row of the result in memory - obtained from malloc(), then returns all of the result after the - query has finished. - - As an example, suppose the query result where this table: - - <pre> - Name | Age - ----------------------- - Alice | 43 - Bob | 28 - Cindy | 21 - </pre> - - If the 3rd argument were &azResult then after the function returns - azResult will contain the following data: - - <pre> - azResult[0] = "Name"; - azResult[1] = "Age"; - azResult[2] = "Alice"; - azResult[3] = "43"; - azResult[4] = "Bob"; - azResult[5] = "28"; - azResult[6] = "Cindy"; - azResult[7] = "21"; - </pre> - - Notice that there is an extra row of data containing the column - headers. But the *nrow return value is still 3. *ncolumn is - set to 2. In general, the number of values inserted into azResult - will be ((*nrow) + 1)*(*ncolumn). - - After the calling function has finished using the result, it should - pass the result data pointer to sqlite3_free_table() in order to - release the memory that was malloc-ed. Because of the way the - malloc() happens, the calling function must not try to call - malloc() directly. Only sqlite3_free_table() is able to release - the memory properly and safely. - - The return value of this routine is the same as from sqlite3_exec(). -} - -api {sqlite3_interrupt} { - void sqlite3_interrupt(sqlite3*); -} { - This function causes any pending database operation to abort and - return at its earliest opportunity. This routine is typically - called in response to a user action such as pressing "Cancel" - or Ctrl-C where the user wants a long query operation to halt - immediately. -} {} - -api {} { -long long int sqlite3_last_insert_rowid(sqlite3*); -} { - Each entry in an SQLite table has a unique integer key called the "rowid". - The rowid is always available as an undeclared column - named ROWID, OID, or _ROWID_. - If the table has a column of type INTEGER PRIMARY KEY then that column - is another an alias for the rowid. - - This routine - returns the rowid of the most recent INSERT into the database - from the database connection given in the first argument. If - no inserts have ever occurred on this database connection, zero - is returned. - - If an INSERT occurs within a trigger, then the rowid of the - inserted row is returned by this routine as long as the trigger - is running. But once the trigger terminates, the value returned - by this routine reverts to the last value inserted before the - trigger fired. -} {} - -api {} { -char *sqlite3_mprintf(const char*,...); -char *sqlite3_vmprintf(const char*, va_list); -} { - These routines are variants of the "sprintf()" from the - standard C library. The resulting string is written into memory - obtained from malloc() so that there is never a possibility of buffer - overflow. These routines also implement some additional formatting - options that are useful for constructing SQL statements. - - The strings returned by these routines should be freed by calling - sqlite3_free(). - - All of the usual printf formatting options apply. In addition, there - is a "%q" option. %q works like %s in that it substitutes a null-terminated - string from the argument list. But %q also doubles every '\\'' character. - %q is designed for use inside a string literal. By doubling each '\\'' - character it escapes that character and allows it to be inserted into - the string. - - For example, so some string variable contains text as follows: - - <blockquote><pre> - char *zText = "It's a happy day!"; - </pre></blockquote> - - One can use this text in an SQL statement as follows: - - <blockquote><pre> - sqlite3_exec_printf(db, "INSERT INTO table VALUES('%q')", - callback1, 0, 0, zText); - </pre></blockquote> - - Because the %q format string is used, the '\\'' character in zText - is escaped and the SQL generated is as follows: - - <blockquote><pre> - INSERT INTO table1 VALUES('It''s a happy day!') - </pre></blockquote> - - This is correct. Had we used %s instead of %q, the generated SQL - would have looked like this: - - <blockquote><pre> - INSERT INTO table1 VALUES('It's a happy day!'); - </pre></blockquote> - - This second example is an SQL syntax error. As a general rule you - should always use %q instead of %s when inserting text into a string - literal. -} {} - -api {} { -char *sqlite3_snprintf(int bufSize, char *buf, const char *zFormat, ...); -} { - This routine works like "sprintf()", writing a formatted string into - the buf[]. However, no more than bufSize characters will be written - into buf[]. This routine returns a pointer to buf[]. If bufSize is - greater than zero, then buf[] is guaranteed to be zero-terminated. - - This routine uses the same extended formatting options as - sqlite3_mprintf() and sqlite3_vmprintf(). - - Note these differences with the snprintf() function found in many - standard libraries: (1) sqlite3_snprintf() returns a pointer to the - buffer rather than the number of characters written. (It would, - arguably, be more useful to return the number of characters written, - but we discovered that after the interface had been published and - are unwilling to break backwards compatibility.) (2) The order - of the bufSize and buf parameter is reversed from snprintf(). - And (3) sqlite3_snprintf() always writes a zero-terminator if bufSize - is positive. - - Please do not use the return value of this routine. We may - decide to make the minor compatibility break and change this routine - to return the number of characters written rather than a pointer to - the buffer in a future minor version increment. -} - -api {} { -int sqlite3_open( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -int sqlite3_open16( - const void *filename, /* Database filename (UTF-16) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -} { - Open the sqlite database file "filename". The "filename" is UTF-8 - encoded for sqlite3_open() and UTF-16 encoded in the native byte order - for sqlite3_open16(). An sqlite3* handle is returned in *ppDb, even - if an error occurs. If the database is opened (or created) successfully, - then SQLITE_OK is returned. Otherwise an error code is returned. The - sqlite3_errmsg() or sqlite3_errmsg16() routines can be used to obtain - an English language description of the error. - - If the database file does not exist, then a new database will be created - as needed. - The encoding for the database will be UTF-8 if sqlite3_open() is called and - UTF-16 if sqlite3_open16 is used. - - Whether or not an error occurs when it is opened, resources associated - with the sqlite3* handle should be released by passing it to - sqlite3_close() when it is no longer required. - - The returned sqlite3* can only be used in the same thread in which it - was created. It is an error to call sqlite3_open() in one thread then - pass the resulting database handle off to another thread to use. This - restriction is due to goofy design decisions (bugs?) in the way some - threading implementations interact with file locks. - - Note to windows users: The encoding used for the filename argument - of sqlite3_open() must be UTF-8, not whatever codepage is currently - defined. Filenames containing international characters must be converted - to UTF-8 prior to passing them into sqlite3_open(). -} - -api {} { -int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); - -/* Legacy Interfaces */ -int sqlite3_prepare( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -int sqlite3_prepare16( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); -} { - To execute an SQL query, it must first be compiled into a byte-code - program using one of these routines. - - The first argument "db" is an SQLite database handle. The second - argument "zSql" is the statement to be compiled, encoded as either - UTF-8 or UTF-16. The sqlite3_prepare_v2() - interfaces uses UTF-8 and sqlite3_prepare16_v2() - use UTF-16. If the next argument, "nBytes", is less - than zero, then zSql is read up to the first nul terminator. If - "nBytes" is not less than zero, then it is the length of the string zSql - in bytes (not characters). - - *pzTail is made to point to the first byte past the end of the first - SQL statement in zSql. This routine only compiles the first statement - in zSql, so *pzTail is left pointing to what remains uncompiled. - - *ppStmt is left pointing to a compiled SQL statement that can be - executed using sqlite3_step(). Or if there is an error, *ppStmt may be - set to NULL. If the input text contained no SQL (if the input is and - empty string or a comment) then *ppStmt is set to NULL. The calling - procedure is responsible for deleting this compiled SQL statement - using sqlite3_finalize() after it has finished with it. - - On success, SQLITE_OK is returned. Otherwise an error code is returned. - - The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are - recommended for all new programs. The two older interfaces are retained - for backwards compatibility, but their use is discouraged. - In the "v2" interfaces, the prepared statement - that is returned (the sqlite3_stmt object) contains a copy of the original - SQL. This causes the sqlite3_step() interface to behave a differently in - two ways: - - <ol> - <li> - If the database schema changes, instead of returning SQLITE_SCHEMA as it - always used to do, sqlite3_step() will automatically recompile the SQL - statement and try to run it again. If the schema has changed in a way - that makes the statement no longer valid, sqlite3_step() will still - return SQLITE_SCHEMA. But unlike the legacy behavior, SQLITE_SCHEMA is - now a fatal error. Calling sqlite3_prepare_v2() again will not make the - error go away. Note: use sqlite3_errmsg() to find the text of the parsing - error that results in an SQLITE_SCHEMA return. - </li> - - <li> - When an error occurs, - sqlite3_step() will return one of the detailed result-codes - like SQLITE_IOERR or SQLITE_FULL or SQLITE_SCHEMA directly. The - legacy behavior was that sqlite3_step() would only return a generic - SQLITE_ERROR code and you would have to make a second call to - sqlite3_reset() in order to find the underlying cause of the problem. - With the "v2" prepare interfaces, the underlying reason for the error is - returned directly. - </li> - </ol> -} - -api {} { -void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); -} { - <i>Experimental</i> - - This routine configures a callback function - the progress callback - that - is invoked periodically during long running calls to sqlite3_exec(), - sqlite3_step() and sqlite3_get_table(). - An example use for this API is to keep - a GUI updated during a large query. - - The progress callback is invoked once for every N virtual machine opcodes, - where N is the second argument to this function. The progress callback - itself is identified by the third argument to this function. The fourth - argument to this function is a void pointer passed to the progress callback - function each time it is invoked. - - If a call to sqlite3_exec(), sqlite3_step() or sqlite3_get_table() results - in less than N opcodes being executed, then the progress callback is not - invoked. - - To remove the progress callback altogether, pass NULL as the third - argument to this function. - - If the progress callback returns a result other than 0, then the current - query is immediately terminated and any database changes rolled back. If the - query was part of a larger transaction, then the transaction is not rolled - back and remains active. The sqlite3_exec() call returns SQLITE_ABORT. - -} - -api {} { -int sqlite3_reset(sqlite3_stmt *pStmt); -} { - The sqlite3_reset() function is called to reset a prepared SQL - statement obtained by a previous call to - sqlite3_prepare_v2() or - sqlite3_prepare16_v2() back to it's initial state, ready to be re-executed. - Any SQL statement variables that had values bound to them using - the sqlite3_bind_*() API retain their values. -} - -api {} { -void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_double(sqlite3_context*, double); -void sqlite3_result_error(sqlite3_context*, const char*, int); -void sqlite3_result_error16(sqlite3_context*, const void*, int); -void sqlite3_result_int(sqlite3_context*, int); -void sqlite3_result_int64(sqlite3_context*, long long int); -void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*)); -void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_text16be(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_text16le(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -} { - User-defined functions invoke these routines in order to - set their return value. The sqlite3_result_value() routine is used - to return an exact copy of one of the arguments to the function. - - The operation of these routines is very similar to the operation of - sqlite3_bind_blob() and its cousins. Refer to the documentation there - for additional information. -} - -api {} { -int sqlite3_set_authorizer( - sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData -); -#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ -#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ -#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ -#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ -#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ -#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ -#define SQLITE_DELETE 9 /* Table Name NULL */ -#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ -#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ -#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ -#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ -#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ -#define SQLITE_DROP_VIEW 17 /* View Name NULL */ -#define SQLITE_INSERT 18 /* Table Name NULL */ -#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ -#define SQLITE_READ 20 /* Table Name Column Name */ -#define SQLITE_SELECT 21 /* NULL NULL */ -#define SQLITE_TRANSACTION 22 /* NULL NULL */ -#define SQLITE_UPDATE 23 /* Table Name Column Name */ -#define SQLITE_ATTACH 24 /* Filename NULL */ -#define SQLITE_DETACH 25 /* Database Name NULL */ -#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ -#define SQLITE_REINDEX 27 /* Index Name NULL */ -#define SQLITE_ANALYZE 28 /* Table Name NULL */ -#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ -#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ -#define SQLITE_FUNCTION 31 /* Function Name NULL */ - -#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ -#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ -} { - This routine registers a callback with the SQLite library. The - callback is invoked by sqlite3_prepare_v2() to authorize various - operations against the database. The callback should - return SQLITE_OK if access is allowed, SQLITE_DENY if the entire - SQL statement should be aborted with an error and SQLITE_IGNORE - if the operation should be treated as a no-op. - - Each database connection have at most one authorizer registered - at a time one time. Each call - to sqlite3_set_authorizer() overrides the previous authorizer. - Setting the callback to NULL disables the authorizer. - - The second argument to the access authorization function will be one - of the defined constants shown. These values signify what kind of operation - is to be authorized. The 3rd and 4th arguments to the authorization - function will be arguments or NULL depending on which of the - codes is used as the second argument. For example, if the the - 2nd argument code is SQLITE_READ then the 3rd argument will be the name - of the table that is being read from and the 4th argument will be the - name of the column that is being read from. Or if the 2nd argument - is SQLITE_FUNCTION then the 3rd argument will be the name of the - function that is being invoked and the 4th argument will be NULL. - - The 5th argument is the name - of the database ("main", "temp", etc.) where applicable. The 6th argument - is the name of the inner-most trigger or view that is responsible for - the access attempt or NULL if this access attempt is directly from - input SQL code. - - The return value of the authorization callback function should be one of the - constants SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. A return of - SQLITE_OK means that the operation is permitted and that - sqlite3_prepare_v2() can proceed as normal. - A return of SQLITE_DENY means that the sqlite3_prepare_v2() - should fail with an error. A return of SQLITE_IGNORE causes the - sqlite3_prepare_v2() to continue as normal but the requested - operation is silently converted into a no-op. A return of SQLITE_IGNORE - in response to an SQLITE_READ or SQLITE_FUNCTION causes the column - being read or the function being invoked to return a NULL. - - The intent of this routine is to allow applications to safely execute - user-entered SQL. An appropriate callback can deny the user-entered - SQL access certain operations (ex: anything that changes the database) - or to deny access to certain tables or columns within the database. - - SQLite is not reentrant through the authorization callback function. - The authorization callback function should not attempt to invoke - any other SQLite APIs for the same database connection. If the - authorization callback function invokes some other SQLite API, an - SQLITE_MISUSE error or a segmentation fault may result. -} - -api {} { -int sqlite3_step(sqlite3_stmt*); -} { - After an SQL query has been prepared with a call to either - sqlite3_prepare_v2() or sqlite3_prepare16_v2() or to one of - the legacy interfaces sqlite3_prepare() or sqlite3_prepare16(), - then this function must be - called one or more times to execute the statement. - - The details of the behavior of this sqlite3_step() interface depend - on whether the statement was prepared using the newer "v2" interface - sqlite3_prepare_v2() and sqlite3_prepare16_v2() or the older legacy - interface sqlite3_prepare() and sqlite3_prepare16(). The use of the - new "v2" interface is recommended for new applications but the legacy - interface will continue to be supported. - - In the lagacy interface, the return value will be either SQLITE_BUSY, - SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. With the "v2" - interface, any of the other SQLite result-codes might be returned as - well. - - SQLITE_BUSY means that the database engine attempted to open - a locked database and there is no busy callback registered. - Call sqlite3_step() again to retry the open. - - SQLITE_DONE means that the statement has finished executing - successfully. sqlite3_step() should not be called again on this virtual - machine without first calling sqlite3_reset() to reset the virtual - machine back to its initial state. - - If the SQL statement being executed returns any data, then - SQLITE_ROW is returned each time a new row of data is ready - for processing by the caller. The values may be accessed using - the sqlite3_column_int(), sqlite3_column_text(), and similar functions. - sqlite3_step() is called again to retrieve the next row of data. - - SQLITE_ERROR means that a run-time error (such as a constraint - violation) has occurred. sqlite3_step() should not be called again on - the VM. More information may be found by calling sqlite3_errmsg(). - A more specific error code (example: SQLITE_INTERRUPT, SQLITE_SCHEMA, - SQLITE_CORRUPT, and so forth) can be obtained by calling - sqlite3_reset() on the prepared statement. In the "v2" interface, - the more specific error code is returned directly by sqlite3_step(). - - SQLITE_MISUSE means that the this routine was called inappropriately. - Perhaps it was called on a virtual machine that had already been - finalized or on one that had previously returned SQLITE_ERROR or - SQLITE_DONE. Or it could be the case that a database connection - is being used by a different thread than the one it was created it. - - <b>Goofy Interface Alert:</b> - In the legacy interface, - the sqlite3_step() API always returns a generic error code, - SQLITE_ERROR, following any error other than SQLITE_BUSY and SQLITE_MISUSE. - You must call sqlite3_reset() (or sqlite3_finalize()) in order to find - one of the specific result-codes that better describes the error. - We admit that this is a goofy design. The problem has been fixed - with the "v2" interface. If you prepare all of your SQL statements - using either sqlite3_prepare_v2() or sqlite3_prepare16_v2() instead - of the legacy sqlite3_prepare() and sqlite3_prepare16(), then the - more specific result-codes are returned directly by sqlite3_step(). - The use of the "v2" interface is recommended. -} - -api {} { -void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -} { - Register a function that is called each time an SQL statement is evaluated. - The callback function is invoked on the first call to sqlite3_step() after - calls to sqlite3_prepare_v2() or sqlite3_reset(). - This function can be used (for example) to generate - a log file of all SQL executed against a database. This can be - useful when debugging an application that uses SQLite. -} - -api {} { -void *sqlite3_user_data(sqlite3_context*); -} { - The pUserData argument to the sqlite3_create_function() and - sqlite3_create_function16() routines used to register user functions - is available to the implementation of the function using this - call. -} - -api {} { -const void *sqlite3_value_blob(sqlite3_value*); -int sqlite3_value_bytes(sqlite3_value*); -int sqlite3_value_bytes16(sqlite3_value*); -double sqlite3_value_double(sqlite3_value*); -int sqlite3_value_int(sqlite3_value*); -long long int sqlite3_value_int64(sqlite3_value*); -const unsigned char *sqlite3_value_text(sqlite3_value*); -const void *sqlite3_value_text16(sqlite3_value*); -const void *sqlite3_value_text16be(sqlite3_value*); -const void *sqlite3_value_text16le(sqlite3_value*); -int sqlite3_value_type(sqlite3_value*); -} { - This group of routines returns information about arguments to - a user-defined function. Function implementations use these routines - to access their arguments. These routines are the same as the - sqlite3_column_... routines except that these routines take a single - sqlite3_value* pointer instead of an sqlite3_stmt* and an integer - column number. - - See the documentation under sqlite3_column_blob for additional - information. - - Please pay particular attention to the fact that the pointer that - is returned from sqlite3_value_blob(), sqlite3_value_text(), or - sqlite3_value_text16() can be invalidated by a subsequent call to - sqlite3_value_bytes(), sqlite3_value_bytes16(), sqlite_value_text(), - or sqlite3_value_text16(). -} - -api {} { - int sqlite3_sleep(int); -} { - Sleep for a little while. The second parameter is the number of - miliseconds to sleep for. - - If the operating system does not support sleep requests with - milisecond time resolution, then the time will be rounded up to - the nearest second. The number of miliseconds of sleep actually - requested from the operating system is returned. -} - -api {} { - int sqlite3_expired(sqlite3_stmt*); -} { - Return TRUE (non-zero) if the statement supplied as an argument needs - to be recompiled. A statement needs to be recompiled whenever the - execution environment changes in a way that would alter the program - that sqlite3_prepare() generates. For example, if new functions or - collating sequences are registered or if an authorizer function is - added or changed. -} - -api {} { - int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -} { - Move all bindings from the first prepared statement over to the second. - This routine is useful, for example, if the first prepared statement - fails with an SQLITE_SCHEMA error. The same SQL can be prepared into - the second prepared statement then all of the bindings transfered over - to the second statement before the first statement is finalized. -} - -api {} { - int sqlite3_global_recover(); -} { - This function used to be involved in recovering from out-of-memory - errors. But as of SQLite version 3.3.0, out-of-memory recovery is - automatic and this routine now does nothing. THe interface is retained - to avoid link errors with legacy code. -} - -api {} { - int sqlite3_get_autocommit(sqlite3*); -} { - Test to see whether or not the database connection is in autocommit - mode. Return TRUE if it is and FALSE if not. Autocommit mode is on - by default. Autocommit is disabled by a BEGIN statement and reenabled - by the next COMMIT or ROLLBACK. -} - -api {} { - int sqlite3_clear_bindings(sqlite3_stmt*); -} { - Set all the parameters in the compiled SQL statement back to NULL. -} - -api {} { - sqlite3 *sqlite3_db_handle(sqlite3_stmt*); -} { - Return the sqlite3* database handle to which the prepared statement given - in the argument belongs. This is the same database handle that was - the first argument to the sqlite3_prepare() that was used to create - the statement in the first place. -} - -api {} { - void *sqlite3_update_hook( - sqlite3*, - void(*)(void *,int ,char const *,char const *,sqlite_int64), - void* - ); -} { - Register a callback function with the database connection identified by the - first argument to be invoked whenever a row is updated, inserted or deleted. - Any callback set by a previous call to this function for the same - database connection is overridden. - - The second argument is a pointer to the function to invoke when a - row is updated, inserted or deleted. The first argument to the callback is - a copy of the third argument to sqlite3_update_hook. The second callback - argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending - on the operation that caused the callback to be invoked. The third and - fourth arguments to the callback contain pointers to the database and - table name containing the affected row. The final callback parameter is - the rowid of the row. In the case of an update, this is the rowid after - the update takes place. - - The update hook is not invoked when internal system tables are - modified (i.e. sqlite_master and sqlite_sequence). - - If another function was previously registered, its pArg value is returned. - Otherwise NULL is returned. - - See also: sqlite3_commit_hook(), sqlite3_rollback_hook() -} - -api {} { - void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); -} { - Register a callback to be invoked whenever a transaction is rolled - back. - - The new callback function overrides any existing rollback-hook - callback. If there was an existing callback, then it's pArg value - (the third argument to sqlite3_rollback_hook() when it was registered) - is returned. Otherwise, NULL is returned. - - For the purposes of this API, a transaction is said to have been - rolled back if an explicit "ROLLBACK" statement is executed, or - an error or constraint causes an implicit rollback to occur. The - callback is not invoked if a transaction is automatically rolled - back because the database connection is closed. -} - -api {} { - int sqlite3_enable_shared_cache(int); -} { - This routine enables or disables the sharing of the database cache - and schema data structures between connections to the same database. - Sharing is enabled if the argument is true and disabled if the argument - is false. - - Cache sharing is enabled and disabled on a thread-by-thread basis. - Each call to this routine enables or disables cache sharing only for - connections created in the same thread in which this routine is called. - There is no mechanism for sharing cache between database connections - running in different threads. - - Sharing must be disabled prior to shutting down a thread or else - the thread will leak memory. Call this routine with an argument of - 0 to turn off sharing. Or use the sqlite3_thread_cleanup() API. - - This routine must not be called when any database connections - are active in the current thread. Enabling or disabling shared - cache while there are active database connections will result - in memory corruption. - - When the shared cache is enabled, the - following routines must always be called from the same thread: - sqlite3_open(), sqlite3_prepare_v2(), sqlite3_step(), sqlite3_reset(), - sqlite3_finalize(), and sqlite3_close(). - This is due to the fact that the shared cache makes use of - thread-specific storage so that it will be available for sharing - with other connections. - - Virtual tables cannot be used with a shared cache. When shared - cache is enabled, the sqlite3_create_module() API used to register - virtual tables will always return an error. - - This routine returns SQLITE_OK if shared cache was - enabled or disabled successfully. An error code is returned - otherwise. - - Shared cache is disabled by default for backward compatibility. -} - -api {} { - void sqlite3_thread_cleanup(void); -} { - This routine makes sure that all thread local storage used by SQLite - in the current thread has been deallocated. A thread can call this - routine prior to terminating in order to make sure there are no memory - leaks. - - This routine is not strictly necessary. If cache sharing has been - disabled using sqlite3_enable_shared_cache() and if all database - connections have been closed and if SQLITE_ENABLE_MEMORY_MANAGMENT is - on and all memory has been freed, then the thread local storage will - already have been automatically deallocated. This routine is provided - as a convenience to the program who just wants to make sure that there - are no leaks. -} - -api {} { - int sqlite3_release_memory(int N); -} { - This routine attempts to free at least N bytes of memory from the caches - of database connecions that were created in the same thread from which this - routine is called. The value returned is the number of bytes actually - freed. - - This routine is only available if memory management has been enabled - by compiling with the SQLITE_ENABLE_MEMORY_MANAGMENT macro. -} - -api {} { - void sqlite3_soft_heap_limit(int N); -} { - This routine sets the soft heap limit for the current thread to N. - If the total heap usage by SQLite in the current thread exceeds N, - then sqlite3_release_memory() is called to try to reduce the memory usage - below the soft limit. - - Prior to shutting down a thread sqlite3_soft_heap_limit() must be set to - zero (the default) or else the thread will leak memory. Alternatively, use - the sqlite3_thread_cleanup() API. - - A negative or zero value for N means that there is no soft heap limit and - sqlite3_release_memory() will only be called when memory is exhaused. - The default value for the soft heap limit is zero. - - SQLite makes a best effort to honor the soft heap limit. But if it - is unable to reduce memory usage below the soft limit, execution will - continue without error or notification. This is why the limit is - called a "soft" limit. It is advisory only. - - This routine is only available if memory management has been enabled - by compiling with the SQLITE_ENABLE_MEMORY_MANAGMENT macro. -} - -api {} { - void sqlite3_thread_cleanup(void); -} { - This routine ensures that a thread that has used SQLite in the past - has released any thread-local storage it might have allocated. - When the rest of the API is used properly, the cleanup of - thread-local storage should be completely automatic. You should - never really need to invoke this API. But it is provided to you - as a precaution and as a potential work-around for future - thread-releated memory-leaks. -} - -set n 0 -set i 0 -foreach item $apilist { - set namelist [lindex $item 0] - foreach name $namelist { - set n_to_name($n) $name - set n_to_idx($n) $i - set name_to_idx($name) $i - incr n - } - incr i -} -set i 0 -foreach name [lsort [array names name_to_idx]] { - set sname($i) $name - incr i -} -#parray n_to_name -#parray n_to_idx -#parray name_to_idx -#parray sname -incr n -1 -puts "<DIV class=pdf_ignore>" -puts {<table width="100%" cellpadding="5"><tr>} -set nrow [expr {($n+2)/3}] -set i 0 -for {set j 0} {$j<3} {incr j} { - if {$j>0} {puts {<td width="10"></td>}} - puts {<td valign="top">} - set limit [expr {$i+$nrow}] - puts {<ul>} - while {$i<$limit && $i<$n} { - set name $sname($i) - if {[regexp {^sqlite} $name]} {set display $name} {set display <i>$name</i>} - puts "<li><a href=\"#$name\">$display</a></li>" - incr i - } - puts {</ul></td>} -} -puts "</table>" -puts "<!-- $n entries. $nrow rows in 3 columns -->" -puts "</DIV>" - -proc resolve_name {ignore_list name} { - global name_to_idx - if {![info exists name_to_idx($name)] || [lsearch $ignore_list $name]>=0} { - return $name - } else { - return "<a href=\"#$name\">$name</a>" - } -} - -foreach name [lsort [array names name_to_idx]] { - set i $name_to_idx($name) - if {[info exists done($i)]} continue - set done($i) 1 - foreach {namelist prototype desc} [lindex $apilist $i] break - foreach name $namelist { - puts "<a name=\"$name\"></a>" - } - puts "<p><hr></p>" - puts "<blockquote><pre>" - regsub "^( *\n)+" $prototype {} p2 - regsub "(\n *)+\$" $p2 {} p3 - puts $p3 - puts "</pre></blockquote>" - regsub -all {\[} $desc {\[} desc - regsub -all {sqlite3_[a-z0-9_]+} $desc "\[resolve_name $name &\]" d2 - foreach x $specialname { - regsub -all $x $d2 "\[resolve_name $name &\]" d2 - } - regsub -all "\n( *\n)+" [subst $d2] "</p>\n\n<p>" d3 - puts "<p>$d3</p>" -} - -puts "<DIV class=pdf_ignore>" -footer $rcsid -puts "</DIV>" diff --git a/third_party/sqlite/test.patch b/third_party/sqlite/test.patch new file mode 100644 index 0000000..28c98d3 --- /dev/null +++ b/third_party/sqlite/test.patch @@ -0,0 +1,167 @@ +Index: Makefile.linux-gcc +=================================================================== +--- Makefile.linux-gcc 2009-09-03 13:32:06.000000000 -0700 ++++ Makefile.linux-gcc 2009-07-01 12:08:39.000000000 -0700 +@@ -14,7 +14,7 @@ + #### The toplevel directory of the source tree. This is the directory + # that contains this "Makefile.in" and the "configure.in" script. + # +-TOP = ../sqlite ++TOP = .. + + #### C Compiler and options for use in building executables that + # will run on the platform that is doing the build. +@@ -33,13 +33,13 @@ + # appropriately: + # + #THREADSAFE = -DTHREADSAFE=1 +-THREADSAFE = -DTHREADSAFE=0 ++THREADSAFE = -DTHREADSAFE=1 + + #### Specify any extra linker options needed to make the library + # thread safe + # + #THREADLIB = -lpthread +-THREADLIB = ++THREADLIB = -lpthread + + #### Specify any extra libraries needed to access required functions. + # +@@ -57,8 +57,28 @@ + #OPTS = -DSQLITE_DEBUG=2 + #OPTS = -DSQLITE_DEBUG=1 + #OPTS = +-OPTS = -DNDEBUG=1 +-OPTS += -DHAVE_FDATASYNC=1 ++ ++# These flags match those for SQLITE_CFLAGS in config.mk. ++ ++OPTS += -DNDEBUG ++OPTS += -DSQLITE_CORE ++OPTS += -DSQLITE_ENABLE_FTS2 -DSQLITE_ENABLE_BROKEN_FTS2 ++OPTS += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 ++OPTS += -DHAVE_USLEEP=1 ++ ++# Additional SQLite tests. ++OPTS += -DSQLITE_MEMDEBUG=1 ++ ++# Don't include these ones, they break the SQLite tests. ++# -DSQLITE_OMIT_ATTACH=1 \ ++# -DSQLITE_OMIT_LOAD_EXTENSION=1 \ ++# -DSQLITE_OMIT_VACUUM=1 \ ++# -DSQLITE_TRANSACTION_DEFAULT_IMMEDIATE=1 \ ++ ++SHELL_ICU = $(TOP)/src/shell_icu_linux.c -licuuc ++ ++# TODO(shess) I can't see why I need this setting. ++OPTS += -DOS_UNIX=1 + + #### The suffix to add to executable files. ".exe" for windows. + # Nothing for unix. +@@ -91,16 +112,16 @@ + + #### Extra compiler options needed for programs that use the TCL library. + # +-#TCL_FLAGS = ++TCL_FLAGS = -I/usr/include/tcl8.4 + #TCL_FLAGS = -DSTATIC_BUILD=1 +-TCL_FLAGS = -I/home/drh/tcltk/8.4linux ++#TCL_FLAGS = -I/home/drh/tcltk/8.4linux + #TCL_FLAGS = -I/home/drh/tcltk/8.4win -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.4linux/libtcl8.4g.a -lm -ldl ++LIBTCL = -ltcl8.4 -lm -ldl ++#LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl + #LIBTCL = /home/drh/tcltk/8.4win/libtcl84s.a -lmsvcrt + #LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc + +Index: main.mk +=================================================================== +--- main.mk 2009-09-10 12:18:17.000000000 -0700 ++++ main.mk 2009-09-15 11:45:21.000000000 -0700 +@@ -69,6 +69,12 @@ + walker.o where.o utf.o vtab.o + + ++LIBOBJ += fts2.o \ ++ fts2_hash.o \ ++ fts2_icu.o \ ++ fts2_porter.o \ ++ fts2_tokenizer.o \ ++ fts2_tokenizer1.o + + # All of the source code files. + # +@@ -243,6 +253,17 @@ + $(TOP)/src/test_thread.c \ + $(TOP)/src/test_wsd.c + ++TESTSRC += \ ++ $(TOP)/ext/fts2/fts2.c \ ++ $(TOP)/ext/fts2/fts2.h \ ++ $(TOP)/ext/fts2/fts2_hash.c \ ++ $(TOP)/ext/fts2/fts2_hash.h \ ++ $(TOP)/ext/fts2/fts2_icu.c \ ++ $(TOP)/ext/fts2/fts2_porter.c \ ++ $(TOP)/ext/fts2/fts2_tokenizer.h \ ++ $(TOP)/ext/fts2/fts2_tokenizer.c \ ++ $(TOP)/ext/fts2/fts2_tokenizer1.c ++ + #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c + #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c + +@@ -314,8 +343,8 @@ + + sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h + $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \ +- $(TOP)/src/shell.c \ +- libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) ++ $(TOP)/src/shell.c $(SHELL_ICU) \ ++ libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) -ldl + + objects: $(LIBOBJ_ORIG) + +@@ -484,6 +527,12 @@ + test: testfixture$(EXE) sqlite3$(EXE) + ./testfixture$(EXE) $(TOP)/test/veryquick.test + ++ftstest: testfixture$(EXE) sqlite3$(EXE) ++ ./testfixture$(EXE) $(TOP)/test/fts.test ++ ++fts2test: testfixture$(EXE) sqlite3$(EXE) ++ ./testfixture$(EXE) $(TOP)/test/fts2.test ++ + sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \ + $(TOP)/tool/spaceanal.tcl + sed \ +Index: src/test_autoext.c +=================================================================== +--- src/test_autoext.c 2009-09-03 13:32:06.000000000 -0700 ++++ src/test_autoext.c 2009-09-15 18:14:35.000000000 -0700 +@@ -17,7 +17,9 @@ + #include "sqlite3ext.h" + + #ifndef SQLITE_OMIT_LOAD_EXTENSION ++#ifndef SQLITE_CORE + static SQLITE_EXTENSION_INIT1 ++#endif + + /* + ** The sqr() SQL function returns the square of its input value. +Index: src/quick.test +=================================================================== +--- test/quick.test 2009-09-04 13:37:44.000000000 -0700 ++++ test/quick.test 2009-09-15 11:34:54.000000000 -0700 +@@ -58,6 +58,8 @@ + crash7.test + delete3.test + fts3.test ++ fts.test ++ fts2.test + fuzz.test + fuzz3.test + fuzz_malloc.test diff --git a/third_party/sqlite/webdb.patch b/third_party/sqlite/webdb.patch new file mode 100644 index 0000000..226ca5b --- /dev/null +++ b/third_party/sqlite/webdb.patch @@ -0,0 +1,163 @@ +The WebDatabase implementation in the renderer users a custom vfs to +broker file open and other requests. This modifies the built-in vfs +implementation to let that code share much of the implementation +details. + +diff --git src/os_unix.c src/os_unix.c +index ef04a72..e5e1509 100644 +--- src/os_unix.c ++++ src/os_unix.c +@@ -3496,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); + */ + + /* ++** Initializes a unixFile structure with zeros. ++*/ ++void initUnixFile(sqlite3_file* file) { ++ memset(file, 0, sizeof(unixFile)); ++} ++ ++/* + ** Initialize the contents of the unixFile structure pointed to by pId. + */ +-static int fillInUnixFile( ++int fillInUnixFile( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + int h, /* Open file descriptor of file being opened */ + int dirfd, /* Directory file descriptor */ +@@ -3812,6 +3819,73 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + } + + /* ++** Initializes a unixFile structure with zeros. ++*/ ++void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { ++ memset(file, 0, sizeof(unixFile)); ++} ++ ++int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, ++ int fd, ++ int dirfd, ++ sqlite3_file* file, ++ const char* fileName, ++ int noLock, ++ int isDelete) { ++ return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete); ++} ++ ++/* ++** Search for an unused file descriptor that was opened on the database file. ++** If a suitable file descriptor if found, then it is stored in *fd; otherwise, ++** *fd is not modified. ++** ++** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot ++** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. ++*/ ++int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, ++ const char* fileName, ++ int flags, ++ int* fd) { ++ unixFile* unixSQLite3File = (unixFile*)file; ++ int fileType = flags & 0xFFFFFF00; ++ if (fileType == SQLITE_OPEN_MAIN_DB) { ++ UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); ++ if (unusedFd) { ++ *fd = unusedFd->fd; ++ } else { ++ unusedFd = sqlite3_malloc(sizeof(*unusedFd)); ++ if (!unusedFd) { ++ return SQLITE_NOMEM; ++ } ++ } ++ unixSQLite3File->pUnused = unusedFd; ++ } ++ return SQLITE_OK; ++} ++ ++/* ++** Marks 'fd' as the unused file descriptor for 'pFile'. ++*/ ++void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, ++ int fd, ++ int flags) { ++ unixFile* unixSQLite3File = (unixFile*)file; ++ if (unixSQLite3File->pUnused) { ++ unixSQLite3File->pUnused->fd = fd; ++ unixSQLite3File->pUnused->flags = flags; ++ } ++} ++ ++/* ++** Destroys pFile's field that keeps track of the unused file descriptor. ++*/ ++void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { ++ unixFile* unixSQLite3File = (unixFile*)file; ++ sqlite3_free(unixSQLite3File->pUnused); ++} ++ ++/* + ** Open the file zPath. + ** + ** Previously, the SQLite OS layer used three functions in place of this +@@ -3893,20 +3967,13 @@ static int unixOpen( + || eType==SQLITE_OPEN_TRANSIENT_DB + ); + +- memset(p, 0, sizeof(unixFile)); ++ chromium_sqlite3_initialize_unix_sqlite3_file(pFile); + + if( eType==SQLITE_OPEN_MAIN_DB ){ +- UnixUnusedFd *pUnused; +- pUnused = findReusableFd(zName, flags); +- if( pUnused ){ +- fd = pUnused->fd; +- }else{ +- pUnused = sqlite3_malloc(sizeof(*pUnused)); +- if( !pUnused ){ +- return SQLITE_NOMEM; +- } ++ rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); ++ if( rc!=SQLITE_OK ){ ++ return rc; + } +- p->pUnused = pUnused; + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ + assert(isDelete && !isOpenDirectory); +@@ -3949,10 +4016,7 @@ static int unixOpen( + *pOutFlags = flags; + } + +- if( p->pUnused ){ +- p->pUnused->fd = fd; +- p->pUnused->flags = flags; +- } ++ chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); + + if( isDelete ){ + #if OS_VXWORKS +@@ -4028,7 +4092,7 @@ static int unixOpen( + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + open_finished: + if( rc!=SQLITE_OK ){ +- sqlite3_free(p->pUnused); ++ chromium_sqlite3_destroy_reusable_file_handle(pFile); + } + return rc; + } +diff --git src/os_win.c src/os_win.c +index bc03a4b..06539d7 100644 +--- src/os_win.c ++++ src/os_win.c +@@ -1890,4 +1890,11 @@ int sqlite3_os_end(void){ + return SQLITE_OK; + } + ++void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { ++ winFile* winSQLite3File = (winFile*)file; ++ memset(file, 0, sizeof(*file)); ++ winSQLite3File->pMethod = &winIoMethod; ++ winSQLite3File->h = handle; ++} ++ + #endif /* SQLITE_OS_WIN */ |