Class Postgres
A PostgreSQL client speaking the v3 frontend/backend protocol directly.
Written rather than wrapped because there is nothing to wrap: JDBC needs a
driver manager, a class loader and reflection, none of which a translated
server binary has. The protocol is small, stable (v3 has been the wire format
since 7.4) and documented, so the honest option is to speak it. The same source
runs on both targets because it is built on Tcp, which each target
implements.
Three decisions worth stating:
- The extended query protocol, always. Simple Query would be fewer round
trips, but it has no parameters, and a client with no way to bind a value is
a client whose users concatenate SQL. Parse/Bind/Execute is what makes
query(sql, params)safe by construction. - Text format for parameters and results. The binary format saves parsing at the cost of a per-type encoder on both sides, and gets subtly wrong for the types nobody tested. Text is what psql sends.
- SCRAM-SHA-256 is verified in both directions. The server's final message proves it knew the stored key; skipping that check (which a client can do and still connect successfully) leaves the handshake open to a server that only pretends to be PostgreSQL.
-
Method Summary
Modifier and TypeMethodDescriptionvoidclose()static Postgresconnect(String host, int port, String database, String user, String password, String sslMode, String caFile, int timeoutMillis, int socketTimeoutMillis) Connects, negotiates TLS when asked, authenticates, and returns a session ready for queries.intRuns a statement that returns no rows, and returns the number affected.booleanisClosed()Runs a query and returns each row as a column-name to value map, with the SAME value types the SQLite path produces: Long, Double, String, byte[] or null.
-
Method Details
-
connect
public static Postgres connect(String host, int port, String database, String user, String password, String sslMode, String caFile, int timeoutMillis, int socketTimeoutMillis) throws IOException Connects, negotiates TLS when asked, authenticates, and returns a session ready for queries.
sslModeis "require", "prefer" or "disable". "prefer" exists because it is what a local development database usually needs and a managed one usually forbids; "require" fails rather than falling back, which is the only setting that means anything against an attacker.- Throws:
IOException
-
execute
Runs a statement that returns no rows, and returns the number affected.- Throws:
IOException
-
query
Runs a query and returns each row as a column-name to value map, with the SAME value types the SQLite path produces: Long, Double, String, byte[] or null. A handler must not be able to tell which engine answered it.- Throws:
IOException
-
close
public void close() -
isClosed
public boolean isClosed()
-