8000 (DOCSP-29208): CRUD > Compound Operations page (#45) · nickldp/docs-kotlin@62284b2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 62284b2

Browse files
authored
(DOCSP-29208): CRUD > Compound Operations page (mongodb#45)
# Pull Request Info [PR Reviewing Guidelines](https://github.com/mongodb/docs-java/blob/master/REVIEWING.md) JIRA - https://jira.mongodb.org/browse/DOCSP-29208 Staging - https://docs-mongodbcom-staging.corp.mongodb.com/kotlin/docsworker-xlarge/docsp-29208-compound/fundamentals/crud/compound-operations/ ## Updated Page CRUD Operations > [Compound Operations page](https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/crud/compound-operations/) ## Self-Review Checklist - [ ] Is this free of any warnings or errors in the RST? - [ ] Did you run a spell-check? - [ ] Did you run a grammar-check? - [ ] Are all the links working?
1 parent f5e3d9e commit 62284b2

9 files changed

+303
-68
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
2+
import com.mongodb.client.model.*
3+
import com.mongodb.client.model.Sorts.*
4+
import com.mongodb.kotlin.client.coroutine.MongoClient
5+
import io.github.cdimascio.dotenv.dotenv
6+
import kotlinx.coroutines.flow.first
7+
import kotlinx.coroutines.flow.firstOrNull
8+
import kotlinx.coroutines.runBlocking
9+
import org.bson.codecs.pojo.annotations.BsonId
10+
import org.junit.jupiter.api.*
11+
import org.junit.jupiter.api.Assertions.*
12+
import org.junit.jupiter.api.Test
13+
import java.util.*
14+
import java.util.concurrent.TimeUnit
15+
import kotlin.test.*
16+
17+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
18+
internal class CompoundOperationsTest {
19+
// :snippet-start: compound-data-model
20+
data class FoodOrder(
21+
@BsonId val id: Int,
22+
val food: String,
23+
val color: String
24+
)
25+
// :snippet-end:
26+
27+
// :snippet-start: room-data-class
28+
data class HotelRoom(
29+
@BsonId val id: Int,
30+
val guest: String? = null,
31+
val room: String,
32+
val reserved: Boolean = false
33+
)
34+
// :snippet-end:
35+
companion object {
36+
val dotenv = dotenv()
37+
val client = MongoClient.create(dotenv["MONGODB_CONNECTION_URI"])
38+
val database = client.getDatabase("compound_operations")
39+
val collection = database.getCollection<FoodOrder>("example")
40+
val hotelCollection = database.getCollection<HotelRoom>("rooms")
41+
42+
@AfterAll
43+
@JvmStatic
44+
fun afterAll() {
45+
runBlocking {
46+
database.drop()
47+
client.close()
48+
}
49+
}
50+
}
51+
52+
@BeforeEach
53+
fun beforeEach() {
54+
runBlocking {
55+
val room = HotelRoom(1, null, "Blue Room")
56+
hotelCollection.insertOne(room)
57+
}
58+
}
59+
60+
@AfterEach
61+
fun afterEach() {
62+
runBlocking {
63+
collection.drop()
64+
hotelCollection.drop()
65+
}
66+
}
67+
68+
@Test
69+
fun findOneUpdateTest() = runBlocking {
70+
val foodOrders = FoodOrder(1, "donut", "green")
71+
collection.insertOne(foodOrders)
72+
// :snippet-start: find-one-update
73+
74+
val filter = Filters.eq(FoodOrder::color.name, "green")
75+
val update = Updates.set(FoodOrder::food.name, "pizza")
76+
val options = FindOneAndUpdateOptions()
77+
.upsert(true)
78+
.maxTime(5, TimeUnit.SECONDS)
79+
/* The result variable contains your document in the
80+
state before your update operation is performed
81+
or null if the document was inserted due to upsert
82+
being true */
83+
val result = collection.findOneAndUpdate(filter, update, options)
84+
println(result)
85+
// :snippet-end:
86+
// Junit test for the above code
87+
val expected = FoodOrder(1, "donut", "green")
88+
assertEquals(expected, result)
89+
}
90+
91+
@Test
92+
fun findOneReplaceTest() = runBlocking {
93+
val foodOrders = FoodOrder(1, "pizza", "green")
94+
collection.insertOne(foodOrders)
95+
// :snippet-start: find-one-replace
96+
data class Music(
97+
@BsonId val id: Int,
98+
val music: String,
99+
val color: String
100+
)
101+
102+
val filter = Filters.eq(FoodOrder::color.name, "green")
103+
val replace = Music(1, "classical", "green")
104+
val options = FindOneAndReplaceOptions()
105+
.returnDocument(ReturnDocument.AFTER)
106+
val result = collection.withDocumentClass<Music>().findOneAndReplace(filter, replace, options)
107+
println(result)
108+
// :snippet-end:
109+
assertEquals(replace, result)
110+
}
111+
112+
@Test
113+
fun findOneDeleteTest() = runBlocking {
114+
val foodOrders = listOf(
115+
FoodOrder(1, "pizza", "green"),
116+
FoodOrder(2, "pear", "yellow")
117+
)
118+
collection.insertMany(foodOrders)
119+
// :snippet-start: find-one-delete
120+
val sort = Sorts.descending("_id")
121+
val filter = Filters.empty()
122+
val options = FindOneAndDeleteOptions().sort(sort)
123+
val result = collection.findOneAndDelete(filter, options)
124+
// Returns the deleted document
125+
println(result)
126+
// :snippet-end:
127+
// Junit test for the above code
128+
val expectedDeleted = FoodOrder(2, "pear", "yellow")
129+
assertEquals(expectedDeleted, result)
130+
}
131+
@Test
132+
fun bookARoom() = runBlocking {
133+
// :snippet-start: unsafe
134+
suspend fun bookARoomUnsafe(guestName: String) {
135+
val filter = Filters.eq("reserved", false)
136+
val myRoom = hotelCollection.find(filter).firstOrNull()
137+
if (myRoom == null) {
138+
println("Sorry, we are booked, $guestName")
139+
return
140+
}
141+
142+
val myRoomName = myRoom.room
143+
println("You got the $myRoomName, $guestName")
144+
145+
val update = Updates.combine(Updates.set("reserved", true), Updates.set("guest", guestName))
146+
val roomFilter = Filters.eq("_id", myRoom.id)
147+
hotelCollection.updateOne(roomFilter, update)
148+
}
149+
// :snippet-end:
150+
bookARoomUnsafe("joe")
151+
val roomAfterUnsafe = hotelCollection.find()
152+
assertEquals("joe", roomAfterUnsafe.first().guest)
153+
assertTrue(roomAfterUnsafe.first().reserved)
154+
155+
// :snippet-start: safe
156+
suspend fun bookARoomSafe(guestName: String) {
157+
val update = Updates.combine(
158+
Updates.set(HotelRoom::reserved.name, true),
159+
Updates.set(HotelRoom::guest.name, guestName)
160+
)
161+
val filter = Filters.eq("reserved", false)
162+
val myRoom = hotelCollection.findOneAndUpdate(filter, update)
163+
if (myRoom == null) {
164+
println("Sorry, we are booked, $guestName")
165+
return
166+
}
167+
val myRoomName = myRoom.room
168+
println("You got the $myRoomName, $guestName")
169+
}
170+
// :snippet-end:
171+
bookARoomSafe("joe")
172+
val roomAfterSafe = hotelCollection.find()
173+
assertEquals("joe", roomAfterSafe.first().guest)
174+
assertTrue(roomAfterSafe.first().reserved)
175+
}
176+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data class FoodOrder(
2+
@BsonId val id: Int,
3+
val food: String,
4+
val color: String
5+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
val sort = Sorts.descending("_id")
2+
val filter = Filters.empty()
3+
val options = FindOneAndDeleteOptions().sort(sort)
4+
val result = collection.findOneAndDelete(filter, options)
5+
// Returns the deleted document
6+
println(result)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
data class Music(
2+
@BsonId val id: Int,
3+
val music: String,
4+
val color: String
5+
)
6+
7+
val filter = Filters.eq(FoodOrder::color.name, "green")
8+
val replace = Music(1, "classical", "green")
9+
val options = FindOneAndReplaceOptions()
10+
.returnDocument(ReturnDocument.AFTER)
11+
val result = collection.withDocumentClass<Music>().findOneAndReplace(filter, replace, options)
12+
println(result)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
val filter = Filters.eq(FoodOrder::color.name, "green")
3+
val update = Updates.set(FoodOrder::food.name, "pizza")
4+
val options = FindOneAndUpdateOptions()
5+
.upsert(true)
6+
.maxTime(5, TimeUnit.SECONDS)
7+
/* The result variable contains your document in the
8+
state before your update operation is performed
9+
or null if the document was inserted due to upsert
10+
being true */
11+
val result = collection.findOneAndUpdate(filter, update, options)
12+
println(result)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
data class HotelRoom(
2+
@BsonId val id: Int,
3+
val guest: String? = null,
4+
val room: String,
5+
val reserved: Boolean = false
6+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
suspend fun bookARoomSafe(guestName: String) {
2+
val update = Updates.combine(
3+
Updates.set(HotelRoom::reserved.name, true),
4+
Updates.set(HotelRoom::guest.name, guestName)
5+
)
6+
val filter = Filters.eq("reserved", false)
7+
val myRoom = hotelCollection.findOneAndUpdate(filter, update)
8+
if (myRoom == null) {
9+
println("Sorry, we are booked, $guestName")
10+
return
11+
}
12+
val myRoomName = myRoom.room
13+
println("You got the $myRoomName, $guestName")
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
suspend fun bookARoomUnsafe(guestName: String) {
2+
val filter = Filters.eq("reserved", false)
3+
val myRoom = hotelCollection.find(filter).firstOrNull()
4+
if (myRoom == null) {
5+
println("Sorry, we are booked, $guestName")
6+
return
7+
}
8+
9+
val myRoomName = myRoom.room
10+
println("You got the $myRoomName, $guestName")
11+
12+
val update = Updates.combine(Updates.set("reserved", true), Updates.set("guest", guestName))
13+
val roomFilter = Filters.eq("_id", myRoom.id)
14+
hotelCollection.updateOne(roomFilter, update)
15+
}

0 commit comments

Comments
 (0)
0