// Copyright 2024 Vincent Chan // // 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. use polodb_core::options::UpdateOptions; use polodb_core::{CollectionT, Database, Result}; use polodb_core::bson::{Document, doc}; mod common; use common::prepare_db; #[test] fn test_update_one() { vec![ prepare_db("test-update-one").unwrap(), ].iter().for_each(|db| { let collection = db.collection::("test"); let result = collection.insert_many(vec![ doc! { "name": "Vincent", "age": 17, }, doc! { "name": "Vincent", "age": 18, }, ]).unwrap(); assert_eq!(result.inserted_ids.len(), 2); let result = collection.update_one(doc! { "name": "Vincent", }, doc! { "$set": { "name": "Steve", } }).unwrap(); assert_eq!(result.modified_count, 1); }); } fn prepare_db_with_data(db_name: &str) -> Database { let db = prepare_db(db_name).unwrap(); let mut arr = vec![]; for i in 0..1000 { arr.push(doc! { "_id": i, "num": i, "content": i.to_string(), }); } let col = db.collection::("test"); col.insert_many(arr).unwrap(); db } #[test] fn test_update_gte_set() { let db = prepare_db_with_data("test-update-many"); let col = db.collection::("test"); let update_result = col.update_many(doc! { "_id": { "$gte": 500, }, }, doc! { "$set": { "content": "updated!", }, }).unwrap(); assert_eq!(update_result.modified_count, 500); let cursor = col .find(doc! { "content": "updated!", }) .run() .unwrap(); let result: Vec> = cursor.collect(); assert_eq!(result.len(), 500); assert_eq!(result[0].as_ref().unwrap().get("_id").unwrap().as_i32().unwrap(), 500); } #[test] fn test_throw_error_while_updating_primary_key() { let db = prepare_db_with_data("test-update-pkey"); let col = db.collection::("test"); let result = col.update_many(doc! { "_id": 0, }, doc! { "$inc": { "_id": 100, }, }); assert!(result.is_err()); } #[test] fn test_update_inc() { let db = prepare_db_with_data("test-update-inc"); let col = db.collection::("test"); col.update_many(doc! { "_id": 0, }, doc! { "$inc": { "num": 100, }, }).unwrap(); let mut cursor = col .find(doc! { "_id": 0, }) .run() .unwrap(); assert!(cursor.advance().unwrap()); let result = cursor.deserialize_current().unwrap(); assert_eq!(result.get("num").unwrap().as_i32().unwrap(), 100); } #[test] fn test_update_rename() { let db = prepare_db_with_data("test-update-rename"); let col = db.collection::("test"); col.update_many(doc! { "_id": 0, }, doc! { "$rename": { "num": "num2", }, }).unwrap(); let result = col.find_one(doc! { "_id": 0, }).unwrap().unwrap(); println!("result: {}", result); assert_eq!(result.get("_id").unwrap().as_i32().unwrap(), 0); assert!(result.get("num").is_none()); assert_eq!(result.get("num2").unwrap().as_i32().unwrap(), 0); } #[test] fn test_update_unset() { let db = prepare_db_with_data("test-update-unset"); let col = db.collection::("test"); col.update_many(doc! { "_id": 0, }, doc! { "$unset": { "num": "", }, }).unwrap(); let result = col.find_one(doc! { "_id": 0, }).unwrap().unwrap(); assert!(result.get("num").is_none()); } #[test] fn test_update_max() { let db = prepare_db_with_data("test-update-max"); let col = db.collection::("test"); col.update_many(doc! { "_id": 1, }, doc! { "$max": { "num": 0, }, }).unwrap(); let result = col.find_one(doc! { "_id": 1, }).unwrap().unwrap(); assert_eq!(result.get("num").unwrap().as_i32().unwrap(), 1); col.update_many(doc! { "_id": 1, }, doc! { "$max": { "num": 2, }, }).unwrap(); let mut cursor = col.find(doc! { "_id": 1, }).run().unwrap(); assert!(cursor.advance().unwrap()); let result = cursor.deserialize_current().unwrap(); assert_eq!(result.get("num").unwrap().as_i32().unwrap(), 2); } #[test] fn test_update_min() { let db = prepare_db_with_data("test-update-min"); let col = db.collection::("test"); let update_result = col.update_many(doc! { "_id": 1, }, doc! { "$min": { "num": 2, }, }).unwrap(); let result = col.find_one(doc! { "_id": 1, }).unwrap().unwrap(); assert_eq!(update_result.modified_count, 0); assert_eq!(update_result.matched_count, 1); assert_eq!(result.get("num").unwrap().as_i32().unwrap(), 1); let update_result = col.update_many(doc! { "_id": 1, }, doc! { "$min": { "num": 0, }, }).unwrap(); let mut cursor = col.find(doc! { "_id": 1, }).run().unwrap(); assert!(cursor.advance().unwrap()); let result = cursor.deserialize_current().unwrap(); assert_eq!(update_result.modified_count, 1); assert_eq!(update_result.matched_count, 1); assert_eq!(result.get("num").unwrap().as_i32().unwrap(), 0); } #[test] fn test_update_push() { let db = prepare_db("test-update-push").unwrap(); let col = db.collection::("test"); let insert_doc = doc! { "_id": 0, "content": [1, 2, 3], }; col.insert_one(insert_doc).unwrap(); let update_result = col.update_many(doc! { "_id": 0, }, doc! { "$push": { "content": 4, }, }).unwrap(); assert_eq!(update_result.modified_count, 1); let result = col.find_one(doc! { "_id": 0, }).unwrap().unwrap(); let content = result.get_array("content").unwrap(); assert_eq!(content.len(), 4); } #[test] fn test_upsert() { let db = prepare_db("test-upsert").unwrap(); let col = db.collection::("test"); // Attempt to update a non-existent document with upsert let update_result = col.update_one_with_options( doc! { "_id": 1 }, doc! { "$set": { "name": "John", "age": 30 } }, UpdateOptions::builder().upsert(true).build(), ).unwrap(); // Check that the document was inserted assert_eq!(update_result.matched_count, 0); assert_eq!(update_result.modified_count, 0); // assert!(update_result.upserted_id.is_some()); // Verify the inserted document let result = col.find_one(doc! { "name": "John" }).unwrap().unwrap(); assert_eq!(result.get_str("name").unwrap(), "John"); assert_eq!(result.get_i32("age").unwrap(), 30); // Update the existing document with upsert let update_result = col.update_one_with_options( doc! { "name": "John" }, doc! { "$set": { "age": 31 }, "$push": { "hobbies": "reading" } }, UpdateOptions::builder().upsert(true).build(), ).unwrap(); // Check that the document was updated assert_eq!(update_result.matched_count, 1); assert_eq!(update_result.modified_count, 1); // assert!(update_result.upserted_id.is_none()); // // Verify the updated document let result = col.find_one(doc! { "name": "John" }).unwrap().unwrap(); assert_eq!(result.get_str("name").unwrap(), "John"); assert_eq!(result.get_i32("age").unwrap(), 31); // let hobbies = result.get_array("hobbies").unwrap(); // assert_eq!(hobbies.len(), 1); // assert_eq!(hobbies[0].as_str().unwrap(), "reading"); }