To simulate fields of type ForeignKey and ManyToMany, a simplified alternative (Types of selective fields with dynamic addition of elements) is used.
( all parameters are optional )
| Parameter: | Default: | Description: | | :------------------ | :----------- | :--------------------------------------------------------------------------------------------------- | | dbclientname | empty string | Used to connect to a MongoDB cluster. | | dbquerydocslimit | 1000 | limiting query results. | | isadddocs | true | Create documents in the database. false - Alternatively, use it to validate data from web forms. | | isupdocs | true | Update documents in the database. | | isdeldocs | true | Delete documents from the database. | | ignorefields | empty string | Fields that are not included in the database (separated by commas). | | isuseaddvalid | false | Allows additional validation - impl AdditionalValidation for ModelName. | | isuse_hooks | false | Allows hooks methods - impl Hooks for ModelName. |
See documentation -fields.
```shell
$ sudo apt install mongodb
$ sudo apt update $ sudo apt install dirmngr gnupg apt-transport-https ca-certificates $ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - $ sudo add-apt-repository 'deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse' $ sudo apt update $ sudo apt install mongodb-org $ sudo systemctl enable --now mongod
$ mongod --version $ mongo --eval 'db.runCommand({ connectionStatus: 1 })' $ reboot #
$ sudo nano /etc/mongod.conf #
$ sudo systemctl status mongod $ sudo systemctl start mongod $ sudo systemctl stop mongod $ sudo systemctl restart mongod $ sudo systemctl enable mongod $ sudo systemctl disable mongod #
$ sudo systemctl stop mongod $ sudo systemctl disable mongod $ sudo apt --purge remove mongodb* # OR (for mongodb-org) - $ sudo apt --purge remove mongodb-org** $ sudo rm -r /var/log/mongodb $ sudo rm -r /var/lib/mongodb $ sudo rm -f /etc/mongod.conf $ sudo apt-add-repository --remove 'deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse' # for mongodb-org $ sudo apt update ```
```toml [dependencies] green-barrel = "1.0.12-beta" metamorphose = "1.0.4-beta" regex = "1.6.0" serde_json = "1.0.85"
[dependencies.mongodb] default-features = false features = ["sync"] version = "1.2.5"
[dependencies.serde] features = ["derive"] version = "1.0.145" ```
```rust // General settings for the project. // Project name. // Hint: PROJECTNAM it is recommended not to change. // Valid characters: _ a-z A-Z 0-9 // Max size: 21 // First character: a-z A-Z pub const PROJECTNAME: &str = "store";
// Unique project key. // Hint: UNIQUEPROJECTKEY it is recommended not to change. // Valid characters: a-z A-Z 0-9 // Size: 8-16 // Example: "7rzgacfqQB3B7q7T" // To generate a key: https://randompasswordgen.com/ pub const UNIQUEPROJECTKEY: &str = "A3iBcq9K19287PN3";
// Settings for user accounts. pub mod users { // Valid characters: _ a-z A-Z 0-9 // Max size: 31 // First character: a-z A-Z pub const SERVICENAME: &str = "accounts"; // Valid characters: _ a-z A-Z 0-9 // Max size: 21 // First character: a-z A-Z pub const DATABASENAME: &str = "accounts"; pub const DBCLIENTNAME: &str = "default"; pub const DBQUERYDOCS_LIMIT: u32 = 1000; } ```
```rust use crate::{models, settings}; use greenbarrel::{Caching, Monitor, MONGODBCLIENT_STORE}; use std::error::Error;
// Migration
pub fn runmigration() -> Result<(), Box
Ok(())
} ```
```rust use green_barrel::*; use metamorphose::Model; use regex::RegexBuilder; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, error::Error};
use crate::settings::{ users::{DATABASENAME, DBCLIENTNAME, DBQUERYDOCSLIMIT, SERVICENAME}, PROJECTNAME, UNIQUEPROJECTKEY, };
is_use_add_valid = true,
is_use_hooks = true,
ignore_fields = "confirm_password" // Example: "field_name, field_name_2"
)]
pub struct User { pub username: InputText, pub slug: AutoSlug, pub firstname: InputText, pub lastname: InputText, pub email: InputEmail, pub phone: InputPhone, pub password: InputPassword, pub confirmpassword: InputPassword, pub isstaff: CheckBox, pub is_active: CheckBox, }
impl Control for User {
fn customdefault() -> Self {
Self {
username: InputText {
label: "Username".into(),
placeholder: "Enter your username".into(),
maxlength: 150,
required: true,
unique: true,
hint: "Valid characters: a-z A-Z 0-9 _ @ + .
Max size: 150".into(),
..Default::default()
},
slug: AutoSlug {
label: "Slug".into(),
unique: true,
readonly: true,
hint: "To create a human readable url".into(),
slugsources: vec!["hash".into(), "username".into()],
..Default::default()
},
firstname: InputText {
label: "First name".into(),
placeholder: "Enter your First name".into(),
maxlength: 150,
..Default::default()
},
lastname: InputText {
label: "Last name".into(),
placeholder: "Enter your Last name".into(),
maxlength: 150,
..Default::default()
},
email: InputEmail {
label: "E-mail".into(),
placeholder: "Please enter your email".into(),
required: true,
unique: true,
maxlength: 320,
hint: "Your actual E-mail".into(),
..Default::default()
},
phone: InputPhone {
label: "Phone number".into(),
placeholder: "Please enter your phone number".into(),
unique: true,
maxlength: 30,
hint: "Your actual phone number".into(),
..Default::default()
},
password: InputPassword {
label: "Password".into(),
placeholder: "Enter your password".into(),
required: true,
minlength: 8,
hint: "Valid characters: a-z A-Z 0-9 @ # $ % ^ & + = * ! ~ ) (
Min size: 8"
.into(),
..Default::default()
},
confirmpassword: InputPassword {
label: "Confirm password".into(),
placeholder: "Repeat your password".into(),
required: true,
minlength: 8,
..Default::default()
},
isstaff: CheckBox {
label: "is staff?".into(),
checked: Some(true),
hint: "User can access the admin site?".into(),
..Default::default()
},
is_active: CheckBox {
label: "is active?".into(),
checked: Some(true),
hint: "Is this an active account?".into(),
..Default::default()
},
..Default::default()
}
}
}
impl AdditionalValidation for User {
fn addvalidation<'a>(&self) -> Result
// Get clean data
let hash = self.hash.value.clone().unwrap_or_default();
let password = self.password.value.clone().unwrap_or_default();
let confirm_password = self.confirm_password.value.clone().unwrap_or_default();
let username = self.username.value.clone().unwrap_or_default();
// Fields validation
if hash.is_empty() && password != confirm_password {
error_map.insert("confirm_password", "Password confirmation does not match.");
}
if !RegexBuilder::new(r"^[a-z\d_@+.]+$")
.case_insensitive(true)
.build()
.unwrap()
.is_match(username.as_str())
{
error_map.insert(
"username",
"Invalid characters present.<br>\
Valid characters: a-z A-Z 0-9 _ @ + .",
);
}
Ok(error_map)
}
}
impl Hooks for User { fn precreate(&self) { println!("!!!Pre Create!!!"); } // fn postcreate(&self) { println!("!!!Post Create!!!"); } // fn preupdate(&self) { println!("!!!Pre Update!!!"); } // fn postupdate(&self) { println!("!!!Post Update!!!"); } // fn predelete(&self) { println!("!!!Pre Delet!!!"); } // fn postdelete(&self) { println!("!!!Post Delet!!!"); } } ```
```rust mod migration; mod models; mod settings;
use green_barrel::*; use std::error::Error;
fn main() -> Result<(), Box
// Create model instance.
// ---------------------------------------------------------------------------------------------
let mut user = models::User::new()?;
user.username.set("user_1");
user.email.set("user_1_@noreply.net");
user.password.set("12345678");
user.confirm_password.value = Some("12345678".to_string()); // Example without the set() method
user.is_staff.set(true);
user.is_active.set(true);
// Check Model.
// ---------------------------------------------------------------------------------------------
println!("\n\nCheck Modell:\n");
let output_data = user.check(None)?;
if output_data.is_valid() {
println!("Hash: {:?}", user.hash.get());
println!("Hash: {}", output_data.hash());
println!("Created at: {:?}", user.created_at.get());
println!("Updated at: {:?}", user.updated_at.get());
println!("Created at: {:?}", output_data.created_at());
println!("Updated at: {:?}", output_data.updated_at());
println!("Object Id: {:?}", user.hash.obj_id()?);
println!("Object Id: {:?}", output_data.obj_id()?);
} else {
// Printing errors to the console ( for development ).
output_data.print_err();
}
//println!("Json:\n{}", output_data.json()?);
//println!("Json for admin:\n{}", output_data.json_for_admin()?);
// Create document in database.
// ---------------------------------------------------------------------------------------------
println!("\n\nCreate document in database:\n");
let output_data = user.save(None, None)?;
if output_data.is_valid() {
println!("Hash: {}", user.hash.get().unwrap());
println!("Hash: {}", output_data.hash());
println!("Created at: {}", user.created_at.get().unwrap());
println!("Updated at: {}", user.updated_at.get().unwrap());
println!("Created at: {}", output_data.created_at().unwrap());
println!("Updated at: {}", output_data.updated_at().unwrap());
println!("Object Id: {:?}", user.hash.obj_id()?.unwrap());
println!("Object Id: {:?}", output_data.obj_id()?.unwrap());
// If there are AutoSlug fields, do an update.
user = output_data.update()?;
println!("Slug: {}", user.slug.get().unwrap())
//println!("Json:\n{}", output_data.json()?);
//println!("Json for admin:\n{}", output_data.json_for_admin()?);
} else {
// Printing errors to the console ( for development ).
output_data.print_err();
}
// Update document in database.
// ---------------------------------------------------------------------------------------------
println!("\n\nUpdate document in database:\n");
if output_data.is_valid() {
user.username.set("user_1_update");
let output_data = user.save(None, None)?;
println!("Hash: {}", user.hash.get().unwrap());
println!("Hash: {}", output_data.hash());
println!("Created at: {}", user.created_at.get().unwrap());
println!("Updated at: {}", user.updated_at.get().unwrap());
println!("Created at: {}", output_data.created_at().unwrap());
println!("Updated at: {}", output_data.updated_at().unwrap());
println!("Object Id: {:?}", user.hash.obj_id()?.unwrap());
println!("Object Id: {:?}", output_data.obj_id()?.unwrap());
// If there are AutoSlug fields, do an update.
user = output_data.update()?;
println!("Slug: {}", user.slug.get().unwrap())
//println!("Json:\n{}", output_data.json()?);
//println!("Json for admin:\n{}", output_data.json_for_admin()?);
} else {
// Printing errors to the console ( for development ).
output_data.print_err();
}
// Delete document in database.
// ---------------------------------------------------------------------------------------------
println!("\n\nDelete document in database:\n");
let output_data = user.delete(None)?;
if !output_data.is_valid() {
// Printing errors to the console ( for development ).
output_data.print_err();
}
Ok(())
} ```