Skip to content

A Java library to read PostgreSQL libpq C library conninfo

License

Notifications You must be signed in to change notification settings

grzm/pqconninfo.alpha

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PQConninfo - Use PostgreSQL libpq conninfo with JDBC

The pqconninfo library is a Java implementation of the portions of PostgreSQL’s libpq C client library that collect connection options from the system for use in Java applications, such as with the PostgreSQL JDBC Driver.

pqconninfo reads the same environment variables, connection service files, and password files used by libpq. This includes common enviroment variables such as PGDATABASE and PGUSER, and also PGSERVICEFILE and PGPASSFILE. Connection service files (e.g., ~~/.pg_service.conf~) and password files (e.g., ~~/.pgpass~) are also read, just like libpq clients such as psql.

Not all libpq connection parameters make sense for JDBC, but those that do are used to create JDBC urls and connection properties suitable for creating connections with the PostgreSQL JDBC Driver.

Note: While the functionality is largely here, the API and behavior may change as the code gets exercised in the wild. As such, I’ve marked the artifact and package names alpha. Once it’s stable, pqconninfo will be released sans alpha. Semantic versioning is broken.

Rationale

The libpq C client library provides a number of methods to provide configuration data which can be used by any client that uses the libpq library. The PostgreSQL JDBC driver, implemented in Java, doesn’t pick up the libpq client configuration by default. If you’re using both libpq clients and JDBC, you need to use some bespoke method of client configuration if you want to share the a common client configuration source.

pqconninfo is first a Java library that reads libpq client configuration and second a tool that translates the libpq client configuration into something that is useful for the PostgreSQL JDBC driver. Being able to read libpq configuration in Java means it can be used by any Java PostgreSQL client application, and the PostgreSQL JDBC driver is just one of these. As such, pqconninfo is useful independent of just one Java client application, and why pqconninfo isn’t a PostgreSQL JDBC Driver-specific connection configurator.

Release information

<dependency>
  <groupId>com.grzm</groupId>
  <artifactId>pqconninfo.alpha</artifactId>
  <version>0.7.0</version>
</dependency>

Clojure deps.edn

com.grzm/pqconninfo.alpha {:mvn/version "0.7.0"}

Usage

API docs

Reading libpq client configuration

import com.grzm.pqconninfo.alpha.PqConninfo;
import com.grzm.pqconninfo.alpha.PqConninfoOption;
import com.grzm.pqconninfo.alpha.PqConninfoReader;
import java.sqlConnection;
import java.sql.DriverManager;
import java.util.Properties;

// Provide or override parameters fetched from the environment. This
// is particularly useful for passfile password lookups.
Properties initProps = new Properties() {{
    setProperty("dbname", "some_database");
    setProperty("user", "some_user");
}};

PqConninfo conninfo = PqConninfoReader.read(initProps);

String host = conninfo.get(PqConninfoOption.HOST);
String port = conninfo.get(PqConninfoOption.PORT);

PostgreSQL JDBC Driver connection parameters

import com.grzm.pqconninfo.alpha.jdbc.JdbcConnectionParameters;
import com.grzm.pqconninfo.alpha.jdbc.JdbcConnectionParametersReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

// ...

JdbcConnectionParameters params = JdbcConnectionParametersReader.read();

// Provide or override parameters fetched from the environment. This
// is particularly useful for passfile password lookups.
Properties initProps = new Properties() {{
    setProperty("dbname", "some_database");
    setProperty("user", "some_user");
}};
JdbcConnectionParameters params = JdbcConnectionParametersReader.read(initProps);

String url = params.getUrl();
Properties info = params.getInfo();
Connection conn = DriverManager.getConnection(url, info);

// If you want to include all parameters in the query string,
String urlWithQueryString = params.getUrlWithQueryParameters();
Connection conn = DriverManager.getConnection(urlWithParams);

libpq and pqconninfo compatibility

libpq is the reference implementation, and pqconninfo defers to how libpq works. If pqconninfo behaves differently from libpq in a meaningful way, it’s a bug. A few allowances have been made (such as using 5432 as a default connection port and attempting to use pg_config to discover a PostgreSQL installation sysconfdir), but those are open to revisiting if we find that causes issues with expected behavior.

In addition, the pqconninfo library does not do any validation of the well-formedness of passfiles or connection service files (other than what it needs to do to read them) or whether connection parameter values are valid. If a file can be parsed by libpq for particular values, it should be parsable by pqconninfo and return the same values.

Connection parameter documentation

The pgconninfo library intends to provide a simple and easy way to use libpq connection configuration with the PostgreSQL JDBC driver. When pqconninfo does not provide a faithful translation of libpq connection info to PostgreSQL JDBC connection parameters, that is a bug, and please report it.

In the same vein as libpq compatibility, this library does not intend to include extensive or authoritative documentation of either libpq or PostgreSQL JDBC connection parameters and configuration. Please refer to the revelent sections of their respective documentation.

Known issues

  • The Windows implementation is incomplete and untested, as I don’t have access to a Windows system.
  • Both libpq and the PostgreSQL JDBC driver support connection info for multiple hosts. This library doesn’t handle this yet.
  • I’ve only confirmed testing with basic parameters such as host, port, dbname, user, and password, so it’s quite possible there are issues with the libpq-to-PostgreSQL JDBC parameter translation.

Future work

  • Add an feature to provide context provider chains rather than rely on the hard-coded SystemContextFactory. This would allow alternative system detection mechanisms.

License

© 2020 Michael Glaesemann

This code is licensed under the MIT License (see LICENSE file for details), with exceptions noted in the source.

This project contains code from the excellent Hikari-CP connection pooler, which is licensed under the Apache-2.0 License.

About

A Java library to read PostgreSQL libpq C library conninfo

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published