Skip to content

Commit 472d1b2

Browse files
committed
plugins/sql: print out part of man page referring to schemas.
We now add tables to the strmap as we allocate them, since we don't want to call "finish_td" when we're merely invoked for the documentation, and don't need a database. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 4885ef6 commit 472d1b2

File tree

1 file changed

+111
-9
lines changed

1 file changed

+111
-9
lines changed

plugins/sql.c

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
#include <common/json_param.h>
99
#include <common/json_stream.h>
1010
#include <common/memleak.h>
11+
#include <common/setup.h>
1112
#include <common/type_to_string.h>
1213
#include <errno.h>
1314
#include <fcntl.h>
1415
#include <gossipd/gossip_store_wiregen.h>
1516
#include <plugins/libplugin.h>
1617
#include <sqlite3.h>
18+
#include <stdio.h>
1719
#include <sys/stat.h>
1820
#include <sys/types.h>
1921
#include <unistd.h>
@@ -25,8 +27,6 @@ static const char schemas[] =
2527

2628
/* TODO:
2729
* 2. Refresh time in API.
28-
* 3. Colnames API to return dict.
29-
* 4. sql-schemas command.
3030
* 5. documentation.
3131
* 6. test on mainnet.
3232
* 7. Some cool query for documentation.
@@ -94,9 +94,10 @@ struct db_query {
9494
};
9595

9696
struct table_desc {
97-
/* e.g. listpeers */
97+
/* e.g. listpeers. For sub-tables, the raw name without
98+
* parent prepended */
9899
const char *cmdname;
99-
/* e.g. peers for listpeers */
100+
/* e.g. peers for listpeers, peers_channels for listpeers.channels. */
100101
const char *name;
101102
/* e.g. "payments" for listsendpays */
102103
const char *arrname;
@@ -969,7 +970,7 @@ static bool ignore_column(const struct table_desc *td, const jsmntok_t *t)
969970
return false;
970971
}
971972

972-
/* Creates sql statements, initializes table, adds to tablemap */
973+
/* Creates sql statements, initializes table */
973974
static void finish_td(struct plugin *plugin, struct table_desc *td)
974975
{
975976
char *create_stmt;
@@ -1027,8 +1028,6 @@ static void finish_td(struct plugin *plugin, struct table_desc *td)
10271028
if (err != SQLITE_OK)
10281029
plugin_err(plugin, "Could not create %s: %s", td->name, errmsg);
10291030

1030-
strmap_add(&tablemap, td->name, td);
1031-
10321031
/* Now do any children */
10331032
for (size_t i = 0; i < tal_count(td->columns); i++) {
10341033
const struct column *col = &td->columns[i];
@@ -1101,6 +1100,11 @@ static struct table_desc *new_table_desc(struct table_desc *parent,
11011100
td->refresh = nodes_refresh;
11021101
else
11031102
td->refresh = default_refresh;
1103+
1104+
/* sub-objects are a JSON thing, not a real table! */
1105+
if (!td->is_subobject)
1106+
strmap_add(&tablemap, td->name, td);
1107+
11041108
return td;
11051109
}
11061110

@@ -1238,6 +1242,7 @@ static void add_table_object(struct table_desc *td, const jsmntok_t *tok)
12381242
add_table_object(td, cond);
12391243
}
12401244

1245+
/* plugin is NULL if we're just doing --print-docs */
12411246
static void init_tablemap(struct plugin *plugin)
12421247
{
12431248
const jsmntok_t *toks, *t;
@@ -1259,10 +1264,14 @@ static void init_tablemap(struct plugin *plugin)
12591264
assert(json_tok_streq(schemas, type, "object"));
12601265

12611266
td = new_table_desc(NULL, t, cmd, false);
1262-
tal_steal(plugin, td);
1267+
if (plugin)
1268+
tal_steal(plugin, td);
1269+
else
1270+
tal_steal(tmpctx, td);
12631271
add_table_object(td, items);
12641272

1265-
finish_td(plugin, td);
1273+
if (plugin)
1274+
finish_td(plugin, td);
12661275
}
12671276
}
12681277

@@ -1315,9 +1324,102 @@ static const struct plugin_command commands[] = { {
13151324
},
13161325
};
13171326

1327+
static const char *fmt_indexes(const tal_t *ctx, const char *table)
1328+
{
1329+
char *ret = NULL;
1330+
1331+
for (size_t i = 0; i < ARRAY_SIZE(indices); i++) {
1332+
if (!streq(indices[i].tablename, table))
1333+
continue;
1334+
/* FIXME: Handle multiple indices! */
1335+
assert(!ret);
1336+
BUILD_ASSERT(ARRAY_SIZE(indices[i].fields) == 2);
1337+
if (indices[i].fields[1])
1338+
ret = tal_fmt(tmpctx, "%s and %s",
1339+
indices[i].fields[0],
1340+
indices[i].fields[1]);
1341+
else
1342+
ret = tal_fmt(tmpctx, "%s",
1343+
indices[i].fields[0]);
1344+
}
1345+
if (!ret)
1346+
return "";
1347+
return tal_fmt(ctx, " indexed by `%s`", ret);
1348+
}
1349+
1350+
static void print_columns(const struct table_desc *td, const char *indent,
1351+
const char *objsrc)
1352+
{
1353+
for (size_t i = 0; i < tal_count(td->columns); i++) {
1354+
const char *origin;
1355+
if (td->columns[i].sub) {
1356+
const struct table_desc *subtd = td->columns[i].sub;
1357+
1358+
if (!subtd->is_subobject) {
1359+
const char *subindent;
1360+
1361+
subindent = tal_fmt(tmpctx, "%s ", indent);
1362+
printf("%s- related table `%s`%s\n",
1363+
indent, subtd->name, objsrc);
1364+
printf("%s- `row` (reference to `%s.rowid`, sqltype `INTEGER`)\n"
1365+
"%s- `arrindex` (index within array, sqltype `INTEGER`)\n",
1366+
subindent, td->name, subindent);
1367+
print_columns(subtd, subindent, "");
1368+
} else {
1369+
const char *subobjsrc;
1370+
1371+
subobjsrc = tal_fmt(tmpctx,
1372+
", from JSON object `%s`",
1373+
td->columns[i].jsonname);
1374+
print_columns(subtd, indent, subobjsrc);
1375+
}
1376+
continue;
1377+
}
1378+
1379+
if (streq(objsrc, "")
1380+
&& td->columns[i].jsonname
1381+
&& !streq(td->columns[i].dbname, td->columns[i].jsonname)) {
1382+
origin = tal_fmt(tmpctx, ", from JSON field `%s`",
1383+
td->columns[i].jsonname);
1384+
} else
1385+
origin = "";
1386+
printf("%s- `%s` (type `%s`, sqltype `%s`%s%s)\n",
1387+
indent, td->columns[i].dbname,
1388+
fieldtypemap[td->columns[i].ftype].name,
1389+
fieldtypemap[td->columns[i].ftype].sqltype,
1390+
origin, objsrc);
1391+
}
1392+
}
1393+
1394+
static bool print_one_table(const char *member,
1395+
struct table_desc *td,
1396+
void *unused)
1397+
{
1398+
if (td->parent)
1399+
return true;
1400+
1401+
printf("- `%s`%s (see lightning-%s(7))\n",
1402+
member, fmt_indexes(tmpctx, member), td->cmdname);
1403+
1404+
print_columns(td, " ", "");
1405+
printf("\n");
1406+
return true;
1407+
}
1408+
13181409
int main(int argc, char *argv[])
13191410
{
13201411
setup_locale();
1412+
1413+
if (argc == 2 && streq(argv[1], "--print-docs")) {
1414+
common_setup(argv[0]);
1415+
/* plugin is NULL, so just sets up tables */
1416+
init_tablemap(NULL);
1417+
1418+
printf("The following tables are currently supported:\n");
1419+
strmap_iterate(&tablemap, print_one_table, NULL);
1420+
common_shutdown();
1421+
return 0;
1422+
}
13211423
plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands),
13221424
NULL, 0, NULL, 0, NULL, 0,
13231425
plugin_option("sqlfilename",

0 commit comments

Comments
 (0)