I'm working with SQLite 3.13.0, and am the process of adding a new table to a
database:
CREATE TABLE settings(key TEXT PRIMARY KEY NOT NULL, value TEXT)
This table will hold arbitrarily named application defined settings. For the
value column I’d like to use JSON for every row, as some of the settings will
be structured (either as arrays or objects, possibly with nested
substructures). The json1 extension seems to cover most of what I need (without
having a separate JSON library outside of SQLite), but I've run into a problem
which might point to a missing function.
I can easily deal with arrays and objects using functions like json_array(),
but I'm having trouble with simple values, particularly strings: there appears
to be no function to turn an SQLite text value into a simple JSON text value,
without putting it in an array or object.
e.g. this is fine:
sqlite> SELECT json_array('one',2,'we"ird');
["one",2,"we\"ird"]
but I can't find a way to convert just the SQLite text 'one' into the JSON text
"one" (or 'we"ird' into "we\"ird") without the array (or object) wrapper.
A function like json_value(value) would solve the problem. It would be a single
argument function based on the implementation of json_array(), which doesn't
output the square brackets. It should also support NULL and numeric arguments,
like json_array().
Converting a simple JSON value back to native SQLite types is easy:
json_extract(json,'$'), or I can use json_each() or json_tree() to parse the
JSON values without knowing their structure.
Perhaps json_set() should be able to handle this? I tried something like this:
sqlite> SELECT json_set('null', '$', 'test');
test
It copies the string in the third parameter, but doesn't output valid JSON
because the quotes haven't been added. Is this a bug?
As an interim solution, I can modify a local copy of the json1 extension to add
my proposed function, but it would be nice if this was standard in a later
version.
Here is a draft implementation:
static void jsonValueFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString jx;
jsonInit(&jx, ctx);
jsonAppendValue(&jx, argv[0]);
jsonResult(&jx);
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
with this definition in the aFunc[] array:
{ "json_value", -1, 0, jsonValueFunc },
A workaround I've found is to use json_array('text') wrapped in SQLite
functions to strip the square brackets off the array, but that seems ugly.
An alternative solution would be that I only use JSON for the complex settings
and leave the simple ones stored using SQLite native types, but that either
means adding a column to track which ones are JSON, or having inherent
knowledge for each setting, which could lead to compatibility problems and
potential ambiguity if a future update changes to using JSON for an existing
setting, and an existing value happens to be valid JSON, such as the word
'true'.
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users