Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating query clauses with korma and clojure

Tags:

sql

clojure

korma

I am trying to generate korma query conditions based on a map of columns and values that I pass into a function.

I am finding that when an empty map is passed to korma's where:

(select "things"
  (where conditions))

Generates queries with an empty WHERE which causes a SQL error:

SELECT * FROM things WHERE () LIMIT 10 

However using this form:

(select "things"
  (if-not (empty? conditions) 
    (where conditions)))

Results in an error: "Wrong number of args (1) passed to: core$where"

Is there an idiomatic way of handling dynamic clauses in korma?

UPDATE

The following works, but is pretty clumsy (note the strangely necessary if format)

(defn do-select []
  (->  (select* "things") 
    (fields :id :data)
    (limit 10)))

(defn add-constraints [query conditions]
  (if (empty? conditions) 
      query
      (where query (conditions-to-clause-map conditions))))

(select (do-select) 
  (add-constraints conditions)           
  (where (is_owner? owner)))     
like image 896
Toby Hede Avatar asked Apr 14 '26 12:04

Toby Hede


1 Answers

I don't think if it is possible to generate dynamic queries without looking under the hood of korma and trying to call some private API, but that is a bad bad idea. The problem with your second code is that select and where are macros. What select does is:

(defmacro select
    [ent & body]
      `(let [query# (-> (select* ~ent)
                     ~@body)]
         (exec query#)))

As you can see it thread the select* return value to next forms and if you introduce the if clause that causes this threading to break and where gets only one value (which was your map) rather than the getting value of select* and the map, hence the error says wrong number of arguments.

As of now it seems eval with some dynamic code generation is your friend. Something like:

(eval `(select "things"
       ~(if (empty? conditions) 
           `identity
           `(where conditions))))

I haven't tried it, but I hope it gives you the idea.

like image 181
Ankur Avatar answered Apr 16 '26 01:04

Ankur