use gorm::{
execution::DatabaseConnectionPool,
returning, select_values, selected_value_to_order_by,
sql::{
self, AddableSqlExpression, BooleanAndableSqlExpression, BooleanOrableSqlExpression,
Insertable, LikeableSqlExpression, Migration, MultipliableSqlExpression,
OrderableSqlExpression, SqlExpression, TableMarker,
},
statements::{
DeleteStatementReturning, ExecuteSqlStatment, Filter, FilterDeleteStatement, GroupBy,
InnerJoinOnTrait, InnerJoinTrait, InsertStatementOnConflict, InsertStatementReturning,
LoadSingleColumnSqlStatment, LoadSqlStatment, OrderBy, OrderBySelectedValue, SelectFrom,
SelectValues, UpdateStatementReturning,
},
update_set, FromQueryResult,
};
mod tables;
use tables::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let pool =
DatabaseConnectionPool::connect("postgres://postgres:postgres@localhost/gorm_test").await?;
{
let mut client = pool.get().await?;
let transaction = client.begin_transaction().await?;
CreateTablesMigration::down(&transaction).await?;
CreateTablesMigration::up(&transaction).await?;
transaction.commit().await?;
}
school::new { name: "Stanford" }
.insert()
.execute(&pool)
.await?;
let second_school = school::new {
name: "Marble Hills School",
}
.insert()
.returning(school::id)
.load_one_value(&pool)
.await?;
let inserted_pet = pet::new_with_id {
name: "Kitty",
id: &5,
ty: &PetType::Dog,
}
.insert()
.returning(pet::all)
.load_one::<Pet>(&pool)
.await?;
println!("inserted pet: {:?}", inserted_pet);
person::new {
name: "James",
age: &44,
school_id: &1,
first_pet_id: &None,
second_pet_id: &None,
}
.insert()
.execute(&pool)
.await?;
person::new {
name: "Harry",
age: &33,
school_id: &1,
first_pet_id: &None,
second_pet_id: &None,
}
.insert()
.execute(&pool)
.await?;
person::new {
name: "David",
age: &34,
school_id: &1,
first_pet_id: &None,
second_pet_id: &None,
}
.insert()
.execute(&pool)
.await?;
let upserted_person = person::new {
name: "James",
age: &44,
school_id: &second_school,
first_pet_id: &None,
second_pet_id: &None,
}
.insert()
.on_conflict(person::unique_constraints::name_age)
.do_update(update_set!(person::school_id = second_school))
.returning(person::all)
.load_one::<Person>(&pool)
.await?;
let person_if_no_conflict_occured = person::new {
name: "James",
age: &44,
school_id: &second_school,
first_pet_id: &None,
second_pet_id: &None,
}
.insert()
.on_conflict_do_nothing()
.returning(person::all)
.load_optional::<Person>(&pool)
.await?;
println!("person if no conflict occured: {:?}", person_if_no_conflict_occured);
let inserted_person = person::new {
name: "Jake",
age: &29,
school_id: &1,
first_pet_id: &Some(inserted_pet.id),
second_pet_id: &None,
}
.insert()
.returning(person::all)
.load_one::<Person>(&pool)
.await?;
println!("inserted person: {:?}", inserted_person);
let deleted_people_ids = person::table
.delete()
.filter(person::name.not_like("J%"))
.returning(returning!(person::id))
.load_all_values(&pool)
.await
.unwrap();
println!("deleted people: {:?}", deleted_people_ids);
#[derive(Debug, FromQueryResult)]
struct PersonNameAndSchoolName {
name: String,
school_name: String,
}
let people_and_school_names = person::table
.inner_join(school::table)
.find()
.filter(
school::id.greater_equals(1).or(school::name
.equals("Stanford")
.and(school::id.greater_than(2))),
)
.select(select_values!(person::name, school::name as school_name))
.order_by_ascending(person::name)
.load_all::<PersonNameAndSchoolName>(&pool)
.await
.unwrap();
println!("{:?}", people_and_school_names);
#[derive(Debug, FromQueryResult)]
struct SomeAggregateExpression {
some_aggregate_expression: i64,
}
let aggregate_exprs = person::table
.find()
.select(select_values!(
sql::sum(person::age.multiply(person::id)) as some_aggregate_expression
))
.filter(person::age.greater_than(0))
.group_by(person::school_id.add(person::id))
.order_by_selected_value_descending(selected_value_to_order_by!(some_aggregate_expression))
.load_all::<SomeAggregateExpression>(&pool)
.await
.unwrap();
println!("aggregate expressions: {:?}", aggregate_exprs);
let schools_of_people = person::table
.inner_join(school::table)
.find()
.select(school::all)
.load_all::<School>(&pool)
.await
.unwrap();
println!("people: {:?}", schools_of_people);
#[derive(Debug, FromQueryResult)]
struct PersonAndPetName {
name: String,
pet_name: String,
}
let person_and_pet_names = person::table
.inner_join_on_column(person::first_pet_id, pet::table)
.find()
.select(select_values!(person::name, pet::name as pet_name))
.load_all::<PersonAndPetName>(&pool)
.await
.unwrap();
println!("{:?}", person_and_pet_names);
let names = person::table
.find()
.select(select_values!(person::name))
.load_all_values(&pool)
.await
.unwrap();
println!("{:?}", names);
let count = person::table
.find()
.select(select_values!(sql::count_rows() as count))
.load_one_value(&pool)
.await
.unwrap();
println!("count: {}", count);
let ages = person::table
.update()
.set(update_set!(person::age = person::age.add(1)))
.returning(person::age)
.load_all_values(&pool)
.await?;
println!("updated ages: {:?}", ages);
Ok(())
}