Improve tag endpoint
This commit is contained in:
parent
8215461e0d
commit
bb76e3db4d
7 changed files with 147 additions and 12 deletions
29
api.v1.yaml
29
api.v1.yaml
|
@ -443,6 +443,10 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
'201':
|
'201':
|
||||||
description: Created
|
description: Created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/tag_full'
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
requestBody:
|
requestBody:
|
||||||
|
@ -474,16 +478,7 @@ paths:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
$ref: '#/components/schemas/tag_full'
|
||||||
properties:
|
|
||||||
relays:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/relay'
|
|
||||||
schedules:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/schedule'
|
|
||||||
'404':
|
'404':
|
||||||
description: Not Found
|
description: Not Found
|
||||||
operationId: get-tags-tag
|
operationId: get-tags-tag
|
||||||
|
@ -822,6 +817,20 @@ components:
|
||||||
type: string
|
type: string
|
||||||
title: tag
|
title: tag
|
||||||
example: sprinkler
|
example: sprinkler
|
||||||
|
tag_full:
|
||||||
|
title: tag (full)
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
tag:
|
||||||
|
$ref: '#/components/schemas/tag'
|
||||||
|
relays:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/relay'
|
||||||
|
schedules:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/schedule'
|
||||||
schedule_id:
|
schedule_id:
|
||||||
type: string
|
type: string
|
||||||
title: schedule_id
|
title: schedule_id
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use actix_web::{get, web, HttpResponse};
|
use actix_web::{delete, get, post, web, HttpResponse};
|
||||||
use emgauwa_lib::db::DbTag;
|
use emgauwa_lib::db::DbTag;
|
||||||
use emgauwa_lib::errors::EmgauwaError;
|
use emgauwa_lib::errors::{DatabaseError, EmgauwaError};
|
||||||
|
use emgauwa_lib::models::{FromDbModel, Tag};
|
||||||
|
use emgauwa_lib::types::RequestCreateTag;
|
||||||
use sqlx::{Pool, Sqlite};
|
use sqlx::{Pool, Sqlite};
|
||||||
|
|
||||||
#[get("/api/v1/tags")]
|
#[get("/api/v1/tags")]
|
||||||
|
@ -13,3 +15,47 @@ pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, Emgauw
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(tags))
|
Ok(HttpResponse::Ok().json(tags))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/api/v1/tags/{tag_name}")]
|
||||||
|
pub async fn show(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (tag_name,) = path.into_inner();
|
||||||
|
|
||||||
|
let tag = DbTag::get_by_tag(&mut pool_conn, &tag_name)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
let return_tag = Tag::from_db_model(&mut pool_conn, tag)?;
|
||||||
|
Ok(HttpResponse::Ok().json(return_tag))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/api/v1/tags/{tag_name}")]
|
||||||
|
pub async fn delete(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (tag_name,) = path.into_inner();
|
||||||
|
|
||||||
|
DbTag::delete_by_tag(&mut pool_conn, &tag_name).await?;
|
||||||
|
Ok(HttpResponse::Ok().json("tag got deleted"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/api/v1/tags")]
|
||||||
|
pub async fn add(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
data: web::Json<RequestCreateTag>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let new_tag = DbTag::create(&mut pool_conn, &data.tag).await?;
|
||||||
|
|
||||||
|
let cache = (Vec::new(), Vec::new()); // a new tag can't have any relays or schedules
|
||||||
|
let return_tag = Tag::from_db_model_cache(&mut pool_conn, new_tag, cache)?;
|
||||||
|
Ok(HttpResponse::Created().json(return_tag))
|
||||||
|
}
|
||||||
|
|
|
@ -85,6 +85,9 @@ async fn main() -> Result<(), std::io::Error> {
|
||||||
.service(handlers::v1::schedules::update)
|
.service(handlers::v1::schedules::update)
|
||||||
.service(handlers::v1::schedules::delete)
|
.service(handlers::v1::schedules::delete)
|
||||||
.service(handlers::v1::tags::index)
|
.service(handlers::v1::tags::index)
|
||||||
|
.service(handlers::v1::tags::show)
|
||||||
|
.service(handlers::v1::tags::delete)
|
||||||
|
.service(handlers::v1::tags::add)
|
||||||
.service(handlers::v1::ws::ws_controllers)
|
.service(handlers::v1::ws::ws_controllers)
|
||||||
})
|
})
|
||||||
.listen(listener)?
|
.listen(listener)?
|
||||||
|
|
|
@ -63,4 +63,25 @@ impl DbTag {
|
||||||
.await
|
.await
|
||||||
.map_err(DatabaseError::from)
|
.map_err(DatabaseError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn delete_by_tag(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
filter_tag: &str,
|
||||||
|
) -> Result<(), DatabaseError> {
|
||||||
|
if sqlx::query_scalar!("SELECT 1 FROM tags WHERE tag = ?", filter_tag)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await?
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
return Err(DatabaseError::NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlx::query!("DELETE FROM tags WHERE tag = ?", filter_tag)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map(|res| match res.rows_affected() {
|
||||||
|
0 => Err(DatabaseError::DeleteError),
|
||||||
|
_ => Ok(()),
|
||||||
|
})?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
mod controller;
|
mod controller;
|
||||||
mod relay;
|
mod relay;
|
||||||
mod schedule;
|
mod schedule;
|
||||||
|
mod tag;
|
||||||
|
|
||||||
pub use controller::Controller;
|
pub use controller::Controller;
|
||||||
pub use relay::Relay;
|
pub use relay::Relay;
|
||||||
pub use schedule::Schedule;
|
pub use schedule::Schedule;
|
||||||
use sqlx::pool::PoolConnection;
|
use sqlx::pool::PoolConnection;
|
||||||
use sqlx::Sqlite;
|
use sqlx::Sqlite;
|
||||||
|
pub use tag::Tag;
|
||||||
|
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
|
|
||||||
|
|
49
emgauwa-lib/src/models/tag.rs
Normal file
49
emgauwa-lib/src/models/tag.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use actix::MessageResponse;
|
||||||
|
use futures::executor::block_on;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use sqlx::pool::PoolConnection;
|
||||||
|
use sqlx::Sqlite;
|
||||||
|
|
||||||
|
use crate::db::{DbRelay, DbSchedule, DbTag};
|
||||||
|
use crate::errors::DatabaseError;
|
||||||
|
use crate::models::{convert_db_list, FromDbModel, Relay, Schedule};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, MessageResponse)]
|
||||||
|
pub struct Tag {
|
||||||
|
pub tag: String,
|
||||||
|
pub relays: Vec<Relay>,
|
||||||
|
pub schedules: Vec<Schedule>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromDbModel for Tag {
|
||||||
|
type DbModel = DbTag;
|
||||||
|
type DbModelCache = (Vec<Relay>, Vec<Schedule>);
|
||||||
|
|
||||||
|
fn from_db_model(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
let db_schedules = block_on(DbSchedule::get_by_tag(conn, &db_model))?;
|
||||||
|
let schedules: Vec<Schedule> = convert_db_list(conn, db_schedules)?;
|
||||||
|
|
||||||
|
let db_relays = block_on(DbRelay::get_by_tag(conn, &db_model))?;
|
||||||
|
let relays: Vec<Relay> = convert_db_list(conn, db_relays)?;
|
||||||
|
|
||||||
|
let cache = (relays, schedules);
|
||||||
|
Self::from_db_model_cache(conn, db_model, cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_db_model_cache(
|
||||||
|
_conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
cache: Self::DbModelCache,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
let tag = db_model.tag.clone();
|
||||||
|
let (relays, schedules) = cache;
|
||||||
|
Ok(Tag {
|
||||||
|
tag,
|
||||||
|
relays,
|
||||||
|
schedules,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,11 @@ pub struct RequestUpdateController {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestCreateTag {
|
||||||
|
pub tag: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl RequestScheduleId {
|
impl RequestScheduleId {
|
||||||
pub async fn get_schedule(
|
pub async fn get_schedule(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Reference in a new issue