1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Minor cleanups in OO API #1. Add Sudoku SQL to batch-runner.js's list.

FossilOrigin-Name: 4488cb5798f34cbba14eb8e2aa5da8420c14a85d37d278d357406aedd5c3a9e5
This commit is contained in:
stephan
2022-09-05 13:24:08 +00:00
parent cdefd5d046
commit 49cb8d7314
5 changed files with 86 additions and 49 deletions

View File

@ -126,7 +126,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
try { try {
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */; const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, null); const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, null);
ptr = capi.wasm.getMemValue(ppDb, '*'); ptr = capi.wasm.getPtrValue(ppDb);
ctor.checkRc(ptr, rc); ctor.checkRc(ptr, rc);
}catch( e ){ }catch( e ){
if( ptr ) capi.sqlite3_close_v2(ptr); if( ptr ) capi.sqlite3_close_v2(ptr);
@ -166,6 +166,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
For purposes of passing a Stmt instance to C-style sqlite3 For purposes of passing a Stmt instance to C-style sqlite3
functions, its read-only `pointer` property holds its `sqlite3_stmt*` functions, its read-only `pointer` property holds its `sqlite3_stmt*`
pointer value. pointer value.
Other non-function properties include:
- `db`: the DB object which created the statement.
- `columnCount`: the number of result columns in the query, or 0 for
queries which cannot return results.
- `parameterCount`: the number of bindable paramters in the query.
*/ */
const Stmt = function(){ const Stmt = function(){
if(BindTypes!==arguments[2]){ if(BindTypes!==arguments[2]){
@ -272,22 +281,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}; };
/** /**
Expects to be given a DB instance or an `sqlite3*` pointer, and an Expects to be given a DB instance or an `sqlite3*` pointer (may
sqlite3 API result code. If the result code is not falsy, this be null) and an sqlite3 API result code. If the result code is
function throws an SQLite3Error with an error message from not falsy, this function throws an SQLite3Error with an error
sqlite3_errmsg(), using dbPtr as the db handle. Note that if it's message from sqlite3_errmsg(), using dbPtr as the db handle, or
passed a non-error code like SQLITE_ROW or SQLITE_DONE, it will sqlite3_errstr() if dbPtr is falsy. Note that if it's passed a
still throw but the error string might be "Not an error." The non-error code like SQLITE_ROW or SQLITE_DONE, it will still
various non-0 non-error codes need to be checked for in client throw but the error string might be "Not an error." The various
code where they are expected. non-0 non-error codes need to be checked for in
client code where they are expected.
*/ */
DB.checkRc = function(dbPtr, sqliteResultCode){ DB.checkRc = function(dbPtr, sqliteResultCode){
if(sqliteResultCode){ if(sqliteResultCode){
if(dbPtr instanceof DB) dbPtr = dbPtr.pointer; if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
throw new SQLite3Error([ throw new SQLite3Error(
"sqlite result code",sqliteResultCode+":", "sqlite result code",sqliteResultCode+":",
capi.sqlite3_errmsg(dbPtr) || "Unknown db error." (dbPtr
].join(' ')); ? capi.sqlite3_errmsg(dbPtr)
: capi.sqlite3_errstr(sqliteResultCode))
);
} }
}; };
@ -379,9 +391,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
required to check `stmt.pointer` after calling `prepare()` in required to check `stmt.pointer` after calling `prepare()` in
order to determine whether the Stmt instance is empty or not. order to determine whether the Stmt instance is empty or not.
Long-time practice (with other sqlite3 script bindings) Long-time practice (with other sqlite3 script bindings)
suggests that the empty-prepare case is sufficiently rare (and suggests that the empty-prepare case is sufficiently rare that
useless) that supporting it here would simply hurt overall supporting it here would simply hurt overall usability.
usability.
*/ */
prepare: function(sql){ prepare: function(sql){
affirmDbOpen(this); affirmDbOpen(this);
@ -390,7 +401,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
try{ try{
ppStmt = capi.wasm.scopedAllocPtr()/* output (sqlite3_stmt**) arg */; ppStmt = capi.wasm.scopedAllocPtr()/* output (sqlite3_stmt**) arg */;
DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null)); DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null));
pStmt = capi.wasm.getMemValue(ppStmt, '*'); pStmt = capi.wasm.getPtrValue(ppStmt);
} }
finally {capi.wasm.scopedAllocPop(stack)} finally {capi.wasm.scopedAllocPop(stack)}
if(!pStmt) toss3("Cannot prepare empty SQL."); if(!pStmt) toss3("Cannot prepare empty SQL.");
@ -412,22 +423,21 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
The optional options object may contain any of the following The optional options object may contain any of the following
properties: properties:
- .sql = the SQL to run (unless it's provided as the first - `.sql` = the SQL to run (unless it's provided as the first
argument). This must be of type string, Uint8Array, or an array argument). This must be of type string, Uint8Array, or an array
of strings. In the latter case they're concatenated together of strings. In the latter case they're concatenated together
as-is, _with no separator_ between elements, before evaluation. as-is, _with no separator_ between elements, before evaluation.
The array form is often simpler for long hand-written queries. The array form is often simpler for long hand-written queries.
- .bind = a single value valid as an argument for - `.bind` = a single value valid as an argument for
Stmt.bind(). This is _only_ applied to the _first_ non-empty Stmt.bind(). This is _only_ applied to the _first_ non-empty
statement in the SQL which has any bindable parameters. (Empty statement in the SQL which has any bindable parameters. (Empty
statements are skipped entirely.) statements are skipped entirely.)
- .saveSql = an optional array. If set, the SQL of each - `.saveSql` = an optional array. If set, the SQL of each
executed statement is appended to this array before the executed statement is appended to this array before the
statement is executed (but after it is prepared - we statement is executed (but after it is prepared - we don't have
don't have the string until after that). Empty SQL the string until after that). Empty SQL statements are elided.
statements are elided.
================================================================== ==================================================================
The following options apply _only_ to the _first_ statement The following options apply _only_ to the _first_ statement
@ -435,8 +445,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
the statement actually produces any result rows. the statement actually produces any result rows.
================================================================== ==================================================================
- .callback = a function which gets called for each row of the - `.callback` = a function which gets called for each row of
result set, but only if that statement has any result the result set, but only if that statement has any result
_rows_. The callback's "this" is the options object. The second _rows_. The callback's "this" is the options object. The second
argument passed to the callback is always the current Stmt argument passed to the callback is always the current Stmt
object (so that the caller may collect column names, or object (so that the caller may collect column names, or
@ -455,24 +465,24 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
The first argument passed to the callback defaults to an array of The first argument passed to the callback defaults to an array of
values from the current result row but may be changed with ... values from the current result row but may be changed with ...
- .rowMode = specifies the type of he callback's first argument. - `.rowMode` = specifies the type of he callback's first argument.
It may be any of... It may be any of...
A) A string describing what type of argument should be passed A) A string describing what type of argument should be passed
as the first argument to the callback: as the first argument to the callback:
A.1) 'array' (the default) causes the results of A.1) `'array'` (the default) causes the results of
`stmt.get([])` to be passed to passed on and/or appended to `stmt.get([])` to be passed to passed on and/or appended to
`resultRows`. `resultRows`.
A.2) 'object' causes the results of A.2) `'object'` causes the results of
`stmt.get(Object.create(null))` to be passed to the `stmt.get(Object.create(null))` to be passed to the
`callback` and/or appended to `resultRows`. Achtung: an SQL `callback` and/or appended to `resultRows`. Achtung: an SQL
result may have multiple columns with identical names. In result may have multiple columns with identical names. In
that case, the right-most column will be the one set in this that case, the right-most column will be the one set in this
object! object!
A.3) 'stmt' causes the current Stmt to be passed to the A.3) `'stmt'` causes the current Stmt to be passed to the
callback, but this mode will trigger an exception if callback, but this mode will trigger an exception if
`resultRows` is an array because appending the statement to `resultRows` is an array because appending the statement to
the array would be unhelpful. the array would be unhelpful.
@ -491,7 +501,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
Any other `rowMode` value triggers an exception. Any other `rowMode` value triggers an exception.
- .resultRows: if this is an array, it functions similarly to - `.resultRows`: if this is an array, it functions similarly to
the `callback` option: each row of the result set (if any), the `callback` option: each row of the result set (if any),
with the exception that the `rowMode` 'stmt' is not legal. It with the exception that the `rowMode` 'stmt' is not legal. It
is legal to use both `resultRows` and `callback`, but is legal to use both `resultRows` and `callback`, but
@ -499,12 +509,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
and can be used over a WebWorker-style message interface. and can be used over a WebWorker-style message interface.
exec() throws if `resultRows` is set and `rowMode` is 'stmt'. exec() throws if `resultRows` is set and `rowMode` is 'stmt'.
- .columnNames: if this is an array, the column names of the - `.columnNames`: if this is an array, the column names of the
result set are stored in this array before the callback (if result set are stored in this array before the callback (if
any) is triggered (regardless of whether the query produces any any) is triggered (regardless of whether the query produces any
result rows). If no statement has result columns, this value is result rows). If no statement has result columns, this value is
unchanged. Achtung: an SQL result may have multiple columns with unchanged. Achtung: an SQL result may have multiple columns
identical names. with identical names.
*/ */
exec: function(/*(sql [,obj]) || (obj)*/){ exec: function(/*(sql [,obj]) || (obj)*/){
affirmDbOpen(this); affirmDbOpen(this);
@ -517,11 +527,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const callback = opt.callback; const callback = opt.callback;
let resultRows = (Array.isArray(opt.resultRows) let resultRows = (Array.isArray(opt.resultRows)
? opt.resultRows : undefined); ? opt.resultRows : undefined);
let rowMode = (((callback||resultRows) && (undefined!==opt.rowMode))
? opt.rowMode : undefined);
let stmt; let stmt;
let bind = opt.bind; let bind = opt.bind;
let runFirstQuery = !!(arg.cbArg || opt.columnNames) /* true to evaluate the first result-returning query */; let evalFirstResult = !!(arg.cbArg || opt.columnNames) /* true to evaluate the first result-returning query */;
const stack = wasm.scopedAllocPush(); const stack = wasm.scopedAllocPush();
try{ try{
const isTA = util.isSQLableTypedArray(arg.sql) const isTA = util.isSQLableTypedArray(arg.sql)
@ -565,10 +573,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
stmt.bind(bind); stmt.bind(bind);
bind = null; bind = null;
} }
if(runFirstQuery && stmt.columnCount){ if(evalFirstResult && stmt.columnCount){
/* Only forward SELECT results for the FIRST query /* Only forward SELECT results for the FIRST query
in the SQL which potentially has them. */ in the SQL which potentially has them. */
runFirstQuery = false; evalFirstResult = false;
if(Array.isArray(opt.columnNames)){ if(Array.isArray(opt.columnNames)){
stmt.getColumnNames(opt.columnNames); stmt.getColumnNames(opt.columnNames);
} }
@ -580,7 +588,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
stmt._isLocked = false; stmt._isLocked = false;
} }
}else{ }else{
// Do we need to while(stmt.step()){} here?
stmt.step(); stmt.step();
} }
stmt.finalize(); stmt.finalize();
@ -679,8 +686,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
let i, pVal, valType, arg; let i, pVal, valType, arg;
const tgt = []; const tgt = [];
for(i = 0; i < argc; ++i){ for(i = 0; i < argc; ++i){
pVal = capi.wasm.getMemValue(pArgv + (capi.wasm.ptrSizeof * i), pVal = capi.wasm.getPtrValue(pArgv + (capi.wasm.ptrSizeof * i));
capi.wasm.ptrIR);
/** /**
Curiously: despite ostensibly requiring 8-byte Curiously: despite ostensibly requiring 8-byte
alignment, the pArgv array is parcelled into chunks of alignment, the pArgv array is parcelled into chunks of

View File

@ -25,7 +25,9 @@
<progress value="0" max="100" id="module-progress" hidden='1'></progress> <progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits --> </div><!-- /emscripten bits -->
<p> <p>
This page is for running extracts from the output of <tt>speedtest --script</tt>. This page is for batch-running extracts from the output
of <tt>speedtest1 --script</tt>, as well as other standalone SQL
scripts.
</p> </p>
<p id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list <p id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list
file. Run "make batch" from this directory to generate it. file. Run "make batch" from this directory to generate it.

View File

@ -0,0 +1,28 @@
WITH RECURSIVE
input(sud) AS (
VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')
),
digits(z, lp) AS (
VALUES('1', 1)
UNION ALL SELECT
CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9
),
x(s, ind) AS (
SELECT sud, instr(sud, '.') FROM input
UNION ALL
SELECT
substr(s, 1, ind-1) || z || substr(s, ind+1),
instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )
FROM x, digits AS z
WHERE ind>0
AND NOT EXISTS (
SELECT 1
FROM digits AS lp
WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)
OR z.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1)
OR z.z = substr(s, (((ind-1)/3) % 3) * 3
+ ((ind-1)/27) * 27 + lp
+ ((lp-1) / 3) * 6, 1)
)
)
SELECT s FROM x WHERE ind=0;

View File

@ -1,5 +1,5 @@
C wasm:\sminor\stext\sand\sbuild\scleanups. C Minor\scleanups\sin\sOO\sAPI\s#1.\sAdd\sSudoku\sSQL\sto\sbatch-runner.js's\slist.
D 2022-09-03T11:41:44.176 D 2022-09-05T13:24:08.577
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -483,13 +483,13 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
F ext/wasm/api/sqlite3-api-cleanup.js 1a12e64060c2cb0defd34656a76a9b1d7ed58459c290249bb31567c806fd44de F ext/wasm/api/sqlite3-api-cleanup.js 1a12e64060c2cb0defd34656a76a9b1d7ed58459c290249bb31567c806fd44de
F ext/wasm/api/sqlite3-api-glue.js 67ca83974410961953eeaa1dfed3518530d68381729ed1d27f95122f5baeabd3 F ext/wasm/api/sqlite3-api-glue.js 67ca83974410961953eeaa1dfed3518530d68381729ed1d27f95122f5baeabd3
F ext/wasm/api/sqlite3-api-oo1.js 183e863eedaba547ffe4981ab95797813b60da46749992bca400d2646e5ccd82 F ext/wasm/api/sqlite3-api-oo1.js 8818c96272ed70e8a95d09b10f2381df94a79de0d722ef9057005e6594db2f33
F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
F ext/wasm/api/sqlite3-api-prologue.js 2d5c5d3355f55eefe51922cec5bfedbec0f8300db98a17685ab7a34a03953c7a F ext/wasm/api/sqlite3-api-prologue.js 2d5c5d3355f55eefe51922cec5bfedbec0f8300db98a17685ab7a34a03953c7a
F ext/wasm/api/sqlite3-api-worker1.js 73579555563b789785ae83724014eaf31811073aad9be6596c8336ffb51edd71 F ext/wasm/api/sqlite3-api-worker1.js 73579555563b789785ae83724014eaf31811073aad9be6596c8336ffb51edd71
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c 0d81282eaeff2a6e9fc5c28a388c5c5b45cf25a9393992fa511ac009b27df982 F ext/wasm/api/sqlite3-wasm.c 0d81282eaeff2a6e9fc5c28a388c5c5b45cf25a9393992fa511ac009b27df982
F ext/wasm/batch-runner.html 439245594711981831f2775f1426fd20d73a9b1bbf53f2cbbfc1194fa069891c F ext/wasm/batch-runner.html 2d44d99a556c46f586d3319003dd281dd0eb6a13eeadde3eab05ba81eec9ff8a
F ext/wasm/batch-runner.js a727cbbffe63fd17fb5a590dc679f0b13bd51880e8f84b461d7df246417689e8 F ext/wasm/batch-runner.js a727cbbffe63fd17fb5a590dc679f0b13bd51880e8f84b461d7df246417689e8
F ext/wasm/common/SqliteTestUtil.js 7a543e238c2ebda922c85076abda017d0480944fdfee576692a0c3a580319ebd F ext/wasm/common/SqliteTestUtil.js 7a543e238c2ebda922c85076abda017d0480944fdfee576692a0c3a580319ebd
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
@ -512,6 +512,7 @@ F ext/wasm/scratchpad-opfs-worker.js 3ec2868c669713145c76eb5877c64a1b20741f74181
F ext/wasm/scratchpad-opfs-worker2.js 5f2237427ac537b8580b1c659ff14ad2621d1694043eaaf41ae18dbfef2e48c0 F ext/wasm/scratchpad-opfs-worker2.js 5f2237427ac537b8580b1c659ff14ad2621d1694043eaaf41ae18dbfef2e48c0
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
F ext/wasm/sqlite3-worker1-promiser.js 92b8da5f38439ffec459a8215775d30fa498bc0f1ab929ff341fc3dd479660b9 F ext/wasm/sqlite3-worker1-promiser.js 92b8da5f38439ffec459a8215775d30fa498bc0f1ab929ff341fc3dd479660b9
F ext/wasm/sqlite3-worker1.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e F ext/wasm/sqlite3-worker1.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893 F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
@ -2013,8 +2014,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P b26e2bc05537a1f451db1bdd36a824d71c3ea25a130b6285f31ff9799d65fa7a P 36ceef94e1935f5e85f79e489cd0ed265a77820fb68329c190794df5e076bf84
R be49009f54e0ae14227cc16ba0e36553 R 7441dbef21a285816a3b01822ba89eea
U stephan U stephan
Z eee0918a1e799dd377ca7c8eb624a8df Z 1c45c40df6428914f663fd75d3ed35bb
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
36ceef94e1935f5e85f79e489cd0ed265a77820fb68329c190794df5e076bf84 4488cb5798f34cbba14eb8e2aa5da8420c14a85d37d278d357406aedd5c3a9e5