[sql] add uri_encode()/uri_decode() functions

Fixes #1014
This commit is contained in:
Tim Stack 2022-07-29 23:05:16 -07:00
parent be862e0eab
commit 1f8e2bd46c
4 changed files with 145 additions and 1 deletions

View File

@ -3624,6 +3624,54 @@ upper(*str*)
----
.. _uri_decode:
uri_decode(*str*)
^^^^^^^^^^^^^^^^^
Decode the given URI-encoded string
**Parameters**
* **str\*** --- The string to decode
**Examples**
To decode '%63%75%72%6c':
.. code-block:: custsqlite
;SELECT uri_decode('%63%75%72%6c')
curl
**See Also**
:ref:`uri_encode`
----
.. _uri_encode:
uri_encode(*str*)
^^^^^^^^^^^^^^^^^
URI-encode the given string
**Parameters**
* **str\*** --- The string to URI-encode
**Examples**
To encode 'Hello, World!':
.. code-block:: custsqlite
;SELECT uri_encode('Hello, World!')
Hello%2C%20World%21
**See Also**
:ref:`uri_decode`
----
.. _xpath:
xpath(*xpath*, *xmldoc*)

View File

@ -41,6 +41,10 @@
#include "sqlite3.h"
#include "vtab_module.hh"
#if defined(HAVE_LIBCURL)
# include <curl/curl.h>
#endif
static std::string
sql_gethostbyname(const char* name_in)
{
@ -54,7 +58,8 @@ sql_gethostbyname(const char* name_in)
for (auto family : {AF_INET, AF_INET6}) {
hints.ai_family = family;
while ((rc = getaddrinfo(name_in, nullptr, &hints, ai.out()))
== EAI_AGAIN) {
== EAI_AGAIN)
{
sqlite3_sleep(10);
}
if (rc != 0) {
@ -130,6 +135,42 @@ sql_gethostbyaddr(const char* addr_str)
return buffer;
}
#if defined(HAVE_LIBCURL)
static CURL*
get_curl_easy()
{
static struct curl_wrapper {
curl_wrapper() { this->cw_value = curl_easy_init(); }
auto_mem<CURL> cw_value{curl_easy_cleanup};
} retval;
return retval.cw_value.in();
}
static auto_mem<char>
sql_uri_encode(string_fragment str)
{
auto_mem<char> retval(curl_free);
retval = curl_easy_escape(get_curl_easy(), str.data(), str.length());
return retval;
}
static auto_mem<char>
sql_uri_decode(string_fragment str)
{
auto_mem<char> retval(curl_free);
retval = curl_easy_unescape(
get_curl_easy(), str.data(), str.length(), nullptr);
return retval;
}
#endif
int
network_extension_functions(struct FuncDef** basic_funcs,
struct FuncDefAgg** agg_funcs)
@ -159,6 +200,28 @@ network_extension_functions(struct FuncDef** basic_funcs,
"SELECT gethostbyaddr('127.0.0.1')",
})),
#if defined(HAVE_LIBCURL)
sqlite_func_adapter<decltype(&sql_uri_encode), sql_uri_encode>::builder(
help_text("uri_encode", "URI-encode the given string")
.sql_function()
.with_parameter({"str", "The string to URI-encode"})
.with_tags({"uri"})
.with_example({
"To encode 'Hello, World!'",
"SELECT uri_encode('Hello, World!')",
})),
sqlite_func_adapter<decltype(&sql_uri_decode), sql_uri_decode>::builder(
help_text("uri_decode", "Decode the given URI-encoded string")
.sql_function()
.with_parameter({"str", "The string to decode"})
.with_tags({"uri"})
.with_example({
"To decode '%63%75%72%6c'",
"SELECT uri_decode('%63%75%72%6c')",
})),
#endif
{nullptr},
};

View File

@ -288,6 +288,13 @@ to_sqlite(sqlite3_context* ctx, double val)
sqlite3_result_double(ctx, val);
}
inline void
to_sqlite(sqlite3_context* ctx, auto_mem<char> str)
{
auto free_func = str.get_free_func<void(*)(void*)>();
sqlite3_result_text(ctx, str.release(), -1, free_func);
}
#define JSON_SUBTYPE 74 /* Ascii for "J" */
#define FLATTEN_SUBTYPE 0x5f

View File

@ -4027,6 +4027,32 @@ lnav@googlegroups.com[1] support@lnav.org[2]
uri_decode(str)
══════════════════════════════════════════════════════════════════════
Decode the given URI-encoded string
Parameter
str The string to decode
See Also
uri_encode()
Example
#1 To decode '%63%75%72%6c':
;SELECT uri_decode('%63%75%72%6c') 
uri_encode(str)
══════════════════════════════════════════════════════════════════════
URI-encode the given string
Parameter
str The string to URI-encode
See Also
uri_decode()
Example
#1 To encode 'Hello, World!':
;SELECT uri_encode('Hello, World!') 
xpath(xpath, xmldoc)
══════════════════════════════════════════════════════════════════════
A table-valued function that executes an xpath expression over an