mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add --json and --json-block SQLTester commands.
FossilOrigin-Name: 478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5
This commit is contained in:
@ -521,7 +521,6 @@ class GlobCommand extends Command {
|
|||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
argcCheck(argv,1);
|
argcCheck(argv,1);
|
||||||
affirmNoContent(content);
|
affirmNoContent(content);
|
||||||
|
|
||||||
t.incrementTestCounter();
|
t.incrementTestCounter();
|
||||||
final String sql = t.takeInputBuffer();
|
final String sql = t.takeInputBuffer();
|
||||||
//t.verbose(argv[0]," SQL =\n",sql);
|
//t.verbose(argv[0]," SQL =\n",sql);
|
||||||
@ -539,6 +538,16 @@ class GlobCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --json command
|
||||||
|
class JsonCommand extends ResultCommand {
|
||||||
|
public JsonCommand(){ super(ResultBufferMode.ASIS); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --json-block command
|
||||||
|
class JsonBlockCommand extends TableResultCommand {
|
||||||
|
public JsonBlockCommand(){ super(true); }
|
||||||
|
}
|
||||||
|
|
||||||
//! --new command
|
//! --new command
|
||||||
class NewDbCommand extends Command {
|
class NewDbCommand extends Command {
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
@ -551,7 +560,7 @@ class NewDbCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Placeholder dummy/no-op command
|
//! Placeholder dummy/no-op commands
|
||||||
class NoopCommand extends Command {
|
class NoopCommand extends Command {
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
}
|
}
|
||||||
@ -596,15 +605,18 @@ class PrintCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --result command
|
||||||
class ResultCommand extends Command {
|
class ResultCommand extends Command {
|
||||||
|
private final ResultBufferMode bufferMode;
|
||||||
|
protected ResultCommand(ResultBufferMode bm){ bufferMode = bm; }
|
||||||
|
public ResultCommand(){ this(ResultBufferMode.ESCAPED); }
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
argcCheck(argv,0,-1);
|
argcCheck(argv,0,-1);
|
||||||
affirmNoContent(content);
|
affirmNoContent(content);
|
||||||
t.incrementTestCounter();
|
t.incrementTestCounter();
|
||||||
final String sql = t.takeInputBuffer();
|
final String sql = t.takeInputBuffer();
|
||||||
//t.verbose(argv[0]," SQL =\n",sql);
|
//t.verbose(argv[0]," SQL =\n",sql);
|
||||||
int rc = t.execSql(null, true, ResultBufferMode.ESCAPED,
|
int rc = t.execSql(null, true, bufferMode, ResultRowMode.ONELINE, sql);
|
||||||
ResultRowMode.ONELINE, sql);
|
|
||||||
final String result = t.getResultText().trim();
|
final String result = t.getResultText().trim();
|
||||||
final String sArgs = argv.length>1 ? Util.argvToString(argv) : "";
|
final String sArgs = argv.length>1 ? Util.argvToString(argv) : "";
|
||||||
//t.verbose(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs);
|
//t.verbose(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs);
|
||||||
@ -614,6 +626,7 @@ class ResultCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --run command
|
||||||
class RunCommand extends Command {
|
class RunCommand extends Command {
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
argcCheck(argv,0,1);
|
argcCheck(argv,0,1);
|
||||||
@ -630,10 +643,15 @@ class RunCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --tableresult command
|
||||||
class TableResultCommand extends Command {
|
class TableResultCommand extends Command {
|
||||||
|
private final boolean jsonMode;
|
||||||
|
protected TableResultCommand(boolean jsonMode){ this.jsonMode = jsonMode; }
|
||||||
|
public TableResultCommand(){ this(false); }
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
argcCheck(argv,0);
|
argcCheck(argv,0);
|
||||||
affirmHasContent(content);
|
affirmHasContent(content);
|
||||||
|
t.incrementTestCounter();
|
||||||
if( !content.endsWith("\n--end") ){
|
if( !content.endsWith("\n--end") ){
|
||||||
Util.toss(TestFailure.class, argv[0], " must be terminated with --end.");
|
Util.toss(TestFailure.class, argv[0], " must be terminated with --end.");
|
||||||
}else{
|
}else{
|
||||||
@ -642,7 +660,8 @@ class TableResultCommand extends Command {
|
|||||||
}
|
}
|
||||||
final String[] globs = content.split("\s*\n\s*");
|
final String[] globs = content.split("\s*\n\s*");
|
||||||
if( globs.length < 1 ){
|
if( globs.length < 1 ){
|
||||||
Util.toss(TestFailure.class, argv[0], " requires 1 or more globs.");
|
Util.toss(TestFailure.class, argv[0], " requires 1 or more ",
|
||||||
|
(jsonMode ? "json snippets" : "globs"),".");
|
||||||
}
|
}
|
||||||
final String sql = t.takeInputBuffer();
|
final String sql = t.takeInputBuffer();
|
||||||
t.execSql(null, true, ResultBufferMode.ESCAPED, ResultRowMode.NEWLINE, sql);
|
t.execSql(null, true, ResultBufferMode.ESCAPED, ResultRowMode.NEWLINE, sql);
|
||||||
@ -654,14 +673,21 @@ class TableResultCommand extends Command {
|
|||||||
}
|
}
|
||||||
for(int i = 0; i < res.length; ++i){
|
for(int i = 0; i < res.length; ++i){
|
||||||
final String glob = GlobCommand.globToStrglob(globs[i]).replaceAll("\s+"," ");
|
final String glob = GlobCommand.globToStrglob(globs[i]).replaceAll("\s+"," ");
|
||||||
if( 0 != sqlite3_strglob(glob, res[i]) ){
|
//t.verbose(argv[0]," <<",glob,">> vs <<",res[i],">>");
|
||||||
Util.toss(TestFailure.class, argv[0], " glob {",glob,
|
if( jsonMode ){
|
||||||
"} does not match: {",res[i],"}");
|
if( !glob.equals(res[i]) ){
|
||||||
|
Util.toss(TestFailure.class, argv[0], " json <<",glob,
|
||||||
|
">> does not match: <<",res[i],">>");
|
||||||
|
}
|
||||||
|
}else if( 0 != sqlite3_strglob(glob, res[i]) ){
|
||||||
|
Util.toss(TestFailure.class, argv[0], " glob <<",glob,
|
||||||
|
">> does not match: <<",res[i],">>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --testcase command
|
||||||
class TestCaseCommand extends Command {
|
class TestCaseCommand extends Command {
|
||||||
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
public void process(SQLTester t, String[] argv, String content) throws Exception{
|
||||||
argcCheck(argv,1);
|
argcCheck(argv,1);
|
||||||
@ -673,37 +699,48 @@ class TestCaseCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper for dispatching Command instances.
|
||||||
|
*/
|
||||||
class CommandDispatcher {
|
class CommandDispatcher {
|
||||||
|
|
||||||
private static java.util.Map<String,Command> commandMap =
|
private static java.util.Map<String,Command> commandMap =
|
||||||
new java.util.HashMap<>();
|
new java.util.HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a (cached) instance mapped to name, or null if no match
|
||||||
|
is found.
|
||||||
|
*/
|
||||||
static Command getCommandByName(String name){
|
static Command getCommandByName(String name){
|
||||||
// TODO? Do this dispatching using a custom annotation on
|
|
||||||
// Command impls. That requires a surprisingly huge amount
|
|
||||||
// of code, though.
|
|
||||||
Command rv = commandMap.get(name);
|
Command rv = commandMap.get(name);
|
||||||
if( null!=rv ) return rv;
|
if( null!=rv ) return rv;
|
||||||
switch(name){
|
switch(name){
|
||||||
case "close": rv = new CloseDbCommand(); break;
|
case "close": rv = new CloseDbCommand(); break;
|
||||||
case "db": rv = new DbCommand(); break;
|
case "db": rv = new DbCommand(); break;
|
||||||
case "glob": rv = new GlobCommand(); break;
|
case "glob": rv = new GlobCommand(); break;
|
||||||
case "new": rv = new NewDbCommand(); break;
|
case "json": rv = new JsonCommand(); break;
|
||||||
case "notglob": rv = new NotGlobCommand(); break;
|
case "json-block": rv = new JsonBlockCommand(); break;
|
||||||
case "null": rv = new NullCommand(); break;
|
case "new": rv = new NewDbCommand(); break;
|
||||||
case "oom": rv = new NoopCommand(); break;
|
case "notglob": rv = new NotGlobCommand(); break;
|
||||||
case "open": rv = new OpenDbCommand(); break;
|
case "null": rv = new NullCommand(); break;
|
||||||
case "print": rv = new PrintCommand(); break;
|
case "oom": rv = new NoopCommand(); break;
|
||||||
case "result": rv = new ResultCommand(); break;
|
case "open": rv = new OpenDbCommand(); break;
|
||||||
case "run": rv = new RunCommand(); break;
|
case "print": rv = new PrintCommand(); break;
|
||||||
|
case "result": rv = new ResultCommand(); break;
|
||||||
|
case "run": rv = new RunCommand(); break;
|
||||||
case "tableresult": rv = new TableResultCommand(); break;
|
case "tableresult": rv = new TableResultCommand(); break;
|
||||||
case "testcase": rv = new TestCaseCommand(); break;
|
case "testcase": rv = new TestCaseCommand(); break;
|
||||||
default: rv = null; break;
|
default: rv = null; break;
|
||||||
}
|
}
|
||||||
if( null!=rv ) commandMap.put(name, rv);
|
if( null!=rv ) commandMap.put(name, rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
/**
|
||||||
|
Treats argv[0] as a command name, looks it up with
|
||||||
|
getCommandByName(), and calls process() on that instance, passing
|
||||||
|
it arguments given to this function.
|
||||||
|
*/
|
||||||
static void dispatch(SQLTester tester, String[] argv, String content) throws Exception{
|
static void dispatch(SQLTester tester, String[] argv, String content) throws Exception{
|
||||||
final Command cmd = getCommandByName(argv[0]);
|
final Command cmd = getCommandByName(argv[0]);
|
||||||
if(null == cmd){
|
if(null == cmd){
|
||||||
@ -722,7 +759,12 @@ class CommandDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
General utilities for the SQLTester bits.
|
||||||
|
*/
|
||||||
final class Util {
|
final class Util {
|
||||||
|
|
||||||
|
//! Throws a new T, appending all msg args into a string for the message.
|
||||||
public static void toss(Class<? extends Exception> errorType, Object... msg) throws Exception {
|
public static void toss(Class<? extends Exception> errorType, Object... msg) throws Exception {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for(Object s : msg) sb.append(s);
|
for(Object s : msg) sb.append(s);
|
||||||
@ -739,6 +781,7 @@ final class Util {
|
|||||||
toss(IllegalArgumentException.class, msg);
|
toss(IllegalArgumentException.class, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Tries to delete the given file, silently ignoring failure.
|
||||||
public static void unlink(String filename){
|
public static void unlink(String filename){
|
||||||
try{
|
try{
|
||||||
final java.io.File f = new java.io.File(filename);
|
final java.io.File f = new java.io.File(filename);
|
||||||
@ -748,6 +791,11 @@ final class Util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Appends all entries in argv[1..end] into a space-separated
|
||||||
|
string, argv[0] is not included because it's expected to
|
||||||
|
be a command name.
|
||||||
|
*/
|
||||||
public static String argvToString(String[] argv){
|
public static String argvToString(String[] argv){
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for(int i = 1; i < argv.length; ++i ){
|
for(int i = 1; i < argv.length; ++i ){
|
||||||
|
@ -12,8 +12,8 @@ junk
|
|||||||
--new SQLTester.db
|
--new SQLTester.db
|
||||||
--null zilch
|
--null zilch
|
||||||
--run
|
--run
|
||||||
select 1;
|
SELECT 1;
|
||||||
select 2;
|
SELECT 2;
|
||||||
-- comment
|
-- comment
|
||||||
-- uncomment to introduce intentional syntax error
|
-- uncomment to introduce intentional syntax error
|
||||||
--oom
|
--oom
|
||||||
@ -22,24 +22,34 @@ This is from the print command's body.
|
|||||||
--print
|
--print
|
||||||
Also from the print command.
|
Also from the print command.
|
||||||
--- also ignored
|
--- also ignored
|
||||||
--testcase first
|
--testcase 1
|
||||||
select 'a', 'b';
|
SELECT 'a', 'b';
|
||||||
select 'a', 'b';
|
SELECT 'a', 'b';
|
||||||
--result a b a b
|
--result a b a b
|
||||||
--testcase second
|
--testcase 2
|
||||||
select 123
|
SELECT 123
|
||||||
--glob ###
|
--glob ###
|
||||||
--testcase third
|
--testcase 3
|
||||||
select 'a'
|
SELECT 'a'
|
||||||
--notglob #
|
--notglob #
|
||||||
--close
|
--close
|
||||||
--open SQLTester.db
|
--open SQLTester.db
|
||||||
--print Re-opened db.
|
--print Re-opened db.
|
||||||
--testcase fourth
|
--testcase fourth
|
||||||
SELECT 1, 2;
|
SELECT 1, 2;
|
||||||
SELECT 'b', 'c';
|
SELECT 'b', 'c';
|
||||||
--tableresult
|
--tableresult
|
||||||
[0-9] #
|
[0-9] #
|
||||||
b c
|
b c
|
||||||
--end
|
--end
|
||||||
|
--testcase json-array-1
|
||||||
|
SELECT json_array(1,2,3)
|
||||||
|
--json [1,2,3]
|
||||||
|
--testcase json-array-2
|
||||||
|
SELECT json_array(1,2,3);
|
||||||
|
SELECT json_object('a',1,'b',2);
|
||||||
|
--json-block
|
||||||
|
[1,2,3]
|
||||||
|
{"a":1,"b":2}
|
||||||
|
--end
|
||||||
--an-uknown-command
|
--an-uknown-command
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sSQLTester\s--tableresult\scommand.
|
C Add\s--json\sand\s--json-block\sSQLTester\scommands.
|
||||||
D 2023-08-09T13:16:10.208
|
D 2023-08-09T13:51:50.893
|
||||||
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
|
||||||
@ -266,10 +266,10 @@ F ext/jni/src/org/sqlite/jni/sqlite3_context.java d26573fc7b309228cb49786e907859
|
|||||||
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
||||||
F ext/jni/src/org/sqlite/jni/tester/Outer.java 3d9c40f8ed58ec0df05ca160986ea06ec84ec1f338b069cfba9604bbba467a01
|
F ext/jni/src/org/sqlite/jni/tester/Outer.java 3d9c40f8ed58ec0df05ca160986ea06ec84ec1f338b069cfba9604bbba467a01
|
||||||
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 59ac50bbc1abc37b34bc4cd47b564d770de2828e045ba59c056f873543de10b3
|
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 41f48e3d4834e08bf35e21f8c62b8350c61161aafb498e4961c642194c06a29d
|
||||||
F ext/jni/src/org/sqlite/jni/tester/TestScript.java f2a87c88ab23fa4601a985eb69bdc8b4f81cabfab04fdc3544ecefde207e08d4
|
F ext/jni/src/org/sqlite/jni/tester/TestScript.java f2a87c88ab23fa4601a985eb69bdc8b4f81cabfab04fdc3544ecefde207e08d4
|
||||||
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md ae1d6706f723517e03a04ab578a539fa3df66fe38adad113f10b61eabc524d09
|
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md ae1d6706f723517e03a04ab578a539fa3df66fe38adad113f10b61eabc524d09
|
||||||
F ext/jni/src/tests/000_first.test 461f465cd1e9c60f19a8fd4231721c1bbd01702d9677696d56087a58f9d2e09e
|
F ext/jni/src/tests/000_first.test ea6ac62e13a3787f3f6d402fa5e9c7a7e85b43ec11ce10e260d673be7ecc537b
|
||||||
F ext/jni/src/tests/010_ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
F ext/jni/src/tests/010_ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||||
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
||||||
@ -2090,8 +2090,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 5323e4fd254274cc527af7536c622b786394599c68eca2da6c7fc641727dbdb2
|
P 8c5b6d893df4a4e82c6d8e07507fc160b11412ede4bb903ff4e3f5ffa59a9cb9
|
||||||
R c0ec1fc5e7c5611a47b223974ef77855
|
R 90d3df2a48743fa4d0421d9f7ba4a451
|
||||||
U stephan
|
U stephan
|
||||||
Z 3ccc1c720ec01884cd7c12ccaa2f6b70
|
Z 0acfbb2c69aeffb3bdb56736e07c0e08
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
8c5b6d893df4a4e82c6d8e07507fc160b11412ede4bb903ff4e3f5ffa59a9cb9
|
478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5
|
Reference in New Issue
Block a user