Skip to content

Commit

Permalink
allow to sort sites
Browse files Browse the repository at this point in the history
  • Loading branch information
huangcheng committed Dec 7, 2023
1 parent ccd38b5 commit a6ad4f3
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 12 deletions.
1 change: 1 addition & 0 deletions migrations/20231127033035_site.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CREATE TABLE site
url VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL,
icon VARCHAR(255) NOT NULL,
sort_order INT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
1 change: 1 addition & 0 deletions src/bin/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ async fn main() -> Result<(), rocket::Error> {
category::delete,
category::get_sites,
category::sort,
category::sort_sites,
],
)
.mount("/api/sites", routes![site::all])
Expand Down
50 changes: 48 additions & 2 deletions src/handlers/category.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use log::error;
use rocket_db_pools::Connection;
use sqlx::{query, query_as, Row};

Expand Down Expand Up @@ -200,15 +201,15 @@ pub async fn get_sites(
) -> Result<Vec<response::site::Site>, ServiceError> {
let sites = match search {
Some(search) => query_as::<_, response::site::Site>(
r#"SELECT site.id, site.name, site.url, site.description, site.icon FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ? AND (site.name LIKE ? OR site.description LIKE ?)"#,
r#"SELECT site.id, site.name, site.url, site.description, site.icon FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ? AND (site.name LIKE ? OR site.description LIKE ?) ORDER BY site.sort_order"#,
)
.bind(category_id)
.bind(format!("%{}%", search))
.bind(format!("%{}%", search))
.fetch_all(&mut ***db)
.await?,
None => query_as::<_, response::site::Site>(
r#"SELECT site.id, site.name, site.url, site.description, site.icon FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ?"#,
r#"SELECT site.id, site.name, site.url, site.description, site.icon FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ? ORDER BY site.sort_order"#,
)
.bind(category_id)
.fetch_all(&mut ***db)
Expand Down Expand Up @@ -264,3 +265,48 @@ pub async fn sort_categories(

Ok(())
}

pub async fn sort_category_sites(
id: i64,
active_id: i64,
over_id: Option<i64>,
db: &mut Connection<MySQLDb>,
) -> Result<(), ServiceError> {
query(r#"
SELECT site.id as site_id
FROM site
INNER JOIN category
INNER JOIN category_site ON site.id = category_site.site_id AND category.id = category_site.category_id
WHERE site.id = ? AND category.id = ?;
"#)
.bind(active_id)
.bind(id)
.fetch_one(&mut ***db)
.await
.map_err(|e| {
error!("{}", e);

ServiceError::BadRequest(String::from("Site not found"))
})?;

let over_id = match over_id {
Some(over_id) => over_id,
None => {
query(r#"SELECT site.id as site_id FROM site INNER JOIN category INNER JOIN category_site ON site.id = category_site.site_id AND category.id = category_site.category_id WHERE category.id = ? ORDER BY site.id DESC LIMIT 1"#)
.bind(id)
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("site_id")
}
};

query(r#"
UPDATE site as s1, site as s2 SET s1.sort_order = s2.sort_order, s2.sort_order = s1.sort_order WHERE s1.id = ? AND s2.id = ?;
"#)
.bind(active_id)
.bind(over_id)
.execute(&mut ***db)
.await?;

Ok(())
}
49 changes: 40 additions & 9 deletions src/handlers/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,29 @@ pub async fn add_site(
_ => ServiceError::DatabaseError(e),
})?;

let id = query(r#"INSERT INTO site (name, url, description, icon) VALUES (?, ?, ?, ?)"#)
.bind(site.name)
.bind(site.url)
.bind(site.description)
.bind(site.icon)
.execute(&mut ***db)
.await?
.last_insert_id();
let order = match query(r#"SELECT MAX(sort_order) AS sort_order FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ?"#)
.bind(site.category)
.fetch_one(&mut ***db)
.await
{
Ok(row) => match row.try_get::<i64, &str>("sort_order") {
Ok(order) => order + 1,
Err(_) => 0,
},
Err(_) => 0,
};

let id = query(
r#"INSERT INTO site (name, url, description, icon, sort_order) VALUES (?, ?, ?, ?, ?)"#,
)
.bind(site.name)
.bind(site.url)
.bind(site.description)
.bind(site.icon)
.bind(order)
.execute(&mut ***db)
.await?
.last_insert_id();

query(r#"INSERT INTO category_site (category_id, site_id) VALUES (?, ?)"#)
.bind(site.category)
Expand All @@ -121,7 +136,7 @@ pub async fn update_site(
db: &mut Connection<MySQLDb>,
) -> Result<(), ServiceError> {
let record = query_as::<_, Site>(
r#"SELECT id, name, url, description, icon, created_at, updated_at FROM site WHERE id = ?"#,
r#"SELECT id, name, url, description, icon, sort_order, created_at, updated_at FROM site WHERE id = ?"#,
)
.bind(site_id)
.fetch_one(&mut ***db)
Expand Down Expand Up @@ -169,6 +184,7 @@ pub async fn update_site(
url,
description,
icon,
sort_order: record.sort_order,
created_at: record.created_at,
updated_at: record.updated_at,
};
Expand All @@ -194,6 +210,21 @@ pub async fn update_site(
_ => ServiceError::DatabaseError(e),
})?;

let order = match query(r#"SELECT MAX(sort_order) AS sort_order FROM site INNER JOIN category_site ON site.id = category_site.site_id WHERE category_site.category_id = ?"#).bind(category).fetch_one(&mut ***db).await
{
Ok(row) => match row.try_get::<i64, &str>("sort_order") {
Ok(order) => order + 1,
Err(_) => 0,
},
Err(_) => 0,
};

query(r#"UPDATE site SET sort_order = ? WHERE id = ?"#)
.bind(order)
.bind(record.id)
.execute(&mut ***db)
.await?;

query(r#"UPDATE category_site SET category_id = ? WHERE site_id = ?"#)
.bind(category)
.bind(record.id)
Expand Down
1 change: 1 addition & 0 deletions src/models/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct Site {
pub url: String,
pub description: String,
pub icon: String,
pub sort_order: i64,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
20 changes: 19 additions & 1 deletion src/routes/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use rocket_db_pools::Connection;

use crate::config::Config;
use crate::handlers::category::{
self, add_category, delete_category, get_categories, sort_categories, update_category,
self, add_category, delete_category, get_categories, sort_categories, sort_category_sites,
update_category,
};
use crate::middlewares::JwtMiddleware;
use crate::request::category::{CreateCategory, SortCategory, UpdateCategory};
Expand Down Expand Up @@ -137,3 +138,20 @@ pub async fn sort(data: Json<SortCategory>, mut db: Connection<MySQLDb>) -> Resu

Ok(())
}

#[post("/<id>/sites/sort", format = "json", data = "<data>")]
pub async fn sort_sites(
id: i64,
data: Json<SortCategory>,
mut db: Connection<MySQLDb>,
) -> Result<(), Status> {
sort_category_sites(id, data.active, data.over, &mut db)
.await
.map_err(|e| {
error!("{}", e);

e.status()
})?;

Ok(())
}

0 comments on commit a6ad4f3

Please sign in to comment.