plugins/sql: make columns an array of pointers.

`struct column` has a dynamically allocated member, which is neater if
it is a tal object itself (we allocated the member off the array, instead).
We're about to add two new members, so clean this up first.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2024-01-25 10:58:53 +10:30
parent dadbdf488c
commit 46ba105518

View File

@@ -101,7 +101,7 @@ struct table_desc {
const char *name;
/* e.g. "payments" for listsendpays */
const char *arrname;
struct column *columns;
struct column **columns;
char *update_stmt;
/* If we are a subtable */
struct table_desc *parent;
@@ -431,7 +431,7 @@ static struct command_result *process_json_subobjs(struct command *cmd,
u64 this_rowid)
{
for (size_t i = 0; i < tal_count(td->columns); i++) {
const struct column *col = &td->columns[i];
const struct column *col = td->columns[i];
struct command_result *ret;
const jsmntok_t *coltok;
@@ -477,7 +477,7 @@ static struct command_result *process_json_obj(struct command *cmd,
/* FIXME: This is O(n^2): hash td->columns and look up the other way. */
for (size_t i = 0; i < tal_count(td->columns); i++) {
const struct column *col = &td->columns[i];
const struct column *col = td->columns[i];
const jsmntok_t *coltok;
if (col->sub) {
@@ -1054,13 +1054,13 @@ static void json_add_columns(struct json_stream *js,
const struct table_desc *td)
{
for (size_t i = 0; i < tal_count(td->columns); i++) {
if (td->columns[i].sub) {
if (td->columns[i].sub->is_subobject)
json_add_columns(js, td->columns[i].sub);
if (td->columns[i]->sub) {
if (td->columns[i]->sub->is_subobject)
json_add_columns(js, td->columns[i]->sub);
continue;
}
json_add_column(js, td->columns[i].dbname,
fieldtypemap[td->columns[i].ftype].sqltype);
json_add_column(js, td->columns[i]->dbname,
fieldtypemap[td->columns[i]->ftype].sqltype);
}
}
@@ -1142,7 +1142,7 @@ static void add_sub_object(char **update_stmt, char **create_stmt,
/* sub-objects are folded into this table. */
for (size_t j = 0; j < tal_count(sub->columns); j++) {
const struct column *subcol = &sub->columns[j];
const struct column *subcol = sub->columns[j];
if (subcol->sub) {
add_sub_object(update_stmt, create_stmt, sep,
@@ -1192,7 +1192,7 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
}
for (size_t i = 0; i < tal_count(td->columns); i++) {
const struct column *col = &td->columns[i];
const struct column *col = td->columns[i];
if (col->sub) {
add_sub_object(&td->update_stmt, &create_stmt,
@@ -1216,7 +1216,7 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
do_subtables:
/* Now do any children */
for (size_t i = 0; i < tal_count(td->columns); i++) {
const struct column *col = &td->columns[i];
const struct column *col = td->columns[i];
if (col->sub)
finish_td(plugin, col->sub);
}
@@ -1261,7 +1261,8 @@ static const char *db_table_name(const tal_t *ctx, const char *cmdname)
return ret;
}
static struct table_desc *new_table_desc(struct table_desc *parent,
static struct table_desc *new_table_desc(const tal_t *ctx,
struct table_desc *parent,
const jsmntok_t *cmd,
const jsmntok_t *arrname,
bool is_subobject)
@@ -1269,7 +1270,7 @@ static struct table_desc *new_table_desc(struct table_desc *parent,
struct table_desc *td;
const char *name;
td = tal(parent, struct table_desc);
td = tal(ctx, struct table_desc);
td->cmdname = json_strdup(td, schemas, cmd);
name = db_table_name(tmpctx, td->cmdname);
if (!parent)
@@ -1279,7 +1280,7 @@ static struct table_desc *new_table_desc(struct table_desc *parent,
td->parent = parent;
td->is_subobject = is_subobject;
td->arrname = json_strdup(td, schemas, arrname);
td->columns = tal_arr(td, struct column, 0);
td->columns = tal_arr(td, struct column *, 0);
if (streq(td->name, "channels"))
td->refresh = channels_refresh;
else if (streq(td->name, "nodes"))
@@ -1298,7 +1299,7 @@ static bool find_column(const struct table_desc *td,
const char *dbname)
{
for (size_t i = 0; i < tal_count(td->columns); i++) {
if (streq(td->columns[i].dbname, dbname))
if (streq(td->columns[i]->dbname, dbname))
return true;
}
return false;
@@ -1312,19 +1313,19 @@ static void add_table_singleton(struct table_desc *td,
const jsmntok_t *name,
const jsmntok_t *tok)
{
struct column col;
struct column *col = tal(td->columns, struct column);
const jsmntok_t *type;
/* FIXME: We would need to return false here and delete table! */
assert(!ignore_column(td, tok));
type = json_get_member(schemas, tok, "type");
col.ftype = find_fieldtype(type);
col.sub = NULL;
col->ftype = find_fieldtype(type);
col->sub = NULL;
/* We name column after the JSON parent field; but jsonname is NULL so we
* know to expect an array not a member. */
col.dbname = db_column_name(td->columns, td, name);
col.jsonname = NULL;
col->dbname = db_column_name(col, td, name);
col->jsonname = NULL;
tal_arr_expand(&td->columns, col);
}
@@ -1360,7 +1361,7 @@ static void add_table_properties(struct table_desc *td,
json_for_each_obj(i, t, properties) {
const jsmntok_t *type;
struct column col;
struct column *col;
if (ignore_column(td, t))
continue;
@@ -1370,10 +1371,14 @@ static void add_table_properties(struct table_desc *td,
if (!type)
continue;
col = tal(td->columns, struct column);
/* Depends on when it was deprecated, and whether deprecations
* are enabled! */
if (is_deprecated(schemas, t+1))
if (is_deprecated(schemas, t+1)) {
tal_free(col);
continue;
}
if (json_tok_streq(schemas, type, "array")) {
const jsmntok_t *items;
@@ -1381,25 +1386,25 @@ static void add_table_properties(struct table_desc *td,
items = json_get_member(schemas, t+1, "items");
type = json_get_member(schemas, items, "type");
col.sub = new_table_desc(td, t, t, false);
col->sub = new_table_desc(col, td, t, t, false);
/* Array of primitives? Treat as single-entry obj */
if (!json_tok_streq(schemas, type, "object"))
add_table_singleton(col.sub, t, items);
add_table_singleton(col->sub, t, items);
else
add_table_object(col.sub, items);
add_table_object(col->sub, items);
} else if (json_tok_streq(schemas, type, "object")) {
col.sub = new_table_desc(td, t, t, true);
add_table_object(col.sub, t+1);
col->sub = new_table_desc(col, td, t, t, true);
add_table_object(col->sub, t+1);
} else {
col.ftype = find_fieldtype(type);
col.sub = NULL;
col->ftype = find_fieldtype(type);
col->sub = NULL;
}
col.dbname = db_column_name(td->columns, td, t);
col->dbname = db_column_name(col, td, t);
/* Some schemas repeat, assume they're the same */
if (find_column(td, col.dbname)) {
tal_free(col.dbname);
if (find_column(td, col->dbname)) {
tal_free(col);
} else {
col.jsonname = json_strdup(td->columns, schemas, t);
col->jsonname = json_strdup(col, schemas, t);
tal_arr_expand(&td->columns, col);
}
}
@@ -1434,8 +1439,14 @@ static void add_table_object(struct table_desc *td, const jsmntok_t *tok)
static void init_tablemap(struct plugin *plugin)
{
const jsmntok_t *toks, *t;
const tal_t *ctx;
size_t i;
if (plugin)
ctx = plugin;
else
ctx = tmpctx;
strmap_init(&tablemap);
toks = json_parse_simple(tmpctx, schemas, strlen(schemas));
@@ -1451,11 +1462,7 @@ static void init_tablemap(struct plugin *plugin)
type = json_get_member(schemas, items, "type");
assert(json_tok_streq(schemas, type, "object"));
td = new_table_desc(NULL, t, cmd, false);
if (plugin)
tal_steal(plugin, td);
else
tal_steal(tmpctx, td);
td = new_table_desc(ctx, NULL, t, cmd, false);
add_table_object(td, items);
if (plugin)
@@ -1543,8 +1550,8 @@ static void print_columns(const struct table_desc *td, const char *indent,
{
for (size_t i = 0; i < tal_count(td->columns); i++) {
const char *origin;
if (td->columns[i].sub) {
const struct table_desc *subtd = td->columns[i].sub;
if (td->columns[i]->sub) {
const struct table_desc *subtd = td->columns[i]->sub;
if (!subtd->is_subobject) {
const char *subindent;
@@ -1561,23 +1568,23 @@ static void print_columns(const struct table_desc *td, const char *indent,
subobjsrc = tal_fmt(tmpctx,
", from JSON object `%s`",
td->columns[i].jsonname);
td->columns[i]->jsonname);
print_columns(subtd, indent, subobjsrc);
}
continue;
}
if (streq(objsrc, "")
&& td->columns[i].jsonname
&& !streq(td->columns[i].dbname, td->columns[i].jsonname)) {
&& td->columns[i]->jsonname
&& !streq(td->columns[i]->dbname, td->columns[i]->jsonname)) {
origin = tal_fmt(tmpctx, ", from JSON field `%s`",
td->columns[i].jsonname);
td->columns[i]->jsonname);
} else
origin = "";
printf("%s- `%s` (type `%s`, sqltype `%s`%s%s)\n",
indent, td->columns[i].dbname,
fieldtypemap[td->columns[i].ftype].name,
fieldtypemap[td->columns[i].ftype].sqltype,
indent, td->columns[i]->dbname,
fieldtypemap[td->columns[i]->ftype].name,
fieldtypemap[td->columns[i]->ftype].sqltype,
origin, objsrc);
}
}