Expand description
§MongoDrop
A Rust library that provides an experimental AsyncDrop implementation for MongoDB change streams.
This library allows you to collect changes made to a MongoDB database and automatically
undo them when the MongoDrop instance is dropped. It uses the async_drop feature
to ensure that the undo operations are performed asynchronously.
§Features
tracing: Enables tracing for logging events.
§Usage
#[cfg(test)]
mod tests {
use mongodb::{Client, options::ClientOptions};
use mongo_drop::MongoDrop;
#[tokio::test]
async fn trivial_mongo_drop_insert() {
// Initialize MongoDB
let client = Client::with_uri_str("mongodb://localhost:27017").await.unwrap();
let database = client.database("mongo_drop_db");
let coll = database.collection("insert_collection");
{
// Create a MongoDrop guard
let _guard = MongoDrop::new(&database).await.unwrap();
// Perform database operations within the guard
coll.insert_one(doc! { "key": "value" }).await.unwrap();
let record = coll.find_one(doc! {}).await.unwrap();
assert_eq!(record, Some(doc! { "key": "value" }));
// The changes will be rolled back automatically when the guard goes out of scope
}
// After the guard is dropped, verify that the changes were rolled back
let record = coll.find_one(doc! {}).await.unwrap();
assert_eq!(record, None);
}
#[tokio::test]
async fn deletes() -> Result<(), Box<dyn std::error::Error>> {
let mongodb_client = get_client().await?;
let database_name = "mongo_drop_db";
let db = mongodb_client.database(database_name);
let collection = create_collection(&db, "delete").await?;
// Insert a document to delete
let d = collection.insert_one(doc! { "value": "to_delete"}).await?;
{
let _guard = MongoDrop::new(&db).await?;
// Delete the document
collection.delete_one(doc! {"_id": &d.inserted_id}).await?;
// Verify deletion
let deleted_doc = collection.find_one(doc! {"_id": &d.inserted_id}).await?;
assert!(deleted_doc.is_none());
}
// After drop, verify document is restored
let deleted_doc = collection.find_one(doc! {"_id": &d.inserted_id}).await?;
assert!(deleted_doc.is_some());
Ok(())
}
async fn get_client() -> Result<Client, mongodb::error::Error> {
Client::with_uri_str("mongodb://127.0.0.1:27017/mongo_drop_db?directConnection=true").await
}
async fn create_collection(
db: &Database,
name: &str,
) -> Result<mongodb::Collection<Document>, mongodb::error::Error> {
// Delete existing collection if it exists
let _ = db.collection::<Document>(name).drop().await;
// Delete, Update, and Replace operations require collections to be created with pre-images enabled
let options = mongodb::options::CreateCollectionOptions::builder()
.change_stream_pre_and_post_images(
ChangeStreamPreAndPostImages::builder()
.enabled(true)
.build(),
)
.build();
let _ = db.create_collection(name).with_options(options).await?;
let collection = db.collection::<Document>(name);
Ok(collection)
}
}Structs§
- Mongo
Drop - A data type that collects database changes and automatically undoes them
asynchronously when dropped within an async context using AsyncDrop.
Requires nightly Rust and the
async_dropfeature.