mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-10 17:44:22 +01:00
plugins/sql: recurse correctly into complex objects during processing.
We didn't handle the case of an array inside a subobject. But that happens when we add the next commit! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -422,6 +422,39 @@ static struct command_result *process_json_list(struct command *cmd,
|
||||
const u64 *rowid,
|
||||
const struct table_desc *td);
|
||||
|
||||
/* Process all subobject columns */
|
||||
static struct command_result *process_json_subobjs(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *t,
|
||||
const struct table_desc *td,
|
||||
u64 this_rowid)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(td->columns); i++) {
|
||||
const struct column *col = &td->columns[i];
|
||||
struct command_result *ret;
|
||||
const jsmntok_t *coltok;
|
||||
|
||||
if (!col->sub)
|
||||
continue;
|
||||
|
||||
coltok = json_get_member(buf, t, col->jsonname);
|
||||
if (!coltok)
|
||||
continue;
|
||||
|
||||
/* If it's an array, use process_json_list */
|
||||
if (!col->sub->is_subobject) {
|
||||
ret = process_json_list(cmd, buf, coltok, &this_rowid,
|
||||
col->sub);
|
||||
} else {
|
||||
ret = process_json_subobjs(cmd, buf, coltok, col->sub,
|
||||
this_rowid);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns NULL on success, otherwise has failed cmd. */
|
||||
static struct command_result *process_json_obj(struct command *cmd,
|
||||
const char *buf,
|
||||
@@ -569,23 +602,7 @@ static struct command_result *process_json_obj(struct command *cmd,
|
||||
sqlite3_errmsg(db));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tal_count(td->columns); i++) {
|
||||
const struct column *col = &td->columns[i];
|
||||
const jsmntok_t *coltok;
|
||||
struct command_result *ret;
|
||||
|
||||
if (!col->sub || col->sub->is_subobject)
|
||||
continue;
|
||||
|
||||
coltok = json_get_member(buf, t, col->jsonname);
|
||||
if (!coltok)
|
||||
continue;
|
||||
|
||||
ret = process_json_list(cmd, buf, coltok, &this_rowid, col->sub);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
return process_json_subobjs(cmd, buf, t, td, this_rowid);
|
||||
}
|
||||
|
||||
/* A list, such as in the top-level reply, or for a sub-table */
|
||||
@@ -1150,7 +1167,8 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
|
||||
|
||||
/* subobject are separate at JSON level, folded at db level! */
|
||||
if (td->is_subobject)
|
||||
return;
|
||||
/* But it might have sub-sub objects! */
|
||||
goto do_subtables;
|
||||
|
||||
/* We make an explicit rowid in each table, for subtables to access. This is
|
||||
* becuase the implicit rowid can't be used as a foreign key! */
|
||||
@@ -1160,10 +1178,14 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
|
||||
|
||||
/* If we're a child array, we reference the parent column */
|
||||
if (td->parent) {
|
||||
/* But if parent is a subobject, we reference the outer! */
|
||||
struct table_desc *parent = td->parent;
|
||||
while (parent->is_subobject)
|
||||
parent = parent->parent;
|
||||
tal_append_fmt(&create_stmt,
|
||||
"row INTEGER REFERENCES %s(rowid) ON DELETE CASCADE,"
|
||||
" arrindex INTEGER",
|
||||
td->parent->name);
|
||||
parent->name);
|
||||
tal_append_fmt(&td->update_stmt, "?,?");
|
||||
sep = ",";
|
||||
}
|
||||
@@ -1190,6 +1212,7 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
|
||||
if (err != SQLITE_OK)
|
||||
plugin_err(plugin, "Could not create %s: %s", td->name, errmsg);
|
||||
|
||||
do_subtables:
|
||||
/* Now do any children */
|
||||
for (size_t i = 0; i < tal_count(td->columns); i++) {
|
||||
const struct column *col = &td->columns[i];
|
||||
|
||||
Reference in New Issue
Block a user