sqlx icon indicating copy to clipboard operation
sqlx copied to clipboard

Add pg connection options creation without environment

Open mbj opened this issue 9 months ago • 6 comments

Is this a breaking change?

no.

Rationale:

I make SQL tools that need to behave correctly in situations the environment cannot be relied upon (developer boxes, my code is run as a 3rd party library etc) and where my SQL connections need to be precisely controlled by my own code.

Before my only option was to use new_without_pgpass and explicitly unset any field that may have been picked up by that function in my own code. But this is breaky as sqlx-postgresql may accumulate new fields in new releases. Also not all fields have APIs to unset the effect of env reflection.

mbj avatar Apr 19 '25 23:04 mbj

It seems a lot of users don't care or generally don't want to "just do whatever libpq does" and are perfectly happy configuring everything explicitly. So maybe that should be the default mode of operation here and maybe "do what libpq does" should be explicitly opt-in.

Yes I agree to that. Want me to re-PR this replacing new as a breaking change, adding new_with_libpq_behavior?

mbj avatar May 06 '25 01:05 mbj

Yes I agree to that. Want me to re-PR this replacing new as a breaking change, adding new_with_libpq_behavior?

I'd like to experiment with this a bit, so I'm going to open a PR of my own.

abonander avatar Jul 05 '25 01:07 abonander

Actually, on second thought, I have too many other things I still need to work on. This is what I'd go with if you want to implement it:

  • Deprecate new() (don't delete) in favor of with_libpq_defaults(), implementing the current behavior.
  • rename new_without_pgpass to default_without_env(), drop all parameters and use the following defaults:
    • host: "localhost"
    • port: 5432
    • username: "postgres" (both the direct install and Docker images use this by default)
    • ssl_mode: PgSslMode::Prefer
      • I still don't think we should force the user to choose at this point. For local development or where a TLS backend isn't enabled, this doesn't matter. For production deployment, this needs several other parameters to be set to enable a truly secure connection (CA cert, password/client cert). A naive user wouldn't immediately understand which option to choose anyway, and would likely just pass Default::default() or brute-force until they find an option that actually connects.
  • add from_url_without_env() to give an option to parse from a database URL without applying environment variables or .pgpass.

abonander avatar Jul 05 '25 01:07 abonander

I still don't think we should force the user to choose at this point. For local development or where a TLS backend isn't enabled, this doesn't matter. For production deployment, this needs several other parameters to be set to enable a truly secure connection (CA cert, password/client cert). A naive user wouldn't immediately understand which option to choose anyway, and would likely just pass Default::default() or brute-force until they find an option that actually connects.

I disagree with that sentiment, as a naive user may be lured into "yes it works so skip all investigation" with a default of Prefer. But as everything else is an improvement I'm going to simply begrudingly keep the default as Prefer and implement the rest of your request.

mbj avatar Aug 20 '25 10:08 mbj

@abonander Thinking a bit longer, what do you think about: https://github.com/launchbadge/sqlx/pull/3983, I can bypass all the concerns I have in using a project specific wrapper around PgConnectOptions, and I can be as strict as I want to be in my default behavior.

mbj avatar Aug 20 '25 11:08 mbj

Okay since #3983 is not acceptable I'll finish this one once I'm back from my vacation.

mbj avatar Aug 22 '25 22:08 mbj