PostgresqlUri (postgresql_uri v0.1.0) View Source
Parse PostgreSQL connection URIs of the form:
postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
and returns a keyword list ready for use with Postgrex.start_link/1
.
The URI format largely follows the description at https://www.postgresql.org/docs/13/libpq-connect.html#id-1.7.3.8.3.6, with parameter keywords as listed at https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-PARAMKEYWORDS .
There is only partial correspondence between the PostgreSQL parameters and the Postgrex options.
No validation is performed and unrecognized/unsupported URL parameter keywords are passed verbatim.
This means that you may be able to stuff simple string parameters into the URL to pass them on to Postgrex, but URIs crafted this way
may not be compatible with libpq
.
In particular, the following PostgreSQL URL phenomena are unhandled/untranslated:
- Parameter keywords marked as deprectated in the PostgreSQL documentation.
- Things related to the TCP connection beyond
connect_timeout
(read timeouts, keepalives, ...). - Failover (specifying multiple hosts).
- Advanced SSL configuration (beyond simply turning it on or off)
Related project: https://github.com/s-m-i-t-a/database_url — gives you an Ecto adapter rather than a keyword list.
See the documentation of parse/1
, the only exposed function, for more details and some examples.
Link to this section Summary
Functions
Parse a PostgreSQL URI into a keyword list.
Link to this section Functions
Specs
parse(nonempty_charlist()) :: keyword()
Parse a PostgreSQL URI into a keyword list.
Examples
These examples should (with suitably chosen values) also work as an argument to the psql
command-line client and make it
attempt to do the same thing as Postgrex would.
Quotidian case
iex> PostgresqlUri.parse("postgresql://someuser:somepassword@some.ser.ver:2345/somedb")
[
hostname: "some.ser.ver",
database: "somedb",
port: 2345,
username: "someuser",
password: "somepassword",
]
No-frills SSL
For the sslmode
keyword, any value but "disable" will result in enabling SSL.
iex> PostgresqlUri.parse("postgresql://someuser:somepassword@some.ser.ver/somedb?sslmode=yesplease")
[
hostname: "some.ser.ver",
database: "somedb",
username: "someuser",
password: "somepassword",
ssl: true
]
Unix socket
PostgreSQL has the concept of a "socket directory" which can hold different Unix sockets, named after port numbers. So, in order to specify a socket belonging to a server listening on a port different from the default (5432), you need to pass in a port number, even though you won't be connecting over TCP.
iex> PostgresqlUri.parse("postgresql:///somedb?user=someuser&password=somepassword&host=/path/to/socketdir&port=2345")
[
database: "somedb",
socket_dir: "/path/to/socketdir",
password: "somepassword",
port: 2345,
username: "someuser",
]
Minimal case - local Unix socket, peer authentication.
Theoretically, postgresql:///somedb
should work. However, Postgrex.start_link/1
works differently from psql
here.
psql
, absent host specification, will try to use a Unix socket, perusing the libpq
compile-time default socket directory.
Yet Postgrex will fail for this URI (demanding a password), as it doesn't know what socket directory to use.
So, to make things work for Postgrex, we will have to pass the socket directory explicitly.
The resulting URI still works as intended for psql
.
iex> PostgresqlUri.parse("postgresql:///some_db?host=/run/postgresql")
[
database: "some_db",
socket_dir: "/run/postgresql",
]