Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b783ec950 | |||
| 847d2ed685 | |||
| 18a9bdd90a | |||
| 3e2ecc390b | |||
| a1dede1e58 | |||
| 982274b8e9 | |||
| e83ffd5c87 | |||
| 393a4d8ac5 | |||
| 987870a6a0 | |||
| a804a65617 | |||
| 5279cbd353 | |||
| c14ae9cd3b | |||
| ed7981ea3e | |||
| e1f7ec65fd | |||
| 505d8a43db | |||
| 408c991017 | |||
| 09cc9b5184 | |||
| 9bafbd122b | |||
| 7a796b702f | |||
| 8b34ce7d61 | |||
| 826bebdb31 | |||
| 388c1da56e | |||
| 9e6474c5a8 | |||
| 319870836c | |||
| a9025a5f1a | |||
| 237778289b | |||
| 57a533a7c3 | |||
| f47095a5a0 | |||
| 791b767b26 | |||
| ce53b80819 | |||
| b867030b1a | |||
| 7efded5edc | |||
| f07576429e | |||
| 14fcb8252a | |||
| a79f685533 | |||
| 240397bb03 | |||
| 4ac766cc05 | |||
| 73caea1764 | |||
| 998ebf1de7 | |||
| 051e942f5d | |||
| 4182294987 | |||
| c55d8262cf | |||
| 66b37e991b | |||
| 0aca0ccf2c | |||
| 748c0adb62 | |||
| e77530050e | |||
| 366e0ed80c | |||
| 201066302e | |||
| 29bdac3ee5 | |||
| 53ba0b80f2 | |||
| b799156a31 | |||
| 23e4ae2121 | |||
| abc23b5404 | |||
| e977440d79 | |||
| bb3b269ba9 | |||
| c129de05bb | |||
| 6acd8d28fd | |||
| bc5e0be7f8 | |||
| 241004f8fc | |||
| 89a9efe840 | |||
| 4f177f1d3e | |||
| 02c5f3976f |
@@ -1770,6 +1770,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -117,19 +117,6 @@ sqlite_cfg.h: $(AS_AUTO_DEF)
|
||||
# CFLAGS for sqlite3$(T.exe)
|
||||
#
|
||||
SHELL_OPT ?= @OPT_SHELL@
|
||||
SHELL_OPT += -DSQLITE_DQS=0
|
||||
SHELL_OPT += -DSQLITE_ENABLE_FTS4
|
||||
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
|
||||
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
|
||||
|
||||
#
|
||||
# Library-level feature flags
|
||||
|
||||
@@ -557,7 +557,25 @@ proc proc-debug {msg} {
|
||||
}
|
||||
|
||||
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
|
||||
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
|
||||
#
|
||||
# OPT_SHELL = feature-related CFLAGS for the sqlite3 CLI app. The
|
||||
# list's initial values are defaults which are always applied and not
|
||||
# affected by --feature-flags. The list is appended to by various
|
||||
# --feature-flags.
|
||||
define OPT_SHELL {
|
||||
-DSQLITE_DQS=0
|
||||
-DSQLITE_ENABLE_FTS4
|
||||
-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_ENABLE_PERCENTILE
|
||||
-DSQLITE_STRICT_SUBTYPE=1
|
||||
}
|
||||
########################################################################
|
||||
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
|
||||
# -shell then it strips that arg and passes the remaining args the
|
||||
|
||||
+22
-7
@@ -695,6 +695,7 @@ other than that, the order of directives in Lemon is arbitrary.</p>
|
||||
<li><tt><a href='#parse_failure'>%parse_failure</a></tt>
|
||||
<li><tt><a href='#pright'>%right</a></tt>
|
||||
<li><tt><a href='#reallc'>%realloc</a></tt>
|
||||
<li><tt><a href='#reallc'>%reallocx</a></tt>
|
||||
<li><tt><a href='#stack_overflow'>%stack_overflow</a></tt>
|
||||
<li><tt><a href='#stack_size'>%stack_size</a></tt>
|
||||
<li><tt><a href='#start_symbol'>%start_symbol</a></tt>
|
||||
@@ -1203,15 +1204,29 @@ the wildcard token and some other token, the other token is always used.
|
||||
The wildcard token is only matched if there are no alternatives.</p>
|
||||
|
||||
<a id='reallc'></a>
|
||||
<h4>4.4.26 The <tt>%realloc</tt> and <tt>%free</tt> directives</h4>
|
||||
<h4>4.4.26 The <tt>%realloc</tt>, <tt>%reallocx</tt>,
|
||||
and <tt>%free</tt> directives</h4>
|
||||
|
||||
<p>The <tt>%realloc</tt> and <tt>%free</tt> directives defines function
|
||||
that allocate and free heap memory. The signatures of these functions
|
||||
should be the same as the realloc() and free() functions from the standard
|
||||
C library.
|
||||
<p>The <tt>%realloc</tt>, <tt>%reallocx</tt>, and <tt>%free</tt>
|
||||
directives defines function that allocate and free heap memory.
|
||||
The signatures of th3 %realloc and %free are the same as
|
||||
realloc() and free() functions from the standard C library.
|
||||
The %reallocx function has the same semantics as %realloc but
|
||||
takes four parameters instead of two:
|
||||
<ol>
|
||||
<li> A pointer to the space to be reallocated, or NULL for a new allocation,
|
||||
<li> The number of elements to allocate,
|
||||
<li> The size of each element,
|
||||
<li> The %extra parameter.
|
||||
</ol>
|
||||
The extra parameters of %reallocx can be used, for example, to monitor
|
||||
the parser stack size and raise an error if it exceeds application-defined
|
||||
limits.
|
||||
If both %reallocx and %realloc are defined, then %reallocx is used
|
||||
and %realloc is ignored.
|
||||
|
||||
<p>If both of these functions are defined
|
||||
then these functions are used to allocate and free
|
||||
<p>If %free is defined and one of %realloc and %reallocx is
|
||||
defined then the functions are used to allocate and free
|
||||
memory for supplemental parser stack space, if the initial
|
||||
parse stack space is exceeded. The initial parser stack size
|
||||
is specified by either <tt>%stack_size</tt> or the
|
||||
|
||||
@@ -2074,7 +2074,6 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
|
||||
while( 1 ){
|
||||
u64 iDelta = 0;
|
||||
|
||||
if( i>=n ) break;
|
||||
if( eDetail==FTS5_DETAIL_NONE ){
|
||||
/* todo */
|
||||
if( i<n && a[i]==0 ){
|
||||
|
||||
@@ -396,12 +396,7 @@ static int fts5VocabOpenMethod(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Restore cursor pCsr to the state it was in immediately after being
|
||||
** created by the xOpen() method.
|
||||
*/
|
||||
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
|
||||
int nCol = pCsr->pFts5->pConfig->nCol;
|
||||
pCsr->rowid = 0;
|
||||
sqlite3Fts5IterClose(pCsr->pIter);
|
||||
sqlite3Fts5StructureRelease(pCsr->pStruct);
|
||||
@@ -411,12 +406,6 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
|
||||
pCsr->nLeTerm = -1;
|
||||
pCsr->zLeTerm = 0;
|
||||
pCsr->bEof = 0;
|
||||
pCsr->iCol = 0;
|
||||
pCsr->iInstPos = 0;
|
||||
pCsr->iInstOff = 0;
|
||||
pCsr->colUsed = 0;
|
||||
memset(pCsr->aCnt, 0, sizeof(i64)*nCol);
|
||||
memset(pCsr->aDoc, 0, sizeof(i64)*nCol);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -16124,367 +16124,5 @@ do_catchsql_test 83.1 {
|
||||
SELECT * FROM t1('R*R*R*R*R*R*R*R*') WHERE (a,b)<=(current_date,0 BETWEEN 'a'<>11 AND '') ORDER BY rowid DESC;
|
||||
} {/.*fts5: corruption found/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 84.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 53248 pagesize 4096 filename c1a.txt.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 0d .....@ ........
|
||||
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
|
||||
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
|
||||
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
|
||||
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
|
||||
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
|
||||
| 3488: 32 74 32 0d 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
|
||||
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
|
||||
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
|
||||
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
|
||||
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
|
||||
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
|
||||
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
|
||||
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
|
||||
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
|
||||
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
|
||||
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
|
||||
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
|
||||
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
|
||||
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
|
||||
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
|
||||
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
|
||||
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
|
||||
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
|
||||
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
|
||||
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
|
||||
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
|
||||
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
|
||||
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
|
||||
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
|
||||
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
|
||||
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
|
||||
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
|
||||
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
|
||||
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
|
||||
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
|
||||
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
|
||||
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
|
||||
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
|
||||
| 4032: 28 61 2c 62 2c 63 29 00 00 00 39 00 00 00 00 00 (a,b,c)...9.....
|
||||
| page 3 offset 8192
|
||||
| 0: 05 00 00 00 02 0f f1 00 00 00 00 0c 0f fb 0f f1 ................
|
||||
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0a ........:.^.:.:.
|
||||
| 4080: 0a 00 00 00 0b 84 80 80 80 80 01 00 00 00 0a 0a ................
|
||||
| page 4 offset 12288
|
||||
| 0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
|
||||
| page 7 offset 24576
|
||||
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
|
||||
| page 10 offset 36864
|
||||
| 0: 0d 00 00 00 02 0f e2 00 0f e2 0f ef 00 00 00 00 ................
|
||||
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0f ........:.^.:.:.
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 02 00 01 01 01 09 ...$............
|
||||
| page 11 offset 40960
|
||||
| 0: 0d 00 00 00 01 00 22 00 00 22 00 00 00 00 00 00 ................
|
||||
| 32: 00 00 9f 56 84 80 80 80 80 01 04 00 bf 30 00 00 ...V.........0..
|
||||
| 48: 0f 58 02 30 30 19 02 05 01 02 05 01 02 05 16 02 .X.00...........
|
||||
| 64: 05 01 02 05 01 02 05 61 02 05 01 02 05 01 02 05 .......a........
|
||||
| 80: 13 02 05 01 02 05 01 02 05 0d 02 03 01 02 03 01 ................
|
||||
| 96: 02 03 02 09 78 66 66 66 66 66 66 66 65 81 17 02 ....xfffffffe...
|
||||
| 112: 05 01 02 05 01 02 05 01 01 31 04 02 04 01 02 04 .........1......
|
||||
| 128: 01 02 04 01 02 05 01 02 05 01 02 05 0d 02 06 01 ................
|
||||
| 144: 02 06 01 02 06 02 01 30 79 02 04 01 02 04 01 02 .......0y.......
|
||||
| 160: 04 03 02 30 30 2b 02 05 01 02 05 01 02 05 58 02 ...00+........X.
|
||||
| 176: 05 01 02 05 01 02 05 01 02 05 01 02 05 01 02 05 ................
|
||||
| 192: 16 02 05 01 02 05 01 02 05 05 06 30 30 30 30 30 ...........00000
|
||||
| 208: 30 81 0b 02 04 01 02 04 01 02 04 10 02 05 01 02 0...............
|
||||
| 224: 05 01 02 05 03 02 32 34 76 02 05 01 02 05 01 02 ......24v.......
|
||||
| 240: 05 02 01 38 07 02 04 01 02 04 01 02 04 01 01 32 ...8...........2
|
||||
| 256: 28 02 04 01 02 04 01 02 04 04 02 05 01 02 05 01 (...............
|
||||
| 272: 02 05 02 01 30 1f 02 05 01 02 05 01 02 05 03 02 ....0...........
|
||||
| 288: 30 30 10 02 05 01 02 05 01 02 05 6a 02 04 01 02 00.........j....
|
||||
| 304: 04 01 02 04 02 08 35 30 30 30 30 30 30 30 81 26 ......50000000.&
|
||||
| 320: 02 05 01 02 05 01 02 05 01 01 33 07 02 06 01 02 ..........3.....
|
||||
| 336: 06 01 02 06 81 2c 02 04 01 02 04 01 02 04 02 04 .....,..........
|
||||
| 352: 32 37 36 36 81 23 02 05 01 02 05 01 02 05 01 01 2766.#..........
|
||||
| 368: 34 13 02 05 01 02 05 01 02 05 02 03 30 39 36 1c 4...........096.
|
||||
| 384: 02 05 01 02 05 01 02 05 07 02 05 01 02 05 01 02 ................
|
||||
| 400: 05 01 03 35 30 30 7f 02 05 01 02 05 01 02 05 04 ...500..........
|
||||
| 416: 02 30 30 81 0e 02 06 01 02 06 01 02 06 06 03 30 .00............0
|
||||
| 432: 30 30 81 11 02 04 01 02 04 01 02 04 01 05 36 35 00............65
|
||||
| 448: 35 33 36 81 1a 02 05 01 02 05 01 02 05 01 04 38 536............8
|
||||
| 464: 31 39 32 81 02 02 06 01 02 06 01 02 06 01 05 61 192............a
|
||||
| 480: 6c 6c 6f 77 01 02 02 01 02 02 01 02 02 02 02 72 llow...........r
|
||||
| 496: 67 81 08 02 04 01 02 04 01 02 04 02 05 74 6f 6d g............tom
|
||||
| 512: 69 63 04 02 02 01 02 02 01 02 02 03 06 74 61 63 ic...........tac
|
||||
| 528: 68 65 64 79 02 03 01 02 03 01 02 03 02 0d 75 74 hedy..........ut
|
||||
| 544: 6f 63 68 65 63 6b 70 6f 69 6e 74 2b 02 04 01 02 ocheckpoint+....
|
||||
| 560: 04 01 02 04 05 06 76 61 63 75 75 6d 0d 02 03 01 ......vacuum....
|
||||
| 576: 02 03 01 02 03 01 06 62 69 6e 61 72 79 03 06 01 .......binary...
|
||||
| 592: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 608: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 624: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 640: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 656: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 672: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 688: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 704: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 720: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 736: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 752: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 768: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 784: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 800: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 816: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 832: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 848: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 864: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 880: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 896: 01 02 02 02 07 79 74 65 63 6f 64 65 37 02 03 01 .....ytecode7...
|
||||
| 912: 02 03 01 02 03 01 05 63 61 63 68 65 10 02 03 01 .......cache....
|
||||
| 928: 02 03 01 01 03 02 04 6c 61 6e 67 07 02 03 01 02 .......lang.....
|
||||
| 944: 03 01 02 03 02 05 6f 6c 75 6d 6e 7c 02 03 01 02 ......olumn|....
|
||||
| 960: 03 01 02 03 03 06 6d 6d 65 6e 74 73 43 02 04 01 ......mmentsC...
|
||||
| 976: 02 04 01 02 04 04 05 70 69 6c 65 72 07 02 02 01 .......piler....
|
||||
| 992: 02 02 01 02 02 05 04 6f 75 6e 64 7f 02 03 01 02 .......ound.....
|
||||
| 1008: 03 01 02 03 03 03 75 6e 74 81 17 02 04 01 02 04 ......unt.......
|
||||
| 1024: 01 02 04 02 05 75 72 73 6f 72 3a 02 03 01 02 03 .....ursor:.....
|
||||
| 1040: 01 02 03 01 06 64 62 70 61 67 65 3d 02 03 01 02 .....dbpage=....
|
||||
| 1056: 03 01 02 03 03 04 73 74 61 74 40 02 03 01 02 03 ......stat@.....
|
||||
| 1072: 01 02 03 02 04 65 62 75 67 0a 02 02 01 02 02 01 .....ebug.......
|
||||
| 1088: 02 02 03 05 66 61 75 6c 74 0d 02 02 01 02 02 01 ....fault.......
|
||||
| 1104: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1120: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1136: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1152: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1168: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1184: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1200: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 4f 02 ..............O.
|
||||
| 1216: 03 01 02 03 01 02 03 03 03 70 74 68 81 05 02 04 .........pth....
|
||||
| 1232: 01 02 04 01 02 04 19 02 04 01 02 04 01 02 04 02 ................
|
||||
| 1248: 05 69 72 65 63 74 34 02 02 01 02 02 01 02 02 01 .irect4.........
|
||||
| 1264: 06 65 6e 61 62 6c 65 37 02 02 01 02 02 01 02 02 .enable7........
|
||||
| 1280: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1296: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1312: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1328: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1344: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1360: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1376: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1392: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1408: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1424: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1440: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1456: 02 01 02 02 02 06 78 70 6c 61 69 6e 43 02 03 01 ......xplainC...
|
||||
| 1472: 02 03 01 02 03 04 01 72 81 05 02 03 01 02 03 01 .......r........
|
||||
| 1488: 02 03 03 07 74 65 6e 73 69 6f 6e 81 2f 02 04 01 ....tension./...
|
||||
| 1504: 02 04 01 02 04 01 04 66 69 6c 65 13 02 03 01 02 .......file.....
|
||||
| 1520: 03 01 02 03 02 05 6f 72 6d 61 74 13 02 04 01 02 ......ormat.....
|
||||
| 1536: 04 01 02 04 02 03 74 73 33 46 02 03 01 02 03 01 ......ts3F......
|
||||
| 1552: 02 03 01 02 03 01 02 03 01 02 03 04 01 34 4c 02 .............4L.
|
||||
| 1568: 03 01 02 03 01 02 03 04 01 35 4f 02 03 01 02 03 .........5O.....
|
||||
| 1584: 01 02 03 02 03 75 6e 63 5e 02 05 01 02 05 01 02 .....unc^.......
|
||||
| 1600: 05 05 04 74 69 6f 6e 73 02 05 01 02 05 01 02 05 ...tions........
|
||||
| 1616: 13 02 03 01 02 03 01 02 03 09 01 73 55 02 04 01 ...........sU...
|
||||
| 1632: 02 04 01 02 04 01 07 67 65 6f 70 6f 6c 79 52 02 .......geopolyR.
|
||||
| 1648: 03 01 02 03 01 02 03 01 05 68 69 6e 74 73 3a 02 .........hints:.
|
||||
| 1664: 04 01 02 04 01 02 04 02 03 6f 6f 6b 61 02 04 01 .........ooka...
|
||||
| 1680: 02 04 01 02 04 01 02 69 6e 01 02 04 01 02 04 01 .......in.......
|
||||
| 1696: 02 04 03 04 69 74 73 7a 1f 02 04 01 02 04 01 02 ....itsz........
|
||||
| 1712: 04 03 08 74 72 69 6e 73 69 63 73 04 02 03 01 02 ...trinsics.....
|
||||
| 1728: 03 01 02 03 01 07 6a 6f 75 72 6e 61 6c 16 02 03 ......journal...
|
||||
| 1744: 01 02 03 01 02 03 01 06 6c 65 6e 67 74 68 81 0b ........length..
|
||||
| 1760: 02 03 01 02 03 01 02 03 01 02 05 01 02 05 01 02 ................
|
||||
| 1776: 05 0d 02 04 01 02 04 01 02 04 02 03 69 6b 65 81 ............ike.
|
||||
| 1792: 0e 02 03 01 02 03 01 02 03 03 03 6d 69 74 16 02 ...........mit..
|
||||
| 1808: 05 01 02 05 01 02 05 5e 02 04 01 02 04 01 02 04 .......^........
|
||||
| 1824: 02 03 6f 61 64 81 2f 02 03 01 02 03 01 02 03 01 ..oad./.........
|
||||
| 1840: 06 6d 61 6c 6c 6f 63 76 02 02 01 02 02 01 02 02 .mallocv........
|
||||
| 1856: 3a 02 03 01 02 03 01 02 03 03 02 74 68 55 02 03 :..........thU..
|
||||
| 1872: 01 02 03 01 02 03 03 01 78 79 02 02 01 02 02 01 ........xy......
|
||||
| 1888: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1904: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1920: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1936: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 1952: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 1968: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 1984: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 2000: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 2016: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
|
||||
| 2032: 02 02 02 05 65 6d 6f 72 79 81 11 02 03 01 02 03 ....emory.......
|
||||
| 2048: 01 02 03 04 04 73 79 73 35 58 02 03 01 02 03 01 .....sys5X......
|
||||
| 2064: 02 03 02 03 6d 61 70 19 02 03 01 02 03 01 02 03 ....map.........
|
||||
| 2080: 79 02 03 01 02 03 01 02 03 02 04 75 74 65 78 81 y..........utex.
|
||||
| 2096: 2c 02 02 01 02 02 01 02 02 01 06 6e 6f 63 61 73 ,..........nocas
|
||||
| 2112: 65 02 06 01 02 02 03 06 01 02 02 03 06 01 02 02 e...............
|
||||
| 2128: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2144: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2160: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2176: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2192: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2208: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2224: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2240: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2256: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2272: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2288: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2304: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2320: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2336: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2352: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2368: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2384: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2400: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2416: 02 02 03 06 01 02 02 03 07 72 6d 61 6c 69 7a 65 .........rmalize
|
||||
| 2432: 5b 02 03 01 02 03 01 02 03 02 05 75 6d 62 65 72 [..........umber
|
||||
| 2448: 81 23 02 04 01 02 04 01 02 04 01 06 6f 66 66 73 .#..........offs
|
||||
| 2464: 65 74 5e 02 03 01 02 03 01 02 03 02 03 6d 69 74 et^..........mit
|
||||
| 2480: 81 2c 02 03 01 02 03 01 02 03 01 02 02 01 02 02 .,..............
|
||||
| 2496: 01 02 02 02 01 70 81 26 02 04 01 02 04 01 02 04 .....p.&........
|
||||
| 2512: 02 07 76 65 72 66 6c 6f 77 34 02 03 01 02 03 01 ..verflow4......
|
||||
| 2528: 02 03 01 04 70 61 67 65 1c 02 03 01 02 03 01 02 ....page........
|
||||
| 2544: 03 64 02 04 01 02 04 01 02 04 13 02 03 01 02 03 .d..............
|
||||
| 2560: 01 02 03 01 02 03 01 02 03 01 02 03 03 09 72 65 ..............re
|
||||
| 2576: 6e 74 68 65 73 69 73 49 02 04 01 02 04 01 02 04 nthesisI........
|
||||
| 2592: 03 05 74 74 65 72 6e 81 0e 02 04 01 02 04 01 02 ..ttern.........
|
||||
| 2608: 04 02 05 63 61 63 68 65 1f 02 03 01 02 03 01 02 ...cache........
|
||||
| 2624: 03 02 08 72 65 75 70 64 61 74 65 61 02 03 01 02 ...reupdatea....
|
||||
| 2640: 03 01 02 03 01 04 72 65 61 64 34 02 04 01 02 04 ......read4.....
|
||||
| 2656: 01 02 04 03 07 63 75 72 73 69 76 65 22 02 03 01 .....cursive....
|
||||
| 2672: 02 03 01 02 03 02 04 6f 77 69 64 01 02 03 01 02 .......owid.....
|
||||
| 2688: 03 01 02 03 02 04 74 72 65 65 64 02 03 01 02 03 ......treed.....
|
||||
| 2704: 01 02 03 04 02 69 6d 01 06 01 02 02 03 06 01 02 .....im.........
|
||||
| 2720: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2736: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2752: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2768: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2784: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2800: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2816: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2832: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2848: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2864: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2880: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2896: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2912: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 2928: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 2944: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 2960: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 2976: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
|
||||
| 2992: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 3008: 01 02 02 03 06 01 02 02 03 06 01 02 02 01 0a 73 ...............s
|
||||
| 3024: 63 61 6e 73 74 61 74 75 73 70 02 04 01 02 04 01 canstatusp......
|
||||
| 3040: 02 04 02 05 65 63 74 6f 72 25 02 03 01 02 03 01 ....ector%......
|
||||
| 3056: 02 03 03 04 6c 65 63 74 7f 02 04 01 02 04 01 02 ....lect........
|
||||
| 3072: 04 03 05 73 73 69 6f 6e 67 02 03 01 02 03 01 02 ...ssiong.......
|
||||
| 3088: 03 02 03 69 7a 65 10 02 04 01 02 04 01 02 04 04 ...ize..........
|
||||
| 3104: 02 04 01 02 04 01 02 04 01 02 04 01 02 04 01 02 ................
|
||||
| 3120: 04 01 02 04 01 02 04 01 02 04 07 02 04 01 02 04 ................
|
||||
| 3136: 01 02 04 5b 02 05 01 02 05 01 02 05 10 02 04 01 ...[............
|
||||
| 3152: 02 04 01 02 04 04 02 04 01 02 04 01 02 04 02 03 ................
|
||||
| 3168: 6f 66 74 76 02 03 01 02 03 01 02 03 02 02 71 6c oftv..........ql
|
||||
| 3184: 5e 02 04 01 02 04 01 02 04 13 02 04 01 02 04 01 ^...............
|
||||
| 3200: 02 04 28 02 03 01 02 03 01 02 03 02 04 74 61 74 ..(..........tat
|
||||
| 3216: 34 6a 02 03 01 02 03 01 02 03 03 02 6d 74 70 02 4j..........mtp.
|
||||
| 3232: 03 01 02 03 01 02 03 05 04 76 74 61 62 6d 02 03 .........vtabm..
|
||||
| 3248: 01 02 03 01 02 03 03 03 6f 72 65 81 35 02 03 01 ........ore.5...
|
||||
| 3264: 02 03 01 02 03 02 0a 79 6e 63 68 72 6f 6e 6f 75 .......ynchronou
|
||||
| 3280: 73 28 02 03 01 02 03 01 02 03 04 02 04 01 02 04 s(..............
|
||||
| 3296: 01 02 04 03 04 73 74 65 6d 81 32 02 02 01 02 02 .....stem.2.....
|
||||
| 3312: 01 02 02 01 04 74 65 6d 70 81 35 02 02 01 02 02 .....temp.5.....
|
||||
| 3328: 01 02 02 02 06 68 72 65 61 64 73 31 02 04 01 02 .....hreads1....
|
||||
| 3344: 04 01 02 04 76 02 04 01 02 04 01 02 04 08 03 61 ....v..........a
|
||||
| 3360: 66 65 81 38 02 02 01 02 02 01 02 02 02 06 72 69 fe.8..........ri
|
||||
| 3376: 67 67 65 72 81 20 02 03 01 02 03 01 02 03 08 01 gger. ..........
|
||||
| 3392: 73 22 02 04 01 02 04 01 02 04 01 07 75 6e 6b 6e s...........unkn
|
||||
| 3408: 6f 77 6e 73 02 03 01 02 03 01 02 03 01 08 76 61 owns..........va
|
||||
| 3424: 72 69 61 62 6c 65 81 23 02 03 01 02 03 01 02 03 riable.#........
|
||||
| 3440: 02 03 64 62 65 81 26 02 03 01 02 03 01 02 03 02 ..dbe.&.........
|
||||
| 3456: 03 69 65 77 01 02 05 01 02 05 01 02 05 02 03 74 .iew...........t
|
||||
| 3472: 61 62 37 02 04 01 02 04 01 02 04 04 02 04 01 02 ab7.............
|
||||
| 3488: 04 01 02 04 01 02 04 01 02 04 01 02 04 01 03 77 ...............w
|
||||
| 3504: 61 6c 2b 02 03 01 02 03 01 02 03 01 02 03 01 02 al+.............
|
||||
| 3520: 03 01 02 03 02 05 6f 72 6b 65 72 31 02 03 01 02 ......orker1....
|
||||
| 3536: 03 01 02 03 76 02 03 01 02 03 01 02 03 01 01 78 ....v..........x
|
||||
| 3552: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3568: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3584: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3600: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3616: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3632: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3648: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3664: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3680: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3696: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3712: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3728: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3744: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3760: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3776: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3792: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3808: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3824: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3840: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3856: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3872: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3888: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3904: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3920: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3936: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3952: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3968: 06 01 01 02 01 06 04 30 15 1e 0c 28 1b 0d 0c 15 .......0...(....
|
||||
| 3984: 0c 16 14 16 10 0c 17 0e 0e 0f 11 10 10 0e 10 11 ................
|
||||
| 4000: 18 11 82 3e 12 10 0f 10 11 10 0f 0f 10 11 0f 0f ...>............
|
||||
| 4016: 81 05 18 10 81 45 11 0d 13 0f 10 17 0c 0c 0e 18 .....E..........
|
||||
| 4032: 0c 12 10 0e 0d 0f 13 12 24 0f 17 0f 1a 0d 81 1c ........$.......
|
||||
| 4048: 11 0f 17 10 82 3e 12 11 11 18 0d 12 2a 14 11 10 .....>......*...
|
||||
| 4064: 13 0f 12 0f 0f 82 3a 15 10 0f 10 4d 0e 1f 0f 0d ......:....M....
|
||||
| 4080: 0f 0f 1e 10 10 1a 0f 12 0c 12 14 0f 0e 20 17 19 ............. ..
|
||||
| page 12 offset 45056
|
||||
| 0: 0d 00 00 00 01 0d f4 00 0d f4 00 00 00 00 00 00 ................
|
||||
| 3568: 00 00 00 00 84 04 84 80 80 80 80 02 04 00 88 0c ................
|
||||
| 3584: 00 07 02 00 01 01 02 56 06 01 01 02 01 06 01 01 .......V........
|
||||
| 3600: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3616: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3632: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3648: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3664: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3680: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3696: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3712: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3728: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3744: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3760: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3776: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3792: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3808: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3824: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3840: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3856: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3872: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3888: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3904: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3920: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3936: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3952: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3968: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3984: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 4000: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 4016: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 4032: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 4048: 52 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 R...............
|
||||
| 4064: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 4080: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| end c1a.txt.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 84.1 {
|
||||
SELECT * FROM t1('R*R*x') ORDER BY rowid DESC;
|
||||
} {1 {fts5: corruption found reading blob 137438953475 from table "t1"}}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -305,28 +305,6 @@ do_catchsql_test 6.2 {
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
|
||||
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, col);
|
||||
|
||||
INSERT INTO t1 VALUES('xx', 'xx');
|
||||
|
||||
CREATE TABLE x1(t);
|
||||
INSERT INTO x1 VALUES('xx');
|
||||
INSERT INTO x1 VALUES('xx');
|
||||
|
||||
SELECT term, col FROM v1;
|
||||
} {
|
||||
xx a xx b
|
||||
}
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
SELECT * FROM x1 WHERE 'a'=(SELECT col FROM v1 WHERE term=t)
|
||||
} {xx xx}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
+19
-16
@@ -13,11 +13,14 @@ Technical support is available in the forum:
|
||||
<https://sqlite.org/forum>
|
||||
|
||||
|
||||
> **FOREWARNING:** this subproject is very much in development and
|
||||
subject to any number of changes. Please do not rely on any
|
||||
information about its API until this disclaimer is removed. The JNI
|
||||
bindings released with version 3.43 are a "tech preview." Once
|
||||
finalized, strong backward compatibility guarantees will apply.
|
||||
> **FOREWARNING:** the JNI subproject is experimental and subject to
|
||||
any number of changes. This API is "feature-complete", with only a
|
||||
few difficult-to-reach corners of the C API not represented here,
|
||||
but it is not a supported deliverable of the project so does not
|
||||
have same backward compatibility guarantees which the C APIs
|
||||
do. That said: the [C-style API](#1to1ish) is especially resistent
|
||||
to compatibility breakage because it's designed to be as close to
|
||||
the C API as feasible.
|
||||
|
||||
Project goals/requirements:
|
||||
|
||||
@@ -162,11 +165,13 @@ or propagate exceptions and must return error information (if any) via
|
||||
result codes or `null`. The only cases where the C-style APIs may
|
||||
throw is through client-side misuse, e.g. passing in a null where it
|
||||
may cause a `NullPointerException`. The APIs clearly mark function
|
||||
parameters which should not be null, but does not generally actively
|
||||
defend itself against such misuse. Some C-style APIs explicitly accept
|
||||
`null` as a no-op for usability's sake, and some of the JNI APIs
|
||||
deliberately return an error code, instead of segfaulting, when passed
|
||||
a `null`.
|
||||
parameters which should not be null, and it internally uses the
|
||||
`SQLITE_API_ARMOR` mechanism to help product against such misuse. Some
|
||||
C-style APIs explicitly accept `null` as a no-op for usability's sake,
|
||||
and some of the JNI APIs deliberately return an error code, instead of
|
||||
segfaulting, when passed a `null`. There are no known cases where it
|
||||
will misuse memory if passed a `null` or out-of-range value from
|
||||
client code.
|
||||
|
||||
Client-defined callbacks _must never throw exceptions_ unless _very
|
||||
explicitly documented_ as being throw-safe. Exceptions are generally
|
||||
@@ -194,7 +199,8 @@ Some constructs, when modelled 1-to-1 from C to Java, are unduly
|
||||
clumsy to work with in Java because they try to shoehorn C's way of
|
||||
doing certain things into Java's wildly different ways. The following
|
||||
subsections cover those, starting with a verbose explanation and
|
||||
demonstration of where such changes are "really necessary"...
|
||||
demonstration of where such changes are "really necessary" for
|
||||
usability's sake...
|
||||
|
||||
### Custom Collations
|
||||
|
||||
@@ -286,12 +292,9 @@ binding. The Java API has only one core function-registration function:
|
||||
|
||||
```java
|
||||
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
|
||||
int encoding, SQLFunction func);
|
||||
int flags, SQLFunction func);
|
||||
```
|
||||
|
||||
> Design question: does the encoding argument serve any purpose in
|
||||
Java? That's as-yet undetermined. If not, it will be removed.
|
||||
|
||||
`SQLFunction` is not used directly, but is instead instantiated via
|
||||
one of its three subclasses:
|
||||
|
||||
@@ -313,4 +316,4 @@ in-flux nature of this API.
|
||||
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
|
||||
`sqlite3_update_hook()`, use interfaces similar to those shown above.
|
||||
Despite the changes in signature, the JNI layer makes every effort to
|
||||
provide the same semantics as the C API documentation suggests.
|
||||
provide the same semantics as the C API documentation describes.
|
||||
|
||||
+43
-51
@@ -133,11 +133,9 @@
|
||||
** Which sqlite3.c we're using needs to be configurable to enable
|
||||
** building against a custom copy, e.g. the SEE variant. We have to
|
||||
** include sqlite3.c, as opposed to sqlite3.h, in order to get access
|
||||
** to some internal details like SQLITE_MAX_... and friends. This
|
||||
** increases the rebuild time considerably but we need this in order
|
||||
** to access some internal functionality and keep the to-Java-exported
|
||||
** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C
|
||||
** build.
|
||||
** to some internal details like SQLITE_MAX_... and friends, and keep
|
||||
** those consistent with this build. This increases the rebuild time
|
||||
** considerably, however.
|
||||
*/
|
||||
#ifndef SQLITE_C
|
||||
# define SQLITE_C sqlite3.c
|
||||
@@ -335,7 +333,7 @@ struct S3JniNphOp {
|
||||
const char * const zMember /* Name of member property */;
|
||||
const char * const zTypeSig /* JNI type signature of zMember */;
|
||||
/*
|
||||
** klazz is a global ref to the class represented by pRef.
|
||||
** klazz is a global ref to the class represented by zName.
|
||||
**
|
||||
** According to:
|
||||
**
|
||||
@@ -999,19 +997,20 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){
|
||||
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
|
||||
** from client code.
|
||||
**
|
||||
** Returns err_code.
|
||||
** Returns err_code _unless_ err_code is 0 and sqlite3_set_errmsg()
|
||||
** fails with OOM, in which case it may return SQLITE_OOM or fail
|
||||
** fatally.
|
||||
**
|
||||
** This function predates sqlite3_set_errmsg(), which is why it has a
|
||||
** slightly different interface. Before that function was introduced,
|
||||
** this code used the SQLite-internal APIs to do this.
|
||||
*/
|
||||
static int s3jni_db_error(sqlite3* const db, int err_code,
|
||||
const char * const zMsg){
|
||||
static int s3jni_db_error(JNIEnv * env, sqlite3* const db,
|
||||
int err_code, const char * const zMsg){
|
||||
if( db!=0 ){
|
||||
if( 0==zMsg ){
|
||||
sqlite3Error(db, err_code);
|
||||
}else{
|
||||
const int nMsg = sqlite3Strlen30(zMsg);
|
||||
sqlite3_mutex_enter(sqlite3_db_mutex(db));
|
||||
sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
|
||||
sqlite3_mutex_leave(sqlite3_db_mutex(db));
|
||||
}
|
||||
int const rc = sqlite3_set_errmsg(db, err_code, zMsg);
|
||||
s3jni_oom_fatal(0==rc);
|
||||
if( rc && !err_code ) err_code=rc;
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
@@ -1235,11 +1234,11 @@ static int s3jni__db_exception(JNIEnv * const env, sqlite3 * const pDb,
|
||||
char * zMsg;
|
||||
S3JniExceptionClear;
|
||||
zMsg = s3jni_exception_error_msg(env, ex);
|
||||
s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg);
|
||||
s3jni_db_error(env, pDb, errCode, zMsg ? zMsg : zDfltMsg);
|
||||
sqlite3_free(zMsg);
|
||||
S3JniUnrefLocal(ex);
|
||||
}else if( zDfltMsg ){
|
||||
s3jni_db_error(pDb, errCode, zDfltMsg);
|
||||
s3jni_db_error(env, pDb, errCode, zDfltMsg);
|
||||
}
|
||||
return errCode;
|
||||
}
|
||||
@@ -1956,15 +1955,6 @@ static void S3JniUdf_finalizer(void * s){
|
||||
S3JniUdf_free(s3jni_env(), (S3JniUdf*)s, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Helper for processing args to UDF handlers with signature
|
||||
** (sqlite3_context*,int,sqlite3_value**).
|
||||
*/
|
||||
typedef struct {
|
||||
jobject jcx /* sqlite3_context */;
|
||||
jobjectArray jargv /* sqlite3_value[] */;
|
||||
} udf_jargs;
|
||||
|
||||
/*
|
||||
** Converts the given (cx, argc, argv) into arguments for the given
|
||||
** UDF, writing the result (Java wrappers for cx and argv) in the
|
||||
@@ -2006,7 +1996,7 @@ error_oom:
|
||||
/*
|
||||
** Requires that jCx and jArgv are sqlite3_context
|
||||
** resp. array-of-sqlite3_value values initialized by udf_args(). The
|
||||
** latter will be 0-and-NULL for UDF types with no arguments. This
|
||||
** (argc,argv) are (0,NULL) for UDF types with no arguments. This
|
||||
** function zeroes out the nativePointer member of jCx and each entry
|
||||
** in jArgv. This is a safety-net precaution to avoid undefined
|
||||
** behavior if a Java-side UDF holds a reference to its context or one
|
||||
@@ -2099,19 +2089,19 @@ static int udf_xFSI(sqlite3_context* const pCx, int argc,
|
||||
sqlite3_value** const argv, S3JniUdf * const s,
|
||||
jmethodID xMethodID, const char * const zFuncType){
|
||||
S3JniDeclLocal_env;
|
||||
udf_jargs args = {0,0};
|
||||
int rc = udf_args(env, pCx, argc, argv, &args.jcx, &args.jargv);
|
||||
|
||||
jobject jcx = 0 /* sqlite3_context */;
|
||||
jobjectArray jargv = 0 /* sqlite3_value[] */;
|
||||
int rc = udf_args(env, pCx, argc, argv, &jcx, &jargv);
|
||||
if( 0 == rc ){
|
||||
(*env)->CallVoidMethod(env, s->jObj, xMethodID, args.jcx, args.jargv);
|
||||
(*env)->CallVoidMethod(env, s->jObj, xMethodID, jcx, jargv);
|
||||
S3JniIfThrew{
|
||||
rc = udf_report_exception(env, 'F'==zFuncType[1]/*xFunc*/, pCx,
|
||||
s->zFuncName, zFuncType);
|
||||
}
|
||||
udf_unargs(env, args.jcx, argc, args.jargv);
|
||||
udf_unargs(env, jcx, argc, jargv);
|
||||
}
|
||||
S3JniUnrefLocal(args.jcx);
|
||||
S3JniUnrefLocal(args.jargv);
|
||||
S3JniUnrefLocal(jcx);
|
||||
S3JniUnrefLocal(jargv);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3300,7 +3290,7 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
|
||||
S3JniDb_mutex_enter;
|
||||
ps = S3JniDb_from_jlong(jpDb);
|
||||
if( !ps ){
|
||||
s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
|
||||
s3jni_db_error(env, ps->pDb, SQLITE_MISUSE, 0);
|
||||
S3JniDb_mutex_leave;
|
||||
return 0;
|
||||
}
|
||||
@@ -3320,13 +3310,14 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
|
||||
else sqlite3_rollback_hook(ps->pDb, 0, 0);
|
||||
}else{
|
||||
jclass const klazz = (*env)->GetObjectClass(env, jHook);
|
||||
jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call",
|
||||
isCommit ? "()I" : "()V");
|
||||
jmethodID const xCallback =
|
||||
(*env)->GetMethodID(env, klazz, "call",
|
||||
isCommit ? "()I" : "()V");
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew {
|
||||
S3JniExceptionReport;
|
||||
S3JniExceptionClear;
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching call() method in"
|
||||
"hook object.");
|
||||
}else{
|
||||
@@ -3606,7 +3597,7 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(),
|
||||
(*env)->GetMethodID(env, klazz, "call", "([B[B)I");
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew{
|
||||
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Could not get call() method from "
|
||||
"CollationCallback object.");
|
||||
}else{
|
||||
@@ -3645,15 +3636,15 @@ S3JniApi(sqlite3_create_function() sqlite3_create_function_v2()
|
||||
|
||||
if( !pDb || !jFuncName ){
|
||||
return SQLITE_MISUSE;
|
||||
}else if( !encodingTypeIsValid(eTextRep) ){
|
||||
return s3jni_db_error(pDb, SQLITE_FORMAT,
|
||||
}else if( !encodingTypeIsValid(eTextRep & 0x0f) ){
|
||||
return s3jni_db_error(env, pDb, SQLITE_FORMAT,
|
||||
"Invalid function encoding option.");
|
||||
}
|
||||
s = S3JniUdf_alloc(env, jFunctor);
|
||||
if( !s ) return SQLITE_NOMEM;
|
||||
|
||||
if( UDF_UNKNOWN_TYPE==s->type ){
|
||||
rc = s3jni_db_error(pDb, SQLITE_MISUSE,
|
||||
rc = s3jni_db_error(env, pDb, SQLITE_MISUSE,
|
||||
"Cannot unambiguously determine function type.");
|
||||
S3JniUdf_free(env, s, 1);
|
||||
goto error_cleanup;
|
||||
@@ -4012,7 +4003,7 @@ S3JniApi(sqlite3_jni_db_error(), jint, 1jni_1db_1error)(
|
||||
zStr = jStr
|
||||
? s3jni_jstring_to_utf8( jStr, 0)
|
||||
: NULL;
|
||||
rc = s3jni_db_error( ps->pDb, (int)jRc, zStr );
|
||||
rc = s3jni_db_error(env, ps->pDb, (int)jRc, zStr );
|
||||
sqlite3_free(zStr);
|
||||
}
|
||||
return rc;
|
||||
@@ -4321,7 +4312,7 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
|
||||
jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0;
|
||||
S3JniIfThrew {
|
||||
S3JniExceptionClear;
|
||||
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
|
||||
s3jni_db_error(env, ps->pDb, SQLITE_NOMEM, 0);
|
||||
}else{
|
||||
assert( hook.jObj );
|
||||
assert( hook.midCallback );
|
||||
@@ -4423,7 +4414,7 @@ static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jlong jpDb, jobject
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew {
|
||||
S3JniExceptionClear;
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching callback on "
|
||||
"(pre)update hook object.");
|
||||
}else{
|
||||
@@ -4532,7 +4523,7 @@ S3JniApi(sqlite3_progress_handler(),void,1progress_1handler)(
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew {
|
||||
S3JniExceptionClear;
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching xCallback() on "
|
||||
"ProgressHandler object.");
|
||||
}else{
|
||||
@@ -4906,8 +4897,9 @@ S3JniApi(sqlite3_set_authorizer(),jint,1set_1authorizer)(
|
||||
")I");
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew {
|
||||
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Error setting up Java parts of authorizer hook.");
|
||||
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Error setting up Java parts of "
|
||||
"authorizer hook.");
|
||||
}else{
|
||||
rc = sqlite3_set_authorizer(ps->pDb, s3jni_xAuth, ps);
|
||||
}
|
||||
@@ -5191,7 +5183,7 @@ S3JniApi(sqlite3_trace_v2(),jint,1trace_1v2)(
|
||||
S3JniUnrefLocal(klazz);
|
||||
S3JniIfThrew {
|
||||
S3JniExceptionClear;
|
||||
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching call() on "
|
||||
"TracerCallback object.");
|
||||
}else{
|
||||
|
||||
@@ -245,8 +245,10 @@ extern "C" {
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL 13L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 13L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8
|
||||
#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L
|
||||
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE
|
||||
|
||||
@@ -115,8 +115,9 @@ public final class CApi {
|
||||
JNIEnv is not cached, else returns true, but this information is
|
||||
primarily for testing of the JNI bindings and is not information
|
||||
which client-level code can use to make any informed
|
||||
decisions. Its return type and semantics are not considered
|
||||
stable and may change at any time.
|
||||
decisions. The semantics of its return type and value are not
|
||||
considered stable and may change at any time. i.e. act as if it
|
||||
returns null.
|
||||
*/
|
||||
public static native boolean sqlite3_java_uncache_thread();
|
||||
|
||||
@@ -2585,7 +2586,8 @@ public final class CApi {
|
||||
public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
|
||||
public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
|
||||
public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12;
|
||||
public static final int SQLITE_DBSTATUS_MAX = 12;
|
||||
public static final int SQLITE_DBSTATUS_TEMPBUF_SPILL = 13;
|
||||
public static final int SQLITE_DBSTATUS_MAX = 13;
|
||||
|
||||
// encodings
|
||||
public static final int SQLITE_UTF8 = 1;
|
||||
|
||||
@@ -815,7 +815,9 @@ public class Tester1 implements Runnable {
|
||||
};
|
||||
|
||||
// Register and use the function...
|
||||
int rc = sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func);
|
||||
int rc = sqlite3_create_function(db, "myfunc", -1,
|
||||
SQLITE_UTF8 | SQLITE_INNOCUOUS,
|
||||
func);
|
||||
affirm(0 == rc);
|
||||
affirm(0 == xFuncAccum.value);
|
||||
final sqlite3_stmt stmt = prepare(db, "SELECT myfunc(1,2,3)");
|
||||
|
||||
@@ -171,6 +171,7 @@ public final class Sqlite implements AutoCloseable {
|
||||
public static final int DBSTATUS_DEFERRED_FKS = CApi.SQLITE_DBSTATUS_DEFERRED_FKS;
|
||||
public static final int DBSTATUS_CACHE_USED_SHARED = CApi.SQLITE_DBSTATUS_CACHE_USED_SHARED;
|
||||
public static final int DBSTATUS_CACHE_SPILL = CApi.SQLITE_DBSTATUS_CACHE_SPILL;
|
||||
public static final int DBSTATUS_TEMPBUF_SPILL = CApi.SQLITE_DBSTATUS_TEMPBUF_SPILL;
|
||||
|
||||
// Limits
|
||||
public static final int LIMIT_LENGTH = CApi.SQLITE_LIMIT_LENGTH;
|
||||
|
||||
@@ -1122,11 +1122,3 @@ int sqlite3_fileio_init(
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
|
||||
/* To allow a standalone DLL, make test_windirent.c use the same
|
||||
* redefined SQLite API calls as the above extension code does.
|
||||
* Just pull in this .c to accomplish this. As a beneficial side
|
||||
* effect, this extension becomes a single translation unit. */
|
||||
# include "test_windirent.c"
|
||||
#endif
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
_fiddle_db_arg
|
||||
_fiddle_db_filename
|
||||
_fiddle_exec
|
||||
_fiddle_experiment
|
||||
_fiddle_interrupt
|
||||
_fiddle_main
|
||||
_fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
+197
-142
@@ -1,5 +1,6 @@
|
||||
#######################################################################
|
||||
# This GNU makefile creates the canonical sqlite3 WASM builds.
|
||||
#
|
||||
# This GNU makefile creates the canonical sqlite3 WASM builds. Plus some
|
||||
# others.
|
||||
#
|
||||
# This build assumes a Linux platform and is not intended for
|
||||
# general-purpose client-level use, except for creating builds with
|
||||
@@ -10,28 +11,33 @@
|
||||
#
|
||||
# default, all = build in dev mode
|
||||
#
|
||||
# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level indicated
|
||||
# by the target name. Rebuild is necessary for all components to get
|
||||
# the desired optimization level.
|
||||
# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level
|
||||
# indicated by the target name. A clean rebuild is necessary for
|
||||
# all components to get the desired optimization level.
|
||||
#
|
||||
# dist = create end user deliverables. Add dist.build=oX to build
|
||||
# with a specific optimization level, where oX is one of the
|
||||
# above-listed o? or qo? target names.
|
||||
# with a specific optimization level, where oX is one of the
|
||||
# above-listed o? target names.
|
||||
#
|
||||
# snapshot = like dist, but uses a zip file name which clearly
|
||||
# marks it as a prerelease/snapshot build.
|
||||
# marks it as a prerelease/snapshot build.
|
||||
#
|
||||
# clean = clean up
|
||||
#
|
||||
# Required tools beyond those needed for the canonical builds:
|
||||
#
|
||||
# - Emscripten SDK: https://emscripten.org/docs/getting_started/downloads.html
|
||||
#
|
||||
# - The bash shell
|
||||
#
|
||||
# - GNU make, GNU sed, GNU awk, GNU grep (all in the $PATH and without
|
||||
# a "g" prefix like they have on some non-GNU systems)
|
||||
# - wasm-strip for release builds: https://github.com/WebAssembly/wabt
|
||||
#
|
||||
# - wasm-strip for release builds: https://github.com/WebAssembly/wabt.
|
||||
# It will build without this but the .wasm files will be huge.
|
||||
#
|
||||
# - InfoZip for 'dist' zip file
|
||||
########################################################################
|
||||
#
|
||||
default: all
|
||||
MAKEFILE = $(lastword $(MAKEFILE_LIST))
|
||||
CLEAN_FILES =
|
||||
@@ -213,9 +219,8 @@ b.cp = $(call b.mkdir@); \
|
||||
# $4 = optional $(bin.c-pp) flags
|
||||
define b.c-pp.shcmd
|
||||
$(call b.mkdir@); \
|
||||
$(call b.echo,$(1),$(emo.disk)$(emo.lock) $(bin.c-pp) $(4) $(if $(loud.if),$(2))); \
|
||||
rm -f $(3); \
|
||||
$(bin.c-pp) -o $(3) $(4) $(2) || exit; \
|
||||
$(call b.echo,$(1),$(emo.disk)$(emo.lock)[$(3)] $(4)); \
|
||||
rm -f $(3); $(bin.c-pp) -o $(3) $(4) $(2) || exit; \
|
||||
chmod -w $(3)
|
||||
endef
|
||||
|
||||
@@ -227,10 +232,38 @@ endef
|
||||
# Args: as for $(b.c-pp.shcmd).
|
||||
define b.c-pp.target
|
||||
$(3): $$(MAKEFILE_LIST) $$(bin.c-pp) $(2)
|
||||
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4) $(b.c-pp.target.flags))
|
||||
@$$(call b.mkdir@)
|
||||
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4) $$(b.c-pp.target.flags))
|
||||
CLEAN_FILES += $(3)
|
||||
endef
|
||||
|
||||
|
||||
#
|
||||
# The various -D... values used by *.c-pp.js include:
|
||||
#
|
||||
# -Dtarget:es6-module: for all ESM module builds
|
||||
#
|
||||
# -Dtarget:node: for node.js builds
|
||||
#
|
||||
# -Dtarget:es6-module -Dtarget:es6-bundler-friendly: intended for
|
||||
# "bundler-friendly" ESM module build. These have some restrictions
|
||||
# on how URL() objects are constructed in some contexts: URLs which
|
||||
# refer to files which are part of this project must be referenced
|
||||
# as string literals so that bundlers' static-analysis tools can
|
||||
# find those files and include them in their bundles.
|
||||
#
|
||||
# -Dtarget:es6-module -Dtarget:node: is intended for use by node.js
|
||||
# for node.js, as opposed to by node.js on behalf of a
|
||||
# browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to
|
||||
# ambiguity and confusion on node's part, as it's unable to
|
||||
# reliably determine whether the target is a browser or node.
|
||||
#
|
||||
# To repeat: all node.js builds are 100% untested and unsupported.
|
||||
#
|
||||
# Most c-pp.D.X are set via $(bin.mkwb) and X is a build name.
|
||||
# Those make rules reference c-pp.D.64bit, so it should be defined in
|
||||
# advance.
|
||||
#
|
||||
c-pp.D.64bit = -Dbits64
|
||||
|
||||
#
|
||||
@@ -248,11 +281,21 @@ c-pp.D.64bit = -Dbits64
|
||||
#
|
||||
# This is intended to be used in makefile targets which generate an
|
||||
# Emscripten module and where $@ is the module's .js/.mjs file.
|
||||
#
|
||||
# This is inherently fragile and has been broken by Emscripten updates
|
||||
# before.
|
||||
#
|
||||
ifeq (1,1)
|
||||
define b.strip-js-emcc-bindings
|
||||
echo "$(1) $(emo.garbage) Stripping export wrappers."; \
|
||||
sed -i -e '/var _sqlite3.*makeInvalidEarly.*;/d' \
|
||||
-e '/assert.*sqlite3.*missing.*;/d' \
|
||||
-e '/_sqlite.*createExportWrapper.*;/d' $@
|
||||
endef
|
||||
else
|
||||
b.strip-js-emcc-bindings = \
|
||||
sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]*=.*createExportWrapper/d' \
|
||||
-e '/^var \(_sqlite3\|_fiddle\)[^=]*=.*makeInvalidEarlyAccess/d' $@ || exit; \
|
||||
echo '$(1) $(emo.garbage) (Probably) /createExportWrapper()/d and /makeInvalidEarlyAccess()/d'
|
||||
|
||||
echo '$(1) $(emo.bug) (disabled because it breaks emsdk 4.0.16+)'
|
||||
endif
|
||||
|
||||
#
|
||||
# Set up sqlite3.c and sqlite3.h...
|
||||
@@ -271,6 +314,7 @@ b.strip-js-emcc-bindings = \
|
||||
# $(sqlite3.canonical.c) must point to the sqlite3.c in
|
||||
# the sqlite3 canonical source tree, as that source file
|
||||
# is required for certain utility and test code.
|
||||
#
|
||||
sqlite3.canonical.c = $(dir.top)/sqlite3.c
|
||||
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
|
||||
sqlite3.h = $(dir $(sqlite3.c))/sqlite3.h
|
||||
@@ -280,24 +324,26 @@ sqlite3.h = $(dir $(sqlite3.c))/sqlite3.h
|
||||
# embedding in the JS files and in building the distribution zip file.
|
||||
# It must NOT be in $(dir.tmp) because we need it to survive the
|
||||
# cleanup process for the dist build to work properly.
|
||||
#
|
||||
bin.version-info = ./version-info
|
||||
$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
|
||||
$(CC) -o $@ -I$(dir $(sqlite3.h)) $(dir.tool)/version-info.c
|
||||
t-version-info: $(bin.version-info)
|
||||
DISTCLEAN_FILES += $(bin.version-info)
|
||||
|
||||
#
|
||||
# bin.stripcomments is used for stripping C/C++-style comments from JS
|
||||
# files. The JS files contain large chunks of documentation which we
|
||||
# don't need for all builds. That app's -k flag is of particular
|
||||
# importance here, as it allows us to retain the opening comment
|
||||
# block(s), which contain the license header and version info.
|
||||
#
|
||||
bin.stripccomments = $(dir.tool)/stripccomments
|
||||
$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
|
||||
$(CC) -o $@ $<
|
||||
t-stripccomments: $(bin.stripccomments)
|
||||
DISTCLEAN_FILES += $(bin.stripccomments)
|
||||
|
||||
|
||||
ifeq (1,$(MAKING_CLEAN))
|
||||
SQLITE_C_IS_SEE = 0
|
||||
else
|
||||
@@ -325,7 +371,7 @@ endif
|
||||
# undefine barebones # relatively new gmake feature, not ubiquitous
|
||||
|
||||
#
|
||||
# It's important that sqlite3.h be built to completion before any
|
||||
# It's important that sqlite3.[ch] be built to completion before any
|
||||
# other parts of the build run, thus we use .NOTPARALLEL to disable
|
||||
# parallel build of that file and its dependants. However, that makes
|
||||
# the whole build non-parallelizable because everything has a dep on
|
||||
@@ -342,8 +388,10 @@ $(sqlite3.h):
|
||||
# $(MAKE) -C $(dir.top) sqlite3.c
|
||||
$(sqlite3.c): $(sqlite3.h)
|
||||
|
||||
#
|
||||
# Common options for building sqlite3-wasm.c and speedtest1.c.
|
||||
# Explicit ENABLEs...
|
||||
#
|
||||
SQLITE_OPT.common = \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_TEMP_STORE=2 \
|
||||
@@ -360,11 +408,15 @@ SQLITE_OPT.common = \
|
||||
# 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 \
|
||||
@@ -421,13 +473,14 @@ else
|
||||
# -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:
|
||||
#
|
||||
@@ -436,10 +489,9 @@ endif
|
||||
# SQLITE_OMIT_DEPRECATED
|
||||
# SQLITE_OMIT_UTF16
|
||||
# SQLITE_OMIT_SHARED_CACHE
|
||||
########################################################################
|
||||
#
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Adding custom C code via sqlite3_wasm_extra_init.c:
|
||||
#
|
||||
# If the canonical build process finds the file
|
||||
@@ -460,7 +512,7 @@ endif
|
||||
# make sqlite3_wasm_extra_init.c=my_custom_stuff.c
|
||||
#
|
||||
# See example_extra_init.c for an example implementation.
|
||||
########################################################################
|
||||
#
|
||||
sqlite3_wasm_extra_init.c ?= $(wildcard sqlite3_wasm_extra_init.c)
|
||||
cflags.wasm_extra_init =
|
||||
ifneq (,$(sqlite3_wasm_extra_init.c))
|
||||
@@ -481,7 +533,7 @@ endif
|
||||
#
|
||||
WASM_CUSTOM_INSTANTIATE = 1
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# $(bin.c-pp): a minimal text file preprocessor. Like C's but much
|
||||
# less so.
|
||||
#
|
||||
@@ -512,6 +564,7 @@ WASM_CUSTOM_INSTANTIATE = 1
|
||||
#
|
||||
# -D... flags which should be included in all invocations should be
|
||||
# appended to $(b.c-pp.target.flags).
|
||||
#
|
||||
bin.c-pp = ./c-pp-lite
|
||||
$(bin.c-pp): c-pp-lite.c $(sqlite3.c) $(MAKEFILE)
|
||||
$(CC) -O0 -o $@ c-pp-lite.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \
|
||||
@@ -523,7 +576,12 @@ b.c-pp.target.flags ?=
|
||||
ifeq (1,$(SQLITE_C_IS_SEE))
|
||||
b.c-pp.target.flags += -Denable-see
|
||||
endif
|
||||
api.oo1 ?= 1
|
||||
ifeq (0,$(api.oo1))
|
||||
b.c-pp.target.flags += -Domit-oo1
|
||||
endif
|
||||
|
||||
#
|
||||
# cflags.common = C compiler flags for all builds
|
||||
cflags.common = -I. -I$(dir $(sqlite3.c)) -std=c99 -fPIC
|
||||
# emcc.WASM_BIGINT = 1 for BigInt (C int64) support, else 0. The API
|
||||
@@ -531,13 +589,14 @@ cflags.common = -I. -I$(dir $(sqlite3.c)) -std=c99 -fPIC
|
||||
# _are not tested_ on any regular basis.
|
||||
emcc.WASM_BIGINT ?= 1
|
||||
emcc.MEMORY64 ?= 0
|
||||
########################################################################
|
||||
#
|
||||
# https://emscripten.org/docs/tools_reference/settings_reference.html#memory64
|
||||
#
|
||||
# 64-bit build requires wasm-strip 1.0.36 (maybe 1.0.35, but not
|
||||
# 1.0.34) or will fail to strip with "tables may not be 64-bit".
|
||||
########################################################################
|
||||
#
|
||||
|
||||
#
|
||||
# emcc_opt = optimization-related flags. These are primarily used by
|
||||
# the various oX targets. build times for -O levels higher than 0 are
|
||||
# painful at dev-time.
|
||||
@@ -549,14 +608,17 @@ emcc.MEMORY64 ?= 0
|
||||
# -O2 (which consistently creates the fastest-running deliverables).
|
||||
# Build time suffers greatly compared to -O0, which is why -O0 is the
|
||||
# default.
|
||||
#
|
||||
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
|
||||
# effect, so emcc_opt+=-g3 doesn't work. So...
|
||||
#
|
||||
emcc_opt_full = $(emcc_opt) -g3
|
||||
# ^^^ ALWAYS use -g3. See below for why.
|
||||
#
|
||||
@@ -583,26 +645,26 @@ emcc_opt_full = $(emcc_opt) -g3
|
||||
# Much practice has demonstrated that -O2 consistently gives the best
|
||||
# runtime speeds, but not by a large enough factor to rule out use of
|
||||
# -Oz when smaller deliverable size is a priority.
|
||||
########################################################################
|
||||
#
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# EXPORTED_FUNCTIONS.* = files for use with Emscripten's
|
||||
# -sEXPORTED_FUNCTION flag.
|
||||
EXPORTED_FUNCTIONS.api.core = $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core
|
||||
EXPORTED_FUNCTIONS.api.in = $(EXPORTED_FUNCTIONS.api.core)
|
||||
ifeq (1,$(SQLITE_C_IS_SEE))
|
||||
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
|
||||
endif
|
||||
ifeq (0,$(wasm-bare-bones))
|
||||
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
|
||||
endif
|
||||
#
|
||||
EXPORTED_FUNCTIONS.api.in = $(dir.api)/EXPORTED_FUNCTIONS.c-pp
|
||||
EXPORTED_FUNCTIONS.api = $(dir.tmp)/EXPORTED_FUNCTIONS.api
|
||||
$(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE)
|
||||
@$(call b.mkdir@)
|
||||
cat $(EXPORTED_FUNCTIONS.api.in) > $@
|
||||
EXPORTED_FUNCTIONS.c-pp.flags =
|
||||
ifeq (1,$(wasm-bare-bones))
|
||||
EXPORTED_FUNCTIONS.c-pp.flags += -Dbare-bones
|
||||
endif
|
||||
$(eval $(call b.c-pp.target,filter,\
|
||||
$(EXPORTED_FUNCTIONS.api.in),\
|
||||
$(EXPORTED_FUNCTIONS.api),\
|
||||
$(EXPORTED_FUNCTIONS.c-pp.flags)))
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# emcc flags for .c/.o/.wasm/.js.
|
||||
#
|
||||
emcc.flags =
|
||||
ifeq (1,$(emcc.verbose))
|
||||
emcc.flags += -v
|
||||
@@ -690,9 +752,9 @@ ifeq (,$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY)))
|
||||
$(error emcc.INITIAL_MEMORY must be one of: 4, 8, 16, 32, 64, 96, 128 (megabytes))
|
||||
endif
|
||||
emcc.jsflags += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
|
||||
#
|
||||
# /INITIAL_MEMORY
|
||||
########################################################################
|
||||
#emcc.jsflags += -sMEMORY64=$(emcc.MEMORY64)
|
||||
#
|
||||
|
||||
emcc.jsflags += $(emcc.environment)
|
||||
emcc.jsflags += -sSTACK_SIZE=512KB
|
||||
@@ -701,7 +763,8 @@ emcc.jsflags += -sSTACK_SIZE=512KB
|
||||
# VFS, which requires twice that for its xRead() and xWrite() methods.
|
||||
# 2023-03: those methods have since been adapted to use a malloc()'d
|
||||
# buffer.
|
||||
########################################################################
|
||||
|
||||
#
|
||||
# $(sqlite3.js.init-func) is the name Emscripten assigns our exported
|
||||
# module init/load function. This symbol name is hard-coded in
|
||||
# $(extern-post-js.js) as well as in numerous docs.
|
||||
@@ -741,7 +804,7 @@ emcc.jsflags += -sLLD_REPORT_UNDEFINED
|
||||
#emcc.jsflags += --experimental-pic --unresolved-symbols=ingore-all --import-undefined
|
||||
#emcc.jsflags += --unresolved-symbols=ignore-all
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# -sSINGLE_FILE:
|
||||
# https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
|
||||
#
|
||||
@@ -750,12 +813,7 @@ emcc.jsflags += -sLLD_REPORT_UNDEFINED
|
||||
# cannot wasm-strip the binary before it gets encoded into the JS
|
||||
# file. The result is that the generated JS file is, because of the
|
||||
# -g3 debugging info, _huge_.
|
||||
########################################################################
|
||||
|
||||
|
||||
sqlite3.wasm = $(dir.dout)/sqlite3.wasm
|
||||
sqlite3-wasm.c = $(dir.api)/sqlite3-wasm.c
|
||||
sqlite3-wasm.c.in = $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
||||
#
|
||||
|
||||
#
|
||||
# b.call.patch-export-default is used by mkwasmbuilds.c and the
|
||||
@@ -798,51 +856,6 @@ if [ x1 = x$(1) ]; then \
|
||||
fi
|
||||
endef
|
||||
|
||||
#
|
||||
# The various -D... values used by *.c-pp.js include:
|
||||
#
|
||||
# -Dtarget:es6-module: for all ESM module builds
|
||||
#
|
||||
# -Dtarget:node: for node.js builds
|
||||
#
|
||||
# -Dtarget:es6-module -Dtarget:es6-bundler-friendly: intended for
|
||||
# "bundler-friendly" ESM module build. These have some restrictions
|
||||
# on how URL() objects are constructed in some contexts: URLs which
|
||||
# refer to files which are part of this project must be referenced
|
||||
# as string literals so that bundlers' static-analysis tools can
|
||||
# find those files and include them in their bundles.
|
||||
#
|
||||
# -Dtarget:es6-module -Dtarget:node: is intended for use by node.js
|
||||
# for node.js, as opposed to by node.js on behalf of a
|
||||
# browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to
|
||||
# ambiguity and confusion on node's part, as it's unable to
|
||||
# reliably determine whether the target is a browser or node.
|
||||
#
|
||||
# To repeat: all node.js builds are 100% untested and unsupported.
|
||||
#
|
||||
########################################################################
|
||||
|
||||
#
|
||||
# Inputs/outputs for the sqlite3-api.js family.
|
||||
#
|
||||
# sqlite3-api.jses = the list of JS files which make up
|
||||
# sqlite3-api.js, in the order they need to be assembled.
|
||||
sqlite3-api.jses = $(sqlite3-license-version.js)
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js
|
||||
sqlite3-api.jses += $(dir.common)/whwasmutil.js
|
||||
sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js
|
||||
sqlite3-api.jses += $(sqlite3-api-build-version.js)
|
||||
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-vfs-helper.c-pp.js
|
||||
ifeq (0,$(wasm-bare-bones))
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
|
||||
endif
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||
|
||||
#
|
||||
# $(sqlite3-license-version.js) contains the license header and
|
||||
# in-comment build version info.
|
||||
@@ -852,9 +865,8 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||
#
|
||||
sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js
|
||||
$(sqlite3-license-version.js): $(bin.version-info) \
|
||||
$(dir.api)/sqlite3-license-version-header.js
|
||||
@echo '$(logtag.@) $(emo.disk)'; { \
|
||||
$(call b.mkdir@); \
|
||||
$(dir.api)/sqlite3-license-version-header.js $(MAKEFILE)
|
||||
@$(call b.mkdir@); echo '$(logtag.@) $(emo.disk)'; { \
|
||||
cat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \
|
||||
echo '/*'; \
|
||||
echo '** This code was built from sqlite3 version...'; \
|
||||
@@ -862,7 +874,7 @@ $(sqlite3-license-version.js): $(bin.version-info) \
|
||||
awk '/define SQLITE_VERSION/{$$1=""; print "**" $$0}' $(sqlite3.h); \
|
||||
awk '/define SQLITE_SOURCE_ID/{$$1=""; print "**" $$0}' $(sqlite3.h); \
|
||||
echo '**'; echo '** Emscripten SDK: $(emcc.version)'; \
|
||||
echo '**'; \
|
||||
echo '**'; echo '** Preprocessed by:'; echo '** @c-pp::ARGV@'; \
|
||||
echo '*/'; \
|
||||
} > $@
|
||||
|
||||
@@ -881,6 +893,33 @@ $(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE)
|
||||
echo '});'; \
|
||||
} > $@
|
||||
|
||||
#
|
||||
# Inputs/outputs for the sqlite3-api.js family.
|
||||
#
|
||||
# sqlite3-api.jses = the list of JS files which make up
|
||||
# sqlite3-api.js, in the order they need to be assembled.
|
||||
sqlite3-api.jses = $(sqlite3-license-version.js)
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js
|
||||
sqlite3-api.jses += $(sqlite3-api-build-version.js)
|
||||
sqlite3-api.jses += $(dir.common)/whwasmutil.js
|
||||
sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js
|
||||
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-vfs-helper.c-pp.js
|
||||
ifeq (0,$(wasm-bare-bones))
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
|
||||
endif
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
|
||||
|
||||
# Parallel builds can fail if $(sqlite3-license-version.js) is not
|
||||
# created early enough, so make all files in $(sqlite-api.jses) except
|
||||
# for $(sqlite3-license-version.js) depend on
|
||||
# $(sqlite3-license-version.js).
|
||||
deps.jses = $(filter-out $(sqlite3-license-version.js),$(sqlite3-api.jses))
|
||||
$(deps.jses): $(sqlite3-license-version.js)
|
||||
|
||||
#
|
||||
# extern-post-js* and extern-pre-js* are files for use with
|
||||
# Emscripten's --extern-pre-js and --extern-post-js flags.
|
||||
@@ -918,7 +957,7 @@ $(post-js.in.js): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE)
|
||||
done > $@
|
||||
|
||||
#
|
||||
# speedtest1 decls needed before the $(bin.mkws)-generated makefile
|
||||
# speedtest1 decls needed before the $(bin.mkwb)-generated makefile
|
||||
# is included.
|
||||
#
|
||||
bin.speedtest1 = ../../speedtest1
|
||||
@@ -958,9 +997,10 @@ endif
|
||||
########################################################################
|
||||
|
||||
EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
|
||||
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE_LIST)
|
||||
@$(b.mkdir@)
|
||||
@sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
|
||||
$(EXPORTED_FUNCTIONS.fiddle): $(EXPORTED_FUNCTIONS.api.in) $(MAKEFILE_LIST)
|
||||
@$(call b.mkdir@)
|
||||
@$(call b.c-pp.shcmd,filter,$(EXPORTED_FUNCTIONS.api.in),\
|
||||
$@,$(EXPORTED_FUNCTIONS.c-pp.flags) -Dfiddle)
|
||||
@echo $(logtag.@) $(emo.disk)
|
||||
|
||||
emcc.flags.fiddle = \
|
||||
@@ -993,7 +1033,7 @@ clean-fiddle:
|
||||
$(dir.fiddle)/*.wasm \
|
||||
$(dir.fiddle)/sqlite3-opfs-*.js \
|
||||
$(dir.fiddle)/*.gz \
|
||||
EXPORTED_FUNCTIONS.fiddle
|
||||
$(EXPORTED_FUNCTIONS.fiddle)
|
||||
rm -fr $(dir.fiddle-debug)
|
||||
|
||||
emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
|
||||
@@ -1001,11 +1041,6 @@ emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
|
||||
-DSQLITE_ENABLE_SELECTTRACE \
|
||||
-DSQLITE_ENABLE_WHERETRACE
|
||||
|
||||
fiddle.EXPORTED_FUNCTIONS.in = \
|
||||
EXPORTED_FUNCTIONS.fiddle.in \
|
||||
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
|
||||
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
|
||||
|
||||
fiddle.c.in = $(dir.top)/shell.c $(sqlite3-wasm.c)
|
||||
|
||||
#
|
||||
@@ -1028,6 +1063,14 @@ cflags.wasmfs = -DSQLITE_ENABLE_WASMFS
|
||||
# end wasmfs (the rest is in mkwasmbuilds.c)
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
sqlite3-wasm.c = $(dir.api)/sqlite3-wasm.c
|
||||
# List of input files for compiling $(sqlite3-wasm.c). That file
|
||||
# #include's sqlite3.c directly, so it's implicitly includes here.
|
||||
sqlite3-wasm.c.in = $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
||||
|
||||
#
|
||||
# $(bin.mkwb) is used for generating much of the makefile code for the
|
||||
# various wasm builds. It used to be generated in this makefile via a
|
||||
@@ -1083,10 +1126,10 @@ sqlite3.ext.js =
|
||||
define gen-worker1
|
||||
# $1 = X.ext part of sqlite3-worker1X.ext
|
||||
# $2 = $(c-pp.D.NAME)
|
||||
$(call b.c-pp.target,filter,$(dir.api)/sqlite3-worker1.c-pp.js,\
|
||||
$(dir.dout)/sqlite3-worker1$(1),$(2))
|
||||
sqlite3.ext.js += $(dir.dout)/sqlite3-worker1$(1)
|
||||
all: $(dir.dout)/sqlite3-worker1$(1)
|
||||
$(call b.c-pp.target,filter,$$(dir.api)/sqlite3-worker1.c-pp.js,\
|
||||
$$(dir.dout)/sqlite3-worker1$(1),$(2))
|
||||
sqlite3.ext.js += $$(dir.dout)/sqlite3-worker1$(1)
|
||||
all: $$(dir.dout)/sqlite3-worker1$(1)
|
||||
endef
|
||||
|
||||
$(eval $(call gen-worker1,.js,$(c-pp.D.vanilla)))
|
||||
@@ -1100,10 +1143,10 @@ $(eval $(call gen-worker1,-bundler-friendly.mjs,$(c-pp.D.bundler)))
|
||||
define gen-promiser
|
||||
# $1 = X.ext part of sqlite3-worker1-promiserX.ext
|
||||
# $2 = $(c-pp.D.NAME)
|
||||
$(call b.c-pp.target,filter,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\
|
||||
$(dir.dout)/sqlite3-worker1-promiser$(1),$(2))
|
||||
sqlite3.ext.js += $(dir.dout)/sqlite3-worker1-promiser$(1)
|
||||
all: $(dir.dout)/sqlite3-worker1-promiser$(1)
|
||||
$(call b.c-pp.target,filter,$$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\
|
||||
$$(dir.dout)/sqlite3-worker1-promiser$(1),$(2))
|
||||
sqlite3.ext.js += $$(dir.dout)/sqlite3-worker1-promiser$(1)
|
||||
all: $$(dir.dout)/sqlite3-worker1-promiser$(1)
|
||||
endef
|
||||
|
||||
$(eval $(call gen-promiser,.js,$(c-pp.D.vanilla)))
|
||||
@@ -1145,12 +1188,19 @@ $(dir.dout)/sqlite3-opfs-async-proxy.js: $(dir.api)/sqlite3-opfs-async-proxy.js
|
||||
# we don't otherwise have a great place to attach them such that
|
||||
# they're always copied when we need them.
|
||||
#
|
||||
# The var $(out.$(B).js) comes from $(bin.mkwb) and $(B) is the name
|
||||
# of a build set up by that tool, e.g. b-vanilla or b-esm64.
|
||||
#
|
||||
$(foreach B,$(b.names),$(eval $(out.$(B).js): $(sqlite3.ext.js)))
|
||||
|
||||
#
|
||||
# b-all: builds all available js/wasm builds.
|
||||
#
|
||||
$(foreach B,$(b.names),$(eval b-all: $(out.$(B).js)))
|
||||
|
||||
#$(foreach B,$(b.names),$(eval pre: $(pre-js.$(B).js)))
|
||||
$(foreach B,$(b.names),$(eval post: $(post-js.$(B).js)))
|
||||
|
||||
#
|
||||
# speedtest1 is our primary benchmarking tool.
|
||||
#
|
||||
@@ -1199,10 +1249,9 @@ speedtest1.exit-runtime1 = -sEXIT_RUNTIME=1
|
||||
# -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app
|
||||
# which runs speedtest1 multiple times.
|
||||
|
||||
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core)
|
||||
@$(call b.echo,@,$(emo.disk)); \
|
||||
$(call b.mkdir@); \
|
||||
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ || exit
|
||||
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api)
|
||||
@$(call b.mkdir@); $(call b.echo,@,$(emo.disk)); \
|
||||
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api); } > $@ || exit
|
||||
speedtest1: b-speedtest1
|
||||
|
||||
#
|
||||
@@ -1244,9 +1293,11 @@ $(eval $(call gen-st64,speedtest1-worker.js,speedtest1-worker-64bit.js,speedtest
|
||||
#
|
||||
# To create those, we filter tester1.c-pp.js/html with $(bin.c-pp)...
|
||||
|
||||
#
|
||||
# tester1.js variants:
|
||||
#
|
||||
define gen-tester1.js
|
||||
# $1 = build name to have dep on
|
||||
# $1 = build name to have a dep on
|
||||
# $2 = suffix for tester1SUFFIX JS
|
||||
# $3 = $(bin.c-pp) flags
|
||||
$(call b.c-pp.target,test,tester1.c-pp.js,tester1$(2),$(3))
|
||||
@@ -1255,20 +1306,18 @@ tester1-$(1): tester1$(2)
|
||||
tester1: tester1$(2)
|
||||
endef
|
||||
|
||||
$(eval $(call gen-tester1.js,vanilla,.js, \
|
||||
$(c-pp.D.vanilla) \
|
||||
-Dsqlite3.js=$(dir.dout)/sqlite3.js))
|
||||
$(eval $(call gen-tester1.js,vanilla64,-64bit.js, \
|
||||
$(c-pp.D.vanilla64) \
|
||||
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.js))
|
||||
$(eval $(call gen-tester1.js,esm,.mjs, \
|
||||
$(c-pp.D.esm) \
|
||||
-Dsqlite3.js=$(dir.dout)/sqlite3.mjs))
|
||||
$(eval $(call gen-tester1.js,esm64,-64bit.mjs, \
|
||||
$(c-pp.D.esm64) \
|
||||
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
|
||||
$(eval $(call gen-tester1.js,vanilla,.js,\
|
||||
$(c-pp.D.vanilla) -Dsqlite3.js=$(dir.dout)/sqlite3.js))
|
||||
$(eval $(call gen-tester1.js,vanilla64,-64bit.js,\
|
||||
$(c-pp.D.vanilla64) -Dsqlite3.js=$(dir.dout)/sqlite3-64bit.js))
|
||||
$(eval $(call gen-tester1.js,esm,.mjs,\
|
||||
$(c-pp.D.esm) -Dsqlite3.js=$(dir.dout)/sqlite3.mjs))
|
||||
$(eval $(call gen-tester1.js,esm64,-64bit.mjs,\
|
||||
$(c-pp.D.esm64) -Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
|
||||
|
||||
#
|
||||
# tester1.html variants:
|
||||
#
|
||||
define gen-tester1.html
|
||||
# $1 = build name to have a dep on
|
||||
# $2 = filename suffix: empty, -64bit, -esm, esm-64bit
|
||||
@@ -1303,9 +1352,11 @@ $(eval $(call gen-tester1.html,esm64,-esm-64bit,\
|
||||
-Dtester1.js=tester1-64bit.mjs \
|
||||
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
|
||||
|
||||
# tester1-worker.html variants:
|
||||
# There is no ESM variant of this file. Instead, that page accepts a
|
||||
# ?esm URL flag to switch to ESM mode.
|
||||
#
|
||||
# tester1-worker.html variants: There is no ESM variant of this
|
||||
# file. Instead, that page accepts the ?esm URL flag to switch to ESM
|
||||
# mode.
|
||||
#
|
||||
$(eval $(call b.c-pp.target,test,tester1-worker.c-pp.html,\
|
||||
tester1-worker.html,-Dbitness=32))
|
||||
$(eval $(call b.c-pp.target,test,tester1-worker.c-pp.html,\
|
||||
@@ -1315,8 +1366,9 @@ tester1-worker.html: tester1.mjs
|
||||
tester1-worker-64bit.html: tester1-64bit.mjs
|
||||
|
||||
all: tester1
|
||||
#
|
||||
# end tester1
|
||||
########################################################################
|
||||
#
|
||||
|
||||
#
|
||||
# Convenience rules to rebuild with various -Ox levels. Much
|
||||
@@ -1327,6 +1379,7 @@ all: tester1
|
||||
#
|
||||
# Achtung: build times with anything higher than -O0 are somewhat
|
||||
# painful, which is why -O0 is the default.
|
||||
#
|
||||
.PHONY: o0 o1 o2 o3 os oz
|
||||
emcc-opt-extra =
|
||||
#ifeq (1,$(wasm-bare-bones))
|
||||
@@ -1377,7 +1430,9 @@ push-testing:
|
||||
ssh wasm-testing 'cd $(wasm-testing.dir) && bash .gzip' || \
|
||||
echo "SSH failed: it's likely that stale content will be served via old gzip files."
|
||||
|
||||
#
|
||||
# build everything needed by push-testing with -Oz
|
||||
#
|
||||
.PHONY: for-testing
|
||||
for-testing: emcc_opt=-Oz
|
||||
for-testing: loud=1
|
||||
@@ -1462,9 +1517,9 @@ endif
|
||||
dist-name-prefix = sqlite-wasm$(dist-name-extra)
|
||||
.PHONY: dist
|
||||
dist:
|
||||
./mkdist.sh $(dist-name-prefix)
|
||||
$(bin.bash) ./mkdist.sh $(dist-name-prefix)
|
||||
snapshot:
|
||||
./mkdist.sh $(dist-name-prefix) --snapshot
|
||||
$(bin.bash) ./mkdist.sh $(dist-name-prefix) --snapshot
|
||||
endif
|
||||
# ^^^ making dist/snapshot
|
||||
CLEAN_FILES += $(wildcard sqlite-wasm-*.zip)
|
||||
|
||||
@@ -155,3 +155,92 @@ _sqlite3_vtab_in_next
|
||||
_sqlite3_vtab_nochange
|
||||
_sqlite3_vtab_on_conflict
|
||||
_sqlite3_vtab_rhs_value
|
||||
//#if not bare-bones
|
||||
_sqlite3_column_database_name
|
||||
_sqlite3_column_origin_name
|
||||
_sqlite3_column_table_name
|
||||
_sqlite3_create_module
|
||||
_sqlite3_create_module_v2
|
||||
_sqlite3_create_window_function
|
||||
_sqlite3_declare_vtab
|
||||
_sqlite3_drop_modules
|
||||
_sqlite3_preupdate_blobwrite
|
||||
_sqlite3_preupdate_count
|
||||
_sqlite3_preupdate_depth
|
||||
_sqlite3_preupdate_hook
|
||||
_sqlite3_preupdate_new
|
||||
_sqlite3_preupdate_old
|
||||
_sqlite3_progress_handler
|
||||
_sqlite3_set_authorizer
|
||||
_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
|
||||
_sqlite3changegroup_add
|
||||
_sqlite3changegroup_add_strm
|
||||
_sqlite3changegroup_delete
|
||||
_sqlite3changegroup_new
|
||||
_sqlite3changegroup_output
|
||||
_sqlite3changegroup_output_strm
|
||||
_sqlite3changeset_apply
|
||||
_sqlite3changeset_apply_strm
|
||||
_sqlite3changeset_apply_v2
|
||||
_sqlite3changeset_apply_v2_strm
|
||||
_sqlite3changeset_apply_v3
|
||||
_sqlite3changeset_apply_v3_strm
|
||||
_sqlite3changeset_concat
|
||||
_sqlite3changeset_concat_strm
|
||||
_sqlite3changeset_conflict
|
||||
_sqlite3changeset_finalize
|
||||
_sqlite3changeset_fk_conflicts
|
||||
_sqlite3changeset_invert
|
||||
_sqlite3changeset_invert_strm
|
||||
_sqlite3changeset_new
|
||||
_sqlite3changeset_next
|
||||
_sqlite3changeset_old
|
||||
_sqlite3changeset_op
|
||||
_sqlite3changeset_pk
|
||||
_sqlite3changeset_start
|
||||
_sqlite3changeset_start_strm
|
||||
_sqlite3changeset_start_v2
|
||||
_sqlite3changeset_start_v2_strm
|
||||
_sqlite3session_attach
|
||||
_sqlite3session_changeset
|
||||
_sqlite3session_changeset_size
|
||||
_sqlite3session_changeset_strm
|
||||
_sqlite3session_config
|
||||
_sqlite3session_create
|
||||
_sqlite3session_delete
|
||||
_sqlite3session_diff
|
||||
_sqlite3session_enable
|
||||
_sqlite3session_indirect
|
||||
_sqlite3session_isempty
|
||||
_sqlite3session_memory_used
|
||||
_sqlite3session_object_config
|
||||
_sqlite3session_patchset
|
||||
_sqlite3session_patchset_strm
|
||||
_sqlite3session_table_filter
|
||||
//#endif not bare-bones
|
||||
//#if enable-see
|
||||
_sqlite3_key
|
||||
_sqlite3_key_v2
|
||||
_sqlite3_rekey
|
||||
_sqlite3_rekey_v2
|
||||
_sqlite3_activate_see
|
||||
//#endif enable-see
|
||||
//#if fiddle
|
||||
_fiddle_db_arg
|
||||
_fiddle_db_filename
|
||||
_fiddle_exec
|
||||
_fiddle_experiment
|
||||
_fiddle_interrupt
|
||||
_fiddle_main
|
||||
_fiddle_reset_db
|
||||
_fiddle_db_handle
|
||||
_fiddle_db_vfs
|
||||
_fiddle_export_db
|
||||
//#endif fiddle
|
||||
@@ -1,68 +0,0 @@
|
||||
_sqlite3_column_database_name
|
||||
_sqlite3_column_origin_name
|
||||
_sqlite3_column_table_name
|
||||
_sqlite3_create_module
|
||||
_sqlite3_create_module_v2
|
||||
_sqlite3_create_window_function
|
||||
_sqlite3_declare_vtab
|
||||
_sqlite3_drop_modules
|
||||
_sqlite3_preupdate_blobwrite
|
||||
_sqlite3_preupdate_count
|
||||
_sqlite3_preupdate_depth
|
||||
_sqlite3_preupdate_hook
|
||||
_sqlite3_preupdate_new
|
||||
_sqlite3_preupdate_old
|
||||
_sqlite3_progress_handler
|
||||
_sqlite3_set_authorizer
|
||||
_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
|
||||
_sqlite3changegroup_add
|
||||
_sqlite3changegroup_add_strm
|
||||
_sqlite3changegroup_delete
|
||||
_sqlite3changegroup_new
|
||||
_sqlite3changegroup_output
|
||||
_sqlite3changegroup_output_strm
|
||||
_sqlite3changeset_apply
|
||||
_sqlite3changeset_apply_strm
|
||||
_sqlite3changeset_apply_v2
|
||||
_sqlite3changeset_apply_v2_strm
|
||||
_sqlite3changeset_apply_v3
|
||||
_sqlite3changeset_apply_v3_strm
|
||||
_sqlite3changeset_concat
|
||||
_sqlite3changeset_concat_strm
|
||||
_sqlite3changeset_conflict
|
||||
_sqlite3changeset_finalize
|
||||
_sqlite3changeset_fk_conflicts
|
||||
_sqlite3changeset_invert
|
||||
_sqlite3changeset_invert_strm
|
||||
_sqlite3changeset_new
|
||||
_sqlite3changeset_next
|
||||
_sqlite3changeset_old
|
||||
_sqlite3changeset_op
|
||||
_sqlite3changeset_pk
|
||||
_sqlite3changeset_start
|
||||
_sqlite3changeset_start_strm
|
||||
_sqlite3changeset_start_v2
|
||||
_sqlite3changeset_start_v2_strm
|
||||
_sqlite3session_attach
|
||||
_sqlite3session_changeset
|
||||
_sqlite3session_changeset_size
|
||||
_sqlite3session_changeset_strm
|
||||
_sqlite3session_config
|
||||
_sqlite3session_create
|
||||
_sqlite3session_delete
|
||||
_sqlite3session_diff
|
||||
_sqlite3session_enable
|
||||
_sqlite3session_indirect
|
||||
_sqlite3session_isempty
|
||||
_sqlite3session_memory_used
|
||||
_sqlite3session_object_config
|
||||
_sqlite3session_patchset
|
||||
_sqlite3session_patchset_strm
|
||||
_sqlite3session_table_filter
|
||||
@@ -1,5 +0,0 @@
|
||||
_sqlite3_key
|
||||
_sqlite3_key_v2
|
||||
_sqlite3_rekey
|
||||
_sqlite3_rekey_v2
|
||||
_sqlite3_activate_see
|
||||
@@ -1,3 +0,0 @@
|
||||
FS
|
||||
wasmMemory
|
||||
|
||||
+43
-39
@@ -23,7 +23,7 @@ this writing, but is not set in stone forever and may change at any
|
||||
time. This doc targets maintainers of this code and those wanting to
|
||||
dive in to the details, not end user.
|
||||
|
||||
First off, a pikchr of the proverbial onion:
|
||||
First off, a [pikchr][] of the proverbial onion:
|
||||
|
||||
```pikchr toggle center
|
||||
scale = 0.85
|
||||
@@ -60,14 +60,14 @@ maintenance point of view.
|
||||
At the center of the onion is `sqlite3-api.js`, which gets generated
|
||||
by concatenating the following files together in their listed order:
|
||||
|
||||
- **`sqlite3-api-prologue.js`**\
|
||||
- **`sqlite3-api-prologue.js`**
|
||||
Contains the initial bootstrap setup of the sqlite3 API
|
||||
objects. This is exposed as a function, rather than objects, so that
|
||||
the next step can pass in a config object which abstracts away parts
|
||||
of the WASM environment, to facilitate plugging it in to arbitrary
|
||||
WASM toolchains. The bootstrapping function gets removed from the
|
||||
global scope in a later stage of the bootstrapping process.
|
||||
- **`../common/whwasmutil.js`**\
|
||||
- **`../common/whwasmutil.js`**
|
||||
A semi-third-party collection of JS/WASM utility code intended to
|
||||
replace much of the Emscripten glue. The sqlite3 APIs internally use
|
||||
these APIs instead of their Emscripten counterparts, in order to be
|
||||
@@ -77,79 +77,78 @@ by concatenating the following files together in their listed order:
|
||||
toolchains. It is "semi-third-party" in that it was created in order
|
||||
to support this tree but is standalone and maintained together
|
||||
with...
|
||||
- **`../jaccwabyt/jaccwabyt.js`**\
|
||||
- **`../jaccwabyt/jaccwabyt.js`**
|
||||
Another semi-third-party API which creates bindings between JS
|
||||
and C structs, such that changes to the struct state from either JS
|
||||
or C are visible to the other end of the connection. This is also an
|
||||
independent spinoff project, conceived for the sqlite3 project but
|
||||
maintained separately.
|
||||
- **`sqlite3-api-glue.js`**\
|
||||
- **`sqlite3-api-glue.js`**
|
||||
Invokes functionality exposed by the previous two files to flesh out
|
||||
low-level parts of `sqlite3-api-prologue.js`. Most of these pieces
|
||||
involve populating the `sqlite3.capi.wasm` object and creating
|
||||
`sqlite3.capi.sqlite3_...()` bindings. This file also deletes most
|
||||
global-scope symbols the above files create, effectively moving them
|
||||
into the scope being used for initializing the API.
|
||||
- **`<build>/sqlite3-api-build-version.js`**\
|
||||
- **`<build>/sqlite3-api-build-version.js`**
|
||||
Gets created by the build process and populates the
|
||||
`sqlite3.version` object. This part is not critical, but records the
|
||||
version of the library against which this module was built.
|
||||
- **`sqlite3-api-oo1.js`**\
|
||||
- **`sqlite3-api-oo1.js`**
|
||||
Provides a high-level object-oriented wrapper to the lower-level C
|
||||
API, colloquially known as OO API #1. Its API is similar to other
|
||||
high-level sqlite3 JS wrappers and should feel relatively familiar
|
||||
to anyone familiar with such APIs. It is not a "required component"
|
||||
and can be elided from builds which do not want it.
|
||||
- **`sqlite3-api-worker1.js`**\
|
||||
- **`sqlite3-api-worker1.js`**
|
||||
A Worker-thread-based API which uses OO API #1 to provide an
|
||||
interface to a database which can be driven from the main Window
|
||||
thread via the Worker message-passing interface. Like OO API #1,
|
||||
this is an optional component, offering one of any number of
|
||||
potential implementations for such an API.
|
||||
- **`sqlite3-worker1.js`**\
|
||||
- **`sqlite3-worker1.js`**
|
||||
Is not part of the amalgamated sources and is intended to be
|
||||
loaded by a client Worker thread. It loads the sqlite3 module
|
||||
and runs the Worker #1 API which is implemented in
|
||||
`sqlite3-api-worker1.js`.
|
||||
- **`sqlite3-worker1-promiser.js`**\
|
||||
- **`sqlite3-worker1-promiser.js`**
|
||||
Is likewise not part of the amalgamated sources and provides
|
||||
a Promise-based interface into the Worker #1 API. This is
|
||||
a far user-friendlier way to interface with databases running
|
||||
in a Worker thread.
|
||||
- **`sqlite3-vfs-helper.js`**\
|
||||
- **`sqlite3-vfs-helper.js`**
|
||||
Installs the `sqlite3.vfs` namespace, which contain helpers for use
|
||||
by downstream code which creates `sqlite3_vfs` implementations.
|
||||
- **`sqlite3-vtab-helper.js`**\
|
||||
- **`sqlite3-vtab-helper.js`**
|
||||
Installs the `sqlite3.vtab` namespace, which contain helpers for use
|
||||
by downstream code which creates `sqlite3_module` implementations.
|
||||
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
||||
- **`sqlite3-vfs-opfs.c-pp.js`**
|
||||
is an sqlite3 VFS implementation which supports the [Origin-Private
|
||||
FileSystem (OPFS)][OPFS] as a storage layer to provide persistent
|
||||
storage for database files in a browser. It requires...
|
||||
- **`sqlite3-opfs-async-proxy.js`**\
|
||||
- **`sqlite3-opfs-async-proxy.js`**
|
||||
is the asynchronous backend part of the [OPFS][] proxy. It
|
||||
speaks directly to the (async) OPFS API and channels those
|
||||
results back to its synchronous counterpart. This file, because
|
||||
it must be started in its own Worker, is not part of the
|
||||
amalgamation.
|
||||
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\
|
||||
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**
|
||||
is another sqlite3 VFS supporting the [OPFS][], but uses a
|
||||
completely different approach than the above-listed one.
|
||||
- **`sqlite3-api-cleanup.js`**\
|
||||
The previous files do not immediately extend the library. Instead
|
||||
they add callback functions to be called during its
|
||||
bootstrapping. Some also temporarily create global objects in order
|
||||
to communicate their state to the files which follow them. This file
|
||||
cleans up any dangling globals and runs the API bootstrapping
|
||||
process, which is what finally executes the initialization code
|
||||
installed by the previous files. As of this writing, this code
|
||||
ensures that the previous files leave no more than a single global
|
||||
symbol installed - `sqlite3InitModule()`. When adapting the API for
|
||||
non-Emscripten toolchains, this "should" be the only file, of those
|
||||
in this list, where changes are needed. The Emscripten-specific
|
||||
pieces described below may also require counterparts in any as-yet
|
||||
hypothetical alternative build.
|
||||
|
||||
The previous files do not immediately extend the library. Instead they
|
||||
install a global function `sqlite3ApiBootstrap()`, which downstream
|
||||
code must call to configure the library for the current JS/WASM
|
||||
environment. Each file listed above pushes a callback into the
|
||||
bootstrapping queue, to be called as part of `sqlite3ApiBootstrap()`.
|
||||
Some files also temporarily create global objects in order to
|
||||
communicate their state to the files which follow them. Those
|
||||
get cleaned up vi `post-js-footer.js`, described below.
|
||||
|
||||
Adapting the build for non-Emscripten toolchains essentially requires packaging
|
||||
the above files, concatated together, into that toolchain's "JS glue"
|
||||
and, in the final stage of that glue, call `sqlite3ApiBootstrap()` and
|
||||
return its result to the end user.
|
||||
|
||||
**Files with the extension `.c-pp.js`** are intended [to be processed
|
||||
with `c-pp`](#c-pp), noting that such preprocessing may be applied
|
||||
@@ -171,23 +170,27 @@ from this file rather than `sqlite3.c`.
|
||||
The following Emscripten-specific files are injected into the
|
||||
build-generated `sqlite3.js` along with `sqlite3-api.js`.
|
||||
|
||||
- **`extern-pre-js.js`**\
|
||||
- **`extern-pre-js.js`**
|
||||
Emscripten-specific header for Emscripten's `--extern-pre-js`
|
||||
flag. As of this writing, that file is only used for experimentation
|
||||
purposes and holds no code relevant to the production deliverables.
|
||||
- **`pre-js.c-pp.js`**\
|
||||
- **`pre-js.c-pp.js`**
|
||||
Emscripten-specific header for Emscripten's `--pre-js` flag. This
|
||||
file overrides certain Emscripten behavior before Emscripten does
|
||||
most of its work.
|
||||
- **`post-js-header.js`**\
|
||||
- **`post-js-header.js`**
|
||||
Emscripten-specific header for the `--post-js` input. It opens up,
|
||||
but does not close, a function used for initializing the library.
|
||||
- (**`sqlite3-api.js`** gets sandwiched between these ↑ two
|
||||
↓ files.)
|
||||
- **`post-js-footer.js`**\
|
||||
- **`sqlite3-api.js`** gets sandwiched between these ↑ two
|
||||
↓ files.
|
||||
- **`post-js-footer.js`**
|
||||
Emscripten-specific footer for the `--post-js` input. This closes
|
||||
off the function opened by `post-js-header.js`.
|
||||
- **`extern-post-js.c-pp.js`**\
|
||||
off the function opened by `post-js-header.js`. This file cleans up
|
||||
any dangling globals and runs `sqlite3ApiBootstrap()`. As of this
|
||||
writing, this code ensures that the previous files leave no more
|
||||
than a single global symbol installed - `sqlite3InitModule()`.
|
||||
|
||||
- **`extern-post-js.c-pp.js`**
|
||||
Emscripten-specific header for Emscripten's `--extern-post-js`
|
||||
flag. This file is run in the global scope. It overwrites the
|
||||
Emscripten-installed `sqlite3InitModule()` function with one which
|
||||
@@ -205,9 +208,10 @@ Preprocessing of Source Files
|
||||
Certain files in the build require preprocessing to filter in/out
|
||||
parts which differ between vanilla JS, ES6 Modules, and node.js
|
||||
builds. The preprocessor application itself is in
|
||||
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
|
||||
of such preprocessing are maintained in
|
||||
[`c-pp-lite.c`](/file/ext/wasm/c-pp-lite.c) and the complete technical
|
||||
details of such preprocessing are maintained in
|
||||
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
|
||||
|
||||
|
||||
[OPFS]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system
|
||||
[pikchr]: https://pikchr.org
|
||||
|
||||
@@ -26,7 +26,7 @@ const toExportForESM =
|
||||
*/
|
||||
const originalInit = sqlite3InitModule;
|
||||
if(!originalInit){
|
||||
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
|
||||
throw new Error("Expecting sqlite3InitModule to be defined by the Emscripten build.");
|
||||
}
|
||||
/**
|
||||
We need to add some state which our custom Module.locateFile()
|
||||
|
||||
@@ -1,3 +1,72 @@
|
||||
/*
|
||||
2022-07-22
|
||||
|
||||
The author disclaims copyright to this source code. In place of a
|
||||
legal notice, here is a blessing:
|
||||
|
||||
* May you do good and not evil.
|
||||
* May you find forgiveness for yourself and forgive others.
|
||||
* May you share freely, never taking more than you give.
|
||||
|
||||
***********************************************************************
|
||||
|
||||
This file is the tail end of the sqlite3-api.js constellation,
|
||||
closing the function scope opened by post-js-header.js.
|
||||
|
||||
In terms of amalgamation code placement, this file is appended
|
||||
immediately after the final sqlite3-api-*.js piece. Those files
|
||||
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
|
||||
It is run within a context which gives it access to Emscripten's
|
||||
Module object, after sqlite3.wasm is loaded but before
|
||||
sqlite3ApiBootstrap() has been called.
|
||||
|
||||
Because this code resides (after building) inside the function
|
||||
installed by post-js-header.js, it has access to state set up by
|
||||
pre-js.c-pp.js and friends.
|
||||
*/
|
||||
try{
|
||||
/* We are in the closing block of Module.runSQLite3PostLoadInit(), so
|
||||
its arguments are visible here. */
|
||||
|
||||
/* Config options for sqlite3ApiBootstrap(). */
|
||||
const bootstrapConfig = Object.assign(
|
||||
Object.create(null),
|
||||
/** The WASM-environment-dependent configuration for sqlite3ApiBootstrap() */
|
||||
{
|
||||
memory: ('undefined'!==typeof wasmMemory)
|
||||
? wasmMemory
|
||||
: EmscriptenModule['wasmMemory'],
|
||||
exports: ('undefined'!==typeof wasmExports)
|
||||
? wasmExports /* emscripten >=3.1.44 */
|
||||
: (Object.prototype.hasOwnProperty.call(EmscriptenModule,'wasmExports')
|
||||
? EmscriptenModule['wasmExports']
|
||||
: EmscriptenModule['asm']/* emscripten <=3.1.43 */)
|
||||
},
|
||||
globalThis.sqlite3ApiBootstrap.defaultConfig, // default options
|
||||
globalThis.sqlite3ApiConfig || {} // optional client-provided options
|
||||
);
|
||||
|
||||
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
|
||||
|
||||
/**
|
||||
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
|
||||
Ideally clients should be able to inject their own config here,
|
||||
but that's not practical in this particular build constellation
|
||||
because of the order everything happens in. Clients may either
|
||||
define globalThis.sqlite3ApiConfig or modify
|
||||
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
|
||||
configuration used by a no-args call to sqlite3ApiBootstrap(),
|
||||
but must have first loaded their WASM module in order to be able
|
||||
to provide the necessary configuration state.
|
||||
*/
|
||||
const p = globalThis.sqlite3ApiBootstrap(bootstrapConfig);
|
||||
delete globalThis.sqlite3ApiBootstrap;
|
||||
return p /* the eventual result of globalThis.sqlite3InitModule() */;
|
||||
}catch(e){
|
||||
console.error("sqlite3ApiBootstrap() error:",e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
//console.warn("This is the end of the Module.runSQLite3PostLoadInit handler.");
|
||||
}/*Module.runSQLite3PostLoadInit(...)*/;
|
||||
//console.warn("This is the end of the setup of the (pending) Module.runSQLite3PostLoadInit");
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
post-js.js for use with Emscripten's --post-js flag, so it gets
|
||||
injected in the earliest stages of sqlite3InitModule().
|
||||
|
||||
This function wraps the whole SQLite3 library but does not
|
||||
bootstrap it.
|
||||
|
||||
Running this function will bootstrap the library and return
|
||||
a Promise to the sqlite3 namespace object.
|
||||
|
||||
In the canonical builds, this gets called by extern-post-js.c-pp.js
|
||||
*/
|
||||
Module.runSQLite3PostLoadInit = function(
|
||||
sqlite3InitScriptInfo /* populated by extern-post-js.c-pp.js */,
|
||||
Module.runSQLite3PostLoadInit = async function(
|
||||
sqlite3InitScriptInfo,
|
||||
EmscriptenModule/*the Emscripten-style module object*/,
|
||||
sqlite3IsUnderTest
|
||||
){
|
||||
@@ -35,7 +34,6 @@ Module.runSQLite3PostLoadInit = function(
|
||||
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
|
||||
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
|
||||
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
|
||||
- sqlite3-api-cleanup.js => final bootstrapping phase
|
||||
- post-js-footer.js => this file's epilogue
|
||||
|
||||
And all of that gets sandwiched between extern-pre-js.js and
|
||||
|
||||
@@ -14,12 +14,33 @@
|
||||
itself. i.e. try to keep file-local symbol names obnoxiously
|
||||
collision-resistant.
|
||||
*/
|
||||
/**
|
||||
This file was preprocessed using:
|
||||
|
||||
//#@policy error
|
||||
@c-pp::ARGV@
|
||||
//#@policy off
|
||||
*/
|
||||
//#if unsupported-build
|
||||
/**
|
||||
UNSUPPORTED BUILD:
|
||||
|
||||
This SQLite JS build configuration is entirely unsupported! It has
|
||||
not been tested beyond the ability to compile it. It may not
|
||||
load. It may not work properly. Only builds targeting browser
|
||||
environments are supported and tested.
|
||||
*/
|
||||
//#endif
|
||||
(function(Module){
|
||||
const sIMS =
|
||||
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|
||||
|| Object.assign(Object.create(null),{
|
||||
debugModule: ()=>{
|
||||
console.warn("globalThis.sqlite3InitModuleState is missing");
|
||||
/* In WASMFS builds this file gets loaded once per thread,
|
||||
but sqlite3InitModuleState is not getting set for the
|
||||
worker threads? That those workers seem to function fine
|
||||
despite that is curious. */
|
||||
debugModule: function(){
|
||||
console.warn("globalThis.sqlite3InitModuleState is missing",arguments);
|
||||
}
|
||||
});
|
||||
delete globalThis.sqlite3InitModuleState;
|
||||
@@ -72,8 +93,7 @@
|
||||
//#endif target:es6-module
|
||||
}.bind(sIMS);
|
||||
|
||||
//#if Module.instantiateWasm
|
||||
//#if not wasmfs
|
||||
//#if Module.instantiateWasm and not wasmfs
|
||||
/**
|
||||
Override Module.instantiateWasm().
|
||||
|
||||
@@ -109,7 +129,6 @@
|
||||
.then(finalThen)
|
||||
return loadWasm();
|
||||
}.bind(sIMS);
|
||||
//#endif not wasmfs
|
||||
//#endif Module.instantiateWasm
|
||||
//#endif Module.instantiateWasm and not wasmfs
|
||||
})(Module);
|
||||
/* END FILE: api/pre-js.js. */
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
2022-07-22
|
||||
|
||||
The author disclaims copyright to this source code. In place of a
|
||||
legal notice, here is a blessing:
|
||||
|
||||
* May you do good and not evil.
|
||||
* May you find forgiveness for yourself and forgive others.
|
||||
* May you share freely, never taking more than you give.
|
||||
|
||||
***********************************************************************
|
||||
|
||||
This file is the tail end of the sqlite3-api.js constellation,
|
||||
intended to be appended after all other sqlite3-api-*.js files so
|
||||
that it can finalize any setup and clean up any global symbols
|
||||
temporarily used for setting up the API's various subsystems.
|
||||
|
||||
In Emscripten builds it's run in the context of what amounts to a
|
||||
Module.postRun handler, though it's no longer actually a postRun
|
||||
handler because Emscripten 4.0 changed postRun semantics in an
|
||||
incompatible way.
|
||||
|
||||
In terms of amalgamation code placement, this file is appended
|
||||
immediately after the final sqlite3-api-*.js piece. Those files
|
||||
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
|
||||
It is run within a context which gives it access to Emscripten's
|
||||
Module object, after sqlite3.wasm is loaded but before
|
||||
sqlite3ApiBootstrap() has been called.
|
||||
|
||||
Because this code resides (after building) inside the function
|
||||
installed by post-js-header.js, it has access to the
|
||||
*/
|
||||
'use strict';
|
||||
if( 'undefined' === typeof EmscriptenModule/*from post-js-header.js*/ ){
|
||||
console.warn("This is not running in the context of Module.runSQLite3PostLoadInit()");
|
||||
throw new Error("sqlite3-api-cleanup.js expects to be running in the "+
|
||||
"context of its Emscripten module loader.");
|
||||
}
|
||||
try{
|
||||
/* Config options for sqlite3ApiBootstrap(). */
|
||||
const bootstrapConfig = Object.assign(
|
||||
Object.create(null),
|
||||
globalThis.sqlite3ApiBootstrap.defaultConfig, // default options
|
||||
globalThis.sqlite3ApiConfig || {}, // optional client-provided options
|
||||
/** The WASM-environment-dependent configuration for sqlite3ApiBootstrap() */
|
||||
{
|
||||
memory: ('undefined'!==typeof wasmMemory)
|
||||
? wasmMemory
|
||||
: EmscriptenModule['wasmMemory'],
|
||||
exports: ('undefined'!==typeof wasmExports)
|
||||
? wasmExports /* emscripten >=3.1.44 */
|
||||
: (Object.prototype.hasOwnProperty.call(EmscriptenModule,'wasmExports')
|
||||
? EmscriptenModule['wasmExports']
|
||||
: EmscriptenModule['asm']/* emscripten <=3.1.43 */)
|
||||
}
|
||||
);
|
||||
|
||||
/** Figure out if this is a 32- or 64-bit WASM build. */
|
||||
bootstrapConfig.wasmPtrIR =
|
||||
'number'===(typeof bootstrapConfig.exports.sqlite3_libversion())
|
||||
? 'i32' :'i64';
|
||||
const sIMS = sqlite3InitScriptInfo;
|
||||
sIMS.debugModule("Bootstrapping lib config", sIMS);
|
||||
|
||||
/**
|
||||
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
|
||||
Ideally clients should be able to inject their own config here,
|
||||
but that's not practical in this particular build constellation
|
||||
because of the order everything happens in. Clients may either
|
||||
define globalThis.sqlite3ApiConfig or modify
|
||||
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
|
||||
configuration used by a no-args call to sqlite3ApiBootstrap(),
|
||||
but must have first loaded their WASM module in order to be able
|
||||
to provide the necessary configuration state.
|
||||
*/
|
||||
const p = globalThis.sqlite3ApiBootstrap(bootstrapConfig);
|
||||
delete globalThis.sqlite3ApiBootstrap;
|
||||
return p /* the eventual result of globalThis.sqlite3InitModule() */;
|
||||
}catch(e){
|
||||
console.error("sqlite3ApiBootstrap() error:",e);
|
||||
throw e;
|
||||
}
|
||||
throw new Error("Maintenance required: this line should never be reached");
|
||||
@@ -120,7 +120,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
|
||||
//#define proxy-text-apis=1
|
||||
//#if not proxy-text-apis
|
||||
/* Search this file for tag:proxy-text-apis to see what this is about. */
|
||||
["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
|
||||
//#endif
|
||||
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
|
||||
["sqlite3_commit_hook", "void*", [
|
||||
@@ -317,7 +321,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
|
||||
["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
|
||||
["sqlite3_value_subtype", "int", "sqlite3_value*"],
|
||||
//#if not proxy-text-apis
|
||||
["sqlite3_value_text", "string", "sqlite3_value*"],
|
||||
//#endif
|
||||
["sqlite3_value_type", "int", "sqlite3_value*"],
|
||||
["sqlite3_vfs_find", "*", "string"],
|
||||
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
|
||||
@@ -1654,6 +1660,45 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
}/*sqlite3_bind_text/blob()*/
|
||||
|
||||
//#if proxy-text-apis
|
||||
if(!capi.sqlite3_column_text){
|
||||
/*[tag:proxy-text-apis]
|
||||
As discussed at:
|
||||
|
||||
https://sqlite.org/forum/forumpost/d77281aec2df9ada
|
||||
|
||||
Summary: there are opinions that sqlite3_column_text() and
|
||||
sqlite3_value_text() should handle strings such that embedded
|
||||
NULs are retained. This block does that. This block does _not_
|
||||
apply that special-case behavior to any number of _other_
|
||||
APIs which return C-strings. That discrepancy makes this
|
||||
block highly arguable, but one can also argue that these two
|
||||
specific functions can get away with such acrobatics without
|
||||
it being called voodoo in a pejorative sense.
|
||||
*/
|
||||
const argStmt = wasm.xWrap.argAdapter('sqlite3_stmt*'),
|
||||
argInt = wasm.xWrap.argAdapter('int'),
|
||||
argValue = wasm.xWrap.argAdapter('sqlite3_value*'),
|
||||
newStr =
|
||||
(cstr,n)=>wasm.typedArrayToString(wasm.heap8u(),
|
||||
Number(cstr), Number(cstr)+n)
|
||||
capi.sqlite3_column_text = function(stmt, colIndex){
|
||||
const a0 = argStmt(stmt), a1 = argInt(colIndex);
|
||||
const cstr = wasm.exports.sqlite3_column_text(a0, a1);
|
||||
return cstr
|
||||
? newStr(cstr,wasm.exports.sqlite3_column_bytes(a0, a1))
|
||||
: null;
|
||||
};
|
||||
capi.sqlite3_value_text = function(val){
|
||||
const a0 = argValue(val);
|
||||
const cstr = wasm.exports.sqlite3_value_text(a0);
|
||||
return cstr
|
||||
? newStr(cstr,wasm.exports.sqlite3_value_bytes(a0))
|
||||
: null;
|
||||
};
|
||||
}/*text-return-related bindings*/
|
||||
//#endif proxy-text-apis
|
||||
|
||||
{/* sqlite3_config() */
|
||||
/**
|
||||
Wraps a small subset of the C API's sqlite3_config() options.
|
||||
@@ -1836,6 +1881,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
for anything other than local/sessionStorage. It "can"
|
||||
be used that way but it's not really intended to be. */
|
||||
capi.sqlite3_vfs_unregister(pKvvfs);
|
||||
delete capi.sqlite3_kvvfs_methods;
|
||||
}
|
||||
}/*pKvvfs*/
|
||||
|
||||
@@ -1944,7 +1990,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}
|
||||
tgt[memKey] = fProxy;
|
||||
}else{
|
||||
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name));
|
||||
const pFunc = wasm.installFunction(fProxy, sigN);
|
||||
tgt[memKey] = pFunc;
|
||||
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
|
||||
tgt.addOnDispose('ondispose.__removeFuncList handler',
|
||||
|
||||
@@ -27,13 +27,14 @@
|
||||
/**
|
||||
sqlite3ApiBootstrap() is the only global symbol persistently
|
||||
exposed by this API. It is intended to be called one time at the
|
||||
end of the API amalgamation process, passed configuration details
|
||||
for the current environment, and then optionally be removed from
|
||||
the global object using `delete globalThis.sqlite3ApiBootstrap`.
|
||||
end of the API amalgamation process and passed configuration details
|
||||
for the current environment.
|
||||
|
||||
This function is not intended for client-level use. It is intended
|
||||
for use in creating bundles configured for specific WASM
|
||||
environments.
|
||||
environments. That said, the "sqlite3-api.js" intermediary build
|
||||
file aims to be suitable for dropping in to custom builds, and it
|
||||
exposes only this function.
|
||||
|
||||
This function expects a configuration object, intended to abstract
|
||||
away details specific to any given WASM environment, primarily so
|
||||
@@ -93,9 +94,10 @@
|
||||
can be replaced with (e.g.) empty functions to squelch all such
|
||||
output.
|
||||
|
||||
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
|
||||
filesystem in WASMFS-capable builds.
|
||||
|
||||
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the
|
||||
OPFS-backed filesystem in WASMFS-capable builds. This is only
|
||||
used in WASMFS-capable builds of the library (which the canonical
|
||||
builds do not include).
|
||||
|
||||
[^1] = This property may optionally be a function, in which case
|
||||
this function calls that function to fetch the value,
|
||||
@@ -125,7 +127,8 @@
|
||||
Both sqlite3ApiBootstrap.defaultConfig and
|
||||
globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap()
|
||||
because any changes to them made after that point would have no
|
||||
useful effect.
|
||||
useful effect. This function also deletes itself from globalThis
|
||||
when it's called.
|
||||
|
||||
This function returns a Promise to the sqlite3 namespace object,
|
||||
which resolves after the async pieces of the library init are
|
||||
@@ -177,14 +180,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
Eliminate any confusion about whether these config objects may
|
||||
be used after library initialization by eliminating the outward-facing
|
||||
objects...
|
||||
*/
|
||||
delete globalThis.sqlite3ApiConfig;
|
||||
delete sqlite3ApiBootstrap.defaultConfig;
|
||||
|
||||
/**
|
||||
The main sqlite3 binding API gets installed into this object,
|
||||
mimicking the C API as closely as we can. The numerous members
|
||||
@@ -796,25 +791,10 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
|
||||
/**
|
||||
wasm.X properties which are used for configuring the wasm
|
||||
environment via whwashutil.js.
|
||||
environment via whwashutil.js. This object gets fleshed out with
|
||||
a number of WASM-specific utilities, in sqlite3-api-glue.c-pp.js.
|
||||
*/
|
||||
Object.assign(wasm, {
|
||||
/**
|
||||
The WASM IR (Intermediate Representation) value for
|
||||
pointer-type values. If set then it MUST be one of 'i32' or
|
||||
'i64' (else an exception will be thrown). If it's not set, it
|
||||
will default to 'i32'.
|
||||
*/
|
||||
pointerIR: config.wasmPtrIR,
|
||||
|
||||
/**
|
||||
True if BigInt support was enabled via (e.g.) the
|
||||
Emscripten -sWASM_BIGINT flag, else false. When
|
||||
enabled, certain 64-bit sqlite3 APIs are enabled which
|
||||
are not otherwise enabled due to JS/WASM int64
|
||||
impedance mismatches.
|
||||
*/
|
||||
bigIntEnabled: !!config.bigIntEnabled,
|
||||
|
||||
/**
|
||||
The symbols exported by the WASM environment.
|
||||
@@ -825,8 +805,9 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
/**
|
||||
When Emscripten compiles with `-sIMPORTED_MEMORY`, it
|
||||
initializes the heap and imports it into wasm, as opposed to
|
||||
the other way around. In this case, the memory is not
|
||||
available via this.exports.memory.
|
||||
the other way around. In this case, the memory is not available
|
||||
via this.exports.memory so the client must pass it in via
|
||||
config.memory.
|
||||
*/
|
||||
memory: config.memory
|
||||
|| config.exports['memory']
|
||||
@@ -834,6 +815,29 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
"in either config.exports.memory (exported)",
|
||||
"or config.memory (imported)."),
|
||||
|
||||
/**
|
||||
The WASM pointer size. If set then it MUST be one of 4 or 8 and
|
||||
it MUST correspond to the WASM environment's pointer size. We
|
||||
figure out the size by calling some un-JS-wrapped WASM function
|
||||
which returns a pointer-type value. If that value is a BigInt,
|
||||
it's 64-bit, else it's 32-bit. The pieces which populate
|
||||
sqlite3.wasm (whwasmutil.js) can figure this out _if_ they can
|
||||
allocate, but we have a chicken/egg situation there which makes
|
||||
it illegal for that code to invoke wasm.dealloc() at the time
|
||||
it would be needed. So we need to configure it ahead of time
|
||||
(here) instead.
|
||||
*/
|
||||
pointerSize: ('number'===typeof config.exports.sqlite3_libversion()) ? 4 : 8,
|
||||
|
||||
/**
|
||||
True if BigInt support was enabled via (e.g.) the
|
||||
Emscripten -sWASM_BIGINT flag, else false. When
|
||||
enabled, certain 64-bit sqlite3 APIs are enabled which
|
||||
are not otherwise enabled due to JS/WASM int64
|
||||
impedance mismatches.
|
||||
*/
|
||||
bigIntEnabled: !!config.bigIntEnabled,
|
||||
|
||||
/**
|
||||
WebAssembly.Table object holding the indirect function call
|
||||
table. Defaults to exports.__indirect_function_table.
|
||||
@@ -949,7 +953,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
};
|
||||
wasm.realloc.impl = wasm.exports[keyRealloc];
|
||||
wasm.dealloc = function f(m){
|
||||
f.impl(wasm.ptr.coerce(m)/*tag:64bit*/);
|
||||
f.impl(wasm.ptr.coerce(m)/*tag:64bit*/)
|
||||
/* This coerce() is the reason we have to set wasm.pointerSize before
|
||||
calling WhWasmUtilInstaller(). If we don't, that code will call
|
||||
into this very early in its init, before wasm.ptr has been set up,
|
||||
resulting in a null deref here. */;
|
||||
};
|
||||
wasm.dealloc.impl = wasm.exports[keyDealloc];
|
||||
}
|
||||
@@ -1020,18 +1028,18 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
}/*compileOptionUsed()*/;
|
||||
|
||||
/**
|
||||
sqlite3.wasm.pstack (pseudo-stack) holds a special-case intended
|
||||
solely for short-lived, small data. In practice, it's primarily
|
||||
used to allocate output pointers. It mus not be used for any
|
||||
memory which needs to outlive the scope in which it's obtained
|
||||
from pstack.
|
||||
sqlite3.wasm.pstack (pseudo-stack) holds a special-case allocator
|
||||
intended solely for short-lived, small data. In practice, it's
|
||||
primarily used to allocate output pointers. It must not be used
|
||||
for any memory which needs to outlive the scope in which it's
|
||||
obtained from pstack.
|
||||
|
||||
The library guarantees only that a minimum of 2kb are available
|
||||
in this allocator, and it may provide more (it's a build-time
|
||||
value). pstack.quota and pstack.remaining can be used to get the
|
||||
total resp. remaining amount of memory.
|
||||
|
||||
It has only a single intended usage:
|
||||
It has only a single intended usage pattern:
|
||||
|
||||
```
|
||||
const stackPos = pstack.pointer;
|
||||
@@ -1048,13 +1056,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
```
|
||||
|
||||
This allocator is much faster than a general-purpose one but is
|
||||
limited to usage patterns like the one shown above.
|
||||
limited to usage patterns like the one shown above (which are
|
||||
pretty common when using sqlite3.capi).
|
||||
|
||||
It operates from a static range of memory which lives outside of
|
||||
space managed by Emscripten's stack-management, so does not
|
||||
collide with Emscripten-provided stack allocation APIs. The
|
||||
memory lives in the WASM heap and can be used with routines such
|
||||
as wasm.poke() and wasm.heap8u().slice().
|
||||
The memory lives in the WASM heap and can be used with routines
|
||||
such as wasm.poke() and wasm.heap8u().slice().
|
||||
*/
|
||||
wasm.pstack = Object.assign(Object.create(null),{
|
||||
/**
|
||||
@@ -1128,7 +1134,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
argument: if it's 1, it returns a single pointer value. If it's
|
||||
more than 1, it returns the same as allocChunks().
|
||||
|
||||
When a returned pointers will refer to a 64-bit value, e.g. a
|
||||
When a returned pointer will refer to a 64-bit value, e.g. a
|
||||
double or int64, and that value must be written or fetched,
|
||||
e.g. using wasm.poke() or wasm.peek(), it is
|
||||
important that the pointer in question be aligned to an 8-byte
|
||||
@@ -1196,6 +1202,9 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
}
|
||||
})/*wasm.pstack properties*/;
|
||||
|
||||
/**
|
||||
Docs: https://sqlite.org/wasm/doc/trunk/api-c-style.md#sqlite3_randomness
|
||||
*/
|
||||
capi.sqlite3_randomness = (...args)=>{
|
||||
if(1===args.length
|
||||
&& util.isTypedArray(args[0])
|
||||
@@ -1230,8 +1239,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
wasm.exports.sqlite3_randomness(...args);
|
||||
};
|
||||
|
||||
/** State for sqlite3_wasmfs_opfs_dir(). */
|
||||
let __wasmfsOpfsDir = undefined;
|
||||
/**
|
||||
If the wasm environment has a WASMFS/OPFS-backed persistent
|
||||
storage directory, its path is returned by this function. If it
|
||||
@@ -1255,7 +1262,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
WASMFS capability requires a custom build.
|
||||
*/
|
||||
capi.sqlite3_wasmfs_opfs_dir = function(){
|
||||
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
|
||||
if(undefined !== this.dir) return this.dir;
|
||||
// If we have no OPFS, there is no persistent dir
|
||||
const pdir = config.wasmfsOpfsDir;
|
||||
if(!pdir
|
||||
@@ -1263,21 +1270,21 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
|| !globalThis.FileSystemDirectoryHandle
|
||||
|| !globalThis.FileSystemFileHandle
|
||||
|| !wasm.exports.sqlite3__wasm_init_wasmfs){
|
||||
return __wasmfsOpfsDir = "";
|
||||
return this.dir = "";
|
||||
}
|
||||
try{
|
||||
if(pdir && 0===wasm.xCallWrapped(
|
||||
'sqlite3__wasm_init_wasmfs', 'i32', ['string'], pdir
|
||||
)){
|
||||
return __wasmfsOpfsDir = pdir;
|
||||
return this.dir = pdir;
|
||||
}else{
|
||||
return __wasmfsOpfsDir = "";
|
||||
return this.dir = "";
|
||||
}
|
||||
}catch(e){
|
||||
// sqlite3__wasm_init_wasmfs() is not available
|
||||
return __wasmfsOpfsDir = "";
|
||||
return this.dir = "";
|
||||
}
|
||||
};
|
||||
}.bind(Object.create(null));
|
||||
|
||||
/**
|
||||
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
|
||||
@@ -1333,7 +1340,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
*/
|
||||
capi.sqlite3_js_vfs_list = function(){
|
||||
const rc = [];
|
||||
let pVfs = capi.sqlite3_vfs_find(wasm.ptr.coerce(0));
|
||||
let pVfs = capi.sqlite3_vfs_find(wasm.ptr.null);
|
||||
while(pVfs){
|
||||
const oVfs = new capi.sqlite3_vfs(pVfs);
|
||||
rc.push(wasm.cstrToJs(oVfs.$zName));
|
||||
@@ -1953,55 +1960,58 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
return (0===v) ? undefined : capi.sqlite3_value_to_js(v, throwIfCannotConvert);
|
||||
};
|
||||
|
||||
/**
|
||||
Internal impl of sqlite3_preupdate_new/old_js() and
|
||||
sqlite3changeset_new/old_js().
|
||||
*/
|
||||
const __newOldValue = function(pObj, iCol, impl){
|
||||
impl = capi[impl];
|
||||
if(!this.ptr) this.ptr = wasm.allocPtr();
|
||||
else wasm.pokePtr(this.ptr, 0);
|
||||
const rc = impl(pObj, iCol, this.ptr);
|
||||
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
|
||||
const pv = wasm.peekPtr(this.ptr);
|
||||
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
|
||||
}.bind(Object.create(null));
|
||||
if( true ){ /* changeset/preupdate additions... */
|
||||
/**
|
||||
Internal impl of sqlite3_preupdate_new/old_js() and
|
||||
sqlite3changeset_new/old_js().
|
||||
*/
|
||||
const __newOldValue = function(pObj, iCol, impl){
|
||||
impl = capi[impl];
|
||||
if(!this.ptr) this.ptr = wasm.allocPtr();
|
||||
else wasm.pokePtr(this.ptr, 0);
|
||||
const rc = impl(pObj, iCol, this.ptr);
|
||||
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
|
||||
const pv = wasm.peekPtr(this.ptr);
|
||||
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
|
||||
}.bind(Object.create(null));
|
||||
|
||||
/**
|
||||
A wrapper around sqlite3_preupdate_new() which fetches the
|
||||
sqlite3_value at the given index and returns the result of
|
||||
passing it to sqlite3_value_to_js(). Throws on error.
|
||||
*/
|
||||
capi.sqlite3_preupdate_new_js =
|
||||
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
|
||||
/**
|
||||
A wrapper around sqlite3_preupdate_new() which fetches the
|
||||
sqlite3_value at the given index and returns the result of
|
||||
passing it to sqlite3_value_to_js(). Throws on error.
|
||||
*/
|
||||
capi.sqlite3_preupdate_new_js =
|
||||
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
|
||||
|
||||
/**
|
||||
The sqlite3_preupdate_old() counterpart of
|
||||
sqlite3_preupdate_new_js(), with an identical interface.
|
||||
*/
|
||||
capi.sqlite3_preupdate_old_js =
|
||||
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
|
||||
/**
|
||||
The sqlite3_preupdate_old() counterpart of
|
||||
sqlite3_preupdate_new_js(), with an identical interface.
|
||||
*/
|
||||
capi.sqlite3_preupdate_old_js =
|
||||
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
|
||||
|
||||
/**
|
||||
A wrapper around sqlite3changeset_new() which fetches the
|
||||
sqlite3_value at the given index and returns the result of
|
||||
passing it to sqlite3_value_to_js(). Throws on error.
|
||||
/**
|
||||
A wrapper around sqlite3changeset_new() which fetches the
|
||||
sqlite3_value at the given index and returns the result of
|
||||
passing it to sqlite3_value_to_js(). Throws on error.
|
||||
|
||||
If sqlite3changeset_new() succeeds but has no value to report,
|
||||
this function returns the undefined value, noting that undefined
|
||||
is a valid conversion from an `sqlite3_value`, so is unambiguous.
|
||||
*/
|
||||
capi.sqlite3changeset_new_js =
|
||||
(pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
|
||||
'sqlite3changeset_new');
|
||||
If sqlite3changeset_new() succeeds but has no value to report,
|
||||
this function returns the undefined value, noting that
|
||||
undefined is not a valid conversion from an `sqlite3_value`, so
|
||||
is unambiguous.
|
||||
*/
|
||||
capi.sqlite3changeset_new_js =
|
||||
(pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
|
||||
'sqlite3changeset_new');
|
||||
|
||||
/**
|
||||
The sqlite3changeset_old() counterpart of
|
||||
sqlite3changeset_new_js(), with an identical interface.
|
||||
*/
|
||||
capi.sqlite3changeset_old_js =
|
||||
(pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
|
||||
'sqlite3changeset_old');
|
||||
/**
|
||||
The sqlite3changeset_old() counterpart of
|
||||
sqlite3changeset_new_js(), with an identical interface.
|
||||
*/
|
||||
capi.sqlite3changeset_old_js =
|
||||
(pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
|
||||
'sqlite3changeset_old');
|
||||
}/*changeset/preupdate additions*/
|
||||
|
||||
/* The remainder of the API will be set up in later steps. */
|
||||
const sqlite3 = {
|
||||
@@ -2013,10 +2023,10 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
config,
|
||||
/**
|
||||
Holds the version info of the sqlite3 source tree from which
|
||||
the generated sqlite3-api.js gets built. Note that its version
|
||||
may well differ from that reported by sqlite3_libversion(), but
|
||||
that should be considered a source file mismatch, as the JS and
|
||||
WASM files are intended to be built and distributed together.
|
||||
the generated sqlite3-api.js gets built. Its version may well
|
||||
differ from that reported by sqlite3_libversion(), but that
|
||||
should be considered a source file mismatch, as the JS and WASM
|
||||
files are intended to be built and distributed together.
|
||||
|
||||
This object is initially a placeholder which gets replaced by a
|
||||
build-generated object.
|
||||
@@ -2041,9 +2051,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
async init will be fatal to the init as a whole, but init
|
||||
routines are themselves welcome to install dummy catch()
|
||||
handlers which are not fatal if their failure should be
|
||||
considered non-fatal. If called more than once, the second and
|
||||
subsequent calls are no-ops which return a pre-resolved
|
||||
Promise.
|
||||
considered non-fatal.
|
||||
|
||||
Ideally this function is called as part of the Promise chain
|
||||
which handles the loading and bootstrapping of the API. If not
|
||||
@@ -2060,18 +2068,14 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
*/
|
||||
asyncPostInit: async function ff(){
|
||||
if(ff.isReady instanceof Promise) return ff.isReady;
|
||||
let lia = sqlite3ApiBootstrap.initializersAsync;
|
||||
delete sqlite3ApiBootstrap.initializersAsync;
|
||||
let lia = this.initializersAsync;
|
||||
delete this.initializersAsync;
|
||||
const postInit = async ()=>{
|
||||
if(!sqlite3.__isUnderTest){
|
||||
/* Delete references to internal-only APIs which are used by
|
||||
some initializers. Retain them when running in test mode
|
||||
so that we can add tests for them. */
|
||||
delete sqlite3.util;
|
||||
/* It's conceivable that we might want to expose
|
||||
StructBinder to client-side code, but it's only useful if
|
||||
clients build their own sqlite3.wasm which contains their
|
||||
own C struct types. */
|
||||
delete sqlite3.StructBinder;
|
||||
}
|
||||
return sqlite3;
|
||||
@@ -2090,7 +2094,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
let p = Promise.resolve(sqlite3);
|
||||
while(lia.length) p = p.then(lia.shift());
|
||||
return ff.isReady = p.catch(catcher);
|
||||
},
|
||||
}.bind(sqlite3ApiBootstrap),
|
||||
/**
|
||||
scriptInfo ideally gets injected into this object by the
|
||||
infrastructure which assembles the JS/WASM module. It contains
|
||||
@@ -2117,16 +2121,37 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
}
|
||||
delete sqlite3ApiBootstrap.initializers;
|
||||
sqlite3ApiBootstrap.sqlite3 = sqlite3;
|
||||
delete globalThis.sqlite3ApiBootstrap;
|
||||
delete globalThis.sqlite3ApiConfig;
|
||||
sqlite3InitScriptInfo.debugModule(
|
||||
"sqlite3ApiBootstrap() complete", sqlite3
|
||||
);
|
||||
sqlite3.scriptInfo /* used by some async init code */ =
|
||||
sqlite3InitScriptInfo /* from post-js-header.js */;
|
||||
if( (sqlite3.__isUnderTest = sqlite3IsUnderTest /* from post-js-header.js */) ){
|
||||
sqlite3.config.emscripten = EmscriptenModule;
|
||||
const iw = sqlite3InitScriptInfo.instantiateWasm;
|
||||
if( 'undefined'!==typeof sqlite3InitScriptInfo/* from post-js-header.js */ ){
|
||||
sqlite3InitScriptInfo.debugModule(
|
||||
"sqlite3ApiBootstrap() complete", sqlite3
|
||||
);
|
||||
sqlite3.scriptInfo
|
||||
/* Used by some async init code. As of 2025-11-15 this is still
|
||||
in use by the OPFS VFS for locating its worker. In non-Emscripten
|
||||
builds, this would need to be injected in somewhere to get
|
||||
that VFS loading. */ = sqlite3InitScriptInfo;
|
||||
}
|
||||
sqlite3.__isUnderTest =
|
||||
('undefined'===typeof sqlite3IsUnderTest /* from post-js-header.js */)
|
||||
? false : !!sqlite3IsUnderTest;
|
||||
if( sqlite3.__isUnderTest ){
|
||||
if( 'undefined'!==typeof EmscriptenModule ){
|
||||
sqlite3.config.emscripten = EmscriptenModule;
|
||||
}
|
||||
/*
|
||||
The problem with exposing these pieces (in non-testing runs) via
|
||||
sqlite3.wasm is that it exposes non-SQLite pieces to the
|
||||
clients, who may come to expect it to remain. _We_ only have
|
||||
these data because we've overridden Emscripten's wasm file
|
||||
loader, and if we lose that capability for some reason then
|
||||
we'll lose access to this metadata.
|
||||
|
||||
These data are interesting for exploring how the wasm/JS
|
||||
pieces connect, e.g. for exploring exactly what Emscripten
|
||||
imports into WASM from its JS glue, but it's not
|
||||
SQLite-related.
|
||||
*/
|
||||
const iw = sqlite3.scriptInfo?.instantiateWasm;
|
||||
if( iw ){
|
||||
/* Metadata injected by the custom Module.instantiateWasm()
|
||||
in pre-js.c-pp.js. */
|
||||
@@ -2135,6 +2160,15 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|
||||
sqlite3.wasm.imports = iw.imports;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Eliminate any confusion about whether these config objects may
|
||||
be used after library initialization by eliminating the outward-facing
|
||||
objects...
|
||||
*/
|
||||
delete globalThis.sqlite3ApiConfig;
|
||||
delete globalThis.sqlite3ApiBootstrap;
|
||||
delete sqlite3ApiBootstrap.defaultConfig;
|
||||
return sqlite3.asyncPostInit().then((s)=>{
|
||||
sqlite3InitScriptInfo.debugModule(
|
||||
"sqlite3.asyncPostInit() complete", sqlite3
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
asynchronous Origin-Private FileSystem (OPFS) APIs using a second
|
||||
Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
|
||||
intended to be appended to the main sqlite3 JS deliverable somewhere
|
||||
after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js.
|
||||
after sqlite3-api-oo1.js.
|
||||
*/
|
||||
'use strict';
|
||||
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
@@ -1441,7 +1441,7 @@ installOpfsVfs.defaultProxyUri =
|
||||
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
||||
try{
|
||||
let proxyJs = installOpfsVfs.defaultProxyUri;
|
||||
if(sqlite3.scriptInfo.sqlite3Dir){
|
||||
if( sqlite3?.scriptInfo?.sqlite3Dir ){
|
||||
installOpfsVfs.defaultProxyUri =
|
||||
sqlite3.scriptInfo.sqlite3Dir + proxyJs;
|
||||
//sqlite3.config.warn("installOpfsVfs.defaultProxyUri =",installOpfsVfs.defaultProxyUri);
|
||||
|
||||
@@ -136,8 +136,8 @@
|
||||
/*
|
||||
** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE
|
||||
** macros. This will, when using the canonical makefile, also elide
|
||||
** any C functions from the WASM exports which are listed in
|
||||
** ./EXPORT_FUNCTIONS.sqlite3-extras.
|
||||
** any C functions from the WASM exports: see
|
||||
** ./EXPORTED_FUNCTIONS.c-pp.
|
||||
*/
|
||||
#ifdef SQLITE_WASM_BARE_BONES
|
||||
# undef SQLITE_ENABLE_COLUMN_METADATA
|
||||
@@ -326,7 +326,7 @@ SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){
|
||||
*/
|
||||
SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){
|
||||
assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos);
|
||||
assert(0==((unsigned long long)p & 0x7));
|
||||
assert(0==((unsigned long long)p & 0x7) /* 8-byte aligned */);
|
||||
if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){
|
||||
PStack.pPos = p;
|
||||
}
|
||||
|
||||
+53
-16
@@ -270,9 +270,10 @@ static void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...);
|
||||
/*
|
||||
** Opens the given file and processes its contents as c-pp, sending
|
||||
** all output to the global c-pp output channel. Fails fatally on
|
||||
** error.
|
||||
** error. If bRaw is true then the file's contents are passed through
|
||||
** verbatim, rather than being preprocessed.
|
||||
*/
|
||||
static void cmpp_process_file(const char * zName);
|
||||
static void cmpp_process_file(const char * zName, int bRaw);
|
||||
|
||||
/*
|
||||
** Operator policy for cmpp_kvp_parse().
|
||||
@@ -970,7 +971,6 @@ void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...){
|
||||
char * z = 0;
|
||||
int n = 0;
|
||||
va_list va;
|
||||
if(!str) fatal("sqlite3_str_new() failed");
|
||||
va_start(va, zSql);
|
||||
sqlite3_str_vappendf(str, zSql, va);
|
||||
va_end(va);
|
||||
@@ -2213,12 +2213,23 @@ static void cmpp_kwd_endif(CmppKeyword const * pKw, CmppTokenizer *t){
|
||||
static void cmpp_kwd_include(CmppKeyword const * pKw, CmppTokenizer *t){
|
||||
char const * zFile;
|
||||
char * zResolved;
|
||||
int bRaw = 0 /* -raw flag */;
|
||||
if(CT_skip(t)) return;
|
||||
else if(t->args.argc!=2){
|
||||
cmpp_kwd__err(pKw, t, "Expecting exactly 1 filename argument");
|
||||
else if(t->args.argc<2 || t->args.argc>3){
|
||||
cmpp_kwd__err(pKw, t, "Expected args: ?-raw? filename");
|
||||
}
|
||||
zFile = (const char *)t->args.argv[1];
|
||||
if(db_including_has(zFile)){
|
||||
if(t->args.argc==2){
|
||||
zFile = (const char *)t->args.argv[1];
|
||||
}else{
|
||||
if( 0==strcmp("-raw", (char*)t->args.argv[1]) ){
|
||||
bRaw = 1;
|
||||
}else{
|
||||
cmpp_kwd__err(pKw, t, "Unhandled argument: %s",
|
||||
t->args.argv[1]);
|
||||
}
|
||||
zFile = (const char *)t->args.argv[2];
|
||||
}
|
||||
if(!bRaw && db_including_has(zFile)){
|
||||
/* Note that different spellings of the same filename
|
||||
** will elude this check, but that seems okay, as different
|
||||
** spellings means that we're not re-running the exact same
|
||||
@@ -2229,16 +2240,15 @@ static void cmpp_kwd_include(CmppKeyword const * pKw, CmppTokenizer *t){
|
||||
}
|
||||
zResolved = db_include_search(zFile);
|
||||
if(zResolved){
|
||||
db_including_add(zFile, t->zName, t->token.lineNo);
|
||||
cmpp_process_file(zResolved);
|
||||
db_include_rm(zFile);
|
||||
if( bRaw ) db_including_add(zFile, t->zName, t->token.lineNo);
|
||||
cmpp_process_file(zResolved, bRaw);
|
||||
if( bRaw ) db_include_rm(zFile);
|
||||
db_free(zResolved);
|
||||
}else{
|
||||
cmpp_t__err(t, "file not found: %s", zFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cmpp_dump_defines( FILE * fp, int bIndent ){
|
||||
sqlite3_stmt * const q = g_stmt(GStmt_defSelAll);
|
||||
while( SQLITE_ROW==sqlite3_step(q) ){
|
||||
@@ -2392,7 +2402,7 @@ CmppKeyword aKeywords[] = {
|
||||
{S(Endif), 0, TT_Endif, cmpp_kwd_endif},
|
||||
{S(Error), 0, TT_Error, cmpp_kwd_error},
|
||||
{S(If), 1, TT_If, cmpp_kwd_if},
|
||||
{S(Include), 0, TT_Include, cmpp_kwd_include},
|
||||
{S(Include), 1, TT_Include, cmpp_kwd_include},
|
||||
{S(Pragma), 1, TT_Pragma, cmpp_kwd_pragma},
|
||||
{S(Savepoint), 1, TT_Savepoint, cmpp_kwd_savepoint},
|
||||
{S(Stderr), 0, TT_Stderr, cmpp_kwd_stderr},
|
||||
@@ -2444,14 +2454,25 @@ void cmpp_process_string(const char * zName,
|
||||
g.tok = oldTok;
|
||||
}
|
||||
|
||||
void cmpp_process_file(const char * zName){
|
||||
void cmpp_process_file(const char * zName, int bRaw){
|
||||
FileWrapper fw = FileWrapper_empty;
|
||||
FileWrapper_open(&fw, zName, "r");
|
||||
g_FileWrapper_link(&fw);
|
||||
FileWrapper_slurp(&fw);
|
||||
g_debug(1,("Read %u byte(s) from [%s]\n", fw.nContent, fw.zName));
|
||||
if( fw.zContent ){
|
||||
cmpp_process_string(zName, fw.zContent, fw.nContent);
|
||||
if( bRaw ){
|
||||
FileWrapper fw = FileWrapper_empty;
|
||||
FileWrapper_open(&fw, zName, "rb");
|
||||
g_FileWrapper_link(&fw);
|
||||
FileWrapper_slurp(&fw);
|
||||
if( 1!=fwrite(fw.zContent, fw.nContent, 1, g.out.pFile) ){
|
||||
fatal("fwrite() failed with errno %d\n", errno);
|
||||
}
|
||||
g_FileWrapper_close(&fw);
|
||||
}else{
|
||||
cmpp_process_string(zName, fw.zContent, fw.nContent);
|
||||
}
|
||||
}
|
||||
g_FileWrapper_close(&fw);
|
||||
}
|
||||
@@ -2580,6 +2601,21 @@ static int arg_is_flag( char const *zFlag, char const *zArg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void define_argv(int argc, char const * const * argv){
|
||||
sqlite3_str * const s = sqlite3_str_new(g.db);
|
||||
sqlite3_str_append(s, "c-pp::ARGV=", 11);
|
||||
for( int i = 0; i < argc; ++i ){
|
||||
if( i ) sqlite3_str_appendchar(s, 1, ' ');
|
||||
sqlite3_str_appendf(s, "%s", argv[i]);
|
||||
}
|
||||
char * const z = sqlite3_str_finish(s);
|
||||
assert(z);
|
||||
if(z){
|
||||
db_define_add(z, NULL);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char const * const * argv){
|
||||
int rc = 0;
|
||||
int inclCount = 0;
|
||||
@@ -2617,6 +2653,7 @@ int main(int argc, char const * const * argv){
|
||||
g.sqlTrace.expandSql = expandMode;
|
||||
}
|
||||
cmpp_initdb();
|
||||
define_argv(argc, argv);
|
||||
}
|
||||
for(int i = 1; i < argc; ++i){
|
||||
int negate = 0;
|
||||
@@ -2674,7 +2711,7 @@ int main(int argc, char const * const * argv){
|
||||
DOIT {
|
||||
++nFile;
|
||||
g_out_open;
|
||||
cmpp_process_file(zVal);
|
||||
cmpp_process_file(zVal, 0);
|
||||
}
|
||||
}
|
||||
ISFLAG("e"){
|
||||
@@ -2757,7 +2794,7 @@ int main(int argc, char const * const * argv){
|
||||
++inclCount;
|
||||
}
|
||||
FileWrapper_open(&g.out, g.out.zName, "w");
|
||||
cmpp_process_file("-");
|
||||
cmpp_process_file("-", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,6 +227,14 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
all args with a space between each. */
|
||||
const toss = (...args)=>{throw new Error(args.join(' '))};
|
||||
|
||||
if( !target.pointerSize && !target.pointerIR
|
||||
&& target.alloc && target.dealloc ){
|
||||
/* Try to determine the pointer size by allocating. */
|
||||
const ptr = target.alloc(1);
|
||||
target.pointerSize = ('bigint'===typeof ptr ? 8 : 4);
|
||||
target.dealloc(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
As of 2025-09-21, this library works with 64-bit WASM modules
|
||||
built with Emscripten's -sMEMORY64=1.
|
||||
@@ -659,12 +667,14 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
const ft = target.functionTable();
|
||||
const oldLen = __asPtrType(ft.length);
|
||||
let ptr;
|
||||
while(cache.freeFuncIndexes.length){
|
||||
ptr = cache.freeFuncIndexes.pop();
|
||||
if(ft.get(ptr)){ /* Table was modified via a different API */
|
||||
while( (ptr = cache.freeFuncIndexes.pop()) ){
|
||||
if(ft.get(ptr)){
|
||||
/* freeFuncIndexes's entry is stale. Table was modified via a
|
||||
different API */
|
||||
ptr = null;
|
||||
continue;
|
||||
}else{
|
||||
/* This index is free. We'll re-use it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -755,10 +765,9 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
has no side effects and returns undefined.
|
||||
*/
|
||||
target.uninstallFunction = function(ptr){
|
||||
if(!ptr && 0!==ptr) return undefined;
|
||||
const fi = cache.freeFuncIndexes;
|
||||
if(!ptr && __NullPtr!==ptr) return undefined;
|
||||
const ft = target.functionTable();
|
||||
fi.push(ptr);
|
||||
cache.freeFuncIndexes.push(ptr);
|
||||
const rc = ft.get(ptr);
|
||||
ft.set(ptr, null);
|
||||
return rc;
|
||||
@@ -996,12 +1005,12 @@ globalThis.WhWasmUtilInstaller = function(target){
|
||||
target.heap8u().
|
||||
*/
|
||||
target.cstrlen = function(ptr){
|
||||
if(!ptr || !target.isPtr(ptr)) return null;
|
||||
if(!ptr || !target.isPtr/*64*/(ptr)) return null;
|
||||
ptr = Number(ptr) /*tag:64bit*/;
|
||||
const h = heapWrappers().HEAP8U;
|
||||
let pos = ptr;
|
||||
for( ; h[pos] !== 0; ++pos ){}
|
||||
return Number(pos - ptr);
|
||||
return pos - ptr;
|
||||
};
|
||||
|
||||
/** Internal helper to use in operations which need to distinguish
|
||||
|
||||
+365
-96
@@ -32,7 +32,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
|
||||
if(!(config.heap instanceof WebAssembly.Memory)
|
||||
&& !(config.heap instanceof Function)){
|
||||
toss("config.heap must be WebAssembly.Memory instance or a function.");
|
||||
toss("config.heap must be WebAssembly.Memory instance or a function which returns one.");
|
||||
}
|
||||
['alloc','dealloc'].forEach(function(k){
|
||||
(config[k] instanceof Function) ||
|
||||
@@ -48,14 +48,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
memberSuffix = (config.memberSuffix || ""),
|
||||
BigInt = globalThis['BigInt'],
|
||||
BigInt64Array = globalThis['BigInt64Array'],
|
||||
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array,
|
||||
ptrIR = config.pointerIR
|
||||
|| config.ptrIR/*deprecated*/
|
||||
|| 'i32',
|
||||
/* Undocumented (on purpose) config options: */
|
||||
ptrSize = config.ptrSize/*deprecated*/
|
||||
|| ('i32'===ptrIR ? 4 : 8)
|
||||
;
|
||||
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array;
|
||||
|
||||
//console.warn("config",config);
|
||||
let ptr = alloc(1);
|
||||
const ptrIR = config.pointerIR
|
||||
|| config.ptrIR/*deprecated*/
|
||||
|| ('bigint'===typeof ptr ? 'i64' : 'i32');
|
||||
/* Undocumented (on purpose) config options: */
|
||||
const ptrSize = config.ptrSize/*deprecated*/
|
||||
|| ('i32'===ptrIR ? 4 : 8);
|
||||
dealloc(ptr);
|
||||
ptr = undefined;
|
||||
//console.warn("ptrIR =",ptrIR,"ptrSize =",ptrSize);
|
||||
|
||||
if(ptrIR!=='i32' && ptrIR!=='i64') toss("Invalid pointer representation:",ptrIR);
|
||||
if(ptrSize!==4 && ptrSize!==8) toss("Invalid pointer size:",ptrSize);
|
||||
@@ -136,11 +141,11 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
/** True if SIG s looks like a function signature, else
|
||||
false. */
|
||||
const isFuncSig = (s)=>'('===s[1];
|
||||
/** True if SIG s is-a pointer signature. */
|
||||
const isPtrSig = (s)=>'p'===s || 'P'===s;
|
||||
/** True if SIG s is-a pointer-type signature. */
|
||||
const isPtrSig = (s)=>'p'===s || 'P'===s || 's'===s;
|
||||
const isAutoPtrSig = (s)=>'P'===s /*EXPERIMENTAL*/;
|
||||
/** Returns p if SIG s is a function SIG, else returns s[0]. */
|
||||
const sigLetter = (s)=>isFuncSig(s) ? 'p' : s[0];
|
||||
const sigLetter = (s)=>s ? (isFuncSig(s) ? 'p' : s[0]) : undefined;
|
||||
/** Returns the WASM IR form of the Emscripten-conventional letter
|
||||
at SIG s[0]. Throws for an unknown SIG. */
|
||||
const sigIR = function(s){
|
||||
@@ -154,6 +159,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
}
|
||||
toss("Unhandled signature IR:",s);
|
||||
};
|
||||
/** Returns the WASM sizeof of the Emscripten-conventional letter
|
||||
at SIG s[0]. Throws for an unknown SIG. */
|
||||
const sigSize = function(s){
|
||||
switch(sigLetter(s)){
|
||||
case 'c': case 'C': return 1;
|
||||
case 'i': return 4;
|
||||
case 'p': case 'P': case 's': return ptrSize;
|
||||
case 'j': return 8;
|
||||
case 'f': return 4;
|
||||
case 'd': return 8;
|
||||
}
|
||||
toss("Unhandled signature sizeof:",s);
|
||||
};
|
||||
|
||||
const affirmBigIntArray = BigInt64Array
|
||||
? ()=>true : ()=>toss('BigInt64Array is not available.');
|
||||
@@ -232,11 +250,22 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
accessible via boundObject.pointer, which is gated behind a
|
||||
property interceptor, but are not exposed anywhere else in the
|
||||
object.
|
||||
|
||||
This approach means we cannot proxy arrays, or any type which
|
||||
might be realloced, as that pointer could change out from under
|
||||
us. That's not an issue for nested structs, but it might be for a
|
||||
struct they're embedded in. In the case of nested structs we
|
||||
"could" record their top-most parent object and their offset into
|
||||
that object, instead of storing the pointer itself. We could that
|
||||
by allowing a function instead of a pointer in this map, that
|
||||
function returning the (lazily-calculated) address. Hmm.
|
||||
*/
|
||||
const __instancePointerMap = new WeakMap();
|
||||
|
||||
const getInstancePtr = (obj)=>__instancePointerMap.get(obj);
|
||||
|
||||
/** Property name for the pointer-is-external marker. */
|
||||
const xPtrPropName = '(pointer-is-external)';
|
||||
const xPtrPropName = Symbol('(pointer-is-external)');
|
||||
|
||||
const __isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
|
||||
const __isPtr64 = (ptr)=>(
|
||||
@@ -252,7 +281,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
/** Frees the obj.pointer memory and clears the pointer
|
||||
property. */
|
||||
const __freeStruct = function(ctor, obj, m){
|
||||
if(!m) m = __instancePointerMap.get(obj);
|
||||
if(!m) m = getInstancePtr(obj);
|
||||
if(m) {
|
||||
__instancePointerMap.delete(obj);
|
||||
if(Array.isArray(obj.ondispose)){
|
||||
@@ -283,7 +312,12 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
ctor.structName,"instance:",
|
||||
ctor.structInfo.sizeof,"bytes @"+m);
|
||||
}
|
||||
if(!obj[xPtrPropName]) dealloc(m);
|
||||
if(!obj[xPtrPropName]){
|
||||
if( ctor.structInfo.zeroOnFree ){
|
||||
heap().fill(0, Number(m), Number(m)+ctor.structInfo.sizeof);
|
||||
}
|
||||
dealloc(m);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -324,8 +358,69 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
: null;
|
||||
};
|
||||
|
||||
/** True if sig looks like an emscripten/jaccwabyt
|
||||
type signature, else false. */
|
||||
const looksLikeASig = function f(sig){
|
||||
f.rxSig1 ??= /^[ipPsjfdcC]$/;
|
||||
f.rxSig2 ??= /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
|
||||
return f.rxSig1.test(sig) || f.rxSig2.test(sig);
|
||||
};
|
||||
|
||||
/** Returns a pair of adaptor maps (objects) in a length-3
|
||||
array specific to the given object. */
|
||||
const __adaptorsFor = function(who){
|
||||
let x = this.get(who);
|
||||
if( !x ){
|
||||
x = [ Object.create(null), Object.create(null), Object.create(null) ];
|
||||
this.set(who, x);
|
||||
}
|
||||
return x;
|
||||
}.bind(new WeakMap);
|
||||
|
||||
/** Code de-duplifier for __adaptGet(), __adaptSet(), and
|
||||
__adaptStruct(). */
|
||||
const __adaptor = function(who, which, key, proxy){
|
||||
const a = __adaptorsFor(who)[which];
|
||||
if(3===arguments.length) return a[key];
|
||||
if( proxy ) return a[key] = proxy;
|
||||
return delete a[key];
|
||||
};
|
||||
|
||||
const noopAdapter = (x)=>x;
|
||||
|
||||
// StructBinder::adaptGet()
|
||||
const __adaptGet = function(key, ...args){
|
||||
/*if( looksLikeASig(key) ){
|
||||
toss("Getter adaptor's name (",key,") collides with a data type signature.");
|
||||
}*/
|
||||
return __adaptor(this, 0, key, ...args);
|
||||
};
|
||||
|
||||
// StructBinder::adaptSet()
|
||||
const __adaptSet = function(key, ...args){
|
||||
if( looksLikeASig(key) ){
|
||||
toss("Setter adaptor's name (",key,") collides with a data type signature.");
|
||||
}
|
||||
return __adaptor(this, 1, key, ...args);
|
||||
};
|
||||
|
||||
// StructBinder::adaptStruct()
|
||||
const __adaptStruct = function(key, ...args){
|
||||
return __adaptor(this, 2, key, ...args);
|
||||
};
|
||||
|
||||
const __adaptStruct2 = function(who,key){
|
||||
const si = ('string'===typeof key)
|
||||
? __adaptor(who, 2, key) : key;
|
||||
if( 'object'!==typeof si ){
|
||||
toss("Invalid struct mapping object. Arg =",key,JSON.stringify(si));
|
||||
}
|
||||
return si;
|
||||
};
|
||||
|
||||
const __memberKey = (k)=>memberPrefix + k + memberSuffix;
|
||||
const __memberKeyProp = rop(__memberKey);
|
||||
//const __adaptGetProp = rop(__adaptGet);
|
||||
|
||||
/**
|
||||
Looks up a struct member in structInfo.members. Throws if found
|
||||
@@ -342,7 +437,8 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
if(v.key===memberName){ m = v; break; }
|
||||
}
|
||||
if(!m && tossIfNotFound){
|
||||
toss(sPropName(structInfo.name,memberName),'is not a mapped struct member.');
|
||||
toss(sPropName(structInfo.name || structInfo.structName, memberName),
|
||||
'is not a mapped struct member.');
|
||||
}
|
||||
}
|
||||
return m;
|
||||
@@ -361,7 +457,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
|
||||
const __ptrPropDescriptor = {
|
||||
configurable: false, enumerable: false,
|
||||
get: function(){return __instancePointerMap.get(this)},
|
||||
get: function(){return getInstancePtr(this)},
|
||||
set: ()=>toss("Cannot assign the 'pointer' property of a struct.")
|
||||
// Reminder: leaving `set` undefined makes assignments
|
||||
// to the property _silently_ do nothing. Current unit tests
|
||||
@@ -558,78 +654,176 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
});
|
||||
|
||||
/**
|
||||
Pass this a StructBinder-generated prototype, and the struct
|
||||
member description object. It will define property accessors for
|
||||
proto[memberKey] which read from/write to memory in
|
||||
this.pointer. It modifies descr to make certain downstream
|
||||
operations much simpler.
|
||||
If struct description object si has a getter proxy, return it (a
|
||||
function), else return undefined.
|
||||
*/
|
||||
const makeMemberWrapper = function f(ctor,name, descr){
|
||||
const memberGetterProxy = function(si){
|
||||
return si.get || (si.adaptGet
|
||||
? StructBinder.adaptGet(si.adaptGet)
|
||||
: undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
If struct description object si has a setter proxy, return it (a
|
||||
function), else return undefined.
|
||||
*/
|
||||
const memberSetterProxy = function(si){
|
||||
return si.set || (si.adaptSet
|
||||
? StructBinder.adaptSet(si.adaptSet)
|
||||
: undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
To be called by makeMemberWrapper() when si has a 'members'
|
||||
member, i.e. is an embedded struct. This function sets up that
|
||||
struct like any other and also sets up property accessor for
|
||||
ctor.memberKey(name) which returns an instance of that new
|
||||
StructType when the member is accessed. That instance wraps the
|
||||
memory of the member's part of the containing C struct instance.
|
||||
|
||||
That is, if struct Foo has member bar which is an inner struct
|
||||
then:
|
||||
|
||||
const f = new Foo;
|
||||
const b = f.bar;
|
||||
assert( b is-a StructType object );
|
||||
assert( b.pointer === f.b.pointer );
|
||||
|
||||
b will be disposed of when f() is. Calling b.dispose() will not
|
||||
do any permanent harm, as the wrapper object will be recreated
|
||||
when accessing f.bar, pointing to the same memory in f.
|
||||
|
||||
The si.zeroOnFree flag has no effect on embedded structs because
|
||||
they wrap "external" memory, so do not own it, and are thus never
|
||||
freed, as such.
|
||||
*/
|
||||
const makeMemberStructWrapper = function callee(ctor, name, si){
|
||||
/**
|
||||
Where we store inner-struct member proxies. Keys are a
|
||||
combination of the parent object's pointer address and the
|
||||
property's name. The values are StructType instances.
|
||||
*/
|
||||
const __innerStructs = (callee.innerStructs ??= new Map());
|
||||
const key = ctor.memberKey(name);
|
||||
if( undefined!==si.signature ){
|
||||
toss("'signature' cannot be used on an embedded struct (",
|
||||
ctor.structName,".",key,").");
|
||||
}
|
||||
if( memberSetterProxy(si) ){
|
||||
toss("'set' and 'adaptSet' are not permitted for nested struct members.");
|
||||
}
|
||||
//console.warn("si =",ctor.structName, name, JSON.stringify(si,' '));
|
||||
si.structName ??= ctor.structName+'::'+name;
|
||||
si.key = key;
|
||||
si.name = name;
|
||||
si.constructor = this.call(this, si.structName, si);
|
||||
//console.warn("si.constructor =",si.constructor);
|
||||
//console.warn("si =",si,"ctor=",ctor);
|
||||
const getterProxy = memberGetterProxy(si);
|
||||
const prop = Object.assign(Object.create(null),{
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
set: __propThrowOnSet(ctor/*not si.constructor*/.structName, key),
|
||||
get: function(){
|
||||
const dbg = si.constructor.prototype.debugFlags.__flags;
|
||||
const p = this.pointer;
|
||||
const k = p+'.'+key;
|
||||
let s = __innerStructs.get(k);
|
||||
if(dbg.getter){ log("debug.getter: k =",k); }
|
||||
if( !s ){
|
||||
s = new si.constructor(__ptrAdd(p, si.offset));
|
||||
__innerStructs.set(k, s);
|
||||
this.addOnDispose(()=>s.dispose());
|
||||
s.addOnDispose(()=>__innerStructs.delete(k));
|
||||
//console.warn("Created",k,"proxy");
|
||||
}
|
||||
if(getterProxy) s = getterProxy.apply(this,[s,key]);
|
||||
if(dbg.getter) log("debug.getter: result =",s);
|
||||
return s;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(ctor.prototype, key, prop);
|
||||
}/*makeMemberStructWrapper()*/;
|
||||
|
||||
/**
|
||||
Pass this a StructBinderImpl-generated constructor, a member
|
||||
property name, and the struct member description object. It will
|
||||
define property accessors for proto[memberKey] which read
|
||||
from/write to memory in this.pointer. It modifies si to make
|
||||
certain downstream operations simpler.
|
||||
*/
|
||||
const makeMemberWrapper = function f(ctor, name, si){
|
||||
si = __adaptStruct2(this, si);
|
||||
if( si.members ){
|
||||
return makeMemberStructWrapper.call(this, ctor, name, si);
|
||||
}
|
||||
|
||||
if(!f._){
|
||||
/*cache all available getters/setters/set-wrappers for
|
||||
direct reuse in each accessor function. */
|
||||
/* Cache all available getters/setters/set-wrappers for
|
||||
direct reuse in each accessor function. */
|
||||
f._ = {getters: {}, setters: {}, sw:{}};
|
||||
const a = ['i','c','C','p','P','s','f','d','v()'];
|
||||
if(bigIntEnabled) a.push('j');
|
||||
a.forEach(function(v){
|
||||
//const ir = sigIR(v);
|
||||
f._.getters[v] = sigDVGetter(v) /* DataView[MethodName] values for GETTERS */;
|
||||
f._.setters[v] = sigDVSetter(v) /* DataView[MethodName] values for SETTERS */;
|
||||
f._.sw[v] = sigDVSetWrapper(v) /* BigInt or Number ctor to wrap around values
|
||||
for conversion */;
|
||||
});
|
||||
const rxSig1 = /^[ipPsjfdcC]$/,
|
||||
rxSig2 = /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
|
||||
f.sigCheck = function(obj, name, key,sig){
|
||||
if(Object.prototype.hasOwnProperty.call(obj, key)){
|
||||
toss(obj.structName,'already has a property named',key+'.');
|
||||
}
|
||||
rxSig1.test(sig) || rxSig2.test(sig)
|
||||
looksLikeASig(sig)
|
||||
|| toss("Malformed signature for",
|
||||
sPropName(obj.structName,name)+":",sig);
|
||||
};
|
||||
}
|
||||
const key = ctor.memberKey(name);
|
||||
f.sigCheck(ctor.prototype, name, key, descr.signature);
|
||||
descr.key = key;
|
||||
descr.name = name;
|
||||
const sigGlyph = sigLetter(descr.signature);
|
||||
f.sigCheck(ctor.prototype, name, key, si.signature);
|
||||
si.key = key;
|
||||
si.name = name;
|
||||
const sigGlyph = sigLetter(si.signature);
|
||||
const xPropName = sPropName(ctor.prototype.structName,key);
|
||||
const dbg = ctor.prototype.debugFlags.__flags;
|
||||
/*
|
||||
TODO?: set prototype of descr to an object which can set/fetch
|
||||
TODO?: set prototype of si to an object which can set/fetch
|
||||
its preferred representation, e.g. conversion to string or mapped
|
||||
function. Advantage: we can avoid doing that via if/else if/else
|
||||
in the get/set methods.
|
||||
*/
|
||||
const getterProxy = memberGetterProxy(si);
|
||||
const prop = Object.create(null);
|
||||
prop.configurable = false;
|
||||
prop.enumerable = false;
|
||||
prop.get = function(){
|
||||
if(dbg.getter){
|
||||
log("debug.getter:",f._.getters[sigGlyph],"for", sigIR(sigGlyph),
|
||||
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof);
|
||||
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof);
|
||||
}
|
||||
let rc = (
|
||||
new DataView(heap().buffer, Number(this.pointer) + descr.offset, descr.sizeof)
|
||||
new DataView(heap().buffer, Number(this.pointer) + si.offset, si.sizeof)
|
||||
)[f._.getters[sigGlyph]](0, isLittleEndian);
|
||||
if(getterProxy) rc = getterProxy.apply(this,[rc,key]);
|
||||
if(dbg.getter) log("debug.getter:",xPropName,"result =",rc);
|
||||
return rc;
|
||||
};
|
||||
if(descr.readOnly){
|
||||
if(si.readOnly){
|
||||
prop.set = __propThrowOnSet(ctor.prototype.structName,key);
|
||||
}else{
|
||||
const setterProxy = memberSetterProxy(si);
|
||||
prop.set = function(v){
|
||||
if(dbg.setter){
|
||||
log("debug.setter:",f._.setters[sigGlyph],"for", sigIR(sigGlyph),
|
||||
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof, v);
|
||||
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof, v);
|
||||
}
|
||||
if(!this.pointer){
|
||||
toss("Cannot set struct property on disposed instance.");
|
||||
toss("Cannot set native property on a disposed struct instance.");
|
||||
}
|
||||
if(null===v) v = __NullPtr;
|
||||
else while(!__isPtr(v)){
|
||||
if(isAutoPtrSig(descr.signature) && (v instanceof StructType)){
|
||||
if( setterProxy ) v = setterProxy.apply(this,[v]);
|
||||
if( null===v || undefined===v ) v = __NullPtr;
|
||||
else while( isPtrSig(si.signature) && !__isPtr(v) ){
|
||||
if(isAutoPtrSig(si.signature) && (v instanceof StructType)){
|
||||
// It's a struct instance: let's store its pointer value!
|
||||
v = v.pointer || __NullPtr;
|
||||
if(dbg.setter) log("debug.setter:",xPropName,"resolved to",v);
|
||||
@@ -638,66 +832,45 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
toss("Invalid value for pointer-type",xPropName+'.');
|
||||
}
|
||||
(
|
||||
new DataView(heap().buffer, Number(this.pointer) + descr.offset,
|
||||
descr.sizeof)
|
||||
new DataView(heap().buffer, Number(this.pointer) + si.offset,
|
||||
si.sizeof)
|
||||
)[f._.setters[sigGlyph]](0, f._.sw[sigGlyph](v), isLittleEndian);
|
||||
};
|
||||
}
|
||||
Object.defineProperty(ctor.prototype, key, prop);
|
||||
}/*makeMemberWrapper*/;
|
||||
}/*makeMemberWrapper()*/;
|
||||
|
||||
/**
|
||||
The main factory function which will be returned to the
|
||||
caller.
|
||||
caller. The third argument is structly for internal use.
|
||||
|
||||
This level of indirection is to avoid that clients can pass a
|
||||
third argument to this, as that's only for internal use.
|
||||
|
||||
internalOpt options:
|
||||
|
||||
- None right now. This is for potential use in recursion.
|
||||
|
||||
Usages:
|
||||
|
||||
StructBinder(string, obj [,optObj]);
|
||||
StructBinder(obj);
|
||||
*/
|
||||
const StructBinder = function StructBinder(structName, structInfo){
|
||||
if(1===arguments.length){
|
||||
structInfo = structName;
|
||||
structName = structInfo.name;
|
||||
}else if(!structInfo.name){
|
||||
structInfo.name = structName;
|
||||
}
|
||||
if(!structName) toss("Struct name is required.");
|
||||
let lastMember = false;
|
||||
Object.keys(structInfo.members).forEach((k)=>{
|
||||
// Sanity checks of sizeof/offset info...
|
||||
const m = structInfo.members[k];
|
||||
if(!m.sizeof) toss(structName,"member",k,"is missing sizeof.");
|
||||
else if(m.sizeof===1){
|
||||
(m.signature === 'c' || m.signature === 'C') ||
|
||||
toss("Unexpected sizeof==1 member",
|
||||
sPropName(structInfo.name,k),
|
||||
"with signature",m.signature);
|
||||
}else{
|
||||
// sizes and offsets of size-1 members may be odd values, but
|
||||
// others may not.
|
||||
if(0!==(m.sizeof%4)){
|
||||
console.warn("Invalid struct member description =",m,"from",structInfo);
|
||||
toss(structName,"member",k,"sizeof is not aligned. sizeof="+m.sizeof);
|
||||
}
|
||||
if(0!==(m.offset%4)){
|
||||
console.warn("Invalid struct member description =",m,"from",structInfo);
|
||||
toss(structName,"member",k,"offset is not aligned. offset="+m.offset);
|
||||
}
|
||||
}
|
||||
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
|
||||
});
|
||||
if(!lastMember) toss("No member property descriptions found.");
|
||||
else if(structInfo.sizeof < lastMember.offset+lastMember.sizeof){
|
||||
toss("Invalid struct config:",structName,
|
||||
"max member offset ("+lastMember.offset+") ",
|
||||
"extends past end of struct (sizeof="+structInfo.sizeof+").");
|
||||
}
|
||||
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
|
||||
/** Constructor for the StructCtor. */
|
||||
const zeroAsPtr = __asPtrType(0);
|
||||
const StructBinderImpl = function StructBinderImpl(
|
||||
structName, si, opt = Object.create(null)
|
||||
){
|
||||
/**
|
||||
StructCtor is the eventual return value of this function. We
|
||||
need to populate this early on so that we can do some trickery
|
||||
in feeding it through recursion.
|
||||
*/
|
||||
const StructCtor = function StructCtor(externalMemory){
|
||||
externalMemory = __asPtrType(externalMemory);
|
||||
//console.warn("externalMemory",externalMemory,arguments[0]);
|
||||
if(!(this instanceof StructCtor)){
|
||||
toss("The",structName,"constructor may only be called via 'new'.");
|
||||
}else if(arguments.length){
|
||||
if(Number.isNaN(externalMemory) || externalMemory<=zeroAsPtr){
|
||||
if( !__isPtr(externalMemory) ){
|
||||
toss("Invalid pointer value",arguments[0],"for",structName,"constructor.");
|
||||
}
|
||||
__allocStruct(StructCtor, this, externalMemory);
|
||||
@@ -705,31 +878,127 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
|
||||
__allocStruct(StructCtor, this);
|
||||
}
|
||||
};
|
||||
const self = this;
|
||||
/**
|
||||
"Convert" struct description x to a struct description, if
|
||||
needed.
|
||||
*/
|
||||
const ads = (x)=>{
|
||||
//console.warn("looksLikeASig(",x,") =",looksLikeASig(x));
|
||||
return (('string'===typeof x) && looksLikeASig(x))
|
||||
? {signature: x} : __adaptStruct2(self,x);
|
||||
};
|
||||
if(1===arguments.length){
|
||||
si = ads(structName);
|
||||
structName = si.structName || si.name;
|
||||
}else if(2===arguments.length){
|
||||
si = ads(si);
|
||||
si.name ??= structName;
|
||||
}else{
|
||||
si = ads(si);
|
||||
}
|
||||
structName ??= si.structName;
|
||||
//console.warn("arguments =",JSON.stringify(arguments));
|
||||
structName ??= opt.structName;
|
||||
if( !structName ) toss("One of 'name' or 'structName' are required.");
|
||||
if( si.adapt ){
|
||||
Object.keys(si.adapt.struct||{}).forEach((k)=>{
|
||||
__adaptStruct.call(StructBinderImpl, k, si.adapt.struct[k]);
|
||||
});
|
||||
Object.keys(si.adapt.set||{}).forEach((k)=>{
|
||||
__adaptSet.call(StructBinderImpl, k, si.adapt.set[k]);
|
||||
});
|
||||
Object.keys(si.adapt.get||{}).forEach((k)=>{
|
||||
__adaptGet.call(StructBinderImpl, k, si.adapt.get[k]);
|
||||
});
|
||||
}
|
||||
if(!si.members && !si.sizeof){
|
||||
si.sizeof = sigSize(si.signature);
|
||||
}
|
||||
|
||||
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
|
||||
Object.defineProperties(StructCtor,{
|
||||
debugFlags: debugFlags,
|
||||
isA: rop((v)=>v instanceof StructCtor),
|
||||
memberKey: __memberKeyProp,
|
||||
memberKeys: __structMemberKeys,
|
||||
methodInfoForKey: rop(function(mKey){
|
||||
}),
|
||||
structInfo: rop(structInfo),
|
||||
//methodInfoForKey: rop(function(mKey){/*???*/}),
|
||||
structInfo: rop(si),
|
||||
structName: rop(structName)
|
||||
});
|
||||
StructCtor.prototype = new StructType(structName, structInfo, rop);
|
||||
StructCtor.prototype = new StructType(structName, si, rop);
|
||||
Object.defineProperties(StructCtor.prototype,{
|
||||
debugFlags: debugFlags,
|
||||
constructor: rop(StructCtor)
|
||||
/*if we assign StructCtor.prototype and don't do
|
||||
this then StructCtor!==instance.constructor!*/
|
||||
this then StructCtor!==instance.constructor*/
|
||||
});
|
||||
Object.keys(structInfo.members).forEach(
|
||||
(name)=>makeMemberWrapper(StructCtor, name, structInfo.members[name])
|
||||
);
|
||||
|
||||
|
||||
let lastMember = false;
|
||||
let offset = 0;
|
||||
//console.warn(structName,"si =",si);
|
||||
si.offset ??= 0;
|
||||
Object.keys(si.members || {}).forEach((k)=>{
|
||||
// Sanity checks of sizeof/offset info...
|
||||
let m = ads(si.members[k]);
|
||||
if(!m.members && !m.sizeof){
|
||||
/* ^^^^ fixme: we need to recursively collect all sizeofs
|
||||
before updating that. */
|
||||
m.sizeof = sigSize(m.signature);
|
||||
if(!m.sizeof){
|
||||
toss(sPropName(structName,k), "is missing a sizeof property.",m);
|
||||
}
|
||||
}
|
||||
if( undefined===m.offset ){
|
||||
m.offset = offset;
|
||||
}
|
||||
si.members[k] = m;
|
||||
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
|
||||
makeMemberWrapper.call(self, StructCtor, k, m)
|
||||
offset += m.sizeof;
|
||||
//console.warn("offset",sPropName(structName,k),offset);
|
||||
});
|
||||
|
||||
if( !lastMember ) toss("No member property descriptions found.");
|
||||
if( !si.sizeof ) si.sizeof = offset;
|
||||
if(si.sizeof===1){
|
||||
(si.signature === 'c' || si.signature === 'C') ||
|
||||
toss("Unexpected sizeof==1 member",
|
||||
sPropName(structName,k),
|
||||
"with signature",si.signature);
|
||||
}else{
|
||||
// sizes and offsets of size-1 members may be odd values, but
|
||||
// others may not.
|
||||
if(0!==(si.sizeof%4)){
|
||||
console.warn("Invalid struct member description",si);
|
||||
toss(structName,"sizeof is not aligned. sizeof="+si.sizeof);
|
||||
}
|
||||
if(0!==(si.offset%4)){
|
||||
console.warn("Invalid struct member description",si);
|
||||
toss(structName,"offset is not aligned. offset="+si.offset);
|
||||
}
|
||||
}
|
||||
|
||||
if( si.sizeof < offset ){
|
||||
console.warn("Suspect struct description:",si,"offset =",offset);
|
||||
toss("Mismatch in the calculated vs. the provided sizeof/offset info.",
|
||||
"Expected sizeof",offset,"but got",si.sizeof,"for",si);
|
||||
}
|
||||
return StructCtor;
|
||||
}/*StructBinderImpl*/;
|
||||
|
||||
const StructBinder = function StructBinder(structName, structInfo){
|
||||
return (1==arguments.length)
|
||||
? StructBinderImpl.call(StructBinder, structName)
|
||||
: StructBinderImpl.call(StructBinder, structName, structInfo);
|
||||
};
|
||||
StructBinder.StructType = StructType;
|
||||
StructBinder.config = config;
|
||||
StructBinder.allocCString = __allocCString;
|
||||
StructBinder.adaptGet = __adaptGet;
|
||||
StructBinder.adaptSet = __adaptSet;
|
||||
StructBinder.adaptStruct = __adaptStruct;
|
||||
if(!StructBinder.debugFlags){
|
||||
StructBinder.debugFlags = SBF.__makeDebugFlags(SBF.debugFlags);
|
||||
}
|
||||
|
||||
+29
-34
@@ -71,13 +71,13 @@ enum BuildDefFlags {
|
||||
** only their JS file and patch their JS to use the WASM file from a
|
||||
** canonical build which uses that same WASM file. Reusing X.wasm
|
||||
** that way can only work for builds which are processed identically
|
||||
** by Emscripten. For a given set of C flags (as opposed to
|
||||
** by Emscripten. For a given set of C flags (as distinct from
|
||||
** JS-influencing flags), all builds of X.js and Y.js will produce
|
||||
** identical X.wasm and Y.wasm files. Their JS files may well
|
||||
** differ, however.
|
||||
*/
|
||||
CP_JS = 1 << 30,
|
||||
CP_WASM = 1 << 31,
|
||||
CP_JS = 1 << 30, /* X.js or X.mjs, depending on F_ESM */
|
||||
CP_WASM = 1 << 31, /* X,wasm */
|
||||
CP_ALL = CP_JS | CP_WASM
|
||||
};
|
||||
|
||||
@@ -94,11 +94,10 @@ enum BuildDefFlags {
|
||||
** final build directory $(dir.dout).
|
||||
**
|
||||
** To keep parallel builds from stepping on each other, each distinct
|
||||
** build goes into its own subdir $(dir.dout.BuildName)[^1], i.e.
|
||||
** $(dir.dout)/BuildName. Builds which produce deliverables we'd like
|
||||
** to keep/distribute copy their final results into the build dir
|
||||
** $(dir.dout). See the notes for the CP_JS enum entry for more
|
||||
** details on that.
|
||||
** build goes into its own subdir $(dir.dout.$(BuildDef::zBaseName).
|
||||
** Builds which produce deliverables we'd like to keep/distribute copy
|
||||
** their final results into the build dir $(dir.dout). See the notes
|
||||
** for the CP_JS enum entry for more details on that.
|
||||
**
|
||||
** The final result of each build is a pair of JS/WASM files, but
|
||||
** getting there requires generation of several files, primarily as
|
||||
@@ -116,9 +115,9 @@ enum BuildDefFlags {
|
||||
**
|
||||
** --extern-post-js = gets injected immediately after
|
||||
** sqlite3InitModule(), in the global scope. In this step we replace
|
||||
** sqlite3InitModule() with a slightly customized, the main purpose of
|
||||
** which is to (A) give us (not Emscripten) control over the arguments
|
||||
** it accepts and (B) to run the library bootstrap step.
|
||||
** sqlite3InitModule() with a slightly customized one, the main
|
||||
** purpose of which is to (A) give us (not Emscripten) control over
|
||||
** the arguments it accepts and (B) to run the library bootstrap step.
|
||||
**
|
||||
** Then there's sqlite3-api.BuildName.js, which is the entire SQLite3
|
||||
** JS API (generated from the list defined in $(sqlite3-api.jses)). It
|
||||
@@ -126,9 +125,7 @@ enum BuildDefFlags {
|
||||
**
|
||||
** Each of those inputs has to be generated before passing them on to
|
||||
** Emscripten so that any build-specific capabilities can get filtered
|
||||
** in or out (using ./c-pp.c).
|
||||
**
|
||||
** [^1]: The legal BuildNames are in this file's BuildDef_map macro.
|
||||
** in or out (using ./c-pp-lite.c).
|
||||
*/
|
||||
struct BuildDef {
|
||||
/*
|
||||
@@ -143,8 +140,8 @@ struct BuildDef {
|
||||
**
|
||||
** The convention for 32- vs 64-bit pairs is to give them similar
|
||||
** emoji, e.g. a cookie for 32-bit and a donut or cake for 64.
|
||||
** Alternately, the same emoji a "64" suffix, excep that that throws
|
||||
** off the output alignment in parallel builds ;).
|
||||
** Alternately, the same emoji a "64" suffix, except that that
|
||||
** throws off the output alignment in parallel builds ;).
|
||||
*/
|
||||
const char *zEmo;
|
||||
/*
|
||||
@@ -161,7 +158,7 @@ struct BuildDef {
|
||||
const char *zCmppD; /* Extra -D... flags for c-pp */
|
||||
const char *zEmcc; /* Full flags for emcc. Normally NULL for default. */
|
||||
const char *zEmccExtra; /* Extra flags for emcc */
|
||||
const char *zDeps; /* Extra deps */
|
||||
const char *zDeps; /* Extra make target deps */
|
||||
const char *zEnv; /* emcc -sENVIRONMENT=... value */
|
||||
/*
|
||||
** Makefile code "ifeq (...)". If set, this build is enclosed in a
|
||||
@@ -196,9 +193,8 @@ typedef struct BuildDef BuildDef;
|
||||
** The set of WASM builds for the library (as opposed to the apps
|
||||
** (fiddle, speedtest1)). Their order in BuildDefs_map is mostly
|
||||
** insignificant, but some makefile vars used by some builds are set
|
||||
** up by prior builds. Because of that, the (sqlite3, vanilla),
|
||||
** (sqlite3, esm), and (sqlite3, bundler-friendly) builds should be
|
||||
** defined first (in that order).
|
||||
** up by prior builds. Because of that, the vanilla, esm, and
|
||||
** bundler-friendly builds should be defined first (in that order).
|
||||
*/
|
||||
struct BuildDefs {
|
||||
#define E(N) BuildDef N;
|
||||
@@ -284,7 +280,7 @@ const BuildDefs oBuildDefs = {
|
||||
" -DSQLITE_SPEEDTEST1_WASM"
|
||||
" $(SQLITE_OPT)"
|
||||
" -USQLITE_WASM_BARE_BONES"
|
||||
" -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c)"
|
||||
" -USQLITE_C -DSQLITE_C=$(sqlite3.c)"
|
||||
" $(speedtest1.exit-runtime0)"
|
||||
" $(speedtest1.c.in)"
|
||||
" -lm",
|
||||
@@ -312,7 +308,7 @@ const BuildDefs oBuildDefs = {
|
||||
" -DSQLITE_SPEEDTEST1_WASM"
|
||||
" $(SQLITE_OPT)"
|
||||
" -USQLITE_WASM_BARE_BONES"
|
||||
" -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c)"
|
||||
" -USQLITE_C -DSQLITE_C=$(sqlite3.c)"
|
||||
" $(speedtest1.exit-runtime0)"
|
||||
" $(speedtest1.c.in)"
|
||||
" -lm",
|
||||
@@ -346,7 +342,6 @@ const BuildDefs oBuildDefs = {
|
||||
.zDeps = 0,
|
||||
.zIfCond = 0,
|
||||
.flags = CP_JS | F_BUNDLER_FRIENDLY | F_ESM
|
||||
//| F_NOT_IN_ALL
|
||||
},
|
||||
|
||||
/* 64-bit bundler-friendly. */
|
||||
@@ -371,7 +366,7 @@ const BuildDefs oBuildDefs = {
|
||||
.node = {
|
||||
.zEmo = "🍟",
|
||||
.zBaseName = "sqlite3-node",
|
||||
.zDotWasm = 0,
|
||||
.zDotWasm = "sqlite3",
|
||||
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
|
||||
.zEmcc = 0,
|
||||
.zEmccExtra = 0,
|
||||
@@ -382,21 +377,21 @@ const BuildDefs oBuildDefs = {
|
||||
** node. */,
|
||||
.zDeps = 0,
|
||||
.zIfCond = 0,
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS
|
||||
.flags = CP_JS | F_UNSUPPORTED | F_ESM | F_NODEJS
|
||||
},
|
||||
|
||||
/* 64-bit node. */
|
||||
.node64 = {
|
||||
.zEmo = "🍔",
|
||||
.zBaseName = "sqlite3-node-64bit",
|
||||
.zDotWasm = 0,
|
||||
.zDotWasm = "sqlite3-64bit",
|
||||
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
|
||||
.zEmcc = 0,
|
||||
.zEmccExtra = 0,
|
||||
.zEnv = "node",
|
||||
.zDeps = 0,
|
||||
.zIfCond = 0,
|
||||
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS | F_64BIT
|
||||
.flags = CP_JS | F_UNSUPPORTED | F_ESM | F_NODEJS | F_64BIT
|
||||
},
|
||||
|
||||
/* Entirely unsupported. */
|
||||
@@ -638,7 +633,7 @@ static void mk_pre_post(char const *zBuildName, BuildDef const * pB){
|
||||
pB->zDotWasm);
|
||||
}
|
||||
ps("");
|
||||
pf("\t@$(call b.c-pp.shcmd,"
|
||||
pf("\t@$(call b.mkdir@); $(call b.c-pp.shcmd,"
|
||||
"%s,"
|
||||
"$(pre-js.in.js),"
|
||||
"$(pre-js.%s.js),"
|
||||
@@ -777,13 +772,14 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
|
||||
zBuildName, zBuildName, zBaseName);
|
||||
|
||||
pf("dir.dout.%s ?= $(dir.dout)/%s\n", zBuildName, zBuildName);
|
||||
pf("out.%s.base ?= $(dir.dout.%s)/%s\n",
|
||||
zBuildName, zBuildName, zBaseName);
|
||||
|
||||
pf("c-pp.D.%s ?= %s\n", zBuildName, pB->zCmppD ? pB->zCmppD : "");
|
||||
if( pB->flags & F_64BIT ){
|
||||
pf("c-pp.D.%s += $(c-pp.D.64bit)\n", zBuildName);
|
||||
}
|
||||
if( pB->flags & F_UNSUPPORTED ){
|
||||
pf("c-pp.D.%s += -Dunsupported-build\n", zBuildName);
|
||||
}
|
||||
|
||||
pf("emcc.environment.%s ?= %s\n", zBuildName,
|
||||
pB->zEnv ? pB->zEnv : oBuildDefs.vanilla.zEnv);
|
||||
@@ -914,10 +910,9 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
|
||||
|
||||
pf("\n%dbit: $(out.%s.js)\n"
|
||||
"$(out.%s.wasm): $(out.%s.js)\n"
|
||||
"b-%s: $(out.%s.js) $(out.%s.wasm)\n",
|
||||
"b-%s: $(out.%s.wasm)\n",
|
||||
(F_64BIT & pB->flags) ? 64 : 32, zBuildName,
|
||||
zBuildName, zBuildName,
|
||||
zBuildName, zBuildName, zBuildName);
|
||||
zBuildName, zBuildName, zBuildName, zBuildName);
|
||||
|
||||
if( CP_JS & pB->flags ){
|
||||
pf("$(dir.dout)/%s%s: $(out.%s.js)\n",
|
||||
@@ -992,7 +987,7 @@ static void mk_fiddle(void){
|
||||
zBuildName, zBuildName);
|
||||
emit_compile_start(zBuildName);
|
||||
pf("\t$(b.cmd@)$(bin.emcc) -o $@"
|
||||
" $(emcc.flags.%s)" /* set in fiddle.make */
|
||||
" $(emcc.flags.%s)" /* set in GNUmakefile */
|
||||
" $(pre-post.%s.flags)"
|
||||
" $(fiddle.c.in)"
|
||||
"\n",
|
||||
|
||||
@@ -12,11 +12,19 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1 id='color-target'>sqlite3 tester #1: Worker thread (@bitness@-bit WASM)</h1>
|
||||
<div>Variants:
|
||||
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
|
||||
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
|
||||
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
|
||||
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
|
||||
<div>Variants (32-bit):
|
||||
conventional UI thread:
|
||||
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
|
||||
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
|
||||
conventional worker:
|
||||
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
|
||||
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
|
||||
ESM in UI thread:
|
||||
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
|
||||
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
|
||||
ESM worker:</a>
|
||||
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
|
||||
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
|
||||
</div>
|
||||
<div class='input-wrapper'>
|
||||
<input type='checkbox' id='cb-log-reverse'>
|
||||
|
||||
@@ -11,11 +11,19 @@
|
||||
<style></style>
|
||||
</head>
|
||||
<body><h1 id='color-target'></h1>
|
||||
<div>Variants:
|
||||
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
|
||||
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
|
||||
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
|
||||
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
|
||||
<div>Variants (32-bit):
|
||||
conventional UI thread:
|
||||
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
|
||||
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
|
||||
conventional worker:
|
||||
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
|
||||
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
|
||||
ESM in UI thread:
|
||||
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
|
||||
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
|
||||
ESM worker:</a>
|
||||
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
|
||||
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
|
||||
</div>
|
||||
<div class='input-wrapper'>
|
||||
<input type='checkbox' id='cb-log-reverse'>
|
||||
|
||||
+149
-231
@@ -369,6 +369,88 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
clearOnInit: true,
|
||||
initialCapacity: 6
|
||||
};
|
||||
|
||||
//#if enable-see
|
||||
/**
|
||||
Code consolidator for SEE sanity checks for various VFSes. ctor
|
||||
is the VFS's oo1.DB-type constructor. ctorOptFunc(bool) is a
|
||||
function which must return a constructor args object for ctor. It
|
||||
is passed true if the db needs to be cleaned up/unlinked before
|
||||
opening it (OPFS) and false if not (how that is done is
|
||||
VFS-dependent). dbUnlink is a function which is expected to
|
||||
unlink() the db file if the ctorOpfFunc does not do so when
|
||||
passed true (kvvfs).
|
||||
|
||||
This function initializes the db described by ctorOptFunc(...),
|
||||
writes some secret info into it, and re-opens it twice to
|
||||
confirmi that it can be read with an SEE key and cannot be read
|
||||
without one.
|
||||
*/
|
||||
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink){
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
try {
|
||||
if (initDb) {
|
||||
const ctoropt = ctorOptFunc(initDb);
|
||||
initDb = false;
|
||||
db = new ctor({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
db = null;
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new ctor(ctorOptFunc(false));
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
db.exec("select 1 from sqlite_schema");
|
||||
console.warn("(should not be reached) sessionStorage =", sessionStorage);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
db = null;
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
db = new ctor({
|
||||
...ctorOptFunc(false),
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
};
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
dbUnlink();
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
dbUnlink();
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
dbUnlink();
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
dbUnlink();
|
||||
},
|
||||
//#endif enable-see
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// End of infrastructure setup. Now define the tests...
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -945,7 +1027,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
let ptr = k1.pointer;
|
||||
k1.dispose();
|
||||
T.assert(undefined === k1.pointer).
|
||||
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
|
||||
mustThrowMatching(()=>{k1.$pP=1}, /disposed struct instance/);
|
||||
}finally{
|
||||
k1.dispose();
|
||||
k2.dispose();
|
||||
@@ -1549,6 +1631,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
T.assert(blob instanceof Uint8Array).
|
||||
assert(0x68===blob[0] && 0x69===blob[1]);
|
||||
blob = null;
|
||||
blob = db.selectValue("select ?1", new Uint8Array([97,0,98,0,99]),
|
||||
sqlite3.capi.SQLITE_TEXT);
|
||||
T.assert("a\0b\0c"===blob, "Something is amiss with embedded NULs");
|
||||
let counter = 0, colNames = [];
|
||||
list.length = 0;
|
||||
db.exec(new TextEncoder('utf-8').encode("SELECT a a, b b FROM t"),{
|
||||
@@ -2836,71 +2921,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
predicate: ()=>(isUIThread()
|
||||
|| "Only available in main thread."),
|
||||
test: function(sqlite3){
|
||||
this.kvvfsUnlink();
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
const ctoropt = {
|
||||
filename: this.kvvfsDbFile
|
||||
//vfs: 'kvvfs'
|
||||
//,flags: 'ct'
|
||||
};
|
||||
try {
|
||||
if (initDb) {
|
||||
initDb = false;
|
||||
db = new this.JDb({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new this.JDb(ctoropt);
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
db.exec("select 1 from sqlite_schema");
|
||||
console.warn("(should not be reached) sessionStorage =", sessionStorage);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
//console.debug('tryKey()',arguments);
|
||||
db = new sqlite3.oo1.DB({
|
||||
...ctoropt,
|
||||
vfs: 'kvvfs',
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
}.bind(this);
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
this.kvvfsUnlink();
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
this.kvvfsUnlink();
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
this.kvvfsUnlink();
|
||||
T.seeBaseCheck(sqlite3.oo1.JsStorageDb, (isInit)=>{
|
||||
return {filename: "session"};
|
||||
}, ()=>this.kvvfsUnlink());
|
||||
}
|
||||
})/*kvvfs with SEE*/
|
||||
//#endif enable-see
|
||||
@@ -3315,71 +3338,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.t({
|
||||
name: 'OPFS with SEE encryption',
|
||||
test: function(sqlite3){
|
||||
const dbFile = 'file:///sqlite3-see.edb';
|
||||
const dbCtor = sqlite3.oo1.OpfsDb;
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
const ctoropt = {
|
||||
filename: dbFile,
|
||||
flags: 'c'
|
||||
};
|
||||
try {
|
||||
if (initDb) {
|
||||
initDb = false;
|
||||
const opt = {
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
};
|
||||
opt.filename += '?delete-before-open=1';
|
||||
db = new dbCtor(opt);
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new dbCtor(ctoropt);
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
const rv = db.exec({
|
||||
sql:"select count(*) from sqlite_schema",
|
||||
returnValue: 'resultRows'
|
||||
});
|
||||
console.warn("(should not be reached) rv =",rv);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
db = new dbCtor({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
};
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
T.seeBaseCheck(
|
||||
sqlite3.oo1.OpfsDb,
|
||||
function(isInit){
|
||||
const opt = {filename: 'file:///sqlite3-see.edb'};
|
||||
if( isInit ) opt.filename += '?delete-before-open=1';
|
||||
return opt;
|
||||
},
|
||||
()=>{});
|
||||
}
|
||||
})/*OPFS with SEE*/
|
||||
//#endif enable-see
|
||||
@@ -3584,69 +3550,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
let poolUtil;
|
||||
const P1 = await inst(poolConfig).then(u=>poolUtil = u).catch(catcher);
|
||||
const dbFile = '/sqlite3-see.edb';
|
||||
const dbCtor = poolUtil.OpfsSAHPoolDb;
|
||||
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
|
||||
let initDb = true;
|
||||
const tryKey = function(keyKey, key, expectCount){
|
||||
let db;
|
||||
//console.debug('tryKey()',arguments);
|
||||
const ctoropt = {
|
||||
filename: dbFile,
|
||||
flags: 'c'
|
||||
};
|
||||
try {
|
||||
if (initDb) {
|
||||
initDb = false;
|
||||
poolUtil.unlink(dbFile);
|
||||
db = new dbCtor({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec([
|
||||
"drop table if exists t;",
|
||||
"create table t(a);"
|
||||
]);
|
||||
db.close();
|
||||
// Ensure that it's actually encrypted...
|
||||
let err;
|
||||
try {
|
||||
db = new dbCtor(ctoropt);
|
||||
T.assert(db, 'db opened') /* opening is fine, but... */;
|
||||
const rv = db.exec({
|
||||
sql:"select count(*) from sqlite_schema",
|
||||
returnValue: 'resultRows'
|
||||
});
|
||||
console.warn("(should not be reached) rv =",rv);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
} finally {
|
||||
db.close()
|
||||
}
|
||||
T.assert(err, "Expecting an exception")
|
||||
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
|
||||
"Expecting NOTADB");
|
||||
}/*initDb*/
|
||||
db = new dbCtor({
|
||||
...ctoropt,
|
||||
[keyKey]: key
|
||||
});
|
||||
db.exec("insert into t(a) values (1),(2)");
|
||||
T.assert(expectCount === db.selectValue('select sum(a) from t'));
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
};
|
||||
tryKey('textkey', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('textkey', 'foo', 6);
|
||||
initDb = true;
|
||||
tryKey('key', 'foo', 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('key', hexFoo, 6);
|
||||
initDb = true;
|
||||
tryKey('hexkey', hexFoo, 3);
|
||||
T.assert( !initDb );
|
||||
tryKey('hexkey', hexFoo, 6);
|
||||
T.seeBaseCheck(
|
||||
poolUtil.OpfsSAHPoolDb,
|
||||
(isInit)=>{return {filename: dbFile}},
|
||||
()=>poolUtil.unlink(dbFile)
|
||||
);
|
||||
poolUtil.removeVfs();
|
||||
}
|
||||
})/*opfs-sahpool with SEE*/
|
||||
@@ -3715,44 +3623,54 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.t("Misc. stmt_...", function(sqlite3){
|
||||
const db = new sqlite3.oo1.DB();
|
||||
db.exec("create table t(a doggiebiscuits); insert into t(a) values(123)");
|
||||
const stmt = db.prepare("select a, a+1 from t");
|
||||
T.assert( stmt.isReadOnly() )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
|
||||
let n = 0;
|
||||
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
|
||||
++n;
|
||||
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
|
||||
"Because stmt is busy" )
|
||||
.assert( capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( stmt.isBusy() )
|
||||
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
|
||||
.assert( true===stmt.isReadOnly() );
|
||||
const sv = capi.sqlite3_column_value(stmt, 0);
|
||||
T.assert( 123===capi.sqlite3_value_int(sv) )
|
||||
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
|
||||
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
|
||||
let stmt;
|
||||
try{
|
||||
stmt = db.prepare("select a, a+1 from t");
|
||||
T.assert( stmt.isReadOnly() )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
|
||||
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
|
||||
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
|
||||
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
|
||||
let n = 0;
|
||||
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
|
||||
++n;
|
||||
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
|
||||
"Because stmt is busy" )
|
||||
.assert( capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( stmt.isBusy() )
|
||||
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
|
||||
.assert( true===stmt.isReadOnly() );
|
||||
const sv = capi.sqlite3_column_value(stmt, 0);
|
||||
T.assert( 123===capi.sqlite3_value_int(sv) )
|
||||
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
|
||||
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
|
||||
}
|
||||
T.assert( 1===n )
|
||||
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( !stmt.isBusy() );
|
||||
|
||||
if( wasm.exports.sqlite3_column_origin_name ){
|
||||
log("Column metadata APIs enabled");
|
||||
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
|
||||
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
|
||||
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
|
||||
}else{
|
||||
log("Column metadata APIs not enabled");
|
||||
} // column metadata APIs
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
stmt = db.prepare("select ?1").bind(new Uint8Array([97,0,98,0,99]));
|
||||
stmt.step();
|
||||
const sv = capi.sqlite3_column_value(stmt,0);
|
||||
T.assert("a\0b\0c"===capi.sqlite3_value_text(sv),
|
||||
"Expecting NULs to have survived.");
|
||||
}finally{
|
||||
if(stmt) stmt.finalize();
|
||||
db.close();
|
||||
}
|
||||
T.assert( 1===n )
|
||||
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
|
||||
.assert( !stmt.isBusy() );
|
||||
|
||||
if( wasm.exports.sqlite3_column_origin_name ){
|
||||
log("Column metadata APIs enabled");
|
||||
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
|
||||
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
|
||||
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
|
||||
}else{
|
||||
log("Column metadata APIs not enabled");
|
||||
} // column metadata APIs
|
||||
|
||||
stmt.finalize();
|
||||
db.close();
|
||||
})
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -952,25 +952,6 @@ FUZZDATA = \
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
#
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
# Note that some of these will only apply when embedding sqlite3.c
|
||||
# into the shell, as these flags are not otherwise passed on to the
|
||||
# library.
|
||||
SHELL_OPT += -DSQLITE_DQS=0
|
||||
SHELL_OPT += -DSQLITE_ENABLE_FTS4
|
||||
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
|
||||
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
|
||||
FUZZERSHELL_OPT =
|
||||
FUZZCHECK_OPT += -I$(TOP)/test
|
||||
FUZZCHECK_OPT += -I$(TOP)/ext/recover
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
C Version\s3.51.1
|
||||
D 2025-11-28T17:28:25.933
|
||||
C Pervent\sthe\sparser\sstack\sfrom\sgrowing\sto\sbe\slarger\sthan\s100\splus\sfour\stimes\nthe\sSQLITE_LIMIT_EXPR_DEPTH\ssetting.
|
||||
D 2025-11-18T02:24:46.688
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
|
||||
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
|
||||
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
|
||||
F Makefile.msc 8dd676302f3165984c046f81af14b6676a334418fa30255efaf439f8033042fa
|
||||
F Makefile.msc 523bab2f6569e912a0aaf2d13e0b3f9bcb36d52310b236d950b354068c9de3f3
|
||||
F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7
|
||||
F VERSION a3971cc92c03ff4c250d95d1ecf61e2433152c21926d8a7dd429b39218a6e4c7
|
||||
F VERSION 74672bfd4c7826c0fc6f84762488a707c52e7d2d94af42ccb0edcc6c74311c41
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -17,7 +17,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531
|
||||
F auto.def 44a0d1bf09d78355fc88251ccbf8e64e6341fd89c11de68a01c3645e53a2bade
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.in 118aa2c4d49173672d065fdda19eb8a28642e2c684212d7a626d6db5e6762521
|
||||
F autoconf/Makefile.in 306f500fce8cae9e1af9459f1ac7fe89ce46999594ef3fdc62dc9d7d651fb091
|
||||
F autoconf/Makefile.msc 803aa9e23b6a764751f6a91d0673620eefa46729fb80faf51391120e1d752966
|
||||
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
|
||||
F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807
|
||||
@@ -47,7 +47,7 @@ F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1
|
||||
F autosetup/jimsh0.c a57c16e65dcffc9c76e496757cb3f7fb47e01ecbd1631a0a5e01751fc856f049
|
||||
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
|
||||
F autosetup/proj.tcl 6fc14ef82b19b77a95788ffbcfad7989b4e3cb4ce96a21dcb5cf7312f362fba9
|
||||
F autosetup/sqlite-config.tcl 5d779fce20c11fde3fe99d157dcd5b5569d729b301141b8dfb8d5aacf9d48cba
|
||||
F autosetup/sqlite-config.tcl 1fd7c55394051fbfba2fb9fa9192c027ee7d74612dbf772b06e27feb9f1de5df
|
||||
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
|
||||
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
|
||||
F autosetup/teaish/core.tcl e014dd95900c7f9a34e8e0f460f47e94841059827bce8b4c49668b0c7ae3f1a0
|
||||
@@ -60,7 +60,7 @@ F doc/compile-for-unix.md c9dce1ddd4bf0d25efccc5c63eb047e78c01ce06a6ff29c73e0a8a
|
||||
F doc/compile-for-windows.md f9e74d74da88f384edd5809f825035e071608f00f7f39c0e448df7b3982f979c
|
||||
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
||||
F doc/jsonb.md acd77fc3a709f51242655ad7803510c886aa8304202fa9cf2abc5f5c4e9d7ae5
|
||||
F doc/lemon.html 89ea833a6f71773ab1a9063fbb7fb9b32147bc0b1057b53ecab94a3b30c0aef5
|
||||
F doc/lemon.html 0e4b854b5ca0cf3600fec4da454197f651e8a0d411a90653703e75474486ad31
|
||||
F doc/pager-invariants.txt 83aa3a4724b2d7970cc3f3461f0295c46d4fc19a835a5781cbb35cb52feb0577
|
||||
F doc/tcl-extension-testing.md b88861804fc1eaf83249f8e206334189b61e150c360e1b80d0dcf91af82354f5
|
||||
F doc/testrunner.md 5ee928637e03f136a25fef852c5ed975932e31927bd9b05a574424ae18c31019
|
||||
@@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d
|
||||
F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8
|
||||
F ext/fts5/fts5_expr.c b8c32da1127bafaf10d6b4768b0dcb92285798524bed2d87a8686f99a8e8d259
|
||||
F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0
|
||||
F ext/fts5/fts5_index.c 5e82963a6691ae519df1e018cc7971272a3da1fd47daca5029af0e9ce24f1a8b
|
||||
F ext/fts5/fts5_index.c 8dbda33a9830764167d7697f1c9980c8a6ee74f5decb28206b963222583b8cdd
|
||||
F ext/fts5/fts5_main.c 42025174a556257287071e90516d3ab8115daf1dd525a301883544469a260014
|
||||
F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2
|
||||
F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329
|
||||
@@ -122,7 +122,7 @@ F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a
|
||||
F ext/fts5/fts5_tokenize.c 49aea8cc400a690a6c4f83c4cedc67f4f8830c6789c4ee343404f62bcaebca7b
|
||||
F ext/fts5/fts5_unicode2.c 536a6dae41d16edadd6a6b58c56e2ebbb133f0dfe757562a2edbcdc9b8362e50
|
||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||
F ext/fts5/fts5_vocab.c 23e263ad94ac357cfffd19bd7e001c3f15c4420fb10fa35b5993142127e780e6
|
||||
F ext/fts5/fts5_vocab.c ff0441c4ea165081e8152dec6d29056faa0cdc281a9f218a00e3d7aacc1958bc
|
||||
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl c5aa7cf7148b6dcffb5b61520ae18212baf169936af734ab265143f59db328fe
|
||||
@@ -162,7 +162,7 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b
|
||||
F ext/fts5/test/fts5contentless5.test 38cd0392c730dc7090c550321ce3c24ba4c392bc97308b51a4180e9959dca7b5
|
||||
F ext/fts5/test/fts5corrupt.test 237fce1c3261bb3a5bec333b0f0dbf5b105ec32627ef14cccbda3cfe13833193
|
||||
F ext/fts5/test/fts5corrupt2.test 4a03a158c2cb617c9f76d26b35c1ef2534124bc0bbddcea38dfd5b170ebea27b
|
||||
F ext/fts5/test/fts5corrupt3.test e489b51b6c4ded2a808e0f78bdbe126f6d369de41a59ac2717878e37fc3db0e8
|
||||
F ext/fts5/test/fts5corrupt3.test 43d6a836892d79ab738ab89b3b6f4ae46c07ee966193e4b357bbb14e7f81d5da
|
||||
F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733
|
||||
F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a0ff2f26e0c2e222abe
|
||||
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
|
||||
@@ -269,7 +269,7 @@ F ext/fts5/test/fts5update.test b8affd796e45c94a4d19ad5c26606ea06065a0f162a9562d
|
||||
F ext/fts5/test/fts5update2.test c5baa76799ac605ebb8e5e21035db2014b396cef25c903eb96ba39b1d6f9f046
|
||||
F ext/fts5/test/fts5version.test 44ab35566267b7618c090443de2d9ad84f633df5d20bf72e9bad199ae5fced84
|
||||
F ext/fts5/test/fts5vocab.test 2a2bdb60d0998fa3124d541b6d30b019504918dc43a6584645b63a24be72f992
|
||||
F ext/fts5/test/fts5vocab2.test 4265137a3747b27deb1e2e2bde5654120c6de72bfed3238e67806d85af60fc4c
|
||||
F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98f3e9fa3b03786373
|
||||
F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85
|
||||
F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f
|
||||
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
@@ -288,10 +288,10 @@ F ext/intck/sqlite3intck.c b1c8a86f90fc00741d13314db9c58f7e2f92d1d19c5ad1c6904ec
|
||||
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
|
||||
F ext/intck/test_intck.c 4f9eaadaedccb9df1d26ba41116a0a8e5b0c5556dc3098c8ff68633adcccdea8
|
||||
F ext/jni/GNUmakefile 8a94e3a1953b88cf117fb2a5380480feada8b4f5316f02572cab425030a720b4
|
||||
F ext/jni/README.md e3fbd47c774683539b7fdc95a667eb9cd6e64d8510f3ee327e7fa0c61c8aa787
|
||||
F ext/jni/README.md 1479c83dbe26125264a060ee6873531795a7082dbc0d43c4067683371331559f
|
||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||
F ext/jni/src/c/sqlite3-jni.c 3d84a0176af779737ae977ba1c90d2ffe2537b8299c5d9f6552620493f12ac4b
|
||||
F ext/jni/src/c/sqlite3-jni.h ac180ba9b21978727006c790d3006a95a2402a4c3ec7a0def92707ed89b79945
|
||||
F ext/jni/src/c/sqlite3-jni.c 6ccc50b0e98b8ef8fd6a8b837223e1c8ebb92bfe6b976128cc757c26257d994a
|
||||
F ext/jni/src/c/sqlite3-jni.h df43024cced914c49485633d0f90168689e70577b3b17b0ecbdaf16e4a417bff
|
||||
F ext/jni/src/org/sqlite/jni/annotation/Experimental.java 8603498634e41d0f7c70f661f64e05df64376562ea8f126829fd1e0cdd47e82b
|
||||
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java be6cc3e8e114485822331630097cc0f816377e8503af2fc02f9305ff2b353917
|
||||
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90
|
||||
@@ -301,7 +301,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0e28a0df51368c7127e505f
|
||||
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
|
||||
F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
|
||||
F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java 3d275f5f4fbdbe4fff15f4d42cf5ff559f9a4897e7373fa99f3b1dc9cf7f849c
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java a9701cbe736b8bef5bc72ae465be0250e137f67bdb5a3ab62497972b6f51572d
|
||||
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 1b3baf5b772f266e8baf8f35f0ddc5bd87fc8c4927ec69115c46fd6fba6701c3
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
|
||||
@@ -319,7 +319,7 @@ F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385
|
||||
F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 3c0babc067d8560627a9ed1b07979f9d4393464e2282c2fca4832052e982c7bc
|
||||
F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615
|
||||
F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java 9133bb7685901d2edf07801191284975e33b5583ce09dce1c05202ff91e7bb99
|
||||
F ext/jni/src/org/sqlite/jni/capi/Tester1.java 4c3d16fdf6e979f839b2ecdb14d0a0c04bd3d0e41500fc9e8110b588883b140b
|
||||
F ext/jni/src/org/sqlite/jni/capi/Tester1.java 378d142435d220b20b7ce7343c62a03e853bb8c51e80447ee0f8ac5c37362d9a
|
||||
F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
|
||||
F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
|
||||
F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 2ce069f3e007fdbbe1f4e507a5a407fc9679da31a0aa40985e6317ed4d5ec7b5
|
||||
@@ -346,7 +346,7 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md d7987b432870d23f7c72a780
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 326ffba29aab836a6ea189703c3d7fb573305fd93da2d14b0f9e9dcf314c8290
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java e920f7a031e04975579240d4a07ac5e4a9d0f8de31b0aa7a4be753c98ae596c9
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java c82bc00c1988f86246a89f721d3c41f0d952f33f934aa6677ec87f7ca42519a0
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java ce8aef867e06a21685658eb0173768c355e9e1e2dfdc75f382643fa62c7ee779
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 08f92d52be2cec28a7b4555479cc54b7ebeeb94985256144eeb727154ec3f85b
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
|
||||
@@ -372,7 +372,7 @@ F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a0
|
||||
F ext/misc/decimal.c d4883de142f6dcd36eda23da40b55e2b51374e7b01eb54a7173940191389fc5e
|
||||
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
|
||||
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
|
||||
F ext/misc/fileio.c d4918ff3f59a26c447347b40ac5e5c41aef697dfa24ebb2ef61ebad3c32261f0
|
||||
F ext/misc/fileio.c 61af623160c073b605b4ff1f67d278c4c348956efa08f6201756577c7a050d17
|
||||
F ext/misc/fossildelta.c 2fc2dd4f34f478df674887db62586b1071c4cd3c9e73ee40f9ee669670e482d1
|
||||
F ext/misc/fuzzer.c 6b231352815304ba60d8e9ec2ee73d4918e74d9b76bda8940ba2b64e8777515e
|
||||
F ext/misc/ieee754.c 176c061c94857b543313959289cb60cf777c999fd002f82b53d194b95e9f347a
|
||||
@@ -575,8 +575,7 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e
|
||||
F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e946f3aee6e64c54
|
||||
F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a
|
||||
F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile 3dc01e673c456d3b752674c9407276e8fef35dec1d304b3cc1de362f019b2a09
|
||||
F ext/wasm/GNUmakefile 01f5e1bc688911b0c0accb0b152dccb19818cb301a90ba9772e3b329a7f625b0
|
||||
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
|
||||
F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259
|
||||
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
|
||||
@@ -584,35 +583,31 @@ F ext/wasm/SQLTester/SQLTester.mjs 6b3c52ed36a5573ca4883176f326332a8d4c0cecf5efd
|
||||
F ext/wasm/SQLTester/SQLTester.run.mjs 57f2adb33f43f2784abbf8026c1bfd049d8013af1998e7dcb8b50c89ffc332e0
|
||||
F ext/wasm/SQLTester/index.html 64f3435084c7d6139b08d1f2a713828a73f68de2ae6a3112cbb5980d991ba06f
|
||||
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core ef34398a903d0a2425fbbfbd4ed2cd596daea55b8515e2617c8dc7ad7c0767dd
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras 9eae68943ce91ab145892b31370819c2103525240eb72e0fce53c498b8d8275a
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md f4c0d67caaee21a77b8938c30b5f79667bfc9d0c95d01b51df77ea35ee773884
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 205f55aacfc62c580985db5c790300779de3876a76a5c7e1bfb13e71c8b4506b
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp d609c22bc05e25991bdd2eeed4497485a3756446158b2794471426e5e3517056
|
||||
F ext/wasm/api/README.md aae128e14711dafac29e7b645ff1b6be42305b73f74b1303d8401351f8448631
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 4b310c9891886e7c1ea4e2419966ff45dfeda825b897fdaa4119332509f7e3d1
|
||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||
F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c043fd990aa715b74ee
|
||||
F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70
|
||||
F ext/wasm/api/pre-js.c-pp.js a876c6399dff29b6fe9e434036beb89889164cc872334e184291723ecc7cb072
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js d2b8263b3ce0cefc6c5a68d0a4d448a9770eda4bf9d9ded9d7eb0198e4ce4da1
|
||||
F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8aeb3db237ddce2935b
|
||||
F ext/wasm/api/post-js-header.js d24bd0d065f3489c8b78ddf3ead6321e5d047187a162cd503c41700e03dd1f06
|
||||
F ext/wasm/api/pre-js.c-pp.js ad2546290e0c8ce5ca2081bff6e85cc25eeb904a3303921f1184290a7ff1b32f
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js 79a54b54ca6324d28e31e19b56bbaebb7d2cc4b3079066e7e901333fa5047c53
|
||||
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 31dbfd470c91ffd96d77399b749bab6b69e3ba9074188833f97ac13f087cf07b
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 307583ff39a978c897c4ef4ce53fe231dce5c73dc84785969c81c1ab5960a293
|
||||
F ext/wasm/api/sqlite3-api-prologue.js a7cab3e8f78d5a93d7173657677fef18265f48d4e0b1e1755740f734a69cae6d
|
||||
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
|
||||
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 418c33fe284739564daab3c7a7a88882fdd3c99137497900f98eddec1e409af5
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js aa330fa0e8ef35cbd92eb0d52e05fbaa07e61540c5cb164e693c82428ce1d763
|
||||
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
|
||||
F ext/wasm/api/sqlite3-wasm.c dd7fc1d535281f0d5d2732bb1b662d1d403a762f07b63c2ea5663053377b2804
|
||||
F ext/wasm/api/sqlite3-wasm.c 03451f8335f4ba8ea9a79dfc170560b1ee5376de64ff49c1a114274ccf50ab3d
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bda1c75bd674a92a0e27cc2f3d46dbbf21e422413f8046814515a0bd7409328a
|
||||
F ext/wasm/api/sqlite3-worker1.c-pp.js 802d69ead8c38dc1be52c83afbfc77e757da8a91a2e159e7ed3ecda8b8dba2e7
|
||||
F ext/wasm/c-pp-lite.c 8fa0148e73782a86274db688c4730e2962cd675af329490493adddaf3322f16f
|
||||
F ext/wasm/c-pp-lite.c 943be1a36774d58385dca32de36fc18d4f432fe79f7aa35e6c85dd6a6b825bd0
|
||||
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
||||
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
|
||||
F ext/wasm/common/whwasmutil.js 0d539324097fc83b953e9844267359ba0fd02286caa784ea2f597ced279ea640
|
||||
F ext/wasm/common/whwasmutil.js 804409dec98458f732b23e6e86788934ac6dec002107435cc4055355585d1c15
|
||||
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
|
||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||
@@ -629,10 +624,10 @@ F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc6
|
||||
F ext/wasm/fiddle/index.html a27b8127ef9ecf19612da93b2a6a73bdb3777b5c56b5450bb7200a94bc108ff9
|
||||
F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
|
||||
F ext/wasm/index.html 54e27db740695ab2cb296e02d42c4c66b3f11b65797340d19fa6590f5b287da1
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js bbac67bc7a79dca34afe6215fd16b27768d84e22273507206f888c117e2ede7d
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1e734c624205cdf621f322972dfb0fc8013d573a5882f57492a6830e5ec23e17
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.md 167fc0b624c9bc2c477846e336de9403842d81b1a24fc4d3b24317cb9eba734f
|
||||
F ext/wasm/mkdist.sh 64d53f469c823ed311f6696f69cec9093f745e467334b34f5ceabdf9de3c5b28 x
|
||||
F ext/wasm/mkwasmbuilds.c 1b53c4d2a1350c19a96a8cdfbda6a39baea9d2142bfe0cbef0ccb0e898787f47
|
||||
F ext/wasm/mkwasmbuilds.c ef42e404236dd98cedb6ecea47b6d2474e3c593633ce6d992d316289dfc442b6
|
||||
F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2
|
||||
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
|
||||
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
|
||||
@@ -646,9 +641,9 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826
|
||||
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
|
||||
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
|
||||
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
|
||||
F ext/wasm/tester1-worker.c-pp.html 883881eeac14eeeecc8ff22acf9fe0f18a97cacb48be08ebb0bae891ceded584
|
||||
F ext/wasm/tester1.c-pp.html 949920126dcf477925d8d540093d9cc374d3ab4c4ddee920c1dcadcf37917306
|
||||
F ext/wasm/tester1.c-pp.js 2b014884dadf28928fabcb688746ca87145673eef75e154486505a266203fc15
|
||||
F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
|
||||
F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
|
||||
F ext/wasm/tester1.c-pp.js 2c255093205a0dac9dae7475030665c2c9d6dccc857de68ee7daf49aa82e6de8
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
|
||||
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@@ -658,7 +653,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk 00dd631c66c1f7922b2d691631163899eff1c3d1da780ff37a62f8d997b368e1
|
||||
F main.mk 29078d11f7545a8fae4347305b164bb4e777b801da16baeb48214014a8d63a06
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@@ -675,7 +670,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
|
||||
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
|
||||
F src/btree.c cb5b8ceb9baa02a63a2f83dec09c4153e1cfbdf9c2adef5c62c26d2160eeb067
|
||||
F src/btree.c 8850125300b9780fa54bc45a41af88eb2796b90f2f97942279094beef9b0e971
|
||||
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
|
||||
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
|
||||
F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b
|
||||
@@ -693,13 +688,13 @@ F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
|
||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||
F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
|
||||
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/hwtime.h d4d1b98c1afdc56986a5c0eba882786ef017e2180a320da25b4231b8e7e463e8
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
|
||||
F src/json.c fb031340edee159c07ad37dbe668ffe945ed86f525b0eb3822e4a67cbc498a72
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c a3bc9a2522dc3b960e38b7582d1818f6245a49289387c2c7b19f27bfeabf1e81
|
||||
F src/main.c 65d11c17890966d271c925c6cc55e3ba50fa08374633cb99c0dee4719a20915a
|
||||
F src/loadext.c 4747f72084dc80520a2d23e5bb0bc0760672208a81a2b115ce0b657acd65edf4
|
||||
F src/main.c eaf5215917b7e8b34ddea013524287f6d5021ba0fc70202e7602e225ef0d16bf
|
||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -723,23 +718,23 @@ F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae
|
||||
F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
|
||||
F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
|
||||
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
|
||||
F src/pager.c cd562b878ea1b44d021ba199abc9d3b54f6b3347500a9fed03f66d6000620945
|
||||
F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f
|
||||
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
|
||||
F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
|
||||
F src/parse.y 04c6c7278939e3c6307ed3c6ed7482d2928e692560dbe8e57f524851a934e25c
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
|
||||
F src/pragma.c ecec75795c1821520266e4f93fa8840cce48979af532db06f085e36a7813860f
|
||||
F src/prepare.c 2af0b5c1ec787c8eebd21baa9d79caf4a4dc3a18e76ce2edbf2027d706bca37a
|
||||
F src/printf.c 7297c2aeed4d90d80c5ba82920d9e57b7bfad04b3466be1d7e042db382fe296e
|
||||
F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
|
||||
F src/shell.c.in 223e3703657f5e66c136521a32fc8cc9a7dbbe6b1ade6fd47457e78c38f33e6e
|
||||
F src/sqlite.h.in c0979f9ac1f5be887397dd2a0bb485636893a81b34d64df85123aae9650c42f2
|
||||
F src/shell.c.in ceb0a9cc008ac82d8d2e6ef353db14a54bc40dfd60a8cfbb6bc98d071f538761
|
||||
F src/sqlite.h.in 667dff873941366da98da3200cf757ac05dfb62ea785e6642e33dd586ae5285c
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
|
||||
F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
|
||||
F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59aa
|
||||
F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
|
||||
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
|
||||
@@ -756,7 +751,7 @@ F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0
|
||||
F src/test9.c df9ddc7db6ef1b8cf745866ee229090779728bcbe660c7f297d3127ab21d92af
|
||||
F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f
|
||||
F src/test_backup.c a2bfd90d2ff2511b8635507bdb30fa9b605ade19c16b533066cae3077f5bdb72
|
||||
F src/test_bestindex.c a9428931bec06de830b2630f57a7b1f2711761269f04df62b7aa1affcbce15bb
|
||||
F src/test_bestindex.c d75fad21369d80910238032bcf8d9ca1f2bffda13c1ceec63bfbb7f704448b15
|
||||
F src/test_blob.c 77b994e17f2c87055f44fd96c9a206c5a7155bae2cda2769af60c2f3582f962c
|
||||
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
|
||||
F src/test_config.c 18aa596d37de1d5968c439fd58ebf38bc4d9c9d1db63621504e241fde375cecd
|
||||
@@ -805,7 +800,7 @@ F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
|
||||
F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
|
||||
F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
|
||||
F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
|
||||
F src/vdbeapi.c 869a0da5d855495055f4d35c6ada582f64ce995ce14b26ff9d336274d497266c
|
||||
F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938
|
||||
F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
|
||||
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
|
||||
F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021
|
||||
@@ -1693,7 +1688,7 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a
|
||||
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
|
||||
F test/testrunner.tcl 60d7efa1816c5dfc37df3e3454b94b9042c0c8c50b27ae296d4a797cd309ace6 x
|
||||
F test/testrunner.tcl 86179a8e78997e9257cb8f738c5624cb23897da5297855578ba74715e64f1602 x
|
||||
F test/testrunner_data.tcl c507a9afa911c03446ed90442ffd4a98aca02882c3d51bd1177c24795674def8
|
||||
F test/testrunner_estwork.tcl 7927a84327259a32854926f68a75292e33a61e7e052fdbfcb01f18696c99c724
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
@@ -2106,8 +2101,8 @@ F tool/genfkey.README e550911fa984c8255ebed2ef97824125d83806eb5232582700de949edf
|
||||
F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a5a4f
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5
|
||||
F tool/lemon.c 8f6c122e5727cb0e5f302b8efc91489b1947a8d98206d7a1b1cfc0ed685b6e7c
|
||||
F tool/lempar.c bdffd3b233a4e4e78056c9c01fadd2bb3fe902435abde3bce3d769fdf0d5cca2
|
||||
F tool/lemon.c fda0511d71764674919872a1457d2f86a7d48b13bfcf98741955c1b217a84570
|
||||
F tool/lempar.c a59c5474bdd148ca4c61f2977c7ce6b49e99c48a333b6d48fc7ceacf2292b43a
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6
|
||||
F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
|
||||
@@ -2171,10 +2166,11 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 40ddaca3fb752425c26570365a9f31820786d21d043c1c0a4b49746ff9bc0782
|
||||
R e6faec25512909b375a6de433bcc999d
|
||||
T +sym-release *
|
||||
T +sym-version-3.51.1 *
|
||||
P ea48567ac54e4949a8b68977a58a5de7946e074ae8737133071d02f40ac97f34
|
||||
R 94faba231c7b1fe01c357a8fbebddcb3
|
||||
T *branch * parser-recursion-limit
|
||||
T *sym-parser-recursion-limit *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z a5cb39bb0c202daa26ad87d8a3e3f169
|
||||
Z ef6a72fd333d3e7f2a3d9cd4902c91e6
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+2
-4
@@ -1,4 +1,2 @@
|
||||
branch branch-3.51
|
||||
tag release
|
||||
tag branch-3.51
|
||||
tag version-3.51.1
|
||||
branch parser-recursion-limit
|
||||
tag parser-recursion-limit
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88
|
||||
5728129e5432500550096e2a1350897881f0379b49b60faf49481c505b1eb323
|
||||
|
||||
+25
-1
@@ -3673,6 +3673,30 @@ static SQLITE_NOINLINE int btreeBeginTrans(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114
|
||||
/* If both a read and write transaction will be opened by this call,
|
||||
** then issue a file-control as if the following pragma command had
|
||||
** been evaluated:
|
||||
**
|
||||
** PRAGMA experimental_pragma_20251114 = 1|2
|
||||
**
|
||||
** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag
|
||||
** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS.
|
||||
**
|
||||
** WARNING: This code will likely remain part of SQLite only temporarily -
|
||||
** it exists to allow users to experiment with certain types of blocking
|
||||
** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */
|
||||
if( pBt->pPage1==0 && wrflag ){
|
||||
sqlite3_file *fd = sqlite3PagerFile(pPager);
|
||||
char *aFcntl[3] = {0,0,0};
|
||||
aFcntl[1] = "experimental_pragma_20251114";
|
||||
assert( wrflag==1 || wrflag==2 );
|
||||
aFcntl[2] = (wrflag==1 ? "1" : "2");
|
||||
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Call lockBtree() until either pBt->pPage1 is populated or
|
||||
** lockBtree() returns something other than SQLITE_OK. lockBtree()
|
||||
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
|
||||
@@ -9758,7 +9782,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
|
||||
}while( rc==SQLITE_OK && nOut>0 );
|
||||
|
||||
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
|
||||
Pgno pgnoNew;
|
||||
Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
|
||||
MemPage *pNew = 0;
|
||||
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
|
||||
put4byte(pPgnoOut, pgnoNew);
|
||||
|
||||
+19
-21
@@ -16,17 +16,18 @@
|
||||
#ifndef SQLITE_HWTIME_H
|
||||
#define SQLITE_HWTIME_H
|
||||
|
||||
/*
|
||||
** The following routine only works on Pentium-class (or newer) processors.
|
||||
** It uses the RDTSC opcode to read the cycle count value out of the
|
||||
** processor and returns that value. This can be used for high-res
|
||||
** profiling.
|
||||
*/
|
||||
#if !defined(__STRICT_ANSI__) && \
|
||||
(defined(__GNUC__) || defined(_MSC_VER)) && \
|
||||
(defined(i386) || defined(__i386__) || defined(_M_IX86))
|
||||
#if defined(_MSC_VER) && defined(_WIN32)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <profileapi.h>
|
||||
|
||||
__inline sqlite3_uint64 sqlite3Hwtime(void){
|
||||
LARGE_INTEGER tm;
|
||||
QueryPerformanceCounter(&tm);
|
||||
return (sqlite3_uint64)tm.QuadPart;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
|
||||
(defined(i386) || defined(__i386__) || defined(_M_IX86))
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
unsigned int lo, hi;
|
||||
@@ -34,17 +35,6 @@
|
||||
return (sqlite_uint64)hi << 32 | lo;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
__declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
|
||||
__asm {
|
||||
rdtsc
|
||||
ret ; return value at EDX:EAX
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
@@ -52,6 +42,14 @@
|
||||
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||
return (sqlite_uint64)hi << 32 | lo;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
|
||||
|
||||
__inline__ sqlite_uint64 sqlite3Hwtime(void){
|
||||
sqlite3_uint64 cnt;
|
||||
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
|
||||
|
||||
|
||||
+4
-1
@@ -522,7 +522,10 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_setlk_timeout,
|
||||
/* Version 3.51.0 and later */
|
||||
sqlite3_set_errmsg,
|
||||
sqlite3_db_status64
|
||||
sqlite3_db_status64,
|
||||
/* Version 3.52.0 and later */
|
||||
sqlite3_str_truncate,
|
||||
sqlite3_str_free
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
||||
@@ -2526,6 +2526,9 @@ void *sqlite3_wal_hook(
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return pRet;
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(xCallback);
|
||||
UNUSED_PARAMETER(pArg);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -2541,6 +2544,11 @@ int sqlite3_wal_checkpoint_v2(
|
||||
int *pnCkpt /* OUT: Total number of frames checkpointed */
|
||||
){
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(zDb);
|
||||
UNUSED_PARAMETER(eMode);
|
||||
UNUSED_PARAMETER(pnLog);
|
||||
UNUSED_PARAMETER(pnCkpt);
|
||||
return SQLITE_OK;
|
||||
#else
|
||||
int rc; /* Return code */
|
||||
@@ -4903,6 +4911,7 @@ const char *sqlite3_filename_journal(const char *zFilename){
|
||||
}
|
||||
const char *sqlite3_filename_wal(const char *zFilename){
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
UNUSED_PARAMETER(zFilename);
|
||||
return 0;
|
||||
#else
|
||||
zFilename = sqlite3_filename_journal(zFilename);
|
||||
|
||||
@@ -813,6 +813,8 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
|
||||
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
|
||||
if( iRead ) return 0; /* Case (4) */
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(pgno);
|
||||
#endif
|
||||
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
|
||||
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
|
||||
@@ -4192,6 +4194,8 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
|
||||
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
|
||||
pPager->pWal = 0;
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
#endif
|
||||
pager_reset(pPager);
|
||||
if( MEMDB ){
|
||||
|
||||
+14
-5
@@ -22,8 +22,8 @@
|
||||
}
|
||||
|
||||
// Function used to enlarge the parser stack, if needed
|
||||
%realloc parserStackRealloc
|
||||
%free sqlite3_free
|
||||
%reallocx parserStackRealloc
|
||||
%free sqlite3_free
|
||||
|
||||
// All token codes are small integers with #defines that begin with "TK_"
|
||||
%token_prefix TK_
|
||||
@@ -49,7 +49,7 @@
|
||||
}
|
||||
}
|
||||
%stack_overflow {
|
||||
sqlite3OomFault(pParse->db);
|
||||
if( pParse->nErr==0 ) sqlite3OomFault(pParse->db);
|
||||
}
|
||||
|
||||
// The name of the generated procedure that implements the parser
|
||||
@@ -583,8 +583,17 @@ cmd ::= select(X). {
|
||||
** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
|
||||
** testing.
|
||||
*/
|
||||
static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
|
||||
return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
|
||||
static void *parserStackRealloc(
|
||||
void *pOld, /* Old allocation, or NULL to get a new one */
|
||||
int newCount, /* Number of elements */
|
||||
int unitSize, /* Size of each element */
|
||||
Parse *pParse /* Parsing context */
|
||||
){
|
||||
if( sqlite3FaultSim(700) ) return 0;
|
||||
if( newCount > pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]*4+100 ){
|
||||
sqlite3ErrorMsg(pParse, "Recursion limit reached");
|
||||
}
|
||||
return sqlite3_realloc64(pOld, newCount*unitSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1228,6 +1228,14 @@ int sqlite3_str_length(sqlite3_str *p){
|
||||
return p ? p->nChar : 0;
|
||||
}
|
||||
|
||||
/* Truncate the text of the string to be no more than N bytes. */
|
||||
void sqlite3_str_truncate(sqlite3_str *p, int N){
|
||||
if( p!=0 && N>=0 && (u32)N<p->nChar ){
|
||||
p->nChar = N;
|
||||
p->zText[p->nChar] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the current value for p */
|
||||
char *sqlite3_str_value(sqlite3_str *p){
|
||||
if( p==0 || p->nChar==0 ) return 0;
|
||||
@@ -1248,6 +1256,17 @@ void sqlite3_str_reset(StrAccum *p){
|
||||
p->zText = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destroy a dynamically allocate sqlite3_str object and all
|
||||
** of its content, all in one call.
|
||||
*/
|
||||
void sqlite3_str_free(sqlite3_str *p){
|
||||
if( p ){
|
||||
sqlite3_str_reset(p);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a string accumulator.
|
||||
**
|
||||
|
||||
+26
-23
@@ -7225,39 +7225,42 @@ static void clearTempFile(ShellState *p){
|
||||
p->zTempFile = 0;
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static char *find_home_dir(int clearFlag);
|
||||
|
||||
/*
|
||||
** Create a new temp file name with the given suffix.
|
||||
**
|
||||
** Because the classic temp folders like /tmp are no longer
|
||||
** accessible to web browsers, for security reasons, create the
|
||||
** temp file in the user's home directory.
|
||||
*/
|
||||
static void newTempFile(ShellState *p, const char *zSuffix){
|
||||
char *zHome; /* Home directory */
|
||||
int i; /* Loop counter */
|
||||
sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
|
||||
char zRand[32]; /* Text string with 160 bits of randomness */
|
||||
#ifdef _WIN32
|
||||
const char cDirSep = '\\';
|
||||
#else
|
||||
const char cDirSep = '/';
|
||||
#endif
|
||||
|
||||
for(i=0; i<31; i++){
|
||||
if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
|
||||
zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
|
||||
r /= 36;
|
||||
}
|
||||
zRand[i] = 0;
|
||||
clearTempFile(p);
|
||||
sqlite3_free(p->zTempFile);
|
||||
p->zTempFile = 0;
|
||||
if( p->db ){
|
||||
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
|
||||
}
|
||||
if( p->zTempFile==0 ){
|
||||
/* If p->db is an in-memory database then the TEMPFILENAME file-control
|
||||
** will not work and we will need to fallback to guessing */
|
||||
char *zTemp;
|
||||
sqlite3_uint64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
zTemp = getenv("TEMP");
|
||||
if( zTemp==0 ) zTemp = getenv("TMP");
|
||||
if( zTemp==0 ){
|
||||
#ifdef _WIN32
|
||||
zTemp = "\\tmp";
|
||||
#else
|
||||
zTemp = "/tmp";
|
||||
#endif
|
||||
}
|
||||
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
|
||||
}else{
|
||||
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
|
||||
}
|
||||
zHome = find_home_dir(0);
|
||||
p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
|
||||
zHome,cDirSep,zRand,zSuffix);
|
||||
shell_check_oom(p->zTempFile);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** The implementation of SQL scalar function fkey_collate_clause(), used
|
||||
** by the ".lint fkey-indexes" command. This scalar function is always
|
||||
|
||||
+26
-12
@@ -2567,12 +2567,15 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
|
||||
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
|
||||
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
|
||||
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
|
||||
** statistics. For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is prepared and when it
|
||||
** is stepped. The flag is set (collection of statistics is enabled)
|
||||
** by default. <p>This option takes two arguments: an integer and a pointer to
|
||||
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
|
||||
** a flag that enables collection of run-time performance statistics
|
||||
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
|
||||
** columns of the [bytecode virtual table].
|
||||
** For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is
|
||||
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
|
||||
** The flag is set (collection of statistics is enabled) by default.
|
||||
** <p>This option takes two arguments: an integer and a pointer to
|
||||
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the statement scanstatus option. If the second argument
|
||||
** is not NULL, then the value of the statement scanstatus setting after
|
||||
@@ -4217,7 +4220,7 @@ const char *sqlite3_errstr(int);
|
||||
int sqlite3_error_offset(sqlite3 *db);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set Error Codes And Message
|
||||
** CAPI3REF: Set Error Code And Message
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** Set the error code of the database handle passed as the first argument
|
||||
@@ -8724,15 +8727,20 @@ sqlite3_str *sqlite3_str_new(sqlite3*);
|
||||
** errors were encountered during construction of the string. ^The
|
||||
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
|
||||
** string in [sqlite3_str] object X is zero bytes long.
|
||||
**
|
||||
** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
|
||||
** X and the string content it contains. Calling sqlite3_str_free(X) is
|
||||
** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
|
||||
*/
|
||||
char *sqlite3_str_finish(sqlite3_str*);
|
||||
void sqlite3_str_free(sqlite3_str*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Add Content To A Dynamic String
|
||||
** METHOD: sqlite3_str
|
||||
**
|
||||
** These interfaces add content to an sqlite3_str object previously obtained
|
||||
** from [sqlite3_str_new()].
|
||||
** These interfaces add or remove content to an sqlite3_str object
|
||||
** previously obtained from [sqlite3_str_new()].
|
||||
**
|
||||
** ^The [sqlite3_str_appendf(X,F,...)] and
|
||||
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
|
||||
@@ -8755,6 +8763,10 @@ char *sqlite3_str_finish(sqlite3_str*);
|
||||
** ^The [sqlite3_str_reset(X)] method resets the string under construction
|
||||
** inside [sqlite3_str] object X back to zero bytes in length.
|
||||
**
|
||||
** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
|
||||
** under construction to be N bytes are less. This routine is a no-op if
|
||||
** N is negative or if the string is already N bytes or smaller in size.
|
||||
**
|
||||
** These methods do not return a result code. ^If an error occurs, that fact
|
||||
** is recorded in the [sqlite3_str] object and can be recovered by a
|
||||
** subsequent call to [sqlite3_str_errcode(X)].
|
||||
@@ -8765,6 +8777,7 @@ void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
|
||||
void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
|
||||
void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
|
||||
void sqlite3_str_reset(sqlite3_str*);
|
||||
void sqlite3_str_truncate(sqlite3_str*,int N);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Status Of A Dynamic String
|
||||
@@ -10598,9 +10611,9 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
||||
** a variable pointed to by the "pOut" parameter.
|
||||
**
|
||||
** The "flags" parameter must be passed a mask of flags. At present only
|
||||
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
|
||||
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
|
||||
** is specified, then status information is available for all elements
|
||||
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
|
||||
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
|
||||
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
|
||||
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
|
||||
** the EXPLAIN QUERY PLAN output) are available. Invoking API
|
||||
@@ -10614,7 +10627,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
||||
** elements used to implement the statement - a non-zero value is returned and
|
||||
** the variable that pOut points to is unchanged.
|
||||
**
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()]
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()] and the
|
||||
** [nexec and ncycle] columnes of the [bytecode virtual table].
|
||||
*/
|
||||
int sqlite3_stmt_scanstatus(
|
||||
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
|
||||
|
||||
+6
-1
@@ -371,7 +371,9 @@ struct sqlite3_api_routines {
|
||||
/* Version 3.51.0 and later */
|
||||
int (*set_errmsg)(sqlite3*,int,const char*);
|
||||
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
|
||||
/* Version 3.52.0 and later */
|
||||
void (*str_truncate)(sqlite3_str*,int);
|
||||
void (*str_free)(sqlite3_str*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -710,6 +712,9 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.51.0 and later */
|
||||
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
|
||||
#define sqlite3_db_status64 sqlite3_api->db_status64
|
||||
/* Version 3.52.0 and later */
|
||||
#define sqlite3_str_truncate sqlite3_api->str_truncate
|
||||
#define sqlite3_str_free sqlite3_api->str_free
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
@@ -828,7 +828,6 @@ static int tclUpdate(
|
||||
tcl_vtab *pTab = (tcl_vtab*)tab;
|
||||
Tcl_Interp *interp = pTab->interp;
|
||||
Tcl_Obj *pEval = Tcl_DuplicateObj(pTab->pCmd);
|
||||
Tcl_Obj *pRes = 0;
|
||||
int rc = TCL_OK;
|
||||
|
||||
Tcl_IncrRefCount(pEval);
|
||||
|
||||
@@ -736,6 +736,8 @@ static int doWalCallbacks(sqlite3 *db){
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1269,6 +1269,26 @@ proc add_fuzztest_jobs {buildname patternlist} {
|
||||
set subcmd [lrange $interpreter 1 end]
|
||||
set interpreter [lindex $interpreter 0]
|
||||
|
||||
# For fuzzcheck-asan and fuzzcheck-ubsan, break up some
|
||||
# fuzzdata files into multiple slices, for improved
|
||||
# concurrency.
|
||||
#
|
||||
if {[string match *fuzzcheck-*san $interpreter]} {
|
||||
set newscripts {}
|
||||
foreach s $scripts {
|
||||
if {[string match {*fuzzdata[12].db} $s]
|
||||
&& ![string match slice $s]} {
|
||||
set N 6
|
||||
for {set i 0} {$i<$N} {incr i} {
|
||||
lappend newscripts [list --slice $i $N $s]
|
||||
}
|
||||
} else {
|
||||
lappend newscripts $s
|
||||
}
|
||||
}
|
||||
set scripts $newscripts
|
||||
}
|
||||
|
||||
if {[string match fuzzcheck* $interpreter]
|
||||
&& [info exists env(FUZZDB)]
|
||||
&& [file readable $env(FUZZDB)]
|
||||
|
||||
+23
-16
@@ -495,6 +495,7 @@ struct lemon {
|
||||
char *outname; /* Name of the current output file */
|
||||
char *tokenprefix; /* A prefix added to token names in the .h file */
|
||||
char *reallocFunc; /* Function to use to allocate stack space */
|
||||
char *reallocFuncEx; /* Alternative realloc() with context pointer */
|
||||
char *freeFunc; /* Function to use to free stack space */
|
||||
int nconflict; /* Number of parsing conflicts */
|
||||
int nactiontab; /* Number of entries in the yy_action[] table */
|
||||
@@ -2641,6 +2642,9 @@ static void parseonetoken(struct pstate *psp)
|
||||
}else if( strcmp(x,"realloc")==0 ){
|
||||
psp->declargslot = &(psp->gp->reallocFunc);
|
||||
psp->insertLineMacro = 0;
|
||||
}else if( strcmp(x,"reallocx")==0 ){
|
||||
psp->declargslot = &(psp->gp->reallocFuncEx);
|
||||
psp->insertLineMacro = 0;
|
||||
}else if( strcmp(x,"free")==0 ){
|
||||
psp->declargslot = &(psp->gp->freeFunc);
|
||||
psp->insertLineMacro = 0;
|
||||
@@ -4414,7 +4418,7 @@ void ReportTable(
|
||||
int mhflag, /* Output in makeheaders format if true */
|
||||
int sqlFlag /* Generate the *.sql file too */
|
||||
){
|
||||
FILE *out, *in, *sql;
|
||||
FILE *out, *in;
|
||||
int lineno;
|
||||
struct state *stp;
|
||||
struct action *ap;
|
||||
@@ -4439,18 +4443,10 @@ void ReportTable(
|
||||
|
||||
in = tplt_open(lemp);
|
||||
if( in==0 ) return;
|
||||
out = file_open(lemp,".c","wb");
|
||||
if( out==0 ){
|
||||
fclose(in);
|
||||
return;
|
||||
}
|
||||
if( sqlFlag==0 ){
|
||||
sql = 0;
|
||||
}else{
|
||||
sql = file_open(lemp, ".sql", "wb");
|
||||
if( sqlFlag ){
|
||||
FILE *sql = file_open(lemp, ".sql", "wb");
|
||||
if( sql==0 ){
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return;
|
||||
}
|
||||
fprintf(sql,
|
||||
@@ -4515,6 +4511,12 @@ void ReportTable(
|
||||
}
|
||||
}
|
||||
fprintf(sql, "COMMIT;\n");
|
||||
fclose(sql);
|
||||
}
|
||||
out = file_open(lemp,".c","wb");
|
||||
if( out==0 ){
|
||||
fclose(in);
|
||||
return;
|
||||
}
|
||||
lineno = 1;
|
||||
|
||||
@@ -4612,17 +4614,21 @@ void ReportTable(
|
||||
fprintf(out,"#define %sARG_FETCH\n",name); lineno++;
|
||||
fprintf(out,"#define %sARG_STORE\n",name); lineno++;
|
||||
}
|
||||
if( lemp->reallocFunc ){
|
||||
fprintf(out,"#define YYREALLOC %s\n", lemp->reallocFunc); lineno++;
|
||||
if( lemp->reallocFuncEx ){
|
||||
fprintf(out,"#define YYREALLOC(A,B,C,D) %s(A,B,C,D)\n",
|
||||
lemp->reallocFuncEx); lineno++;
|
||||
}else if( lemp->reallocFunc ){
|
||||
fprintf(out,"#define YYREALLOC(A,B,C,D) %s(A,B*C)\n",
|
||||
lemp->reallocFunc); lineno++;
|
||||
}else{
|
||||
fprintf(out,"#define YYREALLOC realloc\n"); lineno++;
|
||||
fprintf(out,"#define YYREALLOC(A,B,C,D) realloc(A,B*C)\n"); lineno++;
|
||||
}
|
||||
if( lemp->freeFunc ){
|
||||
fprintf(out,"#define YYFREE %s\n", lemp->freeFunc); lineno++;
|
||||
}else{
|
||||
fprintf(out,"#define YYFREE free\n"); lineno++;
|
||||
}
|
||||
if( lemp->reallocFunc && lemp->freeFunc ){
|
||||
if( (lemp->reallocFunc || lemp->reallocFuncEx) && lemp->freeFunc ){
|
||||
fprintf(out,"#define YYDYNSTACK 1\n"); lineno++;
|
||||
}else{
|
||||
fprintf(out,"#define YYDYNSTACK 0\n"); lineno++;
|
||||
@@ -4634,6 +4640,7 @@ void ReportTable(
|
||||
fprintf(out,"#define %sCTX_SDECL %s;\n",name,lemp->ctx); lineno++;
|
||||
fprintf(out,"#define %sCTX_PDECL ,%s\n",name,lemp->ctx); lineno++;
|
||||
fprintf(out,"#define %sCTX_PARAM ,%s\n",name,&lemp->ctx[i]); lineno++;
|
||||
fprintf(out,"#define %sCTX_FIELD %s\n",name,&lemp->ctx[i]); lineno++;
|
||||
fprintf(out,"#define %sCTX_FETCH %s=yypParser->%s;\n",
|
||||
name,lemp->ctx,&lemp->ctx[i]); lineno++;
|
||||
fprintf(out,"#define %sCTX_STORE yypParser->%s=%s;\n",
|
||||
@@ -4642,6 +4649,7 @@ void ReportTable(
|
||||
fprintf(out,"#define %sCTX_SDECL\n",name); lineno++;
|
||||
fprintf(out,"#define %sCTX_PDECL\n",name); lineno++;
|
||||
fprintf(out,"#define %sCTX_PARAM\n",name); lineno++;
|
||||
fprintf(out,"#define %sCTX_FIELD yyhwm\n", name); lineno++;
|
||||
fprintf(out,"#define %sCTX_FETCH\n",name); lineno++;
|
||||
fprintf(out,"#define %sCTX_STORE\n",name); lineno++;
|
||||
}
|
||||
@@ -5103,7 +5111,6 @@ void ReportTable(
|
||||
acttab_free(pActtab);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
if( sql ) fclose(sql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -303,11 +303,11 @@ static int yyGrowStack(yyParser *p){
|
||||
newSize = oldSize*2 + 100;
|
||||
idx = (int)(p->yytos - p->yystack);
|
||||
if( p->yystack==p->yystk0 ){
|
||||
pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
|
||||
pNew = YYREALLOC(0,newSize,sizeof(pNew[0]), p->ParseCTX_FIELD);
|
||||
if( pNew==0 ) return 1;
|
||||
memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
|
||||
}else{
|
||||
pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
|
||||
pNew = YYREALLOC(p->yystack,newSize,sizeof(pNew[0]),p->ParseCTX_FIELD);
|
||||
if( pNew==0 ) return 1;
|
||||
}
|
||||
p->yystack = pNew;
|
||||
|
||||
Reference in New Issue
Block a user