Class Postgres

java.lang.Object
com.codename1.backend.sql.Postgres

public final class Postgres extends Object

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 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.

      Throws:
      IOException
    • execute

      public int execute(String sql, Object[] params) throws IOException
      Runs a statement that returns no rows, and returns the number affected.
      Throws:
      IOException
    • 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.
      Throws:
      IOException
    • close

      public void close()
    • isClosed

      public boolean isClosed()