mirror of
https://github.com/Nutomic/ibis.git
synced 2025-02-10 15:54:42 +00:00
join lateral
This commit is contained in:
parent
18514e082c
commit
0ffbcb7471
6 changed files with 47 additions and 63 deletions
|
@ -7,11 +7,16 @@ use crate::{
|
|||
},
|
||||
common::{
|
||||
instance::{
|
||||
DbInstance, FollowInstanceParams, GetInstanceParams, InstanceView, InstanceView2,
|
||||
DbInstance,
|
||||
FollowInstanceParams,
|
||||
GetInstanceParams,
|
||||
InstanceView,
|
||||
InstanceView2,
|
||||
UpdateInstanceParams,
|
||||
},
|
||||
user::LocalUserView,
|
||||
ResolveObjectParams, SuccessResponse,
|
||||
ResolveObjectParams,
|
||||
SuccessResponse,
|
||||
},
|
||||
};
|
||||
use activitypub_federation::{config::Data, fetch::object_id::ObjectId};
|
||||
|
|
|
@ -5,14 +5,14 @@ use crate::{
|
|||
IbisContext,
|
||||
},
|
||||
federation::objects::{
|
||||
articles_collection::DbArticleCollection, instance_collection::DbInstanceCollection,
|
||||
articles_collection::DbArticleCollection,
|
||||
instance_collection::DbInstanceCollection,
|
||||
},
|
||||
utils::error::MyResult,
|
||||
},
|
||||
common::{
|
||||
article::DbArticle,
|
||||
instance::{DbInstance, InstanceView, InstanceView2},
|
||||
newtypes::{ArticleId, CommentId, InstanceId},
|
||||
newtypes::{CommentId, InstanceId},
|
||||
user::DbPerson,
|
||||
},
|
||||
};
|
||||
|
@ -21,20 +21,9 @@ use activitypub_federation::{
|
|||
fetch::{collection_id::CollectionId, object_id::ObjectId},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use diesel::{
|
||||
associations::HasTable,
|
||||
define_sql_function,
|
||||
deserialize::{self, FromSql},
|
||||
insert_into,
|
||||
pg::{Pg, PgValue},
|
||||
sql_types::Record,
|
||||
update, AsChangeset, ExpressionMethods, Insertable, JoinOnDsl, NullableExpressionMethods,
|
||||
QueryDsl, RunQueryDsl,
|
||||
};
|
||||
use diesel::*;
|
||||
use std::{fmt::Debug, ops::DerefMut};
|
||||
|
||||
use super::array_agg;
|
||||
|
||||
#[derive(Debug, Clone, Insertable, AsChangeset)]
|
||||
#[diesel(table_name = instance, check_for_backend(diesel::pg::Pg))]
|
||||
pub struct DbInstanceForm {
|
||||
|
@ -151,26 +140,28 @@ impl DbInstance {
|
|||
|
||||
pub fn list(context: &Data<IbisContext>) -> MyResult<Vec<InstanceView>> {
|
||||
let mut conn = context.db_pool.get()?;
|
||||
// select instance, array_agg(article) from instance left join article on instance.id=article.instance_id group by instance.id;
|
||||
let res: Vec<_> = instance::table
|
||||
.left_join(article::table.on(instance::id.eq(article::instance_id)))
|
||||
.select((
|
||||
instance::all_columns,
|
||||
//array_agg(article::all_columns)
|
||||
diesel::dsl::sql::<diesel::sql_types::Array<article::SqlType>>(
|
||||
"array_agg(article.*)",
|
||||
),
|
||||
))
|
||||
.group_by(instance::id)
|
||||
// TODO: throws invalid trait bound
|
||||
.get_results::<(DbInstance, Vec<DbArticle>)>(conn.deref_mut())?;
|
||||
Ok(res
|
||||
.into_iter()
|
||||
.map(|x| InstanceView {
|
||||
instance: x.0,
|
||||
articles: x.1,
|
||||
})
|
||||
.collect())
|
||||
let res: Vec<_> = sql_query(
|
||||
"SELECT
|
||||
instance,
|
||||
array_agg(a) as articles
|
||||
FROM
|
||||
instance
|
||||
CROSS JOIN LATERAL (
|
||||
SELECT
|
||||
title
|
||||
FROM
|
||||
article
|
||||
WHERE
|
||||
instance.id = article.instance_id
|
||||
GROUP BY
|
||||
article.id
|
||||
LIMIT 5) a
|
||||
GROUP BY
|
||||
id;",
|
||||
)
|
||||
.select(InstanceView::as_select())
|
||||
.get_results::<InstanceView>(conn.deref_mut())?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Read the instance where an article is hosted, based on a comment id.
|
||||
|
@ -188,16 +179,3 @@ impl DbInstance {
|
|||
.get_result(conn.deref_mut())?)
|
||||
}
|
||||
}
|
||||
|
||||
define_sql_function!(fn array_agg<T: diesel::sql_types::SingleValue>(expr: T) -> Array<T>);
|
||||
|
||||
// https://github.com/diesel-rs/diesel/discussions/3826
|
||||
impl FromSql<diesel::sql_types::Record<article::SqlType>, Pg> for DbArticle {
|
||||
fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
|
||||
//let mut bytes = value.as_bytes();
|
||||
//let res: (i32,) = FromSql::<Record<article::SqlType>, Pg>::from_sql(value)?;
|
||||
|
||||
//Ok(Label1 { id: res.0 })
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ use crate::backend::{
|
|||
};
|
||||
use diesel::{
|
||||
r2d2::{ConnectionManager, Pool},
|
||||
PgConnection, QueryDsl, RunQueryDsl,
|
||||
PgConnection,
|
||||
QueryDsl,
|
||||
RunQueryDsl,
|
||||
};
|
||||
use std::ops::DerefMut;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use super::{
|
|||
user::DbPerson,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use diesel::QueryableByName;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use uuid::Uuid;
|
||||
|
@ -39,7 +40,7 @@ pub struct DbArticleView {
|
|||
pub latest_version: EditVersion,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, QueryableByName)]
|
||||
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
||||
#[cfg_attr(feature = "ssr", diesel(table_name = article, check_for_backend(diesel::pg::Pg), belongs_to(DbInstance, foreign_key = instance_id)))]
|
||||
pub struct DbArticle {
|
||||
|
|
|
@ -4,13 +4,15 @@ use super::{
|
|||
user::{DbPerson, LocalUserView},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use diesel::QueryableByName;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smart_default::SmartDefault;
|
||||
use url::Url;
|
||||
#[cfg(feature = "ssr")]
|
||||
use {
|
||||
crate::backend::{
|
||||
database::schema::instance, federation::objects::articles_collection::DbArticleCollection,
|
||||
database::schema::instance,
|
||||
federation::objects::articles_collection::DbArticleCollection,
|
||||
federation::objects::instance_collection::DbInstanceCollection,
|
||||
},
|
||||
activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId},
|
||||
|
@ -18,7 +20,7 @@ use {
|
|||
doku::Document,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, QueryableByName)]
|
||||
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
||||
#[cfg_attr(feature = "ssr", diesel(table_name = instance, check_for_backend(diesel::pg::Pg)))]
|
||||
pub struct DbInstance {
|
||||
|
@ -52,10 +54,12 @@ impl DbInstance {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "ssr", derive(Queryable))]
|
||||
#[cfg_attr(feature = "ssr", diesel(table_name = article, check_for_backend(diesel::pg::Pg)))]
|
||||
#[cfg_attr(feature = "ssr", derive(Queryable, QueryableByName))]
|
||||
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||
pub struct InstanceView {
|
||||
#[diesel(embed)]
|
||||
pub instance: DbInstance,
|
||||
#[diesel(embed)]
|
||||
pub articles: Vec<DbArticle>,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
use super::{result_to_option, ApiClient};
|
||||
use crate::common::{
|
||||
article::{DbArticle, SearchArticleParams},
|
||||
instance::{
|
||||
DbInstance,
|
||||
FollowInstanceParams,
|
||||
InstanceView2,
|
||||
SiteView,
|
||||
UpdateInstanceParams,
|
||||
},
|
||||
instance::{DbInstance, FollowInstanceParams, InstanceView2, SiteView, UpdateInstanceParams},
|
||||
Notification,
|
||||
ResolveObjectParams,
|
||||
SuccessResponse,
|
||||
|
|
Loading…
Reference in a new issue