-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.clj
80 lines (64 loc) · 2.61 KB
/
util.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(ns com.timezynk.mongo.util
(:require
[clojure.tools.logging :as log]
[com.timezynk.mongo.helpers :as h]
[com.timezynk.mongo.methods.connection :refer [connection-method]]
[com.timezynk.mongo.methods.create-collection :refer [create-collection-method]]
[com.timezynk.mongo.methods.modify-collection :refer [modify-collection]]
[com.timezynk.mongo.config :refer [*mongo-client* *mongo-database*]])
(:import [com.mongodb MongoClientException MongoCommandException]))
; ------------------------
; Persistent binding
; ------------------------
(def ^:no-doc ^:private mongo-uri (atom nil))
(defn set-mongo-uri!
"Set connection string prior to creating a persistent binding.
| Parameter | Description |
| --- | --- |
| `uri` | `string` Database location. |"
{:arglists '([<uri>])}
[uri & options]
(reset! mongo-uri {:uri uri
:options options}))
(def ^:private connection-map
(atom {}))
(defn ^:no-doc upsert-connection []
(let [uri (or @mongo-uri
{:uri (System/getenv "MONGO_URI")}
(throw (MongoClientException. "Call set-mongo-uri! or define MONGO_URI environment variable prior to calling wrap-mongo")))]
(or (get @connection-map uri)
(let [connection (connection-method (:uri uri) (:options uri))]
(log/info "MongoDB servers" uri)
(swap! connection-map assoc uri connection)
connection))))
(defmacro wrap-mongo
"Functionally set up or change mongodb connection, using a persistent connection. Reverts to earlier settings when leaving scope.
1. Looks for a connection string set by a prior call to `set-mongo-uri!`.
2. Failing that, retrieves a connection string `MONGO_URI` environment variable.
The connection string is used only once to set up the persistent connection.
| Parameter | Description |
| --- | --- |
| `body` | Encapsulated program calling the database. |
**Returns**
The result of the last encapsulated expression.
**Examples**
```Clojure
(set-mongo-uri! \"mongodb://localhost:27017/my-database\")
(wrap-mongo
(insert! :users {:name \"My Name\"})
(fetch! :users))
```"
{:arglists '([& <body>])}
[& body]
`(let [client# (upsert-connection)]
(binding [*mongo-client* (:client client#)
*mongo-database* (:database client#)]
~@body)))
; ------------------------
; Collections
; ------------------------
(defn make-collection! [coll & options]
(try
(create-collection-method (name coll) options)
(catch MongoCommandException _e
(modify-collection (h/get-collection coll) options))))