#[derive(Debug, Clone, Copy)]
pub struct Posts;
#[derive(Debug, Clone, PartialEq)]
pub struct Post {
pub id: i32,
pub user_id: i32,
pub title: String,
pub status: Option<String>,
pub views: i32,
pub published_at: Option<chrono::DateTime<chrono::Utc>>,
pub rel: Rel,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Rel {
pub user: Option<Box<super::users::User>>,
pub authorship: Option<Box<super::post_authors::PostAuthor>>,
pub comments: Vec<super::comments::Comment>,
pub post_tags: Vec<super::post_tags::PostTag>,
}
impl keelson_exec::FromRow for Post {
fn from_row(row: &mut keelson_exec::Row) -> Result<Self, keelson_exec::ExecError> {
Ok(Post {
id: row.take("id")?,
user_id: row.take("user_id")?,
title: row.take("title")?,
status: row.take("status")?,
views: row.take("views")?,
published_at: row.take("published_at")?,
rel: Rel::default(),
})
}
}
#[derive(Debug, Clone, Default)]
pub struct Setter {
pub id: keelson_models::Set<i32>,
pub user_id: keelson_models::Set<i32>,
pub title: keelson_models::Set<String>,
pub status: keelson_models::Set<String>,
pub views: keelson_models::Set<i32>,
pub published_at: keelson_models::Set<chrono::DateTime<chrono::Utc>>,
}
pub fn table() -> keelson_models::ModelTable<Posts> {
keelson_models::ModelTable::new()
}
pub fn id() -> keelson_models::Column<i32> {
keelson_models::Column::new("posts", "id")
}
pub fn user_id() -> keelson_models::Column<i32> {
keelson_models::Column::new("posts", "user_id")
}
pub fn title() -> keelson_models::Column<String> {
keelson_models::Column::new("posts", "title")
}
pub fn status() -> keelson_models::Column<String> {
keelson_models::Column::new("posts", "status")
}
pub fn views() -> keelson_models::Column<i32> {
keelson_models::Column::new("posts", "views")
}
pub fn published_at() -> keelson_models::Column<chrono::DateTime<chrono::Utc>> {
keelson_models::Column::new("posts", "published_at")
}
#[allow(clippy::type_complexity)]
fn all_columns() -> (
keelson_models::Column<i32>,
keelson_models::Column<i32>,
keelson_models::Column<String>,
keelson_models::Column<String>,
keelson_models::Column<i32>,
keelson_models::Column<chrono::DateTime<chrono::Utc>>,
) {
(id(), user_id(), title(), status(), views(), published_at())
}
impl keelson_models::View for Posts {
type Row = Post;
type Select = keelson_psql::SelectQuery;
fn base_select() -> Self::Select {
keelson_psql::select((
keelson_psql::select::columns(all_columns()),
keelson_psql::select::from(keelson_psql::quote("posts")),
))
}
}
impl keelson_models::Table for Posts {
type Pk = i32;
type Setter = Setter;
type Insert = keelson_psql::InsertQuery;
type Update = keelson_psql::UpdateQuery;
type Delete = keelson_psql::DeleteQuery;
fn insert_query(s: Setter) -> Self::Insert {
let mut cols: Vec<&'static str> = Vec::new();
let mut vals: Vec<keelson_core::expr::Expr> = Vec::new();
s.id.push_into("id", &mut cols, &mut vals);
s.user_id.push_into("user_id", &mut cols, &mut vals);
s.title.push_into("title", &mut cols, &mut vals);
s.status.push_into("status", &mut cols, &mut vals);
s.views.push_into("views", &mut cols, &mut vals);
s.published_at.push_into("published_at", &mut cols, &mut vals);
let mut q = keelson_psql::insert((
keelson_psql::insert::into(keelson_psql::quote("posts")).columns(cols),
keelson_psql::insert::returning(all_columns()),
));
if !vals.is_empty() {
q.apply(keelson_psql::insert::values(vals));
}
q
}
fn update_query() -> Self::Update {
keelson_psql::update(keelson_psql::update::table(keelson_psql::quote("posts")))
}
fn apply_setter(s: Setter, q: &mut Self::Update) {
if let Some(v) = s.id.into_expr() {
q.apply(keelson_psql::update::set_col("id").to(v));
}
if let Some(v) = s.user_id.into_expr() {
q.apply(keelson_psql::update::set_col("user_id").to(v));
}
if let Some(v) = s.title.into_expr() {
q.apply(keelson_psql::update::set_col("title").to(v));
}
if let Some(v) = s.status.into_expr() {
q.apply(keelson_psql::update::set_col("status").to(v));
}
if let Some(v) = s.views.into_expr() {
q.apply(keelson_psql::update::set_col("views").to(v));
}
if let Some(v) = s.published_at.into_expr() {
q.apply(keelson_psql::update::set_col("published_at").to(v));
}
}
fn delete_query() -> Self::Delete {
keelson_psql::delete(keelson_psql::delete::from(keelson_psql::quote("posts")))
}
fn pk(row: &Post) -> Self::Pk {
row.id
}
}
pub mod preload {
pub fn user() -> impl keelson_core::Mod<keelson_models::ModelSelect<super::Posts>> {
keelson_core::mod_fn(|q: &mut keelson_models::ModelSelect<super::Posts>| {
use keelson_psql::Chain as _;
use keelson_psql::Mod as _;
(
keelson_psql::select::left_join(keelson_psql::quote("users"))
.on(
keelson_psql::quote(("users", "id"))
.eq(keelson_psql::quote(("posts", "user_id"))),
),
keelson_psql::select::preload_columns((
keelson_psql::quote(("users", "id")).as_("user.id"),
keelson_psql::quote(("users", "name")).as_("user.name"),
keelson_psql::quote(("users", "email")).as_("user.email"),
keelson_psql::quote(("users", "age")).as_("user.age"),
keelson_psql::quote(("users", "is_active")).as_("user.is_active"),
keelson_psql::quote(("users", "created_at")).as_("user.created_at"),
)),
)
.apply(q);
q.add_mapper_mod(
keelson_models::mapper_mod(|row, parent: &mut super::Post| {
parent.rel.user = user_from_preload(row)?.map(Box::new);
Ok(())
}),
);
})
}
pub fn user_from_preload(
row: &mut keelson_exec::Row,
) -> Result<Option<super::super::users::User>, keelson_exec::ExecError> {
if matches!(row.value("user.id"), None | Some(keelson_psql::Value::Null)) {
return Ok(None);
}
Ok(
Some(super::super::users::User {
id: row.take("user.id")?,
name: row.take("user.name")?,
email: row.take("user.email")?,
age: row.take("user.age")?,
is_active: row.take("user.is_active")?,
created_at: row.take("user.created_at")?,
rel: super::super::users::Rel::default(),
}),
)
}
pub fn authorship() -> impl keelson_core::Mod<
keelson_models::ModelSelect<super::Posts>,
> {
keelson_core::mod_fn(|q: &mut keelson_models::ModelSelect<super::Posts>| {
use keelson_psql::Chain as _;
use keelson_psql::Mod as _;
(
keelson_psql::select::left_join(keelson_psql::quote("post_authors"))
.on(
keelson_psql::quote(("post_authors", "post_id"))
.eq(keelson_psql::quote(("posts", "id"))),
),
keelson_psql::select::preload_columns((
keelson_psql::quote(("post_authors", "post_id"))
.as_("authorship.post_id"),
keelson_psql::quote(("post_authors", "title"))
.as_("authorship.title"),
keelson_psql::quote(("post_authors", "user_id"))
.as_("authorship.user_id"),
keelson_psql::quote(("post_authors", "user_name"))
.as_("authorship.user_name"),
)),
)
.apply(q);
q.add_mapper_mod(
keelson_models::mapper_mod(|row, parent: &mut super::Post| {
parent.rel.authorship = authorship_from_preload(row)?.map(Box::new);
Ok(())
}),
);
})
}
pub fn authorship_from_preload(
row: &mut keelson_exec::Row,
) -> Result<
Option<super::super::post_authors::PostAuthor>,
keelson_exec::ExecError,
> {
if matches!(
row.value("authorship.post_id"), None | Some(keelson_psql::Value::Null)
) {
return Ok(None);
}
Ok(
Some(super::super::post_authors::PostAuthor {
post_id: row.take("authorship.post_id")?,
title: row.take("authorship.title")?,
user_id: row.take("authorship.user_id")?,
user_name: row.take("authorship.user_name")?,
rel: super::super::post_authors::Rel::default(),
}),
)
}
}
pub mod then_load {
pub fn user() -> keelson_models::ThenLoad<
super::Posts,
super::super::users::Users,
i32,
> {
keelson_models::ThenLoad::new(
|rows: &[super::Post]| rows.iter().map(|r| r.user_id).collect(),
|keys, q| keelson_core::Mod::apply(super::super::users::id().in_(keys), q),
|rows: &mut [super::Post], related| {
keelson_models::attach_to_one(
rows,
related,
|r| r.user_id,
|c| c.id,
|r, c| {
r.rel.user = c.map(Box::new);
},
);
},
)
}
pub fn authorship() -> keelson_models::ThenLoad<
super::Posts,
super::super::post_authors::PostAuthors,
i32,
> {
keelson_models::ThenLoad::new(
|rows: &[super::Post]| rows.iter().map(|r| r.id).collect(),
|keys, q| keelson_core::Mod::apply(
super::super::post_authors::post_id().in_(keys),
q,
),
|rows: &mut [super::Post], related| {
keelson_models::attach_to_one(
rows,
related,
|r| Some(r.id),
|c| c.post_id,
|r, c| {
r.rel.authorship = c.map(Box::new);
},
);
},
)
}
pub fn comments() -> keelson_models::ThenLoad<
super::Posts,
super::super::comments::Comments,
i32,
> {
keelson_models::ThenLoad::new(
|rows: &[super::Post]| rows.iter().map(|r| r.id).collect(),
|keys, q| keelson_core::Mod::apply(
super::super::comments::post_id().in_(keys),
q,
),
|rows: &mut [super::Post], related| {
keelson_models::attach_to_many(
rows,
related,
|r| r.id,
|c| c.post_id,
|r, cs| {
r.rel.comments = cs;
},
);
},
)
}
pub fn post_tags() -> keelson_models::ThenLoad<
super::Posts,
super::super::post_tags::PostTags,
i32,
> {
keelson_models::ThenLoad::new(
|rows: &[super::Post]| rows.iter().map(|r| r.id).collect(),
|keys, q| keelson_core::Mod::apply(
super::super::post_tags::post_id().in_(keys),
q,
),
|rows: &mut [super::Post], related| {
keelson_models::attach_to_many(
rows,
related,
|r| r.id,
|c| c.post_id,
|r, cs| {
r.rel.post_tags = cs;
},
);
},
)
}
}