feat: added device models

episode-actions
Jef Roosens 2025-02-23 18:11:58 +01:00
parent 1f4b0c35c5
commit 993e58babf
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
7 changed files with 148 additions and 3 deletions

View File

@ -0,0 +1 @@
drop table devices;

View File

@ -0,0 +1,13 @@
create table devices (
id integer primary key not null,
device_id text not null,
user_id bigint not null
references users (id)
on delete cascade,
caption text not null,
type text not null,
unique (user_id, device_id)
);

View File

@ -1,6 +1,7 @@
pub mod models;
mod schema;
pub use models::device::{Device, NewDevice};
pub use models::session::Session;
pub use models::user::{NewUser, User};

View File

@ -0,0 +1,115 @@
use std::{fmt, str::FromStr};
use diesel::{
deserialize::{FromSql, FromSqlRow},
expression::AsExpression,
prelude::*,
serialize::ToSql,
sql_types::Text,
sqlite::{Sqlite, SqliteValue},
};
use serde::{Deserialize, Serialize};
use crate::db::{schema::*, DbPool, DbResult};
#[derive(Serialize, Deserialize, Clone, Queryable, Selectable)]
#[diesel(table_name = devices)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct Device {
id: i64,
device_id: String,
user_id: i64,
caption: String,
type_: DeviceType,
}
#[derive(Deserialize, Insertable)]
#[diesel(table_name = devices)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct NewDevice {
device_id: String,
user_id: i64,
caption: String,
type_: DeviceType,
}
#[derive(Serialize, Deserialize, FromSqlRow, Debug, AsExpression, Clone)]
#[diesel(sql_type = Text)]
#[serde(rename_all = "lowercase")]
pub enum DeviceType {
Desktop,
Laptop,
Mobile,
Server,
Other,
}
impl Device {
pub fn for_user(pool: &DbPool, user_id: i64) -> DbResult<Vec<Self>> {
Ok(devices::dsl::devices
.select(Self::as_select())
.filter(devices::user_id.eq(user_id))
.get_results(&mut pool.get()?)?)
}
}
impl fmt::Display for DeviceType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Desktop => "desktop",
Self::Laptop => "laptop",
Self::Mobile => "mobile",
Self::Server => "server",
Self::Other => "other",
}
)
}
}
#[derive(Debug)]
pub struct DeviceTypeParseErr(String);
impl fmt::Display for DeviceTypeParseErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid device type '{}'", self.0)
}
}
impl std::error::Error for DeviceTypeParseErr {}
impl FromStr for DeviceType {
type Err = DeviceTypeParseErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"desktop" => Ok(Self::Desktop),
"laptop" => Ok(Self::Laptop),
"mobile" => Ok(Self::Mobile),
"server" => Ok(Self::Server),
"other" => Ok(Self::Other),
_ => Err(DeviceTypeParseErr(s.to_string())),
}
}
}
impl FromSql<Text, Sqlite> for DeviceType {
fn from_sql(bytes: SqliteValue) -> diesel::deserialize::Result<Self> {
let s = <String as FromSql<Text, Sqlite>>::from_sql(bytes)?;
Ok(s.as_str().parse()?)
}
}
impl ToSql<Text, Sqlite> for DeviceType {
fn to_sql<'b>(
&'b self,
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
) -> diesel::serialize::Result {
out.set_value(self.to_string());
Ok(diesel::serialize::IsNull::No)
}
}

View File

@ -1,2 +1,3 @@
pub mod device;
pub mod session;
pub mod user;

View File

@ -23,15 +23,16 @@ impl Session {
.get_result(&mut pool.get()?)?)
}
pub fn user_from_id(pool: &DbPool, id: i64) -> DbResult<super::user::User> {
pub fn user_from_id(pool: &DbPool, id: i64) -> DbResult<Option<super::user::User>> {
Ok(sessions::dsl::sessions
.inner_join(users::table)
.filter(sessions::id.eq(id))
.select(User::as_select())
.get_result(&mut pool.get()?)?)
.get_result(&mut pool.get()?)
.optional()?)
}
pub fn user(&self, pool: &DbPool) -> DbResult<super::user::User> {
pub fn user(&self, pool: &DbPool) -> DbResult<Option<super::user::User>> {
Self::user_from_id(pool, self.id)
}

View File

@ -1,5 +1,16 @@
// @generated automatically by Diesel CLI.
diesel::table! {
devices (id) {
id -> BigInt,
device_id -> Text,
user_id -> BigInt,
caption -> Text,
#[sql_name = "type"]
type_ -> Text,
}
}
diesel::table! {
sessions (id) {
id -> BigInt,
@ -15,9 +26,11 @@ diesel::table! {
}
}
diesel::joinable!(devices -> users (user_id));
diesel::joinable!(sessions -> users (user_id));
diesel::allow_tables_to_appear_in_same_query!(
devices,
sessions,
users,
);