summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs1
-rw-r--r--src/main.rs2
-rw-r--r--src/models/model.rs20
-rw-r--r--src/models/user.rs19
-rw-r--r--src/pagination.rs7
-rw-r--r--src/routes/model.rs18
-rw-r--r--src/routes/user.rs25
7 files changed, 80 insertions, 12 deletions
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..6449a3f
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1 @@
+pub static PAGE_LIMIT: i64 = 20;
diff --git a/src/main.rs b/src/main.rs
index 1c9d63a..59ffb24 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,9 @@
+mod config;
mod db;
mod errors;
mod logger;
mod models;
+mod pagination;
mod routes;
use axum::{
diff --git a/src/models/model.rs b/src/models/model.rs
index e3fc7ac..a87cddb 100644
--- a/src/models/model.rs
+++ b/src/models/model.rs
@@ -1,4 +1,6 @@
+use crate::config::PAGE_LIMIT;
use crate::db::get_client;
+
use crate::errors::AppError;
use sqlx::types::JsonValue;
@@ -111,18 +113,32 @@ impl Model {
}
/// List all models
- pub async fn list() -> Result<Vec<ModelUser>, AppError> {
+ pub async fn list(page: i64) -> Result<Vec<ModelUser>, AppError> {
let pool = unsafe { get_client() };
let rows = sqlx::query_as!(
ModelUser,
r#"SELECT
models.*,
json_build_object('id', users.id, 'email', users.email, 'username', users.username, 'is_staff', users.is_staff) as author
- FROM models JOIN users ON users.id = models.author_id"#
+ FROM models JOIN users ON users.id = models.author_id
+ LIMIT $1 OFFSET $2
+ "#,
+ PAGE_LIMIT,
+ PAGE_LIMIT * page
)
.fetch_all(pool)
.await?;
Ok(rows)
}
+
+ /// Return the number of models.
+ pub async fn count() -> Result<i64, AppError> {
+ let pool = unsafe { get_client() };
+ let row = sqlx::query!(r#"SELECT COUNT(id) as count FROM models"#)
+ .fetch_one(pool)
+ .await?;
+
+ Ok(row.count.unwrap())
+ }
}
diff --git a/src/models/user.rs b/src/models/user.rs
index 71b35b6..22bd130 100644
--- a/src/models/user.rs
+++ b/src/models/user.rs
@@ -1,3 +1,4 @@
+use crate::config::PAGE_LIMIT;
use crate::db::get_client;
use crate::errors::AppError;
@@ -113,15 +114,29 @@ impl User {
}
/// List all users
- pub async fn list() -> Result<Vec<UserList>, AppError> {
+ pub async fn list(page: i64) -> Result<Vec<UserList>, AppError> {
let pool = unsafe { get_client() };
let rows = sqlx::query_as!(
UserList,
- r#"SELECT id, email, username, is_staff FROM users"#
+ r#"SELECT id, email, username, is_staff FROM users
+ LIMIT $1 OFFSET $2
+ "#,
+ PAGE_LIMIT,
+ PAGE_LIMIT * page
)
.fetch_all(pool)
.await?;
Ok(rows)
}
+
+ /// Return the number of users.
+ pub async fn count() -> Result<i64, AppError> {
+ let pool = unsafe { get_client() };
+ let row = sqlx::query!(r#"SELECT COUNT(id) as count FROM users"#)
+ .fetch_one(pool)
+ .await?;
+
+ Ok(row.count.unwrap())
+ }
}
diff --git a/src/pagination.rs b/src/pagination.rs
new file mode 100644
index 0000000..1f902b4
--- /dev/null
+++ b/src/pagination.rs
@@ -0,0 +1,7 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+pub struct Pagination {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub page: Option<i64>,
+}
diff --git a/src/routes/model.rs b/src/routes/model.rs
index a5cd2b3..4ac2688 100644
--- a/src/routes/model.rs
+++ b/src/routes/model.rs
@@ -3,18 +3,28 @@ use crate::models::{
auth::Claims,
model::{Model, ModelCreate, ModelUser},
};
-use axum::{routing::get, Json, Router};
+use crate::pagination::Pagination;
+use axum::{extract::Query, routing::get, Json, Router};
+use serde::Serialize;
/// Create routes for `/v1/models/` namespace
pub fn create_route() -> Router {
Router::new().route("/", get(list_models).post(create_model))
}
+#[derive(Serialize)]
+struct ModelPagination {
+ count: i64,
+ results: Vec<ModelUser>,
+}
+
/// List models.
-async fn list_models() -> Result<Json<Vec<ModelUser>>, AppError> {
- let models = Model::list().await?;
+async fn list_models(pagination: Query<Pagination>) -> Result<Json<ModelPagination>, AppError> {
+ let page = pagination.0.page.unwrap_or_default();
+ let results = Model::list(page).await?;
+ let count = Model::count().await?;
- Ok(Json(models))
+ Ok(Json(ModelPagination { count, results }))
}
/// Create a model. Checks Authorization token
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 3dfb73a..4ac994c 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -3,7 +3,13 @@ use crate::models::{
auth::Claims,
user::{User, UserCreate, UserList},
};
-use axum::{extract::Path, routing::get, Json, Router};
+use crate::pagination::Pagination;
+use axum::{
+ extract::{Path, Query},
+ routing::get,
+ Json, Router,
+};
+use serde::Serialize;
/// Create routes for `/v1/users/` namespace
pub fn create_route() -> Router {
@@ -12,11 +18,22 @@ pub fn create_route() -> Router {
.route("/:id", get(get_user))
}
+#[derive(Serialize)]
+struct UserPagination {
+ count: i64,
+ results: Vec<UserList>,
+}
+
/// List users. Checks Authorization token
-async fn list_users(_: Claims) -> Result<Json<Vec<UserList>>, AppError> {
- let users = User::list().await?;
+async fn list_users(
+ _: Claims,
+ pagination: Query<Pagination>,
+) -> Result<Json<UserPagination>, AppError> {
+ let page = pagination.0.page.unwrap_or_default();
+ let results = User::list(page).await?;
+ let count = User::count().await?;
- Ok(Json(users))
+ Ok(Json(UserPagination { count, results }))
}
/// Create an user. Checks Authorization token