honeysql

slipset 2023-06-24T09:01:49.539309Z

I don’t think this would solve any problem for me. Typing out the honey is never where I spend significant time. I tend to use the helpers, and occasionally drop down to maps/kws when I’ve spent too much time with the helpers without achieving my goal. Adding a third syntax is not going to help me much. What does throw me off from time to time is when to use a vector and when not. ie {:select :id :name} vs {:select [:id :name]}. This is all on me, as I expect this is well documented, but I feel unsure all and every time this comes up. My mental model hasn’t quite formed.

daniel.flexiana 2023-06-28T01:37:28.078269Z

https://clojurians.slack.com/archives/C66EM8D5H/p1687627158290349?thread_ts=1687597309.539309&cid=C66EM8D5H Yes. This is very helpful. Updating a query with helper/where adds the new clause using "AND". Also if you update with nil it just keeps the original query. So one can rely on that to (update query h/where (when something [:= :x 1])) or something like that. Very handy IMHO

p-himik 2023-06-24T09:07:03.270209Z

Maps are pairs of keys and values. {:select :id :name} is not just an invalid HoneySQL syntax, it's an invalid Clojure syntax. SQL clauses in HoneySQL maps are keys, whatever you can consider a parameter of a clause will go to the value position. And you have to be able to group multiple parameters together - that's why there must be a vector (or sometimes another map, depending on the clause) if there are multiple parameters (you can skip a vector if you need just one column, for example).

slipset 2023-06-24T09:09:18.100199Z

Sorry, consider the example as helpers (hh/select :id, :name) vs (hh/select [:id :name])

p-himik 2023-06-24T09:09:51.687079Z

Ah, alright. I avoid helpers so I wouldn't have any idea either. :D

slipset 2023-06-24T09:11:45.081649Z

I’m fairly confident that the first leads to select id, name and that the second leads to select id as name but I’m never certain :)

seancorfield 2023-06-24T16:10:22.469249Z

The rule of thumb -- which clearly isn't explained clearly enough in the docs, despite multiple attempts -- is that the helpers implicitly wrap their arguments in a sequence so you use one level less brackets.

seancorfield 2023-06-24T16:13:19.314639Z

https://cljdoc.org/d/com.github.seancorfield/honeysql/2.4.1033/doc/getting-started#functional-helpers -- improvements welcome (and I guess the ns docstring for helpers could contain more of this?).

p-himik 2023-06-24T16:19:33.009499Z

I think the explanation is clear, and all the docstrings of helper functions are of great help here. My comment was based solely on the fact that I never use the helpers, so haven't even checked any of the docs.

markaddleman 2023-06-24T17:15:51.669599Z

Fwiw, we never use the helpers either. Constructing the data directly is pretty easy (except for one or two oddball situations) and supports programmatically building SQL - which we do a lot

➕ 1
seancorfield 2023-06-24T17:19:18.290349Z

Funnily enough, programmatically building SQL is where I use helpers the most, to take care of the automatic merging of multiple where or select clauses, for example... (This is all great feedback -- thank you!)

seancorfield 2023-06-24T17:24:46.821479Z

I just added the (helper :foo expr) example from Getting Started to the honey.sql.helpers ns docstring (for folks who rely more on docstrings than the online docs).

markaddleman 2023-06-24T17:26:28.395559Z

Interesting. I hadn't thought about using the helpers that way. I could probably replace some custom functions.

seancorfield 2023-06-24T17:40:34.995369Z

I'm guessing that the Datalog-style quoted data structure form of query just isn't widely used with HoneySQL (yet? it's new in 2.x)...

p-himik 2023-06-24T17:51:55.140209Z

FWIW, when switching from v1 to v2 in a project that was using helpers and where I wanted to stop using helpers, I went with maps after some deliberation. While the quoted syntax is shorter, it's somewhat harder to use even without taking variables/parameters into consideration. My current IDE (Cursive) can highlight and search for a keyword, which is useful in complex queries. And it might be the most subjective thing, but for me it's much easier to think of keywords as data rather than symbols as data. When I see a symbol, my internal gauge of the chance of it being eventually resolved rises significantly, adding a bit to the overall cognitive load. Especially when it comes to stuff like and, =, >, etc.

seancorfield 2023-06-24T17:57:50.069329Z

> it's somewhat harder to use even without taking variables/parameters into consideration Yeah, this is what inspired the thinking behind formatf... I feel like the queries are easier to read but parameters are harder to deal with... and quite a few people were asking for the quoted symbol form and it was mostly easy to add in the v2 rewrite so here we are 🙂

2023-06-24T21:53:14.691769Z

fwiw I much prefer quoted symbols. I'm not totally following the proposal, but when I started using honeysql, I spent an hour or so futzing around with symbols/keywords/quoting before deciding to just (un)quote as needed.

seancorfield 2023-06-24T22:10:23.073379Z

@potetm The main issue with the quoted symbol version is how do you handle variables/parameters? In the (non-quoted) keyword version, you can put values and local symbols in and they get turned into ? and parameters automatically (because they are evaluated and are not keywords). In the quoted version, you can't do that for local symbols... ...of course, you can use ?param in the quoted symbol form and then pass {:param some-val} in the :params options but that gets a bit verbose: every parameter name is repeated -- once in the quoted symbol form with a ? and then in the options with a : -- and you need to wrap that up in {:params {..}} as well... ...so the proposal is just a shorthand so you can use ?1, ?2, ... in the quoted symbol form and provide those parameters in order in the formatf call and it "does the right thing" behind the scenes (building the {:params {:1 ... :2 ...}} options map for you).