Compare commits
3 commits
ce1e93fc49
...
1a5c245250
Author | SHA1 | Date | |
---|---|---|---|
1a5c245250 | |||
e72ed778a2 | |||
bfded464c9 |
4 changed files with 143 additions and 17 deletions
79
src/api.rs
79
src/api.rs
|
@ -8,9 +8,12 @@ use std::sync::Arc;
|
|||
use tokio::sync::Mutex;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn get_items(db: web::Data<Arc<Mutex<Database>>>) -> HttpResponse {
|
||||
pub async fn get_items(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Query<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.get_items().await {
|
||||
match db.get_items_by_url(&url).await {
|
||||
Ok(items) => HttpResponse::Ok().json(items),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to fetch items: {:?}", err);
|
||||
|
@ -22,10 +25,11 @@ pub async fn get_items(db: web::Data<Arc<Mutex<Database>>>) -> HttpResponse {
|
|||
#[cfg(feature = "ssr")]
|
||||
pub async fn create_item(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Query<String>,
|
||||
item: web::Json<DbItem>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.insert_item(&item.into_inner()).await {
|
||||
match db.insert_item_by_url(&url, &item.into_inner()).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Item inserted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to insert item: {:?}", err);
|
||||
|
@ -37,10 +41,11 @@ pub async fn create_item(
|
|||
#[cfg(feature = "ssr")]
|
||||
pub async fn delete_item(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Query<String>,
|
||||
item_id: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.delete_item(&item_id).await {
|
||||
match db.delete_item_by_url(&url, &item_id).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Item deleted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to delete item: {:?}", err);
|
||||
|
@ -52,14 +57,78 @@ pub async fn delete_item(
|
|||
#[cfg(feature = "ssr")]
|
||||
pub async fn delete_property(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Query<String>,
|
||||
property: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.delete_property(&property).await {
|
||||
match db.delete_property_by_url(&url, &property).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Property deleted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to delete property: {:?}", err);
|
||||
HttpResponse::InternalServerError().body("Failed to delete property")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn get_items_by_url(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.get_items_by_url(&url).await {
|
||||
Ok(items) => HttpResponse::Ok().json(items),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to fetch items by URL: {:?}", err);
|
||||
HttpResponse::InternalServerError().body("Failed to fetch items by URL")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn create_item_by_url(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Path<String>,
|
||||
item: web::Json<DbItem>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.insert_item_by_url(&url, &item.into_inner()).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Item inserted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to insert item by URL: {:?}", err);
|
||||
HttpResponse::InternalServerError().body("Failed to insert item by URL")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn delete_item_by_url(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Path<String>,
|
||||
item_id: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.delete_item_by_url(&url, &item_id).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Item deleted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to delete item by URL: {:?}", err);
|
||||
HttpResponse::InternalServerError().body("Failed to delete item by URL")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn delete_property_by_url(
|
||||
db: web::Data<Arc<Mutex<Database>>>,
|
||||
url: web::Path<String>,
|
||||
property: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let db = db.lock().await;
|
||||
match db.delete_property_by_url(&url, &property).await {
|
||||
Ok(_) => HttpResponse::Ok().body("Property deleted"),
|
||||
Err(err) => {
|
||||
leptos::logging::error!("Failed to delete property by URL: {:?}", err);
|
||||
HttpResponse::InternalServerError().body("Failed to delete property by URL")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -116,7 +116,6 @@ pub fn ItemsList(
|
|||
id: Uuid::new_v4().to_string(),
|
||||
name: String::new(),
|
||||
description: String::new(),
|
||||
// reviews: vec![],
|
||||
wikidata_id: None,
|
||||
custom_properties: HashMap::new(),
|
||||
}]);
|
||||
|
@ -206,7 +205,7 @@ pub fn ItemsList(
|
|||
name: db_item.name,
|
||||
description: db_item.description,
|
||||
wikidata_id: db_item.wikidata_id,
|
||||
custom_properties, // Deserialized HashMap
|
||||
custom_properties,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
71
src/db.rs
71
src/db.rs
|
@ -48,13 +48,22 @@ mod db_impl {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Insert a new URL into the database
|
||||
pub async fn insert_url(&self, url: &str) -> Result<i64, Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let mut stmt = conn.prepare("INSERT INTO urls (url) VALUES (?)")?;
|
||||
let url_id = stmt.insert(&[url])?;
|
||||
logging::log!("URL inserted: {}", url);
|
||||
Ok(url_id)
|
||||
}
|
||||
|
||||
// Insert a new item into the database
|
||||
pub async fn insert_item(&self, item: &DbItem) -> Result<(), Error> {
|
||||
pub async fn insert_item(&self, url_id: i64, item: &DbItem) -> Result<(), Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let wikidata_id = item.wikidata_id.as_ref().map(|s| s.as_str()).unwrap_or("");
|
||||
conn.execute(
|
||||
"INSERT INTO items (id, name, description, wikidata_id, custom_properties)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
"INSERT INTO items (id, name, description, wikidata_id, custom_properties, url_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
description = excluded.description,
|
||||
|
@ -66,6 +75,7 @@ mod db_impl {
|
|||
&item.description,
|
||||
&wikidata_id.to_string(),
|
||||
&item.custom_properties,
|
||||
&url_id.to_string(),
|
||||
],
|
||||
)?;
|
||||
logging::log!("Item inserted: {}", item.id);
|
||||
|
@ -107,6 +117,61 @@ mod db_impl {
|
|||
logging::log!("Fetched {} items from the database", result.len()); // Log with Leptos
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// Retrieve all items from the database for a specific URL
|
||||
pub async fn get_items_by_url(&self, url: &str) -> Result<Vec<DbItem>, Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let url_id: i64 = conn.query_row("SELECT id FROM urls WHERE url = ?", &[url], |row| row.get(0))?;
|
||||
let mut stmt = conn.prepare("SELECT * FROM items WHERE url_id = ?")?;
|
||||
let items = stmt.query_map(&[&url_id], |row| {
|
||||
Ok(DbItem {
|
||||
id: row.get(0)?,
|
||||
name: row.get(1)?,
|
||||
description: row.get(2)?,
|
||||
wikidata_id: row.get(3)?,
|
||||
custom_properties: row.get(4)?,
|
||||
})
|
||||
})?;
|
||||
let mut result = Vec::new();
|
||||
for item in items {
|
||||
result.push(item?);
|
||||
}
|
||||
logging::log!("Fetched {} items from the database for URL: {}", result.len(), url);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// Insert a new item into the database for a specific URL
|
||||
pub async fn insert_item_by_url(&self, url: &str, item: &DbItem) -> Result<(), Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let url_id: i64 = conn.query_row("SELECT id FROM urls WHERE url = ?", &[url], |row| row.get(0))?;
|
||||
if url_id == 0 {
|
||||
let url_id = self.insert_url(url).await?;
|
||||
self.insert_item(url_id, item).await?;
|
||||
} else {
|
||||
self.insert_item(url_id, item).await?;
|
||||
}
|
||||
logging::log!("Item inserted into the database for URL: {}", url);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Delete an item from the database for a specific URL
|
||||
pub async fn delete_item_by_url(&self, url: &str, item_id: &str) -> Result<(), Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let url_id: i64 = conn.query_row("SELECT id FROM urls WHERE url = ?", &[url], |row| row.get(0))?;
|
||||
conn.execute("DELETE FROM items WHERE id = ? AND url_id = ?", &[item_id, &url_id.to_string()])?;
|
||||
logging::log!("Item deleted from the database for URL: {}", url);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Delete a property from the database for a specific URL
|
||||
pub async fn delete_property_by_url(&self, url: &str, property: &str) -> Result<(), Error> {
|
||||
let conn = self.conn.lock().await;
|
||||
let url_id: i64 = conn.query_row("SELECT id FROM urls WHERE url = ?", &[url], |row| row.get(0))?;
|
||||
let query = format!("UPDATE items SET custom_properties = json_remove(custom_properties, '$.{}') WHERE url_id = ?", property);
|
||||
conn.execute(&query, &[&url_id.to_string()])?;
|
||||
logging::log!("Property deleted from the database for URL: {}", url);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Define a struct to represent an item in the database
|
||||
|
|
|
@ -7,13 +7,6 @@ pub struct Item {
|
|||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
// pub reviews: Vec<ReviewWithRating>,
|
||||
pub wikidata_id: Option<String>,
|
||||
pub custom_properties: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ReviewWithRating {
|
||||
pub content: String,
|
||||
pub rating: u8, // Ratings from 1 to 5
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue