(ns clojure-sql.jdbc (:require [clojure.java.jdbc :as jdbc] [clojure-sql.query :refer [QueryExecutor fn->QueryExecutor]] [clojure-sql.compiler :as compiler] ;;[clojure-sql.core :refer [set-query-executor!]] [clojure.string :as string])) (defn ^:private dotted-to-nested-map-one [obj] (reduce (fn [acc [key val]] (let [dotted (name key) keys (string/split dotted #"\.") keywords (map keyword keys)] (assert (nil? (get-in acc keywords nil)) "Error converting fields to maps: conflicting paths.") (assoc-in acc keywords val))) {} obj)) (defn ^:private dotted-to-nested-maps [objs] (mapv dotted-to-nested-map-one objs)) (defn jdbc-executor [connection-string & [db-type]] (let [db-type (or db-type (keyword (second (re-find #"^([^:]+)" connection-string))))] (reify QueryExecutor (query [_ query] (let [compiled (compiler/compile-select db-type query)] (jdbc/with-connection connection-string (jdbc/with-query-results results compiled (dotted-to-nested-maps results))))) (insert! [_ query records] (let [compiled (compiler/compile-insert db-type query records)] (jdbc/with-connection connection-string (jdbc/do-prepared-return-keys (first compiled) (next compiled))))) (update! [_ query partial-record] (let [compiled (compiler/compile-update db-type query partial-record)] (jdbc/with-connection connection-string (jdbc/do-prepared-return-keys (first compiled) (next compiled))))) (delete! [_ query] (let [compiled (compiler/compile-delete db-type query)] (jdbc/with-connection connection-string (first (jdbc/do-prepared (first compiled) (next compiled)))))))))