From: numist Date: Wed, 23 Oct 2019 18:14:46 +0000 (+0000) Subject: Add uuid_string and uuid_blob functions X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuuid-funcs;p=thirdparty%2Fsqlite.git Add uuid_string and uuid_blob functions FossilOrigin-Name: 97ba442b8d4534ebd2971f6f10ad6e4fc7593b531ded84574dc7bf7f8e2f76cb --- diff --git a/manifest b/manifest index b23a32a8e2..4ea84f87f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\snew\sbranch\snamed\s"uuid-funcs" -D 2019-10-23T18:01:41.243 +C Add\suuid_string\sand\suuid_blob\sfunctions +D 2019-10-23T18:14:46.421 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -480,7 +480,7 @@ F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c e5dad5e67aa3caed02a41c4822d3df6a1b43fd4a19e93aa0f4a1709405c483fe F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6271fda51794b569d736eba4097d28f13080cd0c9eb66d5fcecb4b77336fae50 -F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12 +F src/func.c 3671aabebf4d7132d3ebbaa6e066a093784ab25614e7299d66d18415e1ec65f8 F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1847,10 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c118617cf08e17a6edfdfba86e3fc49132a780990b68b52724c2aaeac85f506 -R 92e3bc21380d8b35cad891a2258f3a1e -T *branch * uuid-funcs -T *sym-uuid-funcs * -T -sym-trunk * +P 815dc0437c7c069b547171b33ca433288a53688a31093e73044fb9f446d7debd +R 3557095662cc3caba9c660d323917246 U numist -Z 54f150bdc34592bc371755e5c09cc1d8 +Z f7a920e3c6b5f48ad915994ff8383770 diff --git a/manifest.uuid b/manifest.uuid index 3b41180e30..7f3c5a68e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -815dc0437c7c069b547171b33ca433288a53688a31093e73044fb9f446d7debd \ No newline at end of file +97ba442b8d4534ebd2971f6f10ad6e4fc7593b531ded84574dc7bf7f8e2f76cb \ No newline at end of file diff --git a/src/func.c b/src/func.c index 3201b6df86..9044c12d41 100644 --- a/src/func.c +++ b/src/func.c @@ -1802,6 +1802,88 @@ static void groupConcatValue(sqlite3_context *context){ # define groupConcatValue 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ +/* +** The uuid_blob() function. Interpret the argument as a RFC 4122 UUID string. +** Return a blob representing the parsed UUID. +*/ +static void uuidBlob( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int h, i, j = 0, rc = SQLITE_ERROR; + unsigned char parsed[16]; + const char *zHex; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + zHex = sqlite3_value_text(argv[0]); + if( sqlite3_value_bytes(argv[0])==36 ){ + for (i=0, h = zHex[i]; i <= 36; i++, h=zHex[i]) { + if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { + if( h !='-' ){ + break; + } + }else if (i==36 && h==0 ){ + rc = SQLITE_OK; + }else{ + if( (h<'0' || h>'9')&&(h<'a'||h>'f')&&(h<'A'||h>'F') ){ + break; + } + if( j%2 ){ + parsed[j++ / 2] |= sqlite3HexToInt(h); + }else{ + parsed[j++ / 2] = sqlite3HexToInt(h) << 4; + } + } + } + } + + if( rc ){ + sqlite3_result_error(context, "parameter is not a valid UUID", -1); + return; + }else{ + sqlite3_result_blob(context, parsed, sizeof(parsed), SQLITE_TRANSIENT); + } +} + +/* +** The uuid_string() function. Argument must be a 128-bit blob. Return a +** RFC 4122 string representation of the blob. +*/ +static void uuidString( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + if( n>16 ){ + sqlite3_result_error_toobig(context); + return; + } + if( n<16 ){ + sqlite3_result_error(context, "parameter too small to print as UUID", -1); + return; + } + z = zHex = contextMalloc(context, 36); + if( zHex ){ + for(i=0; i<16; i++, pBlob++){ + unsigned char c = *pBlob; + *(z++) = hexdigits[(c>>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + if( i==3||i==5||i==7||i==9 ){ + *(z++) = '-'; + } + } + sqlite3_result_text(context, zHex, 36, sqlite3_free); + } +} + /* ** This routine does per-connection function registration. Most ** of the built-in functions above are part of the global function set. @@ -1907,6 +1989,8 @@ void sqlite3RegisterBuiltinFunctions(void){ ** For peak efficiency, put the most frequently used function last. */ static FuncDef aBuiltinFunc[] = { + FUNCTION(uuid_str, 1, 0, 0, uuidString), + FUNCTION(uuid_blob, 1, 0, 0, uuidBlob), #ifdef SQLITE_SOUNDEX FUNCTION(soundex, 1, 0, 0, soundexFunc ), #endif