it looks a it like honeysql doesn't encourage to move list of fields to select outside of the query
because if I do then I need to do (apply h/select fields-list)
for example
(and similarly for all the other helpers
but I guess it makes sense to not take vectors as input for everything since it makes a bit simpler in the common case
I'm also a bit confused by joins, so two joins in a row doesn't work
(-> (h/select :id)
(h/from :t1)
(h/join :t2 [:= :t1.id :t2.tid])
(h/join :t3 [:= :t2.id :t3.tid])
(sql/format :quoting :ansi :allow-dashed-names? true))
["SELECT \"id\" FROM \"t1\" INNER JOIN \"t3\" ON \"t2\".\"id\" = \"t3\".\"tid\""]
I can write it like this
(-> (h/select :id)
(h/from :t1)
(h/join :t2 [:= :t1.id :t2.tid]
:t3 [:= :t2.id :t3.tid])
(sql/format :quoting :ansi :allow-dashed-names? true))
which does work, but the previous example should not fail silently imhoif I have different types of joins however it does work, but it inverts the order
(-> (h/select :id)
(h/from :t1)
(h/left-join :t2 [:= :t1.id :t2.tid])
(h/join :t3 [:= :t2.id :t3.tid])
(sql/format :quoting :ansi :allow-dashed-names? true))
["SELECT \"id\" FROM \"t1\" INNER JOIN \"t3\" ON \"t2\".\"id\" = \"t3\".\"tid\" LEFT JOIN \"t2\" ON \"t1\".\"id\" = \"t2\".\"tid\""]
and also inverting the position of join/left-join
I get the same result
IIRC, the order of clauses in the resulting query is determined by their type, not by their insertion order. I don’t think that changes the results for joins.
The query builder helper functions don’t complain when you’re replacing a clause in a query map instead of setting one that has no value. I agree that’s initially confusing perhaps but similar to how assoc
works and I’d venture it’s generally the behavior one would like.
yes I understand now but not sure that the paragon with assoc
is relevant
since assoc
doesn't replace the previous statement, it still "accumulates" and only replaces value if they are the same keys
if it was true instead of
(-> {}
(assoc :a 1)
(assoc :b 2))
{:a 1, :b 2}
that should return {:b 2}
and well the order probably doesn't matter, but maintaining it would still be nice so it's kind of easier to compare the result query with what you wnat
and also in a way when writing SQL every JOIN
is generally considered a separate thing
in honeysql they are just grouped together by type of statement, which seems a bit arbitrary in a way, writing them separately would make more sense to me
FWIW when I write honeysql, I never use the query helper fns, I just update the query map directly, so e.g. (update query :join (fnil conj []) [:t3 [:= :t2.id :t3.tid]])
or similar
uhm yeah well I try to use the helpers since in theory they give more guarantees
at least you can't have a silly type like :jon
which goes undetected
but also realised they don't really give many more guarantees either
Use merge-join
@andrea.crotti
(from memory - I'm not at my desk yet)
mm for what @seancorfield?
When you want to add (multiple) JOIN
s to a query.
That's what merge-select
, merge-join
, and merge-where
are about.
@andrea.crotti I use the merge-*
versions all the time for composing query fragments together programmatically. There's a merge-left-join
too.
Also merge-from
, merge-right-join
, and merge-full-join
(Those I had to go lookup in the source/docs).
A few of them are mentioned in the README:
> To add to clauses instead of replacing them, use merge-select
, merge-where
, etc.:
(-> sqlmap
(merge-select :d :e)
(merge-where [:> :b 10])
sql/format)
=> ["SELECT a, b, c, d, e FROM foo WHERE (f.a = ? AND b > ?)" "baz" 10]