summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2022-09-24 16:10:08 +0000
committerSanto Cariotti <santo@dcariotti.me>2022-09-24 16:10:08 +0000
commit357b9e646df220575df37fe1d6705a9667210997 (patch)
tree76f415c19f636a2899dd469745baf21fbff8b808 /src
parentf1b9eb9e54bc264c235a4d77a18ad2f3c943a6d1 (diff)
Get user's models
Diffstat (limited to 'src')
-rw-r--r--src/models/model.rs38
-rw-r--r--src/models/user.rs19
-rw-r--r--src/routes/model.rs6
-rw-r--r--src/routes/user.rs21
4 files changed, 79 insertions, 5 deletions
diff --git a/src/models/model.rs b/src/models/model.rs
index 0a9ea0a..60a6814 100644
--- a/src/models/model.rs
+++ b/src/models/model.rs
@@ -198,6 +198,32 @@ impl Model {
Ok(rows)
}
+ /// List author's models
+ pub async fn list_from_author(page: i64, author: i32) -> Result<Vec<ModelUser>, AppError> {
+ let pool = unsafe { get_client() };
+ let rows: Vec<ModelUser> = sqlx::query_as(
+ r#"
+ SELECT
+ models.*,
+ json_build_object('id', users.id, 'email', users.email, 'username', users.username, 'is_staff', users.is_staff, 'avatar', users.avatar) as author,
+ json_agg(uploads.*) filter (where uploads.* is not null) as uploads
+ FROM models
+ JOIN users ON users.id = models.author_id
+ LEFT JOIN uploads ON uploads.model_id = models.id
+ WHERE author_id = $1
+ GROUP BY models.id, users.id
+ ORDER BY id DESC
+ LIMIT $2 OFFSET $3
+ "#)
+ .bind(author)
+ .bind(CONFIG.page_limit)
+ .bind(CONFIG.page_limit * page)
+ .fetch_all(pool)
+ .await?;
+
+ Ok(rows)
+ }
+
/// Delete a model
pub async fn delete(model_id: i32) -> Result<(), AppError> {
let pool = unsafe { get_client() };
@@ -224,6 +250,18 @@ impl Model {
let count: i64 = cursor.try_get(0).unwrap();
Ok(count)
}
+
+ /// Return the number of author models
+ pub async fn count_filter_by_author(author: i32) -> Result<i64, AppError> {
+ let pool = unsafe { get_client() };
+ let cursor = sqlx::query(r#"SELECT COUNT(id) as count FROM models WHERE author_id = $1"#)
+ .bind(author)
+ .fetch_one(pool)
+ .await?;
+
+ let count: i64 = cursor.try_get(0).unwrap();
+ Ok(count)
+ }
}
impl ModelUser {
diff --git a/src/models/user.rs b/src/models/user.rs
index c4debf5..7c08075 100644
--- a/src/models/user.rs
+++ b/src/models/user.rs
@@ -1,4 +1,9 @@
-use crate::{config::CONFIG, db::get_client, errors::AppError};
+use crate::{
+ config::CONFIG,
+ db::get_client,
+ errors::AppError,
+ models::model::{Model, ModelUser},
+};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, NoneAsEmptyString};
@@ -170,7 +175,7 @@ impl User {
}
impl UserList {
- // Edit an user
+ /// Edit an user
pub async fn edit_avatar(&mut self, avatar: Option<String>) -> Result<(), AppError> {
let pool = unsafe { get_client() };
sqlx::query(
@@ -187,4 +192,14 @@ impl UserList {
Ok(())
}
+
+ /// Get all models created by an user
+ pub async fn get_models(&self, page: i64) -> Result<Vec<ModelUser>, AppError> {
+ Model::list_from_author(page, self.id).await
+ }
+
+ /// Returns the number of models for an user
+ pub async fn count_models(&self) -> Result<i64, AppError> {
+ Model::count_filter_by_author(self.id).await
+ }
}
diff --git a/src/routes/model.rs b/src/routes/model.rs
index b510ade..16468d0 100644
--- a/src/routes/model.rs
+++ b/src/routes/model.rs
@@ -27,9 +27,9 @@ pub fn create_route() -> Router {
}
#[derive(Serialize)]
-struct ModelPagination {
- count: i64,
- results: Vec<ModelUser>,
+pub struct ModelPagination {
+ pub count: i64,
+ pub results: Vec<ModelUser>,
}
/// List models.
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 4904531..172007a 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -6,6 +6,7 @@ use crate::{
user::{User, UserList},
},
pagination::Pagination,
+ routes::model::ModelPagination,
};
use axum::{
extract::{ContentLengthLimit, Multipart, Path, Query},
@@ -21,6 +22,7 @@ pub fn create_route() -> Router {
.route("/me", get(get_me))
.route("/me/avatar", put(edit_my_avatar).delete(delete_my_avatar))
.route("/:id", get(get_user))
+ .route("/:id/models", get(get_user_models))
}
#[derive(Serialize)]
@@ -108,3 +110,22 @@ async fn get_user(Path(user_id): Path<i32>) -> Result<Json<UserList>, AppError>
Err(_) => Err(AppError::NotFound("User not found".to_string())),
}
}
+
+/// Get user models list
+async fn get_user_models(
+ Path(user_id): Path<i32>,
+ pagination: Query<Pagination>,
+) -> Result<Json<ModelPagination>, AppError> {
+ let user = match User::find_by_id(user_id).await {
+ Ok(user) => user,
+ Err(_) => {
+ return Err(AppError::NotFound("User not found".to_string()));
+ }
+ };
+
+ let page = pagination.0.page.unwrap_or_default();
+ let results = user.get_models(page).await?;
+ let count = user.count_models().await?;
+
+ Ok(Json(ModelPagination { count, results }))
+}