From 1d9e7cf079dac3ea30d4de9d4d8567b44ceee572 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 16 Sep 2020 15:52:52 +0200 Subject: [PATCH] db: Add support for key-value pair DSNs in postgresql These are simple space-separated key-value pair sets of options instead of the URI style DSNs, but they are also much more flexible allowing the user to specify client SSL certificates, server certificates, compression and encryption levels, and much more (see [1] for more information) [1]: https://www.postgresql.org/docs/9.1/libpq-connect.html Changelog-Added: db: Added support for key-value DSNs for postgresql, allowing for a wider variety of configurations and environments. --- wallet/db_postgres.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/wallet/db_postgres.c b/wallet/db_postgres.c index d6a523383..6a0dbb431 100644 --- a/wallet/db_postgres.c +++ b/wallet/db_postgres.c @@ -17,7 +17,24 @@ static bool db_postgres_setup(struct db *db) { - db->conn = PQconnectdb(db->filename); + size_t prefix_len = strlen("postgres://"); + + /* We attempt to parse the connection string without the `postgres://` + prefix first, so we can correctly handle the key-value-pair style of + DSN that postgresql supports. If that fails we try with the full + string, which matches the `scheme://user:password@host:port/dbname` + style of DSNs. The call to `PQconninfoParse` here is just to verify + `PQconnectdb` would be able to parse it correctly, that's why the + result is discarded again immediately. */ + PQconninfoOption *info = + PQconninfoParse(db->filename + prefix_len, NULL); + + if (info != NULL) { + PQconninfoFree(info); + db->conn = PQconnectdb(db->filename + prefix_len); + } else { + db->conn = PQconnectdb(db->filename); + } if (PQstatus(db->conn) != CONNECTION_OK) { db->error = tal_fmt(db, "Could not connect to %s: %s", db->filename, PQerrorMessage(db->conn));