]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the fullkey column to both json_each() and json_tree().
authordrh <drh@noemail.net>
Fri, 21 Aug 2015 20:02:48 +0000 (20:02 +0000)
committerdrh <drh@noemail.net>
Fri, 21 Aug 2015 20:02:48 +0000 (20:02 +0000)
FossilOrigin-Name: 15dd99431e9ddd0fbdbb8dcc921687b0c6d26a29

ext/misc/json.c
manifest
manifest.uuid

index 26cde6105636a89865aee58a444eb28fa17ab6a4..9d9bf63896c890b1882cedb46ccc17a38bca5d1f 100644 (file)
@@ -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 */
index 6e096c9ed7d19e3e0c83a27fb31a7051539beef1..a20995d28b26d667ef4437b617cf384ffb9653bc 100644 (file)
--- a/manifest
+++ b/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
index ded172cdf04843f5590a040a768a8f802da5d5d4..7f4f0b9760c941e1baa09a733ce117fdfa562d40 100644 (file)
@@ -1 +1 @@
-7c2713e98ffb5f0d96eb7de9514eab43f0712011
\ No newline at end of file
+15dd99431e9ddd0fbdbb8dcc921687b0c6d26a29
\ No newline at end of file