A MongoDB ODM for Rust based on Mongoose

Overview

Nongoose

MongoDB ODM for Rust based on Mongoose

Basic usage

client, Err(e) => { panic!("Error connecting to the database: {}", e); } }; // Nongoose instance. let nongoose = nongoose::Nongoose::build(client.database("nextchat")) .add_schema:: () .finish(); let user = User { id: ObjectId::new(), username: String::from("nongoose"), }; if let Err(error) = nongoose.create(&user).await { panic!("Cannot create the user: {}", error); } println!("User created in the database: {}", user.id); } ">
use mongodb::{bson::oid::ObjectId, sync::Client};
use nongoose::Schema;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Schema, Serialize)]
struct User {
  #[schema(id)]
  #[serde(rename = "_id")]
  pub id: ObjectId,

  #[schema(unique)]
  pub username: String,
}

#[tokio::main]
async fn main() {
  // Get MongoDB connection.
  let client = match Client::with_uri_str("mongodb://localhost:27017").await {
    Ok(client) => client,
    Err(e) => {
      panic!("Error connecting to the database: {}", e);
    }
  };

  // Nongoose instance.
  let nongoose = nongoose::Nongoose::build(client.database("nextchat"))
    .add_schema::
    ()
    .
    finish();

  
    let user 
    = User {
    id: ObjectId
    ::
    new(),
    username: 
    String
    ::
    from(
    "nongoose"),
  };

  
    if 
    let 
    Err(error) 
    = nongoose.
    create(
    &user).
    await {
    
    panic!(
    "Cannot create the user: {}", error);
  }

  
    println!(
    "User created in the database: {}", user.id);
}
   

Attributes

<-- this is a container attribute struct User { #[schema(id)] // <-- this is a field attribute #[serde(rename = "_id")] id: ObjectId; } ">
#[schema_relations] // <-- this is a macro attribute
#[derive(Clone, Debug, Deserialize, Schema, Serialize)]
#[schema(name = "users")]   // <-- this is a container attribute
struct User {
  #[schema(id)] // <-- this is a field attribute
  #[serde(rename = "_id")]
  id: ObjectId;
}

Macro attributes

  • #[schema_relations]

    Add relations {field_name}_id fields to the Struct.

Container attributes

  • #[schema(name = "name")]

    Set the collection name with the given name instead of its Rust name.

Field attributes

  • #[schema(id)] Required

    Represents the id of the document (_id in MongoDB).

  • #[schema(unique)]

    Unique this field: the field value cannot be duplicated in the document.

  • #[schema(convert = "path")]

    Call a function to convert the field type to a BSON type.

  • #[schema(many_to_one = "Schema")]

    Many to one relation.

  • #[schema(one_to_one = "Schema")]

    One to one relation.

Examples

  1. Many to One relation
# Sync execution
$ DATABASE_URL=mongodb://localhost:27017 cargo run --example many-to-one --no-default-features --features derive

# Async execution
$ DATABASE_URL=mongodb://localhost:27017 cargo run --example many-to-one

License

Check the COPYING file for more information.

Contributors

Thanks to this amazing people for make Nongoose better:

If you help to Nongoose feel free to add here.

Comments
  • add related projects to readme

    add related projects to readme

    I think it might be beneficial for others to know that they are other amazing projects like this they can check in case this does not fully satisfy them or they need to explore other options.

    So, this pr just adds links to those repositories.

    documentation 
    opened by ezesundayeze 1
  • Add before delete method to SchemaBefore trait (CU-2adbfw8)

    Add before delete method to SchemaBefore trait (CU-2adbfw8)

    AS a Nongoose user I WANT to execute an action before deleting a document; for example, delete all references it haves in other collections or check some data to be able to delete it.

    ClickUp card (ID: CU-2adbfw8)

    Technical specifications

    Suppoted features

    • [x] sync
    • [x] tokio-runtime

    Arguments

    • database nongoose::Database

    Return

    • nongoose::Result<bool> - If true the document can be deleted.
    feature schema 
    opened by dsolartec 0
  • Add find one and remove method (CU-2adb20n)

    Add find one and remove method (CU-2adb20n)

    Find one and remove

    Description

    This function will be used to search a document and remove the first one found; to do this, you can use the find_one function of the Nongoose struct and remove of the Schema struct.

    ClickUp card (ID: CU-2adb20n)

    Generics

    • S Schema value of schema to query by

    Arguments

    • conditions bson::Document
    • options Option<mongodb::options::FindOneOptions>

    Return

    • nongoose::Result<S>

    Example

    use nongoose::{
    	bson::{doc, oid::ObjectId},
    	Client, Nongoose, Schema, SchemaBefore,
    };
    use serde::{Deserialize, Serialize};
    
    #[derive(Clone, Debug, Deserialize, Schema, Serialize)]
    struct User {
    	#[schema(id, unique)]
    	#[serde(rename = "_id")]
    	id: ObjectId,
    
    	#[schema(unique)]
    	username: String,
    
    	realname: String,
    }
    
    impl User {
    	pub fn new(username: &str, realname: &str) -> Self {
    		Self {
    			id: ObjectId::new(),
    			username: String::from(username),
    			realname: String::from(realname),
    		}
    	}
    }
    
    #[async_trait::async_trait]
    impl SchemaBefore for User {}
    
    #[tokio::main]
    async fn main() {
            // Get database url.
    	let url = match std::env::var("DATABASE_URL") {
    		Ok(url) => url,
    		Err(_) => {
    			panic!("Cannot find `DATABASE_URL` on the environment variables.");
    		}
    	};
    
    	// Get MongoDB connection.
    	let client = match Client::with_uri_str(&url) {
    		Ok(client) => client,
    		Err(e) => {
    			panic!("Error connecting to the database: {}", e);
    		}
    	};
    
    	let nongoose = Nongoose::builder(client.database("nongoose"))
    		.add_schema::<User>()
    		.build();
    
            // Create default users.
    	let daniel = User::new("nongoose", "Nongoose").save().await;
    	assert!(daniel.is_ok());
    
    	let robert = User::new("robert", "Robert").save().await;
    	assert!(robert.is_ok());
    
            // Find one user and remove.
            let result = nongoose.find_one_and_remove::<User>(doc! { "username": "nongoose" }, None).await;
            assert!(result.is_ok());
    }
    
    feature nongoose 
    opened by dsolartec 0
  • Add delete one method (CU-2adbg1w)

    Add delete one method (CU-2adbg1w)

    This feature requires #9 to be completed before being developed.

    AS a Nongoose user I WANT to delete a document from a collection based on some conditions only if the check made before deleting is true, which in turn should allow me to enter the options provided by the MongoDB driver (Documentation).

    ClickUp card (ID: CU-2adbg1w)

    Technical specifications

    Supported features

    • [ ] sync
    • [ ] tokio-runtime

    Generics

    • S Schema value of schema to query by

    Arguments

    • conditions bson::Document
    • options Option<nongoose::options::DeleteOneOptions>

    Return

    • nongoose::Result<()>

    Example

    use nongoose::{
    	bson::{doc, oid::ObjectId},
    	Client, Nongoose, Schema, SchemaBefore,
    };
    use serde::{Deserialize, Serialize};
    
    #[derive(Clone, Debug, Deserialize, Schema, Serialize)]
    struct User {
    	#[schema(id, unique)]
    	#[serde(rename = "_id")]
    	id: ObjectId,
    
    	#[schema(unique)]
    	username: String,
    }
    
    impl User {
    	pub fn new(username: &str) -> Self {
    		Self {
    			id: ObjectId::new(),
    			username: String::from(username),
    		}
    	}
    }
    
    #[async_trait::async_trait]
    impl SchemaBefore for User {
    	async before_delete(_db: &Database) -> nongoose::Result<bool> {
    		println!("Before delete action");
    		true
    	}
    }
    
    #[tokio::main]
    async fn main() {
    	// Get database url.
    	let url = match std::env::var("DATABASE_URL") {
    		Ok(url) => url,
    		Err(_) => {
    			panic!("Cannot find `DATABASE_URL` on the environment variables.");
    		}
    	};
    
    	// Get MongoDB connection.
    	let client = match Client::with_uri_str(&url) {
    		Ok(client) => client,
    		Err(e) => {
    			panic!("Error connecting to the database: {}", e);
    		}
    	};
    
    	let nongoose = Nongoose::builder(client.database("nongoose"))
    		.add_schema::<User>()
    		.build();
    
    	// Create default users.
    	let daniel = User::new("nongoose").save().await;
    	assert!(daniel.is_ok());
    
    	let robert = User::new("robert").save().await;
    	assert!(robert.is_ok());
    
    	// Find one user and remove.
    	let result = nongoose.delete_one::<User>(doc! { "username": "nongoose" }, None).await;
    	assert!(result.is_ok());
    }
    
    help wanted feature nongoose 
    opened by dsolartec 0
  • v0.1.0-beta.2

    v0.1.0-beta.2

    Features

    • [x] aggregate method to Nongoose struct
    • [x] #8
    • [x] find_and_remove method to Nongoose struct
    • [x] find_by_id_and_remove method to Nongoose struct
    • [x] #9
    • [ ] #10
    version 
    opened by dsolartec 0
Releases(v0.1.0-beta.1)
Owner
NextChat
Messages social network.
NextChat
gobang - A cross-platform TUI database management tool written in Rust

gobang - A cross-platform TUI database management tool written in Rust

Takayuki Maeda 2.1k Jan 1, 2023
A high level async Redis client for Rust built on Tokio and Futures.

A high level async Redis client for Rust built on Tokio and Futures.

Alec Embke 108 Jan 1, 2023
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
The official MongoDB Rust Driver

MongoDB Rust Driver This repository contains the officially supported MongoDB Rust driver, a client side library that can be used to interact with Mon

mongodb 1.1k Dec 30, 2022
A demo blog post engine in Rust, using Rocket and MongoDB

A demo blog post engine written in Rust, using Rocket and MongoDB Quick Start Setup a new MongoDB cluster https://cloud.mongodb.com/ create a new data

Nabil Hachicha 5 Oct 19, 2022
This is superseded by the official MongoDB Rust Driver

This Repository is NOT a supported MongoDB product MongoDB Rust Driver Prototype NOTE: This driver is superseded by the official MongoDB Rust driver,

MongoDB, Inc. Labs 382 Nov 15, 2022
Rust Rocket MongoDB token-authorization REST API boilerplate

Rust Rocket MongoDB token-auth REST API boilerplate In this repository, you can find backend Rust rocket mongodb rest-api boilerplate with token autho

null 6 Dec 7, 2022
Blazingly fast data generation & seeding for MongoDB

Planter Blazingly fast and simple data generation & seeding for MongoDB Installation Use the package manager cargo to install planter. Add the followi

Valencian Digital 4 Jan 12, 2022
CLI tool and crate to download FTDC data from mongodb clusters.

Download mongodb FTDC data Command line tool and lib crate to download FTDC data from mongodb clusters to investigate with e.g. keyhole. Crate For the

Mathias Oertel 0 Nov 7, 2021
Simple backend app with Actix-web, JWT and MongoDB

Actix Web JWT Example Simple backend app with Actix-web, JWT and MongoDB (JWT Token, Protect Route, Login & Register) While developing the web service

Emre 124 Dec 31, 2022
The most efficient, scalable, and fast production-ready serverless REST API backend which provides CRUD operations for a MongoDB collection

Optimal CRUD Mongo Goals of This Project This is meant to be the most efficient, scalable, and fast production-ready serverless REST API backend which

Evaluates2 1 Feb 22, 2022
Teach your PostgreSQL database how to speak MongoDB Wire Protocol

“If it looks like MongoDB, swims like MongoDB, and quacks like MongoDB, then it probably is PostgreSQL.” ?? Discord | Online Demo | Intro Video | Quic

Felipe Coury 261 Jun 18, 2023
Automatically publish MongoDB changes to Redis for Meteor.

changestream-to-redis Warning The project is currently in its alpha phase. There are no production loads using it yet nor any large-scale tests were c

Radosław Miernik 8 Jul 29, 2023
A fully asynchronous, futures-based Kafka client library for Rust based on librdkafka

rust-rdkafka A fully asynchronous, futures-enabled Apache Kafka client library for Rust based on librdkafka. The library rust-rdkafka provides a safe

Federico Giraud 1.1k Jan 8, 2023
A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Intro fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Ze

null 203 Nov 9, 2022
A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Intro fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Ze

null 203 Nov 9, 2022
A Secure Capability-Based Runtime for JavaScript Based on Deno

Secure Runtime secure-runtime, as the name implies, is a secure runtime for JavaScript, designed for the multi-tenant serverless environment. It is an

Gigamono 7 Oct 7, 2022
A minimalist property-based testing library based on the arbitrary crate.

A minimalist property-based testing library based on the arbitrary crate.

Aleksey Kladov 61 Dec 21, 2022
Tokio based client library for the Android Debug Bridge (adb) based on mozdevice

forensic-adb Tokio based client library for the Android Debug Bridge (adb) based on mozdevice for Rust. Documentation This code has been extracted fro

null 6 Mar 31, 2023
Fast Symbol Ranking based compressor. Based on the idea of Matt Mahoney's SR2

Fast Symbol Ranking based compressor. Based on the idea of Matt Mahoney's SR2

Mai Thanh Minh 3 Apr 29, 2023