Macro surreal_simple_querybuilder::model
source · model!() { /* proc-macro */ }
Expand description
The model
macro allows you to quickly create structs (aka models) with fields
that match the nodes of your database.
use surreal_simple_querybuilder::prelude::*;
struct Account {
id: Option<String>,
handle: String,
password: String,
email: String,
friends: Foreign<Vec<Account>>
}
model!(Account {
id,
handle,
password,
friends<Vec<Account>>
});
fn main() {
the schema module is created by the macro
use schema::model as account;
let query = format!("select {} from {account}", account.handle);
assert_eq!("select handle from Account", query);
}
This allows you to have compile time checked constants for your fields, allowing you to reference them while building your queries without fearing of making a typo or using a field you renamed long time ago.
If you wish to include relations (aka edges) in your models, the model
macro
has a special syntax for them:
mod account {
use surreal_simple_querybuilder::prelude::*;
use super::project::schema::Project;
model!(Account {
id,
->manage->Project as managed_projects
});
}
mod project {
use surreal_simple_querybuilder::prelude::*;
use super::project::schema::Project;
model!(Project {
id,
pub name,
<-manage<-Account as authors
});
}
fn main() {
use account::schema::model as account;
let query = format!("select {} from {account}", account.managed_projects);
assert_eq!("select ->manage->Project from Account");
let query = format!("select {} from {account}", account.managed_projects().name.as_alias("project_names"))
assert_eq!("select ->manage->Project.name as project_names from Account", query);
}
public & private fields
The QueryBuilder type offers a series of methods to quickly list the fields of your
models in SET or UPDATE statements so you don’t have to write the fields and the
variable names one by one. Since you may not want to serialize some of the fields
like the id
for example the model macro has the pub
keyword to mark a field
as serializable. Any field without the pub
keyword in front of it will not
be serialized by these methods.
model!(Project {
id, // <- won't be serialized
pub name, // <- will be serialized
})
fn example() {
use schema::model as project;
let query = QueryBuilder::new()
.set_model(project)
.build();
assert_eq!(query, "SET name = $name");
}
Expected output
The macro automatically creates a module named schema
with two main elements
inside:
- a struct named the same way as your model
- a
model
constant that is an instance of the struct above so you can quickly use it without having to callAccount::new()
everytime.
Here is a trimmed down version of what to expect, keep in mind this is an example and not exactly what you will find:
mod schema {
#[derive(Serialize)]
struct Account {
#[serde(skip_serializing)]
id: &'static str
name: &'static str,
// ...
}
pub const model: Account = Account::new();
}