alexdesousa / ayesql

Library for using raw SQL in Elixir
MIT License
138 stars 14 forks source link

Zero arity queries #7

Closed meoyawn closed 4 years ago

meoyawn commented 4 years ago

Hi there, thank you so much for this library!

Is there a reason AyeSQL does not generate /0 functions when the query has no params?

-- name: foo

SELECT *
FROM foo

there is foo/1 but no foo/0

alexdesousa commented 4 years ago

Hi! I'm glad you like the library :)

Regarding the arity: every query goes from one up to two arguments. The first one are the query parameters and the optional second are the runner options e.g. your query would generate two functions:

@spec foo(keyword) :: {:ok, AyeSQL.Query.t()} | {:error, AyeSQL.Error.t()}
@spec foo(keyword, keyword) :: {:ok, AyeSQL.Query.t()} | {:error, AyeSQL.Error.t()}
def foo(parameters, options \\ [])

where:

So, there is no need for a foo/0 function given you can always do something like this:

iex> foo([])                 # foo/1
iex> foo([], runner_options) # foo/2

It's true that the first argument could have an empty list as default, but it could be confusing when using the runner options e.g:

iex> foo()                   # foo/0
iex> foo([], runner_options) # foo/2

So we end up providing the default value for the query parameters when using the runner options. As both arguments can be keyword lists, when reading or writing code we could confuse which one is which and end up with something like:

iex> foo(runner_options)

which is semantically incorrect and Dialyzer won't complain because the types match.

So in the end, I decided to be explicit at least for the first argument. If it always exists in every query, there's little chance you could confuse the query parameters with the runner options.

I hope this answers the question :)

meoyawn commented 4 years ago

thanks! Gotcha, it's tricky to design, and since I'm not passing any runner options it'll be tricky for me to come up with a solution. We'll see, maybe something will come up

alexdesousa commented 4 years ago

I will close this issue then. If you come up with a good idea, feel free to reopen this issue :)

Again, thanks for the feedback :)