Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.

public final class Postgres

  1. Object
  2. 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.

Methods

public static Postgres connect(String host, int port, String database, String user, String password, String sslMode, String caFile, int timeoutMillis, int socketTimeoutMillis) throws IOExceptionConnects, negotiates TLS when asked, authenticates, and returns a session ready for queries.
public int execute(String sql, Object[] params) throws IOExceptionRuns a statement that returns no rows, and returns the number affected.
public List query(String sql, Object[] params) throws IOExceptionRuns 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.
public void close()
public boolean isClosed()

Inherited methods

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.

sslMode is “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.

execute

public int execute(String sql, Object[] params) throws IOException
Runs a statement that returns no rows, and returns the number affected.

query

public List query(String sql, Object[] params) throws IOException
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.

close

public void close()

isClosed

public boolean isClosed()