我希望能够为jdbc编写以下函数:
(def db {:classname "com.mysql.jdbc.Driver"
:subprotocol "mysql"
:subname "//127.0.0.1:3306/santacsv"
:server "//127.0.0.1:3306"
:schema "santa"
:user "root"
:password "root"})
(defn has-schema? [db & [schema]])
(defn create-schema [db & [schema]])
(defn drop-schema [db & [schema]])
我不确定该怎么做。任何帮助将不胜感激
答案 0 :(得分:1)
至少,您可以使用clojure.java.jdbc并将相应的SQL写入execute!
。
或者,我会考虑使用专用的迁移库/框架。 flyway是基于java的,有一个java-api,你可以用interop调用它。
最后,有一些基于clojure的迁移库,如lobos,但我不能说它们的成熟度,所以你的里程可能非常。
答案 1 :(得分:0)
我在这里实现了自己:
https://github.com/zcaudate/manas/blob/master/src/manas/core.clj
(defmacro run-statement [env database body catch-body & [statement]]
`(do (Class/forName (:classname ~env))
(let [~'conn (atom nil)]
(try
(reset! ~'conn (DriverManager/getConnection
(str "jdbc:" (:subprotocol ~env) ":"
(:server ~env) "/" (or ~database (:database ~env)))
(:user ~env)
(:password ~env)))
~@(if statement
[(list 'let '[stmt (.createStatement @conn)]
(list '.executeUpdate 'stmt statement))])
~@body
(catch SQLException ~'e
~@catch-body)
(finally
(if-not (nil? (deref ~'conn))
(.close (deref ~'conn))))))))
(defn has-connection? [env & [url]]
(let [env (if url (assoc env :server url) env)]
(run-statement env "" (true) (false))))
(defn all-databases [env]
(run-statement env ""
((let [rs (.getCatalogs (.getMetaData @conn))]
(loop [rs rs acc []]
(if (.next rs)
(recur rs (conj acc (.getString rs "TABLE_CAT")))
acc))))
()))
(defn has-database? [env & [schema]]
(run-statement env schema (true) (false)))
(defn create-database [env & [schema]]
(run-statement env ""
(true)
(false)
(str "create database " (or schema (:database env)))))
(defn drop-database [env & [schema]]
(run-statement env ""
(true)
(false)
(str "drop database " (or schema (:database env)))))