/
MongoDirectSpec.scala
292 lines (221 loc) · 8.1 KB
/
MongoDirectSpec.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
* Copyright 2010-2015 WorldWide Conferencing, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.liftweb
package mongodb
import net.liftweb.util.{Helpers, DefaultConnectionIdentifier}
import java.util.UUID
import java.util.regex.Pattern
import com.mongodb.{WriteConcern, BasicDBObject, BasicDBObjectBuilder, MongoException}
import org.specs2.mutable.Specification
import json.DefaultFormats
import net.liftweb.common.Failure
/**
* System under specification for MongoDirect.
*/
class MongoDirectSpec extends Specification with MongoTestKit {
"MongoDirect Specification".title
def date(s: String) = DefaultFormats.dateFormat.parse(s).get
"Mongo tutorial example" in {
checkMongoIsRunning
// build the DBObject
val doc = new BasicDBObject
doc.put("name", "MongoDB")
doc.put("type", "database")
doc.put("count", 1)
val info = new BasicDBObject
info.put("x", 203)
info.put("y", 102)
doc.put("info", info)
// use the Mongo instance directly
MongoDB.use(DefaultConnectionIdentifier) ( db => {
val coll = db.getCollection("testCollection")
// save the doc to the db
coll.save(doc)
// get the doc back from the db and compare them
coll.findOne must_== doc
// upsert
doc.put("type", "document")
doc.put("count", 2)
val q = new BasicDBObject("name", "MongoDB") // the query to select the document(s) to update
val o = doc // the new object to update with, replaces the entire document, except possibly _id
val upsert = false // if the database should create the element if it does not exist
val apply = false // if an _id field should be added to the new object
coll.update(q, o, upsert, apply)
// get the doc back from the db and compare
coll.findOne.get("type") must_== "document"
coll.findOne.get("count") must_== 2
// modifier operations $inc, $set, $push...
val o2 = new BasicDBObject
o2.put("$inc", new BasicDBObject("count", 1)) // increment count by 1
o2.put("$set", new BasicDBObject("type", "docdb")) // set type
coll.update(q, o2, false, false)
// get the doc back from the db and compare
coll.findOne.get("type") must_== "docdb"
coll.findOne.get("count") must_== 3
if (!debug) {
// delete it
coll.remove(new BasicDBObject("_id", doc.get("_id")))
coll.find.count must_== 0
coll.drop
}
// server-side eval
val six = db.eval(" function() { return 3+3; } ")
six must_== 6
})
}
"Mongo tutorial 2 example" in {
checkMongoIsRunning
// use a DBCollection directly
MongoDB.useCollection("iDoc") ( coll => {
// insert multiple documents
for (i <- List.range(1, 101)) {
coll.insert(new BasicDBObject().append("i", i))
}
// create an index
coll.createIndex(new BasicDBObject("i", 1)) // create index on "i", ascending
// count the docs
coll.getCount must_== 100
// get the count using a query
coll.getCount(new BasicDBObject("i", new BasicDBObject("$gt", 50))) must_== 50
// use a cursor to get all docs
val cur = coll.find
cur.count must_== 100
// get a single document with a query ( i = 71 )
val query = new BasicDBObject
query.put("i", 71)
val cur2 = coll.find(query)
cur2.count must_== 1
cur2.next.get("i") must_== 71
// get a set of documents with a query
// e.g. find all where i > 50
val cur3 = coll.find(new BasicDBObject("i", new BasicDBObject("$gt", 50)))
cur3.count must_== 50
// range - 20 < i <= 30
val cur4 = coll.find(new BasicDBObject("i", new BasicDBObject("$gt", 20).append("$lte", 30)))
cur4.count must_== 10
// limiting result set
val cur5 = coll.find(new BasicDBObject("i", new BasicDBObject("$gt", 50))).limit(3)
var cntr5 = 0
while(cur5.hasNext) {
cur5.next
cntr5 += 1
}
cntr5 must_== 3
// skip
val cur6 = coll.find(new BasicDBObject("i", new BasicDBObject("$gt", 50))).skip(10)
var cntr6 = 0
while(cur6.hasNext) {
cntr6 += 1
cur6.next.get("i") must_== 60+cntr6
}
cntr6 must_== 40
/* skip and limit */
val cur7 = coll.find.skip(10).limit(20)
var cntr7 = 0
while(cur7.hasNext) {
cntr7 += 1
cur7.next.get("i") must_== 10+cntr7
}
cntr7 must_== 20
// sorting
val cur8 = coll.find.sort(new BasicDBObject("i", -1)) // descending
var cntr8 = 100
while(cur8.hasNext) {
cur8.next.get("i") must_== cntr8
cntr8 -= 1
}
// remove some docs by a query
coll.remove(new BasicDBObject("i", new BasicDBObject("$gt", 50)))
coll.find.count must_== 50
if (!debug) {
// delete the rest of the rows
coll.remove(new BasicDBObject("i", new BasicDBObject("$lte", 50)))
coll.find.count must_== 0
coll.drop
}
})
success
}
"Mongo more examples" in {
checkMongoIsRunning
// use a Mongo instance directly
MongoDB.use ( db => {
val coll = db.getCollection("testCollection")
// create a unique index on name
coll.createIndex(new BasicDBObject("name", 1), new BasicDBObject("unique", true))
// build the DBObjects
val doc = new BasicDBObject
val doc2 = new BasicDBObject
val doc3 = new BasicDBObject
doc.put("name", "MongoSession")
doc.put("type", "db")
doc.put("count", 1)
doc2.put("name", "MongoSession")
doc2.put("type", "db")
doc2.put("count", 1)
doc3.put("name", "MongoDB")
doc3.put("type", "db")
doc3.put("count", 1)
// save the docs to the db
Helpers.tryo(coll.save(doc, WriteConcern.SAFE)).toOption must beSome
coll.save(doc2, WriteConcern.SAFE) must throwA[MongoException]
Helpers.tryo(coll.save(doc2, WriteConcern.SAFE)) must beLike {
case Failure(msg, _, _) =>
msg must contain("E11000 duplicate key error")
}
Helpers.tryo(coll.save(doc3, WriteConcern.SAFE)).toOption must beSome
// query for the docs by type
val qry = new BasicDBObject("type", "db")
coll.find(qry).count must_== 2
// modifier operations $inc, $set, $push...
val o2 = new BasicDBObject
o2.put("$inc", new BasicDBObject("count", 1)) // increment count by 1
coll.update(qry, o2, false, false).getN must_== 1
coll.update(qry, o2, false, false).isUpdateOfExisting must_== true
// this update query won't find any docs to update
coll.update(new BasicDBObject("name", "None"), o2, false, false).getN must_== 0
// regex query example
val key = "name"
val regex = "^Mongo"
val cur = coll.find(
BasicDBObjectBuilder.start.add(key, Pattern.compile(regex)).get)
cur.count must_== 2
// use regex and another dbobject
val cur2 = coll.find(
BasicDBObjectBuilder.start.add(key, Pattern.compile(regex)).add("count", 1).get)
cur2.count must_== 1
if (!debug) {
// delete them
coll.remove(new BasicDBObject("type", "db")).getN must_== 2
coll.find.count must_== 0
coll.drop
}
})
success
}
"UUID Example" in {
checkMongoIsRunning
MongoDB.useCollection("examples.uuid") { coll =>
val uuid = UUID.randomUUID
val dbo = new BasicDBObject("_id", uuid).append("name", "dbo")
coll.save(dbo)
val qry = new BasicDBObject("_id", uuid)
val dbo2 = coll.findOne(qry)
dbo2.get("_id") must_== dbo.get("_id")
dbo2.get("name") must_== dbo.get("name")
}
}
}