Domanda

I'm trying to dynamically add WHERE conditions to Korma SQL query

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

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

I attempted the following approaches to build the dynamic where call. Only the first one, the one with eval works. Why? 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 a newbie to Clojure and Korma

È stato utile?

Soluzione

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

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 (not the symbol) as the value for the params argument, so eval receives the list (where {:your-query nil} (or (between :freq [100 200]) ,,,)), which is what the where macro expects and knows how to handle.

The where macro parses the expression in search of some predicates which it uses to build expressions. where*, the function alternative, doesn't have that kind of functionality, so I can't think of an alternative to eval for eating the cake and having it too.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top