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 {
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, null);
ptr = capi.wasm.getMemValue(ppDb, '*');
ptr = capi.wasm.getPtrValue(ppDb);
ctor.checkRc(ptr, rc);
}catch( e ){
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
functions, its read-only `pointer` property holds its `sqlite3_stmt*`
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(){
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
sqlite3 API result code. If the result code is not falsy, this
function throws an SQLite3Error with an error message from
sqlite3_errmsg(), using dbPtr as the db handle. Note that if it's
passed a non-error code like SQLITE_ROW or SQLITE_DONE, it will
still throw but the error string might be "Not an error." The
various non-0 non-error codes need to be checked for in client
code where they are expected.
Expects to be given a DB instance or an `sqlite3*` pointer (may
be null) and an sqlite3 API result code. If the result code is
not falsy, this function throws an SQLite3Error with an error
message from sqlite3_errmsg(), using dbPtr as the db handle, or
sqlite3_errstr() if dbPtr is falsy. Note that if it's passed a
non-error code like SQLITE_ROW or SQLITE_DONE, it will still
throw but the error string might be "Not an error." The various
non-0 non-error codes need to be checked for in
client code where they are expected.
*/
DB.checkRc = function(dbPtr, sqliteResultCode){
if(sqliteResultCode){
if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
throw new SQLite3Error([
throw new SQLite3Error(
"sqlite result code",sqliteResultCode+":",
capi.sqlite3_errmsg(dbPtr) || "Unknown db error."
].join(' '));
(dbPtr
? 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
order to determine whether the Stmt instance is empty or not.
Long-time practice (with other sqlite3 script bindings)
suggests that the empty-prepare case is sufficiently rare (and
useless) that supporting it here would simply hurt overall
usability.
suggests that the empty-prepare case is sufficiently rare that
supporting it here would simply hurt overall usability.
*/
prepare: function(sql){
affirmDbOpen(this);
@ -390,7 +401,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
try{
ppStmt = capi.wasm.scopedAllocPtr()/* output (sqlite3_stmt**) arg */;
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)}
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
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
of strings. In the latter case they're concatenated together
as-is, _with no separator_ between elements, before evaluation.
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
statement in the SQL which has any bindable parameters. (Empty
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
statement is executed (but after it is prepared - we
don't have the string until after that). Empty SQL
statements are elided.
statement is executed (but after it is prepared - we don't have
the string until after that). Empty SQL statements are elided.
==================================================================
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.
==================================================================
- .callback = a function which gets called for each row of the
result set, but only if that statement has any result
- `.callback` = a function which gets called for each row of
the result set, but only if that statement has any result
_rows_. The callback's "this" is the options object. The second
argument passed to the callback is always the current Stmt
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
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...
A) A string describing what type of argument should be passed
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
`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
`callback` and/or appended to `resultRows`. Achtung: an SQL
result may have multiple columns with identical names. In
that case, the right-most column will be the one set in this
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
`resultRows` is an array because appending the statement to
the array would be unhelpful.
@ -491,7 +501,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
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),
with the exception that the `rowMode` 'stmt' is not legal. It
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.
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
any) is triggered (regardless of whether the query produces any
result rows). If no statement has result columns, this value is
unchanged. Achtung: an SQL result may have multiple columns with
identical names.
unchanged. Achtung: an SQL result may have multiple columns
with identical names.
*/
exec: function(/*(sql [,obj]) || (obj)*/){
affirmDbOpen(this);
@ -517,11 +527,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const callback = opt.callback;
let resultRows = (Array.isArray(opt.resultRows)
? opt.resultRows : undefined);
let rowMode = (((callback||resultRows) && (undefined!==opt.rowMode))
? opt.rowMode : undefined);
let stmt;
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();
try{
const isTA = util.isSQLableTypedArray(arg.sql)
@ -565,10 +573,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
stmt.bind(bind);
bind = null;
}
if(runFirstQuery && stmt.columnCount){
if(evalFirstResult && stmt.columnCount){
/* Only forward SELECT results for the FIRST query
in the SQL which potentially has them. */
runFirstQuery = false;
evalFirstResult = false;
if(Array.isArray(opt.columnNames)){
stmt.getColumnNames(opt.columnNames);
}
@ -580,7 +588,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
stmt._isLocked = false;
}
}else{
// Do we need to while(stmt.step()){} here?
stmt.step();
}
stmt.finalize();
@ -679,8 +686,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
let i, pVal, valType, arg;
const tgt = [];
for(i = 0; i < argc; ++i){
pVal = capi.wasm.getMemValue(pArgv + (capi.wasm.ptrSizeof * i),
capi.wasm.ptrIR);
pVal = capi.wasm.getPtrValue(pArgv + (capi.wasm.ptrSizeof * i));
/**
Curiously: despite ostensibly requiring 8-byte
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>
</div><!-- /emscripten bits -->
<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 id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list
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.
D 2022-09-03T11:41:44.176
C Minor\scleanups\sin\sOO\sAPI\s#1.\sAdd\sSudoku\sSQL\sto\sbatch-runner.js's\slist.
D 2022-09-05T13:24:08.577
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
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/sqlite3-api-cleanup.js 1a12e64060c2cb0defd34656a76a9b1d7ed58459c290249bb31567c806fd44de
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-prologue.js 2d5c5d3355f55eefe51922cec5bfedbec0f8300db98a17685ab7a34a03953c7a
F ext/wasm/api/sqlite3-api-worker1.js 73579555563b789785ae83724014eaf31811073aad9be6596c8336ffb51edd71
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
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/common/SqliteTestUtil.js 7a543e238c2ebda922c85076abda017d0480944fdfee576692a0c3a580319ebd
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/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
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.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e
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.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P b26e2bc05537a1f451db1bdd36a824d71c3ea25a130b6285f31ff9799d65fa7a
R be49009f54e0ae14227cc16ba0e36553
P 36ceef94e1935f5e85f79e489cd0ed265a77820fb68329c190794df5e076bf84
R 7441dbef21a285816a3b01822ba89eea
U stephan
Z eee0918a1e799dd377ca7c8eb624a8df
Z 1c45c40df6428914f663fd75d3ed35bb
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
36ceef94e1935f5e85f79e489cd0ed265a77820fb68329c190794df5e076bf84
4488cb5798f34cbba14eb8e2aa5da8420c14a85d37d278d357406aedd5c3a9e5