rel8
rel8 copied to clipboard
Functions with named parameters
I watched Oliver's Zurihac talk this morning and I've already switched a few postgresql-simple queries over to rel8 :smile:
There is one that I don't know how to write well:
select token_id, token_secret
from tc.admin_log_in( p_username := ?,
p_password := ? )
I believe I could write this using function (I had not trouble doing this to implement another query that calls crypt), but I would have to specify the arguments positionally, which is the sort of error-prone thing I'm trying to avoid. Is there a recommended way to generate the named argument syntax using :=
?
Ah, I didn't even know Postgres had named parameters. I think the bigger issue here though is going to be that tc.admin_log_in
seems to itself return a query? I don't think we have a way to support functions that return queries.
The function returns a composite type, which it looks like rel8 supports? I don't know if there's a difference between that and returning a query, I'm a little fuzzy on the terminology and on PL/pgSQL in general.
create type tc.admin_log_in_result as
( code admin_log_in_result_code
, tc_admin_id integer
, token_id text
, token_secret text
);
create function tc.admin_log_in
( p_username text
, p_password text
)
returns tc.admin_log_in_result
as $$declare
...
I guess handling the function's result is covered by issue #71
Interesting, so the function itself doesn't indicate it returns a query, just a composite type, and PostgreSQL must be somehow able to work with that in FROM
. You're right that #71 should cover the ability to select from a function, so let's keep that there. For composite types, you can use:
data AdminLogInResult = AdminLogInResult
{ code :: AdminLogInResultCode
, adminId :: Int64
, tokenId :: Text
, tokenSecret :: Text
}
deriving (Generic)
deriving DBType via Composite AdminLogInResult
instance DBComposite AdminLogInResult where
compositeTypeName = "admin_log_in_result"
compositeFields = nameHKD @AdminLogInResult "code" "tc_admin_id" "token_id" "token_secret"
This still leaves us with the problem of named parameters though. Maybe we can do this with namedFunction
and the named
library.