It is kind of alien to write like this: |> (fn x -> x == “SELECT” end).()
Any better way to write or idioms?
def is_sql_select?(nil) do
false
end
def is_sql_select?(sql) when not is_nil(sql) do
sql
|> String.trim_leading()
|> String.slice(0, 6)
|> String.upcase()
|> (fn x -> x == "SELECT" end).()
end
I think the better way to do it would be to extract that to a named function, maybe use "SELECT" |> String.equivalent?("SELECT") but that does a bit more than you need.
Yes, there is a better way: put it in its own helper function with its own name.
It was a conscious choice to make this syntax obtuse, to guide people towards having more (and smaller) helper functions.
It’s not necessary to always pipe everything so I would do:
def is_sql_select?(nil) do
false
end
def is_sql_select?(sql) when not is_nil(sql) do
sql_statement =
sql
|> String.trim_leading()
|> String.slice(0, 6)
|> String.upcase()
sql_statement == "SELECT"
end
Anyway from maintenance point of view, I will select @axelson 's reply as solution.
At the same time I also get other people’s help to make this more better:
def sql_select?(nil) do
false
end
def sql_select?(sql) when not is_nil(sql) do
sql_statement =
sql
|> String.trim_leading()
|> String.slice(0, 6)
|> String.upcase()
sql_statement == "SELECT"
end
Note the convention in Elixir is to name functions/macros allowed in guards with the `is_` prefix, such as
[ `is_list/1` ](https://hexdocs.pm/elixir/Kernel.html#is_list/1). If, however, the function/macro returns a
boolean and is not allowed in guards, it should have no prefix and end with a question mark, such as
[ `Keyword.keyword?/1` ](https://hexdocs.pm/elixir/Keyword.html#keyword?/1).
Of course it’s your code and you can do what you want with your function names =D, it’s just a convention that makes reading code easier!
Language feature should support people to express the way they want. If we want work around, that also works, but not ideal. Thanks for your solution, it works.
Keep in mind that pretty much all the proposed solutions here will fail upon meeting a UNION of selects in parentheses.
Just to say that detecting sql syntax is a bit more complex than stripping leading spaces and uppercasing. Not on topic of the actual question, just thought it relevant to mention.
First keyword, yes. But your not matching first keyword, you’re matching against the first six characters, uppercases.
Even if you matched against first keyword, it would get it wrong if it came up against a query that starts with – select, followed by a newline and then some other keyword.
Trim removes whitespace - so all you’re doing is checking whether the first characters in your query (that are not whitespace) is SELECT. In the case of