Skip to content

Commit

Permalink
fix the update category issue
Browse files Browse the repository at this point in the history
  • Loading branch information
huangcheng committed Nov 30, 2023
1 parent 602f7b4 commit 5ea9506
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 26 deletions.
2 changes: 1 addition & 1 deletion migrations/20231126121150_category.up.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE category
(
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL UNIQUE,
icon VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub enum ServiceError {

#[display(fmt = "Bad request: {}", _0)]
BadRequest(String),

#[display(fmt = "{}", _0)]
AlreadyExists(String),
}

impl From<sqlx::Error> for ServiceError {
Expand Down Expand Up @@ -56,6 +59,7 @@ impl ServiceError {
ServiceError::Unauthorized => Status::Unauthorized,
ServiceError::InternalServerError => Status::InternalServerError,
ServiceError::BadRequest(_) => Status::BadRequest,
ServiceError::AlreadyExists(_) => Status::Conflict,
}
}
}
70 changes: 57 additions & 13 deletions src/handlers/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,43 @@ use crate::Db;
pub async fn get_categories(
page: i64,
size: i64,
search: Option<&str>,
upload_url: &str,
db: &mut Connection<Db>,
) -> Result<WithTotal<response::category::Category>, ServiceError> {
let total = query(r#"SELECT COUNT(id) AS count FROM category"#)
let total = match search {
Some(search) => query(
r#"SELECT COUNT(id) AS count FROM category WHERE name LIKE ? OR description LIKE ?"#,
)
.bind(format!("%{}%", search))
.bind(format!("%{}%", search))
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("count");
.get::<i64, &str>("count"),
None => query(r#"SELECT COUNT(id) AS count FROM category"#)
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("count"),
};

let categories = sqlx::query_as::<_, Category>(
r#"SELECT id, name, description, icon, created_at, updated_at FROM category LIMIT ? OFFSET ?"#,
)
.bind(size)
.bind(page * size)
.fetch_all(&mut ***db)
.await?;
let categories = match search {
Some(search) => query_as::<_, Category>(
r#"SELECT id, name, description, icon, created_at, updated_at FROM category WHERE name LIKE ? OR description LIKE ? LIMIT ? OFFSET ?"#,
)
.bind(format!("%{}%", search))
.bind(format!("%{}%", search))
.bind(size)
.bind(page * size)
.fetch_all(&mut ***db)
.await?,
None => query_as::<_, Category>(
r#"SELECT id, name, description, icon, created_at, updated_at FROM category LIMIT ? OFFSET ?"#,
)
.bind(size)
.bind(page * size)
.fetch_all(&mut ***db)
.await?,
};

Ok(WithTotal {
total,
Expand Down Expand Up @@ -68,17 +90,26 @@ pub async fn update_category<'r>(
})?;

let name = match category.name {
Some(name) => String::from(name),
Some(name) => match name.len() {
0 => record.name,
_ => String::from(name),
},
None => record.name,
};

let description = match category.description {
Some(description) => String::from(description),
Some(description) => match description.len() {
0 => record.description,
_ => String::from(description),
},
None => record.description,
};

let icon = match category.icon {
Some(icon) => String::from(icon),
Some(icon) => match icon.len() {
0 => record.icon,
_ => String::from(icon),
},
None => record.icon,
};

Expand All @@ -91,9 +122,10 @@ pub async fn update_category<'r>(
updated_at: record.updated_at,
};

query(r#"UPDATE category SET name = ?, description = ? WHERE id = ?"#)
query(r#"UPDATE category SET name = ?, description = ?, icon = ? WHERE id = ?"#)
.bind(&record.name)
.bind(&record.description)
.bind(&record.icon)
.bind(record.id)
.execute(&mut ***db)
.await?;
Expand All @@ -105,6 +137,18 @@ pub async fn add_category(
category: &CreateCategory<'_>,
db: &mut Connection<Db>,
) -> Result<(), ServiceError> {
let id = query(r#"SELECT id FROM category WHERE name = ?"#)
.bind(category.name)
.fetch_optional(&mut ***db)
.await?
.map(|row| row.get::<i64, &str>("id"));

if id.is_some() {
return Err(ServiceError::AlreadyExists(String::from(
"Category already exists",
)));
}

query(r#"INSERT INTO category (name, description, icon) VALUES (?, ?, ?)"#)
.bind(category.name)
.bind(category.description)
Expand Down
45 changes: 37 additions & 8 deletions src/handlers/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,49 @@ use crate::Db;
pub async fn get_sites(
page: i64,
size: i64,
search: Option<&str>,
upload_url: &str,
db: &mut Connection<Db>,
) -> Result<WithTotal<SiteWithCategory>, ServiceError> {
let count = query(r#"SELECT COUNT(id) AS count FROM site"#)
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("count");
let count = match search {
Some(search) => {
query(r#"SELECT COUNT(id) AS count FROM site WHERE NAME LIKE % OR description LIKE %"#)
.bind(format!("%{}%", search))
.bind(format!("%{}%", search))
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("count")
}
None => query(r#"SELECT COUNT(id) AS count FROM site"#)
.fetch_one(&mut ***db)
.await?
.get::<i64, &str>("count"),
};

let sites = query_as::<_, SiteWithCategory>(
r#"SELECT site.id AS id, site.name AS name, site.url AS url, site.icon AS icon, site.description AS description, category.name AS category FROM site
let sites = match search {
Some(search) => query_as::<_, SiteWithCategory>(
r#"SELECT site.id AS id, site.name AS name, site.url AS url, site.icon AS icon, site.description AS description, category.name AS category 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.name LIKE % OR site.description LIKE % LIMIT ? OFFSET ?
"#,
)
.bind(format!("%{}%", search))
.bind(format!("%{}%", search))
.bind(size)
.bind(page * size)
.fetch_all(&mut ***db)
.await?,
None => query_as::<_, SiteWithCategory>(
r#"SELECT site.id AS id, site.name AS name, site.url AS url, site.icon AS icon, site.description AS description, category.name AS category FROM site
INNER JOIN category
INNER JOIN category_site ON site.id = category_site.site_id AND category.id = category_site.category_id LIMIT ? OFFSET ?
"#,
).bind(size).bind(page * size).fetch_all(&mut ***db).await?;
)
.bind(size)
.bind(page * size)
.fetch_all(&mut ***db)
.await?,
};

Ok(WithTotal {
total: count,
Expand Down Expand Up @@ -55,7 +84,7 @@ pub async fn get_sites(

pub async fn add_site(site: &CreateSite<'_>, db: &mut Connection<Db>) -> Result<(), ServiceError> {
query_as::<_, Category>(
r#"SELECT id, name, description, created_at, updated_at FROM category WHERE id = ?"#,
r#"SELECT id, name, description, icon, created_at, updated_at FROM category WHERE id = ?"#,
)
.bind(site.category)
.fetch_one(&mut ***db)
Expand Down
5 changes: 3 additions & 2 deletions src/routes/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@ use crate::response::WithTotal;
use crate::utils::standardize_url;
use crate::Db;

#[get("/?<page>&<size>")]
#[get("/?<page>&<size>&<search>")]
pub async fn all(
page: Option<i64>,
size: Option<i64>,
search: Option<&str>,
config: &State<Config>,
mut db: Connection<Db>,
) -> Result<Json<WithTotal<Category>>, Status> {
let page = page.unwrap_or(0);

let size = size.unwrap_or(10);

let result = get_categories(page, size, &config.upload_url, &mut db)
let result = get_categories(page, size, search, &config.upload_url, &mut db)
.await
.map_err(|e| {
error!("{}", e);
Expand Down
5 changes: 3 additions & 2 deletions src/routes/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ use crate::response::WithTotal;
use crate::utils::standardize_url;
use crate::Db;

#[get("/?<page>&<size>")]
#[get("/?<page>&<size>&<search>")]
pub async fn all(
page: Option<i64>,
size: Option<i64>,
search: Option<&str>,
config: &State<Config>,
mut db: Connection<Db>,
) -> Result<Json<WithTotal<SiteWithCategory>>, Status> {
let page = page.unwrap_or(0);

let size = size.unwrap_or(10);

let result = get_sites(page, size, &config.upload_url, &mut db)
let result = get_sites(page, size, search, &config.upload_url, &mut db)
.await
.map_err(|e| {
error!("{}", e);
Expand Down

0 comments on commit 5ea9506

Please sign in to comment.