Hi,
On 9 Mrz., 08:52, Andreas Kostler <[email protected]>
wrote:
>>> (defn make-native-query [db str foo]
>>> (. (proxy [ONativeSynchQuery]
>>> [db str foo]
>>> (filter [rec]
>>> (.. rec (field "location") (eq "Madrid") and (field
>>> "name") (eq "Dhali") go))) run objs))
>
> Well, I don't want the symbols location, name, etc to be evaluated...e.g. I
> couldn't use location if not in a macro, right?
> Secondly, the structure isn't quite as uniform. Like in the example above
> (.. rec (create-query [[location eq "Madrid"] and [name eq "Dhali"]])) should
> expand to something like
>
> (.. rec (field "location") (eq "Madrid") and (field "name") (eq "Dhali"))
>
> Maybe I'm still missing something but I can't see how I could do that without
> a macro...
You could use keywords.
(query rec [[:location :eq "Madrid"] :and [:name :eq "Dhali"]])
where query is defined as
(defmulti query (fn [_ [_ op _]] op))
(defmethod query :and
[rec [lhs _ rhs]]
(-> rec (query lhs) .and (query rhs)))
(defmethod query :eq
[rec [lhs _ rhs]]
(-> rec (.field (name lhs)) (.eq rhs)))
Then there is no need for a macro and you can extend things for other
operators like :neq, :or and the like. If you don't need this
extensibility you can even go with a single function and a case.
(defn query
[rec [lhs op rhs]]
(case op
:and (-> rec (query lhs) .and (query rhs))
:eq (-> rec (.field (name lhs)) (.eq rhs))))
This should read pretty much like the API you have to use.
If you really need macros the above should easy to modify:
(defmacro query
[rec [lhs op rhs]]
(case op
'and `(-> ~rec (query ~lhs) .and (query ~rhs))
'eq `(-> ~rec (.field ~(name lhs)) (.eq ~rhs))))
Not tested, though.
By using the .notation for methods you don't have to ~' quote things
in the macro. And by using -> instead of .. you can also use plain
Clojure functions and macros besides method calls.
You cannot write a macro which expands the way you want it to without
significant effort with code walking and a surrounding macro. Which is
not appropriate for this case, I think.
Hope this helps.
Sincerely
Meikel
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en