This is "the most idiomatic question in Clojure."
I use Cassandra for my database, and Alia, as my Clojure driver (both Cassandra and Alia work phenomenally well - cannot be happier).
The problem is this: Cassandra uses underscores (not dashes) in column names, and Clojure prefers underscores. So the "user key" in Clojure is "user_key" in Kassandra. What is the best way to handle mapping Cassandra column names to Clojure variables?
Since I use prepared statements for my CQL queries, I think the fact that column names contain underscores rather than dashes is more than implementation details that need to be abstracted - I often put CQL queries as strings in my Clojure , and I consider it important to present CQL as it really is. I looked at approaches that automatically change dashes to emphasize query strings, so there is a version of Clojure CQL that maps to a version of Cassandra CQL, but this seems like an unacceptable level of abstraction. In addition, you will need to use underscores when you run CQL queries directly in Cassandra to troubleshoot, so you need to keep two different representations of the column names in your head. Sounds like the wrong approach.
The approach I got is to do a mapping in a destructive Clojure map, for example:
(let [{user-key :user_key, user-name :user_name} (conn/exec-1-row-ps "select user_key,user_name from users limit 1")] )
("conn / exec-1-row-ps" is my convenient function, which simply looks at the CQL string on the map and uses the previously prepared statement, if present, or prepares the statement and forces it into map, and then executes the prepared statement and returns the first row of the result set or throws an exception if more than one row is returned).
if I use the more concise method {: keys []} destructuring, then I am stuck with underscores in Clojure variable names:
(let [{:keys [user_key user_name]} ...
This was the first approach I tried, but it becomes ugly very fast, as variable names with underscores leak through the code and go head to head with dashes with dashes. Mixing.
You have run into this problem for a long time, doing a conversion on a destructuring map where Clojure "name-variable" and Cassandra "column_name" feel the best solution side by side. It also allows me to extend short_col_nms to more descriptive name variables when I want.
This has some similarities to the mapping that Clojure does to underline file names for dashes in namespaces, so there seems to be some use case for doing this mapping. In the case of a Clojure file / namespace name, automatic mapping is performed, so the direct analogue may be a version of the destructuring {: keys []} that displays a dash to underline.
I am a relative newbie to Clojure, so I understand that there may be better ways to do this. Hence my question.
One of the improvements that I have reviewed is the macro recording, which dynamically creates a destructuring map at compile time. But I do not know how to write a macro that works at the beginning of the compilation process.