Initial
This commit is contained in:
commit
f7fefe300d
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[env]
|
||||
RUST_LOG="debug,sqlx=info"
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/target
|
||||
/**/target
|
||||
/db.sqite
|
||||
/src/db/models
|
3010
Cargo.lock
generated
Normal file
3010
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
Cargo.toml
Normal file
22
Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "rtmc-be"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.92"
|
||||
argon2 = { version = "0.5.3", features = ["simple"] }
|
||||
axum = { version = "0.7.7", features = ["ws"] }
|
||||
axum-extra = { version = "0.9.4", features = ["typed-header"] }
|
||||
chrono = "0.4.38"
|
||||
clap = "4.5.20"
|
||||
env_logger = "0.11.5"
|
||||
futures-util = "0.3.31"
|
||||
headers = "0.4.0"
|
||||
lazy_static = "1.5.0"
|
||||
log = "0.4.22"
|
||||
sea-orm = { version = "1.1.0", features = ["macros", "runtime-tokio-rustls", "sqlx-sqlite", "with-json", "with-uuid"] }
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde_json = "1.0.132"
|
||||
tokio = { version = "1.41.0", features = ["full"] }
|
||||
uuid = { version = "1.11.0", features = ["serde", "v4"] }
|
64
README.md
Normal file
64
README.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
# setup
|
||||
|
||||
```sh
|
||||
cargo install sea-orm-cli
|
||||
sea-orm-cli generate entity -o src/db/models # do this every time you edit the migrations, or first time on clone
|
||||
cargo build
|
||||
```
|
||||
|
||||
# api docs
|
||||
|
||||
u-token = user token
|
||||
p-token = pc token
|
||||
a-token = u-token or p-token
|
||||
pid = cc:t pc id
|
||||
|
||||
GET - /ws (nothing required on first req, see ws docs for more info)
|
||||
|
||||
POST - /api/user/login (no token (duh), json body with email, pwd, returns json with token)
|
||||
POST - /api/user/add (u-token in header, json body with full user info)
|
||||
POST - /api/user/:id/edit (u-token in header, json body with data to replace with)
|
||||
POST - /api/user/:id/remove (u-token in header, no body required)
|
||||
GET - /api/user/:id/info (u-token in header, get back json)
|
||||
|
||||
GET - /api/cct/ (a-token in header, gets a list of all groups)
|
||||
GET - /api/cct/:group/ (a-token in header, gets a list of all pid's)
|
||||
GET - /api/cct/:group/:pid/ (a-token in header, gets a list of all values for that pc)
|
||||
GET - /api/cct/:group/:pid/:val (a-token in header, gets a value from a pc in a group)
|
||||
|
||||
POST - /api/cct/group/add (a-token in header, adds a group)
|
||||
POST - /api/cct/:group/edit (a-token in header, edits a group)
|
||||
POST - /api/cct/:group/pc/add (a-token in header, adds a pc to a group)
|
||||
POST - /api/cct/:group/:pid/edit (a-token in header, edits a pc in a group)
|
||||
POST - /api/cct/:group/:pid/val/add (a-token in header, adds a value to a pc in a group)
|
||||
POST - /api/cct/:group/:pid/:val/edit (a-token in header, edits value info in a pc in a group)
|
||||
POST - /api/cct/:group/:pid/:val/set (a-token in header, sets a value in a pc in a group)
|
||||
|
||||
==========
|
||||
ws
|
||||
==========
|
||||
|
||||
`ws_msg_t`:
|
||||
0: heartbeat ping
|
||||
1: server to client
|
||||
2: client to server
|
||||
`msg_t`:
|
||||
TODO!
|
||||
|
||||
```json
|
||||
{ // low level message
|
||||
"ws_msg_t": 0, // `ws_msg_t`
|
||||
"ws_msg": { // high level message
|
||||
"auth": "Token", // Auth token
|
||||
"msg": { // Data field
|
||||
"keypad": {
|
||||
"DoorOpenEv": { // "DataType": "Value, can be a struct or anything"
|
||||
"user": "uid",
|
||||
"timestamp": 123456,
|
||||
"door_id": "1234-abcd-1234-abcd"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
2201
migration/Cargo.lock
generated
Normal file
2201
migration/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
migration/Cargo.toml
Normal file
22
migration/Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||
|
||||
[dependencies.sea-orm-migration]
|
||||
version = "1.1.0"
|
||||
features = [
|
||||
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
|
||||
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
|
||||
# e.g.
|
||||
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
|
||||
"sqlx-sqlite", # `DATABASE_DRIVER` feature
|
||||
]
|
41
migration/README.md
Normal file
41
migration/README.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Running Migrator CLI
|
||||
|
||||
- Generate a new migration file
|
||||
```sh
|
||||
cargo run -- generate MIGRATION_NAME
|
||||
```
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
19
migration/src/lib.rs
Normal file
19
migration/src/lib.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20241102_133640_users;
|
||||
mod m20241102_133644_computers;
|
||||
mod m20241102_150432_pc_groups;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![
|
||||
Box::new(m20241102_133640_users::Migration),
|
||||
Box::new(m20241102_133644_computers::Migration),
|
||||
Box::new(m20241102_150432_pc_groups::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
68
migration/src/m20241102_133640_users.rs
Normal file
68
migration/src/m20241102_133640_users.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[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(User::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(User::Id)
|
||||
.uuid()
|
||||
.unique_key()
|
||||
.not_null()
|
||||
.primary_key()
|
||||
)
|
||||
.col(ColumnDef::new(User::Username)
|
||||
.string()
|
||||
.unique_key()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::Email)
|
||||
.string()
|
||||
.unique_key()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::PwdHash)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::PwdSalt)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::IsAdministrator)
|
||||
.boolean()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::CreatedAt)
|
||||
.date_time()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(User::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum User {
|
||||
Table,
|
||||
Id,
|
||||
Username,
|
||||
Email,
|
||||
PwdHash,
|
||||
PwdSalt,
|
||||
IsAdministrator,
|
||||
CreatedAt
|
||||
}
|
63
migration/src/m20241102_133644_computers.rs
Normal file
63
migration/src/m20241102_133644_computers.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Replace the sample below with your own migration scripts
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Computer::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(Computer::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key()
|
||||
)
|
||||
.col(ColumnDef::new(Computer::Name)
|
||||
.string()
|
||||
.unique_key()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Computer::Group)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Computer::Type)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Computer::AccessToken)
|
||||
.string()
|
||||
.unique_key()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Computer::CreatedAt)
|
||||
.date_time()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Computer::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Computer {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
Group,
|
||||
Type,
|
||||
AccessToken,
|
||||
CreatedAt
|
||||
}
|
46
migration/src/m20241102_150432_pc_groups.rs
Normal file
46
migration/src/m20241102_150432_pc_groups.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
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(PcGroup::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(PcGroup::Id)
|
||||
.uuid()
|
||||
.unique_key()
|
||||
.primary_key()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(PcGroup::Name)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(PcGroup::AvailableActions)
|
||||
.json()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(PcGroup::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum PcGroup {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
AvailableActions,
|
||||
}
|
6
migration/src/main.rs
Normal file
6
migration/src/main.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
cli::run_cli(migration::Migrator).await;
|
||||
}
|
31
src/api/mod.rs
Normal file
31
src/api/mod.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use crate::context::AppContext;
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
http::StatusCode,
|
||||
Json, Router,
|
||||
};
|
||||
|
||||
pub mod routes;
|
||||
pub mod ws;
|
||||
|
||||
async fn get_api_info() -> String {
|
||||
format!("API v{}", env!("CARGO_PKG_VERSION"))
|
||||
}
|
||||
|
||||
|
||||
pub async fn start_api(ctx: AppContext) {
|
||||
// build our application with a route
|
||||
let app = Router::new()
|
||||
// `GET /` goes to `root`
|
||||
.route("/api/", get(get_api_info))
|
||||
.route("/ws/", get(ws::WsHandler::ws_handler))
|
||||
.with_state(ctx);
|
||||
// `POST /users` goes to `create_user`
|
||||
// .route("/users", post(create_user));
|
||||
|
||||
// run our app with hyper, listening globally on port 3000
|
||||
log::info!("Listening on http://0.0.0.0:3000");
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
|
||||
}
|
0
src/api/routes/cct/event/mod.rs
Normal file
0
src/api/routes/cct/event/mod.rs
Normal file
0
src/api/routes/cct/event/typ.rs
Normal file
0
src/api/routes/cct/event/typ.rs
Normal file
0
src/api/routes/cct/login.rs
Normal file
0
src/api/routes/cct/login.rs
Normal file
3
src/api/routes/cct/mod.rs
Normal file
3
src/api/routes/cct/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod login;
|
||||
mod register;
|
||||
mod event;
|
0
src/api/routes/cct/register.rs
Normal file
0
src/api/routes/cct/register.rs
Normal file
0
src/api/routes/data/mod.rs
Normal file
0
src/api/routes/data/mod.rs
Normal file
2
src/api/routes/mod.rs
Normal file
2
src/api/routes/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod cct;
|
||||
pub mod user;
|
0
src/api/routes/user/add.rs
Normal file
0
src/api/routes/user/add.rs
Normal file
0
src/api/routes/user/edit.rs
Normal file
0
src/api/routes/user/edit.rs
Normal file
0
src/api/routes/user/login.rs
Normal file
0
src/api/routes/user/login.rs
Normal file
14
src/api/routes/user/mod.rs
Normal file
14
src/api/routes/user/mod.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use axum::extract::State;
|
||||
|
||||
use crate::context::AppContext;
|
||||
|
||||
|
||||
pub mod add;
|
||||
pub mod edit;
|
||||
pub mod login;
|
||||
pub mod remove;
|
||||
|
||||
|
||||
async fn handler(State(ctx): State<AppContext>) -> String {
|
||||
format!(":333")
|
||||
}
|
0
src/api/routes/user/remove.rs
Normal file
0
src/api/routes/user/remove.rs
Normal file
116
src/api/ws/mod.rs
Normal file
116
src/api/ws/mod.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
use std::{collections::HashMap, sync::mpsc::{self, Receiver, Sender}};
|
||||
|
||||
use axum::{body::HttpBody, extract::{ws::WebSocket, State, WebSocketUpgrade}, http::StatusCode, response::Response};
|
||||
use axum_extra::TypedHeader;
|
||||
use chrono::{DateTime, Utc};
|
||||
use futures_util::{stream::{SplitSink, SplitStream}, StreamExt};
|
||||
use headers::{authorization::Bearer, Authorization};
|
||||
use sea_orm::prelude::Uuid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::context::AppContext;
|
||||
|
||||
lazy_static::lazy_static!(
|
||||
pub static ref WS_CLIENTS: Mutex<HashMap<Uuid, WsClient>> = Mutex::new(HashMap::new());
|
||||
);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WsClient {
|
||||
rx: Receiver<WsMessage>,
|
||||
tx: Sender<WsMessage>,
|
||||
alive: bool,
|
||||
last_heartbeat: DateTime<Utc>
|
||||
}
|
||||
|
||||
impl WsClient {
|
||||
pub fn new(rx: Receiver<WsMessage>, tx: Sender<WsMessage>) -> Self {
|
||||
Self {
|
||||
rx, tx,
|
||||
alive: false,
|
||||
last_heartbeat: chrono::Utc::now()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WsHandler {
|
||||
}
|
||||
|
||||
impl WsHandler {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
}
|
||||
}
|
||||
pub async fn ws_handler(ws: WebSocketUpgrade, State(ctx): State<AppContext>, TypedHeader(token): TypedHeader<Authorization<Bearer>>) -> Response {
|
||||
let token = token.0.token().to_string();
|
||||
let Ok(token) = Uuid::parse_str(&token) else {
|
||||
todo!()
|
||||
// return Response::status(Body)
|
||||
};
|
||||
ws.on_upgrade(move |socket| Self::handle_socket(socket, token))
|
||||
}
|
||||
|
||||
async fn handle_socket(socket: WebSocket, token: Uuid) {
|
||||
let (sender, receiver) = socket.split();
|
||||
let (r_tx, from_socket) = mpsc::channel();
|
||||
let (to_socket, s_rx) = mpsc::channel();
|
||||
|
||||
async fn send(sender: SplitSink<WebSocket, axum::extract::ws::Message>, s_rx: mpsc::Receiver<WsMessage>) {
|
||||
|
||||
}
|
||||
|
||||
async fn recv(mut receiver: SplitStream<WebSocket>, tx: mpsc::Sender<WsMessage>) {
|
||||
while let Some(msg) = receiver.next().await {
|
||||
let Ok(msg) = msg else {
|
||||
return;
|
||||
};
|
||||
let Ok(msg) = msg.to_text() else {
|
||||
return;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tokio::spawn(recv(receiver, r_tx));
|
||||
tokio::spawn(send(sender, s_rx));
|
||||
Self::add_client(token, from_socket, to_socket).await;
|
||||
|
||||
}
|
||||
|
||||
async fn add_client(token: Uuid, rx: Receiver<WsMessage>, tx: Sender<WsMessage>) {
|
||||
WS_CLIENTS.lock().await.insert(token, WsClient::new(rx, tx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WsMessage {
|
||||
pub ws_msg_t: usize,
|
||||
pub ws_msg: Message,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
pub auth: Uuid,
|
||||
pub msg: MessageType
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum MessageType {
|
||||
Keypad(KeypadMessageType)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum KeypadMessageType {
|
||||
DoorOpenEv {
|
||||
user: Uuid,
|
||||
timestamp: usize,
|
||||
door_id: Uuid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
26
src/context/mod.rs
Normal file
26
src/context/mod.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use std::sync::{Arc, Mutex, MutexGuard, PoisonError};
|
||||
use crate::{api::ws::WsHandler, db::Database};
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppContext {
|
||||
db: Database,
|
||||
ws: WsHandler
|
||||
}
|
||||
|
||||
impl AppContext {
|
||||
pub fn new(db: Database) -> Self {
|
||||
Self {
|
||||
db,
|
||||
ws: WsHandler::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn db(&mut self) -> &mut Database {
|
||||
&mut self.db
|
||||
}
|
||||
pub fn ws(&mut self) -> &mut WsHandler {
|
||||
&mut self.ws
|
||||
}
|
||||
}
|
36
src/db/mod.rs
Normal file
36
src/db/mod.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use std::time::Duration;
|
||||
use sea_orm::{ConnectOptions, Database as SODatabase, DatabaseConnection};
|
||||
|
||||
mod models;
|
||||
|
||||
// to update the models run `sea-orm-cli generate entity -o src/db/models`
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Database {
|
||||
db: DatabaseConnection
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
db: DatabaseConnection::Disconnected
|
||||
}
|
||||
|
||||
}
|
||||
pub async fn connect(&mut self) -> anyhow::Result<()> {
|
||||
log::info!("Connecting to SQlite database at ./db.sqlite");
|
||||
let mut opt = ConnectOptions::new("sqlite://db.sqlite?mode=rwc");
|
||||
opt.max_connections(100)
|
||||
.min_connections(5)
|
||||
.connect_timeout(Duration::from_secs(8))
|
||||
.acquire_timeout(Duration::from_secs(8))
|
||||
.idle_timeout(Duration::from_secs(8))
|
||||
.max_lifetime(Duration::from_secs(8))
|
||||
.sqlx_logging(true)
|
||||
.sqlx_logging_level(log::LevelFilter::Debug);
|
||||
self.db = SODatabase::connect(opt).await?;
|
||||
log::info!("Connection successful");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
38
src/main.rs
Normal file
38
src/main.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use api::ws::{KeypadMessageType, Message, WsMessage};
|
||||
use sea_orm::prelude::Uuid;
|
||||
|
||||
mod api;
|
||||
mod db;
|
||||
mod context;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
let msg = WsMessage {
|
||||
ws_msg_t: 0,
|
||||
ws_msg: Message {
|
||||
auth: Uuid::new_v4(),
|
||||
msg: api::ws::MessageType::Keypad(
|
||||
KeypadMessageType::DoorOpenEv {
|
||||
user: Uuid::new_v4(),
|
||||
timestamp: 0,
|
||||
door_id: Uuid::new_v4()
|
||||
}
|
||||
)
|
||||
}
|
||||
};
|
||||
dbg!(&msg);
|
||||
let txt = serde_json::to_string_pretty(&msg)?;
|
||||
println!("{txt}");
|
||||
return Ok(());
|
||||
|
||||
// TODO: Start db
|
||||
|
||||
let mut db = db::Database::new();
|
||||
db.connect().await?;
|
||||
let ctx = context::AppContext::new(db);
|
||||
api::start_api(ctx).await;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user