Clojure — избегайте дублирования кода с запросами monger

Я использую Clojure и Monger.

Он отлично работает, и я группирую функции по коллекции, к которой они относятся. Поэтому каждый файл начинается так:

(ns img-cli.model.mycollectionname
  (:require [monger.core            :as mg]
            [monger.collection      :as mc]
            [edn-config.core        :refer [env]])
  (:import  [com.mongodb MongoOptions ServerAddress DB WriteConcern]
            [org.bson.types ObjectId]))


(def config (get-in env [:mongo]))

;; using MongoOptions allows fine-tuning connection parameters,
;; like automatic reconnection (highly recommended for production
;; environment)
(def ^MongoOptions  opts (mg/mongo-options { :threads-allowed-to-block-for-connection-multiplier 300}))
(def ^ServerAddress sa   (mg/server-address (:url config) (:port config)))
(def conn                (mg/connect sa opts))
(def db                  (mg/get-db conn (:db config)))

(def collection-name "asset")

;; I have to write one like this every time
(defn find-one-as-map
  "fetch asset by Id"
  [^String id]
  (mc/find-one-as-map db collection-name {:_id (ObjectId. id)}))

Дублирование кода само по себе имеет несколько недостатков. Также я не уверен, правильно ли впоследствии объединены соединения?

Как я могу избежать этого? Я чувствую, что могу передать дополнительный параметр «db» каждой функции, но тогда откуда он возьмется?

Если я создам соединение с базой данных в «входном» файле моей программы, то как его оттуда передать каждой функции?

Например, скажем, у меня есть Compojure маршрута в разных файлах:

;; in the main handler file

(def db ...) ;; if I move the previous db configuration
             ;; in here, it could be the only place where this is set

;; importing Compojure routes from different files
(defroutes routes-from-file1
                  routes-from-file2...)

Допустим, некоторым функциям, вызываемым из некоторых маршрутов в «file2», требуется доступ к базе данных, как я могу передать им эту переменную?

У меня также есть много повторяющегося кода после этого, например, для получения данных по идентификатору для каждой коллекции... Я чувствую, что это можно упростить, но я не уверен, как это сделать.


person nha    schedule 03.07.2015    source источник


Ответы (1)


Просто обратитесь к нему по его пространству имен

(ns foo
  (:require [handler :as h]))
(println h/db)
person Mark Fisher    schedule 03.07.2015