honeysql

Discussion of https://github.com/seancorfield/honeysql :slightly_smiling_face:
2017-11-15T10:32:58.000166Z

it looks a it like honeysql doesn't encourage to move list of fields to select outside of the query

2017-11-15T10:33:19.000488Z

because if I do then I need to do (apply h/select fields-list) for example

2017-11-15T10:33:39.000351Z

(and similarly for all the other helpers

2017-11-15T10:34:07.000342Z

but I guess it makes sense to not take vectors as input for everything since it makes a bit simpler in the common case

2017-11-15T10:46:46.000415Z

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\""]

2017-11-15T10:47:41.000258Z

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 imho

2017-11-15T10:48:54.000187Z

if 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\""]

2017-11-15T10:51:25.000266Z

and also inverting the position of join/left-join I get the same result

donaldball 2017-11-15T15:01:28.000218Z

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.

donaldball 2017-11-15T15:04:04.000545Z

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.

2017-11-15T15:09:19.000365Z

yes I understand now but not sure that the paragon with assoc is relevant

2017-11-15T15:09:58.000216Z

since assoc doesn't replace the previous statement, it still "accumulates" and only replaces value if they are the same keys

2017-11-15T15:10:55.000213Z

if it was true instead of

(-> {}
               (assoc :a 1)
               (assoc :b 2))
{:a 1, :b 2}
that should return {:b 2}

2017-11-15T15:12:14.000531Z

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

2017-11-15T15:16:11.000809Z

and also in a way when writing SQL every JOIN is generally considered a separate thing

2017-11-15T15:16:44.000639Z

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

donaldball 2017-11-15T15:43:06.000354Z

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

2017-11-15T16:02:51.000529Z

uhm yeah well I try to use the helpers since in theory they give more guarantees

2017-11-15T16:03:12.000356Z

at least you can't have a silly type like :jon which goes undetected

2017-11-15T16:03:25.000496Z

but also realised they don't really give many more guarantees either

seancorfield 2017-11-15T16:08:19.000439Z

Use merge-join @andrea.crotti

seancorfield 2017-11-15T16:08:46.000330Z

(from memory - I'm not at my desk yet)

2017-11-15T16:31:11.000917Z

mm for what @seancorfield?

seancorfield 2017-11-15T16:56:55.000565Z

When you want to add (multiple) JOINs to a query.

seancorfield 2017-11-15T16:57:12.000311Z

That's what merge-select, merge-join, and merge-where are about.

seancorfield 2017-11-15T16:58:36.000272Z

@andrea.crotti I use the merge-* versions all the time for composing query fragments together programmatically. There's a merge-left-join too.

seancorfield 2017-11-15T16:59:45.000893Z

Also merge-from, merge-right-join, and merge-full-join (Those I had to go lookup in the source/docs).

seancorfield 2017-11-15T17:01:03.000295Z

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]