korma / Korma

Tasty SQL for Clojure.
http://sqlkorma.com
1.48k stars 222 forks source link

Composing with `where*` does not work #369

Closed DonDebonair closed 7 years ago

DonDebonair commented 7 years ago

I'm trying to abstract out a where-clause, so I can reuse it between queries.

This is the original code that works:

(defn transactions-for [tenant-id]
  (-> (select* transactions)
      (where {:tenant_id tenant-id})))

(defn get-transactions [tenant-id from to]
  (-> (transactions-for tenant-id)
      (where (and (>= :ended_at from)
                  (<= :ended_at to)))
      (select)))

And here I'm trying to abstract out the date-range filter clause:

(defn transactions-for [tenant-id]
  (-> (select* transactions)
      (where {:tenant_id tenant-id})))

(defn range-in [query from to]
  (where* query (and (>= :ended_at from)
                     (<= :ended_at to))))

(defn get-transactions [tenant-id from to]
  (-> (transactions-for tenant-id)
      (range-in from to)
      (select)))

This results in a ClassCastException:

java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number
  at clojure.lang.Numbers.gte(Numbers.java:233) ~[clojure-1.8.0.jar:na]
  at transaction_service.persistence.queries$range_in.invokeStatic(queries.clj:20) ~[na:na]
  at transaction_service.persistence.queries$range_in.invoke(queries.clj:19) ~[na:na]
  at transaction_service.persistence.queries$get_transactions.invokeStatic(queries.clj:25) ~[na:na]
  at transaction_service.persistence.queries$get_transactions.invoke(queries.clj:23) ~[na:na]

Line 20 here is this part: (where* query (and (>= :ended_at from)

Can you tell me what I'm doing wrong? To be honest, the documentation is a bit lacking in this regard 😃 So I don't know how where* is actually used.

immoh commented 7 years ago

I think your code will work if you replace where* with where.

The idea behind -functions is that select, update, insert and delete all execute the query in the database immediately and in order to prevent this you need to use `select,update,insertanddeleteinstead. Forfields,whereetc. you don't need to do this. Sowhere` is more of an implementation detail, and the naming is unfortunately a bit misleading.

DonDebonair commented 7 years ago

Replacing where* with where works like a charm! Thanks for the help :)