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:
|
||||
'201':
|
||||
description: Created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/tag_full'
|
||||
'400':
|
||||
description: Bad Request
|
||||
requestBody:
|
||||
|
@ -474,16 +478,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
relays:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/relay'
|
||||
schedules:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/schedule'
|
||||
$ref: '#/components/schemas/tag_full'
|
||||
'404':
|
||||
description: Not Found
|
||||
operationId: get-tags-tag
|
||||
|
@ -822,6 +817,20 @@ components:
|
|||
type: string
|
||||
title: tag
|
||||
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:
|
||||
type: string
|
||||
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::errors::EmgauwaError;
|
||||
use emgauwa_lib::errors::{DatabaseError, EmgauwaError};
|
||||
use emgauwa_lib::models::{FromDbModel, Tag};
|
||||
use emgauwa_lib::types::RequestCreateTag;
|
||||
use sqlx::{Pool, Sqlite};
|
||||
|
||||
#[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))
|
||||
}
|
||||
|
||||
#[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::delete)
|
||||
.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)
|
||||
})
|
||||
.listen(listener)?
|
||||
|
|
|
@ -63,4 +63,25 @@ impl DbTag {
|
|||
.await
|
||||
.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 relay;
|
||||
mod schedule;
|
||||
mod tag;
|
||||
|
||||
pub use controller::Controller;
|
||||
pub use relay::Relay;
|
||||
pub use schedule::Schedule;
|
||||
use sqlx::pool::PoolConnection;
|
||||
use sqlx::Sqlite;
|
||||
pub use tag::Tag;
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct RequestCreateTag {
|
||||
pub tag: String,
|
||||
}
|
||||
|
||||
impl RequestScheduleId {
|
||||
pub async fn get_schedule(
|
||||
&self,
|
||||
|
|
Loading…
Reference in a new issue