Fork me on GitHub
#honeysql
<
2024-05-06
>
quan xing11:05:32

Does honey.sql provide options like jdbc/snake-kebab-opts in next.jdbc for column style conversion when inserting data?

p-himik11:05:38

You don't need to specify anything for it to work by default - :a-b will become a_b. But if you use :quoted or :dialect that turns :a-b into "a-b", then you can use :quoted-snake to override that.

quan xing12:05:22

I want to generate sql with snake style

(-> {:insert-into [:t_test]
       :values [{:unitId "1001" :userName "Jack"}]}
      (honey.sql/format ))
hope:  insert into t_test (unit_id,user_name) values (?,?)

p-himik12:05:58

Ah, HoneySQL has built-in facilities only to convert - to _. Next.jdbc uses camel-snake-kebab - you can use it as well. I don't think there's a way for HoneySQL to convert things like :unitId into "unit_id".

quan xing12:05:47

Oh, honey.sql doesn't support this kind of column style conversion. It seems I can only use jdbc/insert! then.

p-himik12:05:53

Oh, wait - you can use register-dialect! to register your own dialect that provides the right :quote function.

quan xing12:05:18

Alright, I'll check the documentation and do some research.

👍 1
igrishaev15:05:12

You may create a function or an operator that produces something like this:

select email as "user-email" from users;
(pay attention to quotes)

igrishaev15:05:15

Ah, it's even simpler:

(format {:select [[:email "user-email"]]})

["SELECT email AS \"user-email\""]

igrishaev16:05:18

(defn make-columns [prefix cols]
    (for [col cols]
      [col (clojure.core/format "%s-%s" (name prefix) (name col))]))

(honey.sql/format {:select (make-columns :user [:id :name :email])})

["SELECT id AS \"user-id\", name AS \"user-name\", email AS \"user-email\""]

quan xing00:05:50

👍oh, self-defined conversion function.

p-himik08:05:05

The problem with the approach, given that the original question is about inserting data, is that if you feed the data in the form of maps then there will be much more work than necessary to convert all of them to use the suitable keys. If you use explicit columns and vectors of vectors, then you only need to convert the columns so it's not a big deal. But I myself would simply use a custom dialect - then there's no extra work anywhere.

igrishaev08:05:59

Right, I didn't notice that the question is about insertion. Well, the simplest way would be to turn maps into arrays of values. You take the first map as reference, and then: • make a juxter like (apply juxt (-> maps first keys) • make arrays like (map juxter maps) • then you convert the keys of the first map into colum_names like this: :`the-map-key` -> "the_map_key"

p-himik08:05:26

Why isn't the custom dialect the simplest way? It's literally calling a function on a map that has another 1-line function. And the rest HoneySQL does for you. The only downside is that the quoting will be applied everywhere. So either you have to use the same kind of keywords everywhere, or the quoting function has to be flexible. If that's a deal breaker, then yeah, pre-formatting the data would be the only way.