Compare commits

..

2 commits

Author SHA1 Message Date
Michael Klishin
39f297740e Update change log 2016-01-16 14:30:20 +03:00
Andre Ambrosio Boechat
f5fcdc7b49 with-collection macro: type hints improvement
From all the resources I found about type hinting in macros,
it doesn't work like it does for normal functions.

I got reflection warnings for a code like this:

```clj
(let [conn (mg/connect)
      db (delay (mg/get-db conn "monger-test"))]
  (with-collection @db "something"
    (find {})))
```

The type hint for `db` didn't work. Actually the type hint that works
comes from the function `core/get-db` and we see this when we remove
`delay` from the code above. As we could expect, the function `deref`
doesn't propagate the type hint.

I did similar tests with the collection name and no reflection warning
was raised for any case. In addition, it looked weird for me to have
a type hint like `^String` and then a checking like `string?` later.

Some references:

* http://stackoverflow.com/questions/11919602/generating-clojure-code-with-type-hints
* Clojure High Performance Programming, page 44.
2016-01-16 14:29:28 +03:00
46 changed files with 465 additions and 841 deletions

4
.gitignore vendored
View file

@ -10,7 +10,3 @@ deploy.docs.sh
target/* target/*
todo.org todo.org
.nrepl-* .nrepl-*
.idea/
*.iml
/.clj-kondo/.cache
/.lsp/.cache

View file

@ -1,20 +1,17 @@
language: clojure language: clojure
sudo: required lein: lein2
lein: lein
dist: xenial
before_script: before_script:
# Give MongoDB server some time to boot - ./bin/ci/install_mongodb.sh
- sleep 15
- mongod --version - mongod --version
- ./bin/ci/before_script.sh - ./bin/ci/before_script.sh
script: lein do clean, javac, test script: lein2 do clean, javac, test
jdk: jdk:
- openjdk10 - openjdk7
- oraclejdk11 - oraclejdk7
- openjdk12 - oraclejdk8
services: services:
- mongodb - mongodb
branches: branches:
only: only:
- master - master
- 3.5.x-stable - 3.0.x-stable

View file

@ -1,11 +1,10 @@
## Pre-requisites ## Pre-requisites
The project uses [Leiningen 2](http://leiningen.org) and requires a recent MongoDB to be running The project uses [Leiningen 2](https://leiningen.org) and requires MongoDB `2.4+` to be running
locally. Make sure you have those two installed and then run tests against all supported Clojure versions using locally. Make
sure you have those two installed and then run tests against all supported Clojure versions using
./bin/ci/before_script.sh
lein all do clean, javac, test
lein2 all test
## Pull Requests ## Pull Requests

View file

@ -1,70 +1,22 @@
## Changes between 3.5.x and 3.6.0 (unreleased) ## Changes between 3.0.2 and 3.0.3 (unreleased)
### UUID Representation Option ### Macro Type Hint Fixes
Added a new connection option, `:uuid-representation`. Contributed by Andre Ambrosio Boechat.
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) ## Changes between 3.0.1 and 3.0.2
### MongoDB Java Driver Update ### MongoDB Java Driver Update
MongoDB Java driver dependency has been updated to `3.9.x`. MongoDB Java driver dependency has been updated to `3.2.0`.
This means that Monger now **requires JDK 8**.
Contributed by @Linicks.
### 3rd Party Library Compatibility
* Cheshire `5.8.x`
* clj-time `0.15.1`
* ring-core `0.15.1`
* Ragtime `0.7.x`.
### URI Connection Usability Improvement
URIs that don't specify a database will now be rejected as invalid.
Contributed by Chris Broome.
## Changes between 3.0.x and 3.1.0 (September 17th, 2016)
### MongoDB Java Driver Update
MongoDB Java driver dependency has been updated to `3.3.0`.
### Cursor Hinting Option Fix ### Cursor Hinting Option Fix
Contributed by Stijn Opheide. Contributed by Stijn Opheide.
### Improved DBObject to Clojure Map conversion performance
New `from-db-object` implementation for `DBObject` avoids creation of an unnecessary ## Changes between 3.0.0 and 3.0.1
sequence and instead directly accesses `DBObject` instance in reduce. This should
offer performance improvement of about 20%. A performance test can be found
at [monger.test.stress-test](https://github.com/michaelklishin/monger/blob/master/test/monger/test/stress_test.clj).
Contributed by Juho Teperi.
### Authencation Function No Longer Ignores Credentials ### Authencation Function No Longer Ignores Credentials
@ -72,10 +24,9 @@ In some cases Monger ignored provided credentials.
Contributed by Artem Chistyakov. Contributed by Artem Chistyakov.
### Macro Type Hint Fixes ### MongoDB Java Driver Update
Contributed by Andre Ambrosio Boechat.
MongoDB Java driver dependency has been updated to `3.0.4`.
## Changes between 2.1.0 and 3.0.0 ## Changes between 2.1.0 and 3.0.0

View file

@ -1,19 +1,14 @@
# Monger, a modern Clojure MongoDB Driver # Monger, a modern Clojure MongoDB Driver
[![Build Status](https://travis-ci.org/xingzhefeng/monger.svg?branch=master)](https://travis-ci.org/xingzhefeng/monger)
Monger is an idiomatic [Clojure MongoDB driver](http://clojuremongodb.info) for a more civilized age. Monger is an idiomatic [Clojure MongoDB driver](http://clojuremongodb.info) for a more civilized age.
It has batteries included, offers powerful expressive query DSL, It has batteries included, offers powerful expressive query DSL, strives to support every MongoDB 2.0+ feature and has sane defaults. Monger is built from for modern Clojure versions and sits on top of the official MongoDB Java driver.
strives to support modern MongoDB features and have the "look and feel" and
flexibility of the MongoDB shell.
Monger is built from for modern Clojure versions and sits on top of
the official MongoDB Java driver.
## Project Goals ## Project Goals
There is one MongoDB client for Clojure that has been around since 2009. So, why create another one? Monger authors There is one MongoDB client for Clojure that has been around since 2009. So, why create another one? Monger authors
wanted a client that would wanted a client that will
* Support most of modern MongoDB features, focus on those that really matter. * Support most of modern MongoDB features, focus on those that really matter.
* Be [well documented](http://clojuremongodb.info). * Be [well documented](http://clojuremongodb.info).
@ -29,7 +24,7 @@ wanted a client that would
## Project Maturity ## Project Maturity
Monger is not a young project: started in July 2011, it is over 7 Monger is not a young project: started in July 2011, it is over 3
years old with active production use from week 1. years old with active production use from week 1.
@ -50,14 +45,14 @@ Maven, add the following repository definition to your `pom.xml`:
With Leiningen: With Leiningen:
[com.novemberain/monger "3.5.0"] [com.novemberain/monger "3.0.0-rc2"]
With Maven: With Maven:
<dependency> <dependency>
<groupId>com.novemberain</groupId> <groupId>com.novemberain</groupId>
<artifactId>monger</artifactId> <artifactId>monger</artifactId>
<version>3.5.0</version> <version>3.0.0-rc2</version>
</dependency> </dependency>
@ -75,13 +70,15 @@ questions, too!
Please see our [documentation guides site](http://clojuremongodb.info/) and [API reference](http://reference.clojuremongodb.info). Please see our [documentation guides site](http://clojuremongodb.info/) and [API reference](http://reference.clojuremongodb.info).
Our [test suite](https://github.com/michaelklishin/monger/tree/master/test/monger/test) Our [test
suite](https://github.com/michaelklishin/monger/tree/master/test/monger/test)
also has many code examples. also has many code examples.
## Community ## Community
[Monger has a mailing list](https://groups.google.com/forum/#!forum/clojure-mongodb). Feel [Monger has a mailing
list](https://groups.google.com/forum/#!forum/clojure-mongodb). Feel
free to join it and ask any questions you may have. free to join it and ask any questions you may have.
To subscribe for announcements of releases, important changes and so To subscribe for announcements of releases, important changes and so
@ -91,13 +88,14 @@ on Twitter.
## Supported Clojure versions ## Supported Clojure versions
Monger requires Clojure 1.8+. The most recent Monger requires Clojure 1.6+. The most recent
stable release is highly recommended. stable release is highly recommended.
## Continuous Integration Status ## Continuous Integration Status
[![Continuous Integration status](https://secure.travis-ci.org/michaelklishin/monger.svg)](http://travis-ci.org/michaelklishin/monger) [![Continuous Integration status](https://secure.travis-ci.org/michaelklishin/monger.svg)](http://travis-ci.org/michaelklishin/monger)
[![Dependencies Status](http://jarkeeper.com/michaelklishin/monger/status.svg)](http://jarkeeper.com/michaelklishin/monger)
## Monger Is a ClojureWerkz Project ## Monger Is a ClojureWerkz Project
@ -112,13 +110,6 @@ 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 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 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 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 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
@ -128,7 +119,7 @@ on Github.
## License ## License
Copyright (C) 2011-2018 [Michael S. Klishin](http://twitter.com/michaelklishin), Alex Petrov, and the ClojureWerkz team. Copyright (C) 2011-2015 [Michael S. Klishin](http://twitter.com/michaelklishin), Alex Petrov, and the ClojureWerkz team.
Double licensed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html) (the same as Clojure) or Double licensed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html) (the same as Clojure) or
the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).

View file

@ -1,18 +1,11 @@
#!/bin/sh #!/bin/sh
# Check which MongoDB shell is available # MongoDB seems to need some time to boot first. MK.
if command -v mongosh >/dev/null 2>&1; then sleep 5
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, # MongoDB Java driver won't run authentication twice on the same DB instance,
# so we need to use multiple DBs. # so we need to use multiple DBs.
$MONGO_SHELL --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"]})' monger-test
$MONGO_SHELL --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"]})' monger-test2
$MONGO_SHELL --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"]})' monger-test3
$MONGO_SHELL --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})' monger-test4 mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"]})' monger-test4

View file

@ -1,18 +0,0 @@
#!/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

View file

@ -1,11 +0,0 @@
#!/bin/sh
# MongoDB seems to need some time to boot first. MK.
sleep 5
# 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"], passwordDigestor: "client"})' monger-test
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], passwordDigestor: "client"})' monger-test2
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], passwordDigestor: "client"})' monger-test3
mongo --eval 'db.createUser({"user": "clojurewerkz/monger", "pwd": "monger", roles: ["dbAdmin"], passwordDigestor: "client"})' monger-test4

View file

@ -1,8 +1,7 @@
#!/bin/sh #!/bin/sh
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.0 main" | sudo tee /etc/apt/sources.list.d/mongodb-org.list
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo apt-get update sudo apt-get update
sudo apt-get install -y mongodb-org sudo apt-get install -y mongodb-org

View file

@ -1,11 +0,0 @@
# 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 "4.0.0-SNAPSHOT" (defproject com.novemberain/monger "3.0.3-SNAPSHOT"
:description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included"
:url "http://clojuremongodb.info" :url "http://clojuremongodb.info"
:min-lein-version "2.5.1" :min-lein-version "2.5.1"
:license {:name "Eclipse Public License" :license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"} :url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.11.1"] :dependencies [[org.clojure/clojure "1.7.0"]
[org.mongodb/mongodb-driver "3.12.11"] [org.mongodb/mongodb-driver "3.2.0"]
[clojurewerkz/support "1.5.0"]] [clojurewerkz/support "1.1.0"]]
:test-selectors {:default (fn [m] :test-selectors {:default (fn [m]
(and (not (:performance m)) (and (not (:performance m))
(not (:edge-features m)) (not (:edge-features m))
@ -27,32 +27,39 @@
:all (constantly true)} :all (constantly true)}
:source-paths ["src/clojure"] :source-paths ["src/clojure"]
:java-source-paths ["src/java"] :java-source-paths ["src/java"]
:javac-options ["-target" "1.8" "-source" "1.8"] :javac-options ["-target" "1.6" "-source" "1.6"]
:mailing-list {:name "clojure-mongodb" :mailing-list {:name "clojure-mongodb"
:archive "https://groups.google.com/group/clojure-mongodb" :archive "https://groups.google.com/group/clojure-mongodb"
:post "clojure-mongodb@googlegroups.com"} :post "clojure-mongodb@googlegroups.com"}
:profiles {:1.10 {:dependencies [[org.clojure/clojure "1.10.2"]]} :profiles {:dj02x {:dependencies [[org.clojure/data.json "0.2.6" :exclusions [org.clojure/clojure]]]}
:1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]} :1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
:master {:dependencies [[org.clojure/clojure "1.8.0-master-SNAPSHOT"]]}
:dev {:resource-paths ["test/resources"] :dev {:resource-paths ["test/resources"]
:dependencies [[clj-time "0.15.1" :exclusions [org.clojure/clojure]] :dependencies [[clj-time "0.8.0" :exclusions [org.clojure/clojure]]
[cheshire "5.8.1" :exclusions [org.clojure/clojure]] [cheshire "5.5.0" :exclusions [org.clojure/clojure]]
[org.clojure/data.json "2.5.0" :exclusions [org.clojure/clojure]] [org.clojure/data.json "0.2.5" :exclusions [org.clojure/clojure]]
[org.clojure/tools.cli "0.4.1" :exclusions [org.clojure/clojure]] [org.clojure/tools.cli "0.3.1" :exclusions [org.clojure/clojure]]
[org.clojure/core.cache "0.7.1" :exclusions [org.clojure/clojure]] [org.clojure/core.cache "0.6.3" :exclusions [org.clojure/clojure]]
[ring/ring-core "1.7.1" :exclusions [org.clojure/clojure]] [ring/ring-core "1.3.0" :exclusions [org.clojure/clojure]]
[com.novemberain/validateur "2.6.0" :exclusions [org.clojure/clojure]] [com.novemberain/validateur "2.4.2" :exclusions [org.clojure/clojure]]
[ch.qos.logback/logback-classic "1.2.3" :exclusions [org.slf4j/slf4j-api]] [ch.qos.logback/logback-classic "1.1.3" :exclusions [org.slf4j/slf4j-api]]
[ragtime/core "0.7.2" :exclusions [org.clojure/clojure]]] [ragtime/ragtime.core "0.3.7" :exclusions [org.clojure/clojure]]]
:plugins [[lein-codox "0.10.5"]] :plugins [[codox "0.8.10"]]
:codox {:source-paths ["src/clojure"] :codox {:sources ["src/clojure"]
:namespaces [#"^monger\.(?!internal)"]}} :output-dir "doc/api"
:exclude [monger.internal.pagination
monger.internal.fn
;; these are not fully baked yet or have changes
;; that are not entirely backwards compatible with 1.0. MK.
monger.testkit
monger.ring.session-store]}}
;; only clj-time/JodaTime available, used to test monger.joda-time w/o clojure.data.json ;; only clj-time/JodaTime available, used to test monger.joda-time w/o clojure.data.json
:dev2 {:resource-paths ["test/resources"] :dev2 {:resource-paths ["test/resources"]
:dependencies [[clj-time "0.15.2" :exclusions [org.clojure/clojure]]]}} :dependencies [[clj-time "0.8.0" :exclusions [org.clojure/clojure]]]}}
:aliases {"all" ["with-profile" "dev:dev,1.10:dev,1.9:dev"]} :aliases {"all" ["with-profile" "dev:dev,1.6:dev,dj02x"]}
:repositories {"sonatype" {:url "https://oss.sonatype.org/content/repositories/releases" :repositories {"sonatype" {:url "http://oss.sonatype.org/content/repositories/releases"
:snapshots false :snapshots false
:releases {:checksum :fail :update :always}} :releases {:checksum :fail :update :always}}
"sonatype-snapshots" {:url "https://oss.sonatype.org/content/repositories/snapshots" "sonatype-snapshots" {:url "http://oss.sonatype.org/content/repositories/snapshots"
:snapshots true :snapshots true
:releases {:checksum :fail :update :always}}}) :releases {:checksum :fail :update :always}}})

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; Copyright (c) 2012 Baishampayan Ghose ;; Copyright (c) 2012 Baishampayan Ghose
;; ;;
@ -24,7 +24,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; Copyright (c) 2012 Baishampayan Ghose ;; Copyright (c) 2012 Baishampayan Ghose
;; ;;
@ -50,7 +50,7 @@
* http://clojuremongodb.info/articles/updating.html * http://clojuremongodb.info/articles/updating.html
* http://clojuremongodb.info/articles/deleting.html * http://clojuremongodb.info/articles/deleting.html
* http://clojuremongodb.info/articles/aggregation.html" * http://clojuremongodb.info/articles/aggregation.html"
(:refer-clojure :exclude [find remove count drop distinct empty? any? update]) (:refer-clojure :exclude [find remove count drop distinct empty? update])
(:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern (:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern
DBCursor MapReduceCommand MapReduceCommand$OutputType AggregationOutput DBCursor MapReduceCommand MapReduceCommand$OutputType AggregationOutput
AggregationOptions AggregationOptions$OutputMode] AggregationOptions AggregationOptions$OutputMode]
@ -61,8 +61,7 @@
(:require [monger.core :as mc] (:require [monger.core :as mc]
[monger.result :as mres] [monger.result :as mres]
[monger.conversion :refer :all] [monger.conversion :refer :all]
[monger.constraints :refer :all] [monger.constraints :refer :all]))
[monger.util :refer [into-array-list]]))
;; ;;
@ -109,7 +108,7 @@
(defn ^WriteResult insert-batch (defn ^WriteResult insert-batch
"Saves documents to collection. You can optionally specify WriteConcern as a third argument." "Saves documents do collection. You can optionally specify WriteConcern as a third argument."
([^DB db ^String coll ^List documents] ([^DB db ^String coll ^List documents]
(.insert (.getCollection db (name coll)) (.insert (.getCollection db (name coll))
^List (to-db-object documents) ^List (to-db-object documents)
@ -148,10 +147,8 @@
(with-open [dbc (find db coll ref)] (with-open [dbc (find db coll ref)]
(map (fn [x] (from-db-object x true)) dbc))) (map (fn [x] (from-db-object x true)) dbc)))
([^DB db ^String coll ^Map ref fields] ([^DB db ^String coll ^Map ref fields]
(find-maps db coll ref fields true))
([^DB db ^String coll ^Map ref fields keywordize]
(with-open [dbc (find db coll ref fields)] (with-open [dbc (find db coll ref fields)]
(map (fn [x] (from-db-object x keywordize)) dbc)))) (map (fn [x] (from-db-object x true)) dbc))))
(defn find-seq (defn find-seq
"Queries for objects in this collection, returns ISeq of DBObjects." "Queries for objects in this collection, returns ISeq of DBObjects."
@ -226,13 +223,13 @@
"Returns a single object, converted to map with matching _id field." "Returns a single object, converted to map with matching _id field."
([^DB db ^String coll id] ([^DB db ^String coll id]
(check-not-nil! id "id must not be nil") (check-not-nil! id "id must not be nil")
(find-one-as-map db coll {:_id id})) (from-db-object ^DBObject (find-one-as-map db coll {:_id id}) true))
([^DB db ^String coll id fields] ([^DB db ^String coll id fields]
(check-not-nil! id "id must not be nil") (check-not-nil! id "id must not be nil")
(find-one-as-map db coll {:_id id} fields)) (from-db-object ^DBObject (find-one-as-map db coll {:_id id} fields) true))
([^DB db ^String coll id fields keywordize] ([^DB db ^String coll id fields keywordize]
(check-not-nil! id "id must not be nil") (check-not-nil! id "id must not be nil")
(find-one-as-map db coll {:_id id} fields keywordize))) (from-db-object ^DBObject (find-one-as-map db coll {:_id id} fields) keywordize)))
;; ;;
;; monger.collection/count ;; monger.collection/count
@ -451,9 +448,9 @@
(defn drop-index (defn drop-index
"Drops an index from this collection." "Drops an index from this collection."
[^DB db ^String coll idx] [^DB db ^String coll idx]
(if (string? idx) (.dropIndex (.getCollection db (name coll)) (if (string? idx)
(.dropIndex (.getCollection db (name coll)) ^String idx) idx
(.dropIndex (.getCollection db (name coll)) (to-db-object idx)))) (to-db-object idx))))
(defn drop-indexes (defn drop-indexes
"Drops all indixes from this collection." "Drops all indixes from this collection."
@ -467,7 +464,7 @@
(defn exists? (defn exists?
"Checks whether collection with certain name exists." "Checks weather collection with certain name exists."
([^DB db ^String coll] ([^DB db ^String coll]
(.collectionExists db coll))) (.collectionExists db coll)))
@ -490,9 +487,9 @@
(defn rename (defn rename
"Renames collection." "Renames collection."
([^DB db ^String from, ^String to] ([^DB db ^String from, ^String to]
(.rename (.getCollection db (name from)) (name to))) (.rename (.getCollection db from) to))
([^DB db ^String from ^String to drop-target?] ([^DB db ^String from ^String to drop-target?]
(.rename (.getCollection db (name from)) (name to) drop-target?))) (.rename (.getCollection db from) to drop-target?)))
;; ;;
;; Map/Reduce ;; Map/Reduce
@ -525,7 +522,6 @@
;; ;;
(defn- build-aggregation-options (defn- build-aggregation-options
^AggregationOptions
[{:keys [^Boolean allow-disk-use cursor ^Long max-time]}] [{:keys [^Boolean allow-disk-use cursor ^Long max-time]}]
(cond-> (AggregationOptions/builder) (cond-> (AggregationOptions/builder)
allow-disk-use (.allowDiskUse allow-disk-use) allow-disk-use (.allowDiskUse allow-disk-use)
@ -541,26 +537,22 @@
is supported, for specifying a limit on the execution time of the query in is supported, for specifying a limit on the execution time of the query in
milliseconds. milliseconds.
:keywordize option that control if resulting map keys will be turned into keywords, default is true.
See http://docs.mongodb.org/manual/applications/aggregation/ to learn more." See http://docs.mongodb.org/manual/applications/aggregation/ to learn more."
[^DB db ^String coll stages & opts] [^DB db ^String coll stages & opts]
(let [coll (.getCollection db (name coll)) (let [coll (.getCollection db coll)
agg-opts (build-aggregation-options opts) agg-opts (build-aggregation-options opts)
pipe (into-array-list (to-db-object stages)) pipe (java.util.ArrayList. (to-db-object stages))
res (.aggregate coll pipe agg-opts) res (.aggregate coll pipe agg-opts)]
{:keys [^Boolean keywordize] (map #(from-db-object % true) (iterator-seq res))))
:or {keywordize true}} opts]
(map #(from-db-object % keywordize) (iterator-seq res))))
(defn explain-aggregate (defn explain-aggregate
"Returns the explain plan for an aggregation query. MongoDB 2.2+ only. "Returns the explain plan for an aggregation query. MongoDB 2.2+ only.
See http://docs.mongodb.org/manual/applications/aggregation/ to learn more." See http://docs.mongodb.org/manual/applications/aggregation/ to learn more."
[^DB db ^String coll stages & opts] [^DB db ^String coll stages & opts]
(let [coll (.getCollection db (name coll)) (let [coll (.getCollection db coll)
agg-opts (build-aggregation-options opts) agg-opts (build-aggregation-options opts)
pipe (into-array-list (to-db-object stages)) pipe (java.util.ArrayList. (to-db-object stages))
res (.explainAggregate coll pipe agg-opts)] res (.explainAggregate coll pipe agg-opts)]
(from-db-object res true))) (from-db-object res true)))
;; ;;

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +23,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; All rights reserved. ;; All rights reserved.
;; ;;

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -5,7 +5,7 @@
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Portions of the code are Copyright (c) 2009 Andrew Boekhoff ;; Portions of the code are Copyright (c) 2009 Andrew Boekhoff
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -24,7 +24,7 @@
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Portions of the code are Copyright (c) 2009 Andrew Boekhoff ;; Portions of the code are Copyright (c) 2009 Andrew Boekhoff
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -46,8 +46,7 @@
(:import [com.mongodb DBObject BasicDBObject BasicDBList DBCursor] (:import [com.mongodb DBObject BasicDBObject BasicDBList DBCursor]
[clojure.lang IPersistentMap Named Keyword Ratio] [clojure.lang IPersistentMap Named Keyword Ratio]
[java.util List Map Date Set] [java.util List Map Date Set]
org.bson.types.ObjectId org.bson.types.ObjectId))
(org.bson.types Decimal128)))
(defprotocol ConvertToDBObject (defprotocol ConvertToDBObject
(^com.mongodb.DBObject to-db-object [input] "Converts given piece of Clojure data to BasicDBObject MongoDB Java driver uses")) (^com.mongodb.DBObject to-db-object [input] "Converts given piece of Clojure data to BasicDBObject MongoDB Java driver uses"))
@ -105,44 +104,55 @@
(declare associate-pairs)
(defprotocol ConvertFromDBObject (defprotocol ConvertFromDBObject
(from-db-object [input keywordize] "Converts given DBObject instance to a piece of Clojure data")) (from-db-object [input keywordize] "Converts given DBObject instance to a piece of Clojure data"))
(extend-protocol ConvertFromDBObject (extend-protocol ConvertFromDBObject
nil nil
(from-db-object [_ _] nil) (from-db-object [input keywordize] input)
Object Object
(from-db-object [input _] input) (from-db-object [input keywordize] input)
Decimal128 Map
(from-db-object [^Decimal128 input _] (from-db-object [^Map input keywordize]
(.bigDecimalValue input)) (associate-pairs (.entrySet input) keywordize))
List List
(from-db-object [^List input keywordize] (from-db-object [^List input keywordize]
(mapv #(from-db-object % keywordize) input)) (vec (map #(from-db-object % keywordize) input)))
BasicDBList BasicDBList
(from-db-object [^BasicDBList input keywordize] (from-db-object [^BasicDBList input keywordize]
(mapv #(from-db-object % keywordize) input)) (vec (map #(from-db-object % keywordize) input)))
com.mongodb.DBRef com.mongodb.DBRef
(from-db-object [^com.mongodb.DBRef input _] (from-db-object [^com.mongodb.DBRef input keywordize]
input) input)
DBObject DBObject
(from-db-object [^DBObject input keywordize] (from-db-object [^DBObject input keywordize]
;; DBObject provides .toMap, but the implementation in ;; DBObject provides .toMap, but the implementation in
;; subclass GridFSFile unhelpfully throws ;; subclass GridFSFile unhelpfully throws
;; UnsupportedOperationException. ;; UnsupportedOperationException. This part is taken from congomongo and
(persistent! ;; may need revisiting at a later point. MK.
(reduce (if keywordize (associate-pairs (for [key-set (.keySet input)] [key-set (.get input key-set)])
(fn [m ^String k] keywordize)))
(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)))) (defn- associate-pairs [pairs keywordize]
(transient {}) (.keySet input))))) ;; Taking the keywordize test out of the fn reduces derefs
;; dramatically, which was the main barrier to matching pure-Java
;; performance for this marshalling. Taken from congomongo. MK.
(reduce (if keywordize
(fn [m [^String k v]]
(assoc m (keyword k) (from-db-object v true)))
(fn [m [^String k v]]
(assoc m k (from-db-object v false))))
{} (reverse pairs)))
(defprotocol ConvertToObjectId (defprotocol ConvertToObjectId

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -42,12 +42,11 @@
* http://clojuremongodb.info/articles/commands.html * http://clojuremongodb.info/articles/commands.html
* http://clojuremongodb.info/articles/gridfs.html" * http://clojuremongodb.info/articles/gridfs.html"
(:refer-clojure :exclude [count]) (:refer-clojure :exclude [count])
(:require [monger.conversion :refer :all] (:require [monger.conversion :refer :all])
[monger.util :refer [into-array-list]])
(:import [com.mongodb MongoClient MongoClientURI MongoCredential DB WriteConcern DBObject DBCursor Bytes (:import [com.mongodb MongoClient MongoClientURI MongoCredential DB WriteConcern DBObject DBCursor Bytes
MongoClientOptions MongoClientOptions$Builder ServerAddress MapReduceOutput MongoException] MongoClientOptions MongoClientOptions$Builder ServerAddress MapReduceOutput MongoException]
[com.mongodb.gridfs GridFS] [com.mongodb.gridfs GridFS]
[java.util Map])) [java.util Map ArrayList]))
;; ;;
;; Defaults ;; Defaults
@ -70,27 +69,26 @@
:host (\"127.0.0.1\" by default) :host (\"127.0.0.1\" by default)
:port (27017 by default)" :port (27017 by default)"
{:arglists '([] {:arglists '([]
[server-address options] [server-address options]
[server-address options credentials] [[server-address & more] options]
[[server-address & more] options] [{:keys [host port uri] :or { host *mongodb-host* port *mongodb-port*}}])}
[{:keys [host port uri] :or { host *mongodb-host* port *mongodb-port*}}])}
([] ([]
(MongoClient.)) (MongoClient.))
([server-address ^MongoClientOptions options] ([server-address ^MongoClientOptions options]
(if (coll? server-address) (if (coll? server-address)
;; connect to a replica set ;; connect to a replica set
(let [server-list (into-array-list server-address)] (let [server-list ^ArrayList (ArrayList. ^java.util.Collection server-address)]
(MongoClient. server-list options)) (MongoClient. server-list options))
;; connect to a single instance ;; connect to a single instance
(MongoClient. ^ServerAddress server-address options))) (MongoClient. ^ServerAddress server-address options)))
([server-address ^MongoClientOptions options credentials] ([server-address ^MongoClientOptions options credentials]
(let [creds (into-array-list (if (coll? credentials) (let [creds (if (coll? credentials)
credentials credentials
[credentials]))] [credentials])]
(if (coll? server-address) (if (coll? server-address)
(let [server-list (into-array-list server-address)] (let [server-list ^ArrayList (ArrayList. ^java.util.Collection server-address)]
(MongoClient. server-list ^java.util.List creds options)) (MongoClient. server-list creds options))
(MongoClient. ^ServerAddress server-address ^java.util.List creds options)))) (MongoClient. ^ServerAddress server-address creds options))))
([{ :keys [host port uri] :or { host *mongodb-host* port *mongodb-port* }}] ([{ :keys [host port uri] :or { host *mongodb-host* port *mongodb-port* }}]
(if uri (if uri
(MongoClient. (MongoClientURI. uri)) (MongoClient. (MongoClientURI. uri))
@ -102,11 +100,11 @@
(connect-with-credentials *mongodb-host* *mongodb-port* credentials)) (connect-with-credentials *mongodb-host* *mongodb-port* credentials))
([^String hostname credentials] ([^String hostname credentials]
(connect-with-credentials hostname *mongodb-port* credentials)) (connect-with-credentials hostname *mongodb-port* credentials))
([^String hostname ^long port credentials] ([^String hostname port credentials]
(MongoClient. (into-array-list [(ServerAddress. hostname port)]) (MongoClient. [(ServerAddress. hostname port)]
(into-array-list (if (coll? credentials) (if (coll? credentials)
credentials credentials
[credentials]))))) [credentials]))))
(defn get-db-names (defn get-db-names
"Gets a list of all database names present on the server" "Gets a list of all database names present on the server"
@ -136,112 +134,38 @@
(ServerAddress. hostname port))) (ServerAddress. hostname port)))
(defn ^MongoClientOptions$Builder mongo-options-builder (defn ^MongoClientOptions$Builder mongo-options-builder
[{:keys [add-cluster-listener add-cluster-listeners add-command-listener add-command-listeners [{:keys [connections-per-host threads-allowed-to-block-for-connection-multiplier
add-connection-pool-listener add-connection-pool-listeners add-server-listener add-server-listeners max-wait-time connect-timeout socket-timeout socket-keep-alive auto-connect-retry max-auto-connect-retry-time
add-server-monitor-listener add-server-monitor-listeners always-use-mbeans application-name description write-concern cursor-finalizer-enabled read-preference
codec-registry compressor-list connect-timeout connections-per-host cursor-finalizer-enabled required-replica-set-name] :or [auto-connect-retry true]}]
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.)] (let [mob (MongoClientOptions$Builder.)]
(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 (when connections-per-host
(.connectionsPerHost mob 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
(.minConnectionsPerHost mob min-connections-per-host))
(when min-heartbeat-frequency
(.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 (when threads-allowed-to-block-for-connection-multiplier
(.threadsAllowedToBlockForConnectionMultiplier mob threads-allowed-to-block-for-connection-multiplier)) (.threadsAllowedToBlockForConnectionMultiplier mob threads-allowed-to-block-for-connection-multiplier))
(when uuid-representation (when max-wait-time
(.uuidRepresentation mob uuid-representation)) (.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 auto-connect-retry
(.autoConnectRetry mob auto-connect-retry))
;; deprecated
(when max-auto-connect-retry-time
(.maxAutoConnectRetryTime mob max-auto-connect-retry-time))
(when read-preference
(.readPreference mob read-preference))
(when description
(.description mob description))
(when write-concern (when write-concern
(.writeConcern mob 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))
mob)) mob))
(defn ^MongoClientOptions mongo-options (defn ^MongoClientOptions mongo-options
@ -273,11 +197,10 @@
Commonly used for PaaS-based applications, for example, running on Heroku. Commonly used for PaaS-based applications, for example, running on Heroku.
If username and password are provided, performs authentication." If username and password are provided, performs authentication."
[^String uri-string] [^String uri-string]
(let [uri (MongoClientURI. uri-string) (let [uri (MongoClientURI. uri-string)
conn (MongoClient. uri)] conn (MongoClient. uri)
(if-let [dbName (.getDatabase uri)] db (.getDB conn (.getDatabase uri))]
{:conn conn :db (.getDB conn dbName)} {:conn conn :db db}))
(throw (IllegalArgumentException. "No database name specified in URI. Monger requires a database to be explicitly configured.")))))
(defn ^com.mongodb.CommandResult command (defn ^com.mongodb.CommandResult command
"Runs a database command (please check MongoDB documentation for the complete list of commands). "Runs a database command (please check MongoDB documentation for the complete list of commands).

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +23,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; Copyright (c) 2012 Toby Hede ;; Copyright (c) 2012 Toby Hede
;; All rights reserved. ;; All rights reserved.
;; ;;

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -114,30 +114,9 @@
(to-input-stream [^InputStream input] (to-input-stream [^InputStream input]
input)) input))
(defprotocol GridFSInputFileFactory
(^GridFSInputFile create-gridfs-file [input ^GridFS fs] "Creates a file entry"))
(extend byte-array-type
GridFSInputFileFactory
{:create-gridfs-file (fn [^bytes input ^GridFS fs]
(.createFile fs input))})
(extend-protocol GridFSInputFileFactory
String
(create-gridfs-file [^String input ^GridFS fs]
(.createFile fs (io/file input)))
File
(create-gridfs-file [^File input ^GridFS fs]
(.createFile fs input))
InputStream
(create-gridfs-file [^InputStream input ^GridFS fs]
(.createFile fs input)))
(defn ^GridFSInputFile make-input-file (defn ^GridFSInputFile make-input-file
[^GridFS fs input] [^GridFS fs input]
(create-gridfs-file input fs)) (.createFile fs (to-input-stream input)))
(defmacro store (defmacro store
[^GridFSInputFile input & body] [^GridFSInputFile input & body]
@ -209,4 +188,4 @@
(defn find-map-by-id (defn find-map-by-id
[^GridFS fs ^ObjectId id] [^GridFS fs ^ObjectId id]
(converter (find-by-id fs id))) (converter (find-one fs id)))

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -70,19 +70,13 @@
(try (try
(extend-protocol clojure.data.json/JSONWriter (extend-protocol clojure.data.json/JSONWriter
ObjectId ObjectId
(-write (-write [^ObjectId object out]
([^ObjectId object out] (clojure.data.json/write (.toString 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 (extend-protocol clojure.data.json/JSONWriter
BSONTimestamp BSONTimestamp
(-write (-write [^BSONTimestamp object out]
([^BSONTimestamp object out] (clojure.data.json/write {:time (.getTime object) :inc (.getInc 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 _ (catch Throwable _
false)) false))

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -46,8 +46,6 @@
;; QUERY OPERATORS ;; QUERY OPERATORS
;; ;;
(declare $gt $gte $lt $lte $all $in $nin $eq $ne $elemMatch $regex $options)
;; $gt is "greater than" comparator ;; $gt is "greater than" comparator
;; $gte is "greater than or equals" comparator ;; $gte is "greater than or equals" comparator
;; $gt is "less than" comparator ;; $gt is "less than" comparator
@ -82,16 +80,10 @@
;; (mgcol/find-maps "languages" { :tags { $nin [ "functional" ] } } ) ;; (mgcol/find-maps "languages" { :tags { $nin [ "functional" ] } } )
(defoperator $nin) (defoperator $nin)
;; $eq is "equals" comparator
;;
;; EXAMPLES:
;; (monger.collection/find "libraries" { :language { $eq "Clojure" }})
(defoperator $eq)
;; $ne is "non-equals" comparator ;; $ne is "non-equals" comparator
;; ;;
;; EXAMPLES: ;; EXAMPLES:
;; (monger.collection/find "libraries" { :language { $ne "Clojure" }}) ;; (monger.collection/find "libraries" {$ne { :language "Clojure" }})
(defoperator $ne) (defoperator $ne)
;; $elemMatch checks if an element in an array matches the specified expression ;; $elemMatch checks if an element in an array matches the specified expression
@ -104,37 +96,6 @@
(defoperator $regex) (defoperator $regex)
(defoperator $options) (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:
;;
;; (monger.collection/find "people" { $where "this.placeOfBirth === this.address.city" })
(defoperator $where)
;; ;;
;; LOGIC OPERATORS ;; LOGIC OPERATORS
;; ;;
@ -167,8 +128,6 @@
;; ATOMIC MODIFIERS ;; 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 ;; $inc increments one or many fields for the given value, otherwise sets the field to value
;; ;;
;; EXAMPLES: ;; EXAMPLES:
@ -212,9 +171,6 @@
;; (mgcol/update "docs" { :_id oid } { $push { :tags "modifiers" } }) ;; (mgcol/update "docs" { :_id oid } { $push { :tags "modifiers" } })
(defoperator $push) (defoperator $push)
;; $position modifies the behavior of $push per https://docs.mongodb.com/manual/reference/operator/update/position/
(defoperator $position)
;; $each is a modifier for the $push and $addToSet operators for appending multiple values to an array field. ;; $each is a modifier for the $push and $addToSet operators for appending multiple values to an array field.
;; Without the $each modifier $push and $addToSet will append an array as a single value. ;; Without the $each modifier $push and $addToSet will append an array as a single value.
;; MongoDB 2.4 adds support for the $each modifier to the $push operator. ;; MongoDB 2.4 adds support for the $each modifier to the $push operator.
@ -224,6 +180,14 @@
;; (mgcol/update coll { :_id oid } { $push { :tags { $each ["mongodb" "docs"] } } }) ;; (mgcol/update coll { :_id oid } { $push { :tags { $each ["mongodb" "docs"] } } })
(defoperator $each) (defoperator $each)
;; $pushAll appends each value in value_array to field, if field is an existing array, otherwise sets field to the array value_array
;; if field is not present. If field is present but is not an array, an error condition is raised.
;; Deprecated since MongoDB 2.4, $push with $each modifier should be used instead.
;;
;; EXAMPLES:
;; (mgcol/update coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } })
(defoperator $pushAll)
;; $addToSet Adds value to the array only if its not in the array already, if field is an existing array, otherwise sets field to the ;; $addToSet Adds value to the array only if its not in the array already, if field is an existing array, otherwise sets field to the
;; array value if field is not present. If field is present but is not an array, an error condition is raised. ;; array value if field is not present. If field is present but is not an array, an error condition is raised.
;; ;;
@ -250,15 +214,11 @@
;; an error condition is raised. ;; an error condition is raised.
;; ;;
;; EXAMPLES: ;; EXAMPLES:
;; (mgcol/update coll { :_id oid } { $pullAll { :measurements 1.2 } }) ;; (mgcol/update coll { :_id oid } { $pull { :measurements 1.2 } })
;; (mgcol/update coll { :_id oid } { $pullAll { :measurements { $gte 1.2 } } }) ;; (mgcol/update coll { :_id oid } { $pull { :measurements { $gte 1.2 } } })
(defoperator $pullAll) (defoperator $pullAll)
(defoperator $bit) (defoperator $bit)
(defoperator $bitsAllClear)
(defoperator $bitsAllSet)
(defoperator $bitsAnyClear)
(defoperator $bitsAnySet)
(defoperator $exists) (defoperator $exists)
(defoperator $mod) (defoperator $mod)
@ -268,132 +228,36 @@
;; ;;
;; Aggregation in 4.2 ;; Aggregation in 2.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 $match)
(defoperator $merge)
(defoperator $out)
(defoperator $planCacheStats)
(defoperator $project) (defoperator $project)
(defoperator $redact)
(defoperator $replaceRoot)
(defoperator $replaceWith)
(defoperator $sample)
(defoperator $limit) (defoperator $limit)
(defoperator $skip) (defoperator $skip)
(defoperator $unwind) (defoperator $unwind)
(defoperator $group) (defoperator $group)
(defoperator $sort) (defoperator $sort)
(defoperator $sortByCount)
(defoperator $currentOp)
(defoperator $listLocalSessions)
(defoperator $cmp) (defoperator $cmp)
(defoperator $min) (defoperator $min)
(defoperator $max) (defoperator $max)
(defoperator $avg) (defoperator $avg)
(defoperator $stdDevPop)
(defoperator $stdDevSamp)
(defoperator $sum) (defoperator $sum)
(defoperator $let)
(defoperator $first) (defoperator $first)
(defoperator $last) (defoperator $last)
(defoperator $abs)
(defoperator $add) (defoperator $add)
(defoperator $ceil)
(defoperator $divide) (defoperator $divide)
(defoperator $exp)
(defoperator $floor)
(defoperator $ln)
(defoperator $log)
(defoperator $log10)
(defoperator $multiply) (defoperator $multiply)
(defoperator $pow) (defoperator $substract)
(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 $strcasecmp)
(defoperator $substr) (defoperator $substr)
(defoperator $substrBytes)
(defoperator $substrCP)
(defoperator $toLower) (defoperator $toLower)
(defoperator $toString)
(defoperator $toUpper) (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 $dayOfMonth)
(defoperator $dayOfWeek) (defoperator $dayOfWeek)
@ -406,54 +270,19 @@
(defoperator $week) (defoperator $week)
(defoperator $year) (defoperator $year)
(defoperator $isoDate) (defoperator $isoDate)
(defoperator $dateFromParts)
(defoperator $dateFromString)
(defoperator $dateToParts)
(defoperator $dateToString)
(defoperator $isoDayOfWeek)
(defoperator $isoWeek)
(defoperator $isoWeekYear)
(defoperator $toDate)
(defoperator $ifNull) (defoperator $ifNull)
(defoperator $cond) (defoperator $cond)
(defoperator $switch)
;; Geospatial
(declare $geoWithin $geoIntersects $near $nearSphere $geometry $maxDistance $minDistance $center $centerSphere $box $polygon $slice)
(defoperator $geoWithin) (defoperator $geoWithin)
(defoperator $geoIntersects) (defoperator $geoIntersects)
(defoperator $near) (defoperator $near)
(defoperator $nearSphere)
(defoperator $geometry)
(defoperator $maxDistance)
(defoperator $minDistance)
(defoperator $center)
(defoperator $centerSphere)
(defoperator $box)
(defoperator $polygon)
(defoperator $slice) (defoperator $slice)
;; full text search ;; full text search
(declare $text $meta $search $language $natural $currentDate $isolated $count)
(defoperator $text) (defoperator $text)
(defoperator $meta)
(defoperator $search) (defoperator $search)
(defoperator $language) (defoperator $language)
(defoperator $natural) (defoperator $natural)
;; $currentDate operator sets the value of a field to the current date, either as a Date or a timestamp. The default type is Date.
;;
;; EXAMPLES:
;; (mgcol/update coll { :_id oid } { $currentDate { :lastModified true } })
(defoperator $currentDate)
;; Isolates intermediate multi-document updates from other clients.
;;
;; EXAMPLES:
;; (mgcol/update "libraries" { :language "Clojure", $isolated 1 } { $inc { :popularity 1 } } {:multi true})
(defoperator $isolated)
(defoperator $count)

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -43,7 +43,6 @@
[monger.conversion :refer :all] [monger.conversion :refer :all]
[monger.operators :refer :all]) [monger.operators :refer :all])
(:import [com.mongodb DB DBCollection DBObject DBCursor ReadPreference] (:import [com.mongodb DB DBCollection DBObject DBCursor ReadPreference]
[java.util.concurrent TimeUnit]
java.util.List)) java.util.List))
@ -97,7 +96,6 @@
snapshot snapshot
read-preference read-preference
keywordize-fields keywordize-fields
max-time
options] options]
:or { limit 0 batch-size 256 skip 0 } }] :or { limit 0 batch-size 256 skip 0 } }]
(with-open [cursor (doto (.find collection (to-db-object query) (as-field-selector fields)) (with-open [cursor (doto (.find collection (to-db-object query) (as-field-selector fields))
@ -111,8 +109,6 @@
(.hint cursor (to-db-object hint))) (.hint cursor (to-db-object hint)))
(when read-preference (when read-preference
(.setReadPreference cursor read-preference)) (.setReadPreference cursor read-preference))
(when max-time
(.maxTime cursor max-time TimeUnit/MILLISECONDS))
(when options (when options
(add-options cursor options)) (add-options cursor options))
(map (fn [x] (from-db-object x keywordize-fields)) (map (fn [x] (from-db-object x keywordize-fields))
@ -158,10 +154,6 @@
[m ^ReadPreference rp] [m ^ReadPreference rp]
(merge m { :read-preference rp })) (merge m { :read-preference rp }))
(defn max-time
[m ^long max-time]
(merge m { :max-time max-time }))
(defn options (defn options
[m opts] [m opts]
(merge m { :options opts })) (merge m { :options opts }))

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -34,7 +34,7 @@
(ns monger.ragtime (ns monger.ragtime
"Ragtime integration" "Ragtime integration"
(:refer-clojure :exclude [find sort]) (:refer-clojure :exclude [find sort])
(:require [ragtime.protocols :as proto] (:require [ragtime.core :as ragtime]
[monger.core :as mg] [monger.core :as mg]
[monger.collection :as mc] [monger.collection :as mc]
[monger.query :refer [with-collection find sort]]) [monger.query :refer [with-collection find sort]])
@ -47,7 +47,7 @@
(extend-type com.mongodb.DB (extend-type com.mongodb.DB
proto/DataStore ragtime/Migratable
(add-migration-id [db id] (add-migration-id [db id]
(mc/insert db migrations-collection {:_id id :created_at (Date.)} WriteConcern/FSYNC_SAFE)) (mc/insert db migrations-collection {:_id id :created_at (Date.)} WriteConcern/FSYNC_SAFE))
(remove-migration-id [db id] (remove-migration-id [db id]

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -65,8 +65,3 @@
(acknowledged? (acknowledged?
[^CommandResult result] [^CommandResult result]
(.ok result))) (.ok result)))
(defn affected-count
"Get the number of documents affected"
[^WriteResult result]
(.getN result))

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of

View file

@ -4,7 +4,7 @@
;; The APL v2.0: ;; The APL v2.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team
;; ;;
;; Licensed under the Apache License, Version 2.0 (the "License"); ;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License. ;; you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
;; The EPL v1.0: ;; The EPL v1.0:
;; ;;
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
;; Copyright (c) 2011-2018 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team. ;; Copyright (c) 2011-2015 Michael S. Klishin, Alex Petrov, and the ClojureWerkz Team.
;; All rights reserved. ;; All rights reserved.
;; ;;
;; This program and the accompanying materials are made available under the terms of ;; This program and the accompanying materials are made available under the terms of
@ -32,14 +32,12 @@
;; ---------------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------------
(ns ^{:doc "Provides various utility functions, primarily for working with document ids."} monger.util (ns ^{:doc "Provides various utility functions, primarily for working with document ids."} monger.util
(:refer-clojure :exclude [random-uuid])
(:import java.security.SecureRandom (:import java.security.SecureRandom
java.math.BigInteger java.math.BigInteger
org.bson.types.ObjectId org.bson.types.ObjectId
com.mongodb.DBObject com.mongodb.DBObject
clojure.lang.IPersistentMap clojure.lang.IPersistentMap
java.util.Map) java.util.Map))
(:refer-clojure :exclude [random-uuid]))
;; ;;
;; API ;; API
@ -59,7 +57,7 @@
"Returns a new BSON object id, or converts str to BSON object id" "Returns a new BSON object id, or converts str to BSON object id"
([] ([]
(ObjectId.)) (ObjectId.))
([^String s] ([s]
(ObjectId. s))) (ObjectId. s)))
(defprotocol GetDocumentId (defprotocol GetDocumentId
@ -75,8 +73,3 @@
(get-id (get-id
[^IPersistentMap object] [^IPersistentMap object]
(or (:_id object) (object "_id")))) (or (:_id object) (object "_id"))))
(defn into-array-list
"Coerce a j.u.Collection into a j.u.ArrayList."
^java.util.ArrayList [^java.util.Collection coll]
(java.util.ArrayList. coll))

View file

@ -15,27 +15,6 @@
(use-fixtures :each purge-collections) (use-fixtures :each purge-collections)
(deftest test-basic-single-stage-$project-aggregation-no-keywordize
(let [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 #{{"quantity" 1 "state" "CA"}
{"quantity" 2 "state" "NY"}
{"quantity" 1 "state" "NY"}
{"quantity" 2 "state" "IL"}
{"quantity" 2 "state" "CA"}
{"quantity" 3 "state" "IL"}}]
(mc/insert-batch db coll batch)
(is (= 6 (mc/count db coll)))
(let [result (->>
(mc/aggregate db coll [{$project {"state" 1 "quantity" 1}}] :keywordize false)
(map #(select-keys % ["state" "quantity"]))
(set))]
(is (= expected result)))))
(deftest test-basic-single-stage-$project-aggregation (deftest test-basic-single-stage-$project-aggregation
(let [batch [{:state "CA" :quantity 1 :price 199.00} (let [batch [{:state "CA" :quantity 1 :price 199.00}
{:state "NY" :quantity 2 :price 199.00} {:state "NY" :quantity 2 :price 199.00}
@ -130,7 +109,9 @@
(deftest test-explain-aggregate (deftest test-explain-aggregate
(let [batch [{:state "CA" :price 100} (let [batch [{:state "CA" :price 100}
{:state "CA" :price 10} {:state "CA" :price 10}
{:state "IL" :price 50}]] {:state "IL" :price 50}]
expected-keys #{:ok :stages}]
(mc/insert-batch db coll batch) (mc/insert-batch db coll batch)
(let [result (mc/explain-aggregate db coll [{$match {:state "CA"}}])] (let [result (mc/explain-aggregate db coll [{$match {:state "CA"}}])
(is (:ok result)))))) key-in-result? (partial contains? result)]
(is (every? key-in-result? expected-keys))))))

View file

@ -174,7 +174,7 @@
;; this is a common mistake, I leave it here to demonstrate it. You almost never ;; this is a common mistake, I leave it here to demonstrate it. You almost never
;; actually want to do this! What you really want is to use $push with $each instead of $push. MK. ;; actually want to do this! What you really want is to use $pushAll instead of $push. MK.
(deftest add-array-value-to-an-existing-array-using-$push-modifier (deftest add-array-value-to-an-existing-array-using-$push-modifier
(let [coll "docs" (let [coll "docs"
oid (ObjectId.) oid (ObjectId.)
@ -228,34 +228,34 @@
(mc/find-map-by-id db coll oid))))) (mc/find-map-by-id db coll oid)))))
;; ;;
;; $push + $each (formerly $pushAll) ;; $pushAll
;; ;;
(deftest initialize-an-array-using-$push-and-$each-modifiers (deftest initialize-an-array-using-$pushAll-modifier
(let [coll "docs" (let [coll "docs"
oid (ObjectId.) oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"] title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll {:_id oid :title title}) (mc/insert db coll {:_id oid :title title})
(mc/update db coll {:_id oid} {$push {:tags {$each ["mongodb" "docs"]}}}) (mc/update db coll {:_id oid} {$pushAll {:tags ["mongodb" "docs"]}})
(is (= {:_id oid :title title :tags ["mongodb" "docs"]} (is (= {:_id oid :title title :tags ["mongodb" "docs"]}
(mc/find-map-by-id db coll oid))))) (mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$push-and-$each-modifier (deftest add-value-to-an-existing-array-using-$pushAll-modifier
(let [coll "docs" (let [coll "docs"
oid (ObjectId.) oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"] title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll {:_id oid :title title :tags ["mongodb"]}) (mc/insert db coll {:_id oid :title title :tags ["mongodb"]})
(mc/update db coll {:_id oid} {$push {:tags {$each ["modifiers" "docs"]}}}) (mc/update db coll {:_id oid} {$pushAll {:tags ["modifiers" "docs"]}})
(is (= {:_id oid :title title :tags ["mongodb" "modifiers" "docs"]} (is (= {:_id oid :title title :tags ["mongodb" "modifiers" "docs"]}
(mc/find-map-by-id db coll oid))))) (mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$push-and-$each-modifier (deftest double-add-value-to-an-existing-array-using-$pushAll-modifier
(let [coll "docs" (let [coll "docs"
oid (ObjectId.) oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"] title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll {:_id oid :title title :tags ["mongodb" "docs"]}) (mc/insert db coll {:_id oid :title title :tags ["mongodb" "docs"]})
(mc/update db coll {:_id oid} {$push {:tags {$each ["modifiers" "docs"]}}}) (mc/update db coll {:_id oid} {$pushAll {:tags ["modifiers" "docs"]}})
(is (= {:_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"]} (is (= {:_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"]}
(mc/find-map-by-id db coll oid))))) (mc/find-map-by-id db coll oid)))))

View file

@ -12,12 +12,12 @@
(when-not (System/getenv "CI") (when-not (System/getenv "CI")
(deftest ^{:authentication true} connect-to-mongo-via-uri-without-credentials (deftest ^{:authentication true} connect-to-mongo-via-uri-without-credentials
(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://127.0.0.1/monger-test4")] (let [{:keys [conn db]} (mg/connect-via-uri "mongodb://127.0.0.1/monger-test4")]
(is (-> conn .getAddress (.sameHost "127.0.0.1"))))) (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1"))))))
(deftest ^{:authentication true} connect-to-mongo-via-uri-with-valid-credentials (deftest ^{:authentication true} connect-to-mongo-via-uri-with-valid-credentials
(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz%2Fmonger:monger@127.0.0.1/monger-test4")] (let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")]
(is (= "monger-test4" (.getName db))) (is (= "monger-test4" (.getName db)))
(is (-> conn .getAddress (.sameHost "127.0.0.1"))) (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1"))))
(mc/remove db "documents") (mc/remove db "documents")
;; make sure that the database is selected ;; make sure that the database is selected
;; and operations get through. ;; and operations get through.
@ -27,7 +27,7 @@
(if-let [uri (System/getenv "MONGOHQ_URL")] (if-let [uri (System/getenv "MONGOHQ_URL")]
(deftest ^{:external true :authentication true} connect-to-mongo-via-uri-with-valid-credentials (deftest ^{:external true :authentication true} connect-to-mongo-via-uri-with-valid-credentials
(let [{:keys [conn db]} (mg/connect-via-uri uri)] (let [{:keys [conn db]} (mg/connect-via-uri uri)]
(is (-> conn .getAddress (.sameHost "127.0.0.1")))))) (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1")))))))
;; ;;

View file

@ -0,0 +1,126 @@
(ns monger.test.cache-test
(:require [monger.core :as mg]
[monger.collection :as mc]
[clojure.core.cache :refer :all]
[clojure.test :refer :all]
[monger.cache :refer :all])
(:import [clojure.core.cache BasicCache FIFOCache LRUCache TTLCache]
java.util.UUID))
;;
;; Playground/Tests. These were necessary because clojure.core.cache has
;; little documentation, incomplete test suite and
;; slightly non-standard (although necessary to support all those cache variations)
;; cache operations protocol.
;;
;; This is by no means clear or complete either but it did the job of helping me
;; explore the API.
(deftest ^{:cache true}
test-has?-with-basic-cache
(testing "that has? returns false for misses"
(let [c (BasicCache. {})]
(are [v] (is (false? (has? c v)))
:missing-key
"missing-key"
(gensym "missing-key"))))
(testing "that has? returns true for hits"
(let [c (BasicCache. {:skey "Value" :lkey (Long/valueOf 10000) "kkey" :keyword})]
(are [v] (is (has? c v))
:skey
:lkey
"kkey"))))
(deftest ^{:cache true}
test-lookup-with-basic-cache
(testing "that lookup returns nil for misses"
(let [c (BasicCache. {})]
(are [v] (is (nil? (lookup c v)))
:missing-key
"missing-key"
(gensym "missing-key"))))
(testing "that lookup returns cached values for hits"
(let [l (Long/valueOf 10000)
c (BasicCache. {:skey "Value" :lkey l "kkey" :keyword})]
(are [v k] (is (= v (lookup c k)))
"Value" :skey
l :lkey
:keyword "kkey"))))
(deftest ^{:cache true}
test-evict-with-basic-cache
(testing "that evict has no effect for keys that do not exist"
(let [c (atom (BasicCache. {:a 1 :b 2}))]
(swap! c evict :missing-key)
(is (has? @c :a))
(is (has? @c :b))))
(testing "that evict removes keys that did exist"
(let [c (atom (BasicCache. {:skey "Value" "kkey" :keyword}))]
(is (has? @c :skey))
(is (= "Value" (lookup @c :skey)))
(swap! c evict :skey)
(is (not (has? @c :skey)))
(is (= nil (lookup @c :skey)))
(is (has? @c "kkey"))
(is (= :keyword (lookup @c "kkey"))))))
(deftest ^{:cache true}
test-seed-with-basic-cache
(testing "that seed returns a new value"
(let [c (atom (BasicCache. {}))]
(swap! c seed {:a 1 :b "b" "c" :d})
(are [k v] (do
(is (has? @c k))
(is (= v (lookup @c k))))
:a 1
:b "b"
"c" :d))))
;;
;; Tests
;;
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each (fn [f]
(mc/remove db "basic_monger_cache_entries")
(f)
(mc/remove db "basic_monger_cache_entries")))
(deftest ^{:cache true}
test-has?-with-basic-monger-cache
(testing "that has? returns false for misses"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory db coll)]
(is (not (has? c (str (UUID/randomUUID)))))
(is (not (has? c (str (UUID/randomUUID)))))))
(testing "that has? returns true for hits"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory db coll {"a" 1 "b" "cache" "c" 3/4})]
(is (has? c "a"))
(is (has? c "b"))
(is (has? c "c"))
(is (not (has? c "d"))))))
(deftest ^{:cache true}
test-lookup-with-basic-monger-cache
(testing "that lookup returns nil for misses"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory db coll)]
(are [v] (is (nil? (lookup c v)))
:missing-key
"missing-key"
(gensym "missing-key"))))
(testing "that lookup returns cached values for hits"
(let [l (Long/valueOf 10000)
coll "basic_monger_cache_entries"
c (basic-monger-cache-factory db coll {:skey "Value" :lkey l "kkey" :keyword})]
(are [v k] (is (= v (lookup c k)))
"Value" :skey
l :lkey
"keyword" "kkey")))))

View file

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

View file

@ -4,8 +4,7 @@
[monger.conversion :refer :all]) [monger.conversion :refer :all])
(:import [com.mongodb DBObject BasicDBObject BasicDBList] (:import [com.mongodb DBObject BasicDBObject BasicDBList]
[java.util Date Calendar List ArrayList] [java.util Date Calendar List ArrayList]
org.bson.types.ObjectId org.bson.types.ObjectId))
(org.bson.types Decimal128)))
;; ;;
@ -102,13 +101,6 @@
(is (= 2 (from-db-object 2 false))) (is (= 2 (from-db-object 2 false)))
(is (= 2 (from-db-object 2 true)))) (is (= 2 (from-db-object 2 true))))
(deftest convert-decimal-from-dbobject
(is (= 2.3M (from-db-object (Decimal128. 2.3M) false)))
(is (= 2.3M (from-db-object (Decimal128. 2.3M) true)))
(is (= 2.3M (from-db-object (Decimal128/parse "2.3") true)))
(is (not= 2.32M (from-db-object (Decimal128/parse "2.3") true)))
)
(deftest convert-float-from-dbobject (deftest convert-float-from-dbobject
(is (= 3.3 (from-db-object 3.3 false))) (is (= 3.3 (from-db-object 3.3 false)))
(is (= 3.3 (from-db-object 3.3 true)))) (is (= 3.3 (from-db-object 3.3 true))))
@ -120,20 +112,20 @@
(.put "name" name) (.put "name" name)
(.put "age" age)) (.put "age" age))
output (from-db-object input false)] output (from-db-object input false)]
(is (= output { "name" name, "age" age })) (is (= (output { "name" name, "age" age })))
(is (= (output "name") name)) (is (= (output "name") name))
(is (nil? (output :name))) (is (nil? (output :name)))
(is (= (output "age") age)) (is (= (output "age") age))
(is (nil? (output "points"))))) (is (nil? (output "points")))))
(deftest convert-flat-db-object-to-map-with-keywordizing (deftest convert-flat-db-object-to-map-without-keywordizing
(let [name "Michael" (let [name "Michael"
age 26 age 26
input (doto (BasicDBObject.) input (doto (BasicDBObject.)
(.put "name" name) (.put "name" name)
(.put "age" age)) (.put "age" age))
output (from-db-object input true)] output (from-db-object input true)]
(is (= output { :name name, :age age })) (is (= (output { :name name, :age age })))
(is (= (output :name) name)) (is (= (output :name) name))
(is (nil? (output "name"))) (is (nil? (output "name")))
(is (= (output :age) age)) (is (= (output :age) age))

View file

@ -55,35 +55,3 @@
dbs (mg/get-db-names conn)] dbs (mg/get-db-names conn)]
(is (not (empty? dbs))) (is (not (empty? dbs)))
(is (dbs "monger-test")))) (is (dbs "monger-test"))))
(deftest monger-options-test
(let [opts {:always-use-mbeans true
:application-name "app"
:connect-timeout 1
:connections-per-host 1
:cursor-finalizer-enabled true
: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
(let [uri "mongodb://localhost:27017"]
(is (thrown? IllegalArgumentException (mg/connect-via-uri uri)))))

View file

@ -78,21 +78,11 @@
(content-type "application/octet-stream")) (content-type "application/octet-stream"))
(is (= 1 (count (gridfs/all-files fs)))))) (is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-deleting-file-instance-on-disk-after-storing
(let [tmp-file (File/createTempFile "monger.test.gridfs" "test-deleting-file-instance-on-disk-after-storing")
_ (spit tmp-file "to be deleted")]
(is (= 0 (count (gridfs/all-files fs))))
(store-file (make-input-file fs tmp-file)
(filename "test-deleting-file-instance-on-disk-after-storing")
(content-type "application/octet-stream"))
(is (= 1 (count (gridfs/all-files fs))))
(is (.delete tmp-file))))
(deftest ^{:gridfs true} test-finding-individual-files-on-gridfs (deftest ^{:gridfs true} test-finding-individual-files-on-gridfs
(testing "gridfs/find-one" (testing "gridfs/find-one"
(purge-gridfs*) (purge-gridfs*)
(let [input "./test/resources/mongo/js/mapfun1.js" (let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream" ct "binary/octet-stream"
fname "monger.test.gridfs.file5" fname "monger.test.gridfs.file5"
@ -131,46 +121,7 @@
(is (= {:meta "data"} (:metadata m)))) (is (= {:meta "data"} (:metadata m))))
(are [a query] (is (= a (:md5 (gridfs/find-one-as-map fs query)))) (are [a query] (is (= a (:md5 (gridfs/find-one-as-map fs query))))
md5 {:_id (:_id stored)} md5 {:_id (:_id stored)}
md5 {:md5 md5}))) md5 {:md5 md5}))))
(testing "gridfs/find-by-id"
(purge-gridfs*)
(let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream"
fname "monger.test.gridfs.file5"
md5 "14a09deabb50925a3381315149017bbd"
stored (store-file (make-input-file fs input)
(filename fname)
(content-type ct))]
(is (= 1 (count (gridfs/all-files fs))))
(is (:_id stored))
(is (:uploadDate stored))
(is (= 62 (:length stored)))
(is (= md5 (:md5 stored)))
(is (= fname (:filename stored)))
(is (= ct (:contentType stored)))
(are [a id] (is (= a (:md5 (from-db-object (gridfs/find-by-id fs id) true))))
md5 (:_id stored))))
(testing "gridfs/find-map-by-id"
(purge-gridfs*)
(let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream"
fname "monger.test.gridfs.file6"
md5 "14a09deabb50925a3381315149017bbd"
stored (store-file (make-input-file fs input)
(filename fname)
(metadata (to-db-object {:meta "data"}))
(content-type ct))]
(is (= 1 (count (gridfs/all-files fs))))
(is (:_id stored))
(is (:uploadDate stored))
(is (= 62 (:length stored)))
(is (= md5 (:md5 stored)))
(is (= fname (:filename stored)))
(is (= ct (:contentType stored)))
(let [m (gridfs/find-map-by-id fs (:_id stored))]
(is (= {:meta "data"} (:metadata m))))
(are [a id] (is (= a (:md5 (gridfs/find-map-by-id fs id))))
md5 (:_id stored)))))
(deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs (deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs
(let [input "./test/resources/mongo/js/mapfun1.js" (let [input "./test/resources/mongo/js/mapfun1.js"

View file

@ -0,0 +1,62 @@
(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)))))

View file

@ -3,28 +3,10 @@
[monger.collection :as mc] [monger.collection :as mc]
[monger.js :as js] [monger.js :as js]
[clojure.test :refer :all] [clojure.test :refer :all]
[clojure.set :refer [difference]] [monger.operators :refer :all]))
[monger.operators :refer :all])
(:import [com.mongodb QueryOperators]))
;; (use-fixtures :each purge-people purge-docs purge-things purge-libraries) ;; (use-fixtures :each purge-people purge-docs purge-things purge-libraries)
(deftest every-query-operator-is-defined
(let [driver-query-operators (->> (.getDeclaredFields QueryOperators) (map #(.get % nil)) set)
monger-query-operators (->> (ns-publics 'monger.operators) (map (comp name first)) set)
; $within is deprecated and replaced by $geoWithin since v2.4.
; $uniqueDocs is deprecated since v2.6.
deprecated-query-operators #{"$within" "$uniqueDocs"}
; Query modifier operators that are deprecated in the mongo shell since v3.2
deprecated-meta-operators #{"$comment" "$explain" "$hint" "$maxScan"
"$maxTimeMS" "$max" "$min" "$orderby"
"$returnKey" "$showDiskLoc" "$snapshot" "$query"}
undefined-non-deprecated-operators (difference driver-query-operators
deprecated-query-operators
deprecated-meta-operators
monger-query-operators)]
(is (= #{} undefined-non-deprecated-operators))))
(let [conn (mg/connect) (let [conn (mg/connect)
db (mg/get-db conn "monger-test")] db (mg/get-db conn "monger-test")]
(defn purge-collections (defn purge-collections
@ -54,29 +36,17 @@
2 {:users {$lte 5}} 2 {:users {$lte 5}}
1 {:users {$gt 10 $lt 150}}))) 1 {:users {$gt 10 $lt 150}})))
;;
;; $eq
;;
(deftest find-with-eq-operator
(let [collection "libraries"]
(mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1 :displayName nil}
{:language "Clojure" :name "langohr" :users 5}
{:language "Clojure" :name "incanter" :users 15}
{:language "Scala" :name "akka" :users 150}])
(is (= 2 (.count (mc/find db collection {:language {$eq "Clojure"}}))))))
;; ;;
;; $ne ;; $ne
;; ;;
(deftest find-with-ne-operator (deftest find-with-and-or-operators
(let [collection "libraries"] (let [collection "libraries"]
(mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1} (mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1}
{:language "Clojure" :name "langohr" :users 5} {:language "Clojure" :name "langohr" :users 5}
{:language "Clojure" :name "incanter" :users 15} {:language "Clojure" :name "incanter" :users 15}
{:language "Scala" :name "akka" :users 150}]) {:language "Scala" :name "akka" :users 150}])
(is (= 2 (.count (mc/find db collection {:language {$ne "Clojure"}})))))) (is (= 2 (.count (mc/find db collection {$ne {:language "Clojure"}}))))))
;; ;;
@ -137,10 +107,4 @@
{:language {$regex "clo.*" $options "i"}} 2 {:language {$regex "clo.*" $options "i"}} 2
{:name {$regex "aK.*" $options "i"}} 1 {:name {$regex "aK.*" $options "i"}} 1
{:language {$regex ".*by"}} 1 {:language {$regex ".*by"}} 1
{:language {$regex ".*ala.*"}} 1))) {:language {$regex ".*ala.*"}} 1))))
(deftest find-with-js-expression
(let [collection "people"]
(mc/insert-batch db collection [{:name "Bob" :placeOfBirth "New York" :address {:city "New York"}}
{:name "Alice" :placeOfBirth "New York" :address {:city "Los Angeles"}}])
(is (= 1 (.count (mc/find db collection {$where "this.placeOfBirth === this.address.city"})))))))

View file

@ -2,7 +2,7 @@
(:require [monger.core :as mg] (:require [monger.core :as mg]
[monger.collection :as mc] [monger.collection :as mc]
monger.ragtime monger.ragtime
[ragtime.protocols :refer :all] [ragtime.core :refer :all]
[clojure.test :refer :all])) [clojure.test :refer :all]))

View file

@ -8,8 +8,7 @@
[monger.result :as mgres] [monger.result :as mgres]
[monger.conversion :as mgcnv] [monger.conversion :as mgcnv]
[clojure.test :refer :all] [clojure.test :refer :all]
[monger.operators :refer :all] [monger.operators :refer :all]))
[monger.conversion :refer [to-db-object]]))
(let [conn (mg/connect) (let [conn (mg/connect)
db (mg/get-db conn "monger-test")] db (mg/get-db conn "monger-test")]
@ -148,36 +147,36 @@
doc-id (mu/random-uuid) doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object doc) (mc/find-by-id db collection doc-id))))) (is (= (doc (mc/find-by-id db collection doc-id))))))
(deftest find-full-document-by-object-id-when-document-does-exist (deftest find-full-document-by-object-id-when-document-does-exist
(let [collection "libraries" (let [collection "libraries"
doc-id (ObjectId.) doc-id (ObjectId.)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object doc) (mc/find-by-id db collection doc-id))))) (is (= (doc (mc/find-by-id db collection doc-id))))))
(deftest find-full-document-map-by-string-id-when-document-does-exist (deftest find-full-document-map-by-string-id-when-document-does-exist
(let [collection "libraries" (let [collection "libraries"
doc-id (mu/random-uuid) doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= doc (mc/find-map-by-id db collection doc-id))))) (is (= (doc (mc/find-map-by-id db collection doc-id))))))
(deftest find-full-document-map-by-object-id-when-document-does-exist (deftest find-full-document-map-by-object-id-when-document-does-exist
(let [collection "libraries" (let [collection "libraries"
doc-id (ObjectId.) doc-id (ObjectId.)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= doc (mc/find-map-by-id db collection doc-id))))) (is (= (doc (mc/find-map-by-id db collection doc-id))))))
(deftest find-partial-document-by-id-when-document-does-exist (deftest find-partial-document-by-id-when-document-does-exist
(let [collection "libraries" (let [collection "libraries"
doc-id (mu/random-uuid) doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object { :_id doc-id :language "Clojure" }) (is (= ({ :language "Clojure" }
(mc/find-by-id db collection doc-id [ :language ]))))) (mc/find-by-id db collection doc-id [ :language ]))))))
(deftest find-partial-document-as-map-by-id-when-document-does-exist (deftest find-partial-document-as-map-by-id-when-document-does-exist
@ -282,12 +281,4 @@
(doseq [i clojure-libs] (doseq [i clojure-libs]
(let [doc (mgcnv/from-db-object i true)] (let [doc (mgcnv/from-db-object i true)]
(is (= (:language doc) "Clojure")))) (is (= (:language doc) "Clojure"))))
(is (empty? (mc/find db collection { :language "Erlang" } [:name])))))) (is (empty? (mc/find db collection { :language "Erlang" } [:name])))))))
(deftest find-maps-with-keywordize-false
(let [collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }])
(let [results (mc/find-maps db collection {:name "langohr"} [] false)]
(is (= 1 (.count results)))
(is (= (get (first results) "language") "Clojure"))))))

View file

@ -15,11 +15,8 @@
date (Date.) date (Date.)
doc { :created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id } doc { :created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id }
modified-doc { :created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id }] modified-doc { :created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id }]
(let [result (mc/update db collection { :language "Clojure" } doc {:upsert true})] (is (not (mgres/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true}))))
(is (not (mgres/updated-existing? result))) (is (mgres/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true})))
(is (= 1 (mgres/affected-count result)))) (mgres/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true}))
(is (mgres/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true})))
(is (mgres/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true})))
(is (= 1 (mgres/affected-count (mc/remove db collection { :_id doc-id }))))
(mc/remove db collection) (mc/remove db collection)
(mg/disconnect conn)))) (mg/disconnect conn))))

View file

@ -1,7 +1,7 @@
(ns monger.test.stress-test (ns monger.test.stress-test
(:require [monger.core :as mg] (:require [monger.core :as mg]
[monger.collection :as mc] [monger.collection :as mc]
[monger.conversion :refer [to-db-object from-db-object]] [monger.conversion :refer [to-db-object]]
[clojure.test :refer :all]) [clojure.test :refer :all])
(:import [com.mongodb WriteConcern] (:import [com.mongodb WriteConcern]
java.util.Date)) java.util.Date))
@ -30,11 +30,4 @@
(mc/remove db collection) (mc/remove db collection)
(println "Inserting " n " documents...") (println "Inserting " n " documents...")
(time (mc/insert-batch db collection docs)) (time (mc/insert-batch db collection docs))
(is (= n (mc/count db collection)))))) (is (= n (mc/count db collection)))))))
(deftest ^{:performance true} convert-large-number-of-dbojects-to-maps
(doseq [n [10 100 1000 20000 40000]]
(let [docs (map (fn [i]
(to-db-object {:title "Untitled" :created-at (Date.) :number i}))
(take n (iterate inc 1)))]
(time (doall (map (fn [x] (from-db-object x true)) docs)))))))

View file

@ -33,9 +33,9 @@
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object doc) (mc/find-by-id db collection doc-id))) (is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update db collection { :_id doc-id } { $set { :language "Erlang" } }) (mc/update db collection { :_id doc-id } { :language "Erlang" })
(is (= (to-db-object modified-doc) (mc/find-by-id db collection doc-id))))) (is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id (deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id
(let [collection "libraries" (let [collection "libraries"
@ -44,9 +44,9 @@
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object doc) (mc/find-by-id db collection doc-id))) (is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { $set { :language "Erlang" } }) (mc/update-by-id db collection doc-id { :language "Erlang" })
(is (= (to-db-object modified-doc) (mc/find-by-id db collection doc-id))))) (is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id (deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id
(let [collection "libraries" (let [collection "libraries"
@ -55,9 +55,9 @@
doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id } doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id }
modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }] modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }]
(mc/insert db collection doc) (mc/insert db collection doc)
(is (= (to-db-object doc) (mc/find-by-id db collection doc-id))) (is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }}) (mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }})
(is (= (to-db-object modified-doc) (mc/find-by-id db collection doc-id))))) (is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-multiple-documents (deftest ^{:updating true} update-multiple-documents
@ -151,7 +151,7 @@
(is (= 1 (mc/count db collection))) (is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true}))) (is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true})))
(is (= 1 (mc/count db collection))) (is (= 1 (mc/count db collection)))
(is (= (to-db-object modified-doc) (mc/find-by-id db collection doc-id))) (is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection))) (mc/remove db collection)))
(deftest ^{:updating true} upsert-a-document-using-upsert (deftest ^{:updating true} upsert-a-document-using-upsert
@ -165,5 +165,5 @@
(is (= 1 (mc/count db collection))) (is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc {:multi false}))) (is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc {:multi false})))
(is (= 1 (mc/count db collection))) (is (= 1 (mc/count db collection)))
(is (= (to-db-object modified-doc) (mc/find-by-id db collection doc-id))) (is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection)))) (mc/remove db collection))))