Compare commits

...

49 commits

Author SHA1 Message Date
Michael Klishin
78c1a37f2e
Merge pull request #235 from quelist/fix/update-before-scripts
Add MongoDB shell version detection to before scripts
2024-11-28 15:12:00 -05:00
quelist
705f4d6f47 Add MongoDB shell version detection to before scripts
Update before_script.sh and before_script_docker.sh to automatically detect and use the appropriate MongoDB shell command (mongo or mongosh) based on availability. This ensures compatibility with both:
- Legacy MongoDB versions using 'mongo' shell
- Modern MongoDB versions (5.0+) using 'mongosh'

The scripts now:
- Check for command availability
- Use the appropriate shell
- Exit with helpful error if no shell is found
2024-11-28 12:54:54 +05:30
Michael Klishin
182a3a6f0b
Merge pull request #234 from tuliolima/feat/supporting_newer_data_json_versions
Feat: supporting 3-ary clojure.data.json/write in newer versions
2024-04-07 21:30:25 -04:00
Tulio Abner de Lima
5852a5fe14 feat: supporting 3-arity clojure.data.json/write in newer versions
Starting at 2.0.0, clojure.data.json implements the additional
parameter `options` in `write` and other functions. The multi-arity
was used in protocol extension to support older and newer versions.
2024-04-04 10:09:20 -03:00
Michael Klishin
84170f7c51
Merge pull request #224 from chrisbroome/wrap-collection-names
Allow keywords as collection names in rename and aggreate
2023-01-19 08:37:42 -06:00
Michael Klishin
9f86984925
Merge pull request #226 from jzsampaio/jzsampaio-patch-1
:exclude random-uuid
2023-01-19 08:37:13 -06:00
Juarez Sampaio
92ea59ff3c
:exclude random-uuid
Should prevent this message when compiling:

> WARNING: random-uuid already refers to: #'clojure.core/random-uuid in namespace: monger.util, being replaced by: #'monger.util/random-uuid
2023-01-19 11:23:34 -03:00
Chris Broome
8deba612bb
Allow keywords as collection names in rename and aggreate 2022-12-01 21:59:06 -05:00
Michael Klishin
74a13a3489
Merge pull request #223 from crinklywrappr/from-db-object-perf
use transients to improve `from-db-object` performance
2022-10-27 09:51:35 +04:00
Daniel Fitzpatrick
14fd0d9189 improve from-db-object performance by leveraging transients 2022-10-26 14:43:41 -05:00
Michael Klishin
dfe29820e1
Merge pull request #222 from crinklywrappr/add-docker-support
add docker support
2022-10-25 20:52:08 +04:00
Daniel Fitzpatrick
999f6ddd9b add docker support 2022-10-25 11:43:05 -05:00
Michael Klishin
a70fd7936a
Merge pull request #220 from jacobemcken/feature/declare_operators
Avoid linter warning about unresolved operator
2022-09-09 11:55:36 +04:00
Jacob Emcken
62ef1d0727 Avoid linter warning about unresolved operator
Causing the message "Unresolved var"
2022-09-09 08:20:47 +02:00
Michael Klishin
54270ad887
Merge pull request #219 from jacobemcken/feature/remove-clj-kondo-cache
Avoid tracking clj-kondo cache in git history
2022-09-08 00:18:52 +04:00
Jacob Emcken
008d1ff1b0 Avoid tracking clojure-lsp cache in git history 2022-09-07 19:42:35 +02:00
Jacob Emcken
088b744991 Avoid tracking clj-kondo cache in git history 2022-09-07 18:23:51 +02:00
Michael Klishin
94cf59a53e
Merge pull request #216 from jacobemcken/cleanup/remove_warning
Prevent "random-uuid already refers to" warning
2022-09-03 14:10:18 +04:00
Jacob Emcken
69bb24b3d9 Prevent "random-uuid already refers to" warning
In Clojure 1.11 the function random-uuid was introduced in clojure.core
causing:

> WARNING: random-uuid already refers to: #'clojure.core/random-uuid in namespace: monger.util, being replaced by: #'monger.util/random-uuid
2022-09-03 08:23:13 +02:00
Michael Klishin
32407c92f1
Merge pull request #215 from punit-naik/master
`insert-batch` fn docfix
2022-06-26 22:26:46 +04:00
Punit Naik
d8ce4ae787
docfix 2022-06-23 18:43:43 +05:30
Michael Klishin
dac9f83a55
Back to dev version 2022-04-23 21:56:21 +04:00
Michael Klishin
9fb211e859
3.6.0 2022-04-23 21:30:18 +04:00
Michael Klishin
b5fd0a2738
More test massaging for MongoDB server 5.x 2022-04-23 21:29:45 +04:00
Michael Klishin
30cd472e23
Remove a test ns that needs reworking for MongoDB 5.x 2022-04-23 21:10:47 +04:00
Michael Klishin
ed613dee94
Bump dependencies 2022-04-23 21:10:21 +04:00
Michael Klishin
801f08b936
Change log updates 2022-04-23 21:04:29 +04:00
Michael Klishin
4d8747f9ed
Merge pull request #213 from okorz001/uuid-representation
Add uuid-representation option
2022-04-03 05:37:20 +04:00
Oscar Korz
ab878ab69c Add uuid-representation option 2022-04-02 15:44:44 -07:00
Michael Klishin
f30a3926e0
Merge pull request #206 from robhanlon22/bump-dependencies
Bump all dependency versions
2021-11-06 02:48:11 +03:00
Michael Klishin
e7c98d66e4
Merge pull request #203 from zackteo/zackteo-patch-1
Fix typo: weather to whether
2021-11-06 02:48:01 +03:00
Rob Hanlon
82ec258f6d
Add 1.9 profile to ensure back compat 2021-01-20 15:41:03 -08:00
Rob Hanlon
37c2d8433b
Bump all dependency versions 2021-01-20 15:38:20 -08:00
Zachary
0494128e15
Fix typo: weather to whether 2020-12-05 08:40:30 +08:00
Michael Klishin
9f3d192dff
Merge pull request #196 from mjrb/master
update operators for MongoDB 4.2
2020-08-10 00:46:26 +03:00
Michael Klishin
1fdd62d3df
Merge pull request #186 from geuscht-m/improve-distinct-tests
Add missing test case for distinct tests
2020-08-10 00:46:12 +03:00
Michael Klishin
c2cbdcaa38
Merge pull request #200 from bdrillard/mongo-options
Adds missing mongo options
2020-08-10 00:45:44 +03:00
Aleksander Eskilson
37aabbe860 testing over non-objects 2020-08-09 16:03:39 -05:00
Aleksander Eskilson
010a977aac adding mongo options 2020-08-09 16:01:20 -05:00
mjrb
b6bd6e55e2 update operators for MongoDB 4.2 2020-02-27 11:12:50 -05:00
Timo Geusch
ce6dcd27cb Added test case for distinct to exercise non-query distinct API
The existing test cases only covered the form (distinct ... :field
{query}). This chance adds a test for the non-query form also.
2019-04-24 14:06:16 -07:00
Timo Geusch
a67f6de06b Merge remote-tracking branch 'upstream/master' 2019-04-18 12:19:17 -07:00
Michael Klishin
d1b77ee3fd
Merge pull request #185 from juvenn/fix/openjdk
Try to use openjdk for travis build
2019-04-12 19:59:18 +04:00
Juvenn Woo
affeb65d00
Try to use openjdk for travis build 2019-04-10 12:13:59 +08:00
Michael Klishin
37816b77a1
Merge pull request #183 from jiacai2050/master
support set max-time on cursor
2019-02-28 17:44:33 +03:00
Jiacai Liu
ba29a45cc6
support set max-time on cursor 2019-02-28 16:48:06 +08:00
Michael Klishin
efc440a8f9
Change log updates 2018-12-10 15:41:15 +03:00
Michael Klishin
805383f1ec
Back to dev version 2018-12-10 15:28:35 +03:00
Timo H. Geusch
595efb926f
Merge pull request #1 from michaelklishin/master
Merged upstream changes
2018-11-08 15:16:44 -05:00
19 changed files with 368 additions and 150 deletions

2
.gitignore vendored
View file

@ -12,3 +12,5 @@ todo.org
.nrepl-*
.idea/
*.iml
/.clj-kondo/.cache
/.lsp/.cache

View file

@ -9,8 +9,9 @@ before_script:
- ./bin/ci/before_script.sh
script: lein do clean, javac, test
jdk:
- oraclejdk8
- openjdk10
- oraclejdk11
- openjdk12
services:
- mongodb
branches:

View file

@ -1,4 +1,29 @@
## Changes between 3.1.x and 3.5.0 (unreleased)
## Changes between 3.5.x and 3.6.0 (unreleased)
### UUID Representation Option
Added a new connection option, `:uuid-representation`.
Contributed by @okorz001.
GitHub issue: [#212](https://github.com/michaelklishin/monger/issues/212)
### Operator List Update
For MongoDB 4.x.
Contributed by @mjrb.
GitHub issue: [#196](https://github.com/michaelklishin/monger/pull/196)
### Dependency Update
Contributed by @robhanlon22.
GitHub issue: [#206](https://github.com/michaelklishin/monger/pull/206)
## Changes between 3.1.x and 3.5.0 (Dec 10th, 2018)
### MongoDB Java Driver Update

View file

@ -111,10 +111,16 @@ Monger is part of the [group of Clojure libraries known as ClojureWerkz](http://
Monger uses [Leiningen 2](https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md). Make sure you have it installed and then run tests against
supported Clojure versions using
./bin/ci/before_script.sh
lein all do clean, javac, test
Or, if you don't have mongodb installed, you can use docker
docker-compose up
./bin/ci/before_script_docker.sh
lein all do clean, javac, test
Then create a branch and make your changes on it. Once you are done with your changes and all tests pass, submit a pull request
on Github.

View file

@ -1,8 +1,18 @@
#!/bin/sh
# Check which MongoDB shell is available
if command -v mongosh >/dev/null 2>&1; then
MONGO_SHELL="mongosh"
elif command -v mongo >/dev/null 2>&1; then
MONGO_SHELL="mongo"
else
echo "Error: Neither mongo nor mongosh shell found. Please install MongoDB shell."
exit 1
fi
# MongoDB Java driver won't run authentication twice on the same DB instance,
# so we need to use multiple DBs.
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test2
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test3
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test4
$MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test
$MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test2
$MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test3
$MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test4

18
bin/ci/before_script_docker.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
# Check which MongoDB shell is available in the container
if docker exec mongo_test which mongosh >/dev/null 2>&1; then
MONGO_SHELL="mongosh"
elif docker exec mongo_test which mongo >/dev/null 2>&1; then
MONGO_SHELL="mongo"
else
echo "Error: Neither mongo nor mongosh shell found in the container."
exit 1
fi
# MongoDB Java driver won't run authentication twice on the same DB instance,
# so we need to use multiple DBs.
docker exec mongo_test $MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test
docker exec mongo_test $MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test2
docker exec mongo_test $MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test3
docker exec mongo_test $MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test4

11
docker-compose.yml Normal file
View file

@ -0,0 +1,11 @@
# Use root/example as user/password credentials
version: '3.1'
services:
mongo:
image: mongo
container_name: mongo_test
restart: always
ports:
- "27017:27017"

View file

@ -1,12 +1,12 @@
(defproject com.novemberain/monger "3.5.0"
(defproject com.novemberain/monger "4.0.0-SNAPSHOT"
:description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included"
:url "http://clojuremongodb.info"
:min-lein-version "2.5.1"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0"]
[org.mongodb/mongodb-driver "3.9.1"]
[clojurewerkz/support "1.1.0"]]
:dependencies [[org.clojure/clojure "1.11.1"]
[org.mongodb/mongodb-driver "3.12.11"]
[clojurewerkz/support "1.5.0"]]
:test-selectors {:default (fn [m]
(and (not (:performance m))
(not (:edge-features m))
@ -31,12 +31,12 @@
:mailing-list {:name "clojure-mongodb"
:archive "https://groups.google.com/group/clojure-mongodb"
:post "clojure-mongodb@googlegroups.com"}
:profiles {:1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]}
:master {:dependencies [[org.clojure/clojure "1.10.0-master-SNAPSHOT"]]}
:profiles {:1.10 {:dependencies [[org.clojure/clojure "1.10.2"]]}
:1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]}
:dev {:resource-paths ["test/resources"]
:dependencies [[clj-time "0.15.1" :exclusions [org.clojure/clojure]]
[cheshire "5.8.1" :exclusions [org.clojure/clojure]]
[org.clojure/data.json "0.2.6" :exclusions [org.clojure/clojure]]
[org.clojure/data.json "2.5.0" :exclusions [org.clojure/clojure]]
[org.clojure/tools.cli "0.4.1" :exclusions [org.clojure/clojure]]
[org.clojure/core.cache "0.7.1" :exclusions [org.clojure/clojure]]
[ring/ring-core "1.7.1" :exclusions [org.clojure/clojure]]
@ -48,8 +48,8 @@
:namespaces [#"^monger\.(?!internal)"]}}
;; only clj-time/JodaTime available, used to test monger.joda-time w/o clojure.data.json
:dev2 {:resource-paths ["test/resources"]
:dependencies [[clj-time "0.15.1" :exclusions [org.clojure/clojure]]]}}
:aliases {"all" ["with-profile" "dev:dev,1.8:dev,master"]}
:dependencies [[clj-time "0.15.2" :exclusions [org.clojure/clojure]]]}}
:aliases {"all" ["with-profile" "dev:dev,1.10:dev,1.9:dev"]}
:repositories {"sonatype" {:url "https://oss.sonatype.org/content/repositories/releases"
:snapshots false
:releases {:checksum :fail :update :always}}

View file

@ -109,7 +109,7 @@
(defn ^WriteResult insert-batch
"Saves documents do collection. You can optionally specify WriteConcern as a third argument."
"Saves documents to collection. You can optionally specify WriteConcern as a third argument."
([^DB db ^String coll ^List documents]
(.insert (.getCollection db (name coll))
^List (to-db-object documents)
@ -467,7 +467,7 @@
(defn exists?
"Checks weather collection with certain name exists."
"Checks whether collection with certain name exists."
([^DB db ^String coll]
(.collectionExists db coll)))
@ -490,9 +490,9 @@
(defn rename
"Renames collection."
([^DB db ^String from, ^String to]
(.rename (.getCollection db from) to))
(.rename (.getCollection db (name from)) (name to)))
([^DB db ^String from ^String to drop-target?]
(.rename (.getCollection db from) to drop-target?)))
(.rename (.getCollection db (name from)) (name to) drop-target?)))
;;
;; Map/Reduce
@ -545,7 +545,7 @@
See http://docs.mongodb.org/manual/applications/aggregation/ to learn more."
[^DB db ^String coll stages & opts]
(let [coll (.getCollection db coll)
(let [coll (.getCollection db (name coll))
agg-opts (build-aggregation-options opts)
pipe (into-array-list (to-db-object stages))
res (.aggregate coll pipe agg-opts)
@ -558,7 +558,7 @@
See http://docs.mongodb.org/manual/applications/aggregation/ to learn more."
[^DB db ^String coll stages & opts]
(let [coll (.getCollection db coll)
(let [coll (.getCollection db (name coll))
agg-opts (build-aggregation-options opts)
pipe (into-array-list (to-db-object stages))
res (.explainAggregate coll pipe agg-opts)]

View file

@ -110,26 +110,25 @@
(extend-protocol ConvertFromDBObject
nil
(from-db-object [input keywordize] input)
(from-db-object [_ _] nil)
Object
(from-db-object [input keywordize] input)
(from-db-object [input _] input)
Decimal128
(from-db-object [^Decimal128 input keywordize]
(.bigDecimalValue input)
)
(from-db-object [^Decimal128 input _]
(.bigDecimalValue input))
List
(from-db-object [^List input keywordize]
(vec (map #(from-db-object % keywordize) input)))
(mapv #(from-db-object % keywordize) input))
BasicDBList
(from-db-object [^BasicDBList input keywordize]
(vec (map #(from-db-object % keywordize) input)))
(mapv #(from-db-object % keywordize) input))
com.mongodb.DBRef
(from-db-object [^com.mongodb.DBRef input keywordize]
(from-db-object [^com.mongodb.DBRef input _]
input)
DBObject
@ -137,12 +136,13 @@
;; DBObject provides .toMap, but the implementation in
;; subclass GridFSFile unhelpfully throws
;; UnsupportedOperationException.
(reduce (if keywordize
(fn [m ^String k]
(assoc m (keyword k) (from-db-object (.get input k) true)))
(fn [m ^String k]
(assoc m k (from-db-object (.get input k) false))))
{} (.keySet input))))
(persistent!
(reduce (if keywordize
(fn [m ^String k]
(assoc! m (keyword k) (from-db-object (.get input k) true)))
(fn [m ^String k]
(assoc! m k (from-db-object (.get input k) false))))
(transient {}) (.keySet input)))))
(defprotocol ConvertToObjectId

View file

@ -136,56 +136,78 @@
(ServerAddress. hostname port)))
(defn ^MongoClientOptions$Builder mongo-options-builder
[{:keys [connections-per-host threads-allowed-to-block-for-connection-multiplier
max-wait-time connect-timeout socket-timeout socket-keep-alive auto-connect-retry max-auto-connect-retry-time
description write-concern cursor-finalizer-enabled read-preference required-replica-set-name
add-command-listener always-use-mbeans codec-registry db-decoder-factory db-encoder-factory
heartbeat-connect-timeout heartbeat-frequency heartbeat-socket-timeout local-threshold
max-connection-idle-time max-connection-life-time min-connections-per-host min-heartbeat-frequency
read-concern server-selection-timeout socket-factory ssl-enabled ssl-invalid-host-name-allowed]}]
[{:keys [add-cluster-listener add-cluster-listeners add-command-listener add-command-listeners
add-connection-pool-listener add-connection-pool-listeners add-server-listener add-server-listeners
add-server-monitor-listener add-server-monitor-listeners always-use-mbeans application-name
codec-registry compressor-list connect-timeout connections-per-host cursor-finalizer-enabled
db-decoder-factory db-encoder-factory description heartbeat-connect-timeout heartbeat-frequency
heartbeat-socket-timeout local-threshold max-connection-idle-time max-connection-life-time
max-wait-time min-connections-per-host min-heartbeat-frequency read-concern read-preference
required-replica-set-name retry-writes server-selection-timeout server-selector socket-keep-alive
socket-factory socket-timeout ssl-context ssl-enabled ssl-invalid-host-name-allowed
threads-allowed-to-block-for-connection-multiplier uuid-representation write-concern]}]
(let [mob (MongoClientOptions$Builder.)]
(when connections-per-host
(.connectionsPerHost mob connections-per-host))
(when threads-allowed-to-block-for-connection-multiplier
(.threadsAllowedToBlockForConnectionMultiplier mob threads-allowed-to-block-for-connection-multiplier))
(when max-wait-time
(.maxWaitTime mob max-wait-time))
(when connect-timeout
(.connectTimeout mob connect-timeout))
(when socket-timeout
(.socketTimeout mob socket-timeout))
(when socket-keep-alive
(.socketKeepAlive mob socket-keep-alive))
(when read-preference
(.readPreference mob read-preference))
(when description
(.description mob description))
(when write-concern
(.writeConcern mob write-concern))
(when cursor-finalizer-enabled
(.cursorFinalizerEnabled mob cursor-finalizer-enabled))
(when required-replica-set-name
(.requiredReplicaSetName mob required-replica-set-name))
(when add-cluster-listener
(.addClusterListener mob add-cluster-listener))
(when add-cluster-listeners
(doseq [cluster-listener add-cluster-listeners]
(.addClusterListener mob cluster-listener)))
(when add-command-listener
(.addCommandListener mob add-command-listener))
(when add-command-listeners
(doseq [command-listener add-command-listeners]
(.addCommandListener mob command-listener)))
(when add-connection-pool-listener
(.addConnectionPoolListener mob add-connection-pool-listener))
(when add-connection-pool-listeners
(doseq [connection-pool-listener add-connection-pool-listeners]
(.addConnectionPoolListener mob connection-pool-listener)))
(when add-server-listener
(.addServerListener mob add-server-listener))
(when add-server-listeners
(doseq [server-listener add-server-listeners]
(.addServerListener mob server-listener)))
(when add-server-monitor-listener
(.addServerMonitorListener mob add-server-monitor-listener))
(when add-server-monitor-listeners
(doseq [server-monitor-listener add-server-monitor-listeners]
(.addServerMonitorListener mob server-monitor-listener)))
(when always-use-mbeans
(.alwaysUseMBeans mob always-use-mbeans))
(when application-name
(.applicationName mob application-name))
(when always-use-mbeans
(.alwaysUseMBeans mob always-use-mbeans))
(when codec-registry
(.codecRegistry mob codec-registry))
(when compressor-list
(.compressorList mob compressor-list))
(when connections-per-host
(.connectionsPerHost mob connections-per-host))
(when connect-timeout
(.connectTimeout mob connect-timeout))
(when cursor-finalizer-enabled
(.cursorFinalizerEnabled mob cursor-finalizer-enabled))
(when db-decoder-factory
(.dbDecoderFactory mob db-decoder-factory))
(when db-encoder-factory
(.dbEncoderFactory mob db-encoder-factory))
(when description
(.description mob description))
(when heartbeat-connect-timeout
(.heartbeatConnectTimeout mob heartbeat-connect-timeout))
(when heartbeat-frequency
(.heartbeatFrequency mob heartbeat-frequency))
(when heartbeat-socket-timeout
(.heartbeatSocketTimeout mob heartbeat-socket-timeout))
(when ssl-context
(.sslContext mob ssl-context))
(when local-threshold
(.localThreshold mob local-threshold))
(when max-connection-idle-time
(.maxConnectionIdleTime mob max-connection-idle-time))
(when max-wait-time
(.maxWaitTime mob max-wait-time))
(when max-connection-life-time
(.maxConnectionLifeTime mob max-connection-life-time))
(when min-connections-per-host
@ -194,14 +216,32 @@
(.minHeartbeatFrequency mob min-heartbeat-frequency))
(when read-concern
(.readConcern mob read-concern))
(when read-preference
(.readPreference mob read-preference))
(when required-replica-set-name
(.requiredReplicaSetName mob required-replica-set-name))
(when retry-writes
(.retryWrites mob retry-writes))
(when server-selection-timeout
(.serverSelectionTimeout mob server-selection-timeout))
(when server-selector
(.serverSelector mob server-selector))
(when socket-keep-alive
(.socketKeepAlive mob socket-keep-alive))
(when socket-factory
(.socketFactory mob socket-factory))
(when socket-timeout
(.socketTimeout mob socket-timeout))
(when ssl-enabled
(.sslEnabled mob ssl-enabled))
(when ssl-invalid-host-name-allowed
(.sslInvalidHostNameAllowed mob ssl-invalid-host-name-allowed))
(when threads-allowed-to-block-for-connection-multiplier
(.threadsAllowedToBlockForConnectionMultiplier mob threads-allowed-to-block-for-connection-multiplier))
(when uuid-representation
(.uuidRepresentation mob uuid-representation))
(when write-concern
(.writeConcern mob write-concern))
mob))
(defn ^MongoClientOptions mongo-options

View file

@ -70,13 +70,19 @@
(try
(extend-protocol clojure.data.json/JSONWriter
ObjectId
(-write [^ObjectId object out]
(clojure.data.json/write (.toString object) out)))
(-write
([^ObjectId object out]
(clojure.data.json/write (.toString object) out))
([^ObjectId object out options]
(clojure.data.json/write (.toString object) out options))))
(extend-protocol clojure.data.json/JSONWriter
BSONTimestamp
(-write [^BSONTimestamp object out]
(clojure.data.json/write {:time (.getTime object) :inc (.getInc object)} out)))
(-write
([^BSONTimestamp object out]
(clojure.data.json/write {:time (.getTime object) :inc (.getInc object)} out))
([^BSONTimestamp object out options]
(clojure.data.json/write {:time (.getTime object) :inc (.getInc object)} out options))))
(catch Throwable _
false))

View file

@ -46,6 +46,8 @@
;; QUERY OPERATORS
;;
(declare $gt $gte $lt $lte $all $in $nin $eq $ne $elemMatch $regex $options)
;; $gt is "greater than" comparator
;; $gte is "greater than or equals" comparator
;; $gt is "less than" comparator
@ -102,6 +104,30 @@
(defoperator $regex)
(defoperator $options)
;; comment on a query predicate
(declare $comment $explain $hint $maxTimeMS $orderBy $query $returnKey $showDiskLoc $natural)
(defoperator $comment)
(defoperator $explain)
(defoperator $hint)
(defoperator $maxTimeMS)
(defoperator $orderBy)
(defoperator $query)
(defoperator $returnKey)
(defoperator $showDiskLoc)
(defoperator $natural)
;;
;; EVALUATION (QUERY)
;;
(declare $expr $jsonSchema $where $and $or $nor)
(defoperator $expr)
(defoperator $jsonSchema)
;; Matches documents that satisfy a JavaScript expression.
;;
;; EXAMPLES:
@ -141,6 +167,8 @@
;; ATOMIC MODIFIERS
;;
(declare $inc $mul $set $unset $setOnInsert $rename $push $position $each $addToSet $pop $pull $pullAll $bit $bitsAllClear $bitsAllSet $bitsAnyClear $bitsAnySet $exists $mod $size $type $not)
;; $inc increments one or many fields for the given value, otherwise sets the field to value
;;
;; EXAMPLES:
@ -227,6 +255,10 @@
(defoperator $pullAll)
(defoperator $bit)
(defoperator $bitsAllClear)
(defoperator $bitsAllSet)
(defoperator $bitsAnyClear)
(defoperator $bitsAnySet)
(defoperator $exists)
(defoperator $mod)
@ -236,36 +268,132 @@
;;
;; Aggregation in 2.2
;; Aggregation in 4.2
;;
(declare $addFields $bucket $bucketAuto $collStats $facet $geoNear $graphLookup $indexStats $listSessions $lookup $match $merge $out $planCacheStats $project $redact $replaceRoot $replaceWith $sample $limit $skip $unwind $group $sort $sortByCount $currentOp $listLocalSessions $cmp $min $max $avg $stdDevPop $stdDevSamp $sum $let $first $last $abs $add $ceil $divide $exp $floor $ln $log $log10 $multiply $pow $round $sqrt $subtract $trunc $literal $arrayElemAt $arrayToObject $concatArrays $filter $indexOfArray $isArray $map $objectToArray $range $reduce $reverseArray $zip $mergeObjects $allElementsTrue $anyElementsTrue $setDifference $setEquals $setIntersection $setIsSubset $setUnion $strcasecmp $substr $substrBytes $substrCP $toLower $toString $toUpper $concat $indexOfBytes $indexOfCP $ltrim $regexFind $regexFindAll $regexMatch $rtrim $split $strLenBytes $subLenCP $trim $sin $cos $tan $asin $acos $atan $atan2 $asinh $acosh $atanh $radiansToDegrees $degreesToRadians $convert $toBool $toDecimal $toDouble $toInt $toLong $toObjectId $dayOfMonth $dayOfWeek $dayOfYear $hour $minute $month $second $millisecond $week $year $isoDate $dateFromParts $dateFromString $dateToParts $dateToString $isoDayOfWeek $isoWeek $isoWeekYear $toDate $ifNull $cond $switch)
(defoperator $addFields)
(defoperator $bucket)
(defoperator $bucketAuto)
(defoperator $collStats)
(defoperator $facet)
(defoperator $geoNear)
(defoperator $graphLookup)
(defoperator $indexStats)
(defoperator $listSessions)
(defoperator $lookup)
(defoperator $match)
(defoperator $merge)
(defoperator $out)
(defoperator $planCacheStats)
(defoperator $project)
(defoperator $redact)
(defoperator $replaceRoot)
(defoperator $replaceWith)
(defoperator $sample)
(defoperator $limit)
(defoperator $skip)
(defoperator $unwind)
(defoperator $group)
(defoperator $sort)
(defoperator $sortByCount)
(defoperator $currentOp)
(defoperator $listLocalSessions)
(defoperator $cmp)
(defoperator $min)
(defoperator $max)
(defoperator $avg)
(defoperator $stdDevPop)
(defoperator $stdDevSamp)
(defoperator $sum)
(defoperator $let)
(defoperator $first)
(defoperator $last)
(defoperator $abs)
(defoperator $add)
(defoperator $ceil)
(defoperator $divide)
(defoperator $exp)
(defoperator $floor)
(defoperator $ln)
(defoperator $log)
(defoperator $log10)
(defoperator $multiply)
(defoperator $pow)
(defoperator $round)
(defoperator $sqrt)
(defoperator $subtract)
(defoperator $trunc)
(defoperator $literal)
(defoperator $arrayElemAt)
(defoperator $arrayToObject)
(defoperator $concatArrays)
(defoperator $filter)
(defoperator $indexOfArray)
(defoperator $isArray)
(defoperator $map)
(defoperator $objectToArray)
(defoperator $range)
(defoperator $reduce)
(defoperator $reverseArray)
(defoperator $zip)
(defoperator $mergeObjects)
(defoperator $allElementsTrue)
(defoperator $anyElementsTrue)
(defoperator $setDifference)
(defoperator $setEquals)
(defoperator $setIntersection)
(defoperator $setIsSubset)
(defoperator $setUnion)
(defoperator $strcasecmp)
(defoperator $substr)
(defoperator $substrBytes)
(defoperator $substrCP)
(defoperator $toLower)
(defoperator $toString)
(defoperator $toUpper)
(defoperator $concat)
(defoperator $indexOfBytes)
(defoperator $indexOfCP)
(defoperator $ltrim)
(defoperator $regexFind)
(defoperator $regexFindAll)
(defoperator $regexMatch)
(defoperator $rtrim)
(defoperator $split)
(defoperator $strLenBytes)
(defoperator $subLenCP)
(defoperator $trim)
(defoperator $sin)
(defoperator $cos)
(defoperator $tan)
(defoperator $asin)
(defoperator $acos)
(defoperator $atan)
(defoperator $atan2)
(defoperator $asinh)
(defoperator $acosh)
(defoperator $atanh)
(defoperator $radiansToDegrees)
(defoperator $degreesToRadians)
(defoperator $convert)
(defoperator $toBool)
(defoperator $toDecimal)
(defoperator $toDouble)
(defoperator $toInt)
(defoperator $toLong)
(defoperator $toObjectId)
(defoperator $dayOfMonth)
(defoperator $dayOfWeek)
@ -278,12 +406,22 @@
(defoperator $week)
(defoperator $year)
(defoperator $isoDate)
(defoperator $dateFromParts)
(defoperator $dateFromString)
(defoperator $dateToParts)
(defoperator $dateToString)
(defoperator $isoDayOfWeek)
(defoperator $isoWeek)
(defoperator $isoWeekYear)
(defoperator $toDate)
(defoperator $ifNull)
(defoperator $cond)
(defoperator $switch)
;; Geospatial
(declare $geoWithin $geoIntersects $near $nearSphere $geometry $maxDistance $minDistance $center $centerSphere $box $polygon $slice)
(defoperator $geoWithin)
(defoperator $geoIntersects)
(defoperator $near)
@ -299,7 +437,9 @@
(defoperator $slice)
;; full text search
(declare $text $meta $search $language $natural $currentDate $isolated $count)
(defoperator $text)
(defoperator $meta)
(defoperator $search)
(defoperator $language)
(defoperator $natural)
@ -316,5 +456,4 @@
;; (mgcol/update "libraries" { :language "Clojure", $isolated 1 } { $inc { :popularity 1 } } {:multi true})
(defoperator $isolated)
(defoperator $count)
(defoperator $dateToString)
(defoperator $count)

View file

@ -43,6 +43,7 @@
[monger.conversion :refer :all]
[monger.operators :refer :all])
(:import [com.mongodb DB DBCollection DBObject DBCursor ReadPreference]
[java.util.concurrent TimeUnit]
java.util.List))
@ -96,6 +97,7 @@
snapshot
read-preference
keywordize-fields
max-time
options]
:or { limit 0 batch-size 256 skip 0 } }]
(with-open [cursor (doto (.find collection (to-db-object query) (as-field-selector fields))
@ -109,6 +111,8 @@
(.hint cursor (to-db-object hint)))
(when read-preference
(.setReadPreference cursor read-preference))
(when max-time
(.maxTime cursor max-time TimeUnit/MILLISECONDS))
(when options
(add-options cursor options))
(map (fn [x] (from-db-object x keywordize-fields))
@ -154,6 +158,10 @@
[m ^ReadPreference rp]
(merge m { :read-preference rp }))
(defn max-time
[m ^long max-time]
(merge m { :max-time max-time }))
(defn options
[m opts]
(merge m { :options opts }))

View file

@ -32,12 +32,14 @@
;; ----------------------------------------------------------------------------------
(ns ^{:doc "Provides various utility functions, primarily for working with document ids."} monger.util
(:refer-clojure :exclude [random-uuid])
(:import java.security.SecureRandom
java.math.BigInteger
org.bson.types.ObjectId
com.mongodb.DBObject
clojure.lang.IPersistentMap
java.util.Map))
java.util.Map)
(:refer-clojure :exclude [random-uuid]))
;;
;; API

View file

@ -130,9 +130,7 @@
(deftest test-explain-aggregate
(let [batch [{:state "CA" :price 100}
{:state "CA" :price 10}
{:state "IL" :price 50}]
expected-keys #{:ok :stages}]
{:state "IL" :price 50}]]
(mc/insert-batch db coll batch)
(let [result (mc/explain-aggregate db coll [{$match {:state "CA"}}])
key-in-result? (partial contains? result)]
(is (every? key-in-result? expected-keys))))))
(let [result (mc/explain-aggregate db coll [{$match {:state "CA"}}])]
(is (:ok result))))))

View file

@ -134,6 +134,7 @@
{:state "CA" :quantity 2 :price 2.95 }
{:state "IL" :quantity 3 :price 5.50 }]]
(mc/insert-batch db collection batch)
(is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state))))
(is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state {}))))
(is (= ["CA" "NY"] (sort (mc/distinct db collection :state {:price {$gt 100.00}}))))))

View file

@ -57,18 +57,31 @@
(is (dbs "monger-test"))))
(deftest monger-options-test
(let [opts {:connections-per-host 1
:threads-allowed-to-block-for-connection-multiplier 1
:max-wait-time 1
(let [opts {:always-use-mbeans true
:application-name "app"
:connect-timeout 1
:socket-timeout 1
:socket-keep-alive true
:auto-connect-retry true
:max-auto-connect-retry-time 1
:description "Description"
:write-concern com.mongodb.WriteConcern/JOURNAL_SAFE
:connections-per-host 1
:cursor-finalizer-enabled true
:required-replica-set-name "rs"}]
:description "Description"
:heartbeat-connect-timeout 1
:heartbeat-frequency 1
:heartbeat-socket-timeout 1
:local-threshold 1
:max-connection-idle-time 1
:max-connection-life-time 1
:max-wait-time 1
:min-connections-per-host 1
:min-heartbeat-frequency 1
:required-replica-set-name "rs"
:retry-writes true
:server-selection-timeout 1
:socket-keep-alive true
:socket-timeout 1
:ssl-enabled true
:ssl-invalid-host-name-allowed true
:threads-allowed-to-block-for-connection-multiplier 1
:uuid-representation org.bson.UuidRepresentation/STANDARD
:write-concern com.mongodb.WriteConcern/JOURNAL_SAFE}]
(is (instance? com.mongodb.MongoClientOptions$Builder (mg/mongo-options-builder opts)))))
(deftest connect-to-uri-without-db-name

View file

@ -1,62 +0,0 @@
(ns monger.test.map-reduce-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType]
org.bson.types.ObjectId
java.util.Date)
(:require [monger.collection :as mc]
[monger.core :as mg]
[clojurewerkz.support.js :as js]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.conversion :refer :all]))
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each (fn [f]
(mc/remove db "widgets")
(f)
(mc/remove db "widgets")))
(let [collection "widgets"
mapper (js/load-resource "resources/mongo/js/mapfun1.js")
reducer "function(key, values) {
var result = 0;
values.forEach(function(v) { result += v });
return result;
}"
batch [{ :state "CA" :quantity 1 :price 199.00 }
{ :state "NY" :quantity 2 :price 199.00 }
{ :state "NY" :quantity 1 :price 299.00 }
{ :state "IL" :quantity 2 :price 11.50 }
{ :state "CA" :quantity 2 :price 2.95 }
{ :state "IL" :quantity 3 :price 5.50 }]
expected [{:_id "CA", :value 204.9} {:_id "IL", :value 39.5} {:_id "NY", :value 697.0}]]
(deftest test-basic-inline-map-reduce-example
(mc/remove db collection)
(mc/insert-batch db collection batch)
(let [output (mc/map-reduce db collection mapper reducer nil MapReduceCommand$OutputType/INLINE {})
results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
(is (= expected results))))
(deftest test-basic-map-reduce-example-that-replaces-named-collection
(mc/remove db collection)
(mc/insert-batch db collection batch)
(let [output (mc/map-reduce db collection mapper reducer "mr_outputs" {})
results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
(is (= 3 (mg/count results)))
(is (= expected
(map #(from-db-object % true) (seq results))))
(is (= expected
(map #(from-db-object % true) (mc/find db "mr_outputs"))))
(.drop ^MapReduceOutput output)))
(deftest test-basic-map-reduce-example-that-merged-results-into-named-collection
(mc/remove db collection)
(mc/insert-batch db collection batch)
(mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})
(mc/insert db collection { :state "OR" :price 17.95 :quantity 4 })
(let [^MapReduceOutput output (mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})]
(is (= 4 (mg/count output)))
(is (= ["CA" "IL" "NY" "OR"]
(map :_id (mc/find-maps db "merged_mr_outputs"))))
(.drop ^MapReduceOutput output)))))