Add the fullkey column to both json_each() and json_tree().
FossilOrigin-Name: 15dd99431e9ddd0fbdbb8dcc921687b0c6d26a29
This commit is contained in:
parent
b1b124d482
commit
4af352d47e
158
ext/misc/json.c
158
ext/misc/json.c
@ -27,6 +27,7 @@ SQLITE_EXTENSION_INIT1
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Unsigned integer types */
|
||||
typedef sqlite3_uint64 u64;
|
||||
@ -181,6 +182,17 @@ static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
|
||||
p->nUsed += N;
|
||||
}
|
||||
|
||||
/* Append formatted text (not to exceed N bytes) to the JsonString.
|
||||
*/
|
||||
static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
|
||||
va_start(ap, zFormat);
|
||||
sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
|
||||
va_end(ap);
|
||||
p->nUsed += (int)strlen(p->zBuf+p->nUsed);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Append the zero-terminated string zIn
|
||||
*/
|
||||
@ -1256,17 +1268,19 @@ static int jsonEachConnect(
|
||||
int rc;
|
||||
|
||||
/* Column numbers */
|
||||
#define JEACH_KEY 0
|
||||
#define JEACH_VALUE 1
|
||||
#define JEACH_TYPE 2
|
||||
#define JEACH_ATOM 3
|
||||
#define JEACH_ID 4
|
||||
#define JEACH_PARENT 5
|
||||
#define JEACH_JSON 6
|
||||
#define JEACH_PATH 7
|
||||
#define JEACH_KEY 0
|
||||
#define JEACH_VALUE 1
|
||||
#define JEACH_TYPE 2
|
||||
#define JEACH_ATOM 3
|
||||
#define JEACH_ID 4
|
||||
#define JEACH_PARENT 5
|
||||
#define JEACH_FULLKEY 6
|
||||
#define JEACH_JSON 7
|
||||
#define JEACH_PATH 8
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(key,value,type,atom,id,parent,json hidden,path hidden)");
|
||||
"CREATE TABLE x(key,value,type,atom,id,parent,fullkey,"
|
||||
"json HIDDEN,path HIDDEN)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
@ -1331,47 +1345,71 @@ static int jsonEachEof(sqlite3_vtab_cursor *cur){
|
||||
}
|
||||
|
||||
/* Advance the cursor to the next element for json_tree() */
|
||||
static int jsonEachNextTree(sqlite3_vtab_cursor *cur){
|
||||
static int jsonEachNext(sqlite3_vtab_cursor *cur){
|
||||
JsonEachCursor *p = (JsonEachCursor*)cur;
|
||||
if( p->i==0 ){
|
||||
p->i = 1;
|
||||
}else if( p->sParse.aNode[p->sParse.aUp[p->i]].eType==JSON_OBJECT ){
|
||||
p->i += 2;
|
||||
if( p->bRecursive ){
|
||||
if( p->i==0 ){
|
||||
p->i = 1;
|
||||
}else if( p->sParse.aNode[p->sParse.aUp[p->i]].eType==JSON_OBJECT ){
|
||||
p->i += 2;
|
||||
}else{
|
||||
p->i++;
|
||||
}
|
||||
p->iRowid++;
|
||||
if( p->i<p->sParse.nNode ){
|
||||
JsonNode *pUp = &p->sParse.aNode[p->sParse.aUp[p->i]];
|
||||
p->eType = pUp->eType;
|
||||
if( pUp->eType==JSON_ARRAY ) pUp->u.iKey++;
|
||||
if( p->sParse.aNode[p->i].eType==JSON_ARRAY ){
|
||||
p->sParse.aNode[p->i].u.iKey = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
p->i++;
|
||||
}
|
||||
p->iRowid++;
|
||||
if( p->i<p->sParse.nNode ){
|
||||
JsonNode *pUp = &p->sParse.aNode[p->sParse.aUp[p->i]];
|
||||
p->eType = pUp->eType;
|
||||
if( pUp->eType==JSON_ARRAY ) pUp->u.iKey++;
|
||||
if( p->sParse.aNode[p->i].eType==JSON_ARRAY ){
|
||||
p->sParse.aNode[p->i].u.iKey = 0;
|
||||
switch( p->eType ){
|
||||
case JSON_ARRAY: {
|
||||
p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
|
||||
p->iRowid++;
|
||||
break;
|
||||
}
|
||||
case JSON_OBJECT: {
|
||||
p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
|
||||
p->iRowid++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
p->i = p->iEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Advance the cursor to the next element for json_each() */
|
||||
static int jsonEachNextEach(sqlite3_vtab_cursor *cur){
|
||||
JsonEachCursor *p = (JsonEachCursor*)cur;
|
||||
switch( p->eType ){
|
||||
case JSON_ARRAY: {
|
||||
p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
|
||||
p->iRowid++;
|
||||
break;
|
||||
}
|
||||
case JSON_OBJECT: {
|
||||
p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
|
||||
p->iRowid++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
p->i = p->iEnd;
|
||||
break;
|
||||
}
|
||||
/* Append the name of the path for element i to pStr
|
||||
*/
|
||||
static void jsonEachComputePath(
|
||||
JsonEachCursor *p, /* The cursor */
|
||||
JsonString *pStr, /* Write the path here */
|
||||
u32 i /* Path to this element */
|
||||
){
|
||||
JsonNode *pNode, *pUp;
|
||||
u32 iUp;
|
||||
if( i==0 ){
|
||||
jsonAppendChar(pStr, '$');
|
||||
return;
|
||||
}
|
||||
iUp = p->sParse.aUp[i];
|
||||
jsonEachComputePath(p, pStr, iUp);
|
||||
pNode = &p->sParse.aNode[i];
|
||||
pUp = &p->sParse.aNode[iUp];
|
||||
if( pUp->eType==JSON_ARRAY ){
|
||||
jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
|
||||
}else{
|
||||
assert( pUp->eType==JSON_OBJECT );
|
||||
if( pNode->eType>=JSON_ARRAY ) pNode--;
|
||||
assert( pNode->eType==JSON_STRING );
|
||||
jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Return the value of a column */
|
||||
@ -1424,9 +1462,38 @@ static int jsonEachColumn(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JEACH_FULLKEY: {
|
||||
JsonString x;
|
||||
jsonInit(&x, ctx);
|
||||
if( p->bRecursive ){
|
||||
jsonEachComputePath(p, &x, p->i);
|
||||
}else{
|
||||
if( p->zPath ){
|
||||
jsonAppendRaw(&x, p->zPath, (int)strlen(p->zPath));
|
||||
}else{
|
||||
jsonAppendChar(&x, '$');
|
||||
}
|
||||
if( p->eType==JSON_ARRAY ){
|
||||
jsonPrintf(30, &x, "[%d]", p->iRowid);
|
||||
}else{
|
||||
jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
|
||||
}
|
||||
}
|
||||
jsonResult(&x);
|
||||
break;
|
||||
}
|
||||
case JEACH_PATH: {
|
||||
const char *zPath = p->zPath;
|
||||
if( zPath==0 ) zPath = "$";
|
||||
if( zPath==0 ){
|
||||
if( p->bRecursive ){
|
||||
JsonString x;
|
||||
jsonInit(&x, ctx);
|
||||
jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
|
||||
jsonResult(&x);
|
||||
break;
|
||||
}
|
||||
zPath = "$";
|
||||
}
|
||||
sqlite3_result_text(ctx, zPath, -1, SQLITE_STATIC);
|
||||
break;
|
||||
}
|
||||
@ -1517,6 +1584,7 @@ static int jsonEachFilter(
|
||||
}else{
|
||||
JsonNode *pNode;
|
||||
if( idxNum==3 ){
|
||||
p->bRecursive = 0;
|
||||
n = sqlite3_value_bytes(argv[1]);
|
||||
p->zPath = sqlite3_malloc( n+1 );
|
||||
if( p->zPath==0 ) return SQLITE_NOMEM;
|
||||
@ -1552,7 +1620,7 @@ static sqlite3_module jsonEachModule = {
|
||||
jsonEachOpenEach, /* xOpen - open a cursor */
|
||||
jsonEachClose, /* xClose - close a cursor */
|
||||
jsonEachFilter, /* xFilter - configure scan constraints */
|
||||
jsonEachNextEach, /* xNext - advance a cursor */
|
||||
jsonEachNext, /* xNext - advance a cursor */
|
||||
jsonEachEof, /* xEof - check for end of scan */
|
||||
jsonEachColumn, /* xColumn - read data */
|
||||
jsonEachRowid, /* xRowid - read data */
|
||||
@ -1576,7 +1644,7 @@ static sqlite3_module jsonTreeModule = {
|
||||
jsonEachOpenTree, /* xOpen - open a cursor */
|
||||
jsonEachClose, /* xClose - close a cursor */
|
||||
jsonEachFilter, /* xFilter - configure scan constraints */
|
||||
jsonEachNextTree, /* xNext - advance a cursor */
|
||||
jsonEachNext, /* xNext - advance a cursor */
|
||||
jsonEachEof, /* xEof - check for end of scan */
|
||||
jsonEachColumn, /* xColumn - read data */
|
||||
jsonEachRowid, /* xRowid - read data */
|
||||
|
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Merge\sheader\sfile\sfixes\sfrom\strunk.
|
||||
D 2015-08-21T19:56:45.243
|
||||
C Add\sthe\sfullkey\scolumn\sto\sboth\sjson_each()\sand\sjson_tree().
|
||||
D 2015-08-21T20:02:48.424
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 90f3097efb9a53f5fc59a4f8a08be07cf9f52c02
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -192,7 +192,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||
F ext/misc/json.c 522d833e6c4ae55b345cf25776aab335323d2f59
|
||||
F ext/misc/json.c 92bb4e5fe2956564d23f933e2140ce8e086d988b
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
||||
@ -1378,7 +1378,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 08c36e45f0d3a7b89caf823652d7543b76ac802a da3c9df09c46564353218d0163e378b880a3ce62
|
||||
R 7de9031da9783d58b8a952bc530228c5
|
||||
P 7c2713e98ffb5f0d96eb7de9514eab43f0712011
|
||||
R a1c5d56719dd38b21713ad204a82abd5
|
||||
U drh
|
||||
Z 5f4a9a3778df860327f346518d686e5d
|
||||
Z 8567373ad141fc34581702b17b3fb646
|
||||
|
@ -1 +1 @@
|
||||
7c2713e98ffb5f0d96eb7de9514eab43f0712011
|
||||
15dd99431e9ddd0fbdbb8dcc921687b0c6d26a29
|
Loading…
Reference in New Issue
Block a user