restructure backend and database
This commit is contained in:
parent
c8a70b5a32
commit
a65657aea1
21 changed files with 373 additions and 76 deletions
11
ApfelBruno/Data/get data from last hour.bru
Normal file
11
ApfelBruno/Data/get data from last hour.bru
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
meta {
|
||||||
|
name: get data from last hour
|
||||||
|
type: http
|
||||||
|
seq: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: http://localhost:8080/api/v1/data
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
meta {
|
meta {
|
||||||
name: Create node group
|
name: Create node group
|
||||||
type: http
|
type: http
|
||||||
seq: 3
|
seq: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
|
@ -12,9 +12,7 @@ post {
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"name":"some mac address",
|
"id":"04-7c-16-06-b3-53",
|
||||||
"coord_la":1.123123,
|
"group":"22da4165-582c-4df9-a911-dfd5573ae468"
|
||||||
"coord_lo":5.3123123,
|
|
||||||
"group":"efbd70a9-dc89-4c8d-9e6c-e7607c823df3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
meta {
|
meta {
|
||||||
name: delete node
|
name: delete node
|
||||||
type: http
|
type: http
|
||||||
seq: 4
|
seq: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
delete {
|
delete {
|
||||||
|
|
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -543,6 +543,7 @@ dependencies = [
|
||||||
"actix-cors",
|
"actix-cors",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"argon2",
|
"argon2",
|
||||||
|
"chrono",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"entity",
|
"entity",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -773,8 +774,10 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -18,3 +18,4 @@ sea-orm = { version = "1", features = [
|
||||||
dotenvy = "*"
|
dotenvy = "*"
|
||||||
jsonwebtoken = "*"
|
jsonwebtoken = "*"
|
||||||
futures = "*"
|
futures = "*"
|
||||||
|
chrono = "*"
|
||||||
|
|
|
@ -1,28 +1,36 @@
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use actix_web::{error::ErrorInternalServerError, web, HttpResponse, Responder};
|
use actix_web::{
|
||||||
use entity::node_group;
|
error::{ErrorBadRequest, ErrorInternalServerError},
|
||||||
use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait};
|
web, HttpResponse, Responder,
|
||||||
|
};
|
||||||
|
use chrono::Utc;
|
||||||
|
use entity::{node, node_group, sensor_data};
|
||||||
|
use sea_orm::{entity::*, query::*, ActiveModelTrait, ActiveValue, DbBackend, EntityTrait};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct NodeWithSensorData {
|
||||||
|
node: node::Model,
|
||||||
|
sensor_data: Vec<sensor_data::Model>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct CreateGroupWithoutId {
|
pub struct CreateGroupWithoutId {
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct CreateLicense {
|
pub struct CreateNode {
|
||||||
name: String,
|
id: i32,
|
||||||
coord_la: f64,
|
|
||||||
coord_lo: f64,
|
|
||||||
group: uuid::Uuid,
|
group: uuid::Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct GroupWithNode {
|
struct GroupWithNode {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
group: entity::node_group::Model,
|
group: node_group::Model,
|
||||||
node: Vec<entity::node::Model>,
|
node: Vec<node::Model>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_nodes(state: web::Data<AppState>) -> actix_web::Result<impl Responder> {
|
pub async fn get_nodes(state: web::Data<AppState>) -> actix_web::Result<impl Responder> {
|
||||||
|
@ -40,6 +48,33 @@ pub async fn get_nodes(state: web::Data<AppState>) -> actix_web::Result<impl Res
|
||||||
Ok(web::Json(result))
|
Ok(web::Json(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_data(state: web::Data<AppState>) -> actix_web::Result<impl Responder> {
|
||||||
|
let db = &state.db;
|
||||||
|
|
||||||
|
let nodes = node::Entity::find()
|
||||||
|
.all(db)
|
||||||
|
.await
|
||||||
|
.map_err(ErrorInternalServerError)?;
|
||||||
|
|
||||||
|
let now = Utc::now();
|
||||||
|
let one_hour_ago = now - chrono::Duration::hours(1);
|
||||||
|
|
||||||
|
let mut result: Vec<NodeWithSensorData> = Vec::new();
|
||||||
|
for node in nodes {
|
||||||
|
let node_id = node.id.clone();
|
||||||
|
let sensor_data = sensor_data::Entity::find()
|
||||||
|
.filter(sensor_data::Column::NodeId.eq(node_id))
|
||||||
|
.filter(sensor_data::Column::Timestamp.gt(one_hour_ago))
|
||||||
|
.all(db)
|
||||||
|
.await
|
||||||
|
.map_err(ErrorInternalServerError)?;
|
||||||
|
|
||||||
|
result.push(NodeWithSensorData { node, sensor_data });
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(web::Json(result))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn create_group(
|
pub async fn create_group(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
group: web::Json<CreateGroupWithoutId>,
|
group: web::Json<CreateGroupWithoutId>,
|
||||||
|
@ -60,7 +95,7 @@ pub async fn create_group(
|
||||||
|
|
||||||
pub async fn create_node(
|
pub async fn create_node(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
node: web::Json<CreateLicense>,
|
node: web::Json<CreateNode>,
|
||||||
) -> actix_web::Result<impl Responder> {
|
) -> actix_web::Result<impl Responder> {
|
||||||
let db = &state.db;
|
let db = &state.db;
|
||||||
|
|
||||||
|
@ -78,18 +113,12 @@ pub async fn create_node(
|
||||||
return Err(ErrorInternalServerError("Group ID does not exist"));
|
return Err(ErrorInternalServerError("Group ID does not exist"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mac_int =
|
||||||
|
mac_to_i32(&node.id).map_err(|_| ErrorInternalServerError("Invalid MAC address"))?;
|
||||||
|
node.id = mac_int;
|
||||||
|
|
||||||
let node = entity::node::ActiveModel {
|
let node = entity::node::ActiveModel {
|
||||||
id: ActiveValue::NotSet,
|
id: ActiveValue::Set(node.id),
|
||||||
name: ActiveValue::Set(node.name),
|
|
||||||
status: ActiveValue::NotSet,
|
|
||||||
coord_la: ActiveValue::Set(node.coord_la),
|
|
||||||
coord_lo: ActiveValue::Set(node.coord_lo),
|
|
||||||
temperature: ActiveValue::NotSet,
|
|
||||||
battery_minimum: ActiveValue::NotSet,
|
|
||||||
battery_current: ActiveValue::NotSet,
|
|
||||||
battery_maximum: ActiveValue::NotSet,
|
|
||||||
voltage: ActiveValue::NotSet,
|
|
||||||
uptime: ActiveValue::NotSet,
|
|
||||||
group: ActiveValue::Set(node.group),
|
group: ActiveValue::Set(node.group),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +127,7 @@ pub async fn create_node(
|
||||||
Ok(web::Json(result))
|
Ok(web::Json(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub async fn delete_node(
|
pub async fn delete_node(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
path: web::Path<Uuid>,
|
path: web::Path<Uuid>,
|
||||||
|
@ -113,3 +143,12 @@ pub async fn delete_node(
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fn mac_to_i32(mac: &str) -> Result<i32, std::num::ParseIntError> {
|
||||||
|
// Remove non-hexadecimal characters
|
||||||
|
let sanitized_mac: String = mac.chars().filter(|c| c.is_digit(16)).collect();
|
||||||
|
|
||||||
|
// Parse the sanitized string as a hexadecimal number
|
||||||
|
i32::from_str_radix(&sanitized_mac, 16)
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
.get(node::get_nodes)
|
.get(node::get_nodes)
|
||||||
.post(node::create_node),
|
.post(node::create_node),
|
||||||
)
|
)
|
||||||
.service(web::resource("/nodes/{id}").delete(node::delete_node))
|
.service(web::resource("/data").get(node::get_data))
|
||||||
|
//.service(web::resource("/nodes/{id}").delete(node::delete_node))
|
||||||
.service(web::resource("/groups").post(node::create_group)),
|
.service(web::resource("/groups").post(node::create_group)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
8
crates/entity/src/crates/entity/src/lib.rs
Normal file
8
crates/entity/src/crates/entity/src/lib.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
pub mod prelude;
|
||||||
|
|
||||||
|
pub mod node;
|
||||||
|
pub mod node_group;
|
||||||
|
pub mod sensor_data;
|
||||||
|
pub mod user;
|
44
crates/entity/src/crates/entity/src/node.rs
Normal file
44
crates/entity/src/crates/entity/src/node.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "node")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(
|
||||||
|
primary_key,
|
||||||
|
auto_increment = false,
|
||||||
|
column_type = "custom(\"macaddr\")"
|
||||||
|
)]
|
||||||
|
pub id: String,
|
||||||
|
pub group: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::node_group::Entity",
|
||||||
|
from = "Column::Group",
|
||||||
|
to = "super::node_group::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
NodeGroup,
|
||||||
|
#[sea_orm(has_many = "super::sensor_data::Entity")]
|
||||||
|
SensorData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::node_group::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::NodeGroup.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::sensor_data::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::SensorData.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
26
crates/entity/src/crates/entity/src/node_group.rs
Normal file
26
crates/entity/src/crates/entity/src/node_group.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "node_group")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: Uuid,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::node::Entity")]
|
||||||
|
Node,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::node::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Node.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
6
crates/entity/src/crates/entity/src/prelude.rs
Normal file
6
crates/entity/src/crates/entity/src/prelude.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
pub use super::node::Entity as Node;
|
||||||
|
pub use super::node_group::Entity as NodeGroup;
|
||||||
|
pub use super::sensor_data::Entity as SensorData;
|
||||||
|
pub use super::user::Entity as User;
|
54
crates/entity/src/crates/entity/src/sensor_data.rs
Normal file
54
crates/entity/src/crates/entity/src/sensor_data.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "sensor_data")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(
|
||||||
|
primary_key,
|
||||||
|
auto_increment = false,
|
||||||
|
column_type = "custom(\"macaddr\")"
|
||||||
|
)]
|
||||||
|
pub id: String,
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub timestamp: DateTime,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub coord_la: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub coord_lo: f64,
|
||||||
|
#[sea_orm(column_type = "Float")]
|
||||||
|
pub temperature: f32,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_minimum: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_current: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_maximum: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub voltage: f64,
|
||||||
|
pub uptime: i64,
|
||||||
|
#[sea_orm(column_type = "custom(\"macaddr\")", nullable)]
|
||||||
|
pub node_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::node::Entity",
|
||||||
|
from = "Column::NodeId",
|
||||||
|
to = "super::node::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
Node,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::node::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Node.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
19
crates/entity/src/crates/entity/src/user.rs
Normal file
19
crates/entity/src/crates/entity/src/user.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "user")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: Uuid,
|
||||||
|
pub name: String,
|
||||||
|
pub email: String,
|
||||||
|
pub hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -4,4 +4,5 @@ pub mod prelude;
|
||||||
|
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod node_group;
|
pub mod node_group;
|
||||||
|
pub mod sensor_data;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
|
@ -3,28 +3,11 @@
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||||
#[sea_orm(table_name = "node")]
|
#[sea_orm(table_name = "node")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key, auto_increment = false)]
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
pub id: Uuid,
|
pub id: i32,
|
||||||
pub name: String,
|
|
||||||
pub status: bool,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub coord_la: f64,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub coord_lo: f64,
|
|
||||||
#[sea_orm(column_type = "Float")]
|
|
||||||
pub temperature: f32,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub battery_minimum: f64,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub battery_current: f64,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub battery_maximum: f64,
|
|
||||||
#[sea_orm(column_type = "Double")]
|
|
||||||
pub voltage: f64,
|
|
||||||
pub uptime: i64,
|
|
||||||
pub group: Uuid,
|
pub group: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +21,8 @@ pub enum Relation {
|
||||||
on_delete = "Cascade"
|
on_delete = "Cascade"
|
||||||
)]
|
)]
|
||||||
NodeGroup,
|
NodeGroup,
|
||||||
|
#[sea_orm(has_many = "super::sensor_data::Entity")]
|
||||||
|
SensorData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::node_group::Entity> for Entity {
|
impl Related<super::node_group::Entity> for Entity {
|
||||||
|
@ -46,4 +31,10 @@ impl Related<super::node_group::Entity> for Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Related<super::sensor_data::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::SensorData.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
pub use super::node::Entity as Node;
|
pub use super::node::Entity as Node;
|
||||||
pub use super::node_group::Entity as NodeGroup;
|
pub use super::node_group::Entity as NodeGroup;
|
||||||
|
pub use super::sensor_data::Entity as SensorData;
|
||||||
pub use super::user::Entity as User;
|
pub use super::user::Entity as User;
|
||||||
|
|
49
crates/entity/src/sensor_data.rs
Normal file
49
crates/entity/src/sensor_data.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.1
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "sensor_data")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub timestamp: DateTime,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub coord_la: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub coord_lo: f64,
|
||||||
|
#[sea_orm(column_type = "Float")]
|
||||||
|
pub temperature: f32,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_minimum: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_current: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub battery_maximum: f64,
|
||||||
|
#[sea_orm(column_type = "Double")]
|
||||||
|
pub voltage: f64,
|
||||||
|
pub uptime: i64,
|
||||||
|
pub node_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::node::Entity",
|
||||||
|
from = "Column::NodeId",
|
||||||
|
to = "super::node::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
Node,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::node::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Node.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -2,6 +2,7 @@ pub use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
mod m20241008_091626_create_table_user;
|
mod m20241008_091626_create_table_user;
|
||||||
mod m20241008_095058_create_table_node;
|
mod m20241008_095058_create_table_node;
|
||||||
|
mod m20241013_134422_create_table_sensor_data;
|
||||||
|
|
||||||
pub struct Migrator;
|
pub struct Migrator;
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ impl MigratorTrait for Migrator {
|
||||||
vec![
|
vec![
|
||||||
Box::new(m20241008_091626_create_table_user::Migration),
|
Box::new(m20241008_091626_create_table_user::Migration),
|
||||||
Box::new(m20241008_095058_create_table_node::Migration),
|
Box::new(m20241008_095058_create_table_node::Migration),
|
||||||
|
Box::new(m20241013_134422_create_table_sensor_data::Migration),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,21 +26,7 @@ impl MigrationTrait for Migration {
|
||||||
Table::create()
|
Table::create()
|
||||||
.table(Node::Table)
|
.table(Node::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(integer(Node::Id).primary_key())
|
||||||
uuid(Node::Id)
|
|
||||||
.extra("DEFAULT gen_random_uuid()")
|
|
||||||
.primary_key(),
|
|
||||||
)
|
|
||||||
.col(string(Node::Name))
|
|
||||||
.col(boolean(Node::Status).default(false))
|
|
||||||
.col(double(Node::CoordLa))
|
|
||||||
.col(double(Node::CoordLo))
|
|
||||||
.col(float(Node::Temperature).default(-127))
|
|
||||||
.col(double(Node::BatteryMinimum).default(-127))
|
|
||||||
.col(double(Node::BatteryCurrent).default(-127))
|
|
||||||
.col(double(Node::BatteryMaximum).default(-127))
|
|
||||||
.col(double(Node::Voltage).default(-127))
|
|
||||||
.col(big_unsigned(Node::Uptime).default(0))
|
|
||||||
.col(uuid(Node::Group))
|
.col(uuid(Node::Group))
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
|
@ -71,25 +57,15 @@ impl MigrationTrait for Migration {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
enum Node {
|
pub enum Node {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id, // Mac address
|
||||||
Name,
|
|
||||||
Status,
|
|
||||||
CoordLa,
|
|
||||||
CoordLo,
|
|
||||||
Temperature, // def: -127
|
|
||||||
BatteryMinimum, // def: -127
|
|
||||||
BatteryCurrent, // def: -127
|
|
||||||
BatteryMaximum, // def: -127
|
|
||||||
Voltage, // def: -127
|
|
||||||
Uptime, // def: 0
|
|
||||||
Group,
|
Group,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
enum NodeGroup {
|
enum NodeGroup {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id, // Uuid
|
||||||
Name,
|
Name, // Groupname
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
use crate::m20241008_095058_create_table_node::Node;
|
||||||
|
use sea_orm_migration::{prelude::*, schema::*};
|
||||||
|
|
||||||
|
#[derive(DeriveMigrationName)]
|
||||||
|
pub struct Migration;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl MigrationTrait for Migration {
|
||||||
|
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
manager
|
||||||
|
.create_table(
|
||||||
|
Table::create()
|
||||||
|
.table(SensorData::Table)
|
||||||
|
.if_not_exists()
|
||||||
|
.col(integer(Node::Id))
|
||||||
|
.col(timestamp(SensorData::Timestamp))
|
||||||
|
.primary_key(
|
||||||
|
Index::create()
|
||||||
|
.col(SensorData::Id)
|
||||||
|
.col(SensorData::Timestamp),
|
||||||
|
)
|
||||||
|
.col(double(SensorData::CoordLa))
|
||||||
|
.col(double(SensorData::CoordLo))
|
||||||
|
.col(float(SensorData::Temperature).default(-127))
|
||||||
|
.col(double(SensorData::BatteryMinimum).default(-127))
|
||||||
|
.col(double(SensorData::BatteryCurrent).default(-127))
|
||||||
|
.col(double(SensorData::BatteryMaximum).default(-127))
|
||||||
|
.col(double(SensorData::Voltage).default(-127))
|
||||||
|
.col(big_unsigned(SensorData::Uptime).default(0))
|
||||||
|
.col(integer(SensorData::NodeId))
|
||||||
|
.foreign_key(
|
||||||
|
ForeignKey::create()
|
||||||
|
.name("fk-data-node_id")
|
||||||
|
.from(SensorData::Table, SensorData::NodeId)
|
||||||
|
.to(Node::Table, Node::Id)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade),
|
||||||
|
)
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
// Replace the sample below with your own migration scripts
|
||||||
|
|
||||||
|
manager
|
||||||
|
.drop_table(Table::drop().table(SensorData::Table).to_owned())
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
enum SensorData {
|
||||||
|
Table,
|
||||||
|
Id, // Mac address
|
||||||
|
Timestamp,
|
||||||
|
CoordLa,
|
||||||
|
CoordLo,
|
||||||
|
Temperature, // def: -127
|
||||||
|
BatteryMinimum, // def: -127
|
||||||
|
BatteryCurrent, // def: -127
|
||||||
|
BatteryMaximum, // def: -127
|
||||||
|
Voltage, // def: -127
|
||||||
|
Uptime, // def: 0
|
||||||
|
NodeId,
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue