refinery icon indicating copy to clipboard operation
refinery copied to clipboard

Document connection strings for unix sockets with postgres

Open lf- opened this issue 3 years ago • 5 comments

I am using tmp-postgres for Haskell which creates a Unix socket with a connection string like host=/tmp/tmp-postgres-socket-33d7937af9c67679 dbname=postgres port=49905.

I want to use refinery-cli to apply my migrations to such a database.

According to the postgres docs, the connection string can be in several formats, which do support Unix sockets: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING

However, it seems that Refinery parses them itself:

https://github.com/rust-db/refinery/blob/36e2c219de236c95853a0aa6cd606a2d52d255f8/refinery_core/src/config.rs#L225-L243

It seems like I need to generate a connection string like so, but this was obtained largely by guessing:

{- | Serializes a 'PG.Options' into the right format for Refinery CLI, which is

 > postgres://user:pass@(urlencoded host)/db

 See <https://github.com/rust-db/refinery/blob/36e2c219de236c95853a0aa6cd606a2d52d255f8/refinery_core/src/config.rs#L225-L243>
-}
optionsToUri :: PG.Options -> Maybe (URIRef Absolute)
optionsToUri PG.Options {host, user, password, dbname, port} = do
  host' <- getLastBS host
  dbname' <- getLastBS dbname
  port' <- getLast port
  -- Postgres will be grumpy if you don't give it a user, so there's not any
  -- reasonable default here
  user' <- getLastBS user
  pure $
    URI
      { uriScheme = Scheme "postgres"
      , uriAuthority =
          Just $
            Authority
              { authorityUserInfo =
                  Just $ UserInfo user' (fromMaybe "" $ getLastBS password)
              , authorityHost = Host (cs . toLazyByteString $ urlEncode [] host')
              , authorityPort = Just $ Port port'
              }
      , uriPath = "/" <> cs dbname'
      , uriQuery = Query []
      , uriFragment = Nothing
      }
  where
    getLastBS :: Last String -> Maybe ByteString
    getLastBS s = cs <$> getLast s

lf- avatar Nov 17 '22 18:11 lf-

Hi, and thanks for the Interest! So, yeah refinery assumes you pass a connection uri, defined in the doc you linked above .
If I understand correctly it worked after you did so right? Would you be willing to submit a PR improving the documentation to make users aware of it? Thanks!

jxs avatar Nov 25 '22 12:11 jxs

that's the thing: it does not parse those as far as i can tell. it only takes the one format that i guessed by reading the code since it does the parsing itself rather than giving the whole thing to postgres.

if i remember, I'll look into filing a pr on Monday

lf- avatar Nov 25 '22 17:11 lf-

yeah, but it then returns a connection string to postgres, see here should have the same format as the input doesn't it on your case?

jxs avatar Nov 25 '22 19:11 jxs

Ah. Yes, but most of the formats supported by postgres are thus unsupported. For instance refinery seemingly discards query parameters.

lf- avatar Nov 25 '22 19:11 lf-

Ah, I see. I will gladly support them for the drivers that support them for the input urls, if you want to submit a PR :)

jxs avatar Nov 25 '22 20:11 jxs