:squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel::squirrel:
Utility functions for translating between Clojure and SQL idioms. Add [squirrel "0.1.1"] to the dependencies vector of you project.clj.
The two you need to know are to-sql and to-clj:
to-sql maps the keys of a map from Clojure style :kebab-case to SQL style :snake_case, ready for use by things like clojure.java.jdbc or yeqsl.
(require '[bugsbio.squirrel :as sq])
(sq/to-sql {:a-nice-cat 777 :some-lovely-cheese "Yes, please."})
;; => {:a_nice_cat 777 :some_lovely_cheese "Yes, please."}It also accepts an optional map of serializers that will be applied to these fields:
(sq/to-sql {:my-json-field {:a 1 :b 2}} {:my-json-field sq/json})
;; => {:my_json_field "{\"a\":1,\"b\":2}"}The keys of the serializer map should match the Clojure style key names.
to-clj maps the keys of a map from SQL style :snake_case to Clojure style :kebab-case.
(sq/to-clj {:a_nice_cat 777 :some_lovely_cheese "Yes, please."})
;; => {:a-nice-cat 777 :some-lovely-cheese "Yes, please."}It also accepts an optional map of serializers - these will be used to deserialize their respective fields.
(sq/to-clj {:my_json_field "{\"a\":1,\"b\":2}"})
;; => {:my-json-field {:a 1 :b 2}}A final nicety of to-clj is that it interprets double underscores in keys as indicating nested maps.
So a single-level map returned by a SQL query can be converted into a nice nested map for use in Clojure.
(sq/to-clj {:a 1 :b__c 2 :b__d 3 :b__e__f 4 :b__e_g "Spot the difference"})
;; => {:a 1 :b {:c 2 :d 3 :e {:f 4} :e-g "Spot the difference"}}Serializers are just anything that satisfies the bugsbio.squirrel.Serializer protocol, which requires just two functions: serialize and deserialize.
As they can do both, you can use the same map of serializers with both to-sql and to-clj.
Squirrel provides two serializers out of the box: bugsbio.squirrel/json and bugsbio.squirrel/edn.
Here's how you could define your own:
(def keyword
(reify sq/Serializer
(serialize [this v] (name v))
(deserialize [this v] (clojure.core/keyword v))))- 0.1.1 - fix bug where keys in nested maps weren't converted to kebab-case