Why does eval work where the macro does not work when creating WHERE conditions in Feed

I am trying to dynamically add WHERE clauses to a SQL Corma query

(-> the-query (where {:archived false}) (add-where-conditions params) (limit 200) (select)) 

I am trying to dynamically build a call to the korma where function. The call will look something like (where query (or (between :freq [100 200]) (between :freq [300 400]) ... )) . The make-conds helper function makes a list of arguments for the function, for example: (or (between :freq [100 200]) ...

I tried using the following approaches to build a dynamic call. Only the first one works with eval . What for? Is there a better way to do this?

 (defn add-where-conditions [query params] (eval (list 'where query (make-conds params)))) (defmacro add-where-conditions-2 [query params] (list 'where query (make-conds params))) ; broken (defmacro add-where-conditions-3 [query params] `(where ~query ~(make-conds params))) ; broken 

Disclaimer: I'm new to Clojure and Korma

+4
source share
1 answer

The reason macros don't work is because in both cases the value for the params argument is the params character. This is why in add-where-conditions-2 and add-where-conditions-3 , when the macros make a call (make-conds params) , the value that the function receives is not the list you are thinking of, but the params symbol that displays line error:

 IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:505) 

The first case works because the function receives the list (rather than the character) as the value for the params argument, so eval receives the list (where {:your-query nil} (or (between :freq [100 200]) ,,,)) , which expects the where macro and knows how to handle it.

The where macro parses an expression for some of the predicates it uses to build expressions. where* , an alternative to a function, does not have such functionality, so I can’t come up with an alternative to eval for eating a cake and having it too.

+1
source

Source: https://habr.com/ru/post/1486489/


All Articles