1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Merge latest trunk changes into this branch.

FossilOrigin-Name: 2b3945e6a597e6853cac567052e92926c8cb6d7a029ac64c2d45c321bbe2e94d
This commit is contained in:
dan
2024-10-02 11:11:29 +00:00
40 changed files with 2483 additions and 1715 deletions

View File

@@ -694,8 +694,8 @@ sqlite3$(TEXE): shell.c sqlite3.c
shell.c sqlite3.c \ shell.c sqlite3.c \
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.lo sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) $(LTLINK) -I$(TOP)/ext/misc -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS)
dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS)
@@ -1187,8 +1187,6 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
# Source and header files that shell.c depends on # Source and header files that shell.c depends on
SHELL_DEP = \ SHELL_DEP = \
$(TOP)/src/shell.c.in \ $(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/intck/sqlite3intck.c \ $(TOP)/ext/intck/sqlite3intck.c \
@@ -1208,6 +1206,8 @@ SHELL_DEP = \
$(TOP)/ext/misc/sha1.c \ $(TOP)/ext/misc/sha1.c \
$(TOP)/ext/misc/shathree.c \ $(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \ $(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/sqlite3_stdio.c \
$(TOP)/ext/misc/sqlite3_stdio.h \
$(TOP)/ext/misc/uint.c \ $(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/vfstrace.c \ $(TOP)/ext/misc/vfstrace.c \
$(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/misc/zipfile.c \

View File

@@ -1861,8 +1861,8 @@ $(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLIT
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# <<mark>> # <<mark>>
sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\consio\console_io.h $(TOP)\ext\consio\console_io.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -I$(TOP)\ext\consio $(TOP)\tool\sqldiff.c $(TOP)\ext\consio\console_io.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -I$(TOP)\ext\misc $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS)
dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H) dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2316,8 +2316,6 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
# Source and header files that shell.c depends on # Source and header files that shell.c depends on
SHELL_DEP = \ SHELL_DEP = \
$(TOP)\src\shell.c.in \ $(TOP)\src\shell.c.in \
$(TOP)\ext\consio\console_io.c \
$(TOP)\ext\consio\console_io.h \
$(TOP)\ext\expert\sqlite3expert.c \ $(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \ $(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\intck\sqlite3intck.c \ $(TOP)\ext\intck\sqlite3intck.c \
@@ -2337,6 +2335,8 @@ SHELL_DEP = \
$(TOP)\ext\misc\sha1.c \ $(TOP)\ext\misc\sha1.c \
$(TOP)\ext\misc\shathree.c \ $(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\sqlar.c \ $(TOP)\ext\misc\sqlar.c \
$(TOP)\ext\misc\sqlite3_stdio.c \
$(TOP)\ext\misc\sqlite3_stdio.h \
$(TOP)\ext\misc\uint.c \ $(TOP)\ext\misc\uint.c \
$(TOP)\ext\misc\vfstrace.c \ $(TOP)\ext\misc\vfstrace.c \
$(TOP)\ext\misc\zipfile.c \ $(TOP)\ext\misc\zipfile.c \
@@ -2624,7 +2624,7 @@ smoketest: $(TESTPROGS)
shelltest: $(TESTPROGS) shelltest: $(TESTPROGS)
.\testfixture.exe $(TOP)\test\permutations.test shell .\testfixture.exe $(TOP)\test\permutations.test shell
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\consio\console_io.h $(TOP)\ext\consio\console_io.c $(SQLITE_TCL_DEP) sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP)
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@ $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)

View File

@@ -4889,6 +4889,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){
nBest = nPercent; nBest = nPercent;
} }
} }
/* If pLvl is already the input level to an ongoing merge, look no
** further for a merge candidate. The caller should be allowed to
** continue merging from pLvl first. */
if( pLvl->nMerge ) break;
} }
} }
return iRet; return iRet;
@@ -8813,7 +8818,7 @@ static int fts5structConnectMethod(
/* /*
** We must have a single struct=? constraint that will be passed through ** We must have a single struct=? constraint that will be passed through
** into the xFilter method. If there is no valid stmt=? constraint, ** into the xFilter method. If there is no valid struct=? constraint,
** then return an SQLITE_CONSTRAINT error. ** then return an SQLITE_CONSTRAINT error.
*/ */
static int fts5structBestIndexMethod( static int fts5structBestIndexMethod(

View File

@@ -35,8 +35,8 @@ do_execsql_test 1.01 {
} }
# explain_i "UPDATE t1 SET a='a' WHERE t1.rowid=1" # explain_i "UPDATE t1 SET a='a' WHERE t1.rowid=1"
breakpoint #breakpoint
explain_i "UPDATE t1 SET a='a' FROM t2 WHERE t1.rowid=1 AND b IS NULL" #explain_i "UPDATE t1 SET a='a' FROM t2 WHERE t1.rowid=1 AND b IS NULL"
#breakpoint #breakpoint
#explain_i "UPDATE t1 SET a='a' WHERE b IS NULL AND rowid=?" #explain_i "UPDATE t1 SET a='a' WHERE b IS NULL AND rowid=?"
@@ -56,4 +56,56 @@ foreach {tn up err} {
do_catchsql_test 1.$tn $up $res($err) do_catchsql_test 1.$tn $up $res($err)
} }
#-------------------------------------------------------------------------
reset_db
proc random {n} { expr {abs(int(rand()*$n))} }
proc select_one {list} {
set n [llength $list]
lindex $list [random $n]
}
proc vocab {} {
list abc def ghi jkl mno pqr stu vwx yza
}
proc term {} {
select_one [vocab]
}
proc document {} {
set nTerm [expr [random 3] + 7]
set doc ""
for {set ii 0} {$ii < $nTerm} {incr ii} {
lappend doc [term]
}
set doc
}
db func document document
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE ft USING fts5(a, contentless_delete=1, content='');
INSERT INTO ft(ft, rank) VALUES('pgsz', 64);
}
do_test 2.1 {
for {set ii 1} {$ii < 12} {incr ii} {
db transaction {
for {set jj 0} {$jj < 10} {incr jj} {
set doc [document]
execsql { INSERT INTO ft VALUES($doc); }
}
}
}
} {}
do_test 2.2 {
foreach r [db eval {SELECT rowid FROM ft}] {
execsql { DELETE FROM ft WHERE rowid=$r }
}
} {}
set doc [document]
do_execsql_test 2.3 {
INSERT INTO ft VALUES($doc)
}
finish_test finish_test

View File

@@ -110,6 +110,13 @@ SQLITE_EXTENSION_INIT1
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
/* When used as part of the CLI, the sqlite3_stdio.h module will have
** been included before this one. In that case use the sqlite3_stdio.h
** #defines. If not, create our own for fopen().
*/
#ifndef _SQLITE3_STDIO_H_
# define sqlite3_fopen fopen
#endif
/* /*
** Structure of the fsdir() table-valued function ** Structure of the fsdir() table-valued function
@@ -142,7 +149,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){
sqlite3 *db; sqlite3 *db;
int mxBlob; int mxBlob;
in = fopen(zName, "rb"); in = sqlite3_fopen(zName, "rb");
if( in==0 ){ if( in==0 ){
/* File does not exist or is unreadable. Leave the result set to NULL. */ /* File does not exist or is unreadable. Leave the result set to NULL. */
return; return;
@@ -397,7 +404,7 @@ static int writeFile(
sqlite3_int64 nWrite = 0; sqlite3_int64 nWrite = 0;
const char *z; const char *z;
int rc = 0; int rc = 0;
FILE *out = fopen(zFile, "wb"); FILE *out = sqlite3_fopen(zFile, "wb");
if( out==0 ) return 1; if( out==0 ) return 1;
z = (const char*)sqlite3_value_blob(pData); z = (const char*)sqlite3_value_blob(pData);
if( z ){ if( z ){

View File

@@ -351,7 +351,7 @@ static int substituteCost(char cPrev, char cFrom, char cTo){
** Negative values indicate an error: ** Negative values indicate an error:
** -1 One of the inputs is NULL ** -1 One of the inputs is NULL
** -2 Non-ASCII characters on input ** -2 Non-ASCII characters on input
** -3 Unable to allocate memory ** -3 Unable to allocate memory
** **
** If pnMatch is not NULL, then *pnMatch is set to the number of bytes ** If pnMatch is not NULL, then *pnMatch is set to the number of bytes
** of zB that matched the pattern in zA. If zA does not end with a '*', ** of zB that matched the pattern in zA. If zA does not end with a '*',
@@ -360,8 +360,8 @@ static int substituteCost(char cPrev, char cFrom, char cTo){
** of zB that was deemed to match zA. ** of zB that was deemed to match zA.
*/ */
static int editdist1(const char *zA, const char *zB, int *pnMatch){ static int editdist1(const char *zA, const char *zB, int *pnMatch){
int nA, nB; /* Number of characters in zA[] and zB[] */ unsigned int nA, nB; /* Number of characters in zA[] and zB[] */
int xA, xB; /* Loop counters for zA[] and zB[] */ unsigned int xA, xB; /* Loop counters for zA[] and zB[] */
char cA = 0, cB; /* Current character of zA and zB */ char cA = 0, cB; /* Current character of zA and zB */
char cAprev, cBprev; /* Previous character of zA and zB */ char cAprev, cBprev; /* Previous character of zA and zB */
char cAnext, cBnext; /* Next character in zA and zB */ char cAnext, cBnext; /* Next character in zA and zB */
@@ -3021,7 +3021,7 @@ static sqlite3_module spellfix1Module = {
*/ */
static int spellfix1Register(sqlite3 *db){ static int spellfix1Register(sqlite3 *db){
int rc = SQLITE_OK; int rc = SQLITE_OK;
int i; unsigned int i;
rc = sqlite3_create_function(db, "spellfix1_translit", 1, rc = sqlite3_create_function(db, "spellfix1_translit", 1,
SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0,
transliterateSqlFunc, 0, 0); transliterateSqlFunc, 0, 0);

211
ext/misc/sqlite3_stdio.c Normal file
View File

@@ -0,0 +1,211 @@
/*
** 2024-09-24
**
** 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.
**
*************************************************************************
**
** Implementation of standard I/O interfaces for UTF-8 that are missing
** on Windows.
*/
#ifdef _WIN32 /* This file is a no-op on all platforms except Windows */
#ifndef _SQLITE3_STDIO_H_
#include "sqlite3_stdio.h"
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>
#include <stdarg.h>
#include <io.h>
#include <fcntl.h>
/*
** If the SQLITE_U8TEXT_ONLY option is defined, then only use
** _O_U8TEXT, _O_WTEXT, and similar together with the UTF-16
** interfaces to the Windows CRT. The use of ANSI-only routines
** like fputs() and ANSI modes like _O_TEXT and _O_BINARY is
** avoided.
**
** The downside of using SQLITE_U8TEXT_ONLY is that it becomes
** impossible to output a bare newline character (0x0a) - that is,
** a newline that is not preceded by a carriage return (0x0d).
** And without that capability, sometimes the output will be slightly
** incorrect, as extra 0x0d characters will have been inserted where
** they do not belong.
**
** The SQLITE_U8TEXT_STDIO compile-time option is a compromise.
** It always enables _O_WTEXT or similar for stdin, stdout, stderr,
** but allows other streams to be _O_TEXT and/or O_BINARY. The
** SQLITE_U8TEXT_STDIO option has the same downside as SQLITE_U8TEXT_ONLY
** in that stray 0x0d characters might appear where they ought not, but
** at least with this option those characters only appear on standard
** I/O streams, and not on new streams that might be created by the
** application using sqlite3_fopen() or sqlite3_popen().
*/
#if defined(SQLITE_U8TEXT_ONLY)
# define UseWtextForOutput(fd) 1
# define UseWtextForInput(fd) 1
# define IsConsole(fd) _isatty(_fileno(fd))
#elif defined(SQLITE_U8TEXT_STDIO)
# define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr)
# define UseWtextForInput(fd) ((fd)==stdin)
# define IsConsole(fd) _isatty(_fileno(fd))
#else
# define UseWtextForOutput(fd) _isatty(_fileno(fd))
# define UseWtextForInput(fd) _isatty(_fileno(fd))
# define IsConsole(fd) 1
#endif
/*
** Work-alike for the fopen() routine from the standard C library.
*/
FILE *sqlite3_fopen(const char *zFilename, const char *zMode){
FILE *fp = 0;
wchar_t *b1, *b2;
int sz1, sz2;
sz1 = (int)strlen(zFilename);
sz2 = (int)strlen(zMode);
b1 = malloc( (sz1+1)*sizeof(b1[0]) );
b2 = malloc( (sz2+1)*sizeof(b1[0]) );
if( b1 && b2 ){
sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1);
b1[sz1] = 0;
sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2);
b2[sz2] = 0;
fp = _wfopen(b1, b2);
}
free(b1);
free(b2);
return fp;
}
/*
** Work-alike for the popen() routine from the standard C library.
*/
FILE *sqlite3_popen(const char *zCommand, const char *zMode){
FILE *fp = 0;
wchar_t *b1, *b2;
int sz1, sz2;
sz1 = (int)strlen(zCommand);
sz2 = (int)strlen(zMode);
b1 = malloc( (sz1+1)*sizeof(b1[0]) );
b2 = malloc( (sz2+1)*sizeof(b1[0]) );
if( b1 && b2 ){
sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1);
b1[sz1] = 0;
sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2);
b2[sz2] = 0;
fp = _wpopen(b1, b2);
}
free(b1);
free(b2);
return fp;
}
/*
** Work-alike for fgets() from the standard C library.
*/
char *sqlite3_fgets(char *buf, int sz, FILE *in){
if( UseWtextForInput(in) ){
/* When reading from the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode to read UTF-16 characters, then translate
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
sqlite3_free(b1);
return 0;
}
WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
sqlite3_free(b1);
return buf;
}else{
/* Reading from a file or other input source, just read bytes without
** any translation. */
return fgets(buf, sz, in);
}
}
/*
** Work-alike for fputs() from the standard C library.
*/
int sqlite3_fputs(const char *z, FILE *out){
if( UseWtextForOutput(out) ){
/* When writing to the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode and write UTF-16 characters.
*/
int sz = (int)strlen(z);
wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
_setmode(_fileno(out), _O_U8TEXT);
fputws(b1, out);
sqlite3_free(b1);
return 0;
}else{
/* Writing to a file or other destination, just write bytes without
** any translation. */
return fputs(z, out);
}
}
/*
** Work-alike for fprintf() from the standard C library.
*/
int sqlite3_fprintf(FILE *out, const char *zFormat, ...){
int rc;
if( UseWtextForOutput(out) ){
/* When writing to the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode and write UTF-16 characters.
*/
char *z;
va_list ap;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
sqlite3_fputs(z, out);
rc = (int)strlen(z);
sqlite3_free(z);
}else{
/* Writing to a file or other destination, just write bytes without
** any translation. */
va_list ap;
va_start(ap, zFormat);
rc = vfprintf(out, zFormat, ap);
va_end(ap);
}
return rc;
}
/*
** Set the mode for an output stream. mode argument is typically _O_BINARY or
** _O_TEXT.
*/
void sqlite3_fsetmode(FILE *fp, int mode){
if( !UseWtextForOutput(fp) ){
fflush(fp);
_setmode(_fileno(fp), mode);
}
}
#endif /* defined(_WIN32) */

55
ext/misc/sqlite3_stdio.h Normal file
View File

@@ -0,0 +1,55 @@
/*
** 2024-09-24
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This header file contains definitions of interfaces that provide
** cross-platform I/O for UTF-8 content.
**
** On most platforms, the interfaces definitions in this file are
** just #defines. For example sqlite3_fopen() is a macro that resolves
** to the standard fopen() in the C-library.
**
** But Windows does not have a standard C-library, at least not one that
** can handle UTF-8. So for windows build, the interfaces resolve to new
** C-language routines contained in the separate sqlite3_stdio.c source file.
**
** So on all non-Windows platforms, simply #include this header file and
** use the interfaces defined herein. Then to run your application on Windows,
** also link in the accompanying sqlite3_stdio.c source file when compiling
** to get compatible interfaces.
*/
#ifndef _SQLITE3_STDIO_H_
#define _SQLITE3_STDIO_H_ 1
#ifdef _WIN32
/**** Definitions For Windows ****/
#include <stdio.h>
#include <windows.h>
FILE *sqlite3_fopen(const char *zFilename, const char *zMode);
FILE *sqlite3_popen(const char *zCommand, const char *type);
char *sqlite3_fgets(char *s, int size, FILE *stream);
int sqlite3_fputs(const char *s, FILE *stream);
int sqlite3_fprintf(FILE *stream, const char *format, ...);
void sqlite3_fsetmode(FILE *stream, int mode);
#else
/**** Definitions For All Other Platforms ****/
#include <stdio.h>
#define sqlite3_fopen fopen
#define sqlite3_popen popen
#define sqlite3_fgets fgets
#define sqlite3_fputs fputs
#define sqlite3_fprintf fprintf
#define sqlite3_fsetmode(F,X) /*no-op*/
#endif
#endif /* _SQLITE3_STDIO_H_ */

View File

@@ -35,6 +35,14 @@ SQLITE_EXTENSION_INIT1
#include <zlib.h> #include <zlib.h>
/* When used as part of the CLI, the sqlite3_stdio.h module will have
** been included before this one. In that case use the sqlite3_stdio.h
** #defines. If not, create our own for fopen().
*/
#ifndef _SQLITE3_STDIO_H_
# define sqlite3_fopen fopen
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
#ifndef SQLITE_AMALGAMATION #ifndef SQLITE_AMALGAMATION
@@ -1291,7 +1299,7 @@ static int zipfileFilter(
} }
if( 0==pTab->pWriteFd && 0==bInMemory ){ if( 0==pTab->pWriteFd && 0==bInMemory ){
pCsr->pFile = zFile ? fopen(zFile, "rb") : 0; pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0;
if( pCsr->pFile==0 ){ if( pCsr->pFile==0 ){
zipfileCursorErr(pCsr, "cannot open file: %s", zFile); zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
@@ -1481,7 +1489,7 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
** structure into memory. During the transaction any new file data is ** structure into memory. During the transaction any new file data is
** appended to the archive file, but the central directory is accumulated ** appended to the archive file, but the central directory is accumulated
** in main-memory until the transaction is committed. */ ** in main-memory until the transaction is committed. */
pTab->pWriteFd = fopen(pTab->zFile, "ab+"); pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+");
if( pTab->pWriteFd==0 ){ if( pTab->pWriteFd==0 ){
pTab->base.zErrMsg = sqlite3_mprintf( pTab->base.zErrMsg = sqlite3_mprintf(
"zipfile: failed to open file %s for writing", pTab->zFile "zipfile: failed to open file %s for writing", pTab->zFile

View File

@@ -15,8 +15,9 @@
# by the target name. Rebuild is necessary for all components to get # by the target name. Rebuild is necessary for all components to get
# the desired optimization level. # the desired optimization level.
# #
# quick, q = do just a minimal build (sqlite3.js/wasm, tester1) for # quick, q = do just build the essentials for testing
# faster development-mode turnaround. # (sqlite3.js/wasm, tester1) for faster development-mode
# turnaround.
# #
# dist = create end user deliverables. Add dist.build=oX to build # dist = create end user deliverables. Add dist.build=oX to build
# with a specific optimization level, where oX is one of the # with a specific optimization level, where oX is one of the
@@ -35,25 +36,21 @@
# - wasm-strip for release builds: https://github.com/WebAssembly/wabt # - wasm-strip for release builds: https://github.com/WebAssembly/wabt
# - InfoZip for 'dist' zip file # - InfoZip for 'dist' zip file
######################################################################## ########################################################################
#
# Significant TODOs for this build include, but are not necessarily
# limited to:
#
# 1) Consolidate the code generation for sqlite3*.*js into a script
# which generates the makefile code, rather than using $(call) and
# $(eval), or at least centralize the setup of the numerous vars
# related to each build variant $(JS_BUILD_MODES). (Update: an
# external script was attempted but generating properly-escaped
# makefile code from within a shell script is even less legible
# than the $(eval) indirection going on in this file.)
#
default: all default: all
#default: quick #default: quick
SHELL := $(shell which bash 2>/dev/null) SHELL := $(firstword $(wildcard /usr/local/bin/bash /usr/bin/bash /bin/bash))
ifeq (,$(SHELL))
$(error Cannot find the bash shell)
endif
MAKEFILE := $(lastword $(MAKEFILE_LIST)) MAKEFILE := $(lastword $(MAKEFILE_LIST))
CLEAN_FILES := CLEAN_FILES :=
DISTCLEAN_FILES := ./--dummy-- DISTCLEAN_FILES :=
release: oz MAKING_CLEAN := $(if $(filter %clean,$(MAKECMDGOALS)),1,0)
.PHONY: clean distclean
clean:
-rm -f $(CLEAN_FILES)
distclean: clean
-rm -f $(DISTCLEAN_FILES)
######################################################################## ########################################################################
# JS_BUILD_NAMES exists for documentation purposes only. It enumerates # JS_BUILD_NAMES exists for documentation purposes only. It enumerates
@@ -86,46 +83,6 @@ JS_BUILD_NAMES := sqlite3 sqlite3-wasmfs
# #
JS_BUILD_MODES := vanilla esm bunder-friendly node JS_BUILD_MODES := vanilla esm bunder-friendly node
########################################################################
# Emscripten SDK home dir and related binaries...
EMSDK_HOME ?= $(word 1,$(wildcard $(HOME)/emsdk $(HOME)/src/emsdk))
emcc.bin ?= $(word 1,$(wildcard $(EMSDK_HOME)/upstream/emscripten/emcc) $(shell which emcc))
ifeq (,$(emcc.bin))
$(error Cannot find emcc.)
endif
emcc.version := $(shell "$(emcc.bin)" --version | sed -n 1p \
| sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;')
ifeq (,$(emcc.version))
$(warning Cannot determine emcc version. This might unduly impact build flags.)
else
$(info using emcc version [$(emcc.version)])
endif
wasm-strip ?= $(shell which wasm-strip 2>/dev/null)
ifeq (,$(filter clean,$(MAKECMDGOALS)))
ifeq (,$(wasm-strip))
$(info WARNING: *******************************************************************)
$(info WARNING: builds using -O2/-O3/-Os/-Oz will minify WASM-exported names,)
$(info WARNING: breaking _All The Things_. The workaround for that is to build)
$(info WARNING: with -g3 (which explodes the file size) and then strip the debug)
$(info WARNING: info after compilation, using wasm-strip, to shrink the wasm file.)
$(info WARNING: wasm-strip was not found in the PATH so we cannot strip those.)
$(info WARNING: If this build uses any optimization level higher than -O1 then)
$(info WARNING: the ***resulting JS code WILL NOT BE USABLE***.)
$(info WARNING: wasm-strip is part of the wabt package:)
$(info WARNING: https://github.com/WebAssembly/wabt)
$(info WARNING: on Ubuntu-like systems it can be installed with:)
$(info WARNING: sudo apt install wabt)
$(info WARNING: *******************************************************************)
endif
endif # 'make clean' check
ifeq (,$(wasm-strip))
maybe-wasm-strip = echo "not wasm-stripping"
else
maybe-wasm-strip = $(wasm-strip)
endif
######################################################################## ########################################################################
# dir.top = the top dir of the canonical build tree, where # dir.top = the top dir of the canonical build tree, where
# sqlite3.[ch] live. # sqlite3.[ch] live.
@@ -141,41 +98,19 @@ dir.common := common
dir.fiddle := fiddle dir.fiddle := fiddle
dir.fiddle-debug := fiddle-debug dir.fiddle-debug := fiddle-debug
dir.tool := $(dir.top)/tool dir.tool := $(dir.top)/tool
CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ \ # dir.dout = output dir for deliverables
$(dir.fiddle-debug)/*
########################################################################
# dir.dout = output dir for deliverables.
#
# MAINTENANCE REMINDER: the output .js and .wasm files of certain emcc
# buildables must be in _this_ dir, rather than a subdir, or else
# parts of the generated code get confused and cannot load
# property. Specifically, when X.js loads X.wasm, whether or not X.js
# uses the correct path for X.wasm depends on how it's loaded: an HTML
# script tag will resolve it intuitively, whereas a Worker's call to
# importScripts() will not. That's a fundamental incompatibility with
# how URL resolution in JS happens between those two contexts. See:
#
# https://zzz.buzz/2017/03/14/relative-uris-in-web-development/
#
# We unfortunately have no way, from Worker-initiated code, to
# automatically resolve the path from X.js to X.wasm.
#
# We have an "only slightly unsightly" solution for our main builds
# but it does not work for the WASMFS builds, so those builds have to
# be built to _this_ directory and can only run when the client app is
# loaded from the same directory.
dir.dout := $(dir.wasm)/jswasm dir.dout := $(dir.wasm)/jswasm
# dir.tmp = output dir for intermediary build files, as opposed to # dir.tmp = output dir for intermediary build files, as opposed to
# end-user deliverables. # end-user deliverables.
dir.tmp := $(dir.wasm)/bld dir.tmp := $(dir.wasm)/bld
CLEAN_FILES += $(dir.tmp)/* $(dir.dout)/* dir.wasmfs := $(dir.dout)
ifeq (,$(wildcard $(dir.dout)))
dir._tmp := $(shell mkdir -p $(dir.dout)) MKDIR.bld := $(dir.tmp)
endif $(MKDIR.bld):
ifeq (,$(wildcard $(dir.tmp))) -mkdir -p $@ $(dir.dout)
dir._tmp := $(shell mkdir -p $(dir.tmp))
endif CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ \
$(dir.fiddle-debug)/* $(dir.dout)/* $(dir.tmp)/*
######################################################################## ########################################################################
# Set up sqlite3.c and sqlite3.h... # Set up sqlite3.c and sqlite3.h...
@@ -197,48 +132,14 @@ endif
sqlite3.canonical.c := $(dir.top)/sqlite3.c sqlite3.canonical.c := $(dir.top)/sqlite3.c
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c)) sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
sqlite3.h := $(dir.top)/sqlite3.h sqlite3.h := $(dir.top)/sqlite3.h
ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c) 2>/dev/null))
ifneq (1,$(MAKING_CLEAN))
ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c)))
SQLITE_C_IS_SEE := 0 SQLITE_C_IS_SEE := 0
else else
SQLITE_C_IS_SEE := 1 SQLITE_C_IS_SEE := 1
$(info This is an SEE build.) $(info This is an SEE build)
endif endif
# Most SQLITE_OPT flags are set in sqlite3-wasm.c but we need them
# made explicit here for building speedtest1.c.
SQLITE_OPT = \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_OFFSET_SQL_FUNC \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_UTF16 \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_TEMP_STORE=2 \
-DSQLITE_OS_KV_OPTIONAL=1 \
'-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
-DSQLITE_USE_URI=1 \
-DSQLITE_WASM_ENABLE_C_TESTS \
-DSQLITE_C=$(sqlite3.c)
#SQLITE_OPT += -DSQLITE_DEBUG
# Enabling SQLITE_DEBUG will break sqlite3_wasm_vfs_create_file()
# (and thus sqlite3_js_vfs_create_file()). Those functions are
# deprecated and alternatives are in place, but this crash behavior
# can be used to find errant uses of sqlite3_js_vfs_create_file()
# in client code.
########################################################################
# minimal=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
# goal being to create a WASM file with only the core APIs.
minimal ?= 0
ifeq (1,$(minimal))
SQLITE_OPT += -DSQLITE_WASM_MINIMAL
endif endif
########################################################################@ ########################################################################@
@@ -250,21 +151,180 @@ $(sqlite3.h):
$(MAKE) -C $(dir.top) sqlite3.c $(MAKE) -C $(dir.top) sqlite3.c
$(sqlite3.c): $(sqlite3.h) $(sqlite3.c): $(sqlite3.h)
.PHONY: clean distclean ########################################################################
clean: # Special-case builds for which we require certain pre-conditions
-rm -f $(CLEAN_FILES) # which, if not met, may cause warnings or fatal errors in the build.
distclean: clean # This also affects the default optimization level flags. Note that
-rm -f $(DISTCLEAN_FILES) # the fiddle targets are in this list because they are used for
# generating sqlite.org/fiddle.
OPTIMIZED_TARGETS := dist snapshot fiddle fiddle.debug
ifeq (release,$(filter release,$(MAKECMDGOALS))) ifneq (1,$(MAKING_CLEAN))
ifeq (,$(wasm-strip)) ifeq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS)))
$(error Cannot make release-quality binary because wasm-strip is not available. \ $(info ==============================================================)
See notes in the warning above) $(info == Development build. Make one of (dist, snapshot) for a)
$(info == smaller release build.)
$(info ==============================================================)
endif endif
else
$(info Development build. Use '$(MAKE) release' for a smaller release build.)
endif endif
########################################################################
# Find emcc (Emscripten compiler)...
ifeq (1,$(MAKING_CLEAN))
emcc.bin := echo
emcc.version := unknown
else
emcc.bin := $(shell which emcc 2>/dev/null)
ifeq (,$(emcc.bin))
ifneq (,$(EMSDK_HOME))
emcc.bin := $(wildcard $(EMSDK_HOME)/upstream/emscripten/emcc)
endif
ifeq (,$(emcc.bin))
$(error Cannot find emcc in path.)
endif
endif
emcc.version := $(shell $(emcc.bin) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;')
$(info using emcc version [$(emcc.version)])
endif
#########################################################################
# Find wasm-strip, which we need for release builds (see below for
# why) but not strictly for non-release builds.
ifeq (1,$(MAKING_CLEAN))
wasm-strip-bin := irrelevant
else
wasm-strip.bin ?= $(shell which wasm-strip 2>/dev/null)
ifeq (,$(wasm-strip.bin))
$(info WARNING: *******************************************************************)
$(info WARNING: Builds using -O2/-O3/-Os/-Oz will minify WASM-exported names,)
$(info WARNING: breaking _All The Things_. The workaround for that is to build)
$(info WARNING: with -g3 (which explodes the file size) and then strip the debug)
$(info WARNING: info after compilation, using wasm-strip, to shrink the wasm file.)
$(info WARNING: wasm-strip was not found in the PATH so we cannot strip those.)
$(info WARNING: If this build uses any optimization level higher than -O1 then)
$(info WARNING: the ***resulting JS code WILL NOT BE USABLE***.)
$(info WARNING: wasm-strip is part of the wabt package:)
$(info WARNING: https://github.com/WebAssembly/wabt)
$(info WARNING: on Ubuntu-like systems it can be installed with:)
$(info WARNING: sudo apt install wabt)
$(info WARNING: *******************************************************************)
ifneq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS)))
$(error Cannot make release-quality binary because wasm-strip is not available.)
endif
wasm-strip.bin := echo "not wasm-stripping"
endif
endif
maybe-wasm-strip := $(wasm-strip.bin)
########################################################################
# barebones=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
# goal being to create a WASM file with only the core APIs.
ifeq (1,$(barebones))
wasm-bare-bones := 1
$(info ==============================================================)
$(info == This is a bare-bones build. It trades away features for)
$(info == a smaller .wasm file.)
$(info ==============================================================)
else
wasm-bare-bones := 0
endif
undefine barebones
# Common options for building sqlite3-wasm.c and speedtest1.c.
# Explicit ENABLEs...
SQLITE_OPT.common := \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_TEMP_STORE=2 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_OS_KV_OPTIONAL=1 \
'-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
-DSQLITE_USE_URI=1 \
-DSQLITE_C=$(sqlite3.c) \
-DSQLITE_USE_LONG_DOUBLE=0 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_UTF16 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_OMIT_SHARED_CACHE
# ^^^ These particular OMITs are hard-coded in sqlite3-wasm.c and
# removing them from this list will serve only to break the speedtest1
# builds.
# Currently always needed but TODO is paring tester1.c-pp.js down
# to be able to run without this:
SQLITE_OPT.common += -DSQLITE_WASM_ENABLE_C_TESTS
# Extra flags for full-featured builds...
SQLITE_OPT.full-featured := \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_OFFSET_SQL_FUNC \
-DSQLITE_ENABLE_PREUPDATE_HOOK \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
ifeq (0,$(wasm-bare-bones))
# The so-called canonical build is full-featured:
SQLITE_OPT := \
$(SQLITE_OPT.common) \
$(SQLITE_OPT.full-featured)
else
# The so-called bare-bones build is exactly that:
SQLITE_OPT := \
$(SQLITE_OPT.common) \
-DSQLITE_WASM_BARE_BONES
# SQLITE_WASM_BARE_BONES tells sqlite3-wasm.c to explicitly omit
# a bunch of stuff, in the interest of keeping the wasm file size
# down. As of this writing it equates to:
#
# -USQLITE_ENABLE_DBPAGE_VTAB
# -USQLITE_ENABLE_DBSTAT_VTAB
# -USQLITE_ENABLE_EXPLAIN_COMMENTS
# -USQLITE_ENABLE_FTS5
# -USQLITE_ENABLE_OFFSET_SQL_FUNC
# -USQLITE_ENABLE_PREUPDATE_HOOK
# -USQLITE_ENABLE_RTREE
# -USQLITE_ENABLE_SESSION
# -USQLITE_ENABLE_STMTVTAB
# -DSQLITE_OMIT_AUTHORIZATION
# -DSQLITE_OMIT_GET_TABLE
# -DSQLITE_OMIT_INCRBLOB
# -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
# -DSQLITE_OMIT_JSON
# -DSQLITE_OMIT_PROGRESS_CALLBACK
# -DSQLITE_OMIT_WAL
#
# There are others we want here but which require explicit OMIT when
# creating their amalgamation, and that step is TODO:
#
# -DSQLITE_OMIT_EXPLAIN
# -DSQLITE_OMIT_TRIGGER
# -DSQLITE_OMIT_VIRTUALTABLE
# -DSQLITE_OMIT_WINDOWFUNC
endif
#SQLITE_OPT += -DSQLITE_DEBUG
# Enabling SQLITE_DEBUG will break sqlite3_wasm_vfs_create_file()
# (and thus sqlite3_js_vfs_create_file()). Those functions are
# deprecated and alternatives are in place, but this crash behavior
# can be used to find errant uses of sqlite3_js_vfs_create_file()
# in client code.
########################################################################
# The following flags are hard-coded into sqlite3-wasm.c and cannot be
# modified via the build process:
#
# SQLITE_ENABLE_API_ARMOR
# SQLITE_OMIT_LOAD_EXTENSION
# SQLITE_OMIT_DEPRECATED
# SQLITE_OMIT_UTF16
# SQLITE_OMIT_SHARED_CACHE
########################################################################
######################################################################## ########################################################################
# Adding custom C code via sqlite3_wasm_extra_init.c: # Adding custom C code via sqlite3_wasm_extra_init.c:
# #
@@ -321,6 +381,18 @@ $(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
$(CC) -o $@ $< $(CC) -o $@ $<
DISTCLEAN_FILES += $(bin.stripccomments) DISTCLEAN_FILES += $(bin.stripccomments)
########################################################################
# bin.mkwb is used for generating some of the makefile code for the
# various wasm builds. It used to be generated in this makefile via a
# difficult-to-read/maintain block of $(eval)'d code. Attempts were
# made to generate it from tcl and bash (shell) but having to escape
# the $ references in those languages made it just as illegible as the
# native makefile code. Somewhat surprisingly, moving that code generation
# to C makes it slightly less illegible than the previous 3 options.
bin.mkwb := ./mkwasmbuilds
$(bin.mkwb): $(bin.mkwb).c $(MAKEFILE)
$(CC) -o $@ $<
DISTCLEAN_FILES += $(bin.mkwb)
######################################################################## ########################################################################
# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via: # C-PP.FILTER: a $(call)able to transform $(1) to $(2) via:
@@ -360,6 +432,7 @@ $(bin.c-pp): c-pp.c $(sqlite3.c) $(MAKEFILE)
-DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \
-DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \ -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \
-DSQLITE_TEMP_STORE=3 -DSQLITE_TEMP_STORE=3
DISTCLEAN_FILES += $(bin.c-pp)
C-PP.FILTER.global ?= C-PP.FILTER.global ?=
ifeq (1,$(SQLITE_C_IS_SEE)) ifeq (1,$(SQLITE_C_IS_SEE))
C-PP.FILTER.global += -Denable-see C-PP.FILTER.global += -Denable-see
@@ -371,7 +444,7 @@ define C-PP.FILTER
# $3 = optional c-pp -D... flags # $3 = optional c-pp -D... flags
$(2): $(1) $$(MAKEFILE) $$(bin.c-pp) $(2): $(1) $$(MAKEFILE) $$(bin.c-pp)
$$(bin.c-pp) -f $(1) -o $$@ $(3) $(C-PP.FILTER.global) $$(bin.c-pp) -f $(1) -o $$@ $(3) $(C-PP.FILTER.global)
CLEAN_FILES += $(2) #CLEAN_FILES += $(2)
endef endef
# /end C-PP.FILTER # /end C-PP.FILTER
######################################################################## ########################################################################
@@ -386,7 +459,17 @@ emcc.WASM_BIGINT ?= 1
# emcc_opt = optimization-related flags. These are primarily used by # emcc_opt = optimization-related flags. These are primarily used by
# the various oX targets. build times for -O levels higher than 0 are # the various oX targets. build times for -O levels higher than 0 are
# painful at dev-time. # painful at dev-time.
emcc_opt ?= -O0 #
# When running any of the $(OPTIMIZED_TARGETS) explicitly, e.g. for a
# release distribution, use a higher optimization level. Experience
# has shown -Oz to produce the smallest deliverables with only a
# roughly 10% performance hit in the resulting WASM file compared to
# -O2 (which consistently creates the fastest-running deliverables).
ifeq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS)))
emcc_opt ?= -O0
else
emcc_opt ?= -Oz
endif
# When passing emcc_opt from the CLI, += and re-assignment have no # When passing emcc_opt from the CLI, += and re-assignment have no
# effect, so emcc_opt+=-g3 doesn't work. So... # effect, so emcc_opt+=-g3 doesn't work. So...
@@ -421,24 +504,16 @@ emcc_opt_full := $(emcc_opt) -g3
######################################################################## ########################################################################
# EXPORTED_FUNCTIONS.* = files for use with Emscripten's # EXPORTED_FUNCTIONS.* = files for use with Emscripten's
# -sEXPORTED_FUNCTION flag. # -sEXPORTED_FUNCTION flag.
EXPORTED_FUNCTIONS.api.core := $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core) EXPORTED_FUNCTIONS.api.core := $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core
EXPORTED_FUNCTIONS.api.in := $(EXPORTED_FUNCTIONS.api.core) EXPORTED_FUNCTIONS.api.in := $(EXPORTED_FUNCTIONS.api.core)
ifeq (1,$(SQLITE_C_IS_SEE)) ifeq (1,$(SQLITE_C_IS_SEE))
EXPORTED_FUNCTIONS.api.in += $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see) EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
endif endif
ifeq (0,$(minimal)) ifeq (0,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.api.in += \ EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-auth) \
$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-preupdate) \
$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-session) \
$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-vtab)
else
$(info ========================================)
$(info This is a minimal-mode build)
$(info ========================================)
endif endif
EXPORTED_FUNCTIONS.api := $(dir.tmp)/EXPORTED_FUNCTIONS.api EXPORTED_FUNCTIONS.api := $(dir.tmp)/EXPORTED_FUNCTIONS.api
$(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE) $(EXPORTED_FUNCTIONS.api): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE)
cat $(EXPORTED_FUNCTIONS.api.in) > $@ cat $(EXPORTED_FUNCTIONS.api.in) > $@
######################################################################## ########################################################################
@@ -470,8 +545,10 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js
# sqlite3-vfs-helper = helper APIs for VFSes: # sqlite3-vfs-helper = helper APIs for VFSes:
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
# sqlite3-vtab-helper = helper APIs for VTABLEs: ifeq (0,$(wasm-bare-bones))
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js # sqlite3-vtab-helper = helper APIs for VTABLEs:
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
endif
# sqlite3-vfs-opfs = the first OPFS VFS: # sqlite3-vfs-opfs = the first OPFS VFS:
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
# sqlite3-vfs-opfs-sahpool = the second OPFS VFS: # sqlite3-vfs-opfs-sahpool = the second OPFS VFS:
@@ -520,7 +597,7 @@ $(SOAP.js.bld): $(SOAP.js)
# preprocessed. It contains all of $(sqlite3-api.jses) but none of the # preprocessed. It contains all of $(sqlite3-api.jses) but none of the
# Emscripten-specific headers and footers. # Emscripten-specific headers and footers.
sqlite3-api.js.in := $(dir.tmp)/sqlite3-api.c-pp.js sqlite3-api.js.in := $(dir.tmp)/sqlite3-api.c-pp.js
$(sqlite3-api.js.in): $(sqlite3-api.jses) $(MAKEFILE) $(sqlite3-api.js.in): $(MKDIR.bld) $(sqlite3-api.jses) $(MAKEFILE)
@echo "Making $@..." @echo "Making $@..."
@for i in $(sqlite3-api.jses); do \ @for i in $(sqlite3-api.jses); do \
echo "/* BEGIN FILE: $$i */"; \ echo "/* BEGIN FILE: $$i */"; \
@@ -687,7 +764,7 @@ emcc.jsflags += -sLLD_REPORT_UNDEFINED
######################################################################## ########################################################################
# $(sqlite3-api-build-version.js) injects the build version info into # $(sqlite3-api-build-version.js) injects the build version info into
# the bundle in JSON form. # the bundle in JSON form.
$(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE) $(sqlite3-api-build-version.js): $(MKDIR.bld) $(bin.version-info) $(MAKEFILE)
@echo "Making $@..." @echo "Making $@..."
@{ \ @{ \
echo 'globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \ echo 'globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \
@@ -703,7 +780,7 @@ $(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE)
# #
# Maintenance reminder: there are awk binaries out there which do not # Maintenance reminder: there are awk binaries out there which do not
# support -e SCRIPT. # support -e SCRIPT.
$(sqlite3-license-version.js): $(sqlite3.h) $(sqlite3-license-version-header.js) \ $(sqlite3-license-version.js): $(MKDIR.bld) $(sqlite3.h) $(sqlite3-license-version-header.js) \
$(MAKEFILE) $(MAKEFILE)
@echo "Making $@..."; { \ @echo "Making $@..."; { \
cat $(sqlite3-license-version-header.js); \ cat $(sqlite3-license-version-header.js); \
@@ -731,7 +808,7 @@ post-jses.js := \
$(dir.api)/post-js-header.js \ $(dir.api)/post-js-header.js \
$(sqlite3-api.js.in) \ $(sqlite3-api.js.in) \
$(dir.api)/post-js-footer.js $(dir.api)/post-js-footer.js
$(post-js.js.in): $(post-jses.js) $(MAKEFILE) $(post-js.js.in): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE)
@echo "Making $@..." @echo "Making $@..."
@for i in $(post-jses.js); do \ @for i in $(post-jses.js); do \
echo "/* BEGIN FILE: $$i */"; \ echo "/* BEGIN FILE: $$i */"; \
@@ -740,55 +817,6 @@ $(post-js.js.in): $(post-jses.js) $(MAKEFILE)
done > $@ done > $@
########################################################################
# call-make-pre-post is a $(call)able which creates rules for
# pre-js.$(1)-$(2).js. $1 = the base name of the JS file on whose
# behalf this pre-js is for (one of: $(JS_BUILD_NAMES)). $2 is
# the build mode: one of $(JS_BUILD_MODES). This sets up
# --[extern-][pre/post]-js flags in $(pre-post-$(1)-$(2).flags) and
# dependencies in $(pre-post-$(1)-$(2).deps). The resulting files get
# filtered using $(C-PP.FILTER). Any flags necessary for such
# filtering need to be set in $(c-pp.D.$(1)-$(2)) before $(call)ing
# this.
#
# Maintenance note: a shell script was written to generate these rules
# with the hope that it would make them more legible and maintainable,
# but embedding makefile code in another language makes it even less
# legible than having the level of $(eval) indirection which we have
# here.
define call-make-pre-post
pre-post-$(1)-$(2).flags ?=
pre-js.js.$(1)-$(2).intermediary := $$(dir.tmp)/pre-js.$(1)-$(2).intermediary.js
pre-js.js.$(1)-$(2) := $$(dir.tmp)/pre-js.$(1)-$(2).js
#$$(error $$(pre-js.js.$(1)-$(2).intermediary) $$(pre-js.js.$(1)-$(2)))
$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)-$(2).intermediary),$$(c-pp.D.$(1)-$(2))))
post-js.js.$(1)-$(2) := $$(dir.tmp)/post-js.$(1)-$(2).js
$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
extern-post-js.js.$(1)-$(2) := $$(dir.tmp)/extern-post-js.$(1)-$(2).js
$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
pre-post-common.flags.$(1)-$(2) := \
$$(pre-post-common.flags) \
--post-js=$$(post-js.js.$(1)-$(2)) \
--extern-post-js=$$(extern-post-js.js.$(1)-$(2))
pre-post-jses.$(1)-$(2).deps := $$(pre-post-jses.deps.common) \
$$(post-js.js.$(1)-$(2)) $$(extern-post-js.js.$(1)-$(2))
$$(pre-js.js.$(1)-$(2)): $$(pre-js.js.$(1)-$(2).intermediary) $$(MAKEFILE)
cp $$(pre-js.js.$(1)-$(2).intermediary) $$@
@if [ sqlite3-wasmfs = $(1) ]; then \
echo "delete Module[xNameOfInstantiateWasm] /*for WASMFS build*/;"; \
elif [ sqlite3 != $(1) ]; then \
echo "Module[xNameOfInstantiateWasm].uri = '$(1).wasm';"; \
fi >> $$@
pre-post-$(1)-$(2).deps := \
$$(pre-post-jses.$(1)-$(2).deps) \
$$(dir.tmp)/pre-js.$(1)-$(2).js
pre-post-$(1)-$(2).flags += \
$$(pre-post-common.flags.$(1)-$(2)) \
--pre-js=$$(dir.tmp)/pre-js.$(1)-$(2).js
endef
# /post-js and pre-js
########################################################################
# Undocumented Emscripten feature: if the target file extension is # Undocumented Emscripten feature: if the target file extension is
# "mjs", it defaults to ES6 module builds: # "mjs", it defaults to ES6 module builds:
# https://github.com/emscripten-core/emscripten/issues/14383 # https://github.com/emscripten-core/emscripten/issues/14383
@@ -802,11 +830,13 @@ sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles)
# difference, so we build all binaries against sqlite3-wasm.c instead # difference, so we build all binaries against sqlite3-wasm.c instead
# of building a shared copy of sqlite3-wasm.o to link against. # of building a shared copy of sqlite3-wasm.o to link against.
######################################################################## ########################################################################
# SQLITE3.xJS.EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE and
# SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid code ########################################################################
# duplication. $1 is 1 if the build mode needs this workaround (esm, # SQLITE3.xJS.ESM-EXPORT-DEFAULT is used by mkwasmbuilds.c and the
# bundler-friendly, node) and 0 if not (vanilla). $2 must be empty for # wasmfs build. $1 is 1 if the build mode needs this workaround
# all builds except sqlite3-wasmfs.mjs, in which case it must be 1. # (modes: esm, bundler-friendly, node) and 0 if not (vanilla). $2 must
# be 0 for all builds except sqlite3-wasmfs.mjs, in which case it must
# be 1.
# #
# Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_ # Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_
# adds: # adds:
@@ -825,11 +855,11 @@ sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles)
# use awk instead of sed for this. # use awk instead of sed for this.
define SQLITE3.xJS.ESM-EXPORT-DEFAULT define SQLITE3.xJS.ESM-EXPORT-DEFAULT
if [ x1 = x$(1) ]; then \ if [ x1 = x$(1) ]; then \
echo "Fragile workaround for emscripten/issues/18237. See SQLITE3.xJS.RECIPE."; \ echo "Fragile workaround for emscripten/issues/18237. See SQLITE3.xJS.ESM-EXPORT-DEFAULT."; \
{\ {\
awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \ awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \
} || exit $$?; \ } || exit $$?; \
if [ x != x$(2) ]; then \ if [ x1 = x$(2) ]; then \
if ! grep -q '^export default' $@; then \ if ! grep -q '^export default' $@; then \
echo "Cannot find export default." 1>&2; \ echo "Cannot find export default." 1>&2; \
exit 1; \ exit 1; \
@@ -838,78 +868,6 @@ if [ x1 = x$(1) ]; then \
fi fi
endef endef
########################################################################
# extern-post-js* and extern-pre-js* are files for use with
# Emscripten's --extern-pre-js and --extern-post-js flags.
extern-pre-js.js := $(dir.api)/extern-pre-js.js
extern-post-js.js.in := $(dir.api)/extern-post-js.c-pp.js
# Emscripten flags for --[extern-][pre|post]-js=... for the
# various builds.
pre-post-common.flags := \
--extern-pre-js=$(sqlite3-license-version.js)
# pre-post-jses.deps.* = a list of dependencies for the
# --[extern-][pre/post]-js files.
pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)
########################################################################
# SETUP_LIB_BUILD_MODE is a $(call)'able which sets up numerous pieces
# for one of the build modes.
#
# $1 = one of: $(JS_BUILD_NAMES)
# $2 = build mode name: one of $(JS_BUILD_MODES)
# $3 = 1 for ESM build mode, else 0
# $4 = resulting sqlite-api JS/MJS file
# $5 = resulting JS/MJS file
# $6 = -D... flags for $(bin.c-pp)
# $7 = optional extra flags for emcc
#
# Maintenance reminder: be careful not to introduce spaces around args
# ($1, $2), otherwise string concatenation will malfunction.
#
# Before calling this, emcc.environment.$(2) must be set to a value
# for emcc's -sENVIRONMENT flag.
#
# $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append
# CFLAGS to a given build mode.
#
# $(emcc.flags.$(1)) and $(emcc.flags.$(1).$(2)) may be defined to
# append emcc-specific flags to a given build mode.
define SETUP_LIB_BUILD_MODE
$(info Setting up build [$(1)-$(2)]: $(5))
c-pp.D.$(1)-$(2) := $(6)
$$(eval $$(call call-make-pre-post,$(1),$(2)))
emcc.flags.$(1).$(2) ?=
emcc.flags.$(1).$(2) += $(7)
$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(4), $(6)))
$(5): $(4) $$(MAKEFILE) $$(sqlite3-wasm.cfiles) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-$(1)-$(2).deps)
@echo "Building $$@ ..."
$$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \
$$(emcc.jsflags) \
-sENVIRONMENT=$$(emcc.environment.$(2)) \
$$(pre-post-$(1)-$(2).flags) \
$$(emcc.flags.$(1)) $$(emcc.flags.$(1).$(2)) \
$$(cflags.common) $$(SQLITE_OPT) \
$$(cflags.$(1)) $$(cflags.$(1).$(2)) \
$$(cflags.wasm_extra_init) $$(sqlite3-wasm.cfiles)
@$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(3))
@dotwasm=$$(basename $$@).wasm; \
chmod -x $$$$dotwasm; \
$(maybe-wasm-strip) $$$$dotwasm; \
case $(2) in \
bundler-friendly|node) \
echo "Patching $$@ for $(1).wasm..."; \
rm -f $$$$dotwasm; \
dotwasm=; \
sed -i -e 's/$(1)-$(2).wasm/$(1).wasm/g' $$@ || exit $$$$?; \
;; \
esac; \
ls -la $$$$dotwasm $$@
all: $(5)
#quick: $(5)
CLEAN_FILES += $(4) $(5)
endef
# ^^^ /SETUP_LIB_BUILD_MODE
########################################################################
sqlite3-api.js := $(dir.dout)/sqlite3-api.js sqlite3-api.js := $(dir.dout)/sqlite3-api.js
sqlite3.js := $(dir.dout)/sqlite3.js sqlite3.js := $(dir.dout)/sqlite3.js
sqlite3-api.mjs := $(dir.dout)/sqlite3-api.mjs sqlite3-api.mjs := $(dir.dout)/sqlite3-api.mjs
@@ -918,17 +876,18 @@ sqlite3-api-bundler-friendly.mjs := $(dir.dout)/sqlite3-api-bundler-friendly.mjs
sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs
sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs
sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs
#$(info $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0, $(sqlite3-api.js), $(sqlite3.js))) sqlite3-api-wasmfs.mjs := $(dir.tmp)/sqlite3-api-wasmfs.mjs
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0,\ sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
$(sqlite3-api.js), $(sqlite3.js))) EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,esm,1,\ ifneq (1,$(MAKING_CLEAN))
$(sqlite3-api.mjs), $(sqlite3.mjs), -Dtarget=es6-module)) .wasmbuilds.make: $(bin.mkwb)
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,bundler-friendly,1,\ @rm -f $@
$(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\ $(bin.mkwb) > $@
$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly)) @chmod -w $@
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,node,1,\ -include .wasmbuilds.make
$(sqlite3-api-node.mjs),$(sqlite3-node.mjs),\ endif
$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node)) DISTCLEAN_FILES += .wasmbuilds.make
# The various -D... values used by *.c-pp.js include: # The various -D... values used by *.c-pp.js include:
# #
# -Dtarget=es6-module: for all ESM module builds # -Dtarget=es6-module: for all ESM module builds
@@ -962,7 +921,7 @@ $(sqlite3.wasm): $(sqlite3.js)
$(sqlite3.mjs): $(sqlite3.js) $(sqlite3.mjs): $(sqlite3.js)
$(sqlite3-bundler-friendly.mjs): $(sqlite3.mjs) $(sqlite3-bundler-friendly.mjs): $(sqlite3.mjs)
$(sqlite3-node.mjs): $(sqlite3.mjs) $(sqlite3-node.mjs): $(sqlite3.mjs)
CLEAN_FILES += $(sqlite3.wasm) #CLEAN_FILES += $(sqlite3.wasm)
######################################################################## ########################################################################
# We need separate copies of certain supplementary JS files for the # We need separate copies of certain supplementary JS files for the
@@ -1078,15 +1037,13 @@ speedtest1.exit-runtime1 := -sEXIT_RUNTIME=1
# -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app # -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app
# which runs speedtest1 multiple times. # which runs speedtest1 multiple times.
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core) $(EXPORTED_FUNCTIONS.speedtest1): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.core)
@echo "Making $@ ..." @echo "Making $@ ..."
@{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@
speedtest1.js := $(dir.dout)/speedtest1.js speedtest1.js := $(dir.dout)/speedtest1.js
speedtest1.wasm := $(dir.dout)/speedtest1.wasm speedtest1.wasm := $(dir.dout)/speedtest1.wasm
emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM
speedtest1.cfiles := $(speedtest1.c) $(sqlite3-wasm.c) speedtest1.cfiles := $(speedtest1.c) $(sqlite3-wasm.c)
$(eval $(call call-make-pre-post,speedtest1,vanilla))
$(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \
$(pre-post-speedtest1-vanilla.deps) \ $(pre-post-speedtest1-vanilla.deps) \
$(EXPORTED_FUNCTIONS.speedtest1) $(EXPORTED_FUNCTIONS.speedtest1)
@@ -1096,7 +1053,7 @@ $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \
$(emcc.speedtest1.common) \ $(emcc.speedtest1.common) \
$(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \ $(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \
$(SQLITE_OPT) \ $(SQLITE_OPT) \
-USQLITE_WASM_MINIMAL \ -USQLITE_WASM_BARE_BONES \
-USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \ -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \
$(speedtest1.exit-runtime0) \ $(speedtest1.exit-runtime0) \
-o $@ $(speedtest1.cfiles) -lm -o $@ $(speedtest1.cfiles) -lm
@@ -1106,7 +1063,7 @@ $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \
speedtest1: $(speedtest1.js) speedtest1: $(speedtest1.js)
all: speedtest1 all: speedtest1
CLEAN_FILES += $(speedtest1.js) $(speedtest1.wasm) #CLEAN_FILES += $(speedtest1.js) $(speedtest1.wasm)
# end speedtest1.js # end speedtest1.js
######################################################################## ########################################################################
@@ -1143,24 +1100,29 @@ quick: $(sqlite3.js)
# painful. # painful.
.PHONY: o0 o1 o2 o3 os oz .PHONY: o0 o1 o2 o3 os oz
o-xtra := emcc-opt-extra :=
#o-xtra ?= -flto #ifeq (1,$(wasm-bare-bones))
#emcc-opt-extra += -flto
# ^^^^ -flto can have a considerably performance boost at -O0 but # ^^^^ -flto can have a considerably performance boost at -O0 but
# doubles the build time and seems to have negligible, if any, effect # doubles the build time and seems to have negligible, if any, effect
# on higher optimization levels. # on higher optimization levels.
#
# -flto does ont shrink the size of bare-bones builds by any measurable
# amount.
#endif
o0: clean o0: clean
$(MAKE) -e "emcc_opt=-O0" $(MAKE) -e "emcc_opt=-O0"
o1: clean o1: clean
$(MAKE) -e "emcc_opt=-O1 $(o-xtra)" $(MAKE) -e "emcc_opt=-O1 $(emcc-opt-extra)"
o2: clean o2: clean
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)" $(MAKE) -j2 -e "emcc_opt=-O2 $(emcc-opt-extra)"
o3: clean o3: clean
$(MAKE) -e "emcc_opt=-O3 $(o-xtra)" $(MAKE) -e "emcc_opt=-O3 $(emcc-opt-extra)"
os: clean os: clean
@echo "WARNING: -Os can result in a build with mysteriously missing pieces!" @echo "WARNING: -Os can result in a build with mysteriously missing pieces!"
$(MAKE) -e "emcc_opt=-Os $(o-xtra)" $(MAKE) -e "emcc_opt=-Os $(emcc-opt-extra)"
oz: clean oz: clean
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)" $(MAKE) -j2 -e "emcc_opt=-Oz $(emcc-opt-extra)"
######################################################################## ########################################################################
# Sub-makes... # Sub-makes...
@@ -1174,7 +1136,7 @@ wasmfs.enable ?= 1
else else
# Unconditionally enable wasmfs for [dist]clean so that the wasmfs # Unconditionally enable wasmfs for [dist]clean so that the wasmfs
# sub-make can clean up. # sub-make can clean up.
wasmfs.enable ?= $(if $(filter %clean,$(MAKECMDGOALS)),1,0) wasmfs.enable ?= $(MAKING_CLEAN)
endif endif
ifeq (1,$(wasmfs.enable)) ifeq (1,$(wasmfs.enable))
# wasmfs build disabled 2022-10-19 per /chat discussion. # wasmfs build disabled 2022-10-19 per /chat discussion.
@@ -1253,4 +1215,3 @@ endif
# Run local web server for the test/demo pages. # Run local web server for the test/demo pages.
httpd: httpd:
althttpd -max-age 1 -enable-sab 1 -page index.html althttpd -max-age 1 -enable-sab 1 -page index.html

View File

@@ -1 +0,0 @@
_sqlite3_set_authorizer

View File

@@ -41,7 +41,6 @@ _sqlite3_create_collation
_sqlite3_create_collation_v2 _sqlite3_create_collation_v2
_sqlite3_create_function _sqlite3_create_function
_sqlite3_create_function_v2 _sqlite3_create_function_v2
_sqlite3_create_window_function
_sqlite3_data_count _sqlite3_data_count
_sqlite3_db_filename _sqlite3_db_filename
_sqlite3_db_handle _sqlite3_db_handle
@@ -49,7 +48,6 @@ _sqlite3_db_name
_sqlite3_db_readonly _sqlite3_db_readonly
_sqlite3_db_status _sqlite3_db_status
_sqlite3_deserialize _sqlite3_deserialize
_sqlite3_drop_modules
_sqlite3_errcode _sqlite3_errcode
_sqlite3_errmsg _sqlite3_errmsg
_sqlite3_error_offset _sqlite3_error_offset
@@ -81,7 +79,6 @@ _sqlite3_open_v2
_sqlite3_overload_function _sqlite3_overload_function
_sqlite3_prepare_v2 _sqlite3_prepare_v2
_sqlite3_prepare_v3 _sqlite3_prepare_v3
_sqlite3_progress_handler
_sqlite3_randomness _sqlite3_randomness
_sqlite3_realloc _sqlite3_realloc
_sqlite3_realloc64 _sqlite3_realloc64

View File

@@ -1,3 +1,12 @@
_sqlite3_create_window_function
_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old
_sqlite3changegroup_add _sqlite3changegroup_add
_sqlite3changegroup_add_strm _sqlite3changegroup_add_strm
_sqlite3changegroup_delete _sqlite3changegroup_delete
@@ -40,3 +49,15 @@ _sqlite3session_object_config
_sqlite3session_patchset _sqlite3session_patchset
_sqlite3session_patchset_strm _sqlite3session_patchset_strm
_sqlite3session_table_filter _sqlite3session_table_filter
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_declare_vtab
_sqlite3_drop_modules
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value

View File

@@ -1,6 +0,0 @@
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old

View File

@@ -1,11 +0,0 @@
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_declare_vtab
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value

View File

@@ -48,7 +48,7 @@ Module['locateFile'] = function(path, prefix) {
}else{ }else{
theFile = prefix + path; theFile = prefix + path;
} }
sqlite3InitModuleState.debugModule( this.debugModule(
"locateFile(",arguments[0], ',', arguments[1],")", "locateFile(",arguments[0], ',', arguments[1],")",
'sqlite3InitModuleState.scriptDir =',this.scriptDir, 'sqlite3InitModuleState.scriptDir =',this.scriptDir,
'up.entries() =',Array.from(up.entries()), 'up.entries() =',Array.from(up.entries()),
@@ -59,6 +59,7 @@ Module['locateFile'] = function(path, prefix) {
}.bind(sqlite3InitModuleState); }.bind(sqlite3InitModuleState);
//#endif ifnot target=es6-bundler-friendly //#endif ifnot target=es6-bundler-friendly
//#if custom-Module.instantiateModule
/** /**
Bug warning: a custom Module.instantiateWasm() does not work Bug warning: a custom Module.instantiateWasm() does not work
in WASMFS builds: in WASMFS builds:
@@ -67,7 +68,15 @@ Module['locateFile'] = function(path, prefix) {
In such builds we must disable this. In such builds we must disable this.
*/ */
const xNameOfInstantiateWasm = false const xNameOfInstantiateWasm =
//#if wasmfs
false
//#else
true /* This works, but it does not have the testing coverage in the
wild which Emscripten's default impl does, so we'll save
this option until we really need a custom
Module.instantiateWasm() */
//#endif
? 'instantiateWasm' ? 'instantiateWasm'
: 'emscripten-bug-17951'; : 'emscripten-bug-17951';
Module[xNameOfInstantiateWasm] = function callee(imports,onSuccess){ Module[xNameOfInstantiateWasm] = function callee(imports,onSuccess){
@@ -80,6 +89,7 @@ Module[xNameOfInstantiateWasm] = function callee(imports,onSuccess){
sqlite3InitModuleState.debugModule( sqlite3InitModuleState.debugModule(
"instantiateWasm() uri =", uri "instantiateWasm() uri =", uri
); );
//console.warn("Custom instantiateModule",uri);
const wfetch = ()=>fetch(uri, {credentials: 'same-origin'}); const wfetch = ()=>fetch(uri, {credentials: 'same-origin'});
const loadWasm = WebAssembly.instantiateStreaming const loadWasm = WebAssembly.instantiateStreaming
? async ()=>{ ? async ()=>{
@@ -105,6 +115,7 @@ Module[xNameOfInstantiateWasm] = function callee(imports,onSuccess){
scripts. scripts.
*/ */
Module[xNameOfInstantiateWasm].uri = 'sqlite3.wasm'; Module[xNameOfInstantiateWasm].uri = 'sqlite3.wasm';
//#endif custom-Module.instantiateModule
/* END FILE: api/pre-js.js, noting that the build process may add a /* END FILE: api/pre-js.js, noting that the build process may add a
line after this one to change the above .uri to a build-specific line after this one to change the above .uri to a build-specific
one. */ one. */

View File

@@ -136,20 +136,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_compileoption_used", "int", "string"], ["sqlite3_compileoption_used", "int", "string"],
["sqlite3_complete", "int", "string:flexible"], ["sqlite3_complete", "int", "string:flexible"],
["sqlite3_context_db_handle", "sqlite3*", "sqlite3_context*"], ["sqlite3_context_db_handle", "sqlite3*", "sqlite3_context*"],
/* sqlite3_create_collation() and sqlite3_create_collation_v2()
use hand-written bindings to simplify passing of the callback
function. */
/* sqlite3_create_function(), sqlite3_create_function_v2(), and /* sqlite3_create_function(), sqlite3_create_function_v2(), and
sqlite3_create_window_function() use hand-written bindings to sqlite3_create_window_function() use hand-written bindings to
simplify handling of their function-type arguments. */ simplify handling of their function-type arguments. */
/* sqlite3_create_collation() and sqlite3_create_collation_v2()
use hand-written bindings to simplify passing of the callback
function.
["sqlite3_create_collation", "int",
"sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
"*", "*"],
["sqlite3_create_collation_v2", "int",
"sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
"*", "*", "*"],
*/
["sqlite3_data_count", "int", "sqlite3_stmt*"], ["sqlite3_data_count", "int", "sqlite3_stmt*"],
["sqlite3_db_filename", "string", "sqlite3*", "string"], ["sqlite3_db_filename", "string", "sqlite3*", "string"],
["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"], ["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
@@ -211,14 +203,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
for those, depending on how their SQL argument is provided. */ for those, depending on how their SQL argument is provided. */
/* sqlite3_randomness() uses a hand-written wrapper to extend /* sqlite3_randomness() uses a hand-written wrapper to extend
the range of supported argument types. */ the range of supported argument types. */
["sqlite3_progress_handler", undefined, [
"sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
name: 'xProgressHandler',
signature: 'i(p)',
bindScope: 'context',
contextKey: (argv,argIndex)=>argv[0/* sqlite3* */]
}), "*"
]],
["sqlite3_realloc", "*","*","int"], ["sqlite3_realloc", "*","*","int"],
["sqlite3_reset", "int", "sqlite3_stmt*"], ["sqlite3_reset", "int", "sqlite3_stmt*"],
/* sqlite3_reset_auto_extension() has a hand-written binding. */ /* sqlite3_reset_auto_extension() has a hand-written binding. */
@@ -303,6 +287,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"] ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
]/*wasm.bindingSignatures*/; ]/*wasm.bindingSignatures*/;
if( !!wasm.exports.sqlite3_progress_handler ){
wasm.bindingSignatures.push(
["sqlite3_progress_handler", undefined, [
"sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
name: 'xProgressHandler',
signature: 'i(p)',
bindScope: 'context',
contextKey: (argv,argIndex)=>argv[0/* sqlite3* */]
}), "*"
]]
);
}
if( !!wasm.exports.sqlite3_stmt_explain ){ if( !!wasm.exports.sqlite3_stmt_explain ){
wasm.bindingSignatures.push( wasm.bindingSignatures.push(
["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"], ["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"],
@@ -336,7 +333,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/* sqlite3_set_authorizer() */ }/* sqlite3_set_authorizer() */
if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){ if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
/* ^^^ "the problem" is that this is an option feature and the /* ^^^ "the problem" is that this is an optional feature and the
build-time function-export list does not currently take build-time function-export list does not currently take
optional features into account. */ optional features into account. */
wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]); wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
@@ -385,7 +382,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
of this, the canonical builds of sqlite3.wasm/js guarantee that of this, the canonical builds of sqlite3.wasm/js guarantee that
sqlite3.wasm.alloc() and friends use those allocators. Custom builds sqlite3.wasm.alloc() and friends use those allocators. Custom builds
may not guarantee that, however. */, may not guarantee that, however. */,
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]], ["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]],
["sqlite3_malloc64", "*","i64"], ["sqlite3_malloc64", "*","i64"],
["sqlite3_msize", "i64", "*"], ["sqlite3_msize", "i64", "*"],
@@ -422,6 +418,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_create_module_v2", "int", ["sqlite3_create_module_v2", "int",
["sqlite3*","string","sqlite3_module*","*","*"]], ["sqlite3*","string","sqlite3_module*","*","*"]],
["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]], ["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]],
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
["sqlite3_vtab_collation","string","sqlite3_index_info*","int"], ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"],
["sqlite3_vtab_distinct","int", "sqlite3_index_info*"], ["sqlite3_vtab_distinct","int", "sqlite3_index_info*"],
["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"], ["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"],
@@ -950,7 +947,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
/** Code duplication reducer for functions which take an encoding /** Code duplication reducer for functions which take an encoding
argument and require SQLITE_UTF8. Sets the db error code to argument and require SQLITE_UTF8. Sets the db error code to
SQLITE_FORMAT and returns that code. */ SQLITE_FORMAT, installs a descriptive error message,
and returns SQLITE_FORMAT. */
const __errEncoding = (pDb)=>{ const __errEncoding = (pDb)=>{
return util.sqlite3__wasm_db_error( return util.sqlite3__wasm_db_error(
pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding." pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding."
@@ -1000,11 +998,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
this._addUDF(pDb, name, arity, m.udf); this._addUDF(pDb, name, arity, m.udf);
}; };
__dbCleanupMap.addWindowFunc = function(pDb, name, arity){ if( wasm.exports.sqlite3_create_window_function ){
const m = __dbCleanupMap(pDb, 1); __dbCleanupMap.addWindowFunc = function(pDb, name, arity){
if(!m.wudf) m.wudf = new Map; const m = __dbCleanupMap(pDb, 1);
this._addUDF(pDb, name, arity, m.wudf); if(!m.wudf) m.wudf = new Map;
}; this._addUDF(pDb, name, arity, m.wudf);
};
}
/** /**
Intended to be called _only_ from sqlite3_close_v2(), Intended to be called _only_ from sqlite3_close_v2(),
@@ -1273,17 +1273,20 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
] ]
); );
const __sqlite3CreateWindowFunction = wasm.xWrap( const __sqlite3CreateWindowFunction =
"sqlite3_create_window_function", "int", [ wasm.exports.sqlite3_create_window_function
"sqlite3*", "string"/*funcName*/, "int"/*nArg*/, ? wasm.xWrap(
"int"/*eTextRep*/, "*"/*pApp*/, "sqlite3_create_window_function", "int", [
new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}), "sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}), "int"/*eTextRep*/, "*"/*pApp*/,
new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}), new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}),
new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}), new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}),
new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy}) new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}),
] new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}),
); new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy})
]
)
: undefined;
/* Documented in the api object's initializer. */ /* Documented in the api object's initializer. */
capi.sqlite3_create_function_v2 = function f( capi.sqlite3_create_function_v2 = function f(
@@ -1328,61 +1331,71 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}; };
/* Documented in the api object's initializer. */ /* Documented in the api object's initializer. */
capi.sqlite3_create_window_function = function f( if( __sqlite3CreateWindowFunction ){
pDb, funcName, nArg, eTextRep, pApp, capi.sqlite3_create_window_function = function f(
xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**) pDb, funcName, nArg, eTextRep, pApp,
xFinal, //void (*xFinal)(sqlite3_context*) xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**)
xValue, //void (*xValue)(sqlite3_context*) xFinal, //void (*xFinal)(sqlite3_context*)
xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**) xValue, //void (*xValue)(sqlite3_context*)
xDestroy //void (*xDestroy)(void*) xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**)
){ xDestroy //void (*xDestroy)(void*)
if( f.length!==arguments.length ){ ){
return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length); if( f.length!==arguments.length ){
}else if( 0 === (eTextRep & 0xf) ){ return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length);
eTextRep |= capi.SQLITE_UTF8; }else if( 0 === (eTextRep & 0xf) ){
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ eTextRep |= capi.SQLITE_UTF8;
return __errEncoding(pDb); }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
} return __errEncoding(pDb);
try{
const rc = __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
pApp, xStep, xFinal, xValue,
xInverse, xDestroy);
if(0===rc && (xStep instanceof Function
|| xFinal instanceof Function
|| xValue instanceof Function
|| xInverse instanceof Function
|| xDestroy instanceof Function)){
__dbCleanupMap.addWindowFunc(pDb, funcName, nArg);
} }
return rc; try{
}catch(e){ const rc = __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
console.error("sqlite3_create_window_function() setup threw:",e); pApp, xStep, xFinal, xValue,
return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e); xInverse, xDestroy);
} if(0===rc && (xStep instanceof Function
}; || xFinal instanceof Function
|| xValue instanceof Function
|| xInverse instanceof Function
|| xDestroy instanceof Function)){
__dbCleanupMap.addWindowFunc(pDb, funcName, nArg);
}
return rc;
}catch(e){
console.error("sqlite3_create_window_function() setup threw:",e);
return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e);
}
};
}else{
delete capi.sqlite3_create_window_function;
}
/** /**
A _deprecated_ alias for capi.sqlite3_result_js() which A _deprecated_ alias for capi.sqlite3_result_js() which
predates the addition of that function in the public API. predates the addition of that function in the public API.
*/ */
capi.sqlite3_create_function_v2.udfSetResult = capi.sqlite3_create_function_v2.udfSetResult =
capi.sqlite3_create_function.udfSetResult = capi.sqlite3_create_function.udfSetResult = capi.sqlite3_result_js;
if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfSetResult = capi.sqlite3_result_js; capi.sqlite3_create_window_function.udfSetResult = capi.sqlite3_result_js;
}
/** /**
A _deprecated_ alias for capi.sqlite3_values_to_js() which A _deprecated_ alias for capi.sqlite3_values_to_js() which
predates the addition of that function in the public API. predates the addition of that function in the public API.
*/ */
capi.sqlite3_create_function_v2.udfConvertArgs = capi.sqlite3_create_function_v2.udfConvertArgs =
capi.sqlite3_create_function.udfConvertArgs = capi.sqlite3_create_function.udfConvertArgs = capi.sqlite3_values_to_js;
if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfConvertArgs = capi.sqlite3_values_to_js; capi.sqlite3_create_window_function.udfConvertArgs = capi.sqlite3_values_to_js;
}
/** /**
A _deprecated_ alias for capi.sqlite3_result_error_js() which A _deprecated_ alias for capi.sqlite3_result_error_js() which
predates the addition of that function in the public API. predates the addition of that function in the public API.
*/ */
capi.sqlite3_create_function_v2.udfSetError = capi.sqlite3_create_function_v2.udfSetError =
capi.sqlite3_create_function.udfSetError = capi.sqlite3_create_function.udfSetError = capi.sqlite3_result_error_js;
if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfSetError = capi.sqlite3_result_error_js; capi.sqlite3_create_window_function.udfSetError = capi.sqlite3_result_error_js;
}
}/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/; }/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/;

View File

@@ -14,16 +14,17 @@
*/ */
#define SQLITE_WASM #define SQLITE_WASM
#ifdef SQLITE_WASM_ENABLE_C_TESTS #ifdef SQLITE_WASM_ENABLE_C_TESTS
# undef SQLITE_WASM_ENABLE_C_TESTS
# define SQLITE_WASM_ENABLE_C_TESTS 1
/* /*
** Code blocked off by SQLITE_WASM_TESTS is intended solely for use in ** Code blocked off by SQLITE_WASM_ENABLE_C_TESTS is intended solely
** unit/regression testing. They may be safely omitted from ** for use in unit/regression testing. They may be safely omitted from
** client-side builds. The main unit test script, tester1.js, will ** client-side builds. The main unit test script, tester1.js, will
** skip related tests if it doesn't find the corresponding functions ** skip related tests if it doesn't find the corresponding functions
** in the WASM exports. ** in the WASM exports.
*/ */
# define SQLITE_WASM_TESTS 1
#else #else
# define SQLITE_WASM_TESTS 0 # define SQLITE_WASM_ENABLE_C_TESTS 0
#endif #endif
/* /*
@@ -92,60 +93,18 @@
#undef SQLITE_ENABLE_API_ARMOR #undef SQLITE_ENABLE_API_ARMOR
#define SQLITE_ENABLE_API_ARMOR 1 #define SQLITE_ENABLE_API_ARMOR 1
#ifndef SQLITE_ENABLE_BYTECODE_VTAB
# define SQLITE_ENABLE_BYTECODE_VTAB 1
#endif
#ifndef SQLITE_ENABLE_DBPAGE_VTAB
# define SQLITE_ENABLE_DBPAGE_VTAB 1
#endif
#ifndef SQLITE_ENABLE_DBSTAT_VTAB
# define SQLITE_ENABLE_DBSTAT_VTAB 1
#endif
#ifndef SQLITE_ENABLE_EXPLAIN_COMMENTS
# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1
#endif
#ifndef SQLITE_ENABLE_FTS5
# define SQLITE_ENABLE_FTS5 1
#endif
#ifndef SQLITE_ENABLE_MATH_FUNCTIONS
# define SQLITE_ENABLE_MATH_FUNCTIONS 1
#endif
#ifndef SQLITE_ENABLE_OFFSET_SQL_FUNC
# define SQLITE_ENABLE_OFFSET_SQL_FUNC 1
#endif
#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
# define SQLITE_ENABLE_PREUPDATE_HOOK 1 /*required by session extension*/
#endif
#ifndef SQLITE_ENABLE_RTREE
# define SQLITE_ENABLE_RTREE 1
#endif
#ifndef SQLITE_ENABLE_SESSION
# define SQLITE_ENABLE_SESSION 1
#endif
#ifndef SQLITE_ENABLE_STMTVTAB
# define SQLITE_ENABLE_STMTVTAB 1
#endif
#ifndef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
# define SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
#endif
/**********************************************************************/ /**********************************************************************/
/* SQLITE_O... */ /* SQLITE_O... */
#ifndef SQLITE_OMIT_DEPRECATED #undef SQLITE_OMIT_DEPRECATED
# define SQLITE_OMIT_DEPRECATED 1 #define SQLITE_OMIT_DEPRECATED 1
#endif #undef SQLITE_OMIT_LOAD_EXTENSION
#ifndef SQLITE_OMIT_LOAD_EXTENSION #define SQLITE_OMIT_LOAD_EXTENSION 1
# define SQLITE_OMIT_LOAD_EXTENSION 1 #undef SQLITE_OMIT_SHARED_CACHE
#endif #define SQLITE_OMIT_SHARED_CACHE 1
#ifndef SQLITE_OMIT_SHARED_CACHE #undef SQLITE_OMIT_UTF16
# define SQLITE_OMIT_SHARED_CACHE 1 #define SQLITE_OMIT_UTF16 1
#endif #undef SQLITE_OS_KV_OPTIONAL
#ifndef SQLITE_OMIT_UTF16 #define SQLITE_OS_KV_OPTIONAL 1
# define SQLITE_OMIT_UTF16 1
#endif
#ifndef SQLITE_OS_KV_OPTIONAL
# define SQLITE_OS_KV_OPTIONAL 1
#endif
/**********************************************************************/ /**********************************************************************/
/* SQLITE_S... */ /* SQLITE_S... */
@@ -168,50 +127,75 @@
# define SQLITE_USE_URI 1 # define SQLITE_USE_URI 1
#endif #endif
#ifndef SQLITE_USE_LONG_DOUBLE
# define SQLITE_USE_LONG_DOUBLE 0
#endif
#ifdef SQLITE_WASM_EXTRA_INIT #ifdef SQLITE_WASM_EXTRA_INIT
# define SQLITE_EXTRA_INIT sqlite3_wasm_extra_init # define SQLITE_EXTRA_INIT sqlite3_wasm_extra_init
#endif #endif
/* /*
** If SQLITE_WASM_MINIMAL is defined, undefine most of the ENABLE ** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE
** macros. ** macros.
*/ */
#ifdef SQLITE_WASM_MINIMAL #ifdef SQLITE_WASM_BARE_BONES
# undef SQLITE_ENABLE_DBPAGE_VTAB # undef SQLITE_ENABLE_DBPAGE_VTAB
# undef SQLITE_ENABLE_DBSTAT_VTAB # undef SQLITE_ENABLE_DBSTAT_VTAB
# undef SQLITE_ENABLE_EXPLAIN_COMMENTS # undef SQLITE_ENABLE_EXPLAIN_COMMENTS
# undef SQLITE_ENABLE_FTS5 # undef SQLITE_ENABLE_FTS5
# undef SQLITE_ENABLE_OFFSET_SQL_FUNC # undef SQLITE_ENABLE_OFFSET_SQL_FUNC
# undef SQLITE_ENABLE_PREUPDATE_HOOK # undef SQLITE_ENABLE_PREUPDATE_HOOK
# undef SQLITE_ENABLE_RTREE # undef SQLITE_ENABLE_RTREE
# undef SQLITE_ENABLE_SESSION # undef SQLITE_ENABLE_SESSION
# undef SQLITE_ENABLE_STMTVTAB # undef SQLITE_ENABLE_STMTVTAB
# undef SQLITE_OMIT_AUTHORIZATION # undef SQLITE_OMIT_AUTHORIZATION
# define SQLITE_OMIT_AUTHORIZATION # define SQLITE_OMIT_AUTHORIZATION
/*Reminder re. custom sqlite3.c: # undef SQLITE_OMIT_GET_TABLE
# define SQLITE_OMIT_GET_TABLE
# undef SQLITE_OMIT_INCRBLOB
# define SQLITE_OMIT_INCRBLOB
# undef SQLITE_OMIT_INTROSPECTION_PRAGMAS
# define SQLITE_OMIT_INTROSPECTION_PRAGMAS
# undef SQLITE_OMIT_JSON
# define SQLITE_OMIT_JSON
# undef SQLITE_OMIT_PROGRESS_CALLBACK
# define SQLITE_OMIT_PROGRESS_CALLBACK
# undef SQLITE_OMIT_WAL
# define SQLITE_OMIT_WAL
# undef SQLITE_USE_LONG_DOUBLE
# define SQLITE_USE_LONG_DOUBLE 0
/*
The following OMITs do not work with the standard amalgamation, so
require a custom build:
fossil clean -x fossil clean -x
./configure ./configure
OPTS='-DSQLITE_OMIT_VIRTUALTABLE -DSQLITE_OMIT_EXPLAIN -DSQLITE_OMIT_TRIGGER' make -e sqlite3 OPTS='...' make -e sqlite3
*/
/*Requires a custom sqlite3.c where ... has a -D... for each of the following OMIT flags:
# undef SQLITE_OMIT_TRIGGER
# define SQLITE_OMIT_TRIGGER
*/
/*TODO (requires build tweaks)
# undef SQLITE_OMIT_WINDOWFUNC
# define SQLITE_OMIT_WINDOWFUNC
*/
/*Requires a custom sqlite3.c
# undef SQLITE_OMIT_EXPLAIN # undef SQLITE_OMIT_EXPLAIN
# define SQLITE_OMIT_EXPLAIN # define SQLITE_OMIT_EXPLAIN
*/
/*Requires a custom sqlite3.c # undef SQLITE_OMIT_TRIGGER
# define SQLITE_OMIT_TRIGGER
# undef SQLITE_OMIT_VIRTUALTABLE # undef SQLITE_OMIT_VIRTUALTABLE
# define SQLITE_OMIT_VIRTUALTABLE # define SQLITE_OMIT_VIRTUALTABLE
# undef SQLITE_OMIT_WINDOWFUNC
# define SQLITE_OMIT_WINDOWFUNC
As of this writing (2024-07-25), such a build fails in various ways
for as-yet-unknown reasons.
*/ */
# undef SQLITE_OMIT_JSON #endif
# define SQLITE_OMIT_JSON
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_BARE_BONES)
# define SQLITE_WASM_HAS_VTAB 1
#else
# define SQLITE_WASM_HAS_VTAB 0
#endif #endif
#include <assert.h> #include <assert.h>
@@ -243,6 +227,23 @@
// See also: // See also:
//__attribute__((export_name("theExportedName"), used, visibility("default"))) //__attribute__((export_name("theExportedName"), used, visibility("default")))
#if 0
/* Details at https://sqlite.org/forum/forumpost/cbfb0d0ac0a4e349
**
** Summary: changing to `double` reduces the wasm file size by a mere
** 2k. It is hypothetically not possible that any clients rely on
** doubles larger than 64-bit because there is no mapping between C
** and JS for them. i.e. we "could" switch LONGDOUBLE_TYPE to double
** for wasm builds with very little risk of problems. Clang 18.1 maps
** `long double` to float128 but Emscripten doesn't (cannot) expose
** that to JS.
**
** See also: SQLITE_USE_LONG_DOUBLE
*/
#undef LONGDOUBLE_TYPE
#define LONGDOUBLE_TYPE double
#endif
/* /*
** Which sqlite3.c we're using needs to be configurable to enable ** Which sqlite3.c we're using needs to be configurable to enable
** building against a custom copy, e.g. the SEE variant. Note that we ** building against a custom copy, e.g. the SEE variant. Note that we
@@ -264,10 +265,6 @@
#undef INC__STRINGIFY #undef INC__STRINGIFY
#undef SQLITE_C #undef SQLITE_C
#if defined(__EMSCRIPTEN__)
# include <emscripten/console.h>
#endif
#if 0 #if 0
/* /*
** An EXPERIMENT in implementing a stack-based allocator analog to ** An EXPERIMENT in implementing a stack-based allocator analog to
@@ -412,7 +409,7 @@ int sqlite3__wasm_db_error(sqlite3*db, int err_code, const char *zMsg){
return err_code; return err_code;
} }
#if SQLITE_WASM_TESTS #if SQLITE_WASM_ENABLE_C_TESTS
struct WasmTestStruct { struct WasmTestStruct {
int v4; int v4;
void * ppV; void * ppV;
@@ -432,7 +429,7 @@ void sqlite3__wasm_test_struct(WasmTestStruct * s){
} }
return; return;
} }
#endif /* SQLITE_WASM_TESTS */ #endif /* SQLITE_WASM_ENABLE_C_TESTS */
/* /*
** This function is NOT part of the sqlite3 public API. It is strictly ** This function is NOT part of the sqlite3 public API. It is strictly
@@ -967,7 +964,7 @@ const char * sqlite3__wasm_enum_json(void){
} _DefGroup; } _DefGroup;
DefGroup(vtab) { DefGroup(vtab) {
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL) #if SQLITE_WASM_HAS_VTAB
DefInt(SQLITE_INDEX_SCAN_UNIQUE); DefInt(SQLITE_INDEX_SCAN_UNIQUE);
DefInt(SQLITE_INDEX_CONSTRAINT_EQ); DefInt(SQLITE_INDEX_CONSTRAINT_EQ);
DefInt(SQLITE_INDEX_CONSTRAINT_GT); DefInt(SQLITE_INDEX_CONSTRAINT_GT);
@@ -995,7 +992,7 @@ const char * sqlite3__wasm_enum_json(void){
DefInt(SQLITE_FAIL); DefInt(SQLITE_FAIL);
//DefInt(SQLITE_ABORT); // Also an error code //DefInt(SQLITE_ABORT); // Also an error code
DefInt(SQLITE_REPLACE); DefInt(SQLITE_REPLACE);
#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ #endif /*SQLITE_WASM_HAS_VTAB*/
} _DefGroup; } _DefGroup;
#undef DefGroup #undef DefGroup
@@ -1110,6 +1107,7 @@ const char * sqlite3__wasm_enum_json(void){
#undef CurrentStruct #undef CurrentStruct
#if SQLITE_WASM_HAS_VTAB
#define CurrentStruct sqlite3_vtab #define CurrentStruct sqlite3_vtab
StructBinder { StructBinder {
M(pModule, "p"); M(pModule, "p");
@@ -1155,7 +1153,6 @@ const char * sqlite3__wasm_enum_json(void){
} _StructBinder; } _StructBinder;
#undef CurrentStruct #undef CurrentStruct
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL)
/** /**
** Workaround: in order to map the various inner structs from ** Workaround: in order to map the various inner structs from
** sqlite3_index_info, we have to uplift those into constructs we ** sqlite3_index_info, we have to uplift those into constructs we
@@ -1232,9 +1229,9 @@ const char * sqlite3__wasm_enum_json(void){
} _StructBinder; } _StructBinder;
#undef CurrentStruct #undef CurrentStruct
#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ #endif /*SQLITE_WASM_HAS_VTAB*/
#if SQLITE_WASM_TESTS #if SQLITE_WASM_ENABLE_C_TESTS
#define CurrentStruct WasmTestStruct #define CurrentStruct WasmTestStruct
StructBinder { StructBinder {
M(v4, "i"); M(v4, "i");
@@ -1244,7 +1241,7 @@ const char * sqlite3__wasm_enum_json(void){
M(xFunc, "v(p)"); M(xFunc, "v(p)");
} _StructBinder; } _StructBinder;
#undef CurrentStruct #undef CurrentStruct
#endif #endif /*SQLITE_WASM_ENABLE_C_TESTS*/
} out( "]"/*structs*/); } out( "]"/*structs*/);
@@ -1603,7 +1600,7 @@ sqlite3_kvvfs_methods * sqlite3__wasm_kvvfs_methods(void){
return &sqlite3KvvfsMethods; return &sqlite3KvvfsMethods;
} }
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL) #if SQLITE_WASM_HAS_VTAB
/* /*
** This function is NOT part of the sqlite3 public API. It is strictly ** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings. ** for use by the sqlite project's own JS/WASM bindings.
@@ -1626,7 +1623,7 @@ int sqlite3__wasm_vtab_config(sqlite3 *pDb, int op, int arg){
return SQLITE_MISUSE; return SQLITE_MISUSE;
} }
} }
#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ #endif /*SQLITE_WASM_HAS_VTAB*/
/* /*
** This function is NOT part of the sqlite3 public API. It is strictly ** This function is NOT part of the sqlite3 public API. It is strictly
@@ -1750,6 +1747,7 @@ char * sqlite3__wasm_qfmt_token(char *z, int addQuotes){
} }
#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS) #if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
#include <emscripten/console.h>
#include <emscripten/wasmfs.h> #include <emscripten/wasmfs.h>
/* /*
@@ -1801,7 +1799,7 @@ int sqlite3__wasm_init_wasmfs(const char *zUnused){
} }
#endif /* __EMSCRIPTEN__ && SQLITE_ENABLE_WASMFS */ #endif /* __EMSCRIPTEN__ && SQLITE_ENABLE_WASMFS */
#if SQLITE_WASM_TESTS #if SQLITE_WASM_ENABLE_C_TESTS
SQLITE_WASM_EXPORT SQLITE_WASM_EXPORT
int sqlite3__wasm_test_intptr(int * p){ int sqlite3__wasm_test_intptr(int * p){
@@ -1967,6 +1965,9 @@ int sqlite3__wasm_SQLTester_strglob(const char *zGlob, const char *z){
return !sqlite3__wasm_SQLTester_strnotglob(zGlob, z); return !sqlite3__wasm_SQLTester_strnotglob(zGlob, z);
} }
#endif /* SQLITE_WASM_TESTS */ #endif /* SQLITE_WASM_ENABLE_C_TESTS */
#undef SQLITE_WASM_EXPORT #undef SQLITE_WASM_EXPORT
#undef SQLITE_WASM_HAS_VTAB
#undef SQLITE_WASM_BARE_BONES
#undef SQLITE_WASM_ENABLE_C_TESTS

View File

@@ -1,7 +1,8 @@
/* /*
** 2022-11-12: ** 2022-11-12:
** **
** In place of a legal notice, here is a blessing: ** 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 do good and not evil.
** * May you find forgiveness for yourself and forgive others. ** * May you find forgiveness for yourself and forgive others.
@@ -1507,7 +1508,7 @@ int main(int argc, char const * const * argv){
} }
ISFLAG("debug"){ ISFLAG("debug"){
++g.doDebug; ++g.doDebug;
}else if(!zInfile){ }else if(!zInfile && '-'!=argv[i][0]){
goto do_infile; goto do_infile;
}else{ }else{
fatal("Unhandled flag: %s", argv[i]); fatal("Unhandled flag: %s", argv[i]);

View File

@@ -7,21 +7,23 @@ MAKEFILE.fiddle := $(lastword $(MAKEFILE_LIST))
######################################################################## ########################################################################
# shell.c and its build flags... # shell.c and its build flags...
make-np-0 := make -C $(dir.top) -n -p ifneq (1,$(MAKING_CLEAN))
make-np-1 := sed -e 's/(TOP)/(dir.top)/g' make-np-0 := make -C $(dir.top) -n -p
# Extract SHELL_OPT and SHELL_DEP from the top-most makefile and import make-np-1 := sed -e 's/(TOP)/(dir.top)/g'
# them as vars here... # Extract SHELL_OPT and SHELL_DEP from the top-most makefile and import
$(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1))) # them as vars here...
$(eval $(shell $(make-np-0) | grep -e '^SHELL_DEP ' | $(make-np-1))) $(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1)))
# ^^^ can't do that in 1 invocation b/c newlines get stripped $(eval $(shell $(make-np-0) | grep -e '^SHELL_DEP ' | $(make-np-1)))
ifeq (,$(SHELL_OPT)) # ^^^ can't do that in 1 invocation b/c newlines get stripped
$(error Could not parse SHELL_OPT from $(dir.top)/Makefile.) ifeq (,$(SHELL_OPT))
endif $(error Could not parse SHELL_OPT from $(dir.top)/Makefile.)
ifeq (,$(SHELL_DEP)) endif
$(error Could not parse SHELL_DEP from $(dir.top)/Makefile.) ifeq (,$(SHELL_DEP))
endif $(error Could not parse SHELL_DEP from $(dir.top)/Makefile.)
$(dir.top)/shell.c: $(SHELL_DEP) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c) endif
$(dir.top)/shell.c: $(SHELL_DEP) $(dir.tool)/mkshellc.tcl $(sqlite3.c)
$(MAKE) -C $(dir.top) shell.c $(MAKE) -C $(dir.top) shell.c
endif
# /shell.c # /shell.c
######################################################################## ########################################################################
@@ -41,10 +43,11 @@ fiddle.emcc-flags = \
$(emcc.exportedRuntimeMethods) \ $(emcc.exportedRuntimeMethods) \
-sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \ -sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \
-sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \ -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \
$(SQLITE_OPT) $(SHELL_OPT) \ $(SQLITE_OPT.full-featured) \
-USQLITE_WASM_MINIMAL \ $(SQLITE_OPT.common) \
$(SHELL_OPT) \
-USQLITE_WASM_BARE_BONES \
-DSQLITE_SHELL_FIDDLE -DSQLITE_SHELL_FIDDLE
# -D_POSIX_C_SOURCE is needed for strdup() with emcc
# Flags specifically for debug builds of fiddle. Performance suffers # Flags specifically for debug builds of fiddle. Performance suffers
# greatly in debug builds. # greatly in debug builds.
@@ -55,52 +58,22 @@ fiddle.emcc-flags.debug := $(fiddle.emcc-flags) \
fiddle.EXPORTED_FUNCTIONS.in := \ fiddle.EXPORTED_FUNCTIONS.in := \
EXPORTED_FUNCTIONS.fiddle.in \ EXPORTED_FUNCTIONS.fiddle.in \
$(EXPORTED_FUNCTIONS.api) $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE.fiddle) $(EXPORTED_FUNCTIONS.fiddle): $(MKDIR.bld) $(fiddle.EXPORTED_FUNCTIONS.in) \
$(MAKEFILE.fiddle)
sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@ sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
fiddle.cses := $(dir.top)/shell.c $(sqlite3-wasm.c) fiddle.cses := $(dir.top)/shell.c $(sqlite3-wasm.c)
$(eval $(call call-make-pre-post,fiddle-module,vanilla))
########################################################################
# emit rules for one of the two fiddle builds. $1 must be
# either $(dir.fiddle) or $(dir.fiddle-debug). $2 must be empty
# in the former case and .debug in the latter.
define make-fiddle-rules
fiddle-module.js$(2) := $(1)/fiddle-module.js
fiddle-module.wasm$(2) := $$(subst .js,.wasm,$$(fiddle-module.js$(2)))
$$(fiddle-module.js$(2)): $$(MAKEFILE) $$(MAKEFILE.fiddle) \
$$(EXPORTED_FUNCTIONS.fiddle) \
$$(fiddle.cses) $$(pre-post-fiddle-module-vanilla.deps) $$(SOAP.js)
@test -d "$$(dir $$@)" || mkdir -p "$$(dir $$@)"
$$(emcc.bin) -o $$@ $$(fiddle.emcc-flags$(2)) \
$$(pre-post-fiddle-module-vanilla.flags) \
$$(fiddle.cses)
$$(maybe-wasm-strip) $$(fiddle-module.wasm$(2))
@cp -p $$(SOAP.js) $$(dir $$@)
@if [[ x.debug = x$(2) ]]; then \
cp -p $$(dir.fiddle)/index.html \
$$(dir.fiddle)/fiddle.js \
$$(dir.fiddle)/fiddle-worker.js \
$$(dir $$@)/.; \
fi
@for i in $(1)/*.*js $(1)/*.html $(1)/*.wasm; do \
test -f $$$${i} || continue; \
gzip < $$$${i} > $$$${i}.gz; \
done
fiddle$(2): $$(fiddle-module.js$(2)) $(1)/fiddle.js.gz
endef
$(eval $(call make-fiddle-rules,$(dir.fiddle)))
$(eval $(call make-fiddle-rules,$(dir.fiddle-debug),.debug))
fiddle: $(fiddle-module.js) $(fiddle-module.js.debug) fiddle: $(fiddle-module.js) $(fiddle-module.js.debug)
fiddle.debug: $(fiddle-module.js.debug) fiddle.debug: $(fiddle-module.js.debug)
clean: clean-fiddle clean: clean-fiddle
clean-fiddle: clean-fiddle:
rm -f $(fiddle-module.js) \ rm -f $(dir.fiddle)/fiddle-module.js \
$(fiddle-module.wasm) \ $(dir.fiddle)/*.wasm \
$(dir.fiddle)/sqlite3-opfs-*.js \ $(dir.fiddle)/sqlite3-opfs-*.js \
$(dir.fiddle)/*.gz \ $(dir.fiddle)/*.gz \
EXPORTED_FUNCTIONS.fiddle EXPORTED_FUNCTIONS.fiddle

View File

@@ -9,7 +9,6 @@
two lines and ensure that these files are on the web server. --> two lines and ensure that these files are on the web server. -->
<!--script src="jqterm/jqterm-bundle.min.js"></script> <!--script src="jqterm/jqterm-bundle.min.js"></script>
<link rel="stylesheet" href="jqterm/jquery.terminal.min.css"/--> <link rel="stylesheet" href="jqterm/jquery.terminal.min.css"/-->
<link rel="stylesheet" href="emscripten.css"/>
<style> <style>
/* The following styles are for app-level use. */ /* The following styles are for app-level use. */
:root { :root {

View File

@@ -125,10 +125,10 @@
the WASMFS build is available on this server (it is not by the WASMFS build is available on this server (it is not by
default) and that this server emits the COOP/COEP headers. default) and that this server emits the COOP/COEP headers.
<ul> <ul>
<li><a href='scratchpad-wasmfs.html'>scratchpad-wasmfs</a>: <!--li><a href='scratchpad-wasmfs.html'>scratchpad-wasmfs</a>:
experimenting with WASMFS/OPFS-based persistence. experimenting with WASMFS/OPFS-based persistence.
</li> </li-->
<li><a href='speedtest1-wasmfs.html?flags=--size,15'>speedtest1-wasmfs</a>: <li><a href='speedtest1-wasmfs.html?flags=--size,10'>speedtest1-wasmfs</a>:
a variant of speedtest1 built solely for the wasmfs/opfs a variant of speedtest1 built solely for the wasmfs/opfs
feature. feature.
</li> </li>

284
ext/wasm/mkwasmbuilds.c Normal file
View File

@@ -0,0 +1,284 @@
/*
** 2024-09-23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This app's single purpose is to emit parts of the Makefile code for
** building sqlite3's WASM build. The main motivation is to generate
** code which "can" be created via GNU Make's eval command but is
** highly illegible when constructed that way. Attempts to write this
** app in Bash and TCL have suffered from the problem that both
** require escaping $ symbols, making the resulting script code as
** illegible as the eval spaghetti we want to get away from. Writing
** it in C is, somewhat surprisingly, _slightly_ less illegible than
** writing it in bash, tcl, or native Make code.
**
** The emitted makefile code is not standalone - it depends on
** variables and $(call)able functions from the main makefile.
**
*/
#undef NDEBUG
#define DEBUG 1
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define pf printf
#define ps puts
/* Very common printf() args combo. */
#define zNM zName, zMode
/*
** Valid names for the zName arguments.
*/
#define JS_BUILD_NAMES sqlite3 sqlite3-wasmfs
/*
** Valid names for the zMode arguments of the "sqlite3" build. For the
** "sqlite3-wasmfs" build, only "esm" (ES6 Module) is legal.
*/
#define JS_BUILD_MODES vanilla esm bundler-friendly node
static const char * zBanner =
"\n########################################################################\n";
/*
** Emits common vars needed by the rest of the emitted code (but not
** needed by makefile code outside of these generated pieces).
*/
static void mk_prologue(void){
pf("%s", zBanner);
ps("# extern-post-js* and extern-pre-js* are files for use with");
ps("# Emscripten's --extern-pre-js and --extern-post-js flags.");
ps("extern-pre-js.js := $(dir.api)/extern-pre-js.js");
ps("extern-post-js.js.in := $(dir.api)/extern-post-js.c-pp.js");
ps("# Emscripten flags for --[extern-][pre|post]-js=... for the");
ps("# various builds.");
ps("pre-post-common.flags := --extern-pre-js=$(sqlite3-license-version.js)");
ps("# pre-post-jses.deps.* = a list of dependencies for the");
ps("# --[extern-][pre/post]-js files.");
ps("pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)");
}
/*
** Emits makefile code for setting up values for the --pre-js=FILE,
** --post-js=FILE, and --extern-post-js=FILE emcc flags, as well as
** populating those files.
*/
static void mk_pre_post(const char *zName /* build name */,
const char *zMode /* build mode */,
const char *zCmppD /* optional -D flags for c-pp for the
** --pre/--post-js files. */){
pf("%s# Begin --pre/--post flags for %s-%s\n", zBanner, zName, zMode);
pf("c-pp.D.%s-%s := %s\n", zNM, zCmppD ? zCmppD : "");
pf("pre-post-%s-%s.flags ?=\n", zNM);
/* --pre-js=... */
pf("pre-js.js.%s-%s := $(dir.tmp)/pre-js.%s-%s.js\n",
zNM, zNM);
pf("$(pre-js.js.%s-%s): $(MAKEFILE)\n", zNM);
#if 1
pf("$(eval $(call C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s),"
"$(c-pp.D.%s-%s)))\n", zNM, zNM);
#else
/* This part is needed if/when we re-enable the custom
** Module.instantiateModule() impl in api/pre-js.c-pp.js. */
pf("pre-js.js.%s-%s.intermediary := $(dir.tmp)/pre-js.%s-%s.intermediary.js\n",
zNM, zNM);
pf("$(eval $(call C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s.intermediary),"
"$(c-pp.D.%s-%s) -Dcustom-Module.instantiateModule))\n", zNM, zNM);
pf("$(pre-js.js.%s-%s): $(pre-js.js.%s-%s.intermediary)\n", zNM, zNM);
pf("\tcp $(pre-js.js.%s-%s.intermediary) $@\n", zNM);
/* Amend $(pre-js.js.zName-zMode) for all targets except the plain
** "sqlite3" build... */
if( 0!=strcmp("sqlite3-wasmfs", zName)
&& 0!=strcmp("sqlite3", zName) ){
pf("\t@echo 'Module[xNameOfInstantiateWasm].uri = "
"\"%s.wasm\";' >> $@\n", zName);
}
#endif
/* --post-js=... */
pf("post-js.js.%s-%s := $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM);
pf("$(eval $(call C-PP.FILTER,$(post-js.js.in),"
"$(post-js.js.%s-%s),$(c-pp.D.%s-%s)))\n", zNM, zNM);
/* --extern-post-js=... */
pf("extern-post-js.js.%s-%s := $(dir.tmp)/extern-post-js.%s-%s.js\n", zNM, zNM);
pf("$(eval $(call C-PP.FILTER,$(extern-post-js.js.in),$(extern-post-js.js.%s-%s),"
"$(c-pp.D.%s-%s)))\n", zNM, zNM);
/* Combine flags for use with emcc... */
pf("pre-post-common.flags.%s-%s := "
"$(pre-post-common.flags) "
"--post-js=$(post-js.js.%s-%s) "
"--extern-post-js=$(extern-post-js.js.%s-%s)\n", zNM, zNM, zNM);
pf("pre-post-%s-%s.flags += $(pre-post-common.flags.%s-%s) "
"--pre-js=$(pre-js.js.%s-%s)\n", zNM, zNM, zNM);
/* Set up deps... */
pf("pre-post-jses.%s-%s.deps := $(pre-post-jses.deps.common) "
"$(post-js.js.%s-%s) $(extern-post-js.js.%s-%s)\n",
zNM, zNM, zNM);
pf("pre-post-%s-%s.deps := $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n",
zNM, zNM, zNM);
pf("# End --pre/--post flags for %s-%s%s", zName, zMode, zBanner);
}
/*
** Emits rules for the fiddle builds.
**
*/
static void mk_fiddle(){
int i = 0;
mk_pre_post("fiddle-module","vanilla", 0);
for( ; i < 2; ++i ){
const char *zTail = i ? ".debug" : "";
const char *zDir = i ? "$(dir.fiddle-debug)" : "$(dir.fiddle)";
pf("%s# Begin fiddle%s\n", zBanner, zTail);
pf("fiddle-module.js%s := %s/fiddle-module.js\n", zTail, zDir);
pf("fiddle-module.wasm%s := "
"$(subst .js,.wasm,$(fiddle-module.js%s))\n", zTail, zTail);
pf("$(fiddle-module.js%s):%s $(MAKEFILE) $(MAKEFILE.fiddle) "
"$(EXPORTED_FUNCTIONS.fiddle) "
"$(fiddle.cses) $(pre-post-fiddle-module-vanilla.deps) "
"$(SOAP.js)\n",
zTail, (i ? " $(fiddle-module.js)" : ""));
if( 1==i ){/*fiddle.debug*/
pf(" @test -d \"$(dir $@)\" || mkdir -p \"$(dir $@)\"\n");
}
pf(" $(emcc.bin) -o $@ $(fiddle.emcc-flags%s) "
"$(pre-post-fiddle-module-vanilla.flags) $(fiddle.cses)\n",
zTail);
pf(" $(maybe-wasm-strip) $(fiddle-module.wasm%s)\n", zTail);
pf(" @cp -p $(SOAP.js) $(dir $@)\n");
if( 1==i ){/*fiddle.debug*/
pf(" cp -p $(dir.fiddle)/index.html "
"$(dir.fiddle)/fiddle.js "
"$(dir.fiddle)/fiddle-worker.js "
"$(dir $@)\n");
}
pf(" @for i in %s/*.*js %s/*.html %s/*.wasm; do \\\n"
" test -f $${i} || continue; \\\n"
" gzip < $${i} > $${i}.gz; \\\n"
" done\n", zDir, zDir, zDir);
if( 0==i ){
ps("fiddle: $(fiddle-module.js)");
}else{
ps("fiddle-debug: $(fiddle-module-debug.js)");
}
pf("# End fiddle%s%s", zTail, zBanner);
}
}
/*
** Emits makefile code for one build of the library, primarily defined
** by the combination of zName and zMode, each of which must be values
** from JS_BUILD_NAMES resp. JS_BUILD_MODES.
*/
static void mk_lib_mode(const char *zName /* build name */,
const char *zMode /* build mode */,
int bIsEsm /* true only for ESM build */,
const char *zApiJsOut /* name of generated sqlite3-api.js/.mjs */,
const char *zJsOut /* name of generated sqlite3.js/.mjs */,
const char *zCmppD /* extra -D flags for c-pp */,
const char *zEmcc /* extra flags for emcc */){
assert( zName );
assert( zMode );
assert( zApiJsOut );
assert( zJsOut );
if( !zCmppD ) zCmppD = "";
if( !zEmcc ) zEmcc = "";
pf("%s# Begin build [%s-%s]\n", zBanner, zNM);
pf("ifneq (1,$(MAKING_CLEAN))\n");
pf("$(info Setting up build [%s-%s]: %s)\n", zNM, zJsOut);
mk_pre_post(zNM, zCmppD);
pf("\nemcc.flags.%s.%s ?=\n", zNM);
if( zEmcc[0] ){
pf("emcc.flags.%s.%s += %s\n", zNM, zEmcc);
}
pf("$(eval $(call C-PP.FILTER, $(sqlite3-api.js.in), %s, %s))\n",
zApiJsOut, zCmppD);
/* target zJsOut */
pf("%s: %s $(MAKEFILE) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) "
"$(pre-post-%s-%s.deps)\n",
zJsOut, zApiJsOut, zNM);
pf("\t@echo \"Building $@ ...\"\n");
pf("\t$(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n");
pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", zMode);
pf("\t\t$(pre-post-%s-%s.flags) \\\n", zNM);
pf("\t\t$(emcc.flags.%s) $(emcc.flags.%s.%s) \\\n", zName, zNM);
pf("\t\t$(cflags.common) $(SQLITE_OPT) \\\n"
"\t\t$(cflags.%s) $(cflags.%s.%s) \\\n"
"\t\t$(cflags.wasm_extra_init) $(sqlite3-wasm.cfiles)\n", zName, zNM);
if( bIsEsm ){
/* TODO? Replace this CALL with the corresponding makefile code.
** OTOH, we also use this $(call) in the speedtest1-wasmfs build,
** which is not part of the rules emitted by this program. */
pf("\t@$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1,%d)\n",
0==strcmp("sqlite3-wasmfs", zName) ? 1 : 0);
}
pf("\t@dotwasm=$(basename $@).wasm; \\\n"
"\tchmod -x $$dotwasm; \\\n"
"\t$(maybe-wasm-strip) $$dotwasm; \\\n");
/*
** The above $(emcc.bin) call will write zJsOut and will create a
** like-named .wasm file. That .wasm file name gets hard-coded into
** zJsOut so we need to, for some cases, patch zJsOut to use the
** name sqlite3.wasm instead. Note that the resulting .wasm file is
** identical for all builds for which zEmcc is empty.
*/
if( 0==strcmp("bundler-friendly", zMode)
|| 0==strcmp("node", zMode) ) {
pf("\techo 'Patching $@ for %s.wasm...' \\\n", zName);
pf("\trm -f $$dotwasm; dotwasm=; \\\n"
"\tsed -i -e 's/%s-%s.wasm/%s.wasm/g' $@ || exit $$?; \\\n",
zNM, zName);
}
pf("\tls -la $$dotwasm $@\n");
if( 0!=strcmp("sqlite3-wasmfs", zName) ){
/* The sqlite3-wasmfs build is optional and needs to be invoked
** conditionally using info we don't have here. */
pf("all: %s\n", zJsOut);
}
ps("endif\n# ^^^ !$(MAKING_CLEAN)");
pf("# End build [%s-%s]%s", zNM, zBanner);
}
int main(void){
int rc = 0;
pf("# What follows was GENERATED by %s. Edit at your own risk.\n", __FILE__);
mk_prologue();
mk_lib_mode("sqlite3", "vanilla", 0,
"$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0);
mk_lib_mode("sqlite3", "esm", 1,
"$(sqlite3-api.mjs)", "$(sqlite3.mjs)",
"-Dtarget=es6-module", 0);
mk_lib_mode("sqlite3", "bundler-friendly", 1,
"$(sqlite3-api-bundler-friendly.mjs)", "$(sqlite3-bundler-friendly.mjs)",
"$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0);
mk_lib_mode("sqlite3" , "node", 1,
"$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)",
"$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0);
mk_lib_mode("sqlite3-wasmfs", "esm" ,1,
"$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)",
"$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs",
"-sEXPORT_ES6 -sUSE_ES6_IMPORT_META");
mk_fiddle();
mk_pre_post("speedtest1","vanilla", 0);
mk_pre_post("speedtest1-wasmfs","esm", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs");
return rc;
}

View File

@@ -10,14 +10,14 @@ wMsg('log',"speedtest1-wasmfs starting...");
*/ */
const wasmfsDir = function f(wasmUtil,dirName="/opfs"){ const wasmfsDir = function f(wasmUtil,dirName="/opfs"){
if(undefined !== f._) return f._; if(undefined !== f._) return f._;
if( !self.FileSystemHandle if( !globalThis.FileSystemHandle
|| !self.FileSystemDirectoryHandle || !globalThis.FileSystemDirectoryHandle
|| !self.FileSystemFileHandle){ || !globalThis.FileSystemFileHandle){
return f._ = ""; return f._ = "";
} }
try{ try{
if(0===wasmUtil.xCallWrapped( if(0===wasmUtil.xCallWrapped(
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName 'sqlite3__wasm_init_wasmfs', 'i32', ['string'], dirName
)){ )){
return f._ = dirName; return f._ = dirName;
}else{ }else{
@@ -36,7 +36,7 @@ const logErr = (...args)=>wMsg('logErr',...args);
const runTests = function(sqlite3){ const runTests = function(sqlite3){
console.log("Module inited.",sqlite3); console.log("Module inited.",sqlite3);
const wasm = sqlite3.wasm; const wasm = sqlite3.wasm;
const __unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["*","string"]); const __unlink = wasm.xWrap("sqlite3__wasm_vfs_unlink", "int", ["*","string"]);
const unlink = (fn)=>__unlink(0,fn); const unlink = (fn)=>__unlink(0,fn);
const pDir = wasmfsDir(wasm); const pDir = wasmfsDir(wasm);
if(pDir) log("Persistent storage:",pDir); if(pDir) log("Persistent storage:",pDir);
@@ -46,7 +46,7 @@ const runTests = function(sqlite3){
} }
const scope = wasm.scopedAllocPush(); const scope = wasm.scopedAllocPush();
const dbFile = pDir+"/speedtest1.db"; const dbFile = pDir+"/speedtest1.db";
const urlParams = new URL(self.location.href).searchParams; const urlParams = new URL(globalThis.location.href).searchParams;
const argv = ["speedtest1"]; const argv = ["speedtest1"];
if(urlParams.has('flags')){ if(urlParams.has('flags')){
argv.push(...(urlParams.get('flags').split(','))); argv.push(...(urlParams.get('flags').split(',')));

View File

@@ -848,171 +848,176 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}/*WhWasmUtil*/) }/*WhWasmUtil*/)
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
.t('sqlite3.StructBinder (jaccwabyt🐇)', function(sqlite3){ .t({
const S = sqlite3, W = S.wasm; name: 'sqlite3.StructBinder (jaccwabyt🐇)',
const MyStructDef = { predicate: (sqlite3)=>!!sqlite3.wasm.exports.sqlite3__wasm_test_struct
sizeof: 16, || "Built without SQLITE_WASM_ENABLE_C_TESTS",
members: { test: function(sqlite3){
p4: {offset: 0, sizeof: 4, signature: "i"}, const S = sqlite3, W = S.wasm;
pP: {offset: 4, sizeof: 4, signature: "P"}, const MyStructDef = {
ro: {offset: 8, sizeof: 4, signature: "i", readOnly: true}, sizeof: 16,
cstr: {offset: 12, sizeof: 4, signature: "s"} members: {
} p4: {offset: 0, sizeof: 4, signature: "i"},
}; pP: {offset: 4, sizeof: 4, signature: "P"},
if(W.bigIntEnabled){ ro: {offset: 8, sizeof: 4, signature: "i", readOnly: true},
const m = MyStructDef; cstr: {offset: 12, sizeof: 4, signature: "s"}
m.members.p8 = {offset: m.sizeof, sizeof: 8, signature: "j"};
m.sizeof += m.members.p8.sizeof;
}
const StructType = S.StructBinder.StructType;
const K = S.StructBinder('my_struct',MyStructDef);
T.mustThrowMatching(()=>K(), /via 'new'/).
mustThrowMatching(()=>new K('hi'), /^Invalid pointer/);
const k1 = new K(), k2 = new K();
try {
T.assert(k1.constructor === K).
assert(K.isA(k1)).
assert(k1 instanceof K).
assert(K.prototype.lookupMember('p4').key === '$p4').
assert(K.prototype.lookupMember('$p4').name === 'p4').
mustThrowMatching(()=>K.prototype.lookupMember('nope'), /not a mapped/).
assert(undefined === K.prototype.lookupMember('nope',false)).
assert(k1 instanceof StructType).
assert(StructType.isA(k1)).
mustThrowMatching(()=>k1.$ro = 1, /read-only/);
Object.keys(MyStructDef.members).forEach(function(key){
key = K.memberKey(key);
T.assert(0 == k1[key],
"Expecting allocation to zero the memory "+
"for "+key+" but got: "+k1[key]+
" from "+k1.memoryDump());
});
T.assert('number' === typeof k1.pointer).
mustThrowMatching(()=>k1.pointer = 1, /pointer/);
k1.$p4 = 1; k1.$pP = 2;
T.assert(1 === k1.$p4).assert(2 === k1.$pP);
if(MyStructDef.members.$p8){
k1.$p8 = 1/*must not throw despite not being a BigInt*/;
k1.$p8 = BigInt(Number.MAX_SAFE_INTEGER * 2);
T.assert(BigInt(2 * Number.MAX_SAFE_INTEGER) === k1.$p8);
}
T.assert(!k1.ondispose);
k1.setMemberCString('cstr', "A C-string.");
T.assert(Array.isArray(k1.ondispose)).
assert(k1.ondispose[0] === k1.$cstr).
assert('number' === typeof k1.$cstr).
assert('A C-string.' === k1.memberToJsString('cstr'));
k1.$pP = k2;
T.assert(k1.$pP === k2.pointer);
k1.$pP = null/*null is special-cased to 0.*/;
T.assert(0===k1.$pP);
let ptr = k1.pointer;
k1.dispose();
T.assert(undefined === k1.pointer).
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
}finally{
k1.dispose();
k2.dispose();
}
if(!W.bigIntEnabled){
log("Skipping WasmTestStruct tests: BigInt not enabled.");
return;
}
const WTStructDesc =
W.ctype.structs.filter((e)=>'WasmTestStruct'===e.name)[0];
const autoResolvePtr = true /* EXPERIMENTAL */;
if(autoResolvePtr){
WTStructDesc.members.ppV.signature = 'P';
}
const WTStruct = S.StructBinder(WTStructDesc);
//log(WTStruct.structName, WTStruct.structInfo);
const wts = new WTStruct();
//log("WTStruct.prototype keys:",Object.keys(WTStruct.prototype));
try{
T.assert(wts.constructor === WTStruct).
assert(WTStruct.memberKeys().indexOf('$ppV')>=0).
assert(wts.memberKeys().indexOf('$v8')>=0).
assert(!K.isA(wts)).
assert(WTStruct.isA(wts)).
assert(wts instanceof WTStruct).
assert(wts instanceof StructType).
assert(StructType.isA(wts)).
assert(wts.pointer>0).assert(0===wts.$v4).assert(0n===wts.$v8).
assert(0===wts.$ppV).assert(0===wts.$xFunc);
const testFunc =
W.xGet('sqlite3__wasm_test_struct'/*name gets mangled in -O3 builds!*/);
let counter = 0;
//log("wts.pointer =",wts.pointer);
const wtsFunc = function(arg){
/*log("This from a JS function called from C, "+
"which itself was called from JS. arg =",arg);*/
++counter;
if(3===counter){
tossQuietly("Testing exception propagation.");
} }
};
if(W.bigIntEnabled){
const m = MyStructDef;
m.members.p8 = {offset: m.sizeof, sizeof: 8, signature: "j"};
m.sizeof += m.members.p8.sizeof;
}
const StructType = S.StructBinder.StructType;
const K = S.StructBinder('my_struct',MyStructDef);
T.mustThrowMatching(()=>K(), /via 'new'/).
mustThrowMatching(()=>new K('hi'), /^Invalid pointer/);
const k1 = new K(), k2 = new K();
try {
T.assert(k1.constructor === K).
assert(K.isA(k1)).
assert(k1 instanceof K).
assert(K.prototype.lookupMember('p4').key === '$p4').
assert(K.prototype.lookupMember('$p4').name === 'p4').
mustThrowMatching(()=>K.prototype.lookupMember('nope'), /not a mapped/).
assert(undefined === K.prototype.lookupMember('nope',false)).
assert(k1 instanceof StructType).
assert(StructType.isA(k1)).
mustThrowMatching(()=>k1.$ro = 1, /read-only/);
Object.keys(MyStructDef.members).forEach(function(key){
key = K.memberKey(key);
T.assert(0 == k1[key],
"Expecting allocation to zero the memory "+
"for "+key+" but got: "+k1[key]+
" from "+k1.memoryDump());
});
T.assert('number' === typeof k1.pointer).
mustThrowMatching(()=>k1.pointer = 1, /pointer/);
k1.$p4 = 1; k1.$pP = 2;
T.assert(1 === k1.$p4).assert(2 === k1.$pP);
if(MyStructDef.members.$p8){
k1.$p8 = 1/*must not throw despite not being a BigInt*/;
k1.$p8 = BigInt(Number.MAX_SAFE_INTEGER * 2);
T.assert(BigInt(2 * Number.MAX_SAFE_INTEGER) === k1.$p8);
}
T.assert(!k1.ondispose);
k1.setMemberCString('cstr', "A C-string.");
T.assert(Array.isArray(k1.ondispose)).
assert(k1.ondispose[0] === k1.$cstr).
assert('number' === typeof k1.$cstr).
assert('A C-string.' === k1.memberToJsString('cstr'));
k1.$pP = k2;
T.assert(k1.$pP === k2.pointer);
k1.$pP = null/*null is special-cased to 0.*/;
T.assert(0===k1.$pP);
let ptr = k1.pointer;
k1.dispose();
T.assert(undefined === k1.pointer).
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
}finally{
k1.dispose();
k2.dispose();
} }
wts.$v4 = 10; wts.$v8 = 20;
wts.$xFunc = W.installFunction(wtsFunc, wts.memberSignature('xFunc'))
T.assert(0===counter).assert(10 === wts.$v4).assert(20n === wts.$v8)
.assert(0 === wts.$ppV).assert('number' === typeof wts.$xFunc)
.assert(0 === wts.$cstr)
.assert(wts.memberIsString('$cstr'))
.assert(!wts.memberIsString('$v4'))
.assert(null === wts.memberToJsString('$cstr'))
.assert(W.functionEntry(wts.$xFunc) instanceof Function);
/* It might seem silly to assert that the values match
what we just set, but recall that all of those property
reads and writes are, via property interceptors,
actually marshaling their data to/from a raw memory
buffer, so merely reading them back is actually part of
testing the struct-wrapping API. */
testFunc(wts.pointer); if(!W.bigIntEnabled){
//log("wts.pointer, wts.$ppV",wts.pointer, wts.$ppV); log("Skipping WasmTestStruct tests: BigInt not enabled.");
T.assert(1===counter).assert(20 === wts.$v4).assert(40n === wts.$v8) return;
.assert(wts.$ppV === wts.pointer) }
.assert('string' === typeof wts.memberToJsString('cstr'))
.assert(wts.memberToJsString('cstr') === wts.memberToJsString('$cstr'))
.mustThrowMatching(()=>wts.memberToJsString('xFunc'),
/Invalid member type signature for C-string/)
;
testFunc(wts.pointer);
T.assert(2===counter).assert(40 === wts.$v4).assert(80n === wts.$v8)
.assert(wts.$ppV === wts.pointer);
/** The 3rd call to wtsFunc throw from JS, which is called
from C, which is called from JS. Let's ensure that
that exception propagates back here... */
T.mustThrowMatching(()=>testFunc(wts.pointer),/^Testing/);
W.uninstallFunction(wts.$xFunc);
wts.$xFunc = 0;
wts.$ppV = 0;
T.assert(!wts.$ppV);
//WTStruct.debugFlags(0x03);
wts.$ppV = wts;
T.assert(wts.pointer === wts.$ppV)
wts.setMemberCString('cstr', "A C-string.");
T.assert(Array.isArray(wts.ondispose)).
assert(wts.ondispose[0] === wts.$cstr).
assert('A C-string.' === wts.memberToJsString('cstr'));
const ptr = wts.pointer;
wts.dispose();
T.assert(ptr).assert(undefined === wts.pointer);
}finally{
wts.dispose();
}
if(1){ // ondispose of other struct instances const WTStructDesc =
const s1 = new WTStruct, s2 = new WTStruct, s3 = new WTStruct; W.ctype.structs.filter((e)=>'WasmTestStruct'===e.name)[0];
T.assert(s1.lookupMember instanceof Function) const autoResolvePtr = true /* EXPERIMENTAL */;
.assert(s1.addOnDispose instanceof Function); if(autoResolvePtr){
s1.addOnDispose(s2,"testing variadic args"); WTStructDesc.members.ppV.signature = 'P';
T.assert(2===s1.ondispose.length); }
s2.addOnDispose(s3); const WTStruct = S.StructBinder(WTStructDesc);
s1.dispose(); //log(WTStruct.structName, WTStruct.structInfo);
T.assert(!s2.pointer,"Expecting s2 to be ondispose'd by s1."); const wts = new WTStruct();
T.assert(!s3.pointer,"Expecting s3 to be ondispose'd by s2."); //log("WTStruct.prototype keys:",Object.keys(WTStruct.prototype));
try{
T.assert(wts.constructor === WTStruct).
assert(WTStruct.memberKeys().indexOf('$ppV')>=0).
assert(wts.memberKeys().indexOf('$v8')>=0).
assert(!K.isA(wts)).
assert(WTStruct.isA(wts)).
assert(wts instanceof WTStruct).
assert(wts instanceof StructType).
assert(StructType.isA(wts)).
assert(wts.pointer>0).assert(0===wts.$v4).assert(0n===wts.$v8).
assert(0===wts.$ppV).assert(0===wts.$xFunc);
const testFunc =
W.xGet('sqlite3__wasm_test_struct'/*name gets mangled in -O3 builds!*/);
let counter = 0;
//log("wts.pointer =",wts.pointer);
const wtsFunc = function(arg){
/*log("This from a JS function called from C, "+
"which itself was called from JS. arg =",arg);*/
++counter;
if(3===counter){
tossQuietly("Testing exception propagation.");
}
}
wts.$v4 = 10; wts.$v8 = 20;
wts.$xFunc = W.installFunction(wtsFunc, wts.memberSignature('xFunc'))
T.assert(0===counter).assert(10 === wts.$v4).assert(20n === wts.$v8)
.assert(0 === wts.$ppV).assert('number' === typeof wts.$xFunc)
.assert(0 === wts.$cstr)
.assert(wts.memberIsString('$cstr'))
.assert(!wts.memberIsString('$v4'))
.assert(null === wts.memberToJsString('$cstr'))
.assert(W.functionEntry(wts.$xFunc) instanceof Function);
/* It might seem silly to assert that the values match
what we just set, but recall that all of those property
reads and writes are, via property interceptors,
actually marshaling their data to/from a raw memory
buffer, so merely reading them back is actually part of
testing the struct-wrapping API. */
testFunc(wts.pointer);
//log("wts.pointer, wts.$ppV",wts.pointer, wts.$ppV);
T.assert(1===counter).assert(20 === wts.$v4).assert(40n === wts.$v8)
.assert(wts.$ppV === wts.pointer)
.assert('string' === typeof wts.memberToJsString('cstr'))
.assert(wts.memberToJsString('cstr') === wts.memberToJsString('$cstr'))
.mustThrowMatching(()=>wts.memberToJsString('xFunc'),
/Invalid member type signature for C-string/)
;
testFunc(wts.pointer);
T.assert(2===counter).assert(40 === wts.$v4).assert(80n === wts.$v8)
.assert(wts.$ppV === wts.pointer);
/** The 3rd call to wtsFunc throw from JS, which is called
from C, which is called from JS. Let's ensure that
that exception propagates back here... */
T.mustThrowMatching(()=>testFunc(wts.pointer),/^Testing/);
W.uninstallFunction(wts.$xFunc);
wts.$xFunc = 0;
wts.$ppV = 0;
T.assert(!wts.$ppV);
//WTStruct.debugFlags(0x03);
wts.$ppV = wts;
T.assert(wts.pointer === wts.$ppV)
wts.setMemberCString('cstr', "A C-string.");
T.assert(Array.isArray(wts.ondispose)).
assert(wts.ondispose[0] === wts.$cstr).
assert('A C-string.' === wts.memberToJsString('cstr'));
const ptr = wts.pointer;
wts.dispose();
T.assert(ptr).assert(undefined === wts.pointer);
}finally{
wts.dispose();
}
if(1){ // ondispose of other struct instances
const s1 = new WTStruct, s2 = new WTStruct, s3 = new WTStruct;
T.assert(s1.lookupMember instanceof Function)
.assert(s1.addOnDispose instanceof Function);
s1.addOnDispose(s2,"testing variadic args");
T.assert(2===s1.ondispose.length);
s2.addOnDispose(s3);
s1.dispose();
T.assert(!s2.pointer,"Expecting s2 to be ondispose'd by s1.");
T.assert(!s3.pointer,"Expecting s3 to be ondispose'd by s2.");
}
} }
}/*StructBinder*/) }/*StructBinder*/)
@@ -1126,75 +1131,83 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
T.g('sqlite3.oo1') T.g('sqlite3.oo1')
.t('Create db', function(sqlite3){ .t({
const dbFile = '/tester1.db'; name:'Create db',
sqlite3.util.sqlite3__wasm_vfs_unlink(0, dbFile); //predicate: (sqlite3)=>
const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c'); test: function(sqlite3){
db.onclose = { const dbFile = '/tester1.db';
disposeAfter: [], sqlite3.util.sqlite3__wasm_vfs_unlink(0, dbFile);
disposeBefore: [ const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c');
(db)=>{ db.onclose = {
//console.debug("db.onclose.before dropping modules"); disposeAfter: [],
//sqlite3.capi.sqlite3_drop_modules(db.pointer, 0); disposeBefore: [
} (db)=>{
], //console.debug("db.onclose.before dropping modules");
before: function(db){ //sqlite3.capi.sqlite3_drop_modules(db.pointer, 0);
while(this.disposeBefore.length){ }
const v = this.disposeBefore.shift(); ],
console.debug("db.onclose.before cleaning up:",v); before: function(db){
if(wasm.isPtr(v)) wasm.dealloc(v); while(this.disposeBefore.length){
else if(v instanceof sqlite3.StructBinder.StructType){ const v = this.disposeBefore.shift();
v.dispose(); console.debug("db.onclose.before cleaning up:",v);
}else if(v instanceof Function){ if(wasm.isPtr(v)) wasm.dealloc(v);
try{ v(db) } catch(e){ else if(v instanceof sqlite3.StructBinder.StructType){
console.warn("beforeDispose() callback threw:",e); v.dispose();
}else if(v instanceof Function){
try{ v(db) } catch(e){
console.warn("beforeDispose() callback threw:",e);
}
}
}
},
after: function(){
while(this.disposeAfter.length){
const v = this.disposeAfter.shift();
console.debug("db.onclose.after cleaning up:",v);
if(wasm.isPtr(v)) wasm.dealloc(v);
else if(v instanceof sqlite3.StructBinder.StructType){
v.dispose();
}else if(v instanceof Function){
try{v()} catch(e){/*ignored*/}
} }
} }
} }
}, };
after: function(){
while(this.disposeAfter.length){ T.assert(wasm.isPtr(db.pointer))
const v = this.disposeAfter.shift(); .mustThrowMatching(()=>db.pointer=1, /read-only/)
console.debug("db.onclose.after cleaning up:",v); .assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
if(wasm.isPtr(v)) wasm.dealloc(v); .assert('main'===db.dbName(0))
else if(v instanceof sqlite3.StructBinder.StructType){ .assert('string' === typeof db.dbVfsName())
v.dispose(); .assert(db.pointer === wasm.xWrap.testConvertArg('sqlite3*',db));
}else if(v instanceof Function){ // Custom db error message handling via sqlite3_prepare_v2/v3()
try{v()} catch(e){/*ignored*/} let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
} T.assert(capi.SQLITE_MISUSE === rc)
} .assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL"))
.assert(dbFile === db.dbFilename())
.assert(!db.dbFilename('nope'));
//Sanity check DB.checkRc()...
let ex;
try{db.checkRc(rc)}
catch(e){ex = e}
T.assert(ex instanceof sqlite3.SQLite3Error)
.assert(capi.SQLITE_MISUSE===ex.resultCode)
.assert(0===ex.message.indexOf("SQLITE_MISUSE: sqlite3 result code"))
.assert(ex.message.indexOf("Invalid SQL")>0);
T.assert(db === db.checkRc(0))
.assert(db === sqlite3.oo1.DB.checkRc(db,0))
.assert(null === sqlite3.oo1.DB.checkRc(null,0));
this.progressHandlerCount = 0;
if( wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK') ){
T.assert( !capi.sqlite3_progress_handler );
}else{
T.assert( !!capi.sqlite3_progress_handler );
capi.sqlite3_progress_handler(db, 5, (p)=>{
++this.progressHandlerCount;
return 0;
}, 0);
} }
}; }
T.assert(wasm.isPtr(db.pointer))
.mustThrowMatching(()=>db.pointer=1, /read-only/)
.assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
.assert('main'===db.dbName(0))
.assert('string' === typeof db.dbVfsName())
.assert(db.pointer === wasm.xWrap.testConvertArg('sqlite3*',db));
// Custom db error message handling via sqlite3_prepare_v2/v3()
let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
T.assert(capi.SQLITE_MISUSE === rc)
.assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL"))
.assert(dbFile === db.dbFilename())
.assert(!db.dbFilename('nope'));
//Sanity check DB.checkRc()...
let ex;
try{db.checkRc(rc)}
catch(e){ex = e}
T.assert(ex instanceof sqlite3.SQLite3Error)
.assert(capi.SQLITE_MISUSE===ex.resultCode)
.assert(0===ex.message.indexOf("SQLITE_MISUSE: sqlite3 result code"))
.assert(ex.message.indexOf("Invalid SQL")>0);
T.assert(db === db.checkRc(0))
.assert(db === sqlite3.oo1.DB.checkRc(db,0))
.assert(null === sqlite3.oo1.DB.checkRc(null,0));
this.progressHandlerCount = 0;
capi.sqlite3_progress_handler(db, 5, (p)=>{
++this.progressHandlerCount;
return 0;
}, 0);
}) })
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
.t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){ .t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){
@@ -1236,7 +1249,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
new TextEncoder('utf-8').encode("select 3 as a") new TextEncoder('utf-8').encode("select 3 as a")
); );
//debug("statement =",st); //debug("statement =",st);
this.progressHandlerCount = 0; T.assert( !this.progressHandlerCount );
let rc; let rc;
try { try {
T.assert(wasm.isPtr(st.pointer)) T.assert(wasm.isPtr(st.pointer))
@@ -1278,7 +1291,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
st, capi.SQLITE_STMTSTATUS_RUN, 0 st, capi.SQLITE_STMTSTATUS_RUN, 0
) > 0); ) > 0);
T.assert(this.progressHandlerCount > 0, T.assert(this.progressHandlerCount>0
|| wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK'),
"Expecting progress callback."). "Expecting progress callback.").
assert(0===capi.sqlite3_strglob("*.txt", "foo.txt")). assert(0===capi.sqlite3_strglob("*.txt", "foo.txt")).
assert(0!==capi.sqlite3_strglob("*.txt", "foo.xtx")). assert(0!==capi.sqlite3_strglob("*.txt", "foo.xtx")).
@@ -1363,7 +1377,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.assert(2 === list.length) .assert(2 === list.length)
.assert('string'===typeof list[1]) .assert('string'===typeof list[1])
.assert(3===db.changes()) .assert(3===db.changes())
.assert(this.progressHandlerCount > 0, .assert(this.progressHandlerCount > 0
|| wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK'),
"Expecting progress callback.") "Expecting progress callback.")
if(wasm.bigIntEnabled){ if(wasm.bigIntEnabled){
T.assert(3n===db.changes(false,true)); T.assert(3n===db.changes(false,true));
@@ -1904,7 +1919,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
.t({ .t({
name: 'Window UDFs', name: 'Window UDFs',
//predicate: ()=>false, predicate: (sqlite3)=>!!sqlite3.wasm.exports.sqlite3_create_window_function
/*!sqlite3.wasm.compileOptionUsed('OMIT_WINDOWFUNC')*/
|| "Missing window functions",
test: function(){ test: function(){
/* Example window function, table, and results taken from: /* Example window function, table, and results taken from:
https://sqlite.org/windowfunctions.html#udfwinfunc */ https://sqlite.org/windowfunctions.html#udfwinfunc */
@@ -2153,7 +2170,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
.t({ .t({
name: 'virtual table #1: eponymous w/ manual exception handling', name: 'virtual table #1: eponymous w/ manual exception handling',
predicate: ()=>!!capi.sqlite3_create_module || "Missing vtab support", predicate: (sqlite3)=>!!sqlite3.capi.sqlite3_vtab || "Missing vtab support",
test: function(sqlite3){ test: function(sqlite3){
const VT = sqlite3.vtab; const VT = sqlite3.vtab;
const tmplCols = Object.assign(Object.create(null),{ const tmplCols = Object.assign(Object.create(null),{
@@ -2350,7 +2367,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
.t({ .t({
name: 'virtual table #2: non-eponymous w/ automated exception wrapping', name: 'virtual table #2: non-eponymous w/ automated exception wrapping',
predicate: ()=>!!capi.sqlite3_create_module || "Missing vtab support", predicate: (sqlite3)=>!!sqlite3.capi.sqlite3_vtab || "Missing vtab support",
test: function(sqlite3){ test: function(sqlite3){
const VT = sqlite3.vtab; const VT = sqlite3.vtab;
const tmplCols = Object.assign(Object.create(null),{ const tmplCols = Object.assign(Object.create(null),{
@@ -3132,7 +3149,10 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
]); ]);
T.assert(2 === u1.getFileCount() /* one is the journal file */) T.assert(2 === u1.getFileCount() /* one is the journal file */)
.assert(3 === db.selectValue('select count(*) from t')) .assert(3 === db.selectValue('select count(*) from t'))
.assert('wal'===db.selectValue('pragma journal_mode')); .assert(
'wal'===db.selectValue('pragma journal_mode')
|| wasm.compileOptionUsed('OMIT_WAL')
);
db.close(); db.close();
T.assert(1 === u1.getFileCount()); T.assert(1 === u1.getFileCount());
db = new u2.OpfsSAHPoolDb(dbName); db = new u2.OpfsSAHPoolDb(dbName);
@@ -3300,17 +3320,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.g('Bug Reports') T.g('Bug Reports')
.t({ .t({
name: 'Delete via bound parameter in subquery', name: 'Delete via bound parameter in subquery',
predicate: function(sqlite3){ predicate: ()=>wasm.compileOptionUsed('ENABLE_FTS5') || "Missing FTS5",
const d = new sqlite3.oo1.DB();
try{
d.exec("create virtual table f using fts5(x)");
return true;
}catch(e){
return "FTS5 is not available";
}finally{
d.close();
}
},
test: function(sqlite3){ test: function(sqlite3){
// Testing https://sqlite.org/forum/forumpost/40ce55bdf5 // Testing https://sqlite.org/forum/forumpost/40ce55bdf5
// with the exception that that post uses "external content" // with the exception that that post uses "external content"

View File

@@ -6,19 +6,20 @@
# GNUMakefile. # GNUMakefile.
######################################################################## ########################################################################
MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST)) MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST))
$(warning The WASMFS build is currently incomplete.) # ensure that the following message starts on line 10 or higher for proper
# $(warning) alignment!
ifneq (1,$(MAKING_CLEAN))
$(warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
$(warning !! The WASMFS build is not well-supported. WASMFS is a proverbial)
$(warning !! moving target, sometimes changing in incompatible ways between)
$(warning !! Emscripten versions. This build is provided for adventurous folks)
$(warning !! and is not a supported deliverable of the SQLite project.)
$(warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
endif
#dir.wasmfs := $(dir.wasm)
dir.wasmfs := $(dir.dout)
sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js
sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm
CLEAN_FILES += $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.wasm) \
$(subst .js,.worker.js,$(sqlite3-wasmfs.js)) \
$(sqlite3-wasmfs.mjs) \
$(subst .mjs,.worker.mjs,$(sqlite3-wasmfs.mjs))
######################################################################## ########################################################################
# emcc flags for .c/.o. # emcc flags for .c/.o.
cflags.sqlite3-wasmfs := cflags.sqlite3-wasmfs :=
@@ -30,12 +31,15 @@ cflags.sqlite3-wasmfs += -DSQLITE_ENABLE_WASMFS
# emcc flags specific to building the final .js/.wasm file... # emcc flags specific to building the final .js/.wasm file...
emcc.flags.sqlite3-wasmfs := emcc.flags.sqlite3-wasmfs :=
emcc.flags.sqlite3-wasmfs += \ emcc.flags.sqlite3-wasmfs += \
-sEXPORTED_RUNTIME_METHODS=wasmMemory,allocateUTF8OnStack,stringToUTF8OnStack -sEXPORTED_RUNTIME_METHODS=wasmMemory
# wasmMemory ==> for -sIMPORTED_MEMORY # wasmMemory ==> for -sIMPORTED_MEMORY
# *OnStack ==> wasmfs internals (leaky abstraction) # Some version of emcc between 3.1.60-ish(?) and 3.1.62 deprecated the
# use of (allocateUTF8OnStack,stringToUTF8OnStack). Earlier emcc
# versions will fail to build without those in the
# EXPORTED_RUNTIME_METHODS list.
emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0 emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0
emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations
# ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag. # ^^^^^ emcc likes to warn when we have "limited optimizations" via the -g3 flag.
emcc.flags.sqlite3-wasmfs += -sMEMORY64=0 emcc.flags.sqlite3-wasmfs += -sMEMORY64=0
emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128)
# ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js # ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js
@@ -51,12 +55,7 @@ emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0
# And, indeed, it runs slowly if memory is permitted to grow. # And, indeed, it runs slowly if memory is permitted to grow.
#emcc.flags.sqlite3-wasmfs.vanilla := #emcc.flags.sqlite3-wasmfs.vanilla :=
#emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META #emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META
sqlite3-api.mjs.wasmfs := $(dir.tmp)/sqlite3-api-wasmfs.mjs all: $(sqlite3-wasmfs.mjs)
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3-wasmfs,esm,1,\
$(sqlite3-api.mjs.wasmfs), $(sqlite3-wasmfs.mjs),\
$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs,\
-sEXPORT_ES6 -sUSE_ES6_IMPORT_META\
))
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs) $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs)
######################################################################## ########################################################################
# Build quirk: we cannot build BOTH .js and .mjs with our current # Build quirk: we cannot build BOTH .js and .mjs with our current
@@ -67,8 +66,8 @@ $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs)
# build both modes they would need to have distinct base names or # build both modes they would need to have distinct base names or
# output directories. "The problem" with giving them distinct base # output directories. "The problem" with giving them distinct base
# names is that it means that the corresponding .wasm file is also # names is that it means that the corresponding .wasm file is also
# built/saved multiple times. # built/saved multiple times. It is likely that anyone wanting to use
# # WASMFS will want an ES6 module, so that's what we build here.
wasmfs.build.ext := mjs wasmfs.build.ext := mjs
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(SOAP.js.bld) $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(SOAP.js.bld)
ifeq (js,$(wasmfs.build.ext)) ifeq (js,$(wasmfs.build.ext))
@@ -78,7 +77,6 @@ else
$(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.mjs) $(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.mjs)
wasmfs: $(sqlite3-wasmfs.mjs) wasmfs: $(sqlite3-wasmfs.mjs)
endif endif
#all: wasmfs
######################################################################## ########################################################################
# speedtest1 for wasmfs. # speedtest1 for wasmfs.
@@ -103,13 +101,11 @@ $(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \
$(emcc.flags.sqlite3-wasmfs) \ $(emcc.flags.sqlite3-wasmfs) \
$(emcc.flags.speedtest1-wasmfs) \ $(emcc.flags.speedtest1-wasmfs) \
-o $@ $(speedtest1.cfiles) -lm -o $@ $(speedtest1.cfiles) -lm
@$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1) @$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1,1)
$(maybe-wasm-strip) $(speedtest1-wasmfs.wasm) $(maybe-wasm-strip) $(speedtest1-wasmfs.wasm)
chmod -x $(speedtest1-wasmfs.wasm) chmod -x $(speedtest1-wasmfs.wasm)
ls -la $@ $(speedtest1-wasmfs.wasm) ls -la $@ $(speedtest1-wasmfs.wasm)
wasmfs: $(speedtest1-wasmfs.mjs) wasmfs: $(speedtest1-wasmfs.mjs)
CLEAN_FILES += $(speedtest1-wasmfs.mjs) $(speedtest1-wasmfs.wasm) \
$(subst .js,.worker.js,$(speedtest1-wasmfs.mjs))
# end speedtest1.js # end speedtest1.js
######################################################################## ########################################################################

View File

@@ -560,8 +560,8 @@ sqlite3$(EXE): sqlite3.h libsqlite3.a shell.c
$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h sqldiff$(EXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.c sqlite3.h
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TCCX) -I$(TOP)/ext/misc -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
@@ -763,8 +763,6 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
# Source and header files that shell.c depends on # Source and header files that shell.c depends on
SHELL_DEP = \ SHELL_DEP = \
$(TOP)/src/shell.c.in \ $(TOP)/src/shell.c.in \
$(TOP)/ext/consio/console_io.c \
$(TOP)/ext/consio/console_io.h \
$(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/intck/sqlite3intck.c \ $(TOP)/ext/intck/sqlite3intck.c \
@@ -784,6 +782,8 @@ SHELL_DEP = \
$(TOP)/ext/misc/sha1.c \ $(TOP)/ext/misc/sha1.c \
$(TOP)/ext/misc/shathree.c \ $(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \ $(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/sqlite3_stdio.c \
$(TOP)/ext/misc/sqlite3_stdio.h \
$(TOP)/ext/misc/uint.c \ $(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/vfstrace.c \ $(TOP)/ext/misc/vfstrace.c \
$(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/misc/zipfile.c \

View File

@@ -1,11 +1,11 @@
C Update\sdocs\sfor\ssqlite3_snapshot_get(). C Merge\slatest\strunk\schanges\sinto\sthis\sbranch.
D 2024-10-02T11:11:00.069 D 2024-10-02T11:11:29.802
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in fa448c4c0567623fd140efebecb570ab58d955d766a5ea0fd8a94e9b5697007c F Makefile.in 6a826facc78c3c8ad38bf00ed588f6aa3665ccd7a9749b891d20582fc290c77e
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -99,7 +99,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70
F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33 F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c 571483823193f09439356741669aa8c81da838ae6f5e1bfa7517f7ee2fb3addd F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6
F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4 F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4
F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470 F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
@@ -145,7 +145,7 @@ F ext/fts5/test/fts5contentless.test 606f063b29ba0f46d4b79aa36cdd1ef4dab5de53eae
F ext/fts5/test/fts5contentless2.test 70ffe6c611d8f278240da56734df8a77948f04e2739b358439e9bdcf56ced35f F ext/fts5/test/fts5contentless2.test 70ffe6c611d8f278240da56734df8a77948f04e2739b358439e9bdcf56ced35f
F ext/fts5/test/fts5contentless3.test 75eaae5ad6b284ee447788943974d323228f27cc35a1681da997135cff95bc6a F ext/fts5/test/fts5contentless3.test 75eaae5ad6b284ee447788943974d323228f27cc35a1681da997135cff95bc6a
F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b05ea89964c863833b6eff8 F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b05ea89964c863833b6eff8
F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a F ext/fts5/test/fts5contentless5.test 38cd0392c730dc7090c550321ce3c24ba4c392bc97308b51a4180e9959dca7b5
F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb26f51ef956c8328bd F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb26f51ef956c8328bd
F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4 F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4
F ext/fts5/test/fts5corrupt3.test 4fc3bf129f1616bea00884a23fd9d7b0e46d01791d2b57fe8d68ac36e8d3ff7c F ext/fts5/test/fts5corrupt3.test 4fc3bf129f1616bea00884a23fd9d7b0e46d01791d2b57fe8d68ac36e8d3ff7c
@@ -399,7 +399,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82
F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
F ext/misc/fileio.c 001179b29735639c607586c9e9398c92505c0833de06eefc27e13acf60dd1577 F ext/misc/fileio.c e6b34db4df4b55b96265086c0010264e257b6eab1644e665697a6da587659403
F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a
F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a
F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d
@@ -423,8 +423,10 @@ F ext/misc/series.c a6089b5e8e3002bd1e5d9877cee6aead0b9a6426e406c09a399817db9e9a
F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9
F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f
F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634
F ext/misc/sqlite3_stdio.c f110e6f2dc97c67e89f941f82af7dbd221193fa44d1e3ef38a691454a2cbccda
F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176
F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321
F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc
F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b
@@ -439,7 +441,7 @@ F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594a
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
F ext/misc/zipfile.c 5a3bf1b9cccb8e0da2389fe9e39e9c7f2b1351474b7e5090635f817d495eee3f F ext/misc/zipfile.c b62147ac4985eaac4e368d529b1f4f43ad6bc9ac13d6805d907fff3afdac64d3
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
@@ -601,7 +603,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/GNUmakefile d4f6586d9a36ee2869a8c7f77227a8b7f42b6c4623f3be594beafb1554ab20d9 F ext/wasm/GNUmakefile c2ee5993e727dd2c1f0f784f47843fb7af45cebd23626b537bae2d2d8f4a3abd
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
@@ -609,21 +611,18 @@ F ext/wasm/SQLTester/SQLTester.mjs ce765c0ad7d57f93553d12ef4dca574deb00300134a26
F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638 F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638
F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-auth 7ac80cc3b6a6d52e041bb295e85555ce797be78c15ef2008a64ae58815014080 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 2bcbbfe3b95c043ed6037e2708a2ee078d212dd1612c364f93588d8dc97300fe
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 400213eb52a7e5ad5f448053d375cacf4dac2cf45d134f3edfe485ae4a49a183 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras fe40d6d758646e38f8b15f709044951e10884214f5453d35502100179c388c13 w ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-preupdate d1d62a2212099f2c0782d730beb8cb84a7a52d99c15ead2cb9b1411fff5fd6b1
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session 213b6c04267cb9bd760172db011eb1650732805fb3d01f9395478a8ceec18eb0
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-vtab fd57af1f4502a052be27d8402df74be1dc60fcb6a687d372972abd90e424120a
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73 F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73
F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122 F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
F ext/wasm/api/sqlite3-api-glue.c-pp.js 54b32b5321105a72d6f3d3e8b77f28f162d0367b08c63184263d3f85f3d7dbed F ext/wasm/api/sqlite3-api-glue.c-pp.js fb6dbfe692cc23000a65a4cd95a1a47ed5eb592dc9d8b55363b3c2952a787244
F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f
F ext/wasm/api/sqlite3-api-prologue.js 6f1257e04885632ed9f44d43aba200b86e0bc16709ffdba29abbbeb1bc8e8b76 F ext/wasm/api/sqlite3-api-prologue.js 6f1257e04885632ed9f44d43aba200b86e0bc16709ffdba29abbbeb1bc8e8b76
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d
@@ -633,14 +632,14 @@ F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js e529a99b7d5a088284821e2902b20d3404b561126969876997d5a73a656c9199 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js e529a99b7d5a088284821e2902b20d3404b561126969876997d5a73a656c9199
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e99e3d99f736937914527070f00ab13e9391d3f1cef884ab99a64cbcbee8d675 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e99e3d99f736937914527070f00ab13e9391d3f1cef884ab99a64cbcbee8d675
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616
F ext/wasm/api/sqlite3-wasm.c 09a938fc570f282e602acd111147c7b74b5332da72540c512a79b916ab57882a F ext/wasm/api/sqlite3-wasm.c 2d4340f2dacd9119e95c470d9c4f392e399feffc292962b855f0a67ffb0fc418
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5 F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7 F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
F ext/wasm/batch-runner.js 05ec254f5dbfe605146d9640b3db17d6ef8c3fbef6aa8396051ca72bb5884e3f F ext/wasm/batch-runner.js 05ec254f5dbfe605146d9640b3db17d6ef8c3fbef6aa8396051ca72bb5884e3f
F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4 F ext/wasm/c-pp.c 6d131069644964223305582a80973477fa8b06b57306781690d7874ebd3a4f84
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
@@ -656,19 +655,20 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
F ext/wasm/fiddle.make 2406b02473878a99fb6a2eaff0923277017adc45eb041b2afb2d7707bf7b375c F ext/wasm/fiddle.make ec2353f0eddade864f67b993376a0949e27b72465c24b1970940e48b70bc2df1
F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce
F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1 F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1
F ext/wasm/fiddle/index.html 739e0b75bc592679665d25e2f7649d2b8b2db678f3b41a772a8720b609b8482d F ext/wasm/fiddle/index.html c79b1741cbeba78f88af0a84cf5ec7de87a909a6a8d10a369b1f4824c66c2088
F ext/wasm/index-dist.html 564b5ec5669676482c5a25dea9e721d8eafed426ecb155f93d29aeff8507511f F ext/wasm/index-dist.html 564b5ec5669676482c5a25dea9e721d8eafed426ecb155f93d29aeff8507511f
F ext/wasm/index.html 4337f495416756802669f69f9f9f3df9f87ee4c1918e6718719b4b5718e4713a F ext/wasm/index.html e4bbffdb3d40eff12b3f9c7abedef91787e2935620b7f8d40f2c774b80ad8fa9
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54 F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
F ext/wasm/jaccwabyt/jaccwabyt.md 59a20df389abcc3606eb4eaea7fb7ba14504beb3e345dbea9b99a0618ba3bec8 F ext/wasm/jaccwabyt/jaccwabyt.md 59a20df389abcc3606eb4eaea7fb7ba14504beb3e345dbea9b99a0618ba3bec8
F ext/wasm/mkwasmbuilds.c e3580b26bc393e4e4beb25f6349b999878782f3319b740469f64c2e772632e03
F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe F ext/wasm/speedtest1-wasmfs.mjs c77c7231338ed5c0e1ce16aa29106df8e5b5cf11a48319c49433490a8d3ded30
F ext/wasm/speedtest1-worker.html 864b65ed78ce24847a348c180e7f267621a02ca027068a1863ec1c90187c1852 F ext/wasm/speedtest1-worker.html 864b65ed78ce24847a348c180e7f267621a02ca027068a1863ec1c90187c1852
F ext/wasm/speedtest1-worker.js 95e549e13a4d35863a9a7fc66122b5f546c0130d3be7b06dfcc556eb66d24bde F ext/wasm/speedtest1-worker.js 95e549e13a4d35863a9a7fc66122b5f546c0130d3be7b06dfcc556eb66d24bde
F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da
@@ -679,15 +679,15 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js a88b9c669715adc1c5e76750ca8c0994ae33d04572e3bf295b6f4f5870f3bdf3 F ext/wasm/tester1.c-pp.js bb8c41a56ca0eabb945ca2e8f06324a7b63ad91630959d714b071bee88322019
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966f1bc16a F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk 67e622f31d10fee8f0f62655b4f9b47cd97fe70a125674ca6754b3549d69cc0e F main.mk 0a55ebec3508ca1bdb593d86f3aa19d7fa42a2ddd3220703e6dc0a65f1338a43
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -730,7 +730,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 3bb768eeeee1cceaed391327362b8be8b5ce61a12fe24d5b555ce9c6b4a883de F src/main.c 45cf169457a1b483f16dd5eba8ddce6e731f88e810e3a48a82fdf46b0783f466
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -751,7 +751,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c 6e3e4fc75904ff85184091dbab996e6e35c1799e771788961cc3b4fcbe8f852c F src/os_unix.c 779e83666ecd535f6725497ba6da069c1d15138ff6a4ee123edad1ae0cdfbe83
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
@@ -768,11 +768,11 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
F src/shell.c.in 9b68a945f3aafc78eac1a256a4a588a9310dbc61a0cd60378c5b7a78f789af50 F src/shell.c.in d71d2463459e6cd9c2f2d702545aed5113ffbcea963c19c1e6d3a6d762ef959c
F src/sqlite.h.in 496f927cf2a687f313c6ac41c03e46f45c8f91c84d8f3ff6607aa9f2794e2ec3 F src/sqlite.h.in 210646bb181ee1034a7288fcb2d3d4dd61dd46d9381a88c26c587828e07d0333
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 5978cbb11becc3ce6471015d770d95f694ece06336c496f691df1b02460e9cd5 F src/sqliteInt.h e4940181e20f67b23b7e1b43807ceb3a9cdb38860225de3d5df7eea37bbe6651
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -835,13 +835,13 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
F src/utf.c 7bc550af6f3ddd5f5dc82d092c41f728acb760c92e0b47f391963b01ae52569b F src/utf.c 7bc550af6f3ddd5f5dc82d092c41f728acb760c92e0b47f391963b01ae52569b
F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375 F src/util.c aea7987484ec05764eabdd63b55eb63ea85cfb5b95dde70a667711c1d326f1a7
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457 F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457
F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d
F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17 F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17
F src/vdbeaux.c 676dbee99b4febdd94bc9658667a2e3bc413c4c0e356242d90f98a1155d513e5 F src/vdbeaux.c a30204ae8820ee5165736c2e67fe9b62ad47690c72248b4adba0435b0b3f8bfe
F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2
F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
@@ -1626,7 +1626,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test 490bf9d0c7c9564fea318c46d49369f4690b825b584c9a544dbdccf61bc0babc F test/shell1.test b02d628494fa284cdb2b7b2fecdadea96913796afd623f340a79d68f055dcb7e
F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24 F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8 F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807 F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
@@ -1668,7 +1668,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
F test/speedtest1.c 19c9b60908d25502d2831f97efee8b81006c356ab8c08327e25d24a4144f2131 F test/speedtest1.c 82f273f6df420bb1563d5202277e4a907e4e032a96a86fa7cf8c7aed34b32724
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
@@ -2173,9 +2173,9 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60
F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b
F tool/sqlite3-rsync.c 187b262035c1159b047dbfa1959c168b87b5a153b63465e8c8bd1b54fabf4460 F tool/sqlite3-rsync.c 187b262035c1159b047dbfa1959c168b87b5a153b63465e8c8bd1b54fabf4460
F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f
@@ -2213,8 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 34b6ac3d76dbc6819778ec2a0f81cbcdcc0cd1a6303381d97f1c479e4ecdd132 P 78c3892ab777a39406da8a9df84d0634397514e25512b0363a13bff3b8bc8925 98066e2d226e7d2eceec1931a1432baea956f49bf3c708d8a6d511fa4e864ca3
R a30055f90af028e040102b1e9655fa8f R 87b444cea9d9fafaf3e9a749b30c4a0d
U dan U dan
Z 068c609e961149f2eac59f5d7b1ce4b0 Z 8747e077fd17f2f82bf023df0407bc7e
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
78c3892ab777a39406da8a9df84d0634397514e25512b0363a13bff3b8bc8925 2b3945e6a597e6853cac567052e92926c8cb6d7a029ac64c2d45c321bbe2e94d

View File

@@ -159,6 +159,7 @@ char *sqlite3_temp_directory = 0;
*/ */
char *sqlite3_data_directory = 0; char *sqlite3_data_directory = 0;
#if !defined(SQLITE_OMIT_WSD) && !defined(SQLITE_USE_LONG_DOUBLE)
/* /*
** Determine whether or not high-precision (long double) floating point ** Determine whether or not high-precision (long double) floating point
** math works correctly on CPU currently running. ** math works correctly on CPU currently running.
@@ -183,7 +184,7 @@ static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){
return b!=c; return b!=c;
} }
} }
#endif /* !SQLITE_OMIT_WSD && !SQLITE_USE_LONG_DOUBLE */
/* /*
** Initialize SQLite. ** Initialize SQLite.
@@ -380,9 +381,7 @@ int sqlite3_initialize(void){
} }
#endif #endif
/* Experimentally determine if high-precision floating point is #if !defined(SQLITE_OMIT_WSD) && !defined(SQLITE_USE_LONG_DOUBLE)
** available. */
#ifndef SQLITE_OMIT_WSD
sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc);
#endif #endif
@@ -4645,12 +4644,18 @@ int sqlite3_test_control(int op, ...){
** X==0 Disable bUseLongDouble ** X==0 Disable bUseLongDouble
** X==1 Enable bUseLongDouble ** X==1 Enable bUseLongDouble
** X>=2 Set bUseLongDouble to its default value for this platform ** X>=2 Set bUseLongDouble to its default value for this platform
**
** If the SQLITE_USE_LONG_DOUBLE compile-time option has been used, then
** the bUseLongDouble setting is fixed. This test-control becomes a
** no-op, except that it still reports the fixed setting.
*/ */
case SQLITE_TESTCTRL_USELONGDOUBLE: { case SQLITE_TESTCTRL_USELONGDOUBLE: {
#if !defined(SQLITE_USE_LONG_DOUBLE)
int b = va_arg(ap, int); int b = va_arg(ap, int);
if( b>=2 ) b = hasHighPrecisionDouble(b); if( b>=2 ) b = hasHighPrecisionDouble(b);
if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; if( b>=0 ) sqlite3Config.bUseLongDouble = b>0;
rc = sqlite3Config.bUseLongDouble!=0; #endif
rc = SqliteUseLongDouble!=0;
break; break;
} }
#endif #endif

View File

@@ -4159,7 +4159,7 @@ static void setDeviceCharacteristics(unixFile *pFd){
static void setDeviceCharacteristics(unixFile *pFile){ static void setDeviceCharacteristics(unixFile *pFile){
if( pFile->sectorSize == 0 ){ if( pFile->sectorSize == 0 ){
struct statvfs fsInfo; struct statvfs fsInfo;
/* Set defaults for non-supported filesystems */ /* Set defaults for non-supported filesystems */
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0; pFile->deviceCharacteristics = 0;
@@ -4199,7 +4199,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize; pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics = pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */ /* full bitset of atomics from max sector size and smaller */
((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */ ** so it is ordered */
0; 0;
@@ -4207,7 +4207,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize; pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics = pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */ /* full bitset of atomics from max sector size and smaller */
((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */ ** so it is ordered */
0; 0;

File diff suppressed because it is too large Load Diff

View File

@@ -4222,13 +4222,17 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** and sqlite3_prepare16_v3() use UTF-16. ** and sqlite3_prepare16_v3() use UTF-16.
** **
** ^If the nByte argument is negative, then zSql is read up to the ** ^If the nByte argument is negative, then zSql is read up to the
** first zero terminator. ^If nByte is positive, then it is the ** first zero terminator. ^If nByte is positive, then it is the maximum
** number of bytes read from zSql. ^If nByte is zero, then no prepared ** number of bytes read from zSql. When nByte is positive, zSql is read
** up to the first zero terminator or until the nByte bytes have been read,
** whichever comes first. ^If nByte is zero, then no prepared
** statement is generated. ** statement is generated.
** If the caller knows that the supplied string is nul-terminated, then ** If the caller knows that the supplied string is nul-terminated, then
** there is a small performance advantage to passing an nByte parameter that ** there is a small performance advantage to passing an nByte parameter that
** is the number of bytes in the input string <i>including</i> ** is the number of bytes in the input string <i>including</i>
** the nul-terminator. ** the nul-terminator.
** Note that nByte measure the length of the input in bytes, not
** characters, even for the UTF-16 inferfaces.
** **
** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only ** past the end of the first SQL statement in zSql. These routines only

View File

@@ -4249,6 +4249,41 @@ typedef struct {
# define Tuning(X) 0 # define Tuning(X) 0
#endif #endif
/* By default, SQLite will use long double if the long double type
** actually provides higher resolution than double. This use or non-use
** of long double is switchable at run-time by a test-control. Dekker
** algorithms are used for high-precision floating point when long double
** is not available.
**
** Having the run-time option to enable/disable long double support
** causes problems for some compiler tool chains. So the following
** compile-time option is available to permanently enable/disable the use
** of long double.
**
** -DSQLITE_USE_LONG_DOUBLE=0 Omit all use of "long double" from
** the code. Instead, the Dekker algorithm
** is always used when high-precision
** floating point is required.
**
** -DSQLITE_USE_LONG_DOUBLE=1 Always use long double when high
** precision is needed. Never fall back
** to using Dekker algorithms.
**
** If the SQLITE_USE_LONG_DOUBLE macro is not defined, then the determination
** of whether or not to use long double is made at run-time.
*/
#ifndef SQLITE_USE_LONG_DOUBLE
# define SqliteUseLongDouble sqlite3Config.bUseLongDouble
#elif SQLITE_USE_LONG_DOUBLE+0==1
# define SqliteUseLongDouble 1
#elif SQLITE_USE_LONG_DOUBLE+0==0
# undef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE double
# define SqliteUseLongDouble 0
#else
# error "SQLITE_USE_LONG_DOUBLE should be set to either 0 or 1"
#endif
/* /*
** Structure containing global configuration data for the SQLite library. ** Structure containing global configuration data for the SQLite library.
** **

View File

@@ -458,6 +458,7 @@ u8 sqlite3StrIHash(const char *z){
return h; return h;
} }
#if !defined(SQLITE_USE_LONG_DOUBLE) || SQLITE_USE_LONG_DOUBLE+0==0
/* Double-Double multiplication. (x[0],x[1]) *= (y,yy) /* Double-Double multiplication. (x[0],x[1]) *= (y,yy)
** **
** Reference: ** Reference:
@@ -493,6 +494,9 @@ static void dekkerMul2(volatile double *x, double y, double yy){
x[1] = c - x[0]; x[1] = c - x[0];
x[1] += cc; x[1] += cc;
} }
#else
# define dekkerMul2(A,B,C) /* No-op if SqliteUseLongDouble is always true */
#endif
/* /*
** The string z[] is an text representation of a real number. ** The string z[] is an text representation of a real number.
@@ -652,7 +656,7 @@ do_atof_calc:
if( e==0 ){ if( e==0 ){
*pResult = s; *pResult = s;
}else if( sqlite3Config.bUseLongDouble ){ }else if( SqliteUseLongDouble ){
LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s;
if( e>0 ){ if( e>0 ){
while( e>=100 ){ e-=100; r *= 1.0e+100L; } while( e>=100 ){ e-=100; r *= 1.0e+100L; }
@@ -1063,7 +1067,7 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
/* Multiply r by powers of ten until it lands somewhere in between /* Multiply r by powers of ten until it lands somewhere in between
** 1.0e+19 and 1.0e+17. ** 1.0e+19 and 1.0e+17.
*/ */
if( sqlite3Config.bUseLongDouble ){ if( SqliteUseLongDouble ){
LONGDOUBLE_TYPE rr = r; LONGDOUBLE_TYPE rr = r;
if( rr>=1.0e+19 ){ if( rr>=1.0e+19 ){
while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; }

View File

@@ -4512,9 +4512,13 @@ SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
** We must use separate SQLITE_NOINLINE functions here, since otherwise ** We must use separate SQLITE_NOINLINE functions here, since otherwise
** optimizer code movement causes gcov to become very confused. ** optimizer code movement causes gcov to become very confused.
*/ */
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) #if (defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)) \
&& (!defined(SQLITE_USE_LONG_DOUBLE) || SQLITE_USE_LONG_DOUBLE+0==0)
static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; } static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; }
static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; } static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; }
#else
# define doubleLt(A,B) 1
# define doubleEq(A,B) 1
#endif #endif
/* /*
@@ -4528,7 +4532,7 @@ int sqlite3IntFloatCompare(i64 i, double r){
** than NULL */ ** than NULL */
return 1; return 1;
} }
if( sqlite3Config.bUseLongDouble ){ if( SqliteUseLongDouble ){
LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
testcase( x<r ); testcase( x<r );
testcase( x>r ); testcase( x>r );

View File

@@ -516,6 +516,8 @@ do_test shell1-3.15.3 {
Options: Options:
--bom Prefix output with a UTF8 byte-order mark --bom Prefix output with a UTF8 byte-order mark
-e Send output to the system text editor -e Send output to the system text editor
--plain Use text/plain for -w option
-w Send output to a web browser
-x Send output as CSV to a spreadsheet -x Send output as CSV to a spreadsheet
child process exited abnormally}} child process exited abnormally}}
@@ -532,6 +534,8 @@ do_test shell1-3.16.2 {
Options: Options:
--bom Prefix output with a UTF8 byte-order mark --bom Prefix output with a UTF8 byte-order mark
-e Send output to the system text editor -e Send output to the system text editor
--plain Use text/plain for -w option
-w Send output to a web browser
-x Send output as CSV to a spreadsheet -x Send output as CSV to a spreadsheet
child process exited abnormally}} child process exited abnormally}}

View File

@@ -2277,6 +2277,7 @@ int main(int argc, char **argv){
int iCur, iHi; /* Stats values, current and "highwater" */ int iCur, iHi; /* Stats values, current and "highwater" */
int i; /* Loop counter */ int i; /* Loop counter */
int rc; /* API return code */ int rc; /* API return code */
int useLongDouble = -1; /* True to set use of long-double */
#ifdef SQLITE_SPEEDTEST1_WASM #ifdef SQLITE_SPEEDTEST1_WASM
/* Resetting all state is important for the WASM build, which may /* Resetting all state is important for the WASM build, which may
@@ -2334,6 +2335,8 @@ int main(int argc, char **argv){
}else if( strcmp(z,"key")==0 ){ }else if( strcmp(z,"key")==0 ){
ARGC_VALUE_CHECK(1); ARGC_VALUE_CHECK(1);
zKey = argv[++i]; zKey = argv[++i];
}else if( strcmp(z,"longdouble")==0 ){
useLongDouble = 1;
}else if( strcmp(z,"lookaside")==0 ){ }else if( strcmp(z,"lookaside")==0 ){
ARGC_VALUE_CHECK(2); ARGC_VALUE_CHECK(2);
nLook = integerValue(argv[i+1]); nLook = integerValue(argv[i+1]);
@@ -2353,9 +2356,7 @@ int main(int argc, char **argv){
mmapSize = integerValue(argv[++i]); mmapSize = integerValue(argv[++i]);
#endif #endif
}else if( strcmp(z,"nolongdouble")==0 ){ }else if( strcmp(z,"nolongdouble")==0 ){
#ifdef SQLITE_TESTCTRL_USELONGDOUBLE useLongDouble = 0;
sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, 0);
#endif
}else if( strcmp(z,"nomutex")==0 ){ }else if( strcmp(z,"nomutex")==0 ){
openFlags |= SQLITE_OPEN_NOMUTEX; openFlags |= SQLITE_OPEN_NOMUTEX;
}else if( strcmp(z,"nosync")==0 ){ }else if( strcmp(z,"nosync")==0 ){
@@ -2528,6 +2529,11 @@ int main(int argc, char **argv){
if( rc ) fatal_error("lookaside configuration failed: %d\n", rc); if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
} }
#endif #endif
#ifdef SQLITE_TESTCTRL_USELONGDOUBLE
if( useLongDouble>=0 ){
sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, useLongDouble);
}
#endif
if( g.nReserve>0 ){ if( g.nReserve>0 ){
sqlite3_file_control(g.db, 0, SQLITE_FCNTL_RESERVE_BYTES, &g.nReserve); sqlite3_file_control(g.db, 0, SQLITE_FCNTL_RESERVE_BYTES, &g.nReserve);
} }

View File

@@ -14,7 +14,7 @@
** between two SQLite databases. ** between two SQLite databases.
** **
** To compile, simply link against SQLite. (Windows builds must also link ** To compile, simply link against SQLite. (Windows builds must also link
** against ext/consio/console_io.c.) ** against ext/misc/sqlite3_stdio.c.)
** **
** See the showHelp() routine below for a brief description of how to ** See the showHelp() routine below for a brief description of how to
** run the utility. ** run the utility.
@@ -26,19 +26,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "sqlite3.h" #include "sqlite3.h"
#include "sqlite3_stdio.h"
/* Output function substitutions that cause UTF8 characters to be rendered
** correctly on Windows:
**
** fprintf() -> Wfprintf()
**
*/
#if defined(_WIN32)
# include "console_io.h"
# define Wfprintf fPrintfUtf8
#else
# define Wfprintf fprintf
#endif
/* /*
** All global variables are gathered into the "g" singleton. ** All global variables are gathered into the "g" singleton.
@@ -76,9 +64,9 @@ static void cmdlineError(const char *zFormat, ...){
va_start(ap, zFormat); va_start(ap, zFormat);
sqlite3_str_vappendf(pOut, zFormat, ap); sqlite3_str_vappendf(pOut, zFormat, ap);
va_end(ap); va_end(ap);
Wfprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); sqlite3_fprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut));
strFree(pOut); strFree(pOut);
Wfprintf(stderr, "\"%s --help\" for more help\n", g.zArgv0); sqlite3_fprintf(stderr, "\"%s --help\" for more help\n", g.zArgv0);
exit(1); exit(1);
} }
@@ -92,7 +80,7 @@ static void runtimeError(const char *zFormat, ...){
va_start(ap, zFormat); va_start(ap, zFormat);
sqlite3_str_vappendf(pOut, zFormat, ap); sqlite3_str_vappendf(pOut, zFormat, ap);
va_end(ap); va_end(ap);
Wfprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); sqlite3_fprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut));
strFree(pOut); strFree(pOut);
exit(1); exit(1);
} }
@@ -349,11 +337,11 @@ static void printQuoted(FILE *out, sqlite3_value *X){
char zBuf[50]; char zBuf[50];
r1 = sqlite3_value_double(X); r1 = sqlite3_value_double(X);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
fprintf(out, "%s", zBuf); sqlite3_fprintf(out, "%s", zBuf);
break; break;
} }
case SQLITE_INTEGER: { case SQLITE_INTEGER: {
fprintf(out, "%lld", sqlite3_value_int64(X)); sqlite3_fprintf(out, "%lld", sqlite3_value_int64(X));
break; break;
} }
case SQLITE_BLOB: { case SQLITE_BLOB: {
@@ -361,14 +349,14 @@ static void printQuoted(FILE *out, sqlite3_value *X){
int nBlob = sqlite3_value_bytes(X); int nBlob = sqlite3_value_bytes(X);
if( zBlob ){ if( zBlob ){
int i; int i;
fprintf(out, "x'"); sqlite3_fprintf(out, "x'");
for(i=0; i<nBlob; i++){ for(i=0; i<nBlob; i++){
fprintf(out, "%02x", zBlob[i]); sqlite3_fprintf(out, "%02x", zBlob[i]);
} }
fprintf(out, "'"); sqlite3_fprintf(out, "'");
}else{ }else{
/* Could be an OOM, could be a zero-byte blob */ /* Could be an OOM, could be a zero-byte blob */
fprintf(out, "X''"); sqlite3_fprintf(out, "X''");
} }
break; break;
} }
@@ -376,38 +364,38 @@ static void printQuoted(FILE *out, sqlite3_value *X){
const unsigned char *zArg = sqlite3_value_text(X); const unsigned char *zArg = sqlite3_value_text(X);
if( zArg==0 ){ if( zArg==0 ){
fprintf(out, "NULL"); sqlite3_fprintf(out, "NULL");
}else{ }else{
int inctl = 0; int inctl = 0;
int i, j; int i, j;
fprintf(out, "'"); sqlite3_fprintf(out, "'");
for(i=j=0; zArg[i]; i++){ for(i=j=0; zArg[i]; i++){
char c = zArg[i]; char c = zArg[i];
int ctl = iscntrl((unsigned char)c); int ctl = iscntrl((unsigned char)c);
if( ctl>inctl ){ if( ctl>inctl ){
inctl = ctl; inctl = ctl;
fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); sqlite3_fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c);
j = i+1; j = i+1;
}else if( ctl ){ }else if( ctl ){
fprintf(out, "%02x", c); sqlite3_fprintf(out, "%02x", c);
j = i+1; j = i+1;
}else{ }else{
if( inctl ){ if( inctl ){
inctl = 0; inctl = 0;
fprintf(out, "'\n||'"); sqlite3_fprintf(out, "'\n||'");
} }
if( c=='\'' ){ if( c=='\'' ){
fprintf(out, "%.*s'", i-j+1, &zArg[j]); sqlite3_fprintf(out, "%.*s'", i-j+1, &zArg[j]);
j = i+1; j = i+1;
} }
} }
} }
fprintf(out, "%s'", &zArg[j]); sqlite3_fprintf(out, "%s'", &zArg[j]);
} }
break; break;
} }
case SQLITE_NULL: { case SQLITE_NULL: {
fprintf(out, "NULL"); sqlite3_fprintf(out, "NULL");
break; break;
} }
} }
@@ -428,7 +416,7 @@ static void dump_table(const char *zTab, FILE *out){
pStmt = db_prepare("SELECT sql FROM aux.sqlite_schema WHERE name=%Q", zTab); pStmt = db_prepare("SELECT sql FROM aux.sqlite_schema WHERE name=%Q", zTab);
if( SQLITE_ROW==sqlite3_step(pStmt) ){ if( SQLITE_ROW==sqlite3_step(pStmt) ){
fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0)); sqlite3_fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
if( !g.bSchemaOnly ){ if( !g.bSchemaOnly ){
@@ -463,14 +451,14 @@ static void dump_table(const char *zTab, FILE *out){
} }
nCol = sqlite3_column_count(pStmt); nCol = sqlite3_column_count(pStmt);
while( SQLITE_ROW==sqlite3_step(pStmt) ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){
Wfprintf(out, "%s",sqlite3_str_value(pIns)); sqlite3_fprintf(out, "%s",sqlite3_str_value(pIns));
zSep = "("; zSep = "(";
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
Wfprintf(out, "%s",zSep); sqlite3_fprintf(out, "%s",zSep);
printQuoted(out, sqlite3_column_value(pStmt,i)); printQuoted(out, sqlite3_column_value(pStmt,i));
zSep = ","; zSep = ",";
} }
Wfprintf(out, ");\n"); sqlite3_fprintf(out, ");\n");
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
strFree(pIns); strFree(pIns);
@@ -479,7 +467,7 @@ static void dump_table(const char *zTab, FILE *out){
" WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL", " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
zTab); zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){
Wfprintf(out, "%s;\n", sqlite3_column_text(pStmt,0)); sqlite3_fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
sqlite3_free(zId); sqlite3_free(zId);
@@ -514,14 +502,14 @@ static void diff_one_table(const char *zTab, FILE *out){
*/ */
az = columnNames("aux",zTab, &nPk, 0); az = columnNames("aux",zTab, &nPk, 0);
if( az==0 ){ if( az==0 ){
Wfprintf(stdout, "Rowid not accessible for %s\n", zId); sqlite3_fprintf(stdout, "Rowid not accessible for %s\n", zId);
}else{ }else{
Wfprintf(stdout, "%s:", zId); sqlite3_fprintf(stdout, "%s:", zId);
for(i=0; az[i]; i++){ for(i=0; az[i]; i++){
Wfprintf(stdout, " %s", az[i]); sqlite3_fprintf(stdout, " %s", az[i]);
if( i+1==nPk ) Wfprintf(stdout, " *"); if( i+1==nPk ) sqlite3_fprintf(stdout, " *");
} }
Wfprintf(stdout, "\n"); sqlite3_fprintf(stdout, "\n");
} }
goto end_diff_one_table; goto end_diff_one_table;
} }
@@ -530,9 +518,9 @@ static void diff_one_table(const char *zTab, FILE *out){
if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){ if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from second database. */ /* Table missing from second database. */
if( g.bSchemaCompare ) if( g.bSchemaCompare )
Wfprintf(out, "-- 2nd DB has no %s table\n", zTab); sqlite3_fprintf(out, "-- 2nd DB has no %s table\n", zTab);
else else
Wfprintf(out, "DROP TABLE %s;\n", zId); sqlite3_fprintf(out, "DROP TABLE %s;\n", zId);
} }
goto end_diff_one_table; goto end_diff_one_table;
} }
@@ -540,7 +528,7 @@ static void diff_one_table(const char *zTab, FILE *out){
if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){ if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from source */ /* Table missing from source */
if( g.bSchemaCompare ){ if( g.bSchemaCompare ){
Wfprintf(out, "-- 1st DB has no %s table\n", zTab); sqlite3_fprintf(out, "-- 1st DB has no %s table\n", zTab);
}else{ }else{
dump_table(zTab, out); dump_table(zTab, out);
} }
@@ -560,7 +548,7 @@ static void diff_one_table(const char *zTab, FILE *out){
|| az[n] || az[n]
){ ){
/* Schema mismatch */ /* Schema mismatch */
Wfprintf(out, "%sDROP TABLE %s; -- due to schema mismatch\n", zLead, zId); sqlite3_fprintf(out, "%sDROP TABLE %s; -- due to schema mismatch\n", zLead, zId);
dump_table(zTab, out); dump_table(zTab, out);
goto end_diff_one_table; goto end_diff_one_table;
} }
@@ -568,7 +556,7 @@ static void diff_one_table(const char *zTab, FILE *out){
/* Build the comparison query */ /* Build the comparison query */
for(n2=n; az2[n2]; n2++){ for(n2=n; az2[n2]; n2++){
char *zNTab = safeId(az2[n2]); char *zNTab = safeId(az2[n2]);
Wfprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, zNTab); sqlite3_fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, zNTab);
sqlite3_free(zNTab); sqlite3_free(zNTab);
} }
nQ = nPk2+1+2*(n2-nPk2); nQ = nPk2+1+2*(n2-nPk2);
@@ -669,7 +657,7 @@ static void diff_one_table(const char *zTab, FILE *out){
zTab, zTab); zTab, zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){
char *z = safeId((const char*)sqlite3_column_text(pStmt,0)); char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
fprintf(out, "DROP INDEX %s;\n", z); sqlite3_fprintf(out, "DROP INDEX %s;\n", z);
sqlite3_free(z); sqlite3_free(z);
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
@@ -681,39 +669,39 @@ static void diff_one_table(const char *zTab, FILE *out){
int iType = sqlite3_column_int(pStmt, nPk); int iType = sqlite3_column_int(pStmt, nPk);
if( iType==1 || iType==2 ){ if( iType==1 || iType==2 ){
if( iType==1 ){ /* Change the content of a row */ if( iType==1 ){ /* Change the content of a row */
fprintf(out, "%sUPDATE %s", zLead, zId); sqlite3_fprintf(out, "%sUPDATE %s", zLead, zId);
zSep = " SET"; zSep = " SET";
for(i=nPk+1; i<nQ; i+=2){ for(i=nPk+1; i<nQ; i+=2){
if( sqlite3_column_int(pStmt,i)==0 ) continue; if( sqlite3_column_int(pStmt,i)==0 ) continue;
fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]); sqlite3_fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
zSep = ","; zSep = ",";
printQuoted(out, sqlite3_column_value(pStmt,i+1)); printQuoted(out, sqlite3_column_value(pStmt,i+1));
} }
}else{ /* Delete a row */ }else{ /* Delete a row */
fprintf(out, "%sDELETE FROM %s", zLead, zId); sqlite3_fprintf(out, "%sDELETE FROM %s", zLead, zId);
} }
zSep = " WHERE"; zSep = " WHERE";
for(i=0; i<nPk; i++){ for(i=0; i<nPk; i++){
fprintf(out, "%s %s=", zSep, az2[i]); sqlite3_fprintf(out, "%s %s=", zSep, az2[i]);
printQuoted(out, sqlite3_column_value(pStmt,i)); printQuoted(out, sqlite3_column_value(pStmt,i));
zSep = " AND"; zSep = " AND";
} }
fprintf(out, ";\n"); sqlite3_fprintf(out, ";\n");
}else{ /* Insert a row */ }else{ /* Insert a row */
fprintf(out, "%sINSERT INTO %s(%s", zLead, zId, az2[0]); sqlite3_fprintf(out, "%sINSERT INTO %s(%s", zLead, zId, az2[0]);
for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]); for(i=1; az2[i]; i++) sqlite3_fprintf(out, ",%s", az2[i]);
fprintf(out, ") VALUES"); sqlite3_fprintf(out, ") VALUES");
zSep = "("; zSep = "(";
for(i=0; i<nPk2; i++){ for(i=0; i<nPk2; i++){
fprintf(out, "%s", zSep); sqlite3_fprintf(out, "%s", zSep);
zSep = ","; zSep = ",";
printQuoted(out, sqlite3_column_value(pStmt,i)); printQuoted(out, sqlite3_column_value(pStmt,i));
} }
for(i=nPk2+2; i<nQ; i+=2){ for(i=nPk2+2; i<nQ; i+=2){
fprintf(out, ","); sqlite3_fprintf(out, ",");
printQuoted(out, sqlite3_column_value(pStmt,i)); printQuoted(out, sqlite3_column_value(pStmt,i));
} }
fprintf(out, ");\n"); sqlite3_fprintf(out, ");\n");
} }
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
@@ -729,7 +717,7 @@ static void diff_one_table(const char *zTab, FILE *out){
" AND sql IS NOT NULL)", " AND sql IS NOT NULL)",
zTab, zTab); zTab, zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){
fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0)); sqlite3_fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
@@ -1283,17 +1271,17 @@ static void rbudiff_one_table(const char *zTab, FILE *out){
** statement first. And reset pCt so that it will not be ** statement first. And reset pCt so that it will not be
** printed again. */ ** printed again. */
if( sqlite3_str_length(pCt) ){ if( sqlite3_str_length(pCt) ){
fprintf(out, "%s\n", sqlite3_str_value(pCt)); sqlite3_fprintf(out, "%s\n", sqlite3_str_value(pCt));
sqlite3_str_reset(pCt); sqlite3_str_reset(pCt);
} }
/* Output the first part of the INSERT statement */ /* Output the first part of the INSERT statement */
fprintf(out, "%s", sqlite3_str_value(pInsert)); sqlite3_fprintf(out, "%s", sqlite3_str_value(pInsert));
nRow++; nRow++;
if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){ if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){
for(i=0; i<=nCol; i++){ for(i=0; i<=nCol; i++){
if( i>0 ) fprintf(out, ", "); if( i>0 ) sqlite3_fprintf(out, ", ");
printQuoted(out, sqlite3_column_value(pStmt, i)); printQuoted(out, sqlite3_column_value(pStmt, i));
} }
}else{ }else{
@@ -1320,9 +1308,9 @@ static void rbudiff_one_table(const char *zTab, FILE *out){
nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta); nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta);
if( nDelta<nFinal ){ if( nDelta<nFinal ){
int j; int j;
fprintf(out, "x'"); sqlite3_fprintf(out, "x'");
for(j=0; j<nDelta; j++) fprintf(out, "%02x", (u8)aDelta[j]); for(j=0; j<nDelta; j++) sqlite3_fprintf(out, "%02x", (u8)aDelta[j]);
fprintf(out, "'"); sqlite3_fprintf(out, "'");
zOtaControl[i-bOtaRowid] = 'f'; zOtaControl[i-bOtaRowid] = 'f';
bDone = 1; bDone = 1;
} }
@@ -1332,14 +1320,14 @@ static void rbudiff_one_table(const char *zTab, FILE *out){
if( bDone==0 ){ if( bDone==0 ){
printQuoted(out, sqlite3_column_value(pStmt, i)); printQuoted(out, sqlite3_column_value(pStmt, i));
} }
fprintf(out, ", "); sqlite3_fprintf(out, ", ");
} }
fprintf(out, "'%s'", zOtaControl); sqlite3_fprintf(out, "'%s'", zOtaControl);
sqlite3_free(zOtaControl); sqlite3_free(zOtaControl);
} }
/* And the closing bracket of the insert statement */ /* And the closing bracket of the insert statement */
fprintf(out, ");\n"); sqlite3_fprintf(out, ");\n");
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
@@ -1347,7 +1335,7 @@ static void rbudiff_one_table(const char *zTab, FILE *out){
sqlite3_str *pCnt = sqlite3_str_new(0); sqlite3_str *pCnt = sqlite3_str_new(0);
sqlite3_str_appendf(pCnt, sqlite3_str_appendf(pCnt,
"INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow); "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow);
fprintf(out, "%s\n", sqlite3_str_value(pCnt)); sqlite3_fprintf(out, "%s\n", sqlite3_str_value(pCnt));
strFree(pCnt); strFree(pCnt);
} }
@@ -1386,14 +1374,14 @@ static void summarize_one_table(const char *zTab, FILE *out){
if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){ if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){ if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from second database. */ /* Table missing from second database. */
Wfprintf(out, "%s: missing from second database\n", zTab); sqlite3_fprintf(out, "%s: missing from second database\n", zTab);
} }
goto end_summarize_one_table; goto end_summarize_one_table;
} }
if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){ if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from source */ /* Table missing from source */
Wfprintf(out, "%s: missing from first database\n", zTab); sqlite3_fprintf(out, "%s: missing from first database\n", zTab);
goto end_summarize_one_table; goto end_summarize_one_table;
} }
@@ -1410,7 +1398,7 @@ static void summarize_one_table(const char *zTab, FILE *out){
|| az[n] || az[n]
){ ){
/* Schema mismatch */ /* Schema mismatch */
Wfprintf(out, "%s: incompatible schema\n", zTab); sqlite3_fprintf(out, "%s: incompatible schema\n", zTab);
goto end_summarize_one_table; goto end_summarize_one_table;
} }
@@ -1455,7 +1443,7 @@ static void summarize_one_table(const char *zTab, FILE *out){
sqlite3_str_appendf(pSql, ")\n ORDER BY 1;\n"); sqlite3_str_appendf(pSql, ")\n ORDER BY 1;\n");
if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){ if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
Wfprintf(stdout, "SQL for %s:\n%s\n", zId, sqlite3_str_value(pSql)); sqlite3_fprintf(stdout, "SQL for %s:\n%s\n", zId, sqlite3_str_value(pSql));
goto end_summarize_one_table; goto end_summarize_one_table;
} }
@@ -1480,7 +1468,7 @@ static void summarize_one_table(const char *zTab, FILE *out){
} }
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
Wfprintf(out, sqlite3_fprintf(out,
"%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n", "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
zTab, nUpdate, nInsert, nDelete, nUnchanged); zTab, nUpdate, nInsert, nDelete, nUnchanged);
@@ -1661,7 +1649,7 @@ static void changeset_one_table(const char *zTab, FILE *out){
sqlite3_str_appendf(pSql, ";\n"); sqlite3_str_appendf(pSql, ";\n");
if( g.fDebug & DEBUG_DIFF_SQL ){ if( g.fDebug & DEBUG_DIFF_SQL ){
Wfprintf(stdout, "SQL for %s:\n%s\n", zId, sqlite3_str_value(pSql)); sqlite3_fprintf(stdout, "SQL for %s:\n%s\n", zId, sqlite3_str_value(pSql));
goto end_changeset_one_table; goto end_changeset_one_table;
} }
@@ -1891,8 +1879,8 @@ const char *all_tables_sql(){
** Print sketchy documentation for this utility program ** Print sketchy documentation for this utility program
*/ */
static void showHelp(void){ static void showHelp(void){
Wfprintf(stdout, "Usage: %s [options] DB1 DB2\n", g.zArgv0); sqlite3_fprintf(stdout, "Usage: %s [options] DB1 DB2\n", g.zArgv0);
Wfprintf(stdout, sqlite3_fprintf(stdout,
"Output SQL text that would transform DB1 into DB2.\n" "Output SQL text that would transform DB1 into DB2.\n"
"Options:\n" "Options:\n"
" --changeset FILE Write a CHANGESET into FILE\n" " --changeset FILE Write a CHANGESET into FILE\n"
@@ -1935,7 +1923,7 @@ int main(int argc, char **argv){
if( z[0]=='-' ) z++; if( z[0]=='-' ) z++;
if( strcmp(z,"changeset")==0 ){ if( strcmp(z,"changeset")==0 ){
if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]); if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
out = fopen(argv[++i], "wb"); out = sqlite3_fopen(argv[++i], "wb");
if( out==0 ) cmdlineError("cannot open: %s", argv[i]); if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
xDiff = changeset_one_table; xDiff = changeset_one_table;
neverUseTransaction = 1; neverUseTransaction = 1;
@@ -2036,9 +2024,9 @@ int main(int argc, char **argv){
} }
if( neverUseTransaction ) useTransaction = 0; if( neverUseTransaction ) useTransaction = 0;
if( useTransaction ) Wfprintf(out, "BEGIN TRANSACTION;\n"); if( useTransaction ) sqlite3_fprintf(out, "BEGIN TRANSACTION;\n");
if( xDiff==rbudiff_one_table ){ if( xDiff==rbudiff_one_table ){
Wfprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count" sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count"
"(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) " "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) "
"WITHOUT ROWID;\n" "WITHOUT ROWID;\n"
); );
@@ -2053,7 +2041,7 @@ int main(int argc, char **argv){
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
} }
if( useTransaction ) Wfprintf(stdout,"COMMIT;\n"); if( useTransaction ) sqlite3_fprintf(stdout,"COMMIT;\n");
/* TBD: Handle trigger differences */ /* TBD: Handle trigger differences */
/* TBD: Handle view differences */ /* TBD: Handle view differences */

View File

@@ -20,8 +20,8 @@ INCLUDE sqlite3.c
INCLUDE $ROOT/src/tclsqlite.c INCLUDE $ROOT/src/tclsqlite.c
#if defined(_WIN32) #if defined(_WIN32)
INCLUDE $ROOT/ext/consio/console_io.h INCLUDE $ROOT/ext/misc/sqlite3_stdio.h
INCLUDE $ROOT/ext/consio/console_io.c INCLUDE $ROOT/ext/misc/sqlite3_stdio.c
/* Substitute "puts" command. Only these forms recognized: /* Substitute "puts" command. Only these forms recognized:
** **
@@ -56,8 +56,8 @@ static int subst_puts(
return TCL_ERROR; return TCL_ERROR;
} }
} }
fPutsUtf8(zOut, pOut); sqlite3_fputs(zOut, pOut);
if( addNewLine ) fPutsUtf8("\n", pOut); if( addNewLine ) sqlite3_fputs("\n", pOut);
return TCL_OK; return TCL_OK;
} }
#endif /* defined(_WIN32) */ #endif /* defined(_WIN32) */