在clojure中处理多个数据层

时间:2016-10-28 22:29:50

标签: database clojure

我正在开发一个Clojure应用程序,我们希望能够对遗留数据库和新数据库起作用。我们的想法是在一个文件中定义通用数据库API函数,该文件根据环境设置映射到旧数据库API或新数据库API中的相应函数。作为Clojure的新手,这就是我想出来的。

(ns app.db-api
  (:require [app.old-api]
            [app.new-api]
            [app.config :refer [env]]))

;; Define placeholder functions that are later interned to point at either
;; new or old API. The corresponding functions are defined and implemented in
;; old-api and new-api
(defn get-user [user-id])
(defn create-user [user-name])

;; Iterate through defined functions in this namespace and intern
;; them to the corresponding functions in the new or old API, as
;; configured by the :db-api environment variable
(doseq [f (keys (ns-publics *ns*))]
  (let [x (symbol f)
        y (eval (symbol (str "app." (env :db-api) "/" f)))]
    (intern *ns* x y)))

使用此功能,对db-api/get-user的调用将映射到old-api/get-usernew-api/get-user,具体取决于:db-api环境变量中的设置。

一个明显的警告是db-api必须复制所有API函数的声明,并且API函数不能分布在多个文件上,但必须驻留在db-api,old-api和new-api中。此外,我们使用conman,conman/connect!conman/bind-connection也必须连接/绑定到不同的数据库/ sql文件,具体取决于是使用旧API还是新API。

问题是这是否是一个合理的解决方案,还是有更好的方法来实现同一目标?感谢任何评论。

1 个答案:

答案 0 :(得分:1)

您可以使用多方法。 https://clojuredocs.org/clojure.core/defmulti

(defmulti get-user (fn [user-id] (grab-env-var :db-api)))

(defmethod get-user :old-api [user-id]
  (use-old-api user-id))

(defmethod get-user :new-api [user-id]
  (use-new-api user-id))